sequel 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +34 -0
- data/Rakefile +1 -1
- data/lib/sequel_core.rb +16 -7
- data/lib/sequel_core/adapters/ado.rb +6 -2
- data/lib/sequel_core/adapters/db2.rb +1 -1
- data/lib/sequel_core/adapters/jdbc.rb +2 -2
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +22 -10
- data/lib/sequel_core/adapters/mysql.rb +2 -2
- data/lib/sequel_core/adapters/odbc.rb +6 -2
- data/lib/sequel_core/adapters/postgres.rb +25 -14
- data/lib/sequel_core/adapters/shared/mysql.rb +15 -35
- data/lib/sequel_core/adapters/shared/postgres.rb +137 -77
- data/lib/sequel_core/adapters/sqlite.rb +2 -2
- data/lib/sequel_core/core_ext.rb +11 -7
- data/lib/sequel_core/database.rb +18 -1
- data/lib/sequel_core/dataset.rb +23 -7
- data/lib/sequel_core/dataset/convenience.rb +1 -1
- data/lib/sequel_core/dataset/sql.rb +46 -31
- data/lib/sequel_core/exceptions.rb +4 -0
- data/lib/sequel_core/schema/generator.rb +43 -3
- data/lib/sequel_core/schema/sql.rb +52 -26
- data/lib/sequel_model.rb +2 -5
- data/lib/sequel_model/associations.rb +3 -3
- data/lib/sequel_model/base.rb +19 -13
- data/lib/sequel_model/record.rb +19 -11
- data/lib/sequel_model/schema.rb +10 -4
- data/lib/sequel_model/validations.rb +20 -7
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/postgres_spec.rb +64 -9
- data/spec/integration/dataset_test.rb +32 -0
- data/spec/sequel_core/core_sql_spec.rb +38 -0
- data/spec/sequel_core/database_spec.rb +16 -1
- data/spec/sequel_core/dataset_spec.rb +66 -1
- data/spec/sequel_core/schema_generator_spec.rb +23 -3
- data/spec/sequel_core/schema_spec.rb +175 -4
- data/spec/sequel_model/record_spec.rb +47 -0
- data/spec/sequel_model/validations_spec.rb +70 -0
- metadata +2 -2
data/lib/sequel_model.rb
CHANGED
@@ -13,17 +13,14 @@ module Sequel
|
|
13
13
|
# Lets you create a Model subclass with its dataset already set.
|
14
14
|
# source can be an existing dataset or a symbol (in which case
|
15
15
|
# it will create a dataset using the default database with
|
16
|
-
# source as the table name.
|
16
|
+
# source as the table name).
|
17
17
|
#
|
18
18
|
# Example:
|
19
19
|
# class Comment < Sequel::Model(:something)
|
20
20
|
# table_name # => :something
|
21
21
|
# end
|
22
22
|
def self.Model(source)
|
23
|
-
|
24
|
-
klass = Class.new(Model)
|
25
|
-
klass.set_dataset(source.is_a?(Dataset) ? source : Model.db[source])
|
26
|
-
@models[source] = klass
|
23
|
+
@models[source] ||= Class.new(Model).set_dataset(source)
|
27
24
|
end
|
28
25
|
|
29
26
|
# Model has some methods that are added via metaprogramming:
|
@@ -297,13 +297,13 @@ module Sequel::Model::Associations
|
|
297
297
|
return if opts[:read_only]
|
298
298
|
|
299
299
|
class_def(opts._add_method) do |o|
|
300
|
-
database
|
300
|
+
database.dataset.from(join_table).insert(left=>pk, right=>o.pk)
|
301
301
|
end
|
302
302
|
class_def(opts._remove_method) do |o|
|
303
|
-
database
|
303
|
+
database.dataset.from(join_table).filter([[left, pk], [right, o.pk]]).delete
|
304
304
|
end
|
305
305
|
class_def(opts._remove_all_method) do
|
306
|
-
database
|
306
|
+
database.dataset.from(join_table).filter(left=>pk).delete
|
307
307
|
end
|
308
308
|
private opts._add_method, opts._remove_method, opts._remove_all_method
|
309
309
|
|
data/lib/sequel_model/base.rb
CHANGED
@@ -206,7 +206,7 @@ module Sequel
|
|
206
206
|
if sup_class == Model
|
207
207
|
subclass.set_dataset(Model.db[subclass.implicit_table_name]) unless subclass.name.blank?
|
208
208
|
elsif ds = sup_class.instance_variable_get(:@dataset)
|
209
|
-
subclass.set_dataset(sup_class.sti_key ? sup_class.sti_dataset.filter(sup_class.sti_key=>subclass.name.to_s) : ds.clone)
|
209
|
+
subclass.set_dataset(sup_class.sti_key ? sup_class.sti_dataset.filter(sup_class.sti_key=>subclass.name.to_s) : ds.clone, :inherited=>true)
|
210
210
|
end
|
211
211
|
rescue
|
212
212
|
nil
|
@@ -308,7 +308,8 @@ module Sequel
|
|
308
308
|
# if there is one associated with the model. Finally, it attempts to
|
309
309
|
# determine the database schema based on the given/created dataset unless
|
310
310
|
# lazy_load_schema is set.
|
311
|
-
def self.set_dataset(ds)
|
311
|
+
def self.set_dataset(ds, opts={})
|
312
|
+
inherited = opts[:inherited]
|
312
313
|
@dataset = case ds
|
313
314
|
when Symbol
|
314
315
|
db[ds]
|
@@ -319,13 +320,15 @@ module Sequel
|
|
319
320
|
raise(Error, "Model.set_dataset takes a Symbol or a Sequel::Dataset")
|
320
321
|
end
|
321
322
|
@dataset.set_model(self)
|
322
|
-
@dataset.extend(DatasetMethods)
|
323
|
-
@dataset.extend(Associations::EagerLoading)
|
324
323
|
@dataset.transform(@transform) if @transform
|
325
|
-
|
326
|
-
|
327
|
-
|
324
|
+
if inherited
|
325
|
+
((@columns = @dataset.columns) rescue nil) unless @@lazy_load_schema
|
326
|
+
else
|
327
|
+
@dataset.extend(DatasetMethods)
|
328
|
+
@dataset.extend(Associations::EagerLoading)
|
329
|
+
@dataset_methods.each{|meth, block| @dataset.meta_def(meth, &block)} if @dataset_methods
|
328
330
|
end
|
331
|
+
((@db_schema = inherited ? superclass.db_schema : get_db_schema) rescue nil) unless @@lazy_load_schema
|
329
332
|
self
|
330
333
|
end
|
331
334
|
metaalias :dataset=, :set_dataset
|
@@ -425,15 +428,18 @@ module Sequel
|
|
425
428
|
|
426
429
|
# Create the column accessors
|
427
430
|
def self.def_column_accessor(*columns) # :nodoc:
|
431
|
+
include(@column_accessors_module = Module.new) unless @column_accessors_module
|
428
432
|
columns.each do |column|
|
429
433
|
im = instance_methods.collect{|x| x.to_s}
|
430
434
|
meth = "#{column}="
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
435
|
+
@column_accessors_module.module_eval do
|
436
|
+
define_method(column){self[column]} unless im.include?(column.to_s)
|
437
|
+
unless im.include?(meth)
|
438
|
+
define_method(meth) do |*v|
|
439
|
+
len = v.length
|
440
|
+
raise(ArgumentError, "wrong number of arguments (#{len} for 1)") unless len == 1
|
441
|
+
self[column] = v.first
|
442
|
+
end
|
437
443
|
end
|
438
444
|
end
|
439
445
|
end
|
data/lib/sequel_model/record.rb
CHANGED
@@ -214,25 +214,33 @@ module Sequel
|
|
214
214
|
# (if !new?) return false, returns nil unless raise_on_save_failure
|
215
215
|
# is true. Otherwise, returns self.
|
216
216
|
def save!(*columns)
|
217
|
+
opts = columns.extract_options!
|
217
218
|
return save_failure(:save) if before_save == false
|
218
219
|
if @new
|
219
220
|
return save_failure(:create) if before_create == false
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
221
|
+
ds = model.dataset
|
222
|
+
if ds.respond_to?(:insert_select) and h = ds.insert_select(@values)
|
223
|
+
@values = h
|
224
|
+
@this = nil
|
225
|
+
else
|
226
|
+
iid = ds.insert(@values)
|
227
|
+
# if we have a regular primary key and it's not set in @values,
|
228
|
+
# we assume it's the last inserted id
|
229
|
+
if (pk = primary_key) && !(Array === pk) && !@values[pk]
|
230
|
+
@values[pk] = iid
|
231
|
+
end
|
232
|
+
if pk
|
233
|
+
@this = nil # remove memoized this dataset
|
234
|
+
refresh
|
235
|
+
end
|
229
236
|
end
|
230
237
|
@new = false
|
231
238
|
after_create
|
232
239
|
else
|
233
240
|
return save_failure(:update) if before_update == false
|
234
241
|
if columns.empty?
|
235
|
-
|
242
|
+
vals = opts[:changed] ? @values.reject{|k,v| !@changed_columns.include?(k)} : @values
|
243
|
+
this.update(vals)
|
236
244
|
@changed_columns = []
|
237
245
|
else # update only the specified columns
|
238
246
|
this.update(@values.reject {|k, v| !columns.include?(k)})
|
@@ -248,7 +256,7 @@ module Sequel
|
|
248
256
|
# chanaged. If no columns have been changed, returns nil. If unable to
|
249
257
|
# save, returns false unless raise_on_save_failure is true.
|
250
258
|
def save_changes
|
251
|
-
save(
|
259
|
+
save(:changed=>true) || false unless @changed_columns.empty?
|
252
260
|
end
|
253
261
|
|
254
262
|
# Updates the instance with the supplied values with support for virtual
|
data/lib/sequel_model/schema.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
module Sequel
|
2
2
|
class Model
|
3
|
-
# Creates table.
|
3
|
+
# Creates table, using the column information from set_schema.
|
4
4
|
def self.create_table
|
5
5
|
db.create_table(table_name, @schema)
|
6
6
|
@db_schema = get_db_schema(true) unless @@lazy_load_schema
|
7
7
|
columns
|
8
8
|
end
|
9
9
|
|
10
|
-
# Drops the table if it exists and then runs create_table.
|
10
|
+
# Drops the table if it exists and then runs create_table. Should probably
|
11
|
+
# not be used except in testing.
|
11
12
|
def self.create_table!
|
12
13
|
drop_table rescue nil
|
13
14
|
create_table
|
@@ -27,8 +28,13 @@ module Sequel
|
|
27
28
|
|
28
29
|
# Defines a table schema (see Schema::Generator for more information).
|
29
30
|
#
|
30
|
-
# This is only needed if you want to use the create_table
|
31
|
-
#
|
31
|
+
# This is only needed if you want to use the create_table/create_table! methods.
|
32
|
+
# Will also set the dataset if you provide a name, as well as setting
|
33
|
+
# the primary key if you defined one in the passed block.
|
34
|
+
#
|
35
|
+
# In general, it is a better idea to use migrations for production code, as
|
36
|
+
# migrations allow changes to existing schema. set_schema is mostly useful for
|
37
|
+
# test code or simple examples.
|
32
38
|
def self.set_schema(name = nil, &block)
|
33
39
|
set_dataset(db[name]) if name
|
34
40
|
@schema = Schema::Generator.new(db, &block)
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module Sequel
|
2
2
|
class Model
|
3
|
+
# Validations without an :if option are always run
|
4
|
+
DEFAULT_VALIDATION_IF_PROC = proc{true}
|
5
|
+
|
3
6
|
# The Validation module houses a couple of classes used by Sequel's
|
4
7
|
# validation code.
|
5
8
|
module Validation
|
@@ -20,7 +23,7 @@ module Sequel
|
|
20
23
|
def full_messages
|
21
24
|
inject([]) do |m, kv|
|
22
25
|
att, errors = *kv
|
23
|
-
errors.each {|e| m << "#{att} #{e}"}
|
26
|
+
errors.each {|e| m << "#{Array(att).join(' and ')} #{e}"}
|
24
27
|
m
|
25
28
|
end
|
26
29
|
end
|
@@ -84,7 +87,12 @@ module Sequel
|
|
84
87
|
superclass.validate(o)
|
85
88
|
end
|
86
89
|
validations.each do |att, procs|
|
87
|
-
v =
|
90
|
+
v = case att
|
91
|
+
when Array
|
92
|
+
att.collect{|a| o.send(a)}
|
93
|
+
else
|
94
|
+
o.send(att)
|
95
|
+
end
|
88
96
|
procs.each {|tag, p| p.call(o, att, v)}
|
89
97
|
end
|
90
98
|
end
|
@@ -300,6 +308,7 @@ module Sequel
|
|
300
308
|
# database, as this suffers from a fairly obvious race condition.
|
301
309
|
#
|
302
310
|
# Possible Options:
|
311
|
+
# * :allow_nil - Whether to skip the validation if the value(s) is/are nil (default: false)
|
303
312
|
# * :if - A symbol (indicating an instance_method) or proc (which is instance_evaled)
|
304
313
|
# skipping this validation if it returns nil or false.
|
305
314
|
# * :message - The message to use (default: 'is already taken')
|
@@ -311,8 +320,12 @@ module Sequel
|
|
311
320
|
|
312
321
|
atts << {:if=>opts[:if], :tag=>opts[:tag]||:uniqueness}
|
313
322
|
validates_each(*atts) do |o, a, v|
|
314
|
-
|
315
|
-
|
323
|
+
error_field = a
|
324
|
+
a = Array(a)
|
325
|
+
v = Array(v)
|
326
|
+
next unless v.any? or opts[:allow_nil] == false
|
327
|
+
ds = o.class.filter(a.zip(v))
|
328
|
+
num_dups = ds.count
|
316
329
|
allow = if num_dups == 0
|
317
330
|
# No unique value in the database
|
318
331
|
true
|
@@ -323,13 +336,13 @@ module Sequel
|
|
323
336
|
elsif o.new?
|
324
337
|
# New record, but unique value already exists in the database
|
325
338
|
false
|
326
|
-
elsif
|
339
|
+
elsif ds.first === o
|
327
340
|
# Unique value exists in database, but for the same record, so the update won't cause a duplicate record
|
328
341
|
true
|
329
342
|
else
|
330
343
|
false
|
331
344
|
end
|
332
|
-
o.errors[
|
345
|
+
o.errors[error_field] << opts[:message] unless allow
|
333
346
|
end
|
334
347
|
end
|
335
348
|
|
@@ -344,7 +357,7 @@ module Sequel
|
|
344
357
|
case opts[:if]
|
345
358
|
when Symbol then proc{send opts[:if]}
|
346
359
|
when Proc then opts[:if]
|
347
|
-
when nil then
|
360
|
+
when nil then DEFAULT_VALIDATION_IF_PROC
|
348
361
|
else raise(::Sequel::Error, "invalid value for :if validation option")
|
349
362
|
end
|
350
363
|
end
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -423,7 +423,7 @@ context "A MySQL database" do
|
|
423
423
|
@db[:test2] << {:name => 'mmm', :value => 111, :tre => 'qqqq'}
|
424
424
|
|
425
425
|
@db[:test2].columns.should == [:name, :value, :zyx, :tre]
|
426
|
-
@db.rename_column :test2, :tre, :ert, :type => :varchar
|
426
|
+
@db.rename_column :test2, :tre, :ert, :type => :varchar, :size=>255
|
427
427
|
@db[:test2].columns.should == [:name, :value, :zyx, :ert]
|
428
428
|
@db[:test2].first[:ert].should == 'qqqq'
|
429
429
|
end
|
@@ -21,6 +21,10 @@ POSTGRES_DB.create_table! :test4 do
|
|
21
21
|
varchar :name, :size => 20
|
22
22
|
bytea :value
|
23
23
|
end
|
24
|
+
POSTGRES_DB.create_table! :test5 do
|
25
|
+
primary_key :xid
|
26
|
+
integer :value
|
27
|
+
end
|
24
28
|
|
25
29
|
context "A PostgreSQL database" do
|
26
30
|
setup do
|
@@ -150,11 +154,11 @@ context "A PostgreSQL dataset" do
|
|
150
154
|
@d.select(:test[:abc__def, 'hello'].as(:x2)).sql.should == \
|
151
155
|
"SELECT test(\"abc\".\"def\", 'hello') AS \"x2\" FROM \"test\""
|
152
156
|
|
153
|
-
@d.insert_sql(:value => 333).should
|
154
|
-
|
157
|
+
@d.insert_sql(:value => 333).should =~ \
|
158
|
+
/\AINSERT INTO "test" \("value"\) VALUES \(333\)( RETURNING NULL)?\z/
|
155
159
|
|
156
|
-
@d.insert_sql(:x => :y).should
|
157
|
-
|
160
|
+
@d.insert_sql(:x => :y).should =~ \
|
161
|
+
/\AINSERT INTO "test" \("x"\) VALUES \("y"\)( RETURNING NULL)?\z/
|
158
162
|
end
|
159
163
|
|
160
164
|
specify "should quote fields correctly when reversing the order if quoting identifiers" do
|
@@ -275,7 +279,7 @@ context "A PostgreSQL dataset" do
|
|
275
279
|
end
|
276
280
|
end
|
277
281
|
|
278
|
-
context "A PostgreSQL
|
282
|
+
context "A PostgreSQL dataset with a timestamp field" do
|
279
283
|
setup do
|
280
284
|
@d = POSTGRES_DB[:test3]
|
281
285
|
@d.delete
|
@@ -417,7 +421,7 @@ context "Postgres::Dataset#multi_insert_sql / #import" do
|
|
417
421
|
end
|
418
422
|
|
419
423
|
specify "should return separate insert statements if server_version < 80200" do
|
420
|
-
@ds.
|
424
|
+
@ds.meta_def(:server_version){80199}
|
421
425
|
|
422
426
|
@ds.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
|
423
427
|
'INSERT INTO test (x, y) VALUES (1, 2)',
|
@@ -426,16 +430,67 @@ context "Postgres::Dataset#multi_insert_sql / #import" do
|
|
426
430
|
end
|
427
431
|
|
428
432
|
specify "should a single insert statement if server_version >= 80200" do
|
429
|
-
@ds.
|
430
|
-
|
433
|
+
@ds.meta_def(:server_version){80200}
|
434
|
+
|
431
435
|
@ds.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
|
432
436
|
'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)'
|
433
437
|
]
|
434
438
|
|
435
|
-
@ds.
|
439
|
+
@ds.meta_def(:server_version){80201}
|
436
440
|
|
437
441
|
@ds.multi_insert_sql([:x, :y], [[1, 2], [3, 4]]).should == [
|
438
442
|
'INSERT INTO test (x, y) VALUES (1, 2), (3, 4)'
|
439
443
|
]
|
440
444
|
end
|
441
445
|
end
|
446
|
+
|
447
|
+
context "Postgres::Dataset#insert" do
|
448
|
+
setup do
|
449
|
+
@ds = POSTGRES_DB[:test5]
|
450
|
+
@ds.delete
|
451
|
+
end
|
452
|
+
|
453
|
+
specify "should call insert_sql if server_version < 80200" do
|
454
|
+
@ds.meta_def(:server_version){80100}
|
455
|
+
@ds.should_receive(:execute_insert).once.with('INSERT INTO test5 (value) VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
456
|
+
@ds.insert(:value=>10)
|
457
|
+
end
|
458
|
+
|
459
|
+
specify "should using call insert_returning_sql if server_version >= 80200" do
|
460
|
+
@ds.meta_def(:server_version){80201}
|
461
|
+
@ds.should_receive(:single_value).once.with(:sql=>'INSERT INTO test5 (value) VALUES (10) RETURNING xid')
|
462
|
+
@ds.insert(:value=>10)
|
463
|
+
end
|
464
|
+
|
465
|
+
specify "should have insert_returning_sql use the RETURNING keyword" do
|
466
|
+
@ds.insert_returning_sql(:xid, :value=>10).should == "INSERT INTO test5 (value) VALUES (10) RETURNING xid"
|
467
|
+
@ds.insert_returning_sql('*'.lit, :value=>10).should == "INSERT INTO test5 (value) VALUES (10) RETURNING *"
|
468
|
+
end
|
469
|
+
|
470
|
+
specify "should have insert_select return nil if server_version < 80200" do
|
471
|
+
@ds.meta_def(:server_version){80100}
|
472
|
+
@ds.insert_select(:value=>10).should == nil
|
473
|
+
end
|
474
|
+
|
475
|
+
specify "should have insert_select insert the record and return the inserted record if server_version < 80200" do
|
476
|
+
@ds.meta_def(:server_version){80201}
|
477
|
+
h = @ds.insert_select(:value=>10)
|
478
|
+
h[:value].should == 10
|
479
|
+
@ds.first(:xid=>h[:xid])[:value].should == 10
|
480
|
+
end
|
481
|
+
|
482
|
+
specify "should correctly return the inserted record's primary key value" do
|
483
|
+
value1 = 10
|
484
|
+
id1 = @ds.insert(:value=>value1)
|
485
|
+
@ds.first(:xid=>id1)[:value].should == value1
|
486
|
+
value2 = 20
|
487
|
+
id2 = @ds.insert(:value=>value2)
|
488
|
+
@ds.first(:xid=>id2)[:value].should == value2
|
489
|
+
end
|
490
|
+
|
491
|
+
specify "should return nil if the table has no primary key" do
|
492
|
+
ds = POSTGRES_DB[:test4]
|
493
|
+
ds.delete
|
494
|
+
ds.insert(:name=>'a').should == nil
|
495
|
+
end
|
496
|
+
end
|
@@ -49,3 +49,35 @@ describe "Simple Dataset operations" do
|
|
49
49
|
sqls_should_be('SELECT * FROM items LIMIT 1')
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
describe "Simple Dataset operations in transactions" do
|
54
|
+
before do
|
55
|
+
INTEGRATION_DB.create_table!(:items_insert_in_transaction) do
|
56
|
+
primary_key :id
|
57
|
+
integer :number
|
58
|
+
end
|
59
|
+
@ds = INTEGRATION_DB[:items_insert_in_transaction]
|
60
|
+
clear_sqls
|
61
|
+
end
|
62
|
+
after do
|
63
|
+
INTEGRATION_DB.drop_table(:items_insert_in_transaction)
|
64
|
+
end
|
65
|
+
|
66
|
+
specify "should insert correctly with a primary key specified inside a transaction" do
|
67
|
+
INTEGRATION_DB.transaction do
|
68
|
+
@ds.insert(:id=>100, :number=>20)
|
69
|
+
sqls_should_be(/INSERT INTO items_insert_in_transaction \((number, id|id, number)\) VALUES \((100, 20|20, 100)\)/)
|
70
|
+
@ds.count.should == 1
|
71
|
+
@ds.order(:id).all.should == [{:id=>100, :number=>20}]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "should have insert return primary key value inside a transaction" do
|
76
|
+
INTEGRATION_DB.transaction do
|
77
|
+
@ds.insert(:number=>20).should == 1
|
78
|
+
sqls_should_be(/INSERT INTO items_insert_in_transaction \(number\) VALUES \(20\)/)
|
79
|
+
@ds.count.should == 1
|
80
|
+
@ds.order(:id).all.should == [{:id=>1, :number=>20}]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -367,20 +367,46 @@ context "String#to_time" do
|
|
367
367
|
end
|
368
368
|
|
369
369
|
context "String#to_date" do
|
370
|
+
after do
|
371
|
+
Sequel.convert_two_digit_years = true
|
372
|
+
end
|
373
|
+
|
370
374
|
specify "should convert the string into a Date object" do
|
371
375
|
"2007-07-11".to_date.should == Date.parse("2007-07-11")
|
372
376
|
end
|
373
377
|
|
378
|
+
specify "should convert 2 digit years by default" do
|
379
|
+
"July 11, 07".to_date.should == Date.parse("2007-07-11")
|
380
|
+
end
|
381
|
+
|
382
|
+
specify "should not convert 2 digit years if set not to" do
|
383
|
+
Sequel.convert_two_digit_years = false
|
384
|
+
"July 11, 07".to_date.should == Date.parse("0007-07-11")
|
385
|
+
end
|
386
|
+
|
374
387
|
specify "should raise Error::InvalidValue for an invalid date" do
|
375
388
|
proc {'0000-00-00'.to_date}.should raise_error(Sequel::Error::InvalidValue)
|
376
389
|
end
|
377
390
|
end
|
378
391
|
|
379
392
|
context "String#to_datetime" do
|
393
|
+
after do
|
394
|
+
Sequel.convert_two_digit_years = true
|
395
|
+
end
|
396
|
+
|
380
397
|
specify "should convert the string into a DateTime object" do
|
381
398
|
"2007-07-11 10:11:12a".to_datetime.should == DateTime.parse("2007-07-11 10:11:12a")
|
382
399
|
end
|
383
400
|
|
401
|
+
specify "should convert 2 digit years by default" do
|
402
|
+
"July 11, 07 10:11:12a".to_datetime.should == DateTime.parse("2007-07-11 10:11:12a")
|
403
|
+
end
|
404
|
+
|
405
|
+
specify "should not convert 2 digit years if set not to" do
|
406
|
+
Sequel.convert_two_digit_years = false
|
407
|
+
"July 11, 07 10:11:12a".to_datetime.should == DateTime.parse("0007-07-11 10:11:12a")
|
408
|
+
end
|
409
|
+
|
384
410
|
specify "should raise Error::InvalidValue for an invalid date" do
|
385
411
|
proc {'0000-00-00'.to_datetime}.should raise_error(Sequel::Error::InvalidValue)
|
386
412
|
end
|
@@ -389,6 +415,7 @@ end
|
|
389
415
|
context "String#to_sequel_time" do
|
390
416
|
after do
|
391
417
|
Sequel.datetime_class = Time
|
418
|
+
Sequel.convert_two_digit_years = true
|
392
419
|
end
|
393
420
|
|
394
421
|
specify "should convert the string into a Time object by default" do
|
@@ -402,6 +429,17 @@ context "String#to_sequel_time" do
|
|
402
429
|
"2007-07-11 10:11:12a".to_sequel_time.should == DateTime.parse("2007-07-11 10:11:12a")
|
403
430
|
end
|
404
431
|
|
432
|
+
specify "should convert 2 digit years by default if using DateTime class" do
|
433
|
+
Sequel.datetime_class = DateTime
|
434
|
+
"July 11, 07 10:11:12a".to_sequel_time.should == DateTime.parse("2007-07-11 10:11:12a")
|
435
|
+
end
|
436
|
+
|
437
|
+
specify "should not convert 2 digit years if set not to when using DateTime class" do
|
438
|
+
Sequel.datetime_class = DateTime
|
439
|
+
Sequel.convert_two_digit_years = false
|
440
|
+
"July 11, 07 10:11:12a".to_sequel_time.should == DateTime.parse("0007-07-11 10:11:12a")
|
441
|
+
end
|
442
|
+
|
405
443
|
specify "should raise Error::InvalidValue for an invalid time" do
|
406
444
|
proc {'0000-00-00'.to_sequel_time}.should raise_error(Sequel::Error::InvalidValue)
|
407
445
|
Sequel.datetime_class = DateTime
|