sequel 3.32.0 → 3.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +42 -0
- data/Rakefile +3 -2
- data/doc/migration.rdoc +41 -14
- data/doc/opening_databases.rdoc +2 -0
- data/doc/release_notes/3.29.0.txt +1 -1
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/sharding.rdoc +93 -7
- data/doc/testing.rdoc +1 -1
- data/lib/sequel/adapters/do.rb +1 -0
- data/lib/sequel/adapters/do/mysql.rb +6 -0
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -5
- data/lib/sequel/adapters/mock.rb +10 -5
- data/lib/sequel/adapters/mysql.rb +23 -1
- data/lib/sequel/adapters/mysql2.rb +16 -2
- data/lib/sequel/adapters/postgres.rb +22 -4
- data/lib/sequel/adapters/shared/mysql.rb +51 -10
- data/lib/sequel/adapters/shared/postgres.rb +101 -63
- data/lib/sequel/adapters/shared/sqlite.rb +19 -0
- data/lib/sequel/adapters/sqlite.rb +71 -16
- data/lib/sequel/adapters/swift.rb +1 -0
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +6 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +6 -1
- data/lib/sequel/connection_pool/threaded.rb +12 -11
- data/lib/sequel/database/connecting.rb +2 -0
- data/lib/sequel/database/misc.rb +6 -0
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
- data/lib/sequel/extensions/migration.rb +45 -7
- data/lib/sequel/extensions/server_block.rb +139 -0
- data/lib/sequel/model/associations.rb +9 -9
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +1 -1
- data/lib/sequel/plugins/list.rb +12 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +64 -8
- data/spec/adapters/postgres_spec.rb +139 -78
- data/spec/adapters/sqlite_spec.rb +87 -0
- data/spec/core/connection_pool_spec.rb +14 -0
- data/spec/core/database_spec.rb +5 -0
- data/spec/core/mock_adapter_spec.rb +21 -9
- data/spec/extensions/arbitrary_servers_spec.rb +114 -0
- data/spec/extensions/instance_hooks_spec.rb +19 -0
- data/spec/extensions/list_spec.rb +31 -0
- data/spec/extensions/migration_spec.rb +61 -4
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/files/transaction_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_migrations/002_create_basic.rb +3 -0
- data/spec/files/transactionless_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transactionless_migrations/002_create_basic.rb +4 -0
- data/spec/integration/dataset_test.rb +2 -2
- data/spec/integration/plugin_test.rb +9 -9
- data/spec/integration/schema_test.rb +3 -1
- data/spec/integration/transaction_test.rb +2 -2
- metadata +12 -2
@@ -139,6 +139,93 @@ describe "An SQLite database" do
|
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
|
+
describe "SQLite type conversion" do
|
143
|
+
before do
|
144
|
+
@db = SQLITE_DB
|
145
|
+
@integer_booleans = @db.integer_booleans
|
146
|
+
@db.integer_booleans = true
|
147
|
+
@ds = @db[:items]
|
148
|
+
@db.drop_table(:items) rescue nil
|
149
|
+
end
|
150
|
+
after do
|
151
|
+
@db.integer_booleans = @integer_booleans
|
152
|
+
Sequel.datetime_class = Time
|
153
|
+
@db.drop_table(:items)
|
154
|
+
end
|
155
|
+
|
156
|
+
specify "should handle integers in boolean columns" do
|
157
|
+
@db.create_table(:items){TrueClass :a}
|
158
|
+
@db[:items].insert(false)
|
159
|
+
@db[:items].select_map(:a).should == [false]
|
160
|
+
@db[:items].select_map(:a+:a).should == [0]
|
161
|
+
@db[:items].update(:a=>true)
|
162
|
+
@db[:items].select_map(:a).should == [true]
|
163
|
+
@db[:items].select_map(:a+:a).should == [2]
|
164
|
+
end
|
165
|
+
|
166
|
+
specify "should handle integers/floats/strings/decimals in numeric/decimal columns" do
|
167
|
+
@db.create_table(:items){Numeric :a}
|
168
|
+
@db[:items].insert(100)
|
169
|
+
@db[:items].select_map(:a).should == [BigDecimal.new('100')]
|
170
|
+
@db[:items].get(:a).should be_a_kind_of(BigDecimal)
|
171
|
+
|
172
|
+
@db[:items].update(:a=>100.1)
|
173
|
+
@db[:items].select_map(:a).should == [BigDecimal.new('100.1')]
|
174
|
+
@db[:items].get(:a).should be_a_kind_of(BigDecimal)
|
175
|
+
|
176
|
+
@db[:items].update(:a=>'100.1')
|
177
|
+
@db[:items].select_map(:a).should == [BigDecimal.new('100.1')]
|
178
|
+
@db[:items].get(:a).should be_a_kind_of(BigDecimal)
|
179
|
+
|
180
|
+
@db[:items].update(:a=>BigDecimal.new('100.1'))
|
181
|
+
@db[:items].select_map(:a).should == [BigDecimal.new('100.1')]
|
182
|
+
@db[:items].get(:a).should be_a_kind_of(BigDecimal)
|
183
|
+
end
|
184
|
+
|
185
|
+
specify "should handle integer/float date columns as julian date" do
|
186
|
+
@db.create_table(:items){Date :a}
|
187
|
+
i = 2455979
|
188
|
+
@db[:items].insert(i)
|
189
|
+
@db[:items].first.should == {:a=>Date.jd(i)}
|
190
|
+
@db[:items].update(:a=>2455979.1)
|
191
|
+
@db[:items].first.should == {:a=>Date.jd(i)}
|
192
|
+
end
|
193
|
+
|
194
|
+
specify "should handle integer/float time columns as seconds" do
|
195
|
+
@db.create_table(:items){Time :a, :only_time=>true}
|
196
|
+
@db[:items].insert(3661)
|
197
|
+
@db[:items].first.should == {:a=>Sequel::SQLTime.create(1, 1, 1)}
|
198
|
+
@db[:items].update(:a=>3661.000001)
|
199
|
+
@db[:items].first.should == {:a=>Sequel::SQLTime.create(1, 1, 1, 1)}
|
200
|
+
end
|
201
|
+
|
202
|
+
specify "should handle integer datetime columns as unix timestamp" do
|
203
|
+
@db.create_table(:items){DateTime :a}
|
204
|
+
i = 1329860756
|
205
|
+
@db[:items].insert(i)
|
206
|
+
@db[:items].first.should == {:a=>Time.at(i)}
|
207
|
+
Sequel.datetime_class = DateTime
|
208
|
+
@db[:items].first.should == {:a=>DateTime.strptime(i.to_s, '%s')}
|
209
|
+
end
|
210
|
+
|
211
|
+
specify "should handle float datetime columns as julian date" do
|
212
|
+
@db.create_table(:items){DateTime :a}
|
213
|
+
i = 2455979.5
|
214
|
+
@db[:items].insert(i)
|
215
|
+
@db[:items].first.should == {:a=>Time.at(1329825600)}
|
216
|
+
Sequel.datetime_class = DateTime
|
217
|
+
@db[:items].first.should == {:a=>DateTime.jd(2455979.5)}
|
218
|
+
end
|
219
|
+
|
220
|
+
specify "should handle integer/float blob columns" do
|
221
|
+
@db.create_table(:items){File :a}
|
222
|
+
@db[:items].insert(1)
|
223
|
+
@db[:items].first.should == {:a=>Sequel::SQL::Blob.new('1')}
|
224
|
+
@db[:items].update(:a=>'1.1')
|
225
|
+
@db[:items].first.should == {:a=>Sequel::SQL::Blob.new(1.1.to_s)}
|
226
|
+
end
|
227
|
+
end if SQLITE_DB.adapter_scheme == :sqlite
|
228
|
+
|
142
229
|
describe "An SQLite dataset" do
|
143
230
|
before do
|
144
231
|
@d = SQLITE_DB[:items]
|
@@ -787,6 +787,20 @@ shared_examples_for "All connection pools classes" do
|
|
787
787
|
y.should == 123
|
788
788
|
end
|
789
789
|
|
790
|
+
specify "should have a reentrent hold method" do
|
791
|
+
o = Object.new
|
792
|
+
c = @class.new({}){o}
|
793
|
+
c.hold do |x|
|
794
|
+
x.should == o
|
795
|
+
c.hold do |x1|
|
796
|
+
x1.should == o
|
797
|
+
c.hold do |x2|
|
798
|
+
x2.should == o
|
799
|
+
end
|
800
|
+
end
|
801
|
+
end
|
802
|
+
end
|
803
|
+
|
790
804
|
specify "should have a servers method that returns an array of shard/server symbols" do
|
791
805
|
@class.new({}){123}.servers.should == [:default]
|
792
806
|
end
|
data/spec/core/database_spec.rb
CHANGED
@@ -1396,6 +1396,11 @@ describe "Database#server_opts" do
|
|
1396
1396
|
opts = {:host=>1, :database=>2, :servers=>{:server1=>2}}
|
1397
1397
|
proc{Sequel::Database.new(opts).send(:server_opts, :server1)}.should raise_error(Sequel::Error)
|
1398
1398
|
end
|
1399
|
+
|
1400
|
+
specify "should return the general opts merged with given opts if given opts is a Hash" do
|
1401
|
+
opts = {:host=>1, :database=>2}
|
1402
|
+
Sequel::Database.new(opts).send(:server_opts, :host=>2)[:host].should == 2
|
1403
|
+
end
|
1399
1404
|
end
|
1400
1405
|
|
1401
1406
|
describe "Database#add_servers" do
|
@@ -406,14 +406,26 @@ describe "Sequel Mock Adapter" do
|
|
406
406
|
end
|
407
407
|
|
408
408
|
specify "should be able to load dialects based on the database name" do
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
409
|
+
begin
|
410
|
+
qi = class Sequel::Database; @@quote_identifiers; end
|
411
|
+
ii = class Sequel::Database; @@identifier_input_method; end
|
412
|
+
io = class Sequel::Database; @@identifier_output_method; end
|
413
|
+
Sequel.quote_identifiers = nil
|
414
|
+
class Sequel::Database; @@identifier_input_method=nil; end
|
415
|
+
class Sequel::Database; @@identifier_output_method=nil; end
|
416
|
+
Sequel.mock(:host=>'access').select(Date.new(2011, 12, 13)).sql.should == 'SELECT #2011-12-13#'
|
417
|
+
Sequel.mock(:host=>'db2').select(1).sql.should == 'SELECT 1 FROM "SYSIBM"."SYSDUMMY1"'
|
418
|
+
Sequel.mock(:host=>'firebird')[:a].distinct.limit(1, 2).sql.should == 'SELECT DISTINCT FIRST 1 SKIP 2 * FROM "A"'
|
419
|
+
Sequel.mock(:host=>'informix')[:a].distinct.limit(1, 2).sql.should == 'SELECT SKIP 2 FIRST 1 DISTINCT * FROM A'
|
420
|
+
Sequel.mock(:host=>'mssql')[:a].full_text_search(:b, 'c').sql.should == "SELECT * FROM [A] WHERE (CONTAINS ([B], 'c'))"
|
421
|
+
Sequel.mock(:host=>'mysql')[:a].full_text_search(:b, 'c').sql.should == "SELECT * FROM `a` WHERE (MATCH (`b`) AGAINST ('c'))"
|
422
|
+
Sequel.mock(:host=>'oracle')[:a].limit(1).sql.should == 'SELECT * FROM (SELECT * FROM "A") "T1" WHERE (ROWNUM <= 1)'
|
423
|
+
Sequel.mock(:host=>'postgres')[:a].full_text_search(:b, 'c').sql.should == "SELECT * FROM \"a\" WHERE (to_tsvector('simple', (COALESCE(\"b\", ''))) @@ to_tsquery('simple', 'c'))"
|
424
|
+
Sequel.mock(:host=>'sqlite')[:a___b].sql.should == "SELECT * FROM `a` AS 'b'"
|
425
|
+
ensure
|
426
|
+
Sequel.quote_identifiers = qi
|
427
|
+
Sequel::Database.send(:class_variable_set, :@@identifier_input_method, ii)
|
428
|
+
Sequel::Database.send(:class_variable_set, :@@identifier_output_method, io)
|
429
|
+
end
|
418
430
|
end
|
419
431
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
if RUBY_VERSION >= '1.8.7'
|
4
|
+
describe "arbtirary servers" do
|
5
|
+
before do
|
6
|
+
@db = Sequel.mock(:servers=>{})
|
7
|
+
@db.pool.extend Sequel::ArbitraryServers
|
8
|
+
end
|
9
|
+
|
10
|
+
specify "should allow arbitrary server options using a hash" do
|
11
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
12
|
+
c.opts[:host].should == 'host1'
|
13
|
+
c.opts[:database].should == 'db1'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
specify "should not cache connections to arbitrary servers" do
|
18
|
+
x = nil
|
19
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
20
|
+
x = c
|
21
|
+
end
|
22
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
23
|
+
c2.should_not equal(x)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "should yield same connection correctly when nesting" do
|
28
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
29
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
30
|
+
c2.should equal(c)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
specify "should disconnect when connection is finished" do
|
36
|
+
x, x1 = nil, nil
|
37
|
+
@db.meta_def(:disconnect_connection){|c| x = c}
|
38
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
39
|
+
x1 = c
|
40
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
41
|
+
c2.should equal(c)
|
42
|
+
end
|
43
|
+
x.should equal(nil)
|
44
|
+
end
|
45
|
+
x.should equal(x1)
|
46
|
+
end
|
47
|
+
|
48
|
+
specify "should yield different connection correctly when nesting" do
|
49
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
50
|
+
c.opts[:host].should == 'host1'
|
51
|
+
@db.synchronize(:host=>'host2', :database=>'db1') do |c2|
|
52
|
+
c2.opts[:host].should == 'host2'
|
53
|
+
c2.should_not equal(c)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
specify "should respect multithreaded access" do
|
59
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c|
|
60
|
+
Thread.new do
|
61
|
+
@db.synchronize(:host=>'host1', :database=>'db1') do |c2|
|
62
|
+
c2.should_not equal(c)
|
63
|
+
end
|
64
|
+
end.join
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
specify "should work correctly with server_block plugin" do
|
69
|
+
@db.extend Sequel::ServerBlock
|
70
|
+
@db.with_server(:host=>'host1', :database=>'db1') do
|
71
|
+
@db.synchronize do |c|
|
72
|
+
c.opts[:host].should == 'host1'
|
73
|
+
c.opts[:database].should == 'db1'
|
74
|
+
@db.synchronize do |c2|
|
75
|
+
c2.should equal(c)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
specify "should respect multithreaded access with server block plugin" do
|
83
|
+
@db.extend Sequel::ServerBlock
|
84
|
+
q, q1 = Queue.new, Queue.new
|
85
|
+
|
86
|
+
t = nil
|
87
|
+
@db[:t].all
|
88
|
+
@db.with_server(:host=>'a') do
|
89
|
+
@db[:t].all
|
90
|
+
t = Thread.new do
|
91
|
+
@db[:t].all
|
92
|
+
@db.with_server(:host=>'c') do
|
93
|
+
@db[:t].all
|
94
|
+
@db.with_server(:host=>'d'){@db[:t].all}
|
95
|
+
q.push nil
|
96
|
+
q1.pop
|
97
|
+
@db[:t].all
|
98
|
+
end
|
99
|
+
@db[:t].all
|
100
|
+
end
|
101
|
+
q.pop
|
102
|
+
@db.with_server(:host=>'b'){@db[:t].all}
|
103
|
+
@db[:t].all
|
104
|
+
end
|
105
|
+
@db[:t].all
|
106
|
+
q1.push nil
|
107
|
+
t.join
|
108
|
+
@db.sqls.should == ['SELECT * FROM t', 'SELECT * FROM t -- {:host=>"a"}', 'SELECT * FROM t', 'SELECT * FROM t -- {:host=>"c"}', 'SELECT * FROM t -- {:host=>"d"}',
|
109
|
+
'SELECT * FROM t -- {:host=>"b"}', 'SELECT * FROM t -- {:host=>"a"}', 'SELECT * FROM t', 'SELECT * FROM t -- {:host=>"c"}', 'SELECT * FROM t']
|
110
|
+
end
|
111
|
+
end
|
112
|
+
else
|
113
|
+
skip_warn "arbitrary_servers plugin: only works on ruby 1.8.7+"
|
114
|
+
end
|
@@ -229,4 +229,23 @@ describe "InstanceHooks plugin with transactions" do
|
|
229
229
|
@or.destroy.should be_nil
|
230
230
|
@db.sqls.should == ['BEGIN', "DELETE FROM items WHERE (id = 1)", 'ad', 'ROLLBACK', 'adr1', 'adr2']
|
231
231
|
end
|
232
|
+
|
233
|
+
it "should have *_hook methods return self "do
|
234
|
+
@o.before_destroy_hook{r 1}.should equal(@o)
|
235
|
+
@o.before_validation_hook{r 1}.should equal(@o)
|
236
|
+
@o.before_save_hook{r 1}.should equal(@o)
|
237
|
+
@o.before_update_hook{r 1}.should equal(@o)
|
238
|
+
@o.before_create_hook{r 1}.should equal(@o)
|
239
|
+
|
240
|
+
@o.after_destroy_hook{r 1}.should equal(@o)
|
241
|
+
@o.after_validation_hook{r 1}.should equal(@o)
|
242
|
+
@o.after_save_hook{r 1}.should equal(@o)
|
243
|
+
@o.after_update_hook{r 1}.should equal(@o)
|
244
|
+
@o.after_create_hook{r 1}.should equal(@o)
|
245
|
+
@o.after_commit_hook{r 1}.should equal(@o)
|
246
|
+
@o.after_rollback_hook{r 1}.should equal(@o)
|
247
|
+
@o.after_destroy_commit_hook{r 1}.should equal(@o)
|
248
|
+
@o.after_destroy_rollback_hook{r 1}.should equal(@o)
|
249
|
+
end
|
250
|
+
|
232
251
|
end
|
@@ -75,6 +75,37 @@ describe "List plugin" do
|
|
75
75
|
"SELECT * FROM items WHERE ((scope_id = 5) AND (position = 20)) ORDER BY scope_id, position LIMIT 1"]
|
76
76
|
end
|
77
77
|
|
78
|
+
it "should have position field set to max+1 when creating if not already set" do
|
79
|
+
@c.dataset._fetch = [[{:pos=>nil}], [{:id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :position=>2}]]
|
80
|
+
@c.dataset.autoid = 1
|
81
|
+
@c.create.values.should == {:id=>1, :position=>1}
|
82
|
+
@c.create.values.should == {:id=>2, :position=>2}
|
83
|
+
@db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
|
84
|
+
"INSERT INTO items (position) VALUES (1)",
|
85
|
+
"SELECT * FROM items WHERE (id = 1) ORDER BY position LIMIT 1",
|
86
|
+
"SELECT max(position) FROM items LIMIT 1",
|
87
|
+
"INSERT INTO items (position) VALUES (2)",
|
88
|
+
"SELECT * FROM items WHERE (id = 2) ORDER BY position LIMIT 1"]
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should have position field set to max+1 in scope when creating if not already set" do
|
92
|
+
@sc.dataset._fetch = [[{:pos=>nil}], [{:id=>1, :scope_id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :scope_id=>1, :position=>2}], [{:pos=>nil}], [{:id=>3, :scope_id=>2, :position=>1}]]
|
93
|
+
@sc.dataset.autoid = 1
|
94
|
+
@sc.create(:scope_id=>1).values.should == {:id=>1, :scope_id=>1, :position=>1}
|
95
|
+
@sc.create(:scope_id=>1).values.should == {:id=>2, :scope_id=>1, :position=>2}
|
96
|
+
@sc.create(:scope_id=>2).values.should == {:id=>3, :scope_id=>2, :position=>1}
|
97
|
+
sqls = @db.sqls
|
98
|
+
sqls.slice!(7).should =~ /INSERT INTO items \((scope_id|position), (scope_id|position)\) VALUES \([12], [12]\)/
|
99
|
+
sqls.slice!(4).should =~ /INSERT INTO items \((scope_id|position), (scope_id|position)\) VALUES \([12], [12]\)/
|
100
|
+
sqls.slice!(1).should =~ /INSERT INTO items \((scope_id|position), (scope_id|position)\) VALUES \(1, 1\)/
|
101
|
+
sqls.should == ["SELECT max(position) FROM items WHERE (scope_id = 1) LIMIT 1",
|
102
|
+
"SELECT * FROM items WHERE (id = 1) ORDER BY scope_id, position LIMIT 1",
|
103
|
+
"SELECT max(position) FROM items WHERE (scope_id = 1) LIMIT 1",
|
104
|
+
"SELECT * FROM items WHERE (id = 2) ORDER BY scope_id, position LIMIT 1",
|
105
|
+
"SELECT max(position) FROM items WHERE (scope_id = 2) LIMIT 1",
|
106
|
+
"SELECT * FROM items WHERE (id = 3) ORDER BY scope_id, position LIMIT 1"]
|
107
|
+
end
|
108
|
+
|
78
109
|
it "should have last_position return the last position in the list" do
|
79
110
|
@c.dataset._fetch = {:max=>10}
|
80
111
|
@o.last_position.should == 10
|
@@ -311,6 +311,30 @@ describe "Sequel::IntegerMigrator" do
|
|
311
311
|
Sequel::Migrator.apply(@db, @dirname, 0).should == 0
|
312
312
|
Sequel::Migrator.apply(@db, @dirname).should == 3
|
313
313
|
end
|
314
|
+
|
315
|
+
specify "should use IntegerMigrator if IntegerMigrator.apply called, even for timestamped migration directory" do
|
316
|
+
proc{Sequel::IntegerMigrator.apply(@db, "spec/files/timestamped_migrations")}.should raise_error(Sequel::Migrator::Error)
|
317
|
+
end
|
318
|
+
|
319
|
+
specify "should use transactions by default" do
|
320
|
+
Sequel::Migrator.apply(@db, "spec/files/transaction_migrations")
|
321
|
+
@db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
|
322
|
+
end
|
323
|
+
|
324
|
+
specify "should not use transactions for migrations that disable it" do
|
325
|
+
Sequel::Migrator.apply(@db, "spec/files/transactionless_migrations")
|
326
|
+
@db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
|
327
|
+
end
|
328
|
+
|
329
|
+
specify "should force transactions if enabled in the migrator" do
|
330
|
+
Sequel::Migrator.run(@db, "spec/files/transactionless_migrations", :use_transactions=>true)
|
331
|
+
@db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
|
332
|
+
end
|
333
|
+
|
334
|
+
specify "should not use transactions if disabled in the migrator" do
|
335
|
+
Sequel::Migrator.run(@db, "spec/files/transaction_migrations", :use_transactions=>false)
|
336
|
+
@db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
|
337
|
+
end
|
314
338
|
end
|
315
339
|
|
316
340
|
describe "Sequel::TimestampMigrator" do
|
@@ -322,6 +346,7 @@ describe "Sequel::TimestampMigrator" do
|
|
322
346
|
define_method(:sequel_migration_version=){|v| sequel_migration_version = v}
|
323
347
|
|
324
348
|
def columns
|
349
|
+
super
|
325
350
|
case opts[:from].first
|
326
351
|
when :schema_info, 'schema_info'
|
327
352
|
[:version]
|
@@ -333,6 +358,7 @@ describe "Sequel::TimestampMigrator" do
|
|
333
358
|
end
|
334
359
|
|
335
360
|
def fetch_rows(sql)
|
361
|
+
super
|
336
362
|
case opts[:from].first
|
337
363
|
when :schema_info, 'schema_info'
|
338
364
|
yield({:version=>sequel_migration_version})
|
@@ -344,6 +370,7 @@ describe "Sequel::TimestampMigrator" do
|
|
344
370
|
end
|
345
371
|
|
346
372
|
def insert(h={})
|
373
|
+
super
|
347
374
|
case opts[:from].first
|
348
375
|
when :schema_info, 'schema_info'
|
349
376
|
self.sequel_migration_version = h.values.first
|
@@ -353,6 +380,7 @@ describe "Sequel::TimestampMigrator" do
|
|
353
380
|
end
|
354
381
|
|
355
382
|
def update(h={})
|
383
|
+
super
|
356
384
|
case opts[:from].first
|
357
385
|
when :schema_info, 'schema_info'
|
358
386
|
self.sequel_migration_version = h.values.first
|
@@ -360,6 +388,7 @@ describe "Sequel::TimestampMigrator" do
|
|
360
388
|
end
|
361
389
|
|
362
390
|
def delete
|
391
|
+
super
|
363
392
|
case opts[:from].first
|
364
393
|
when :schema_migrations, :sm, 'schema_migrations', 'sm'
|
365
394
|
self.class::FILES.delete(opts[:where].args.last)
|
@@ -367,11 +396,14 @@ describe "Sequel::TimestampMigrator" do
|
|
367
396
|
end
|
368
397
|
end
|
369
398
|
dbc = Class.new(Sequel::Mock::Database) do
|
370
|
-
|
399
|
+
self::Tables = tables= {}
|
371
400
|
define_method(:dataset){|*a| dsc.new(self, *a)}
|
372
|
-
|
373
|
-
|
374
|
-
|
401
|
+
def create_table(name, *args, &block)
|
402
|
+
super
|
403
|
+
self.class::Tables[name.to_sym] = true
|
404
|
+
end
|
405
|
+
define_method(:drop_table){|*names| super(*names); names.each{|n| tables.delete(n.to_sym)}}
|
406
|
+
define_method(:table_exists?){|name| super(name); tables.has_key?(name.to_sym)}
|
375
407
|
end
|
376
408
|
@db = dbc.new
|
377
409
|
@m = Sequel::Migrator
|
@@ -559,4 +591,29 @@ describe "Sequel::TimestampMigrator" do
|
|
559
591
|
@m.apply(@db, @dir, 0).should == nil
|
560
592
|
@m.apply(@db, @dir).should == nil
|
561
593
|
end
|
594
|
+
|
595
|
+
specify "should use TimestampMigrator if TimestampMigrator.apply is called even for integer migrations directory" do
|
596
|
+
Sequel::TimestampMigrator.apply(@db, "spec/files/integer_migrations")
|
597
|
+
@db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm1111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_sessions.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm2222 (smc2 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_nodes.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm3333 (smc3 integer)", "INSERT INTO schema_migrations (filename) VALUES ('003_3_create_users.rb')", "COMMIT"]
|
598
|
+
end
|
599
|
+
|
600
|
+
specify "should use transactions by default" do
|
601
|
+
Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_migrations")
|
602
|
+
@db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
|
603
|
+
end
|
604
|
+
|
605
|
+
specify "should not use transactions for migrations that disable it" do
|
606
|
+
Sequel::TimestampMigrator.apply(@db, "spec/files/transactionless_migrations")
|
607
|
+
@db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
|
608
|
+
end
|
609
|
+
|
610
|
+
specify "should force transactions if enabled by the migrator" do
|
611
|
+
Sequel::TimestampMigrator.run(@db, "spec/files/transactionless_migrations", :use_transactions=>true)
|
612
|
+
@db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
|
613
|
+
end
|
614
|
+
|
615
|
+
specify "should not use transactions if disabled in the migrator" do
|
616
|
+
Sequel::TimestampMigrator.run(@db, "spec/files/transaction_migrations", :use_transactions=>false)
|
617
|
+
@db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
|
618
|
+
end
|
562
619
|
end
|