sequel 3.31.0 → 3.32.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 +54 -0
- data/MIT-LICENSE +1 -1
- data/doc/advanced_associations.rdoc +17 -0
- data/doc/association_basics.rdoc +74 -30
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/schema_modification.rdoc +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +7 -0
- data/lib/sequel/adapters/jdbc/derby.rb +13 -0
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/hsqldb.rb +7 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +7 -0
- data/lib/sequel/adapters/mock.rb +4 -0
- data/lib/sequel/adapters/mysql.rb +3 -0
- data/lib/sequel/adapters/oracle.rb +7 -3
- data/lib/sequel/adapters/shared/db2.rb +9 -2
- data/lib/sequel/adapters/shared/mssql.rb +48 -2
- data/lib/sequel/adapters/shared/mysql.rb +24 -4
- data/lib/sequel/adapters/shared/oracle.rb +7 -6
- data/lib/sequel/adapters/shared/progress.rb +1 -1
- data/lib/sequel/adapters/shared/sqlite.rb +16 -10
- data/lib/sequel/core.rb +22 -0
- data/lib/sequel/database/query.rb +13 -4
- data/lib/sequel/dataset/actions.rb +20 -11
- data/lib/sequel/dataset/mutation.rb +7 -1
- data/lib/sequel/dataset/prepared_statements.rb +11 -0
- data/lib/sequel/dataset/sql.rb +21 -24
- data/lib/sequel/extensions/query.rb +1 -1
- data/lib/sequel/model.rb +5 -2
- data/lib/sequel/model/associations.rb +70 -16
- data/lib/sequel/model/base.rb +11 -6
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/composition.rb +43 -10
- data/lib/sequel/plugins/many_through_many.rb +4 -1
- data/lib/sequel/plugins/nested_attributes.rb +65 -10
- data/lib/sequel/plugins/serialization.rb +13 -8
- data/lib/sequel/plugins/serialization_modification_detection.rb +22 -10
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +33 -10
- data/spec/adapters/mysql_spec.rb +111 -91
- data/spec/adapters/oracle_spec.rb +18 -0
- data/spec/core/database_spec.rb +1 -0
- data/spec/core/dataset_spec.rb +110 -15
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/many_through_many_spec.rb +14 -14
- data/spec/extensions/query_spec.rb +6 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +36 -1
- data/spec/extensions/serialization_spec.rb +9 -0
- data/spec/integration/associations_test.rb +278 -154
- data/spec/integration/dataset_test.rb +39 -2
- data/spec/integration/plugin_test.rb +63 -3
- data/spec/integration/prepared_statement_test.rb +10 -3
- data/spec/integration/schema_test.rb +61 -14
- data/spec/integration/transaction_test.rb +10 -0
- data/spec/model/associations_spec.rb +170 -80
- data/spec/model/hooks_spec.rb +40 -0
- metadata +4 -2
@@ -31,6 +31,24 @@ describe "An Oracle database" do
|
|
31
31
|
ORACLE_DB.pool.size.should == 0
|
32
32
|
end
|
33
33
|
|
34
|
+
specify "should have working view_exists?" do
|
35
|
+
begin
|
36
|
+
ORACLE_DB.view_exists?(:cats).should be_false
|
37
|
+
ORACLE_DB.create_view(:cats, ORACLE_DB[:categories])
|
38
|
+
ORACLE_DB.view_exists?(:cats).should be_true
|
39
|
+
om = ORACLE_DB.identifier_output_method
|
40
|
+
im = ORACLE_DB.identifier_input_method
|
41
|
+
ORACLE_DB.identifier_output_method = :reverse
|
42
|
+
ORACLE_DB.identifier_input_method = :reverse
|
43
|
+
ORACLE_DB.view_exists?(:STAC).should be_true
|
44
|
+
ORACLE_DB.view_exists?(:cats).should be_false
|
45
|
+
ensure
|
46
|
+
ORACLE_DB.identifier_output_method = om
|
47
|
+
ORACLE_DB.identifier_input_method = im
|
48
|
+
ORACLE_DB.drop_view(:cats)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
34
52
|
specify "should be able to get current sequence value with SQL" do
|
35
53
|
begin
|
36
54
|
ORACLE_DB.create_table!(:foo){primary_key :id}
|
data/spec/core/database_spec.rb
CHANGED
@@ -566,6 +566,7 @@ describe "Database#table_exists?" do
|
|
566
566
|
specify "should try to select the first record from the table's dataset" do
|
567
567
|
db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
|
568
568
|
db.table_exists?(:a).should be_false
|
569
|
+
db.sqls.should == ["SELECT NULL FROM a LIMIT 1"]
|
569
570
|
db.table_exists?(:b).should be_true
|
570
571
|
db.table_exists?(:c).should be_true
|
571
572
|
end
|
data/spec/core/dataset_spec.rb
CHANGED
@@ -495,29 +495,42 @@ describe "Dataset#where" do
|
|
495
495
|
"SELECT * FROM test WHERE (gdp > (SELECT avg(gdp) FROM test WHERE (region = 'Asia')))"
|
496
496
|
end
|
497
497
|
|
498
|
+
specify "should handle all types of IN/NOT IN queries with empty arrays" do
|
499
|
+
@dataset.filter(:id => []).sql.should == "SELECT * FROM test WHERE (id != id)"
|
500
|
+
@dataset.filter([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
|
501
|
+
@dataset.exclude(:id => []).sql.should == "SELECT * FROM test WHERE (id = id)"
|
502
|
+
@dataset.exclude([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE ((id1 = id1) AND (id2 = id2))"
|
503
|
+
end
|
504
|
+
|
505
|
+
specify "should handle all types of IN/NOT IN queries with empty arrays" do
|
506
|
+
begin
|
507
|
+
Sequel.empty_array_handle_nulls = false
|
508
|
+
@dataset.filter(:id => []).sql.should == "SELECT * FROM test WHERE (1 = 0)"
|
509
|
+
@dataset.filter([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE (1 = 0)"
|
510
|
+
@dataset.exclude(:id => []).sql.should == "SELECT * FROM test WHERE (1 = 1)"
|
511
|
+
@dataset.exclude([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE (1 = 1)"
|
512
|
+
ensure
|
513
|
+
Sequel.empty_array_handle_nulls = true
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
498
517
|
specify "should handle all types of IN/NOT IN queries" do
|
499
518
|
@dataset.filter(:id => @d1.select(:id)).sql.should == "SELECT * FROM test WHERE (id IN (SELECT id FROM test WHERE (region = 'Asia')))"
|
500
|
-
@dataset.filter(:id => []).sql.should == "SELECT * FROM test WHERE (id != id)"
|
501
519
|
@dataset.filter(:id => [1, 2]).sql.should == "SELECT * FROM test WHERE (id IN (1, 2))"
|
502
520
|
@dataset.filter([:id1, :id2] => @d1.select(:id1, :id2)).sql.should == "SELECT * FROM test WHERE ((id1, id2) IN (SELECT id1, id2 FROM test WHERE (region = 'Asia')))"
|
503
|
-
@dataset.filter([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
|
504
521
|
@dataset.filter([:id1, :id2] => [[1, 2], [3,4]].sql_array).sql.should == "SELECT * FROM test WHERE ((id1, id2) IN ((1, 2), (3, 4)))"
|
505
522
|
@dataset.filter([:id1, :id2] => [[1, 2], [3,4]]).sql.should == "SELECT * FROM test WHERE ((id1, id2) IN ((1, 2), (3, 4)))"
|
506
523
|
|
507
524
|
@dataset.exclude(:id => @d1.select(:id)).sql.should == "SELECT * FROM test WHERE (id NOT IN (SELECT id FROM test WHERE (region = 'Asia')))"
|
508
|
-
@dataset.exclude(:id => []).sql.should == "SELECT * FROM test WHERE (1 = 1)"
|
509
525
|
@dataset.exclude(:id => [1, 2]).sql.should == "SELECT * FROM test WHERE (id NOT IN (1, 2))"
|
510
526
|
@dataset.exclude([:id1, :id2] => @d1.select(:id1, :id2)).sql.should == "SELECT * FROM test WHERE ((id1, id2) NOT IN (SELECT id1, id2 FROM test WHERE (region = 'Asia')))"
|
511
|
-
@dataset.exclude([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE (1 = 1)"
|
512
527
|
@dataset.exclude([:id1, :id2] => [[1, 2], [3,4]].sql_array).sql.should == "SELECT * FROM test WHERE ((id1, id2) NOT IN ((1, 2), (3, 4)))"
|
513
528
|
@dataset.exclude([:id1, :id2] => [[1, 2], [3,4]]).sql.should == "SELECT * FROM test WHERE ((id1, id2) NOT IN ((1, 2), (3, 4)))"
|
514
529
|
end
|
515
530
|
|
516
531
|
specify "should handle IN/NOT IN queries with multiple columns and an array where the database doesn't support it" do
|
517
532
|
@dataset.meta_def(:supports_multiple_column_in?){false}
|
518
|
-
@dataset.filter([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
|
519
533
|
@dataset.filter([:id1, :id2] => [[1, 2], [3,4]].sql_array).sql.should == "SELECT * FROM test WHERE (((id1 = 1) AND (id2 = 2)) OR ((id1 = 3) AND (id2 = 4)))"
|
520
|
-
@dataset.exclude([:id1, :id2] => []).sql.should == "SELECT * FROM test WHERE (1 = 1)"
|
521
534
|
@dataset.exclude([:id1, :id2] => [[1, 2], [3,4]].sql_array).sql.should == "SELECT * FROM test WHERE (((id1 != 1) OR (id2 != 2)) AND ((id1 != 3) OR (id2 != 4)))"
|
522
535
|
end
|
523
536
|
|
@@ -537,10 +550,25 @@ describe "Dataset#where" do
|
|
537
550
|
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia').columns(:id1, :id2)
|
538
551
|
@dataset.filter([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
|
539
552
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
540
|
-
@dataset.exclude([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (
|
553
|
+
@dataset.exclude([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE ((id1 = id1) AND (id2 = id2))"
|
541
554
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
542
555
|
end
|
543
556
|
|
557
|
+
specify "should handle IN/NOT IN queries with multiple columns and an empty dataset where the database doesn't support it with correct NULL handling" do
|
558
|
+
begin
|
559
|
+
Sequel.empty_array_handle_nulls = false
|
560
|
+
@dataset.meta_def(:supports_multiple_column_in?){false}
|
561
|
+
db = Sequel.mock
|
562
|
+
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia').columns(:id1, :id2)
|
563
|
+
@dataset.filter([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (1 = 0)"
|
564
|
+
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
565
|
+
@dataset.exclude([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (1 = 1)"
|
566
|
+
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
567
|
+
ensure
|
568
|
+
Sequel.empty_array_handle_nulls = true
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
544
572
|
specify "should handle IN/NOT IN queries for datasets with row_procs" do
|
545
573
|
@dataset.meta_def(:supports_multiple_column_in?){false}
|
546
574
|
db = Sequel.mock(:fetch=>[{:id1=>1, :id2=>2}, {:id1=>3, :id2=>4}])
|
@@ -1581,10 +1609,20 @@ describe "Dataset#limit" do
|
|
1581
1609
|
end
|
1582
1610
|
|
1583
1611
|
describe "Dataset#naked" do
|
1584
|
-
specify "should
|
1612
|
+
specify "should returned clone dataset without row_proc" do
|
1585
1613
|
d = Sequel::Dataset.new(nil)
|
1586
1614
|
d.row_proc = Proc.new{|r| r}
|
1587
1615
|
d.naked.row_proc.should be_nil
|
1616
|
+
d.row_proc.should_not be_nil
|
1617
|
+
end
|
1618
|
+
end
|
1619
|
+
|
1620
|
+
describe "Dataset#naked!" do
|
1621
|
+
specify "should remove any existing row_proc" do
|
1622
|
+
d = Sequel::Dataset.new(nil)
|
1623
|
+
d.row_proc = Proc.new{|r| r}
|
1624
|
+
d.naked!.row_proc.should be_nil
|
1625
|
+
d.row_proc.should be_nil
|
1588
1626
|
end
|
1589
1627
|
end
|
1590
1628
|
|
@@ -2778,10 +2816,10 @@ describe "Dataset#multi_insert" do
|
|
2778
2816
|
|
2779
2817
|
specify "should accept string keys as column names" do
|
2780
2818
|
@ds.multi_insert([{'x'=>1, 'y'=>2}, {'x'=>3, 'y'=>4}])
|
2781
|
-
@db.sqls
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2819
|
+
sqls = @db.sqls
|
2820
|
+
["INSERT INTO items (x, y) VALUES (1, 2)", "INSERT INTO items (y, x) VALUES (2, 1)"].should include(sqls.slice!(1))
|
2821
|
+
["INSERT INTO items (x, y) VALUES (3, 4)", "INSERT INTO items (y, x) VALUES (4, 3)"].should include(sqls.slice!(1))
|
2822
|
+
sqls.should == ['BEGIN', 'COMMIT']
|
2785
2823
|
end
|
2786
2824
|
|
2787
2825
|
specify "should not do anything if no hashes are provided" do
|
@@ -3096,12 +3134,16 @@ describe "Dataset prepared statements and bound variables " do
|
|
3096
3134
|
|
3097
3135
|
specify "#call should take a type and bind hash and interpolate it" do
|
3098
3136
|
@ds.filter(:num=>:$n).call(:select, :n=>1)
|
3137
|
+
@ds.filter(:num=>:$n).call([:map, :a], :n=>1)
|
3138
|
+
@ds.filter(:num=>:$n).call([:to_hash, :a, :b], :n=>1)
|
3099
3139
|
@ds.filter(:num=>:$n).call(:first, :n=>1)
|
3100
3140
|
@ds.filter(:num=>:$n).call(:delete, :n=>1)
|
3101
3141
|
@ds.filter(:num=>:$n).call(:update, {:n=>1, :n2=>2}, :num=>:$n2)
|
3102
3142
|
@ds.call(:insert, {:n=>1}, :num=>:$n)
|
3103
3143
|
@ds.call(:insert_select, {:n=>1}, :num=>:$n)
|
3104
3144
|
@db.sqls.should == ['SELECT * FROM items WHERE (num = 1)',
|
3145
|
+
'SELECT * FROM items WHERE (num = 1)',
|
3146
|
+
'SELECT * FROM items WHERE (num = 1)',
|
3105
3147
|
'SELECT * FROM items WHERE (num = 1) LIMIT 1',
|
3106
3148
|
'DELETE FROM items WHERE (num = 1)',
|
3107
3149
|
'UPDATE items SET num = 2 WHERE (num = 1)',
|
@@ -3112,20 +3154,26 @@ describe "Dataset prepared statements and bound variables " do
|
|
3112
3154
|
specify "#prepare should take a type and name and store it in the database for later use with call" do
|
3113
3155
|
pss = []
|
3114
3156
|
pss << @ds.filter(:num=>:$n).prepare(:select, :sn)
|
3157
|
+
pss << @ds.filter(:num=>:$n).prepare([:map, :a], :sm)
|
3158
|
+
pss << @ds.filter(:num=>:$n).prepare([:to_hash, :a, :b], :sh)
|
3115
3159
|
pss << @ds.filter(:num=>:$n).prepare(:first, :fn)
|
3116
3160
|
pss << @ds.filter(:num=>:$n).prepare(:delete, :dn)
|
3117
3161
|
pss << @ds.filter(:num=>:$n).prepare(:update, :un, :num=>:$n2)
|
3118
3162
|
pss << @ds.prepare(:insert, :in, :num=>:$n)
|
3119
3163
|
pss << @ds.prepare(:insert_select, :ins, :num=>:$n)
|
3120
|
-
@db.prepared_statements.keys.sort_by{|k| k.to_s}.should == [:dn, :fn, :in, :ins, :sn, :un]
|
3121
|
-
[:sn, :fn, :dn, :un, :in, :ins].each_with_index{|x, i| @db.prepared_statements[x].should == pss[i]}
|
3164
|
+
@db.prepared_statements.keys.sort_by{|k| k.to_s}.should == [:dn, :fn, :in, :ins, :sh, :sm, :sn, :un]
|
3165
|
+
[:sn, :sm, :sh, :fn, :dn, :un, :in, :ins].each_with_index{|x, i| @db.prepared_statements[x].should == pss[i]}
|
3122
3166
|
@db.call(:sn, :n=>1)
|
3167
|
+
@db.call(:sm, :n=>1)
|
3168
|
+
@db.call(:sh, :n=>1)
|
3123
3169
|
@db.call(:fn, :n=>1)
|
3124
3170
|
@db.call(:dn, :n=>1)
|
3125
3171
|
@db.call(:un, :n=>1, :n2=>2)
|
3126
3172
|
@db.call(:in, :n=>1)
|
3127
3173
|
@db.call(:ins, :n=>1)
|
3128
3174
|
@db.sqls.should == ['SELECT * FROM items WHERE (num = 1)',
|
3175
|
+
'SELECT * FROM items WHERE (num = 1)',
|
3176
|
+
'SELECT * FROM items WHERE (num = 1)',
|
3129
3177
|
'SELECT * FROM items WHERE (num = 1) LIMIT 1',
|
3130
3178
|
'DELETE FROM items WHERE (num = 1)',
|
3131
3179
|
'UPDATE items SET num = 2 WHERE (num = 1)',
|
@@ -3740,6 +3788,12 @@ describe "Sequel::Dataset#select_map" do
|
|
3740
3788
|
@ds.db.sqls.should == ['SELECT a.b FROM t']
|
3741
3789
|
end
|
3742
3790
|
|
3791
|
+
specify "should raise if multiple arguments and can't determine alias" do
|
3792
|
+
proc{@ds.select_map([:a.sql_function, :b])}.should raise_error(Sequel::Error)
|
3793
|
+
proc{@ds.select_map(:a.sql_function){b}}.should raise_error(Sequel::Error)
|
3794
|
+
proc{@ds.select_map{[a{}, b]}}.should raise_error(Sequel::Error)
|
3795
|
+
end
|
3796
|
+
|
3743
3797
|
specify "should handle implicit aliases in arguments" do
|
3744
3798
|
@ds.select_map(:a___b).should == [1, 2]
|
3745
3799
|
@ds.db.sqls.should == ['SELECT a AS b FROM t']
|
@@ -3750,11 +3804,31 @@ describe "Sequel::Dataset#select_map" do
|
|
3750
3804
|
@ds.db.sqls.should == ['SELECT a AS b FROM t']
|
3751
3805
|
end
|
3752
3806
|
|
3807
|
+
specify "should handle identifiers with strings" do
|
3808
|
+
@ds.select_map([Sequel::SQL::Identifier.new('c'), :c]).should == [[1, 1], [2, 2]]
|
3809
|
+
@ds.db.sqls.should == ['SELECT c, c FROM t']
|
3810
|
+
end
|
3811
|
+
|
3753
3812
|
specify "should accept a block" do
|
3754
3813
|
@ds.select_map{a(t__c)}.should == [1, 2]
|
3755
3814
|
@ds.db.sqls.should == ['SELECT a(t.c) FROM t']
|
3756
3815
|
end
|
3757
3816
|
|
3817
|
+
specify "should accept a block with an array of columns" do
|
3818
|
+
@ds.select_map{[a(t__c).as(c), a(t__c).as(c)]}.should == [[1, 1], [2, 2]]
|
3819
|
+
@ds.db.sqls.should == ['SELECT a(t.c) AS c, a(t.c) AS c FROM t']
|
3820
|
+
end
|
3821
|
+
|
3822
|
+
specify "should accept a block with a column" do
|
3823
|
+
@ds.select_map(:c){a(t__c).as(c)}.should == [[1, 1], [2, 2]]
|
3824
|
+
@ds.db.sqls.should == ['SELECT c, a(t.c) AS c FROM t']
|
3825
|
+
end
|
3826
|
+
|
3827
|
+
specify "should accept a block and array of arguments" do
|
3828
|
+
@ds.select_map([:c, :c]){[a(t__c).as(c), a(t__c).as(c)]}.should == [[1, 1, 1, 1], [2, 2, 2, 2]]
|
3829
|
+
@ds.db.sqls.should == ['SELECT c, c, a(t.c) AS c, a(t.c) AS c FROM t']
|
3830
|
+
end
|
3831
|
+
|
3758
3832
|
specify "should handle an array of columns" do
|
3759
3833
|
@ds.select_map([:c, :c]).should == [[1, 1], [2, 2]]
|
3760
3834
|
@ds.db.sqls.should == ['SELECT c, c FROM t']
|
@@ -3783,6 +3857,12 @@ describe "Sequel::Dataset#select_order_map" do
|
|
3783
3857
|
@ds.db.sqls.should == ['SELECT a.b FROM t ORDER BY a.b']
|
3784
3858
|
end
|
3785
3859
|
|
3860
|
+
specify "should raise if multiple arguments and can't determine alias" do
|
3861
|
+
proc{@ds.select_order_map([:a.sql_function, :b])}.should raise_error(Sequel::Error)
|
3862
|
+
proc{@ds.select_order_map(:a.sql_function){b}}.should raise_error(Sequel::Error)
|
3863
|
+
proc{@ds.select_order_map{[a{}, b]}}.should raise_error(Sequel::Error)
|
3864
|
+
end
|
3865
|
+
|
3786
3866
|
specify "should handle implicit aliases in arguments" do
|
3787
3867
|
@ds.select_order_map(:a___b).should == [1, 2]
|
3788
3868
|
@ds.db.sqls.should == ['SELECT a AS b FROM t ORDER BY a']
|
@@ -3808,6 +3888,21 @@ describe "Sequel::Dataset#select_order_map" do
|
|
3808
3888
|
@ds.db.sqls.should == ['SELECT a(t.c) FROM t ORDER BY a(t.c)']
|
3809
3889
|
end
|
3810
3890
|
|
3891
|
+
specify "should accept a block with an array of columns" do
|
3892
|
+
@ds.select_order_map{[c.desc, a(t__c).as(c)]}.should == [[1, 1], [2, 2]]
|
3893
|
+
@ds.db.sqls.should == ['SELECT c, a(t.c) AS c FROM t ORDER BY c DESC, a(t.c)']
|
3894
|
+
end
|
3895
|
+
|
3896
|
+
specify "should accept a block with a column" do
|
3897
|
+
@ds.select_order_map(:c){a(t__c).as(c)}.should == [[1, 1], [2, 2]]
|
3898
|
+
@ds.db.sqls.should == ['SELECT c, a(t.c) AS c FROM t ORDER BY c, a(t.c)']
|
3899
|
+
end
|
3900
|
+
|
3901
|
+
specify "should accept a block and array of arguments" do
|
3902
|
+
@ds.select_order_map([:c, :c]){[a(t__c).as(c), c.desc]}.should == [[1, 1, 1, 1], [2, 2, 2, 2]]
|
3903
|
+
@ds.db.sqls.should == ['SELECT c, c, a(t.c) AS c, c FROM t ORDER BY c, c, a(t.c), c DESC']
|
3904
|
+
end
|
3905
|
+
|
3811
3906
|
specify "should handle an array of columns" do
|
3812
3907
|
@ds.select_order_map([:c, :c]).should == [[1, 1], [2, 2]]
|
3813
3908
|
@ds.db.sqls.should == ['SELECT c, c FROM t ORDER BY c, c']
|
@@ -3873,7 +3968,7 @@ describe "Sequel::Dataset#select_hash" do
|
|
3873
3968
|
end
|
3874
3969
|
|
3875
3970
|
specify "should raise an error if the resulting symbol cannot be determined" do
|
3876
|
-
proc{@ds.select_hash(:c.as(:a),
|
3971
|
+
proc{@ds.select_hash(:c.as(:a), :b.sql_function)}.should raise_error(Sequel::Error)
|
3877
3972
|
end
|
3878
3973
|
end
|
3879
3974
|
|
@@ -24,6 +24,11 @@ describe "ActiveModel plugin" do
|
|
24
24
|
columns :id, :id2
|
25
25
|
def delete; end
|
26
26
|
end
|
27
|
+
module ::Blog
|
28
|
+
class Post < Sequel::Model
|
29
|
+
plugin :active_model
|
30
|
+
end
|
31
|
+
end
|
27
32
|
@c = AMLintTest
|
28
33
|
@c.plugin :active_model
|
29
34
|
@m = @model = @c.new
|
@@ -33,6 +38,7 @@ describe "ActiveModel plugin" do
|
|
33
38
|
def teardown
|
34
39
|
super
|
35
40
|
Object.send(:remove_const, :AMLintTest)
|
41
|
+
Object.send(:remove_const, :Blog)
|
36
42
|
end
|
37
43
|
include ActiveModel::Lint::Tests
|
38
44
|
|
@@ -80,6 +86,13 @@ describe "ActiveModel plugin" do
|
|
80
86
|
assert_equal false, @m.persisted?
|
81
87
|
assert_equal false, @o.persisted?
|
82
88
|
end
|
89
|
+
|
90
|
+
# Should return self, not a proxy object
|
91
|
+
def test__to_partial_path
|
92
|
+
assert_equal 'am_lint_tests/am_lint_test', @m.to_partial_path
|
93
|
+
assert_equal 'blog/posts/post', Blog::Post.new.to_partial_path
|
94
|
+
end
|
95
|
+
|
83
96
|
end
|
84
97
|
if defined?(MiniTest::Unit)
|
85
98
|
tc.instance_methods.map{|x| x.to_s}.reject{|n| n !~ /\Atest_/}.each do |m|
|
@@ -101,52 +101,52 @@ describe Sequel::Model, "many_through_many" do
|
|
101
101
|
|
102
102
|
it "should allowing filtering by many_through_many associations" do
|
103
103
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
104
|
-
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
104
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
105
105
|
end
|
106
106
|
|
107
107
|
it "should allowing filtering by many_through_many associations with a single through table" do
|
108
108
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id]]
|
109
|
-
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (id IN (SELECT albums_artists.artist_id FROM albums_artists WHERE ((albums_artists.album_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
109
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists WHERE ((albums_artists.album_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
110
110
|
end
|
111
111
|
|
112
112
|
it "should allowing filtering by many_through_many associations with aliased tables" do
|
113
113
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums_artists, :id, :id], [:albums_artists, :album_id, :tag_id]]
|
114
|
-
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.id = albums_artists.album_id) INNER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.album_id = albums_artists_0.id) WHERE ((albums_artists_1.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
114
|
+
@c1.filter(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.id = albums_artists.album_id) INNER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.album_id = albums_artists_0.id) WHERE ((albums_artists_1.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL))))'
|
115
115
|
end
|
116
116
|
|
117
117
|
it "should allowing filtering by many_through_many associations with composite keys" do
|
118
118
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
119
|
-
@c1.filter(:tags=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE ((id, yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
119
|
+
@c1.filter(:tags=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
120
120
|
end
|
121
121
|
|
122
122
|
it "should allowing excluding by many_through_many associations" do
|
123
123
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
124
|
-
@c1.exclude(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE ((id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL)))) OR (id IS NULL))'
|
124
|
+
@c1.exclude(:tags=>@c2.load(:id=>1234)).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id = 1234) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
125
125
|
end
|
126
126
|
|
127
127
|
it "should allowing excluding by many_through_many associations with composite keys" do
|
128
128
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
129
|
-
@c1.exclude(:tags=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE (((id, yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (id IS NULL) OR (yyy IS NULL))'
|
129
|
+
@c1.exclude(:tags=>@c2.load(:h1=>1234, :h2=>85)).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE ((albums_tags.g1 = 1234) AND (albums_tags.g2 = 85) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
130
130
|
end
|
131
131
|
|
132
132
|
it "should allowing filtering by multiple many_through_many associations" do
|
133
133
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
134
|
-
@c1.filter(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE (id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL))))'
|
134
|
+
@c1.filter(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL))))'
|
135
135
|
end
|
136
136
|
|
137
137
|
it "should allowing filtering by multiple many_through_many associations with composite keys" do
|
138
138
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
139
|
-
@c1.filter(:tags=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE ((id, yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
139
|
+
@c1.filter(:tags=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
140
140
|
end
|
141
141
|
|
142
142
|
it "should allowing excluding by multiple many_through_many associations" do
|
143
143
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
144
|
-
@c1.exclude(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE ((id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL)))) OR (id IS NULL))'
|
144
|
+
@c1.exclude(:tags=>[@c2.load(:id=>1234), @c2.load(:id=>2345)]).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (1234, 2345)) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
145
145
|
end
|
146
146
|
|
147
147
|
it "should allowing excluding by multiple many_through_many associations with composite keys" do
|
148
148
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
149
|
-
@c1.exclude(:tags=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE (((id, yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (id IS NULL) OR (yyy IS NULL))'
|
149
|
+
@c1.exclude(:tags=>[@c2.load(:h1=>1234, :h2=>85), @c2.load(:h1=>2345, :h2=>95)]).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN ((1234, 85), (2345, 95))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
150
150
|
end
|
151
151
|
|
152
152
|
it "should allowing filtering/excluding many_through_many associations with NULL values" do
|
@@ -157,22 +157,22 @@ describe Sequel::Model, "many_through_many" do
|
|
157
157
|
|
158
158
|
it "should allowing filtering by many_through_many association datasets" do
|
159
159
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
160
|
-
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT id FROM tags WHERE ((x = 1) AND (id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL))))'
|
160
|
+
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL))))'
|
161
161
|
end
|
162
162
|
|
163
163
|
it "should allowing filtering by many_through_many association datasets with composite keys" do
|
164
164
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
165
|
-
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((id, yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT h1, h2 FROM tags WHERE ((x = 1) AND (h1 IS NOT NULL) AND (h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
165
|
+
@c1.filter(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT tags.h1, tags.h2 FROM tags WHERE ((x = 1) AND (tags.h1 IS NOT NULL) AND (tags.h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL))))'
|
166
166
|
end
|
167
167
|
|
168
168
|
it "should allowing excluding by many_through_many association datasets" do
|
169
169
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
|
170
|
-
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT id FROM tags WHERE ((x = 1) AND (id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL)))) OR (id IS NULL))'
|
170
|
+
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE ((artists.id NOT IN (SELECT albums_artists.artist_id FROM albums_artists INNER JOIN albums ON (albums.id = albums_artists.album_id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE ((albums_tags.tag_id IN (SELECT tags.id FROM tags WHERE ((x = 1) AND (tags.id IS NOT NULL)))) AND (albums_artists.artist_id IS NOT NULL)))) OR (artists.id IS NULL))'
|
171
171
|
end
|
172
172
|
|
173
173
|
it "should allowing excluding by many_through_many association datasets with composite keys" do
|
174
174
|
@c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
|
175
|
-
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (((id, yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT h1, h2 FROM tags WHERE ((x = 1) AND (h1 IS NOT NULL) AND (h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (id IS NULL) OR (yyy IS NULL))'
|
175
|
+
@c1.exclude(:tags=>@c2.filter(:x=>1)).sql.should == 'SELECT * FROM artists WHERE (((artists.id, artists.yyy) NOT IN (SELECT albums_artists.b1, albums_artists.b2 FROM albums_artists INNER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) INNER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) WHERE (((albums_tags.g1, albums_tags.g2) IN (SELECT tags.h1, tags.h2 FROM tags WHERE ((x = 1) AND (tags.h1 IS NOT NULL) AND (tags.h2 IS NOT NULL)))) AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL)))) OR (artists.id IS NULL) OR (artists.yyy IS NULL))'
|
176
176
|
end
|
177
177
|
|
178
178
|
it "should support a :conditions option" do
|
@@ -17,6 +17,12 @@ describe "Dataset#query" do
|
|
17
17
|
@d = Sequel::Dataset.new(nil)
|
18
18
|
end
|
19
19
|
|
20
|
+
specify "should allow cloning without arguments" do
|
21
|
+
q = @d.query {clone}
|
22
|
+
q.class.should == @d.class
|
23
|
+
q.sql.should == "SELECT *"
|
24
|
+
end
|
25
|
+
|
20
26
|
specify "should support #from" do
|
21
27
|
q = @d.query {from :xxx}
|
22
28
|
q.class.should == @d.class
|
@@ -9,12 +9,20 @@ describe "serialization_modification_detection plugin" do
|
|
9
9
|
plugin :serialization, :yaml, :h
|
10
10
|
plugin :serialization_modification_detection
|
11
11
|
end
|
12
|
-
@o1 = @c.new
|
12
|
+
@o1 = @c.new(:h=>{})
|
13
13
|
@o2 = @c.load(:id=>1, :h=>"--- {}\n\n")
|
14
|
+
@o3 = @c.new
|
15
|
+
@o4 = @c.load(:id=>1, :h=>nil)
|
14
16
|
MODEL_DB.reset
|
15
17
|
end
|
16
18
|
|
17
19
|
it "should not detect columns that haven't been changed" do
|
20
|
+
@o1.changed_columns.should == []
|
21
|
+
@o1.h.should == {}
|
22
|
+
@o1.h[1] = 2
|
23
|
+
@o1.h.clear
|
24
|
+
@o1.changed_columns.should == []
|
25
|
+
|
18
26
|
@o2.changed_columns.should == []
|
19
27
|
@o2.h.should == {}
|
20
28
|
@o2.h[1] = 2
|
@@ -23,15 +31,42 @@ describe "serialization_modification_detection plugin" do
|
|
23
31
|
end
|
24
32
|
|
25
33
|
it "should detect columns that have been changed" do
|
34
|
+
@o1.changed_columns.should == []
|
35
|
+
@o1.h.should == {}
|
36
|
+
@o1.h[1] = 2
|
37
|
+
@o1.changed_columns.should == [:h]
|
38
|
+
|
26
39
|
@o2.changed_columns.should == []
|
27
40
|
@o2.h.should == {}
|
28
41
|
@o2.h[1] = 2
|
29
42
|
@o2.changed_columns.should == [:h]
|
43
|
+
|
44
|
+
@o3.changed_columns.should == []
|
45
|
+
@o3.h.should == nil
|
46
|
+
@o3.h = {}
|
47
|
+
@o3.changed_columns.should == [:h]
|
48
|
+
|
49
|
+
@o4.changed_columns.should == []
|
50
|
+
@o4.h.should == nil
|
51
|
+
@o4.h = {}
|
52
|
+
@o4.changed_columns.should == [:h]
|
30
53
|
end
|
31
54
|
|
32
55
|
it "should report correct changed_columns after saving" do
|
56
|
+
@o1.h[1] = 2
|
57
|
+
@o1.save
|
58
|
+
@o1.changed_columns.should == []
|
59
|
+
|
33
60
|
@o2.h[1] = 2
|
34
61
|
@o2.save_changes
|
35
62
|
@o2.changed_columns.should == []
|
63
|
+
|
64
|
+
@o3.h = {1=>2}
|
65
|
+
@o3.save
|
66
|
+
@o3.changed_columns.should == []
|
67
|
+
|
68
|
+
@o4.h = {1=>2}
|
69
|
+
@o4.save
|
70
|
+
@o4.changed_columns.should == []
|
36
71
|
end
|
37
72
|
end
|