sequel 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +62 -0
- data/README.rdoc +4 -4
- data/doc/release_notes/3.3.0.txt +1 -1
- data/doc/release_notes/3.4.0.txt +325 -0
- data/doc/sharding.rdoc +3 -3
- data/lib/sequel/adapters/amalgalite.rb +1 -1
- data/lib/sequel/adapters/firebird.rb +4 -9
- data/lib/sequel/adapters/jdbc.rb +21 -7
- data/lib/sequel/adapters/mysql.rb +2 -1
- data/lib/sequel/adapters/odbc.rb +7 -21
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +6 -1
- data/lib/sequel/adapters/shared/mssql.rb +11 -0
- data/lib/sequel/adapters/shared/mysql.rb +8 -12
- data/lib/sequel/adapters/shared/oracle.rb +13 -0
- data/lib/sequel/adapters/shared/postgres.rb +5 -10
- data/lib/sequel/adapters/shared/sqlite.rb +21 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/core.rb +147 -11
- data/lib/sequel/database.rb +21 -9
- data/lib/sequel/dataset.rb +31 -6
- data/lib/sequel/dataset/convenience.rb +1 -1
- data/lib/sequel/dataset/sql.rb +76 -18
- data/lib/sequel/extensions/inflector.rb +2 -51
- data/lib/sequel/model.rb +16 -10
- data/lib/sequel/model/associations.rb +4 -1
- data/lib/sequel/model/base.rb +13 -6
- data/lib/sequel/model/default_inflections.rb +46 -0
- data/lib/sequel/model/inflections.rb +1 -51
- data/lib/sequel/plugins/boolean_readers.rb +52 -0
- data/lib/sequel/plugins/instance_hooks.rb +57 -0
- data/lib/sequel/plugins/lazy_attributes.rb +13 -1
- data/lib/sequel/plugins/nested_attributes.rb +171 -0
- data/lib/sequel/plugins/serialization.rb +35 -16
- data/lib/sequel/plugins/timestamps.rb +87 -0
- data/lib/sequel/plugins/validation_helpers.rb +8 -1
- data/lib/sequel/sql.rb +33 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +11 -6
- data/spec/core/core_sql_spec.rb +29 -0
- data/spec/core/database_spec.rb +16 -7
- data/spec/core/dataset_spec.rb +264 -20
- data/spec/extensions/boolean_readers_spec.rb +86 -0
- data/spec/extensions/inflector_spec.rb +67 -4
- data/spec/extensions/instance_hooks_spec.rb +133 -0
- data/spec/extensions/lazy_attributes_spec.rb +45 -5
- data/spec/extensions/nested_attributes_spec.rb +272 -0
- data/spec/extensions/serialization_spec.rb +64 -1
- data/spec/extensions/timestamps_spec.rb +150 -0
- data/spec/extensions/validation_helpers_spec.rb +18 -0
- data/spec/integration/dataset_test.rb +79 -2
- data/spec/integration/schema_test.rb +17 -0
- data/spec/integration/timezone_test.rb +55 -0
- data/spec/model/associations_spec.rb +19 -7
- data/spec/model/model_spec.rb +29 -0
- data/spec/model/record_spec.rb +36 -0
- data/spec/spec_config.rb +1 -1
- metadata +14 -2
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
2
|
|
3
3
|
require 'yaml'
|
4
|
+
require 'json'
|
4
5
|
|
5
6
|
describe "Serialization plugin" do
|
6
7
|
before do
|
@@ -10,7 +11,7 @@ describe "Serialization plugin" do
|
|
10
11
|
end
|
11
12
|
end)
|
12
13
|
no_primary_key
|
13
|
-
columns :id, :abc, :def
|
14
|
+
columns :id, :abc, :def, :ghi
|
14
15
|
end
|
15
16
|
MODEL_DB.reset
|
16
17
|
end
|
@@ -23,6 +24,10 @@ describe "Serialization plugin" do
|
|
23
24
|
@c.plugin :serialization, :marshal, :def
|
24
25
|
@c.create(:abc => 1, :def=> 1)
|
25
26
|
MODEL_DB.sqls.last.should =~ /INSERT INTO items \((abc, def|def, abc)\) VALUES \(('--- 1\n', 'BAhpBg==\n'|'BAhpBg==\n', '--- 1\n')\)/
|
27
|
+
|
28
|
+
@c.plugin :serialization, :json, :ghi
|
29
|
+
@c.create(:ghi => [123])
|
30
|
+
MODEL_DB.sqls.last.should =~ /INSERT INTO items \((ghi)\) VALUES \('\[123\]'\)/
|
26
31
|
end
|
27
32
|
|
28
33
|
it "should allow serializing attributes to yaml" do
|
@@ -57,6 +62,18 @@ describe "Serialization plugin" do
|
|
57
62
|
"INSERT INTO items (abc) VALUES ('#{x}')", \
|
58
63
|
]
|
59
64
|
end
|
65
|
+
|
66
|
+
it "should allow serializing attributes to json" do
|
67
|
+
@c.plugin :serialization, :json, :ghi
|
68
|
+
@c.create(:ghi => [1])
|
69
|
+
@c.create(:ghi => ["hello"])
|
70
|
+
|
71
|
+
x = JSON.generate ["hello"]
|
72
|
+
MODEL_DB.sqls.should == [ \
|
73
|
+
"INSERT INTO items (ghi) VALUES ('[1]')", \
|
74
|
+
"INSERT INTO items (ghi) VALUES ('#{x}')", \
|
75
|
+
]
|
76
|
+
end
|
60
77
|
|
61
78
|
it "should translate values to and from yaml serialization format using accessor methods" do
|
62
79
|
@c.set_primary_key :id
|
@@ -102,6 +119,29 @@ describe "Serialization plugin" do
|
|
102
119
|
MODEL_DB.sqls.should == ["UPDATE items SET abc = '#{[Marshal.dump(23)].pack('m')}' WHERE (id = 1)",
|
103
120
|
"INSERT INTO items (abc) VALUES ('#{[Marshal.dump([1, 2, 3])].pack('m')}')"]
|
104
121
|
end
|
122
|
+
|
123
|
+
it "should translate values to and from json serialization format using accessor methods" do
|
124
|
+
@c.set_primary_key :id
|
125
|
+
@c.plugin :serialization, :json, :abc, :def
|
126
|
+
|
127
|
+
ds = @c.dataset
|
128
|
+
def ds.fetch_rows(sql, &block)
|
129
|
+
block.call(:id => 1, :abc => JSON.generate([1]), :def => JSON.generate(["hello"]))
|
130
|
+
end
|
131
|
+
|
132
|
+
o = @c.first
|
133
|
+
o.id.should == 1
|
134
|
+
o.abc.should == [1]
|
135
|
+
o.abc.should == [1]
|
136
|
+
o.def.should == ["hello"]
|
137
|
+
o.def.should == ["hello"]
|
138
|
+
|
139
|
+
o.update(:abc => [23])
|
140
|
+
@c.create(:abc => [1,2,3])
|
141
|
+
|
142
|
+
MODEL_DB.sqls.should == ["UPDATE items SET abc = '#{JSON.generate([23])}' WHERE (id = 1)",
|
143
|
+
"INSERT INTO items (abc) VALUES ('#{JSON.generate([1,2,3])}')"]
|
144
|
+
end
|
105
145
|
|
106
146
|
it "should copy serialization formats and columns to subclasses" do
|
107
147
|
@c.set_primary_key :id
|
@@ -143,4 +183,27 @@ describe "Serialization plugin" do
|
|
143
183
|
lambda{o.send(:serialize_value, :abc, 1)}.should raise_error(Sequel::Error)
|
144
184
|
lambda{o.send(:deserialize_value, :abc, "--- hello\n")}.should raise_error(Sequel::Error)
|
145
185
|
end
|
186
|
+
|
187
|
+
it "should add the accessors to a module included in the class, so they can be easily overridden" do
|
188
|
+
@c.class_eval do
|
189
|
+
def abc
|
190
|
+
"#{super}-blah"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
@c.plugin :serialization, :yaml, :abc
|
194
|
+
o = @c.load(:abc => "--- 1\n")
|
195
|
+
o.abc.should == "1-blah"
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should call super to get the deserialized value from a previous accessor" do
|
199
|
+
m = Module.new do
|
200
|
+
def abc
|
201
|
+
"--- #{@values[:abc]*3}\n"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
@c.send(:include, m)
|
205
|
+
@c.plugin :serialization, :yaml, :abc
|
206
|
+
o = @c.load(:abc => 3)
|
207
|
+
o.abc.should == 9
|
208
|
+
end
|
146
209
|
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe "Sequel::Plugins::Timestamps" do
|
4
|
+
before do
|
5
|
+
dc = Object.new
|
6
|
+
dc.instance_eval do
|
7
|
+
def now
|
8
|
+
'2009-08-01'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
Sequel.datetime_class = dc
|
12
|
+
@c = Class.new(Sequel::Model(:t))
|
13
|
+
@c.class_eval do
|
14
|
+
columns :id, :created_at, :updated_at
|
15
|
+
plugin :timestamps
|
16
|
+
db.reset
|
17
|
+
def _refresh(ds); self end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
after do
|
21
|
+
Sequel.datetime_class = Time
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set the create timestamp field on creation" do
|
25
|
+
o = @c.create
|
26
|
+
@c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
|
27
|
+
o.created_at.should == '2009-08-01'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should set the update timestamp field on update" do
|
31
|
+
o = @c.load(:id=>1).save
|
32
|
+
@c.db.sqls.should == ["UPDATE t SET updated_at = '2009-08-01' WHERE (id = 1)"]
|
33
|
+
o.updated_at.should == '2009-08-01'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not update the update timestamp on creation" do
|
37
|
+
@c.create.updated_at.should == nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use the same value for the creation and update timestamps when creating if the :update_on_create option is given" do
|
41
|
+
@c.plugin :timestamps, :update_on_create=>true
|
42
|
+
o = @c.create
|
43
|
+
@c.db.sqls.length.should == 1
|
44
|
+
@c.db.sqls.first.should =~ /INSERT INTO t \((creat|updat)ed_at, (creat|updat)ed_at\) VALUES \('2009-08-01', '2009-08-01'\)/
|
45
|
+
o.created_at.should === o.updated_at
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should allow specifying the create timestamp field via the :create option" do
|
49
|
+
c = Class.new(Sequel::Model(:t))
|
50
|
+
c.class_eval do
|
51
|
+
columns :id, :c
|
52
|
+
plugin :timestamps, :create=>:c
|
53
|
+
db.reset
|
54
|
+
def _refresh(ds); self end
|
55
|
+
end
|
56
|
+
o = c.create
|
57
|
+
c.db.sqls.should == ["INSERT INTO t (c) VALUES ('2009-08-01')"]
|
58
|
+
o.c.should == '2009-08-01'
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should allow specifying the update timestamp field via the :update option" do
|
62
|
+
c = Class.new(Sequel::Model(:t))
|
63
|
+
c.class_eval do
|
64
|
+
columns :id, :u
|
65
|
+
plugin :timestamps, :update=>:u
|
66
|
+
db.reset
|
67
|
+
def _refresh(ds); self end
|
68
|
+
end
|
69
|
+
o = c.load(:id=>1).save
|
70
|
+
c.db.sqls.should == ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
|
71
|
+
o.u.should == '2009-08-01'
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should not raise an error if the model doesn't have the timestamp columns" do
|
75
|
+
c = Class.new(Sequel::Model(:t))
|
76
|
+
c.class_eval do
|
77
|
+
columns :id, :x
|
78
|
+
plugin :timestamps
|
79
|
+
db.reset
|
80
|
+
def _refresh(ds); self end
|
81
|
+
end
|
82
|
+
c.create(:x=>2)
|
83
|
+
c.load(:id=>1, :x=>2).save
|
84
|
+
c.db.sqls.should == ["INSERT INTO t (x) VALUES (2)", "UPDATE t SET x = 2 WHERE (id = 1)"]
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should not overwrite an existing create timestamp" do
|
88
|
+
o = @c.create(:created_at=>'2009-08-03')
|
89
|
+
@c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-03')"]
|
90
|
+
o.created_at.should == '2009-08-03'
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should overwrite an existing create timestamp if the :force option is used" do
|
94
|
+
@c.plugin :timestamps, :force=>true
|
95
|
+
o = @c.create(:created_at=>'2009-08-03')
|
96
|
+
@c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
|
97
|
+
o.created_at.should == '2009-08-01'
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should have create_timestamp_field give the create timestamp field" do
|
101
|
+
@c.create_timestamp_field.should == :created_at
|
102
|
+
@c.plugin :timestamps, :create=>:c
|
103
|
+
@c.create_timestamp_field.should == :c
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should have update_timestamp_field give the update timestamp field" do
|
107
|
+
@c.update_timestamp_field.should == :updated_at
|
108
|
+
@c.plugin :timestamps, :update=>:u
|
109
|
+
@c.update_timestamp_field.should == :u
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should have create_timestamp_overwrite? give the whether to overwrite an existing create timestamp" do
|
113
|
+
@c.create_timestamp_overwrite?.should == false
|
114
|
+
@c.plugin :timestamps, :force=>true
|
115
|
+
@c.create_timestamp_overwrite?.should == true
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should have set_update_timestamp_on_create? give whether to set the update timestamp on create" do
|
119
|
+
@c.set_update_timestamp_on_create?.should == false
|
120
|
+
@c.plugin :timestamps, :update_on_create=>true
|
121
|
+
@c.set_update_timestamp_on_create?.should == true
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should work with subclasses" do
|
125
|
+
c = Class.new(@c)
|
126
|
+
o = c.create
|
127
|
+
o.created_at.should == '2009-08-01'
|
128
|
+
o.updated_at.should == nil
|
129
|
+
o = c.load(:id=>1).save
|
130
|
+
o.updated_at.should == '2009-08-01'
|
131
|
+
c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-01')", "UPDATE t SET updated_at = '2009-08-01' WHERE (id = 1)"]
|
132
|
+
c.create(:created_at=>'2009-08-03').created_at.should == '2009-08-03'
|
133
|
+
|
134
|
+
c.class_eval do
|
135
|
+
columns :id, :c, :u
|
136
|
+
plugin :timestamps, :create=>:c, :update=>:u, :force=>true, :update_on_create=>true
|
137
|
+
end
|
138
|
+
c2 = Class.new(c)
|
139
|
+
c2.db.reset
|
140
|
+
o = c2.create
|
141
|
+
o.c.should == '2009-08-01'
|
142
|
+
o.u.should === o.c
|
143
|
+
c2.db.sqls.first.should =~ /INSERT INTO t \([cu], [cu]\) VALUES \('2009-08-01', '2009-08-01'\)/
|
144
|
+
c2.db.reset
|
145
|
+
o = c2.load(:id=>1).save
|
146
|
+
o.u.should == '2009-08-01'
|
147
|
+
c2.db.sqls.should == ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
|
148
|
+
c2.create(:c=>'2009-08-03').c.should == '2009-08-01'
|
149
|
+
end
|
150
|
+
end
|
@@ -288,4 +288,22 @@ describe "Sequel::Plugins::ValidationHelpers" do
|
|
288
288
|
@user.should be_valid
|
289
289
|
MODEL_DB.sqls.last.should == "SELECT COUNT(*) AS count FROM items WHERE ((username = '0records') AND (password = 'anothertest')) LIMIT 1"
|
290
290
|
end
|
291
|
+
|
292
|
+
it "should support validates_unique with a block" do
|
293
|
+
@c.columns(:id, :username, :password)
|
294
|
+
@c.set_dataset MODEL_DB[:items]
|
295
|
+
@c.set_validations{validates_unique(:username){|ds| ds.filter(:active)}}
|
296
|
+
@c.dataset.extend(Module.new {
|
297
|
+
def fetch_rows (sql)
|
298
|
+
@db << sql
|
299
|
+
yield({:v => 0})
|
300
|
+
end
|
301
|
+
})
|
302
|
+
|
303
|
+
MODEL_DB.reset
|
304
|
+
@c.new(:username => "0records", :password => "anothertest").should be_valid
|
305
|
+
@c.load(:id=>3, :username => "0records", :password => "anothertest").should be_valid
|
306
|
+
MODEL_DB.sqls.should == ["SELECT COUNT(*) AS count FROM items WHERE ((username = '0records') AND active) LIMIT 1",
|
307
|
+
"SELECT COUNT(*) AS count FROM items WHERE (((username = '0records') AND active) AND (id != 3)) LIMIT 1"]
|
308
|
+
end
|
291
309
|
end
|
@@ -135,6 +135,15 @@ describe Sequel::Dataset do
|
|
135
135
|
@d.count.should == 1
|
136
136
|
@d.first[:name].should == 'def'
|
137
137
|
end
|
138
|
+
|
139
|
+
specify "should be able to truncate the table" do
|
140
|
+
@d << {:name => 'abc', :value => 123}
|
141
|
+
@d << {:name => 'abc', :value => 456}
|
142
|
+
@d << {:name => 'def', :value => 789}
|
143
|
+
@d.count.should == 3
|
144
|
+
@d.truncate.should == nil
|
145
|
+
@d.count.should == 0
|
146
|
+
end
|
138
147
|
|
139
148
|
specify "should be able to literalize booleans" do
|
140
149
|
proc {@d.literal(true)}.should_not raise_error
|
@@ -164,7 +173,7 @@ describe Sequel::Database do
|
|
164
173
|
end
|
165
174
|
end
|
166
175
|
|
167
|
-
context
|
176
|
+
context Sequel::Dataset do
|
168
177
|
before do
|
169
178
|
INTEGRATION_DB.create_table! :items do
|
170
179
|
primary_key :id
|
@@ -418,4 +427,72 @@ if INTEGRATION_DB.dataset.supports_window_functions?
|
|
418
427
|
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
419
428
|
end
|
420
429
|
end
|
421
|
-
end
|
430
|
+
end
|
431
|
+
|
432
|
+
describe Sequel::SQL::Constants do
|
433
|
+
before do
|
434
|
+
@db = INTEGRATION_DB
|
435
|
+
@ds = @db[:constants]
|
436
|
+
@c = proc do |v|
|
437
|
+
case v
|
438
|
+
when Time
|
439
|
+
v
|
440
|
+
when DateTime, String
|
441
|
+
Time.parse(v.to_s)
|
442
|
+
else
|
443
|
+
v
|
444
|
+
end
|
445
|
+
end
|
446
|
+
@c2 = proc{|v| v.is_a?(Date) ? v : Date.parse(v) }
|
447
|
+
end
|
448
|
+
after do
|
449
|
+
@db.drop_table(:constants)
|
450
|
+
end
|
451
|
+
|
452
|
+
it "should have working CURRENT_DATE" do
|
453
|
+
@db.create_table!(:constants){Date :d}
|
454
|
+
@ds.insert(:d=>Sequel::CURRENT_DATE)
|
455
|
+
Date.today.should == @c2[@ds.get(:d)]
|
456
|
+
end
|
457
|
+
|
458
|
+
it "should have working CURRENT_TIME" do
|
459
|
+
@db.create_table!(:constants){Time :t, :only_time=>true}
|
460
|
+
@ds.insert(:t=>Sequel::CURRENT_TIME)
|
461
|
+
(Time.now - @c[@ds.get(:t)]).should be_close(0, 1)
|
462
|
+
end
|
463
|
+
|
464
|
+
it "should have working CURRENT_TIMESTAMP" do
|
465
|
+
@db.create_table!(:constants){DateTime :ts}
|
466
|
+
@ds.insert(:ts=>Sequel::CURRENT_TIMESTAMP)
|
467
|
+
(Time.now - @c[@ds.get(:ts)]).should be_close(0, 1)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
describe "Sequel::Dataset#import and #multi_insert" do
|
472
|
+
before do
|
473
|
+
@db = INTEGRATION_DB
|
474
|
+
@db.create_table!(:imp){Integer :i}
|
475
|
+
@db.create_table!(:exp2){Integer :i}
|
476
|
+
@ids = @db[:imp].order(:i)
|
477
|
+
@eds = @db[:exp2]
|
478
|
+
end
|
479
|
+
after do
|
480
|
+
@db.drop_table(:imp, :exp2)
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should import with multi_insert and an array of hashes" do
|
484
|
+
@ids.multi_insert([{:i=>10}, {:i=>20}])
|
485
|
+
@ids.all.should == [{:i=>10}, {:i=>20}]
|
486
|
+
end
|
487
|
+
|
488
|
+
it "should import with an array of arrays of values" do
|
489
|
+
@ids.import([:i], [[10], [20]])
|
490
|
+
@ids.all.should == [{:i=>10}, {:i=>20}]
|
491
|
+
end
|
492
|
+
|
493
|
+
it "should import with a dataset" do
|
494
|
+
@eds.import([:i], [[10], [20]])
|
495
|
+
@ids.import([:i], @eds)
|
496
|
+
@ids.all.should == [{:i=>10}, {:i=>20}]
|
497
|
+
end
|
498
|
+
end
|
@@ -293,6 +293,23 @@ describe "Database schema modifiers" do
|
|
293
293
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
294
294
|
@ds.columns!.should == [:id]
|
295
295
|
end
|
296
|
+
|
297
|
+
specify "should remove multiple columns in a single alter_table block" do
|
298
|
+
@db.create_table!(:items) do
|
299
|
+
primary_key :id
|
300
|
+
String :name
|
301
|
+
Integer :number
|
302
|
+
end
|
303
|
+
@ds.insert(:number=>10)
|
304
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number]
|
305
|
+
@ds.columns!.should == [:id, :name, :number]
|
306
|
+
@db.alter_table(:items) do
|
307
|
+
drop_column :name
|
308
|
+
drop_column :number
|
309
|
+
end
|
310
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
311
|
+
@ds.columns!.should == [:id]
|
312
|
+
end
|
296
313
|
end
|
297
314
|
|
298
315
|
if INTEGRATION_DB.respond_to?(:tables)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe "Sequel timezone support" do
|
4
|
+
def test_timezone
|
5
|
+
t = Time.now
|
6
|
+
@db[:t].insert(t)
|
7
|
+
t2 = @db[:t].single_value
|
8
|
+
t2 = Sequel.database_to_application_timestamp(t2.to_s) unless t2.is_a?(Time)
|
9
|
+
(t2 - t).should be_close(0, 2)
|
10
|
+
t2.utc_offset.should == 0 if Sequel.application_timezone == :utc
|
11
|
+
t2.utc_offset.should == t.getlocal.utc_offset if Sequel.application_timezone == :local
|
12
|
+
@db[:t].delete
|
13
|
+
|
14
|
+
dt = DateTime.now
|
15
|
+
Sequel.datetime_class = DateTime
|
16
|
+
@db[:t].insert(dt)
|
17
|
+
dt2 = @db[:t].single_value
|
18
|
+
dt2 = Sequel.database_to_application_timestamp(dt2.to_s) unless dt2.is_a?(DateTime)
|
19
|
+
(dt2 - dt).should be_close(0, 0.00002)
|
20
|
+
dt2.offset.should == 0 if Sequel.application_timezone == :utc
|
21
|
+
dt2.offset.should == dt.offset if Sequel.application_timezone == :local
|
22
|
+
end
|
23
|
+
|
24
|
+
before do
|
25
|
+
@db = INTEGRATION_DB
|
26
|
+
@db.create_table!(:t){DateTime :t}
|
27
|
+
end
|
28
|
+
after do
|
29
|
+
@db.drop_table(:t)
|
30
|
+
Sequel.default_timezone = nil
|
31
|
+
Sequel.datetime_class = Time
|
32
|
+
end
|
33
|
+
|
34
|
+
specify "should support using UTC for database storage and local time for the application" do
|
35
|
+
Sequel.database_timezone = :utc
|
36
|
+
Sequel.application_timezone = :local
|
37
|
+
test_timezone
|
38
|
+
end
|
39
|
+
|
40
|
+
specify "should support using local time for database storage and UTC for the application" do
|
41
|
+
Sequel.database_timezone = :local
|
42
|
+
Sequel.application_timezone = :utc
|
43
|
+
test_timezone
|
44
|
+
end
|
45
|
+
|
46
|
+
specify "should support using UTC for both database storage and for application" do
|
47
|
+
Sequel.default_timezone = :utc
|
48
|
+
test_timezone
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "should support using local time for both database storage and for application" do
|
52
|
+
Sequel.default_timezone = :local
|
53
|
+
test_timezone
|
54
|
+
end
|
55
|
+
end
|