sequel 3.21.0 → 3.24.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 +112 -0
- data/README.rdoc +15 -1
- data/doc/association_basics.rdoc +159 -40
- data/doc/model_hooks.rdoc +64 -27
- data/doc/prepared_statements.rdoc +8 -4
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +2 -1
- data/lib/sequel/adapters/db2.rb +8 -1
- data/lib/sequel/adapters/firebird.rb +25 -9
- data/lib/sequel/adapters/informix.rb +4 -19
- data/lib/sequel/adapters/jdbc/h2.rb +5 -0
- data/lib/sequel/adapters/jdbc/informix.rb +31 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +46 -0
- data/lib/sequel/adapters/jdbc.rb +39 -20
- data/lib/sequel/adapters/odbc.rb +2 -0
- data/lib/sequel/adapters/oracle.rb +12 -0
- data/lib/sequel/adapters/postgres.rb +30 -1
- data/lib/sequel/adapters/shared/access.rb +10 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +106 -11
- data/lib/sequel/adapters/shared/mysql.rb +25 -7
- data/lib/sequel/adapters/shared/postgres.rb +39 -6
- data/lib/sequel/adapters/shared/sqlite.rb +57 -5
- data/lib/sequel/adapters/sqlite.rb +8 -3
- data/lib/sequel/adapters/swift/mysql.rb +9 -0
- data/lib/sequel/adapters/tinytds.rb +4 -3
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/misc.rb +6 -0
- data/lib/sequel/database/query.rb +33 -3
- data/lib/sequel/database/schema_methods.rb +13 -4
- data/lib/sequel/dataset/features.rb +6 -0
- data/lib/sequel/dataset/prepared_statements.rb +17 -2
- data/lib/sequel/dataset/query.rb +17 -0
- data/lib/sequel/dataset/sql.rb +2 -53
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +4 -3
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +234 -32
- data/lib/sequel/model/base.rb +187 -60
- data/lib/sequel/model/exceptions.rb +3 -1
- data/lib/sequel/model.rb +5 -0
- data/lib/sequel/plugins/association_pks.rb +6 -4
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/identity_map.rb +2 -2
- data/lib/sequel/plugins/many_through_many.rb +33 -3
- data/lib/sequel/plugins/prepared_statements.rb +140 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +72 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -0
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +8 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +36 -0
- data/spec/adapters/mysql_spec.rb +6 -0
- data/spec/adapters/postgres_spec.rb +43 -18
- data/spec/adapters/spec_helper.rb +5 -0
- data/spec/core/connection_pool_spec.rb +56 -77
- data/spec/core/database_spec.rb +33 -0
- data/spec/core/dataset_spec.rb +127 -16
- data/spec/core/expression_filters_spec.rb +13 -0
- data/spec/core/schema_spec.rb +13 -1
- data/spec/core/spec_helper.rb +5 -0
- data/spec/extensions/association_pks_spec.rb +7 -0
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/many_through_many_spec.rb +77 -0
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/nested_attributes_spec.rb +1 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +69 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +36 -0
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +3 -1
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/xml_serializer_spec.rb +12 -0
- data/spec/integration/associations_test.rb +212 -0
- data/spec/integration/dataset_test.rb +8 -1
- data/spec/integration/plugin_test.rb +134 -0
- data/spec/integration/prepared_statement_test.rb +72 -1
- data/spec/integration/schema_test.rb +66 -8
- data/spec/integration/spec_helper.rb +5 -0
- data/spec/integration/transaction_test.rb +40 -0
- data/spec/integration/type_test.rb +7 -0
- data/spec/model/associations_spec.rb +463 -5
- data/spec/model/base_spec.rb +59 -0
- data/spec/model/eager_loading_spec.rb +269 -1
- data/spec/model/hooks_spec.rb +161 -0
- data/spec/model/record_spec.rb +30 -0
- data/spec/model/spec_helper.rb +5 -0
- metadata +29 -4
|
@@ -357,6 +357,28 @@ describe Sequel::Model, "many_to_one" do
|
|
|
357
357
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
|
358
358
|
end
|
|
359
359
|
|
|
360
|
+
it "should use a callback if given one as the argument" do
|
|
361
|
+
@c2.many_to_one :parent, :class => @c2
|
|
362
|
+
|
|
363
|
+
d = @c2.create(:id => 1)
|
|
364
|
+
MODEL_DB.reset
|
|
365
|
+
d.parent_id = 234
|
|
366
|
+
d.associations[:parent] = 42
|
|
367
|
+
d.parent(proc{|ds| ds.filter{name > 'M'}}).should_not == 42
|
|
368
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
it "should use a block given to the association method as a callback on ruby 1.8.7+" do
|
|
372
|
+
@c2.many_to_one :parent, :class => @c2
|
|
373
|
+
|
|
374
|
+
d = @c2.create(:id => 1)
|
|
375
|
+
MODEL_DB.reset
|
|
376
|
+
d.parent_id = 234
|
|
377
|
+
d.associations[:parent] = 42
|
|
378
|
+
d.parent{|ds| ds.filter{name > 'M'}}.should_not == 42
|
|
379
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
|
|
380
|
+
end if RUBY_VERSION >= '1.8.7'
|
|
381
|
+
|
|
360
382
|
it "should have the setter add to the reciprocal one_to_many cached association list if it exists" do
|
|
361
383
|
@c2.many_to_one :parent, :class => @c2
|
|
362
384
|
@c2.one_to_many :children, :class => @c2, :key=>:parent_id
|
|
@@ -1149,6 +1171,16 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1149
1171
|
v.model.should == Historical::Value
|
|
1150
1172
|
end
|
|
1151
1173
|
|
|
1174
|
+
it "should use a callback if given one as the argument" do
|
|
1175
|
+
@c2.one_to_many :attributes, :class => @c1, :key => :nodeid
|
|
1176
|
+
|
|
1177
|
+
d = @c2.create(:id => 1234)
|
|
1178
|
+
MODEL_DB.reset
|
|
1179
|
+
d.associations[:attributes] = []
|
|
1180
|
+
d.attributes(proc{|ds| ds.filter{name > 'M'}}).should_not == []
|
|
1181
|
+
MODEL_DB.sqls.should == ["SELECT * FROM attributes WHERE ((attributes.nodeid = 1234) AND (name > 'M'))"]
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1152
1184
|
it "should use explicit key if given" do
|
|
1153
1185
|
@c2.one_to_many :attributes, :class => @c1, :key => :nodeid
|
|
1154
1186
|
|
|
@@ -1338,7 +1370,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1338
1370
|
@c2.one_to_many :attributes, :class => @c1
|
|
1339
1371
|
n = @c2.new(:id => 1234)
|
|
1340
1372
|
a = @c1.new(:id => 2345)
|
|
1341
|
-
def a.
|
|
1373
|
+
def a.validate() errors.add(:id, 'foo') end
|
|
1342
1374
|
proc{n.add_attribute(a)}.should raise_error(Sequel::Error)
|
|
1343
1375
|
proc{n.remove_attribute(a)}.should raise_error(Sequel::Error)
|
|
1344
1376
|
end
|
|
@@ -1347,7 +1379,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1347
1379
|
@c2.one_to_many :attributes, :class => @c1, :validate=>false
|
|
1348
1380
|
n = @c2.new(:id => 1234)
|
|
1349
1381
|
a = @c1.new(:id => 2345)
|
|
1350
|
-
def a.
|
|
1382
|
+
def a.validate() errors.add(:id, 'foo') end
|
|
1351
1383
|
n.add_attribute(a).should == a
|
|
1352
1384
|
n.remove_attribute(a).should == a
|
|
1353
1385
|
end
|
|
@@ -2250,7 +2282,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2250
2282
|
@c2.many_to_many :attributes, :class => @c1
|
|
2251
2283
|
n = @c1.new
|
|
2252
2284
|
a = @c2.load(:id=>123)
|
|
2253
|
-
def n.
|
|
2285
|
+
def n.validate() errors.add(:id, 'foo') end
|
|
2254
2286
|
proc{a.add_attribute(n)}.should raise_error(Sequel::ValidationFailed)
|
|
2255
2287
|
end
|
|
2256
2288
|
|
|
@@ -2259,7 +2291,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2259
2291
|
n = @c1.new
|
|
2260
2292
|
n.raise_on_save_failure = false
|
|
2261
2293
|
a = @c2.load(:id=>123)
|
|
2262
|
-
def n.
|
|
2294
|
+
def n.validate() errors.add(:id, 'foo') end
|
|
2263
2295
|
proc{a.add_attribute(n)}.should raise_error(Sequel::Error)
|
|
2264
2296
|
end
|
|
2265
2297
|
|
|
@@ -2267,7 +2299,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2267
2299
|
@c2.many_to_many :attributes, :class => @c1, :validate=>false
|
|
2268
2300
|
n = @c1.new
|
|
2269
2301
|
a = @c2.load(:id=>123)
|
|
2270
|
-
def n.
|
|
2302
|
+
def n.validate() errors.add(:id, 'foo') end
|
|
2271
2303
|
a.add_attribute(n)
|
|
2272
2304
|
n.new?.should == false
|
|
2273
2305
|
end
|
|
@@ -2724,3 +2756,429 @@ describe Sequel::Model, " association reflection methods" do
|
|
|
2724
2756
|
c.instance_methods.map{|x| x.to_s}.should include('parent')
|
|
2725
2757
|
end
|
|
2726
2758
|
end
|
|
2759
|
+
|
|
2760
|
+
describe "Filtering by associations" do
|
|
2761
|
+
before do
|
|
2762
|
+
@Album = Class.new(Sequel::Model(:albums))
|
|
2763
|
+
artist = @Artist = Class.new(Sequel::Model(:artists))
|
|
2764
|
+
tag = @Tag = Class.new(Sequel::Model(:tags))
|
|
2765
|
+
track = @Track = Class.new(Sequel::Model(:tracks))
|
|
2766
|
+
album_info = @AlbumInfo = Class.new(Sequel::Model(:album_infos))
|
|
2767
|
+
@Artist.columns :id, :id1, :id2
|
|
2768
|
+
@Tag.columns :id, :tid1, :tid2
|
|
2769
|
+
@Track.columns :id, :album_id, :album_id1, :album_id2
|
|
2770
|
+
@AlbumInfo.columns :id, :album_id, :album_id1, :album_id2
|
|
2771
|
+
@Album.class_eval do
|
|
2772
|
+
columns :id, :id1, :id2, :artist_id, :artist_id1, :artist_id2
|
|
2773
|
+
many_to_one :artist, :class=>artist
|
|
2774
|
+
one_to_many :tracks, :class=>track, :key=>:album_id
|
|
2775
|
+
one_to_one :album_info, :class=>album_info, :key=>:album_id
|
|
2776
|
+
many_to_many :tags, :class=>tag, :left_key=>:album_id, :join_table=>:albums_tags
|
|
2777
|
+
|
|
2778
|
+
many_to_one :cartist, :class=>artist, :key=>[:artist_id1, :artist_id2], :primary_key=>[:id1, :id2]
|
|
2779
|
+
one_to_many :ctracks, :class=>track, :key=>[:album_id1, :album_id2], :primary_key=>[:id1, :id2]
|
|
2780
|
+
one_to_one :calbum_info, :class=>album_info, :key=>[:album_id1, :album_id2], :primary_key=>[:id1, :id2]
|
|
2781
|
+
many_to_many :ctags, :class=>tag, :left_key=>[:album_id1, :album_id2], :left_primary_key=>[:id1, :id2], :right_key=>[:tag_id1, :tag_id2], :right_primary_key=>[:tid1, :tid2], :join_table=>:albums_tags
|
|
2782
|
+
end
|
|
2783
|
+
end
|
|
2784
|
+
|
|
2785
|
+
it "should be able to filter on many_to_one associations" do
|
|
2786
|
+
@Album.filter(:artist=>@Artist.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE (artist_id = 3)'
|
|
2787
|
+
end
|
|
2788
|
+
|
|
2789
|
+
it "should be able to filter on one_to_many associations" do
|
|
2790
|
+
@Album.filter(:tracks=>@Track.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE (id = 3)'
|
|
2791
|
+
end
|
|
2792
|
+
|
|
2793
|
+
it "should be able to filter on one_to_one associations" do
|
|
2794
|
+
@Album.filter(:album_info=>@AlbumInfo.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE (id = 3)'
|
|
2795
|
+
end
|
|
2796
|
+
|
|
2797
|
+
it "should be able to filter on many_to_many associations" do
|
|
2798
|
+
@Album.filter(:tags=>@Tag.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE (id IN (SELECT album_id FROM albums_tags WHERE ((tag_id = 3) AND (album_id IS NOT NULL))))'
|
|
2799
|
+
end
|
|
2800
|
+
|
|
2801
|
+
it "should be able to filter on many_to_one associations with composite keys" do
|
|
2802
|
+
@Album.filter(:cartist=>@Artist.load(:id1=>3, :id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((artist_id1 = 3) AND (artist_id2 = 4))'
|
|
2803
|
+
end
|
|
2804
|
+
|
|
2805
|
+
it "should be able to filter on one_to_many associations with composite keys" do
|
|
2806
|
+
@Album.filter(:ctracks=>@Track.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((id1 = 3) AND (id2 = 4))'
|
|
2807
|
+
end
|
|
2808
|
+
|
|
2809
|
+
it "should be able to filter on one_to_one associations with composite keys" do
|
|
2810
|
+
@Album.filter(:calbum_info=>@AlbumInfo.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((id1 = 3) AND (id2 = 4))'
|
|
2811
|
+
end
|
|
2812
|
+
|
|
2813
|
+
it "should be able to filter on many_to_many associations with composite keys" do
|
|
2814
|
+
@Album.filter(:ctags=>@Tag.load(:tid1=>3, :tid2=>4)).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN (SELECT album_id1, album_id2 FROM albums_tags WHERE ((tag_id1 = 3) AND (tag_id2 = 4) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL))))'
|
|
2815
|
+
end
|
|
2816
|
+
|
|
2817
|
+
it "should work inside a complex filter" do
|
|
2818
|
+
artist = @Artist.load(:id=>3)
|
|
2819
|
+
@Album.filter{foo & {:artist=>artist}}.sql.should == 'SELECT * FROM albums WHERE (foo AND (artist_id = 3))'
|
|
2820
|
+
track = @Track.load(:album_id=>4)
|
|
2821
|
+
@Album.filter{foo & [[:artist, artist], [:tracks, track]]}.sql.should == 'SELECT * FROM albums WHERE (foo AND (artist_id = 3) AND (id = 4))'
|
|
2822
|
+
end
|
|
2823
|
+
|
|
2824
|
+
it "should raise for an invalid association name" do
|
|
2825
|
+
proc{@Album.filter(:foo=>@Artist.load(:id=>3)).sql}.should raise_error(Sequel::Error)
|
|
2826
|
+
end
|
|
2827
|
+
|
|
2828
|
+
it "should raise for an invalid association type" do
|
|
2829
|
+
@Album.many_to_many :iatags, :clone=>:tags
|
|
2830
|
+
@Album.association_reflection(:iatags)[:type] = :foo
|
|
2831
|
+
proc{@Album.filter(:iatags=>@Tag.load(:id=>3)).sql}.should raise_error(Sequel::Error)
|
|
2832
|
+
end
|
|
2833
|
+
|
|
2834
|
+
it "should raise for an invalid associated object class " do
|
|
2835
|
+
proc{@Album.filter(:tags=>@Artist.load(:id=>3)).sql}.should raise_error(Sequel::Error)
|
|
2836
|
+
end
|
|
2837
|
+
|
|
2838
|
+
it "should raise for an invalid associated object class when multiple objects are used" do
|
|
2839
|
+
proc{@Album.filter(:tags=>[@Tag.load(:id=>3), @Artist.load(:id=>3)]).sql}.should raise_error(Sequel::Error)
|
|
2840
|
+
end
|
|
2841
|
+
|
|
2842
|
+
it "should correctly handle case when a multiple value association is used" do
|
|
2843
|
+
proc{@Album.filter(:tags=>[@Tag.load(:id=>3), @Artist.load(:id=>3)]).sql}.should raise_error(Sequel::Error)
|
|
2844
|
+
end
|
|
2845
|
+
|
|
2846
|
+
it "should not affect non-association IN/NOT IN filtering with an empty array" do
|
|
2847
|
+
@Album.filter(:tag_id=>[]).sql.should == 'SELECT * FROM albums WHERE (tag_id != tag_id)'
|
|
2848
|
+
@Album.exclude(:tag_id=>[]).sql.should == 'SELECT * FROM albums WHERE (1 = 1)'
|
|
2849
|
+
end
|
|
2850
|
+
|
|
2851
|
+
it "should work correctly in subclasses" do
|
|
2852
|
+
c = Class.new(@Album)
|
|
2853
|
+
c.many_to_one :sartist, :class=>@Artist
|
|
2854
|
+
c.filter(:sartist=>@Artist.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE (sartist_id = 3)'
|
|
2855
|
+
end
|
|
2856
|
+
|
|
2857
|
+
it "should be able to exclude on many_to_one associations" do
|
|
2858
|
+
@Album.exclude(:artist=>@Artist.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE ((artist_id != 3) OR (artist_id IS NULL))'
|
|
2859
|
+
end
|
|
2860
|
+
|
|
2861
|
+
it "should be able to exclude on one_to_many associations" do
|
|
2862
|
+
@Album.exclude(:tracks=>@Track.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE ((id != 3) OR (id IS NULL))'
|
|
2863
|
+
end
|
|
2864
|
+
|
|
2865
|
+
it "should be able to exclude on one_to_one associations" do
|
|
2866
|
+
@Album.exclude(:album_info=>@AlbumInfo.load(:album_id=>3)).sql.should == 'SELECT * FROM albums WHERE ((id != 3) OR (id IS NULL))'
|
|
2867
|
+
end
|
|
2868
|
+
|
|
2869
|
+
it "should be able to exclude on many_to_many associations" do
|
|
2870
|
+
@Album.exclude(:tags=>@Tag.load(:id=>3)).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (SELECT album_id FROM albums_tags WHERE ((tag_id = 3) AND (album_id IS NOT NULL)))) OR (id IS NULL))'
|
|
2871
|
+
end
|
|
2872
|
+
|
|
2873
|
+
it "should be able to exclude on many_to_one associations with composite keys" do
|
|
2874
|
+
@Album.exclude(:cartist=>@Artist.load(:id1=>3, :id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((artist_id1 != 3) OR (artist_id2 != 4) OR (artist_id1 IS NULL) OR (artist_id2 IS NULL))'
|
|
2875
|
+
end
|
|
2876
|
+
|
|
2877
|
+
it "should be able to exclude on one_to_many associations with composite keys" do
|
|
2878
|
+
@Album.exclude(:ctracks=>@Track.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((id1 != 3) OR (id2 != 4) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
2879
|
+
end
|
|
2880
|
+
|
|
2881
|
+
it "should be able to exclude on one_to_one associations with composite keys" do
|
|
2882
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.load(:album_id1=>3, :album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE ((id1 != 3) OR (id2 != 4) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
2883
|
+
end
|
|
2884
|
+
|
|
2885
|
+
it "should be able to exclude on many_to_many associations with composite keys" do
|
|
2886
|
+
@Album.exclude(:ctags=>@Tag.load(:tid1=>3, :tid2=>4)).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN (SELECT album_id1, album_id2 FROM albums_tags WHERE ((tag_id1 = 3) AND (tag_id2 = 4) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL)))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
2887
|
+
end
|
|
2888
|
+
|
|
2889
|
+
it "should be able to filter on multiple many_to_one associations" do
|
|
2890
|
+
@Album.filter(:artist=>[@Artist.load(:id=>3), @Artist.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE (artist_id IN (3, 4))'
|
|
2891
|
+
end
|
|
2892
|
+
|
|
2893
|
+
it "should be able to filter on multiple one_to_many associations" do
|
|
2894
|
+
@Album.filter(:tracks=>[@Track.load(:album_id=>3), @Track.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE (id IN (3, 4))'
|
|
2895
|
+
end
|
|
2896
|
+
|
|
2897
|
+
it "should be able to filter on multiple one_to_one associations" do
|
|
2898
|
+
@Album.filter(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE (id IN (3, 4))'
|
|
2899
|
+
end
|
|
2900
|
+
|
|
2901
|
+
it "should be able to filter on multiple many_to_many associations" do
|
|
2902
|
+
@Album.filter(:tags=>[@Tag.load(:id=>3), @Tag.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE (id IN (SELECT album_id FROM albums_tags WHERE ((tag_id IN (3, 4)) AND (album_id IS NOT NULL))))'
|
|
2903
|
+
end
|
|
2904
|
+
|
|
2905
|
+
it "should be able to filter on multiple many_to_one associations with composite keys" do
|
|
2906
|
+
@Album.filter(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>5, :id2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((artist_id1, artist_id2) IN ((3, 4), (5, 6)))'
|
|
2907
|
+
end
|
|
2908
|
+
|
|
2909
|
+
it "should be able to filter on multiple one_to_many associations with composite keys" do
|
|
2910
|
+
@Album.filter(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN ((3, 4), (5, 6)))'
|
|
2911
|
+
end
|
|
2912
|
+
|
|
2913
|
+
it "should be able to filter on multiple one_to_one associations with composite keys" do
|
|
2914
|
+
@Album.filter(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN ((3, 4), (5, 6)))'
|
|
2915
|
+
end
|
|
2916
|
+
|
|
2917
|
+
it "should be able to filter on multiple many_to_many associations with composite keys" do
|
|
2918
|
+
@Album.filter(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5, :tid2=>6)]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN ((3, 4), (5, 6))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL))))'
|
|
2919
|
+
end
|
|
2920
|
+
|
|
2921
|
+
it "should be able to exclude on multiple many_to_one associations" do
|
|
2922
|
+
@Album.exclude(:artist=>[@Artist.load(:id=>3), @Artist.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((artist_id NOT IN (3, 4)) OR (artist_id IS NULL))'
|
|
2923
|
+
end
|
|
2924
|
+
|
|
2925
|
+
it "should be able to exclude on multiple one_to_many associations" do
|
|
2926
|
+
@Album.exclude(:tracks=>[@Track.load(:album_id=>3), @Track.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (3, 4)) OR (id IS NULL))'
|
|
2927
|
+
end
|
|
2928
|
+
|
|
2929
|
+
it "should be able to exclude on multiple one_to_one associations" do
|
|
2930
|
+
@Album.exclude(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.load(:album_id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (3, 4)) OR (id IS NULL))'
|
|
2931
|
+
end
|
|
2932
|
+
|
|
2933
|
+
it "should be able to exclude on multiple many_to_many associations" do
|
|
2934
|
+
@Album.exclude(:tags=>[@Tag.load(:id=>3), @Tag.load(:id=>4)]).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (SELECT album_id FROM albums_tags WHERE ((tag_id IN (3, 4)) AND (album_id IS NOT NULL)))) OR (id IS NULL))'
|
|
2935
|
+
end
|
|
2936
|
+
|
|
2937
|
+
it "should be able to exclude on multiple many_to_one associations with composite keys" do
|
|
2938
|
+
@Album.exclude(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>5, :id2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((artist_id1, artist_id2) NOT IN ((3, 4), (5, 6))) OR (artist_id1 IS NULL) OR (artist_id2 IS NULL))'
|
|
2939
|
+
end
|
|
2940
|
+
|
|
2941
|
+
it "should be able to exclude on multiple one_to_many associations with composite keys" do
|
|
2942
|
+
@Album.exclude(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN ((3, 4), (5, 6))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
2943
|
+
end
|
|
2944
|
+
|
|
2945
|
+
it "should be able to exclude on multiple one_to_one associations with composite keys" do
|
|
2946
|
+
@Album.exclude(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5, :album_id2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN ((3, 4), (5, 6))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
2947
|
+
end
|
|
2948
|
+
|
|
2949
|
+
it "should be able to exclude on multiple many_to_many associations with composite keys" do
|
|
2950
|
+
@Album.exclude(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5, :tid2=>6)]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN ((3, 4), (5, 6))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL)))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
2951
|
+
end
|
|
2952
|
+
|
|
2953
|
+
it "should be able to handle NULL values when filtering many_to_one associations" do
|
|
2954
|
+
@Album.filter(:artist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2955
|
+
end
|
|
2956
|
+
|
|
2957
|
+
it "should be able to handle NULL values when filtering one_to_many associations" do
|
|
2958
|
+
@Album.filter(:tracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2959
|
+
end
|
|
2960
|
+
|
|
2961
|
+
it "should be able to handle NULL values when filtering one_to_one associations" do
|
|
2962
|
+
@Album.filter(:album_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2963
|
+
end
|
|
2964
|
+
|
|
2965
|
+
it "should be able to handle NULL values when filtering many_to_many associations" do
|
|
2966
|
+
@Album.filter(:tags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2967
|
+
end
|
|
2968
|
+
|
|
2969
|
+
it "should be able to handle filteringing with NULL values for many_to_one associations with composite keys" do
|
|
2970
|
+
@Album.filter(:cartist=>@Artist.load(:id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2971
|
+
@Album.filter(:cartist=>@Artist.load(:id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2972
|
+
@Album.filter(:cartist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2973
|
+
end
|
|
2974
|
+
|
|
2975
|
+
it "should be able to filtering with NULL values for one_to_many associations with composite keys" do
|
|
2976
|
+
@Album.filter(:ctracks=>@Track.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2977
|
+
@Album.filter(:ctracks=>@Track.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2978
|
+
@Album.filter(:ctracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2979
|
+
end
|
|
2980
|
+
|
|
2981
|
+
it "should be able to filtering with NULL values for one_to_one associations with composite keys" do
|
|
2982
|
+
@Album.filter(:calbum_info=>@AlbumInfo.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2983
|
+
@Album.filter(:calbum_info=>@AlbumInfo.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2984
|
+
@Album.filter(:calbum_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2985
|
+
end
|
|
2986
|
+
|
|
2987
|
+
it "should be able to filtering with NULL values for many_to_many associations with composite keys" do
|
|
2988
|
+
@Album.filter(:ctags=>@Tag.load(:tid1=>3)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2989
|
+
@Album.filter(:ctags=>@Tag.load(:tid2=>4)).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2990
|
+
@Album.filter(:ctags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
2991
|
+
end
|
|
2992
|
+
|
|
2993
|
+
it "should be able to handle NULL values when excluding many_to_one associations" do
|
|
2994
|
+
@Album.exclude(:artist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2995
|
+
end
|
|
2996
|
+
|
|
2997
|
+
it "should be able to handle NULL values when excluding one_to_many associations" do
|
|
2998
|
+
@Album.exclude(:tracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
2999
|
+
end
|
|
3000
|
+
|
|
3001
|
+
it "should be able to handle NULL values when excluding one_to_one associations" do
|
|
3002
|
+
@Album.exclude(:album_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3003
|
+
end
|
|
3004
|
+
|
|
3005
|
+
it "should be able to handle NULL values when excluding many_to_many associations" do
|
|
3006
|
+
@Album.exclude(:tags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3007
|
+
end
|
|
3008
|
+
|
|
3009
|
+
it "should be able to handle excluding with NULL values for many_to_one associations with composite keys" do
|
|
3010
|
+
@Album.exclude(:cartist=>@Artist.load(:id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3011
|
+
@Album.exclude(:cartist=>@Artist.load(:id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3012
|
+
@Album.exclude(:cartist=>@Artist.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3013
|
+
end
|
|
3014
|
+
|
|
3015
|
+
it "should be able to excluding with NULL values for one_to_many associations with composite keys" do
|
|
3016
|
+
@Album.exclude(:ctracks=>@Track.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3017
|
+
@Album.exclude(:ctracks=>@Track.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3018
|
+
@Album.exclude(:ctracks=>@Track.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3019
|
+
end
|
|
3020
|
+
|
|
3021
|
+
it "should be able to excluding with NULL values for one_to_one associations with composite keys" do
|
|
3022
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.load(:album_id2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3023
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.load(:album_id1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3024
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3025
|
+
end
|
|
3026
|
+
|
|
3027
|
+
it "should be able to excluding with NULL values for many_to_many associations with composite keys" do
|
|
3028
|
+
@Album.exclude(:ctags=>@Tag.load(:tid1=>3)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3029
|
+
@Album.exclude(:ctags=>@Tag.load(:tid2=>4)).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3030
|
+
@Album.exclude(:ctags=>@Tag.new).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3031
|
+
end
|
|
3032
|
+
|
|
3033
|
+
it "should be able to handle NULL values when filtering multiple many_to_one associations" do
|
|
3034
|
+
@Album.filter(:artist=>[@Artist.load(:id=>3), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE (artist_id IN (3))'
|
|
3035
|
+
@Album.filter(:artist=>[@Artist.new, @Artist.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
3036
|
+
end
|
|
3037
|
+
|
|
3038
|
+
it "should be able to handle NULL values when filtering multiple one_to_many associations" do
|
|
3039
|
+
@Album.filter(:tracks=>[@Track.load(:album_id=>3), @Track.new]).sql.should == 'SELECT * FROM albums WHERE (id IN (3))'
|
|
3040
|
+
@Album.filter(:tracks=>[@Track.new, @Track.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
3041
|
+
end
|
|
3042
|
+
|
|
3043
|
+
it "should be able to handle NULL values when filtering multiple one_to_one associations" do
|
|
3044
|
+
@Album.filter(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE (id IN (3))'
|
|
3045
|
+
@Album.filter(:album_info=>[@AlbumInfo.new, @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
3046
|
+
end
|
|
3047
|
+
|
|
3048
|
+
it "should be able to handle NULL values when filtering multiple many_to_many associations" do
|
|
3049
|
+
@Album.filter(:tags=>[@Tag.load(:id=>3), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE (id IN (SELECT album_id FROM albums_tags WHERE ((tag_id IN (3)) AND (album_id IS NOT NULL))))'
|
|
3050
|
+
@Album.filter(:tags=>[@Tag.new, @Tag.new]).sql.should == 'SELECT * FROM albums WHERE \'f\''
|
|
3051
|
+
end
|
|
3052
|
+
|
|
3053
|
+
it "should be able to handle NULL values when filtering multiple many_to_one associations with composite keys" do
|
|
3054
|
+
@Album.filter(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>3)]).sql.should == 'SELECT * FROM albums WHERE ((artist_id1, artist_id2) IN ((3, 4)))'
|
|
3055
|
+
@Album.filter(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE ((artist_id1, artist_id2) IN ((3, 4)))'
|
|
3056
|
+
end
|
|
3057
|
+
|
|
3058
|
+
it "should be able handle NULL values when filtering multiple one_to_many associations with composite keys" do
|
|
3059
|
+
@Album.filter(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>3)]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN ((3, 4)))'
|
|
3060
|
+
@Album.filter(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.new]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN ((3, 4)))'
|
|
3061
|
+
end
|
|
3062
|
+
|
|
3063
|
+
it "should be able to handle NULL values when filtering multiple one_to_one associations with composite keys" do
|
|
3064
|
+
@Album.filter(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5)]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN ((3, 4)))'
|
|
3065
|
+
@Album.filter(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN ((3, 4)))'
|
|
3066
|
+
end
|
|
3067
|
+
|
|
3068
|
+
it "should be able to handle NULL values when filtering multiple many_to_many associations with composite keys" do
|
|
3069
|
+
@Album.filter(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5)]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN ((3, 4))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL))))'
|
|
3070
|
+
@Album.filter(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN ((3, 4))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL))))'
|
|
3071
|
+
end
|
|
3072
|
+
|
|
3073
|
+
it "should be able to handle NULL values when excluding multiple many_to_one associations" do
|
|
3074
|
+
@Album.exclude(:artist=>[@Artist.load(:id=>3), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE ((artist_id NOT IN (3)) OR (artist_id IS NULL))'
|
|
3075
|
+
@Album.exclude(:artist=>[@Artist.new, @Artist.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3076
|
+
end
|
|
3077
|
+
|
|
3078
|
+
it "should be able to handle NULL values when excluding multiple one_to_many associations" do
|
|
3079
|
+
@Album.exclude(:tracks=>[@Track.load(:album_id=>3), @Track.new]).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (3)) OR (id IS NULL))'
|
|
3080
|
+
@Album.exclude(:tracks=>[@Track.new, @Track.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3081
|
+
end
|
|
3082
|
+
|
|
3083
|
+
it "should be able to handle NULL values when excluding multiple one_to_one associations" do
|
|
3084
|
+
@Album.exclude(:album_info=>[@AlbumInfo.load(:album_id=>3), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (3)) OR (id IS NULL))'
|
|
3085
|
+
@Album.exclude(:album_info=>[@AlbumInfo.new, @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3086
|
+
end
|
|
3087
|
+
|
|
3088
|
+
it "should be able to handle NULL values when excluding multiple many_to_many associations" do
|
|
3089
|
+
@Album.exclude(:tags=>[@Tag.load(:id=>3), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (SELECT album_id FROM albums_tags WHERE ((tag_id IN (3)) AND (album_id IS NOT NULL)))) OR (id IS NULL))'
|
|
3090
|
+
@Album.exclude(:tags=>[@Tag.new, @Tag.new]).sql.should == 'SELECT * FROM albums WHERE \'t\''
|
|
3091
|
+
end
|
|
3092
|
+
|
|
3093
|
+
it "should be able to handle NULL values when excluding multiple many_to_one associations with composite keys" do
|
|
3094
|
+
@Album.exclude(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.load(:id1=>3)]).sql.should == 'SELECT * FROM albums WHERE (((artist_id1, artist_id2) NOT IN ((3, 4))) OR (artist_id1 IS NULL) OR (artist_id2 IS NULL))'
|
|
3095
|
+
@Album.exclude(:cartist=>[@Artist.load(:id1=>3, :id2=>4), @Artist.new]).sql.should == 'SELECT * FROM albums WHERE (((artist_id1, artist_id2) NOT IN ((3, 4))) OR (artist_id1 IS NULL) OR (artist_id2 IS NULL))'
|
|
3096
|
+
end
|
|
3097
|
+
|
|
3098
|
+
it "should be able handle NULL values when excluding multiple one_to_many associations with composite keys" do
|
|
3099
|
+
@Album.exclude(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.load(:album_id1=>3)]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN ((3, 4))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3100
|
+
@Album.exclude(:ctracks=>[@Track.load(:album_id1=>3, :album_id2=>4), @Track.new]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN ((3, 4))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3101
|
+
end
|
|
3102
|
+
|
|
3103
|
+
it "should be able to handle NULL values when excluding multiple one_to_one associations with composite keys" do
|
|
3104
|
+
@Album.exclude(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.load(:album_id1=>5)]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN ((3, 4))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3105
|
+
@Album.exclude(:calbum_info=>[@AlbumInfo.load(:album_id1=>3, :album_id2=>4), @AlbumInfo.new]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN ((3, 4))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3106
|
+
end
|
|
3107
|
+
|
|
3108
|
+
it "should be able to handle NULL values when excluding multiple many_to_many associations with composite keys" do
|
|
3109
|
+
@Album.exclude(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.load(:tid1=>5)]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN ((3, 4))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL)))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3110
|
+
@Album.exclude(:ctags=>[@Tag.load(:tid1=>3, :tid2=>4), @Tag.new]).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN ((3, 4))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL)))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3111
|
+
end
|
|
3112
|
+
|
|
3113
|
+
it "should be able to filter on many_to_one association datasets" do
|
|
3114
|
+
@Album.filter(:artist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (artist_id IN (SELECT id FROM artists WHERE ((x = 1) AND (id IS NOT NULL))))'
|
|
3115
|
+
end
|
|
3116
|
+
|
|
3117
|
+
it "should be able to filter on one_to_many association datasets" do
|
|
3118
|
+
@Album.filter(:tracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (id IN (SELECT album_id FROM tracks WHERE ((x = 1) AND (album_id IS NOT NULL))))'
|
|
3119
|
+
end
|
|
3120
|
+
|
|
3121
|
+
it "should be able to filter on one_to_one association datasets" do
|
|
3122
|
+
@Album.filter(:album_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (id IN (SELECT album_id FROM album_infos WHERE ((x = 1) AND (album_id IS NOT NULL))))'
|
|
3123
|
+
end
|
|
3124
|
+
|
|
3125
|
+
it "should be able to filter on many_to_many association datasets" do
|
|
3126
|
+
@Album.filter(:tags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (id IN (SELECT album_id FROM albums_tags WHERE ((tag_id IN (SELECT id FROM tags WHERE ((x = 1) AND (id IS NOT NULL)))) AND (album_id IS NOT NULL))))'
|
|
3127
|
+
end
|
|
3128
|
+
|
|
3129
|
+
it "should be able to filter on many_to_one association datasets with composite keys" do
|
|
3130
|
+
@Album.filter(:cartist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((artist_id1, artist_id2) IN (SELECT id1, id2 FROM artists WHERE ((x = 1) AND (id1 IS NOT NULL) AND (id2 IS NOT NULL))))'
|
|
3131
|
+
end
|
|
3132
|
+
|
|
3133
|
+
it "should be able to filter on one_to_many association datasets with composite keys" do
|
|
3134
|
+
@Album.filter(:ctracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN (SELECT album_id1, album_id2 FROM tracks WHERE ((x = 1) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL))))'
|
|
3135
|
+
end
|
|
3136
|
+
|
|
3137
|
+
it "should be able to filter on one_to_one association datasets with composite keys" do
|
|
3138
|
+
@Album.filter(:calbum_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN (SELECT album_id1, album_id2 FROM album_infos WHERE ((x = 1) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL))))'
|
|
3139
|
+
end
|
|
3140
|
+
|
|
3141
|
+
it "should be able to filter on many_to_many association datasets with composite keys" do
|
|
3142
|
+
@Album.filter(:ctags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((id1, id2) IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN (SELECT tid1, tid2 FROM tags WHERE ((x = 1) AND (tid1 IS NOT NULL) AND (tid2 IS NOT NULL)))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL))))'
|
|
3143
|
+
end
|
|
3144
|
+
|
|
3145
|
+
it "should be able to exclude on many_to_one association datasets" do
|
|
3146
|
+
@Album.exclude(:artist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((artist_id NOT IN (SELECT id FROM artists WHERE ((x = 1) AND (id IS NOT NULL)))) OR (artist_id IS NULL))'
|
|
3147
|
+
end
|
|
3148
|
+
|
|
3149
|
+
it "should be able to exclude on one_to_many association datasets" do
|
|
3150
|
+
@Album.exclude(:tracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (SELECT album_id FROM tracks WHERE ((x = 1) AND (album_id IS NOT NULL)))) OR (id IS NULL))'
|
|
3151
|
+
end
|
|
3152
|
+
|
|
3153
|
+
it "should be able to exclude on one_to_one association datasets" do
|
|
3154
|
+
@Album.exclude(:album_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (SELECT album_id FROM album_infos WHERE ((x = 1) AND (album_id IS NOT NULL)))) OR (id IS NULL))'
|
|
3155
|
+
end
|
|
3156
|
+
|
|
3157
|
+
it "should be able to exclude on many_to_many association datasets" do
|
|
3158
|
+
@Album.exclude(:tags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE ((id NOT IN (SELECT album_id FROM albums_tags WHERE ((tag_id IN (SELECT id FROM tags WHERE ((x = 1) AND (id IS NOT NULL)))) AND (album_id IS NOT NULL)))) OR (id IS NULL))'
|
|
3159
|
+
end
|
|
3160
|
+
|
|
3161
|
+
it "should be able to exclude on many_to_one association datasets with composite keys" do
|
|
3162
|
+
@Album.exclude(:cartist=>@Artist.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((artist_id1, artist_id2) NOT IN (SELECT id1, id2 FROM artists WHERE ((x = 1) AND (id1 IS NOT NULL) AND (id2 IS NOT NULL)))) OR (artist_id1 IS NULL) OR (artist_id2 IS NULL))'
|
|
3163
|
+
end
|
|
3164
|
+
|
|
3165
|
+
it "should be able to exclude on one_to_many association datasets with composite keys" do
|
|
3166
|
+
@Album.exclude(:ctracks=>@Track.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN (SELECT album_id1, album_id2 FROM tracks WHERE ((x = 1) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL)))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3167
|
+
end
|
|
3168
|
+
|
|
3169
|
+
it "should be able to exclude on one_to_one association datasets with composite keys" do
|
|
3170
|
+
@Album.exclude(:calbum_info=>@AlbumInfo.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN (SELECT album_id1, album_id2 FROM album_infos WHERE ((x = 1) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL)))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3171
|
+
end
|
|
3172
|
+
|
|
3173
|
+
it "should be able to exclude on many_to_many association datasets with composite keys" do
|
|
3174
|
+
@Album.exclude(:ctags=>@Tag.filter(:x=>1)).sql.should == 'SELECT * FROM albums WHERE (((id1, id2) NOT IN (SELECT album_id1, album_id2 FROM albums_tags WHERE (((tag_id1, tag_id2) IN (SELECT tid1, tid2 FROM tags WHERE ((x = 1) AND (tid1 IS NOT NULL) AND (tid2 IS NOT NULL)))) AND (album_id1 IS NOT NULL) AND (album_id2 IS NOT NULL)))) OR (id1 IS NULL) OR (id2 IS NULL))'
|
|
3175
|
+
end
|
|
3176
|
+
|
|
3177
|
+
it "should do a regular IN query if the dataset for a different model is used" do
|
|
3178
|
+
@Album.filter(:artist=>@Album.select(:x)).sql.should == 'SELECT * FROM albums WHERE (artist IN (SELECT x FROM albums))'
|
|
3179
|
+
end
|
|
3180
|
+
|
|
3181
|
+
it "should do a regular IN query if a non-model dataset is used" do
|
|
3182
|
+
@Album.filter(:artist=>@Album.db.from(:albums).select(:x)).sql.should == 'SELECT * FROM albums WHERE (artist IN (SELECT x FROM albums))'
|
|
3183
|
+
end
|
|
3184
|
+
end
|
data/spec/model/base_spec.rb
CHANGED
|
@@ -485,3 +485,62 @@ describe Sequel::Model, ".[] optimization" do
|
|
|
485
485
|
@c[1]
|
|
486
486
|
end
|
|
487
487
|
end
|
|
488
|
+
|
|
489
|
+
describe "Model datasets #with_pk" do
|
|
490
|
+
before do
|
|
491
|
+
@c = Class.new(Sequel::Model(:a))
|
|
492
|
+
@ds = @c.dataset
|
|
493
|
+
def @ds.fetch_rows(sql)
|
|
494
|
+
db << sql
|
|
495
|
+
yield(:id=>1)
|
|
496
|
+
end
|
|
497
|
+
@sqls = MODEL_DB.sqls
|
|
498
|
+
@sqls.clear
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
it "should return the first record where the primary key matches" do
|
|
502
|
+
@ds.with_pk(1).should == @c.load(:id=>1)
|
|
503
|
+
@sqls.should == ["SELECT * FROM a WHERE (id = 1) LIMIT 1"]
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
it "should handle existing filters" do
|
|
507
|
+
@ds.filter(:a=>2).with_pk(1)
|
|
508
|
+
@sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (id = 1)) LIMIT 1"]
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
it "should work with string values" do
|
|
512
|
+
@ds.with_pk("foo")
|
|
513
|
+
@sqls.should == ["SELECT * FROM a WHERE (id = 'foo') LIMIT 1"]
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
it "should handle an array for composite primary keys" do
|
|
517
|
+
@c.set_primary_key :id1, :id2
|
|
518
|
+
@ds.with_pk([1, 2])
|
|
519
|
+
@sqls.should == ["SELECT * FROM a WHERE ((id1 = 1) AND (id2 = 2)) LIMIT 1"]
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
it "should raise an error if a single primary key is given when a composite primary key should be used" do
|
|
523
|
+
@c.set_primary_key :id1, :id2
|
|
524
|
+
proc{@ds.with_pk(1)}.should raise_error(Sequel::Error)
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
it "should raise an error if a composite primary key is given when a single primary key should be used" do
|
|
528
|
+
proc{@ds.with_pk([1, 2])}.should raise_error(Sequel::Error)
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
it "should raise an error if the wrong number of composite keys is given" do
|
|
532
|
+
@c.set_primary_key :id1, :id2
|
|
533
|
+
proc{@ds.with_pk([1, 2, 3])}.should raise_error(Sequel::Error)
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
it "should have #[] consider an integer as a primary key lookup" do
|
|
537
|
+
@ds[1].should == @c.load(:id=>1)
|
|
538
|
+
@sqls.should == ["SELECT * FROM a WHERE (id = 1) LIMIT 1"]
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
it "should not have #[] consider a string as a primary key lookup" do
|
|
542
|
+
@ds['foo'].should == @c.load(:id=>1)
|
|
543
|
+
@sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
end
|