sequel 3.27.0 → 3.28.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 +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
|