sequel 5.2.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +32 -0
  3. data/bin/sequel +5 -6
  4. data/doc/release_notes/5.3.0.txt +121 -0
  5. data/doc/schema_modification.rdoc +15 -4
  6. data/doc/testing.rdoc +1 -0
  7. data/lib/sequel/adapters/jdbc.rb +4 -0
  8. data/lib/sequel/adapters/jdbc/postgresql.rb +15 -0
  9. data/lib/sequel/adapters/oracle.rb +2 -1
  10. data/lib/sequel/adapters/postgres.rb +4 -0
  11. data/lib/sequel/adapters/shared/mysql.rb +38 -3
  12. data/lib/sequel/adapters/shared/postgres.rb +15 -6
  13. data/lib/sequel/adapters/shared/sqlite.rb +10 -0
  14. data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -0
  15. data/lib/sequel/connection_pool.rb +12 -0
  16. data/lib/sequel/database/misc.rb +13 -0
  17. data/lib/sequel/dataset/dataset_module.rb +1 -1
  18. data/lib/sequel/dataset/features.rb +5 -0
  19. data/lib/sequel/dataset/query.rb +20 -6
  20. data/lib/sequel/dataset/sql.rb +3 -0
  21. data/lib/sequel/extensions/pg_extended_date_support.rb +15 -0
  22. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  23. data/lib/sequel/model/associations.rb +1 -0
  24. data/lib/sequel/model/base.rb +4 -11
  25. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  26. data/lib/sequel/version.rb +1 -1
  27. data/spec/adapters/postgres_spec.rb +5 -34
  28. data/spec/core/database_spec.rb +32 -0
  29. data/spec/core/dataset_spec.rb +19 -0
  30. data/spec/core/mock_adapter_spec.rb +65 -0
  31. data/spec/extensions/association_pks_spec.rb +26 -33
  32. data/spec/extensions/class_table_inheritance_spec.rb +18 -32
  33. data/spec/extensions/composition_spec.rb +7 -23
  34. data/spec/extensions/list_spec.rb +4 -5
  35. data/spec/extensions/many_through_many_spec.rb +24 -32
  36. data/spec/extensions/optimistic_locking_spec.rb +1 -1
  37. data/spec/extensions/pg_array_associations_spec.rb +18 -25
  38. data/spec/extensions/pg_extended_date_support_spec.rb +13 -0
  39. data/spec/extensions/pg_hstore_spec.rb +2 -2
  40. data/spec/extensions/prepared_statements_safe_spec.rb +6 -6
  41. data/spec/extensions/pretty_table_spec.rb +39 -8
  42. data/spec/extensions/rcte_tree_spec.rb +22 -33
  43. data/spec/extensions/schema_dumper_spec.rb +42 -31
  44. data/spec/extensions/serialization_spec.rb +3 -3
  45. data/spec/extensions/synchronize_sql_spec.rb +124 -0
  46. data/spec/extensions/timestamps_spec.rb +2 -4
  47. data/spec/extensions/update_or_create_spec.rb +11 -15
  48. data/spec/extensions/uuid_spec.rb +2 -3
  49. data/spec/extensions/xml_serializer_spec.rb +5 -10
  50. data/spec/integration/database_test.rb +1 -1
  51. data/spec/integration/dataset_test.rb +7 -0
  52. data/spec/integration/plugin_test.rb +1 -1
  53. data/spec/integration/schema_test.rb +3 -3
  54. data/spec/integration/spec_helper.rb +4 -0
  55. data/spec/model/base_spec.rb +6 -0
  56. data/spec/model/eager_loading_spec.rb +31 -6
  57. data/spec/model/model_spec.rb +9 -19
  58. data/spec/model/record_spec.rb +4 -8
  59. metadata +6 -2
@@ -105,7 +105,7 @@ describe "optimistic_locking plugin" do
105
105
  @c.db.sqls
106
106
  p2.update(:name=>'Bob')
107
107
  end
108
- @c.db.sqls.first.must_match(/UPDATE people SET (name = 'Bob', lock_version = 4|lock_version = 4, name = 'Bob') WHERE \(\(id = 1\) AND \(lock_version = 3\)\)/)
108
+ @c.db.sqls.must_equal ["UPDATE people SET name = 'Bob', lock_version = 4 WHERE ((id = 1) AND (lock_version = 3))"]
109
109
  end
110
110
 
111
111
  it "should increment the lock column when #modified! even if no columns are changed" do
@@ -248,9 +248,8 @@ describe Sequel::Model, "pg_array_associations" do
248
248
  it "should eagerly load correctly" do
249
249
  a = @c1.eager(:tags).all
250
250
  a.must_equal [@o1]
251
- sqls = @db.sqls
252
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
253
- sqls.must_equal ["SELECT * FROM artists"]
251
+ @db.sqls.must_equal ["SELECT * FROM artists",
252
+ 'SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))']
254
253
  a.first.tags.must_equal [@o2]
255
254
  @db.sqls.must_equal []
256
255
 
@@ -268,9 +267,8 @@ describe Sequel::Model, "pg_array_associations" do
268
267
 
269
268
  a = @c1.eager(:tags).all
270
269
  a.must_equal [@o1]
271
- sqls = @db.sqls
272
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(\(tags\.id \* 3\) IN \([369], [369], [369]\)\)/)
273
- sqls.must_equal ["SELECT * FROM artists"]
270
+ @db.sqls.must_equal ["SELECT * FROM artists",
271
+ 'SELECT * FROM tags WHERE ((tags.id * 3) IN (3, 6, 9))']
274
272
  a.first.tags.must_equal [@o2]
275
273
  @db.sqls.must_equal []
276
274
 
@@ -284,9 +282,9 @@ describe Sequel::Model, "pg_array_associations" do
284
282
  it "should allow cascading of eager loading for associations of associated models" do
285
283
  a = @c1.eager(:tags=>:artists).all
286
284
  a.must_equal [@o1]
287
- sqls = @db.sqls
288
- sqls.slice!(1).must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
289
- sqls.must_equal ['SELECT * FROM artists', "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
285
+ @db.sqls.must_equal ["SELECT * FROM artists",
286
+ 'SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))',
287
+ "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
290
288
  a.first.tags.must_equal [@o2]
291
289
  a.first.tags.first.artists.must_equal [@o1]
292
290
  @db.sqls.must_equal []
@@ -302,9 +300,8 @@ describe Sequel::Model, "pg_array_associations" do
302
300
  @db.sqls.must_equal []
303
301
 
304
302
  @o2.artists2.must_equal [@o1]
305
- sqls = @db.sqls
306
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
307
- sqls.must_equal ["SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[2]::integer[])"]
303
+ @db.sqls.must_equal ["SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[2]::integer[])",
304
+ 'SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))']
308
305
  @o2.artists2.first.tags.must_equal [@o2]
309
306
  @db.sqls.must_equal []
310
307
  end
@@ -318,7 +315,7 @@ describe Sequel::Model, "pg_array_associations" do
318
315
  @db.sqls
319
316
 
320
317
  @o1.tags2.must_equal [@o2]
321
- @db.sqls.first.must_match(/SELECT tags\.id, artists\.id AS artists_id, artists\.tag_ids FROM tags LEFT OUTER JOIN artists ON \(artists.tag_ids @> ARRAY\[tags.id\]\) WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
318
+ @db.sqls.must_equal ['SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id]) WHERE (tags.id IN (1, 2, 3))']
322
319
  @o1.tags2.first.artists.must_equal [@o1]
323
320
  @db.sqls.must_equal []
324
321
 
@@ -332,9 +329,8 @@ describe Sequel::Model, "pg_array_associations" do
332
329
  @db.sqls
333
330
 
334
331
  a = @c1.eager(:tags2).all
335
- sqls = @db.sqls
336
- sqls.pop.must_match(/SELECT tags\.id, artists\.id AS artists_id, artists\.tag_ids FROM tags LEFT OUTER JOIN artists ON \(artists.tag_ids @> ARRAY\[tags.id\]\) WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
337
- sqls.must_equal ["SELECT * FROM artists"]
332
+ @db.sqls.must_equal ["SELECT * FROM artists",
333
+ 'SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id]) WHERE (tags.id IN (1, 2, 3))']
338
334
  a.must_equal [@o1]
339
335
  a.first.tags2.must_equal [@o2]
340
336
  a.first.tags2.first.artists.must_equal [@o1]
@@ -359,27 +355,24 @@ describe Sequel::Model, "pg_array_associations" do
359
355
  @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>2
360
356
  a = @c1.eager(:tags).all
361
357
  a.must_equal [@o1]
362
- sqls = @db.sqls
363
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
364
- sqls.must_equal ["SELECT * FROM artists"]
358
+ @db.sqls.must_equal ["SELECT * FROM artists",
359
+ 'SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))']
365
360
  a.first.tags.must_equal [@c2.load(:id=>1), @c2.load(:id=>2)]
366
361
  @db.sqls.must_equal []
367
362
 
368
363
  @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>[1, 1]
369
364
  a = @c1.eager(:tags).all
370
365
  a.must_equal [@o1]
371
- sqls = @db.sqls
372
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
373
- sqls.must_equal ["SELECT * FROM artists"]
366
+ @db.sqls.must_equal ["SELECT * FROM artists",
367
+ 'SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))']
374
368
  a.first.tags.must_equal [@c2.load(:id=>2)]
375
369
  @db.sqls.must_equal []
376
370
 
377
371
  @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>[nil, 1]
378
372
  a = @c1.eager(:tags).all
379
373
  a.must_equal [@o1]
380
- sqls = @db.sqls
381
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
382
- sqls.must_equal ["SELECT * FROM artists"]
374
+ @db.sqls.must_equal ["SELECT * FROM artists",
375
+ 'SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))']
383
376
  a.first.tags.must_equal [@c2.load(:id=>2), @c2.load(:id=>3)]
384
377
  @db.sqls.length.must_equal 0
385
378
 
@@ -49,6 +49,14 @@ describe "pg_extended_date_support extension" do
49
49
  t.(ni).must_equal ni
50
50
  end
51
51
 
52
+ [:date, 'date'].each do |v|
53
+ @db.convert_infinite_timestamps = v
54
+ d.(pi).must_equal Date::Infinity.new
55
+ t.(pi).must_equal Date::Infinity.new
56
+ d.(ni).must_equal -Date::Infinity.new
57
+ t.(ni).must_equal -Date::Infinity.new
58
+ end
59
+
52
60
  [:float, 'float', 't', true].each do |v|
53
61
  @db.convert_infinite_timestamps = v
54
62
  d.(pi).must_equal 1.0/0.0
@@ -92,6 +100,11 @@ describe "pg_extended_date_support extension" do
92
100
  @db.conversion_procs[1114].call("1200-02-15 14:13:20-00:00:00").must_equal DateTime.new(1200, 2, 15, 14, 13, 20)
93
101
  end
94
102
 
103
+ it "should format Date::Infinity values" do
104
+ @db.literal(Date::Infinity.new).must_equal "'infinity'"
105
+ @db.literal(-Date::Infinity.new).must_equal "'-infinity'"
106
+ end
107
+
95
108
  it "should format BC dates" do
96
109
  @db.literal(Date.new(-1091, 10, 20)).must_equal "'1092-10-20 BC'"
97
110
  @db.literal(Date.new(1092, 10, 20)).must_equal "'1092-10-20'"
@@ -32,7 +32,7 @@ describe "pg_hstore extension" do
32
32
  @db.literal(Sequel.hstore("c"=>nil)).must_equal '\'"c"=>NULL\'::hstore'
33
33
  @db.literal(Sequel.hstore("c"=>'NULL')).must_equal '\'"c"=>"NULL"\'::hstore'
34
34
  @db.literal(Sequel.hstore('c'=>'\ "\'=>')).must_equal '\'"c"=>"\\\\ \\"\'\'=>"\'::hstore'
35
- ['\'"a"=>"b","c"=>"d"\'::hstore', '\'"c"=>"d","a"=>"b"\'::hstore'].must_include(@db.literal(Sequel.hstore("a"=>"b","c"=>"d")))
35
+ @db.literal(Sequel.hstore("a"=>"b","c"=>"d")).must_equal '\'"a"=>"b","c"=>"d"\'::hstore'
36
36
  end
37
37
 
38
38
  it "should register conversion proc correctly" do
@@ -178,7 +178,7 @@ describe "pg_hstore extension" do
178
178
  @db.bound_variable_arg(Sequel.hstore('1'=>nil), nil).must_equal '"1"=>NULL'
179
179
  @db.bound_variable_arg(Sequel.hstore('1'=>"NULL"), nil).must_equal '"1"=>"NULL"'
180
180
  @db.bound_variable_arg(Sequel.hstore('1'=>"'\\ \"=>"), nil).must_equal '"1"=>"\'\\\\ \\"=>"'
181
- ['"a"=>"b","c"=>"d"', '"c"=>"d","a"=>"b"'].must_include(@db.bound_variable_arg(Sequel.hstore("a"=>"b","c"=>"d"), nil))
181
+ @db.bound_variable_arg(Sequel.hstore("a"=>"b","c"=>"d"), nil).must_equal '"a"=>"b","c"=>"d"'
182
182
  end
183
183
 
184
184
  it "should parse hstore type from the schema correctly" do
@@ -23,30 +23,30 @@ describe "prepared_statements_safe plugin" do
23
23
 
24
24
  it "should set default values when creating" do
25
25
  @c.create
26
- @db.sqls.first.must_match(/INSERT INTO people \((i|name), (i|name)\) VALUES \(NULL, NULL\)/)
26
+ @db.sqls.must_equal ['INSERT INTO people (i, name) VALUES (NULL, NULL)', "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
27
27
  @c.create(:name=>'foo')
28
- @db.sqls.first.must_match(/INSERT INTO people \((i|name), (i|name)\) VALUES \((NULL|'foo'), (NULL|'foo')\)/)
28
+ @db.sqls.must_equal ["INSERT INTO people (i, name) VALUES (NULL, 'foo')", "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
29
29
  @c.create(:name=>'foo', :i=>2)
30
- @db.sqls.first.must_match(/INSERT INTO people \((i|name), (i|name)\) VALUES \((2|'foo'), (2|'foo')\)/)
30
+ @db.sqls.must_equal ["INSERT INTO people (i, name) VALUES (2, 'foo')", "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
31
31
  end
32
32
 
33
33
  it "should use database default values" do
34
34
  @c.instance_variable_set(:@db_schema, {:i=>{:ruby_default=>2}, :name=>{:ruby_default=>'foo'}, :id=>{:primary_key=>true}})
35
35
  c = Class.new(@c)
36
36
  c.create
37
- @db.sqls.first.must_match(/INSERT INTO people \((i|name), (i|name)\) VALUES \((2|'foo'), (2|'foo')\)/)
37
+ @db.sqls.must_equal ["INSERT INTO people (i, name) VALUES (2, 'foo')", "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
38
38
  end
39
39
 
40
40
  it "should not set defaults for unparseable dataset default values" do
41
41
  @c.instance_variable_set(:@db_schema, {:i=>{:default=>'f(x)'}, :name=>{:ruby_default=>'foo'}, :id=>{:primary_key=>true}})
42
42
  c = Class.new(@c)
43
43
  c.create
44
- @db.sqls.first.must_equal "INSERT INTO people (name) VALUES ('foo')"
44
+ @db.sqls.must_equal ["INSERT INTO people (name) VALUES ('foo')", "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
45
45
  end
46
46
 
47
47
  it "should save all fields when updating" do
48
48
  @p.update(:i=>3)
49
- @db.sqls.first.must_match(/UPDATE people SET (name = 'foo'|i = 3), (name = 'foo'|i = 3) WHERE \(id = 1\)/)
49
+ @db.sqls.must_equal ["UPDATE people SET name = 'foo', i = 3 WHERE (id = 1)"]
50
50
  end
51
51
 
52
52
  it "should work with abstract classes" do
@@ -60,11 +60,23 @@ describe "PrettyTable" do
60
60
  it "should infer the columns if not given" do
61
61
  Sequel::PrettyTable.print(@data1)
62
62
  @output.rewind
63
- @output.read.must_match(/\n(\|x\|y\|)|(\|y\|x\|)\n/)
63
+ @output.read.must_equal(<<OUTPUT)
64
+ +-+-+
65
+ |x|y|
66
+ +-+-+
67
+ |3|4|
68
+ +-+-+
69
+ OUTPUT
64
70
  end
65
71
 
66
72
  it "should have #string return the string without printing" do
67
- Sequel::PrettyTable.string(@data1).must_match(/\n(\|x\|y\|)|(\|y\|x\|)\n/)
73
+ Sequel::PrettyTable.string(@data1).must_equal((<<OUTPUT).chomp)
74
+ +-+-+
75
+ |x|y|
76
+ +-+-+
77
+ |3|4|
78
+ +-+-+
79
+ OUTPUT
68
80
  @output.rewind
69
81
  @output.read.must_equal ''
70
82
  end
@@ -72,21 +84,40 @@ describe "PrettyTable" do
72
84
  it "should calculate the maximum width of each column correctly" do
73
85
  Sequel::PrettyTable.print(@data2, [:a, :b])
74
86
  @output.rewind
75
- @output.read.must_equal \
76
- "+--+----+\n|a |b |\n+--+----+\n|23| 45|\n|45|2377|\n+--+----+\n"
87
+ @output.read.must_equal(<<OUTPUT)
88
+ +--+----+
89
+ |a |b |
90
+ +--+----+
91
+ |23| 45|
92
+ |45|2377|
93
+ +--+----+
94
+ OUTPUT
77
95
  end
78
96
 
79
97
  it "should also take header width into account" do
80
98
  Sequel::PrettyTable.print(@data3, [:aaa, :bb, :c])
81
99
  @output.rewind
82
- @output.read.must_equal \
83
- "+---+--+---+\n|aaa|bb|c |\n+---+--+---+\n| 1| | |\n| | 2| |\n| | |3.1|\n+---+--+---+\n"
100
+ @output.read.must_equal(<<OUTPUT)
101
+ +---+--+---+
102
+ |aaa|bb|c |
103
+ +---+--+---+
104
+ | 1| | |
105
+ | | 2| |
106
+ | | |3.1|
107
+ +---+--+---+
108
+ OUTPUT
84
109
  end
85
110
 
86
111
  it "should print only the specified columns" do
87
112
  Sequel::PrettyTable.print(@data2, [:a])
88
113
  @output.rewind
89
- @output.read.must_equal \
90
- "+--+\n|a |\n+--+\n|23|\n|45|\n+--+\n"
114
+ @output.read.must_equal(<<OUTPUT)
115
+ +--+
116
+ |a |
117
+ +--+
118
+ |23|
119
+ |45|
120
+ +--+
121
+ OUTPUT
91
122
  end
92
123
  end
@@ -121,9 +121,8 @@ describe Sequel::Model, "rcte_tree" do
121
121
  {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>1}, {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>2},
122
122
  {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>2}, {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>1}]])
123
123
  os = @ds.eager(:ancestors).all
124
- sqls = @db.sqls
125
- sqls.first.must_equal "SELECT * FROM nodes"
126
- sqls.last.must_match(/WITH t AS \(SELECT id AS x_root_x, nodes\.\* FROM nodes WHERE \(id IN \([12], [12]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.parent_id = nodes\.id\)\) SELECT \* FROM t AS nodes/)
124
+ @db.sqls.must_equal ["SELECT * FROM nodes",
125
+ 'WITH t AS (SELECT id AS x_root_x, nodes.* FROM nodes WHERE (id IN (1, 2)) UNION ALL SELECT t.x_root_x, nodes.* FROM nodes INNER JOIN t ON (t.parent_id = nodes.id)) SELECT * FROM t AS nodes']
127
126
  os.must_equal [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D'), @c.load(:id=>9, :parent_id=>nil, :name=>'E')]
128
127
  os.map{|o| o.ancestors}.must_equal [[@c.load(:id=>1, :name=>'00', :parent_id=>8), @c.load(:id=>8, :name=>'?', :parent_id=>nil)],
129
128
  [@c.load(:id=>2, :name=>'AA', :parent_id=>1), @c.load(:id=>1, :name=>'00', :parent_id=>8), @c.load(:id=>8, :name=>'?', :parent_id=>nil)],
@@ -143,9 +142,8 @@ describe Sequel::Model, "rcte_tree" do
143
142
  {:i=>1, :name=>'00', :pi=>8, :kal=>1}, {:i=>1, :name=>'00', :pi=>8, :kal=>2},
144
143
  {:i=>8, :name=>'?', :pi=>nil, :kal=>2}, {:i=>8, :name=>'?', :pi=>nil, :kal=>1}]])
145
144
  os = @ds.eager(:as).all
146
- sqls = @db.sqls
147
- sqls.first.must_equal "SELECT * FROM nodes"
148
- sqls.last.must_match(/WITH cte AS \(SELECT i AS kal, nodes\.\* FROM nodes WHERE \(i IN \([12], [12]\)\) UNION ALL SELECT cte\.kal, nodes\.\* FROM nodes INNER JOIN cte ON \(cte\.pi = nodes\.i\)\) SELECT \* FROM cte/)
145
+ @db.sqls.must_equal ["SELECT * FROM nodes",
146
+ 'WITH cte AS (SELECT i AS kal, nodes.* FROM nodes WHERE (i IN (1, 2)) UNION ALL SELECT cte.kal, nodes.* FROM nodes INNER JOIN cte ON (cte.pi = nodes.i)) SELECT * FROM cte AS nodes']
149
147
  os.must_equal [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D'), @c.load(:i=>9, :pi=>nil, :name=>'E')]
150
148
  os.map{|o| o.as}.must_equal [[@c.load(:i=>1, :name=>'00', :pi=>8), @c.load(:i=>8, :name=>'?', :pi=>nil)],
151
149
  [@c.load(:i=>2, :name=>'AA', :pi=>1), @c.load(:i=>1, :name=>'00', :pi=>8), @c.load(:i=>8, :name=>'?', :pi=>nil)],
@@ -164,9 +162,8 @@ describe Sequel::Model, "rcte_tree" do
164
162
  {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>1}, {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>2},
165
163
  {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>2}, {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>1}]])
166
164
  @ds.eager(:ancestors).all
167
- sqls = @db.sqls
168
- sqls.first.must_equal "SELECT * FROM nodes"
169
- sqls.last.must_match(/WITH t AS \(SELECT id AS x_root_x, nodes\.\* FROM nodes WHERE \(\(id IN \([12], [12]\)\) AND \(i = 1\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.parent_id = nodes\.id\) WHERE \(i = 1\)\) SELECT \* FROM t AS nodes WHERE \(i = 1\)/)
165
+ @db.sqls.must_equal ["SELECT * FROM nodes",
166
+ 'WITH t AS (SELECT id AS x_root_x, nodes.* FROM nodes WHERE ((id IN (1, 2)) AND (i = 1)) UNION ALL SELECT t.x_root_x, nodes.* FROM nodes INNER JOIN t ON (t.parent_id = nodes.id) WHERE (i = 1)) SELECT * FROM t AS nodes WHERE (i = 1)']
170
167
  end
171
168
 
172
169
  it "should eagerly load descendants" do
@@ -176,9 +173,8 @@ describe Sequel::Model, "rcte_tree" do
176
173
  {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2},
177
174
  {:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7}]])
178
175
  os = @ds.eager(:descendants).all
179
- sqls = @db.sqls
180
- sqls.first.must_equal "SELECT * FROM nodes"
181
- sqls.last.must_match(/WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\* FROM nodes WHERE \(parent_id IN \([267], [267], [267]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\)\) SELECT \* FROM t AS nodes/)
176
+ @db.sqls.must_equal ["SELECT * FROM nodes",
177
+ 'WITH t AS (SELECT parent_id AS x_root_x, nodes.* FROM nodes WHERE (parent_id IN (2, 6, 7)) UNION ALL SELECT t.x_root_x, nodes.* FROM nodes INNER JOIN t ON (t.id = nodes.parent_id)) SELECT * FROM t AS nodes']
182
178
  os.must_equal [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D')]
183
179
  os.map{|o| o.descendants}.must_equal [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E'), @c.load(:id=>3, :name=>'00', :parent_id=>6)],
184
180
  [@c.load(:id=>3, :name=>'00', :parent_id=>6)],
@@ -198,9 +194,8 @@ describe Sequel::Model, "rcte_tree" do
198
194
  {:i=>3, :name=>'00', :pi=>6, :kal=>6}, {:i=>3, :name=>'00', :pi=>6, :kal=>2},
199
195
  {:i=>4, :name=>'?', :pi=>7, :kal=>7}, {:i=>5, :name=>'?', :pi=>4, :kal=>7}]])
200
196
  os = @ds.eager(:ds).all
201
- sqls = @db.sqls
202
- sqls.first.must_equal "SELECT * FROM nodes"
203
- sqls.last.must_match(/WITH cte AS \(SELECT pi AS kal, nodes\.\* FROM nodes WHERE \(pi IN \([267], [267], [267]\)\) UNION ALL SELECT cte\.kal, nodes\.\* FROM nodes INNER JOIN cte ON \(cte\.i = nodes\.pi\)\) SELECT \* FROM cte/)
197
+ @db.sqls.must_equal ["SELECT * FROM nodes",
198
+ 'WITH cte AS (SELECT pi AS kal, nodes.* FROM nodes WHERE (pi IN (2, 6, 7)) UNION ALL SELECT cte.kal, nodes.* FROM nodes INNER JOIN cte ON (cte.i = nodes.pi)) SELECT * FROM cte AS nodes']
204
199
  os.must_equal [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D')]
205
200
  os.map{|o| o.ds}.must_equal [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E'), @c.load(:i=>3, :name=>'00', :pi=>6)],
206
201
  [@c.load(:i=>3, :name=>'00', :pi=>6)],
@@ -218,9 +213,8 @@ describe Sequel::Model, "rcte_tree" do
218
213
  {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6, :x_level_x=>0}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2, :x_level_x=>1},
219
214
  {:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7, :x_level_x=>0}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7, :x_level_x=>1}]])
220
215
  os = @ds.eager(:descendants=>2).all
221
- sqls = @db.sqls
222
- sqls.first.must_equal "SELECT * FROM nodes"
223
- sqls.last.must_match(/WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\*, CAST\(0 AS integer\) AS x_level_x FROM nodes WHERE \(parent_id IN \([267], [267], [267]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\*, \(t\.x_level_x \+ 1\) AS x_level_x FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\) WHERE \(t\.x_level_x < 1\)\) SELECT \* FROM t AS nodes/)
216
+ @db.sqls.must_equal ["SELECT * FROM nodes",
217
+ 'WITH t AS (SELECT parent_id AS x_root_x, nodes.*, CAST(0 AS integer) AS x_level_x FROM nodes WHERE (parent_id IN (2, 6, 7)) UNION ALL SELECT t.x_root_x, nodes.*, (t.x_level_x + 1) AS x_level_x FROM nodes INNER JOIN t ON (t.id = nodes.parent_id) WHERE (t.x_level_x < 1)) SELECT * FROM t AS nodes']
224
218
  os.must_equal [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D')]
225
219
  os.map{|o| o.descendants}.must_equal [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E'), @c.load(:id=>3, :name=>'00', :parent_id=>6)],
226
220
  [@c.load(:id=>3, :name=>'00', :parent_id=>6)],
@@ -238,9 +232,8 @@ describe Sequel::Model, "rcte_tree" do
238
232
  {:i=>3, :name=>'00', :pi=>6, :kal=>6, :lal=>0}, {:i=>3, :name=>'00', :pi=>6, :kal=>2, :lal=>1},
239
233
  {:i=>4, :name=>'?', :pi=>7, :kal=>7, :lal=>0}, {:i=>5, :name=>'?', :pi=>4, :kal=>7, :lal=>1}]])
240
234
  os = @ds.eager(:ds=>2).all
241
- sqls = @db.sqls
242
- sqls.first.must_equal "SELECT * FROM nodes"
243
- sqls.last.must_match(/WITH cte AS \(SELECT pi AS kal, nodes\.\*, CAST\(0 AS integer\) AS lal FROM nodes WHERE \(pi IN \([267], [267], [267]\)\) UNION ALL SELECT cte\.kal, nodes\.\*, \(cte\.lal \+ 1\) AS lal FROM nodes INNER JOIN cte ON \(cte\.i = nodes\.pi\) WHERE \(cte\.lal < 1\)\) SELECT \* FROM cte/)
235
+ @db.sqls.must_equal ["SELECT * FROM nodes",
236
+ 'WITH cte AS (SELECT pi AS kal, nodes.*, CAST(0 AS integer) AS lal FROM nodes WHERE (pi IN (2, 6, 7)) UNION ALL SELECT cte.kal, nodes.*, (cte.lal + 1) AS lal FROM nodes INNER JOIN cte ON (cte.i = nodes.pi) WHERE (cte.lal < 1)) SELECT * FROM cte AS nodes']
244
237
  os.must_equal [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D')]
245
238
  os.map{|o| o.ds}.must_equal [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E'), @c.load(:i=>3, :name=>'00', :pi=>6)],
246
239
  [@c.load(:i=>3, :name=>'00', :pi=>6)],
@@ -258,9 +251,8 @@ describe Sequel::Model, "rcte_tree" do
258
251
  {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2},
259
252
  {:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7}]])
260
253
  @ds.eager(:descendants).all
261
- sqls = @db.sqls
262
- sqls.first.must_equal "SELECT * FROM nodes"
263
- sqls.last.must_match(/WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\* FROM nodes WHERE \(\(parent_id IN \([267], [267], [267]\)\) AND \(i = 1\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\) WHERE \(i = 1\)\) SELECT \* FROM t AS nodes WHERE \(i = 1\)/)
254
+ @db.sqls.must_equal ["SELECT * FROM nodes",
255
+ 'WITH t AS (SELECT parent_id AS x_root_x, nodes.* FROM nodes WHERE ((parent_id IN (2, 6, 7)) AND (i = 1)) UNION ALL SELECT t.x_root_x, nodes.* FROM nodes INNER JOIN t ON (t.id = nodes.parent_id) WHERE (i = 1)) SELECT * FROM t AS nodes WHERE (i = 1)']
264
256
  end
265
257
  end
266
258
 
@@ -335,9 +327,8 @@ describe Sequel::Model, "rcte_tree with composite keys" do
335
327
  {:id=>1, :id2=>2, :name=>'00', :parent_id=>8, :parent_id2=>9, :x_root_x_0=>1, :x_root_x_1=>2}, {:id=>1, :id2=>2, :name=>'00', :parent_id=>8, :parent_id2=>9, :x_root_x_0=>2, :x_root_x_1=>3},
336
328
  {:id=>8, :id2=>9, :name=>'?', :parent_id=>nil, :parent_id2=>nil, :x_root_x_0=>2, :x_root_x_1=>3}, {:id=>8, :id2=>9, :name=>'?', :parent_id=>nil, :parent_id2=>nil, :x_root_x_0=>1, :x_root_x_1=>2}]])
337
329
  os = @ds.eager(:ancestors).all
338
- sqls = @db.sqls
339
- sqls.first.must_equal "SELECT * FROM nodes"
340
- sqls.last.must_match(/WITH t AS \(SELECT id AS x_root_x_0, id2 AS x_root_x_1, nodes\.\* FROM nodes WHERE \(\(id, id2\) IN \(\([12], [23]\), \([12], [23]\)\)\) UNION ALL SELECT t\.x_root_x_0, t\.x_root_x_1, nodes\.\* FROM nodes INNER JOIN t ON \(\(t\.parent_id = nodes\.id\) AND \(t\.parent_id2 = nodes\.id2\)\)\) SELECT \* FROM t AS nodes/)
330
+ @db.sqls.must_equal ["SELECT * FROM nodes",
331
+ 'WITH t AS (SELECT id AS x_root_x_0, id2 AS x_root_x_1, nodes.* FROM nodes WHERE ((id, id2) IN ((1, 2), (2, 3))) UNION ALL SELECT t.x_root_x_0, t.x_root_x_1, nodes.* FROM nodes INNER JOIN t ON ((t.parent_id = nodes.id) AND (t.parent_id2 = nodes.id2))) SELECT * FROM t AS nodes']
341
332
  os.must_equal [@c.load(:id=>2, :id2=>3, :parent_id=>1, :parent_id2=>2, :name=>'AA'), @c.load(:id=>6, :id2=>7, :parent_id=>2, :parent_id2=>3, :name=>'C'), @c.load(:id=>7, :id2=>8, :parent_id=>1, :parent_id2=>2, :name=>'D'), @c.load(:id=>9, :id2=>10, :parent_id=>nil, :parent_id2=>nil, :name=>'E')]
342
333
  os.map{|o| o.ancestors}.must_equal [[@c.load(:id=>1, :id2=>2, :name=>'00', :parent_id=>8, :parent_id2=>9), @c.load(:id=>8, :id2=>9, :name=>'?', :parent_id=>nil, :parent_id2=>nil)],
343
334
  [@c.load(:id=>2, :id2=>3, :name=>'AA', :parent_id=>1, :parent_id2=>2), @c.load(:id=>1, :id2=>2, :name=>'00', :parent_id=>8, :parent_id2=>9), @c.load(:id=>8, :id2=>9, :name=>'?', :parent_id=>nil, :parent_id2=>nil)],
@@ -357,9 +348,8 @@ describe Sequel::Model, "rcte_tree with composite keys" do
357
348
  {:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7, :x_root_x_0=>6, :x_root_x_1=>7}, {:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7, :x_root_x_0=>2, :x_root_x_1=>3},
358
349
  {:id=>4, :id2=>5, :name=>'?', :parent_id=>7, :parent_id2=>8, :x_root_x_0=>7, :x_root_x_1=>8}, {:id=>5, :id2=>6, :name=>'?', :parent_id=>4, :parent_id2=>5, :x_root_x_0=>7, :x_root_x_1=>8}]])
359
350
  os = @ds.eager(:descendants).all
360
- sqls = @db.sqls
361
- sqls.first.must_equal "SELECT * FROM nodes"
362
- sqls.last.must_match(/WITH t AS \(SELECT parent_id AS x_root_x_0, parent_id2 AS x_root_x_1, nodes\.\* FROM nodes WHERE \(\(parent_id, parent_id2\) IN \(\([267], [378]\), \([267], [378]\), \([267], [378]\)\)\) UNION ALL SELECT t\.x_root_x_0, t\.x_root_x_1, nodes\.\* FROM nodes INNER JOIN t ON \(\(t\.id = nodes\.parent_id\) AND \(t\.id2 = nodes\.parent_id2\)\)\) SELECT \* FROM t AS nodes/)
351
+ @db.sqls.must_equal ["SELECT * FROM nodes",
352
+ 'WITH t AS (SELECT parent_id AS x_root_x_0, parent_id2 AS x_root_x_1, nodes.* FROM nodes WHERE ((parent_id, parent_id2) IN ((2, 3), (6, 7), (7, 8))) UNION ALL SELECT t.x_root_x_0, t.x_root_x_1, nodes.* FROM nodes INNER JOIN t ON ((t.id = nodes.parent_id) AND (t.id2 = nodes.parent_id2))) SELECT * FROM t AS nodes']
363
353
  os.must_equal [@c.load(:id=>2, :id2=>3, :parent_id=>1, :parent_id2=>2, :name=>'AA'), @c.load(:id=>6, :id2=>7, :parent_id=>2, :parent_id2=>3, :name=>'C'), @c.load(:id=>7, :id2=>8, :parent_id=>1, :parent_id2=>2, :name=>'D')]
364
354
  os.map{|o| o.descendants}.must_equal [[@c.load(:id=>6, :id2=>7, :parent_id=>2, :parent_id2=>3, :name=>'C'), @c.load(:id=>9, :id2=>10, :parent_id=>2, :parent_id2=>3, :name=>'E'), @c.load(:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7)],
365
355
  [@c.load(:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7)],
@@ -377,9 +367,8 @@ describe Sequel::Model, "rcte_tree with composite keys" do
377
367
  {:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7, :x_root_x_0=>6, :x_root_x_1=>7, :x_level_x=>0}, {:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7, :x_root_x_0=>2, :x_root_x_1=>3, :x_level_x=>1},
378
368
  {:id=>4, :id2=>5, :name=>'?', :parent_id=>7, :parent_id2=>8, :x_root_x_0=>7, :x_root_x_1=>8, :x_level_x=>0}, {:id=>5, :id2=>6, :name=>'?', :parent_id=>4, :parent_id2=>5, :x_root_x_0=>7, :x_root_x_1=>8, :x_level_x=>1}]])
379
369
  os = @ds.eager(:descendants=>2).all
380
- sqls = @db.sqls
381
- sqls.first.must_equal "SELECT * FROM nodes"
382
- sqls.last.must_match(/WITH t AS \(SELECT parent_id AS x_root_x_0, parent_id2 AS x_root_x_1, nodes\.\*, CAST\(0 AS integer\) AS x_level_x FROM nodes WHERE \(\(parent_id, parent_id2\) IN \(\([267], [378]\), \([267], [378]\), \([267], [378]\)\)\) UNION ALL SELECT t\.x_root_x_0, t\.x_root_x_1, nodes\.\*, \(t\.x_level_x \+ 1\) AS x_level_x FROM nodes INNER JOIN t ON \(\(t\.id = nodes\.parent_id\) AND \(t\.id2 = nodes\.parent_id2\)\) WHERE \(t\.x_level_x < 1\)\) SELECT \* FROM t AS nodes/)
370
+ @db.sqls.must_equal ["SELECT * FROM nodes",
371
+ 'WITH t AS (SELECT parent_id AS x_root_x_0, parent_id2 AS x_root_x_1, nodes.*, CAST(0 AS integer) AS x_level_x FROM nodes WHERE ((parent_id, parent_id2) IN ((2, 3), (6, 7), (7, 8))) UNION ALL SELECT t.x_root_x_0, t.x_root_x_1, nodes.*, (t.x_level_x + 1) AS x_level_x FROM nodes INNER JOIN t ON ((t.id = nodes.parent_id) AND (t.id2 = nodes.parent_id2)) WHERE (t.x_level_x < 1)) SELECT * FROM t AS nodes']
383
372
  os.must_equal [@c.load(:id=>2, :id2=>3, :parent_id=>1, :parent_id2=>2, :name=>'AA'), @c.load(:id=>6, :id2=>7, :parent_id=>2, :parent_id2=>3, :name=>'C'), @c.load(:id=>7, :id2=>8, :parent_id=>1, :parent_id2=>2, :name=>'D')]
384
373
  os.map{|o| o.descendants}.must_equal [[@c.load(:id=>6, :id2=>7, :parent_id=>2, :parent_id2=>3, :name=>'C'), @c.load(:id=>9, :id2=>10, :parent_id=>2, :parent_id2=>3, :name=>'E'), @c.load(:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7)],
385
374
  [@c.load(:id=>3, :id2=>4, :name=>'00', :parent_id=>6, :parent_id2=>7)],
@@ -140,60 +140,55 @@ describe "Sequel::Database dump methods" do
140
140
  def @d.schema(*s) [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
141
141
  def @d.supports_foreign_key_parsing?; true end
142
142
  def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}] end
143
- s = @d.dump_table_schema(:t6)
144
- s.must_match(/create_table\(:t6\) do\n primary_key :c1, /)
145
- s.must_match(/:table=>:t2/)
146
- s.must_match(/:key=>\[:c2\]/)
143
+ @d.dump_table_schema(:t6).must_equal((<<OUTPUT).chomp)
144
+ create_table(:t6) do
145
+ primary_key :c1, :table=>:t2, :key=>[:c2]
146
+ end
147
+ OUTPUT
147
148
  end
148
149
 
149
150
  it "should handle foreign key options" do
150
151
  def @d.schema(*s) [[:c1, {:db_type=>'integer', :allow_null=>true}]] end
151
152
  def @d.supports_foreign_key_parsing?; true end
152
153
  def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}] end
153
- s = @d.dump_table_schema(:t6)
154
- s.must_match(/create_table\(:t6\) do\n foreign_key :c1, :t2, /)
155
- s.must_match(/:key=>\[:c2\]/)
156
- s.must_match(/:on_delete=>:restrict/)
157
- s.must_match(/:on_update=>:set_null/)
158
- s.must_match(/:deferrable=>true/)
154
+ @d.dump_table_schema(:t6).must_equal((<<OUTPUT).chomp)
155
+ create_table(:t6) do
156
+ foreign_key :c1, :t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true
157
+ end
158
+ OUTPUT
159
159
  end
160
160
 
161
161
  it "should handle foreign key options in the primary key" do
162
162
  def @d.schema(*s) [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
163
163
  def @d.supports_foreign_key_parsing?; true end
164
164
  def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}] end
165
- s = @d.dump_table_schema(:t6)
166
- s.must_match(/create_table\(:t6\) do\n primary_key :c1, /)
167
- s.must_match(/:table=>:t2/)
168
- s.must_match(/:key=>\[:c2\]/)
169
- s.must_match(/:on_delete=>:restrict/)
170
- s.must_match(/:on_update=>:set_null/)
171
- s.must_match(/:deferrable=>true/)
165
+ @d.dump_table_schema(:t6).must_equal((<<OUTPUT).chomp)
166
+ create_table(:t6) do
167
+ primary_key :c1, :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true
168
+ end
169
+ OUTPUT
172
170
  end
173
171
 
174
172
  it "should omit foreign key options that are the same as defaults" do
175
173
  def @d.schema(*s) [[:c1, {:db_type=>'integer', :allow_null=>true}]] end
176
174
  def @d.supports_foreign_key_parsing?; true end
177
175
  def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}] end
178
- s = @d.dump_table_schema(:t6)
179
- s.must_match(/create_table\(:t6\) do\n foreign_key :c1, :t2, /)
180
- s.must_match(/:key=>\[:c2\]/)
181
- s.wont_match(/:on_delete/)
182
- s.wont_match(/:on_update/)
183
- s.wont_match(/:deferrable/)
176
+ @d.dump_table_schema(:t6).must_equal((<<OUTPUT).chomp)
177
+ create_table(:t6) do
178
+ foreign_key :c1, :t2, :key=>[:c2]
179
+ end
180
+ OUTPUT
184
181
  end
185
182
 
186
183
  it "should omit foreign key options that are the same as defaults in the primary key" do
187
184
  def @d.schema(*s) [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
188
185
  def @d.supports_foreign_key_parsing?; true end
189
186
  def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}] end
190
- s = @d.dump_table_schema(:t6)
191
- s.must_match(/create_table\(:t6\) do\n primary_key :c1, /)
192
- s.must_match(/:table=>:t2/)
193
- s.must_match(/:key=>\[:c2\]/)
194
- s.wont_match(/:on_delete/)
195
- s.wont_match(/:on_update/)
196
- s.wont_match(/:deferrable/)
187
+ @d.dump_table_schema(:t6).must_equal((<<OUTPUT).chomp)
188
+ create_table(:t6) do
189
+ primary_key :c1, :table=>:t2, :key=>[:c2]
190
+ end
191
+ OUTPUT
197
192
  end
198
193
 
199
194
  it "should dump primary key columns with explicit type equal to the database type when :same_db option is passed" do
@@ -508,7 +503,23 @@ END_MIG
508
503
  def @d.foreign_key_list(t)
509
504
  t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
510
505
  end
511
- @d.dump_schema_migration(:indexes=>false, :foreign_keys=>true).must_match(/foreign_key/)
506
+ @d.dump_schema_migration(:indexes=>false, :foreign_keys=>true).must_equal(<<OUTPUT)
507
+ Sequel.migration do
508
+ change do
509
+ create_table(:t2) do
510
+ Integer :c1, :null=>false
511
+ BigDecimal :c2, :null=>false
512
+
513
+ primary_key [:c1, :c2]
514
+ end
515
+
516
+ create_table(:t1) do
517
+ primary_key :c1
518
+ foreign_key :c2, :t2, :type=>String, :size=>20, :key=>[:c1]
519
+ end
520
+ end
521
+ end
522
+ OUTPUT
512
523
  end
513
524
 
514
525
  it "should support dumping just indexes as a migration" do