sequel 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +40 -0
- data/Rakefile +1 -1
- data/doc/opening_databases.rdoc +7 -0
- data/doc/release_notes/3.3.0.txt +192 -0
- data/lib/sequel/adapters/ado.rb +34 -39
- data/lib/sequel/adapters/ado/mssql.rb +30 -0
- data/lib/sequel/adapters/jdbc.rb +27 -4
- data/lib/sequel/adapters/jdbc/h2.rb +14 -3
- data/lib/sequel/adapters/jdbc/mssql.rb +51 -0
- data/lib/sequel/adapters/mysql.rb +28 -12
- data/lib/sequel/adapters/odbc.rb +36 -30
- data/lib/sequel/adapters/odbc/mssql.rb +44 -0
- data/lib/sequel/adapters/shared/mssql.rb +185 -10
- data/lib/sequel/adapters/shared/mysql.rb +9 -9
- data/lib/sequel/adapters/shared/sqlite.rb +45 -47
- data/lib/sequel/connection_pool.rb +8 -5
- data/lib/sequel/core.rb +2 -8
- data/lib/sequel/database.rb +9 -10
- data/lib/sequel/database/schema_sql.rb +3 -2
- data/lib/sequel/dataset.rb +1 -0
- data/lib/sequel/dataset/sql.rb +15 -6
- data/lib/sequel/extensions/schema_dumper.rb +7 -7
- data/lib/sequel/model/associations.rb +16 -14
- data/lib/sequel/model/base.rb +25 -7
- data/lib/sequel/plugins/association_proxies.rb +41 -0
- data/lib/sequel/plugins/many_through_many.rb +0 -1
- data/lib/sequel/sql.rb +8 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +42 -38
- data/spec/adapters/sqlite_spec.rb +0 -4
- data/spec/core/database_spec.rb +22 -1
- data/spec/core/dataset_spec.rb +37 -12
- data/spec/core/expression_filters_spec.rb +5 -0
- data/spec/core/schema_spec.rb +15 -8
- data/spec/extensions/association_proxies_spec.rb +47 -0
- data/spec/extensions/caching_spec.rb +2 -2
- data/spec/extensions/hook_class_methods_spec.rb +6 -6
- data/spec/extensions/many_through_many_spec.rb +13 -0
- data/spec/extensions/schema_dumper_spec.rb +12 -4
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/integration/dataset_test.rb +47 -17
- data/spec/integration/prepared_statement_test.rb +5 -5
- data/spec/integration/schema_test.rb +111 -34
- data/spec/model/associations_spec.rb +128 -11
- data/spec/model/hooks_spec.rb +7 -6
- data/spec/model/model_spec.rb +54 -4
- data/spec/model/record_spec.rb +2 -3
- data/spec/model/validations_spec.rb +4 -4
- metadata +109 -101
- data/spec/adapters/ado_spec.rb +0 -93
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe "Sequel::Plugins::AssociationProxies" do
|
4
|
+
before do
|
5
|
+
class ::Tag < Sequel::Model
|
6
|
+
end
|
7
|
+
class ::Item < Sequel::Model
|
8
|
+
plugin :association_proxies
|
9
|
+
many_to_many :tags
|
10
|
+
end
|
11
|
+
@i = Item.load(:id=>1)
|
12
|
+
@t = @i.tags
|
13
|
+
Item.db.reset
|
14
|
+
end
|
15
|
+
after do
|
16
|
+
Object.send(:remove_const, :Tag)
|
17
|
+
Object.send(:remove_const, :Item)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should send method calls to the associated object array if sent an array method" do
|
21
|
+
@i.associations.has_key?(:tags).should == false
|
22
|
+
@t.select{|x| false}.should == []
|
23
|
+
@i.associations.has_key?(:tags).should == true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should send method calls to the association dataset sent another method" do
|
27
|
+
@i.associations.has_key?(:tags).should == false
|
28
|
+
@t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
|
29
|
+
@i.associations.has_key?(:tags).should == false
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should reload the cached association if sent an array method and the reload flag was given" do
|
33
|
+
@t.select{|x| false}.should == []
|
34
|
+
Item.db.sqls.length == 1
|
35
|
+
@t.select{|x| false}.should == []
|
36
|
+
Item.db.sqls.length == 1
|
37
|
+
@i.tags(true).select{|x| false}.should == []
|
38
|
+
Item.db.sqls.length == 2
|
39
|
+
@t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
|
40
|
+
Item.db.sqls.length == 2
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not return a proxy object for associations that do not return an array" do
|
44
|
+
Item.many_to_one :tag
|
45
|
+
proc{@i.tag.filter(:a=>1)}.should raise_error(NoMethodError)
|
46
|
+
end
|
47
|
+
end
|
@@ -155,14 +155,14 @@ describe Sequel::Model, "caching" do
|
|
155
155
|
m.name = 'hey'
|
156
156
|
m.save
|
157
157
|
@cache.has_key?(m.cache_key).should be_false
|
158
|
-
$sqls.last.should == "UPDATE items SET name = 'hey'
|
158
|
+
$sqls.last.should == "UPDATE items SET name = 'hey' WHERE (id = 1)"
|
159
159
|
|
160
160
|
m = @c2[1]
|
161
161
|
@cache[m.cache_key].should == m
|
162
162
|
m.name = 'hey'
|
163
163
|
m.save
|
164
164
|
@cache.has_key?(m.cache_key).should be_false
|
165
|
-
$sqls.last.should == "UPDATE items SET name = 'hey'
|
165
|
+
$sqls.last.should == "UPDATE items SET name = 'hey' WHERE (id = 1)"
|
166
166
|
end
|
167
167
|
|
168
168
|
it "should delete the cache when deleting the record" do
|
@@ -240,11 +240,11 @@ describe "Model#before_update && Model#after_update" do
|
|
240
240
|
|
241
241
|
specify "should be called around record update" do
|
242
242
|
@c.before_update {MODEL_DB << "BLAH before"}
|
243
|
-
m = @c.load(:id => 2233)
|
243
|
+
m = @c.load(:id => 2233, :x=>123)
|
244
244
|
m.save
|
245
245
|
MODEL_DB.sqls.should == [
|
246
246
|
'BLAH before',
|
247
|
-
'UPDATE items SET
|
247
|
+
'UPDATE items SET x = 123 WHERE (id = 2233)',
|
248
248
|
'BLAH after'
|
249
249
|
]
|
250
250
|
end
|
@@ -277,11 +277,11 @@ describe "Model#before_save && Model#after_save" do
|
|
277
277
|
|
278
278
|
specify "should be called around record update" do
|
279
279
|
@c.before_save {MODEL_DB << "BLAH before"}
|
280
|
-
m = @c.load(:id => 2233)
|
280
|
+
m = @c.load(:id => 2233, :x=>123)
|
281
281
|
m.save
|
282
282
|
MODEL_DB.sqls.should == [
|
283
283
|
'BLAH before',
|
284
|
-
'UPDATE items SET
|
284
|
+
'UPDATE items SET x = 123 WHERE (id = 2233)',
|
285
285
|
'BLAH after'
|
286
286
|
]
|
287
287
|
end
|
@@ -380,9 +380,9 @@ describe "Model#before_validation && Model#after_validation" do
|
|
380
380
|
|
381
381
|
specify "should be called when calling save" do
|
382
382
|
@c.before_validation{MODEL_DB << "BLAH before"}
|
383
|
-
m = @c.load(:id => 2233)
|
383
|
+
m = @c.load(:id => 2233, :x=>123)
|
384
384
|
m.save.should == m
|
385
|
-
MODEL_DB.sqls.should == ['BLAH before', 'BLAH after', 'UPDATE items SET
|
385
|
+
MODEL_DB.sqls.should == ['BLAH before', 'BLAH after', 'UPDATE items SET x = 123 WHERE (id = 2233)']
|
386
386
|
|
387
387
|
MODEL_DB.sqls.clear
|
388
388
|
m = @c.load(:id => 22)
|
@@ -23,6 +23,19 @@ describe Sequel::Model, "many_through_many" do
|
|
23
23
|
Object.send(:remove_const, :Tag)
|
24
24
|
end
|
25
25
|
|
26
|
+
it "should default to associating to other models in the same scope" do
|
27
|
+
class ::AssociationModuleTest
|
28
|
+
class Artist < Sequel::Model
|
29
|
+
plugin :many_through_many
|
30
|
+
many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
31
|
+
end
|
32
|
+
class Tag < Sequel::Model
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
::AssociationModuleTest::Artist.association_reflection(:tags).associated_class.should == ::AssociationModuleTest::Tag
|
37
|
+
end
|
38
|
+
|
26
39
|
it "should raise an error if in invalid form of through is used" do
|
27
40
|
proc{@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id]]}.should raise_error(Sequel::Error)
|
28
41
|
proc{@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], {:table=>:album_tags, :left=>:album_id}]}.should raise_error(Sequel::Error)
|
@@ -253,13 +253,14 @@ END_MIG
|
|
253
253
|
|
254
254
|
it "should convert many database types to ruby types" do
|
255
255
|
types = %w"mediumint smallint int integer mediumint(6) smallint(7) int(8) integer(9)
|
256
|
-
tinyint tinyint(
|
256
|
+
tinyint tinyint(2) bigint bigint(20) real float double boolean tinytext mediumtext
|
257
257
|
longtext text clob date datetime timestamp time char character
|
258
258
|
varchar varchar(255) varchar(30) bpchar string money
|
259
259
|
decimal decimal(10,2) numeric numeric(15,3) number bytea tinyblob mediumblob longblob
|
260
260
|
blob varbinary varbinary(10) binary binary(20) year" +
|
261
261
|
["double precision", "timestamp with time zone", "timestamp without time zone",
|
262
|
-
"time with time zone", "time without time zone", "character varying(20)"]
|
262
|
+
"time with time zone", "time without time zone", "character varying(20)"] +
|
263
|
+
%w"nvarchar ntext smalldatetime smallmoney binary varbinary nchar"
|
263
264
|
@d.meta_def(:schema) do |t, *o|
|
264
265
|
i = 0
|
265
266
|
types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
|
@@ -274,8 +275,8 @@ create_table(:x) do
|
|
274
275
|
Integer :c6
|
275
276
|
Integer :c7
|
276
277
|
Integer :c8
|
277
|
-
|
278
|
-
|
278
|
+
Integer :c9
|
279
|
+
Integer :c10
|
279
280
|
Bignum :c11
|
280
281
|
Bignum :c12
|
281
282
|
Float :c13
|
@@ -320,6 +321,13 @@ create_table(:x) do
|
|
320
321
|
Time :c52, :only_time=>true
|
321
322
|
Time :c53, :only_time=>true
|
322
323
|
String :c54, :size=>20
|
324
|
+
String :c55
|
325
|
+
String :c56, :text=>true
|
326
|
+
DateTime :c57
|
327
|
+
BigDecimal :c58, :size=>[19, 2]
|
328
|
+
File :c59
|
329
|
+
File :c60
|
330
|
+
String :c61, :fixed=>true
|
323
331
|
end
|
324
332
|
END_MIG
|
325
333
|
@d.dump_table_schema(:x).should == table.chomp
|
@@ -950,7 +950,7 @@ describe "Model#save" do
|
|
950
950
|
o.errors[a] << 'blah' unless v == 5
|
951
951
|
end
|
952
952
|
end
|
953
|
-
@m = @c.load(:id => 4)
|
953
|
+
@m = @c.load(:id => 4, :x=>6)
|
954
954
|
MODEL_DB.reset
|
955
955
|
end
|
956
956
|
|
@@ -963,14 +963,14 @@ describe "Model#save" do
|
|
963
963
|
@m.id = 5
|
964
964
|
@m.should be_valid
|
965
965
|
@m.save.should_not be_false
|
966
|
-
MODEL_DB.sqls.should == ['UPDATE people SET
|
966
|
+
MODEL_DB.sqls.should == ['UPDATE people SET x = 6 WHERE (id = 5)']
|
967
967
|
end
|
968
968
|
|
969
969
|
specify "should skip validations if the :validate=>false option is used" do
|
970
970
|
@m.raise_on_save_failure = false
|
971
971
|
@m.should_not be_valid
|
972
972
|
@m.save(:validate=>false)
|
973
|
-
MODEL_DB.sqls.should == ['UPDATE people SET
|
973
|
+
MODEL_DB.sqls.should == ['UPDATE people SET x = 6 WHERE (id = 4)']
|
974
974
|
end
|
975
975
|
|
976
976
|
specify "should raise error if validations fail and raise_on_save_faiure is true" do
|
@@ -57,6 +57,26 @@ describe "Simple Dataset operations" do
|
|
57
57
|
@ds.first.should == {:id=>1, :number=>10}
|
58
58
|
sqls_should_be('SELECT * FROM items LIMIT 1')
|
59
59
|
end
|
60
|
+
|
61
|
+
specify "should fetch correctly with a limit" do
|
62
|
+
@ds.order(:id).limit(2).all.should == [{:id=>1, :number=>10}]
|
63
|
+
@ds.insert(:number=>20)
|
64
|
+
@ds.order(:id).limit(1).all.should == [{:id=>1, :number=>10}]
|
65
|
+
@ds.order(:id).limit(2).all.should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
66
|
+
end
|
67
|
+
|
68
|
+
specify "should fetch correctly with a limit and offset" do
|
69
|
+
@ds.order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10}]
|
70
|
+
@ds.order(:id).limit(2, 1).all.should == []
|
71
|
+
@ds.insert(:number=>20)
|
72
|
+
@ds.order(:id).limit(1, 1).all.should == [{:id=>2, :number=>20}]
|
73
|
+
@ds.order(:id).limit(2, 0).all.should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
|
74
|
+
@ds.order(:id).limit(2, 1).all.should == [{:id=>2, :number=>20}]
|
75
|
+
end
|
76
|
+
|
77
|
+
specify "should fetch correctly with a limit and offset without an order" do
|
78
|
+
@ds.limit(2, 1).all.should == []
|
79
|
+
end
|
60
80
|
|
61
81
|
specify "should alias columns correctly" do
|
62
82
|
@ds.select(:id___x, :number___n).first.should == {:x=>1, :n=>10}
|
@@ -326,7 +346,7 @@ if INTEGRATION_DB.dataset.supports_cte?
|
|
326
346
|
end
|
327
347
|
|
328
348
|
specify "should give correct results for WITH" do
|
329
|
-
@db[:t].with(:t, @ds.
|
349
|
+
@db[:t].with(:t, @ds.filter(:parent_id=>nil).select(:id)).order(:id).map(:id).should == [1, 2]
|
330
350
|
end
|
331
351
|
|
332
352
|
specify "should give correct results for recursive WITH" do
|
@@ -357,34 +377,44 @@ if INTEGRATION_DB.dataset.supports_window_functions?
|
|
357
377
|
@db.drop_table(:i1)
|
358
378
|
end
|
359
379
|
|
360
|
-
specify "should give correct results for window functions" do
|
361
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id
|
362
|
-
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
363
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id){}}.all.should ==
|
380
|
+
specify "should give correct results for aggregate window functions" do
|
381
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id){}.as(:sum)}.all.should ==
|
364
382
|
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
365
|
-
@ds.select(:id){sum(:over, :args=>amount
|
366
|
-
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
367
|
-
@ds.select(:id){sum(:over, :args=>amount){}}.all.should ==
|
383
|
+
@ds.select(:id){sum(:over, :args=>amount){}.as(:sum)}.all.should ==
|
368
384
|
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
369
385
|
end
|
386
|
+
|
387
|
+
specify "should give correct results for ranking window functions with orders" do
|
388
|
+
@ds.select(:id){rank(:over, :partition=>group_id, :order=>id){}.as(:rank)}.all.should ==
|
389
|
+
[{:rank=>1, :id=>1}, {:rank=>2, :id=>2}, {:rank=>3, :id=>3}, {:rank=>1, :id=>4}, {:rank=>2, :id=>5}, {:rank=>3, :id=>6}]
|
390
|
+
@ds.select(:id){rank(:over, :order=>id){}.as(:rank)}.all.should ==
|
391
|
+
[{:rank=>1, :id=>1}, {:rank=>2, :id=>2}, {:rank=>3, :id=>3}, {:rank=>4, :id=>4}, {:rank=>5, :id=>5}, {:rank=>6, :id=>6}]
|
392
|
+
end
|
393
|
+
|
394
|
+
specify "should give correct results for aggregate window functions with orders" do
|
395
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id){}.as(:sum)}.all.should ==
|
396
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
397
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id){}.as(:sum)}.all.should ==
|
398
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
399
|
+
end
|
370
400
|
|
371
|
-
specify "should give correct results for window functions with frames" do
|
372
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:all){}}.all.should ==
|
401
|
+
specify "should give correct results for aggregate window functions with frames" do
|
402
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:all){}.as(:sum)}.all.should ==
|
373
403
|
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
374
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:all){}}.all.should ==
|
404
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:all){}.as(:sum)}.all.should ==
|
375
405
|
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
376
|
-
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:all){}}.all.should ==
|
406
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:all){}.as(:sum)}.all.should ==
|
377
407
|
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
378
|
-
@ds.select(:id){sum(:over, :args=>amount, :frame=>:all){}}.all.should ==
|
408
|
+
@ds.select(:id){sum(:over, :args=>amount, :frame=>:all){}.as(:sum)}.all.should ==
|
379
409
|
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
380
410
|
|
381
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:rows){}}.all.should ==
|
411
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:rows){}.as(:sum)}.all.should ==
|
382
412
|
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
383
|
-
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:rows){}}.all.should ==
|
413
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:rows){}.as(:sum)}.all.should ==
|
384
414
|
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
385
|
-
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:rows){}}.all.should ==
|
415
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:rows){}.as(:sum)}.all.should ==
|
386
416
|
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
387
|
-
@ds.select(:id){sum(:over, :args=>amount, :frame=>:rows){}}.all.should ==
|
417
|
+
@ds.select(:id){sum(:over, :args=>amount, :frame=>:rows){}.as(:sum)}.all.should ==
|
388
418
|
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
389
419
|
end
|
390
420
|
end
|
@@ -49,9 +49,9 @@ describe "Prepared Statements and Bound Arguments" do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
specify "should support bound variables with insert" do
|
52
|
-
@ds.call(:insert, {:n=>20
|
52
|
+
@ds.call(:insert, {:n=>20}, :number=>@ds.ba(:$n))
|
53
53
|
@ds.count.should == 2
|
54
|
-
@ds.order(:id).
|
54
|
+
@ds.order(:id).map(:number).should == [10, 20]
|
55
55
|
end
|
56
56
|
|
57
57
|
specify "should have insert return primary key value when using bound arguments" do
|
@@ -84,10 +84,10 @@ describe "Prepared Statements and Bound Arguments" do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
specify "should support prepared statements with insert" do
|
87
|
-
@ds.prepare(:insert, :insert_n, :
|
88
|
-
INTEGRATION_DB.call(:insert_n, :n=>20
|
87
|
+
@ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
|
88
|
+
INTEGRATION_DB.call(:insert_n, :n=>20)
|
89
89
|
@ds.count.should == 2
|
90
|
-
@ds.order(:id).
|
90
|
+
@ds.order(:id).map(:number).should == [10, 20]
|
91
91
|
end
|
92
92
|
|
93
93
|
specify "should have insert return primary key value when using prepared statements" do
|
@@ -146,74 +146,151 @@ end
|
|
146
146
|
|
147
147
|
describe "Database schema modifiers" do
|
148
148
|
before do
|
149
|
-
@
|
149
|
+
@db = INTEGRATION_DB
|
150
|
+
@ds = @db[:items]
|
150
151
|
clear_sqls
|
151
152
|
end
|
152
153
|
after do
|
153
|
-
|
154
|
+
@db.drop_table(:items) if @db.table_exists?(:items)
|
154
155
|
end
|
155
156
|
|
156
157
|
specify "should create tables correctly" do
|
157
|
-
|
158
|
-
|
159
|
-
|
158
|
+
@db.create_table!(:items){Integer :number}
|
159
|
+
@db.table_exists?(:items).should == true
|
160
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
160
161
|
@ds.insert([10])
|
161
162
|
@ds.columns!.should == [:number]
|
162
163
|
end
|
163
164
|
|
164
165
|
specify "should handle foreign keys correctly when creating tables" do
|
165
|
-
|
166
|
+
@db.create_table!(:items) do
|
166
167
|
primary_key :id
|
167
168
|
foreign_key :item_id, :items
|
168
169
|
unique [:item_id, :id]
|
169
170
|
foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
|
170
171
|
end
|
171
|
-
|
172
|
-
|
172
|
+
@db.table_exists?(:items).should == true
|
173
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
173
174
|
@ds.columns!.should == [:id, :item_id]
|
174
175
|
end
|
175
176
|
|
176
177
|
specify "should add columns to tables correctly" do
|
177
|
-
|
178
|
-
|
179
|
-
@
|
180
|
-
|
181
|
-
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name]
|
178
|
+
@db.create_table!(:items){Integer :number}
|
179
|
+
@ds.insert(:number=>10)
|
180
|
+
@db.alter_table(:items){add_column :name, :text}
|
181
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name]
|
182
182
|
@ds.columns!.should == [:number, :name]
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
183
|
+
@ds.all.should == [{:number=>10, :name=>nil}]
|
184
|
+
end
|
185
|
+
|
186
|
+
specify "should add primary key columns to tables correctly" do
|
187
|
+
@db.create_table!(:items){Integer :number}
|
188
|
+
@ds.insert(:number=>10)
|
189
|
+
@db.alter_table(:items){add_primary_key :id}
|
190
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :id]
|
191
|
+
@ds.columns!.should == [:number, :id]
|
192
|
+
@ds.map(:number).should == [10]
|
193
|
+
end
|
194
|
+
|
195
|
+
specify "should add foreign key columns to tables correctly" do
|
196
|
+
@db.create_table!(:items){primary_key :id}
|
197
|
+
i = @ds.insert
|
198
|
+
@db.alter_table(:items){add_foreign_key :item_id, :items}
|
199
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
200
|
+
@ds.columns!.should == [:id, :item_id]
|
201
|
+
@ds.all.should == [{:id=>i, :item_id=>nil}]
|
202
|
+
end
|
203
|
+
|
204
|
+
specify "should rename columns correctly" do
|
205
|
+
@db.create_table!(:items){Integer :id}
|
206
|
+
@ds.insert(:id=>10)
|
207
|
+
@db.alter_table(:items){rename_column :id, :id2}
|
208
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id2]
|
209
|
+
@ds.columns!.should == [:id2]
|
210
|
+
@ds.all.should == [{:id2=>10}]
|
211
|
+
end
|
212
|
+
|
213
|
+
specify "should rename columns with defaults correctly" do
|
214
|
+
@db.create_table!(:items){String :n, :default=>'blah'}
|
215
|
+
@ds.insert
|
216
|
+
@db.alter_table(:items){rename_column :n, :n2}
|
217
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:n2]
|
218
|
+
@ds.columns!.should == [:n2]
|
219
|
+
@ds.insert
|
220
|
+
@ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
|
221
|
+
end
|
222
|
+
|
223
|
+
specify "should rename columns with not null constraints" do
|
224
|
+
@db.create_table!(:items){String :n, :null=>false}
|
225
|
+
@ds.insert(:n=>'blah')
|
226
|
+
@db.alter_table(:items){rename_column :n, :n2}
|
227
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:n2]
|
228
|
+
@ds.columns!.should == [:n2]
|
229
|
+
@ds.insert(:n2=>'blah')
|
230
|
+
@ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
|
231
|
+
proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
|
232
|
+
end
|
233
|
+
|
234
|
+
specify "should set column NULL/NOT NULL correctly" do
|
235
|
+
@db.create_table!(:items){Integer :id}
|
236
|
+
@ds.insert(:id=>10)
|
237
|
+
@db.alter_table(:items){set_column_allow_null :id, false}
|
238
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
239
|
+
@ds.columns!.should == [:id]
|
240
|
+
proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
|
241
|
+
@db.alter_table(:items){set_column_allow_null :id, true}
|
242
|
+
@ds.insert
|
243
|
+
@ds.all.should == [{:id=>10}, {:id=>nil}]
|
244
|
+
end
|
245
|
+
|
246
|
+
specify "should set column defaults correctly" do
|
247
|
+
@db.create_table!(:items){Integer :id}
|
248
|
+
@ds.insert(:id=>10)
|
249
|
+
@db.alter_table(:items){set_column_default :id, 20}
|
250
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
251
|
+
@ds.columns!.should == [:id]
|
252
|
+
@ds.insert
|
253
|
+
@ds.all.should == [{:id=>10}, {:id=>20}]
|
254
|
+
end
|
255
|
+
|
256
|
+
specify "should set column types correctly" do
|
257
|
+
@db.create_table!(:items){Integer :id}
|
258
|
+
@ds.insert(:id=>10)
|
259
|
+
@db.alter_table(:items){set_column_type :id, String}
|
260
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
261
|
+
@ds.columns!.should == [:id]
|
262
|
+
@ds.insert(:id=>20)
|
263
|
+
@ds.all.should == [{:id=>"10"}, {:id=>"20"}]
|
264
|
+
end
|
265
|
+
|
266
|
+
specify "should add unique constraints and foreign key table constraints correctly" do
|
267
|
+
@db.create_table!(:items){Integer :id; Integer :item_id}
|
268
|
+
@db.alter_table(:items) do
|
269
|
+
add_unique_constraint [:item_id, :id]
|
270
|
+
add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
|
196
271
|
end
|
272
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
273
|
+
@ds.columns!.should == [:id, :item_id]
|
197
274
|
end
|
198
275
|
|
199
276
|
specify "should remove columns from tables correctly" do
|
200
|
-
|
277
|
+
@db.create_table!(:items) do
|
201
278
|
primary_key :id
|
202
279
|
String :name
|
203
280
|
Integer :number
|
204
281
|
foreign_key :item_id, :items
|
205
282
|
end
|
206
283
|
@ds.insert(:number=>10)
|
207
|
-
|
284
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number, :item_id]
|
208
285
|
@ds.columns!.should == [:id, :name, :number, :item_id]
|
209
|
-
|
210
|
-
|
286
|
+
@db.drop_column(:items, :number)
|
287
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :item_id]
|
211
288
|
@ds.columns!.should == [:id, :name, :item_id]
|
212
|
-
|
213
|
-
|
289
|
+
@db.drop_column(:items, :name)
|
290
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
214
291
|
@ds.columns!.should == [:id, :item_id]
|
215
|
-
|
216
|
-
|
292
|
+
@db.drop_column(:items, :item_id)
|
293
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
217
294
|
@ds.columns!.should == [:id]
|
218
295
|
end
|
219
296
|
end
|