sequel 3.27.0 → 3.28.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +96 -0
- data/README.rdoc +2 -2
- data/Rakefile +1 -1
- data/doc/association_basics.rdoc +48 -0
- data/doc/opening_databases.rdoc +29 -5
- data/doc/prepared_statements.rdoc +1 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/testing.rdoc +42 -0
- data/doc/transactions.rdoc +97 -0
- data/lib/sequel/adapters/db2.rb +95 -65
- data/lib/sequel/adapters/firebird.rb +25 -219
- data/lib/sequel/adapters/ibmdb.rb +440 -0
- data/lib/sequel/adapters/jdbc.rb +12 -0
- data/lib/sequel/adapters/jdbc/as400.rb +0 -7
- data/lib/sequel/adapters/jdbc/db2.rb +49 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +34 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +2 -27
- data/lib/sequel/adapters/jdbc/transactions.rb +34 -0
- data/lib/sequel/adapters/mysql.rb +10 -15
- data/lib/sequel/adapters/odbc.rb +1 -2
- data/lib/sequel/adapters/odbc/db2.rb +5 -5
- data/lib/sequel/adapters/postgres.rb +71 -11
- data/lib/sequel/adapters/shared/db2.rb +290 -0
- data/lib/sequel/adapters/shared/firebird.rb +214 -0
- data/lib/sequel/adapters/shared/mssql.rb +18 -75
- data/lib/sequel/adapters/shared/mysql.rb +13 -0
- data/lib/sequel/adapters/shared/postgres.rb +52 -36
- data/lib/sequel/adapters/shared/sqlite.rb +32 -36
- data/lib/sequel/adapters/sqlite.rb +4 -8
- data/lib/sequel/adapters/tinytds.rb +7 -3
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +55 -0
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/misc.rb +6 -5
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +2 -1
- data/lib/sequel/dataset/actions.rb +149 -33
- data/lib/sequel/dataset/features.rb +44 -7
- data/lib/sequel/dataset/misc.rb +9 -1
- data/lib/sequel/dataset/prepared_statements.rb +2 -2
- data/lib/sequel/dataset/query.rb +63 -10
- data/lib/sequel/dataset/sql.rb +22 -5
- data/lib/sequel/model.rb +3 -3
- data/lib/sequel/model/associations.rb +250 -27
- data/lib/sequel/model/base.rb +10 -16
- data/lib/sequel/plugins/many_through_many.rb +34 -2
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
- data/lib/sequel/sql.rb +94 -51
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/postgres_spec.rb +74 -6
- data/spec/adapters/spec_helper.rb +1 -0
- data/spec/adapters/sqlite_spec.rb +11 -0
- data/spec/core/database_spec.rb +7 -0
- data/spec/core/dataset_spec.rb +180 -17
- data/spec/core/expression_filters_spec.rb +107 -41
- data/spec/core/spec_helper.rb +11 -0
- data/spec/extensions/many_through_many_spec.rb +115 -1
- data/spec/extensions/prepared_statements_with_pk_spec.rb +3 -3
- data/spec/integration/associations_test.rb +193 -15
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +215 -19
- data/spec/integration/plugin_test.rb +8 -5
- data/spec/integration/prepared_statement_test.rb +91 -98
- data/spec/integration/schema_test.rb +27 -11
- data/spec/integration/spec_helper.rb +10 -0
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/association_reflection_spec.rb +91 -0
- data/spec/model/associations_spec.rb +13 -0
- data/spec/model/base_spec.rb +8 -21
- data/spec/model/eager_loading_spec.rb +243 -9
- data/spec/model/model_spec.rb +15 -2
- metadata +16 -4
data/spec/core/spec_helper.rb
CHANGED
@@ -89,3 +89,14 @@ class Dummy2Database < Sequel::Database
|
|
89
89
|
def transaction; yield; end
|
90
90
|
end
|
91
91
|
|
92
|
+
class DummyDataset < Sequel::Dataset
|
93
|
+
VALUES = [
|
94
|
+
{:a => 1, :b => 2},
|
95
|
+
{:a => 3, :b => 4},
|
96
|
+
{:a => 5, :b => 6}
|
97
|
+
]
|
98
|
+
def fetch_rows(sql, &block)
|
99
|
+
VALUES.each(&block)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
@@ -621,6 +621,120 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
621
621
|
MODEL_DB.sqls.length.should == 2
|
622
622
|
end
|
623
623
|
|
624
|
+
it "should respect the :limit option on a many_through_many association" do
|
625
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2
|
626
|
+
Tag.dataset.extend(Module.new {
|
627
|
+
def fetch_rows(sql)
|
628
|
+
MODEL_DB.sqls << sql
|
629
|
+
yield({:x_foreign_key_x=>1, :id=>5})
|
630
|
+
yield({:x_foreign_key_x=>1, :id=>6})
|
631
|
+
yield({:x_foreign_key_x=>1, :id=>7})
|
632
|
+
end
|
633
|
+
})
|
634
|
+
a = @c1.eager(:first_two_tags).all
|
635
|
+
a.should == [@c1.load(:id=>1)]
|
636
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
637
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
|
638
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
639
|
+
MODEL_DB.sqls.length.should == 2
|
640
|
+
|
641
|
+
MODEL_DB.reset
|
642
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[2,1]
|
643
|
+
a = @c1.eager(:first_two_tags).all
|
644
|
+
a.should == [@c1.load(:id=>1)]
|
645
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
646
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))']
|
647
|
+
a.first.first_two_tags.should == [Tag.load(:id=>6), Tag.load(:id=>7)]
|
648
|
+
MODEL_DB.sqls.length.should == 2
|
649
|
+
end
|
650
|
+
|
651
|
+
it "should respect the :limit option on a many_through_many association using a :window_function strategy" do
|
652
|
+
Tag.dataset.meta_def(:supports_window_functions?){true}
|
653
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>true, :order=>:name
|
654
|
+
Tag.dataset.extend(Module.new {
|
655
|
+
def fetch_rows(sql)
|
656
|
+
MODEL_DB.sqls << sql
|
657
|
+
yield({:x_foreign_key_x=>1, :id=>5})
|
658
|
+
yield({:x_foreign_key_x=>1, :id=>6})
|
659
|
+
end
|
660
|
+
})
|
661
|
+
a = @c1.eager(:first_two_tags).all
|
662
|
+
a.should == [@c1.load(:id=>1)]
|
663
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
664
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
665
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
666
|
+
MODEL_DB.sqls.length.should == 2
|
667
|
+
|
668
|
+
MODEL_DB.reset
|
669
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[2,1], :eager_limit_strategy=>true, :order=>:name
|
670
|
+
a = @c1.eager(:first_two_tags).all
|
671
|
+
a.should == [@c1.load(:id=>1)]
|
672
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
673
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1)))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
|
674
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
675
|
+
MODEL_DB.sqls.length.should == 2
|
676
|
+
end
|
677
|
+
|
678
|
+
it "should respect the :limit option on a many_through_many association with composite primary keys on the main table using a :window_function strategy" do
|
679
|
+
Tag.dataset.meta_def(:supports_window_functions?){true}
|
680
|
+
@c1.set_primary_key([:id1, :id2])
|
681
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>true, :order=>:name
|
682
|
+
@c1.dataset.extend(Module.new {
|
683
|
+
def fetch_rows(sql)
|
684
|
+
MODEL_DB.sqls << sql
|
685
|
+
yield({:id1=>1, :id2=>2})
|
686
|
+
end
|
687
|
+
})
|
688
|
+
Tag.dataset.extend(Module.new {
|
689
|
+
def fetch_rows(sql)
|
690
|
+
MODEL_DB.sqls << sql
|
691
|
+
yield({:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5})
|
692
|
+
yield({:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6})
|
693
|
+
end
|
694
|
+
})
|
695
|
+
a = @c1.eager(:first_two_tags).all
|
696
|
+
a.should == [@c1.load(:id1=>1, :id2=>2)]
|
697
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
698
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2))))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
699
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
700
|
+
MODEL_DB.sqls.length.should == 2
|
701
|
+
|
702
|
+
MODEL_DB.reset
|
703
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[2,1], :eager_limit_strategy=>true, :order=>:name
|
704
|
+
a = @c1.eager(:first_two_tags).all
|
705
|
+
a.should == [@c1.load(:id1=>1, :id2=>2)]
|
706
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
707
|
+
'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2))))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
|
708
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
709
|
+
MODEL_DB.sqls.length.should == 2
|
710
|
+
end
|
711
|
+
|
712
|
+
it "should respect the :limit option on a many_through_many association using a :correlated_subquery strategy" do
|
713
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>:correlated_subquery, :order=>:name
|
714
|
+
Tag.dataset.extend(Module.new {
|
715
|
+
def fetch_rows(sql)
|
716
|
+
MODEL_DB.sqls << sql
|
717
|
+
yield({:x_foreign_key_x=>1, :id=>5})
|
718
|
+
yield({:x_foreign_key_x=>1, :id=>6})
|
719
|
+
end
|
720
|
+
})
|
721
|
+
a = @c1.eager(:first_two_tags).all
|
722
|
+
a.should == [@c1.load(:id=>1)]
|
723
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
724
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) WHERE (tags.id IN (SELECT t1.id FROM tags AS t1 INNER JOIN albums_tags ON (albums_tags.tag_id = t1.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists AS t2 ON ((t2.album_id = albums.id) AND (t2.artist_id = albums_artists.artist_id)) ORDER BY name LIMIT 2)) ORDER BY name']
|
725
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
726
|
+
MODEL_DB.sqls.length.should == 2
|
727
|
+
|
728
|
+
MODEL_DB.reset
|
729
|
+
@c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[2,1], :eager_limit_strategy=>:correlated_subquery, :order=>:name
|
730
|
+
a = @c1.eager(:first_two_tags).all
|
731
|
+
a.should == [@c1.load(:id=>1)]
|
732
|
+
MODEL_DB.sqls.should == ['SELECT * FROM artists',
|
733
|
+
'SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON ((albums_artists.album_id = albums.id) AND (albums_artists.artist_id IN (1))) WHERE (tags.id IN (SELECT t1.id FROM tags AS t1 INNER JOIN albums_tags ON (albums_tags.tag_id = t1.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists AS t2 ON ((t2.album_id = albums.id) AND (t2.artist_id = albums_artists.artist_id)) ORDER BY name LIMIT 2 OFFSET 1)) ORDER BY name']
|
734
|
+
a.first.first_two_tags.should == [Tag.load(:id=>5), Tag.load(:id=>6)]
|
735
|
+
MODEL_DB.sqls.length.should == 2
|
736
|
+
end
|
737
|
+
|
624
738
|
it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
|
625
739
|
proc{@c1.eager(:tags).all}.should_not raise_error
|
626
740
|
@c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :allow_eager=>false
|
@@ -637,7 +751,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
|
|
637
751
|
MODEL_DB.sqls.length.should == 2
|
638
752
|
end
|
639
753
|
|
640
|
-
it "should respect
|
754
|
+
it "should respect many_through_many association's :left_primary_key and :right_primary_key options" do
|
641
755
|
@c1.send(:define_method, :yyy){values[:yyy]}
|
642
756
|
@c1.dataset.extend(Module.new {
|
643
757
|
def columns
|
@@ -23,16 +23,16 @@ describe "prepared_statements_with_pk plugin" do
|
|
23
23
|
|
24
24
|
specify "should correctly lookup by primary key from dataset" do
|
25
25
|
@c.dataset.filter(:name=>'foo')[1].should == @p
|
26
|
-
@sqls.should == [:read_only, "SELECT * FROM people WHERE ((name = 'foo') AND (id = 1)) LIMIT 1"]
|
26
|
+
@sqls.should == [:read_only, "SELECT * FROM people WHERE ((name = 'foo') AND (people.id = 1)) LIMIT 1"]
|
27
27
|
end
|
28
28
|
|
29
29
|
specify "should still work correctly if there are multiple conflicting variables" do
|
30
30
|
@c.dataset.filter(:name=>'foo').or(:name=>'bar')[1].should == @p
|
31
|
-
@sqls.should == [:read_only, "SELECT * FROM people WHERE (((name = 'foo') OR (name = 'bar')) AND (id = 1)) LIMIT 1"]
|
31
|
+
@sqls.should == [:read_only, "SELECT * FROM people WHERE (((name = 'foo') OR (name = 'bar')) AND (people.id = 1)) LIMIT 1"]
|
32
32
|
end
|
33
33
|
|
34
34
|
specify "should still work correctly if the primary key is used elsewhere in the query" do
|
35
35
|
@c.dataset.filter{id > 2}[1].should == @p
|
36
|
-
@sqls.should == [:read_only, "SELECT * FROM people WHERE ((id > 2) AND (id = 1)) LIMIT 1"]
|
36
|
+
@sqls.should == [:read_only, "SELECT * FROM people WHERE ((id > 2) AND (people.id = 1)) LIMIT 1"]
|
37
37
|
end
|
38
38
|
end
|
@@ -1,8 +1,105 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
2
2
|
|
3
|
+
shared_examples_for "eager limit strategies" do
|
4
|
+
specify "eager loading one_to_one associations should work correctly" do
|
5
|
+
Artist.one_to_one :first_album, {:clone=>:first_album}.merge(@els) if @els
|
6
|
+
Artist.one_to_one :last_album, {:clone=>:last_album}.merge(@els) if @els
|
7
|
+
@album.update(:artist => @artist)
|
8
|
+
diff_album = @diff_album.call
|
9
|
+
al, ar, t = @pr.call
|
10
|
+
|
11
|
+
a = Artist.eager(:first_album, :last_album).all
|
12
|
+
a.should == [@artist, ar]
|
13
|
+
a.first.first_album.should == @album
|
14
|
+
a.first.last_album.should == diff_album
|
15
|
+
a.last.first_album.should == nil
|
16
|
+
a.last.last_album.should == nil
|
17
|
+
|
18
|
+
# Check that no extra columns got added by the eager loading
|
19
|
+
a.first.first_album.values.should == @album.values
|
20
|
+
a.first.last_album.values.should == diff_album.values
|
21
|
+
|
22
|
+
same_album = @same_album.call
|
23
|
+
a = Artist.eager(:first_album).all
|
24
|
+
a.should == [@artist, ar]
|
25
|
+
[@album, same_album].should include(a.first.first_album)
|
26
|
+
a.last.first_album.should == nil
|
27
|
+
end
|
28
|
+
|
29
|
+
specify "should correctly handle limits and offsets when eager loading one_to_many associations" do
|
30
|
+
Artist.one_to_many :first_two_albums, {:clone=>:first_two_albums}.merge(@els) if @els
|
31
|
+
Artist.one_to_many :second_two_albums, {:clone=>:second_two_albums}.merge(@els) if @els
|
32
|
+
Artist.one_to_many :last_two_albums, {:clone=>:last_two_albums}.merge(@els) if @els
|
33
|
+
@album.update(:artist => @artist)
|
34
|
+
middle_album = @middle_album.call
|
35
|
+
diff_album = @diff_album.call
|
36
|
+
al, ar, t = @pr.call
|
37
|
+
|
38
|
+
ars = Artist.eager(:first_two_albums, :second_two_albums, :last_two_albums).order(:name).all
|
39
|
+
ars.should == [@artist, ar]
|
40
|
+
ars.first.first_two_albums.should == [@album, middle_album]
|
41
|
+
ars.first.second_two_albums.should == [middle_album, diff_album]
|
42
|
+
ars.first.last_two_albums.should == [diff_album, middle_album]
|
43
|
+
ars.last.first_two_albums.should == []
|
44
|
+
ars.last.second_two_albums.should == []
|
45
|
+
ars.last.last_two_albums.should == []
|
46
|
+
|
47
|
+
# Check that no extra columns got added by the eager loading
|
48
|
+
ars.first.first_two_albums.map{|x| x.values}.should == [@album, middle_album].map{|x| x.values}
|
49
|
+
ars.first.second_two_albums.map{|x| x.values}.should == [middle_album, diff_album].map{|x| x.values}
|
50
|
+
ars.first.last_two_albums.map{|x| x.values}.should == [diff_album, middle_album].map{|x| x.values}
|
51
|
+
end
|
52
|
+
|
53
|
+
specify "should correctly handle limits and offsets when eager loading many_to_many associations" do
|
54
|
+
Album.many_to_many :first_two_tags, {:clone=>:first_two_tags}.merge(@els) if @els
|
55
|
+
Album.many_to_many :second_two_tags, {:clone=>:second_two_tags}.merge(@els) if @els
|
56
|
+
Album.many_to_many :last_two_tags, {:clone=>:last_two_tags}.merge(@els) if @els
|
57
|
+
tu, tv = @other_tags.call
|
58
|
+
al, ar, t = @pr.call
|
59
|
+
|
60
|
+
als = Album.eager(:first_two_tags, :second_two_tags, :last_two_tags).order(:name).all
|
61
|
+
als.should == [@album, al]
|
62
|
+
als.first.first_two_tags.should == [@tag, tu]
|
63
|
+
als.first.second_two_tags.should == [tu, tv]
|
64
|
+
als.first.last_two_tags.should == [tv, tu]
|
65
|
+
als.last.first_two_tags.should == []
|
66
|
+
als.last.second_two_tags.should == []
|
67
|
+
als.last.last_two_tags.should == []
|
68
|
+
|
69
|
+
# Check that no extra columns got added by the eager loading
|
70
|
+
als.first.first_two_tags.map{|x| x.values}.should == [@tag, tu].map{|x| x.values}
|
71
|
+
als.first.second_two_tags.map{|x| x.values}.should == [tu, tv].map{|x| x.values}
|
72
|
+
als.first.last_two_tags.map{|x| x.values}.should == [tv, tu].map{|x| x.values}
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "should correctly handle limits and offsets when eager loading many_through_many associations" do
|
76
|
+
Artist.many_through_many :first_two_tags, {:clone=>:first_two_tags}.merge(@els) if @els
|
77
|
+
Artist.many_through_many :second_two_tags, {:clone=>:second_two_tags}.merge(@els) if @els
|
78
|
+
Artist.many_through_many :last_two_tags, {:clone=>:last_two_tags}.merge(@els) if @els
|
79
|
+
@album.update(:artist => @artist)
|
80
|
+
tu, tv = @other_tags.call
|
81
|
+
al, ar, t = @pr.call
|
82
|
+
|
83
|
+
ars = Artist.eager(:first_two_tags, :second_two_tags, :last_two_tags).order(:name).all
|
84
|
+
ars.should == [@artist, ar]
|
85
|
+
ars.first.first_two_tags.should == [@tag, tu]
|
86
|
+
ars.first.second_two_tags.should == [tu, tv]
|
87
|
+
ars.first.last_two_tags.should == [tv, tu]
|
88
|
+
ars.last.first_two_tags.should == []
|
89
|
+
ars.last.second_two_tags.should == []
|
90
|
+
ars.last.last_two_tags.should == []
|
91
|
+
|
92
|
+
# Check that no extra columns got added by the eager loading
|
93
|
+
ars.first.first_two_tags.map{|x| x.values}.should == [@tag, tu].map{|x| x.values}
|
94
|
+
ars.first.second_two_tags.map{|x| x.values}.should == [tu, tv].map{|x| x.values}
|
95
|
+
ars.first.last_two_tags.map{|x| x.values}.should == [tv, tu].map{|x| x.values}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
3
99
|
shared_examples_for "regular and composite key associations" do
|
4
100
|
specify "should return no objects if none are associated" do
|
5
101
|
@album.artist.should == nil
|
102
|
+
@artist.first_album.should == nil
|
6
103
|
@artist.albums.should == []
|
7
104
|
@album.tags.should == []
|
8
105
|
@tag.albums.should == []
|
@@ -17,6 +114,7 @@ shared_examples_for "regular and composite key associations" do
|
|
17
114
|
@tag.reload
|
18
115
|
|
19
116
|
@album.artist.should == @artist
|
117
|
+
@artist.first_album.should == @album
|
20
118
|
@artist.albums.should == [@album]
|
21
119
|
@album.tags.should == [@tag]
|
22
120
|
@tag.albums.should == [@album]
|
@@ -32,6 +130,7 @@ shared_examples_for "regular and composite key associations" do
|
|
32
130
|
|
33
131
|
[Tag, Album, Artist].each{|x| x.plugin :prepared_statements_associations}
|
34
132
|
@album.artist.should == @artist
|
133
|
+
@artist.first_album.should == @album
|
35
134
|
@artist.albums.should == [@album]
|
36
135
|
@album.tags.should == [@tag]
|
37
136
|
@tag.albums.should == [@album]
|
@@ -42,6 +141,7 @@ shared_examples_for "regular and composite key associations" do
|
|
42
141
|
@album.add_tag(@tag)
|
43
142
|
|
44
143
|
Artist.filter(:albums=>@album).all.should == [@artist]
|
144
|
+
Artist.filter(:first_album=>@album).all.should == [@artist]
|
45
145
|
Album.filter(:artist=>@artist).all.should == [@album]
|
46
146
|
Album.filter(:tags=>@tag).all.should == [@album]
|
47
147
|
Tag.filter(:albums=>@album).all.should == [@tag]
|
@@ -55,6 +155,7 @@ shared_examples_for "regular and composite key associations" do
|
|
55
155
|
album, artist, tag = @pr.call
|
56
156
|
|
57
157
|
Artist.exclude(:albums=>@album).all.should == [artist]
|
158
|
+
Artist.exclude(:first_album=>@album).all.should == [artist]
|
58
159
|
Album.exclude(:artist=>@artist).all.should == [album]
|
59
160
|
Album.exclude(:tags=>@tag).all.should == [album]
|
60
161
|
Tag.exclude(:albums=>@album).all.should == [tag]
|
@@ -67,6 +168,7 @@ shared_examples_for "regular and composite key associations" do
|
|
67
168
|
@album.add_tag(@tag)
|
68
169
|
|
69
170
|
Artist.filter(:albums=>[@album, album]).all.should == [@artist]
|
171
|
+
Artist.filter(:first_album=>[@album, album]).all.should == [@artist]
|
70
172
|
Album.filter(:artist=>[@artist, artist]).all.should == [@album]
|
71
173
|
Album.filter(:tags=>[@tag, tag]).all.should == [@album]
|
72
174
|
Tag.filter(:albums=>[@album, album]).all.should == [@tag]
|
@@ -76,6 +178,7 @@ shared_examples_for "regular and composite key associations" do
|
|
76
178
|
album.add_tag(tag)
|
77
179
|
|
78
180
|
Artist.filter(:albums=>[@album, album]).all.should == [@artist]
|
181
|
+
Artist.filter(:first_album=>[@album, album]).all.should == [@artist]
|
79
182
|
Album.filter(:artist=>[@artist, artist]).all.should == [@album]
|
80
183
|
Album.filter(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
81
184
|
Tag.filter(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
@@ -84,6 +187,7 @@ shared_examples_for "regular and composite key associations" do
|
|
84
187
|
album.update(:artist => artist)
|
85
188
|
|
86
189
|
Artist.filter(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
190
|
+
Artist.filter(:first_album=>[@album, album]).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
87
191
|
Album.filter(:artist=>[@artist, artist]).all.sort_by{|x| x.pk}.should == [@album, album]
|
88
192
|
Album.filter(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
89
193
|
Tag.filter(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
@@ -94,6 +198,7 @@ shared_examples_for "regular and composite key associations" do
|
|
94
198
|
album, artist, tag = @pr.call
|
95
199
|
|
96
200
|
Artist.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
201
|
+
Artist.exclude(:first_album=>[@album, album]).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
97
202
|
Album.exclude(:artist=>[@artist, artist]).all.sort_by{|x| x.pk}.should == [@album, album]
|
98
203
|
Album.exclude(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [@album, album]
|
99
204
|
Tag.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [@tag, tag]
|
@@ -103,6 +208,7 @@ shared_examples_for "regular and composite key associations" do
|
|
103
208
|
@album.add_tag(@tag)
|
104
209
|
|
105
210
|
Artist.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [artist]
|
211
|
+
Artist.exclude(:first_album=>[@album, album]).all.sort_by{|x| x.pk}.should == [artist]
|
106
212
|
Album.exclude(:artist=>[@artist, artist]).all.sort_by{|x| x.pk}.should == [album]
|
107
213
|
Album.exclude(:tags=>[@tag, tag]).all.sort_by{|x| x.pk}.should == [album]
|
108
214
|
Tag.exclude(:albums=>[@album, album]).all.sort_by{|x| x.pk}.should == [tag]
|
@@ -111,6 +217,7 @@ shared_examples_for "regular and composite key associations" do
|
|
111
217
|
album.add_tag(tag)
|
112
218
|
|
113
219
|
Artist.exclude(:albums=>[@album, album]).all.should == [artist]
|
220
|
+
Artist.exclude(:first_album=>[@album, album]).all.should == [artist]
|
114
221
|
Album.exclude(:artist=>[@artist, artist]).all.should == [album]
|
115
222
|
Album.exclude(:tags=>[@tag, tag]).all.should == []
|
116
223
|
Tag.exclude(:albums=>[@album, album]).all.should == []
|
@@ -119,6 +226,7 @@ shared_examples_for "regular and composite key associations" do
|
|
119
226
|
album.update(:artist => artist)
|
120
227
|
|
121
228
|
Artist.exclude(:albums=>[@album, album]).all.should == []
|
229
|
+
Artist.exclude(:first_album=>[@album, album]).all.should == []
|
122
230
|
Album.exclude(:artist=>[@artist, artist]).all.should == []
|
123
231
|
Album.exclude(:tags=>[@tag, tag]).all.should == []
|
124
232
|
Tag.exclude(:albums=>[@album, album]).all.should == []
|
@@ -127,6 +235,7 @@ shared_examples_for "regular and composite key associations" do
|
|
127
235
|
|
128
236
|
specify "should work correctly when excluding by associations in regards to NULL values" do
|
129
237
|
Artist.exclude(:albums=>@album).all.should == [@artist]
|
238
|
+
Artist.exclude(:first_album=>@album).all.should == [@artist]
|
130
239
|
Album.exclude(:artist=>@artist).all.should == [@album]
|
131
240
|
Album.exclude(:tags=>@tag).all.should == [@album]
|
132
241
|
Tag.exclude(:albums=>@album).all.should == [@tag]
|
@@ -156,6 +265,9 @@ shared_examples_for "regular and composite key associations" do
|
|
156
265
|
Artist.filter(:albums=>Album.dataset).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
157
266
|
Artist.filter(:albums=>Album.dataset.filter(Array(Album.primary_key).zip(Array(album.pk)))).all.sort_by{|x| x.pk}.should == [artist]
|
158
267
|
Artist.filter(:albums=>Album.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == []
|
268
|
+
Artist.filter(:first_album=>Album.dataset).all.sort_by{|x| x.pk}.should == [@artist, artist]
|
269
|
+
Artist.filter(:first_album=>Album.dataset.filter(Array(Album.primary_key).zip(Array(album.pk)))).all.sort_by{|x| x.pk}.should == [artist]
|
270
|
+
Artist.filter(:first_album=>Album.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == []
|
159
271
|
Album.filter(:artist=>Artist.dataset).all.sort_by{|x| x.pk}.should == [@album, album]
|
160
272
|
Album.filter(:artist=>Artist.dataset.filter(Array(Artist.primary_key).zip(Array(artist.pk)))).all.sort_by{|x| x.pk}.should == [album]
|
161
273
|
Album.filter(:artist=>Artist.dataset.filter(1=>0)).all.sort_by{|x| x.pk}.should == []
|
@@ -226,9 +338,10 @@ shared_examples_for "regular and composite key associations" do
|
|
226
338
|
@album.update(:artist => @artist)
|
227
339
|
@album.add_tag(@tag)
|
228
340
|
|
229
|
-
a = Artist.eager(:albums=>:tags).all
|
341
|
+
a = Artist.eager(:albums=>:tags).eager(:first_album).all
|
230
342
|
a.should == [@artist]
|
231
343
|
a.first.albums.should == [@album]
|
344
|
+
a.first.first_album.should == @album
|
232
345
|
a.first.albums.first.tags.should == [@tag]
|
233
346
|
|
234
347
|
a = Tag.eager(:albums=>:artist).all
|
@@ -237,13 +350,32 @@ shared_examples_for "regular and composite key associations" do
|
|
237
350
|
a.first.albums.first.artist.should == @artist
|
238
351
|
end
|
239
352
|
|
353
|
+
describe "with no :eager_limit_strategy" do
|
354
|
+
it_should_behave_like "eager limit strategies"
|
355
|
+
end
|
356
|
+
|
357
|
+
describe "with :eager_limit_strategy=>true" do
|
358
|
+
before do
|
359
|
+
@els = {:eager_limit_strategy=>true}
|
360
|
+
end
|
361
|
+
it_should_behave_like "eager limit strategies"
|
362
|
+
end
|
363
|
+
|
364
|
+
describe "with :eager_limit_strategy=>:window_function" do
|
365
|
+
before do
|
366
|
+
@els = {:eager_limit_strategy=>:window_function}
|
367
|
+
end
|
368
|
+
it_should_behave_like "eager limit strategies"
|
369
|
+
end if INTEGRATION_DB.dataset.supports_window_functions?
|
370
|
+
|
240
371
|
specify "should eager load via eager_graph correctly" do
|
241
372
|
@album.update(:artist => @artist)
|
242
373
|
@album.add_tag(@tag)
|
243
374
|
|
244
|
-
a = Artist.eager_graph(:albums=>:tags).all
|
375
|
+
a = Artist.eager_graph(:albums=>:tags).eager_graph(:first_album).all
|
245
376
|
a.should == [@artist]
|
246
377
|
a.first.albums.should == [@album]
|
378
|
+
a.first.first_album.should == @album
|
247
379
|
a.first.albums.first.tags.should == [@tag]
|
248
380
|
|
249
381
|
a = Tag.eager_graph(:albums=>:artist).all
|
@@ -285,31 +417,43 @@ end
|
|
285
417
|
describe "Sequel::Model Simple Associations" do
|
286
418
|
before do
|
287
419
|
@db = INTEGRATION_DB
|
288
|
-
@db.
|
420
|
+
[:albums_tags, :tags, :albums, :artists].each{|t| @db.drop_table(t) rescue nil}
|
421
|
+
@db.create_table(:artists) do
|
289
422
|
primary_key :id
|
290
423
|
String :name
|
291
424
|
end
|
292
|
-
@db.create_table
|
425
|
+
@db.create_table(:albums) do
|
293
426
|
primary_key :id
|
294
427
|
String :name
|
295
428
|
foreign_key :artist_id, :artists
|
296
429
|
end
|
297
|
-
@db.create_table
|
430
|
+
@db.create_table(:tags) do
|
298
431
|
primary_key :id
|
299
432
|
String :name
|
300
433
|
end
|
301
|
-
@db.create_table
|
434
|
+
@db.create_table(:albums_tags) do
|
302
435
|
foreign_key :album_id, :albums
|
303
436
|
foreign_key :tag_id, :tags
|
304
437
|
end
|
305
438
|
class ::Artist < Sequel::Model(@db)
|
306
439
|
one_to_many :albums
|
440
|
+
one_to_one :first_album, :class=>:Album, :order=>:name
|
441
|
+
one_to_one :last_album, :class=>:Album, :order=>:name.desc
|
442
|
+
one_to_many :first_two_albums, :class=>:Album, :order=>:name, :limit=>2
|
443
|
+
one_to_many :second_two_albums, :class=>:Album, :order=>:name, :limit=>[2, 1]
|
444
|
+
one_to_many :last_two_albums, :class=>:Album, :order=>:name.desc, :limit=>2
|
307
445
|
plugin :many_through_many
|
308
|
-
|
446
|
+
many_through_many :tags, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]]
|
447
|
+
many_through_many :first_two_tags, :clone=>:tags, :order=>:tags__name, :limit=>2
|
448
|
+
many_through_many :second_two_tags, :clone=>:tags, :order=>:tags__name, :limit=>[2, 1]
|
449
|
+
many_through_many :last_two_tags, :clone=>:tags, :order=>:tags__name.desc, :limit=>2
|
309
450
|
end
|
310
451
|
class ::Album < Sequel::Model(@db)
|
311
452
|
many_to_one :artist
|
312
|
-
many_to_many :tags
|
453
|
+
many_to_many :tags, :right_key=>:tag_id
|
454
|
+
many_to_many :first_two_tags, :clone=>:tags, :order=>:name, :limit=>2
|
455
|
+
many_to_many :second_two_tags, :clone=>:tags, :order=>:name, :limit=>[2, 1]
|
456
|
+
many_to_many :last_two_tags, :clone=>:tags, :order=>:name.desc, :limit=>2
|
313
457
|
end
|
314
458
|
class ::Tag < Sequel::Model(@db)
|
315
459
|
many_to_many :albums
|
@@ -317,6 +461,10 @@ describe "Sequel::Model Simple Associations" do
|
|
317
461
|
@album = Album.create(:name=>'Al')
|
318
462
|
@artist = Artist.create(:name=>'Ar')
|
319
463
|
@tag = Tag.create(:name=>'T')
|
464
|
+
@same_album = lambda{Album.create(:name=>'Al', :artist_id=>@artist.id)}
|
465
|
+
@diff_album = lambda{Album.create(:name=>'lA', :artist_id=>@artist.id)}
|
466
|
+
@middle_album = lambda{Album.create(:name=>'Bl', :artist_id=>@artist.id)}
|
467
|
+
@other_tags = lambda{t = [Tag.create(:name=>'U'), Tag.create(:name=>'V')]; @db[:albums_tags].insert([:album_id, :tag_id], Tag.select(@album.id, :id)); t}
|
320
468
|
@pr = lambda{[Album.create(:name=>'Al2'),Artist.create(:name=>'Ar2'),Tag.create(:name=>'T2')]}
|
321
469
|
@ins = lambda{@db[:albums_tags].insert(:tag_id=>@tag.id)}
|
322
470
|
end
|
@@ -325,6 +473,15 @@ describe "Sequel::Model Simple Associations" do
|
|
325
473
|
[:Tag, :Album, :Artist].each{|x| Object.send(:remove_const, x)}
|
326
474
|
end
|
327
475
|
|
476
|
+
it_should_behave_like "regular and composite key associations"
|
477
|
+
|
478
|
+
describe "with :eager_limit_strategy=>:correlated_subquery" do
|
479
|
+
before do
|
480
|
+
@els = {:eager_limit_strategy=>:correlated_subquery}
|
481
|
+
end
|
482
|
+
it_should_behave_like "eager limit strategies"
|
483
|
+
end unless [:mysql, :db2].include?(INTEGRATION_DB.database_type)
|
484
|
+
|
328
485
|
specify "should handle aliased tables when eager_graphing" do
|
329
486
|
@album.update(:artist => @artist)
|
330
487
|
@album.add_tag(@tag)
|
@@ -348,8 +505,6 @@ describe "Sequel::Model Simple Associations" do
|
|
348
505
|
a.first.balbums.first.bartist.should == @artist
|
349
506
|
end
|
350
507
|
|
351
|
-
it_should_behave_like "regular and composite key associations"
|
352
|
-
|
353
508
|
specify "should have add method accept hashes and create new records" do
|
354
509
|
@artist.remove_all_albums
|
355
510
|
Album.delete
|
@@ -435,13 +590,14 @@ end
|
|
435
590
|
describe "Sequel::Model Composite Key Associations" do
|
436
591
|
before do
|
437
592
|
@db = INTEGRATION_DB
|
438
|
-
@db.
|
593
|
+
[:albums_tags, :tags, :albums, :artists].each{|t| @db.drop_table(t) rescue nil}
|
594
|
+
@db.create_table(:artists) do
|
439
595
|
Integer :id1
|
440
596
|
Integer :id2
|
441
597
|
String :name
|
442
598
|
primary_key [:id1, :id2]
|
443
599
|
end
|
444
|
-
@db.create_table
|
600
|
+
@db.create_table(:albums) do
|
445
601
|
Integer :id1
|
446
602
|
Integer :id2
|
447
603
|
String :name
|
@@ -450,13 +606,13 @@ describe "Sequel::Model Composite Key Associations" do
|
|
450
606
|
foreign_key [:artist_id1, :artist_id2], :artists
|
451
607
|
primary_key [:id1, :id2]
|
452
608
|
end
|
453
|
-
@db.create_table
|
609
|
+
@db.create_table(:tags) do
|
454
610
|
Integer :id1
|
455
611
|
Integer :id2
|
456
612
|
String :name
|
457
613
|
primary_key [:id1, :id2]
|
458
614
|
end
|
459
|
-
@db.create_table
|
615
|
+
@db.create_table(:albums_tags) do
|
460
616
|
Integer :album_id1
|
461
617
|
Integer :album_id2
|
462
618
|
Integer :tag_id1
|
@@ -468,14 +624,25 @@ describe "Sequel::Model Composite Key Associations" do
|
|
468
624
|
set_primary_key :id1, :id2
|
469
625
|
unrestrict_primary_key
|
470
626
|
one_to_many :albums, :key=>[:artist_id1, :artist_id2]
|
627
|
+
one_to_one :first_album, :clone=>:albums, :order=>:name
|
628
|
+
one_to_one :last_album, :clone=>:albums, :order=>:name.desc
|
629
|
+
one_to_many :first_two_albums, :clone=>:albums, :order=>:name, :limit=>2
|
630
|
+
one_to_many :second_two_albums, :clone=>:albums, :order=>:name, :limit=>[2, 1]
|
631
|
+
one_to_many :last_two_albums, :clone=>:albums, :order=>:name.desc, :limit=>2
|
471
632
|
plugin :many_through_many
|
472
|
-
|
633
|
+
many_through_many :tags, [[:albums, [:artist_id1, :artist_id2], [:id1, :id2]], [:albums_tags, [:album_id1, :album_id2], [:tag_id1, :tag_id2]]]
|
634
|
+
many_through_many :first_two_tags, :clone=>:tags, :order=>:tags__name, :limit=>2
|
635
|
+
many_through_many :second_two_tags, :clone=>:tags, :order=>:tags__name, :limit=>[2, 1]
|
636
|
+
many_through_many :last_two_tags, :clone=>:tags, :order=>:tags__name.desc, :limit=>2
|
473
637
|
end
|
474
638
|
class ::Album < Sequel::Model(@db)
|
475
639
|
set_primary_key :id1, :id2
|
476
640
|
unrestrict_primary_key
|
477
641
|
many_to_one :artist, :key=>[:artist_id1, :artist_id2]
|
478
642
|
many_to_many :tags, :left_key=>[:album_id1, :album_id2], :right_key=>[:tag_id1, :tag_id2]
|
643
|
+
many_to_many :first_two_tags, :clone=>:tags, :order=>:name, :limit=>2
|
644
|
+
many_to_many :second_two_tags, :clone=>:tags, :order=>:name, :limit=>[2, 1]
|
645
|
+
many_to_many :last_two_tags, :clone=>:tags, :order=>:name.desc, :limit=>2
|
479
646
|
end
|
480
647
|
class ::Tag < Sequel::Model(@db)
|
481
648
|
set_primary_key :id1, :id2
|
@@ -485,6 +652,10 @@ describe "Sequel::Model Composite Key Associations" do
|
|
485
652
|
@album = Album.create(:name=>'Al', :id1=>1, :id2=>2)
|
486
653
|
@artist = Artist.create(:name=>'Ar', :id1=>3, :id2=>4)
|
487
654
|
@tag = Tag.create(:name=>'T', :id1=>5, :id2=>6)
|
655
|
+
@same_album = lambda{Album.create(:name=>'Al', :id1=>7, :id2=>8, :artist_id1=>3, :artist_id2=>4)}
|
656
|
+
@diff_album = lambda{Album.create(:name=>'lA', :id1=>9, :id2=>10, :artist_id1=>3, :artist_id2=>4)}
|
657
|
+
@middle_album = lambda{Album.create(:name=>'Bl', :id1=>13, :id2=>14, :artist_id1=>3, :artist_id2=>4)}
|
658
|
+
@other_tags = lambda{t = [Tag.create(:name=>'U', :id1=>17, :id2=>18), Tag.create(:name=>'V', :id1=>19, :id2=>20)]; @db[:albums_tags].insert([:album_id1, :album_id2, :tag_id1, :tag_id2], Tag.select(1, 2, :id1, :id2)); t}
|
488
659
|
@pr = lambda{[Album.create(:name=>'Al2', :id1=>11, :id2=>12),Artist.create(:name=>'Ar2', :id1=>13, :id2=>14),Tag.create(:name=>'T2', :id1=>15, :id2=>16)]}
|
489
660
|
@ins = lambda{@db[:albums_tags].insert(:tag_id1=>@tag.id1, :tag_id2=>@tag.id2)}
|
490
661
|
end
|
@@ -495,6 +666,13 @@ describe "Sequel::Model Composite Key Associations" do
|
|
495
666
|
|
496
667
|
it_should_behave_like "regular and composite key associations"
|
497
668
|
|
669
|
+
describe "with :eager_limit_strategy=>:correlated_subquery" do
|
670
|
+
before do
|
671
|
+
@els = {:eager_limit_strategy=>:correlated_subquery}
|
672
|
+
end
|
673
|
+
it_should_behave_like "eager limit strategies"
|
674
|
+
end if INTEGRATION_DB.dataset.supports_multiple_column_in? && ![:mysql, :db2].include?(INTEGRATION_DB.database_type)
|
675
|
+
|
498
676
|
specify "should have add method accept hashes and create new records" do
|
499
677
|
@artist.remove_all_albums
|
500
678
|
Album.delete
|