sequel 3.28.0 → 3.29.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 +119 -3
- data/Rakefile +5 -3
- data/bin/sequel +1 -5
- data/doc/model_hooks.rdoc +9 -1
- data/doc/opening_databases.rdoc +49 -40
- data/doc/prepared_statements.rdoc +27 -6
- data/doc/release_notes/3.28.0.txt +2 -2
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +18 -9
- data/doc/transactions.rdoc +41 -1
- data/lib/sequel/adapters/ado.rb +28 -17
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/amalgalite.rb +11 -7
- data/lib/sequel/adapters/db2.rb +122 -70
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do.rb +5 -36
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/firebird.rb +3 -6
- data/lib/sequel/adapters/ibmdb.rb +24 -16
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +47 -11
- data/lib/sequel/adapters/jdbc/as400.rb +5 -24
- data/lib/sequel/adapters/jdbc/db2.rb +0 -5
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -12
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +0 -5
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
- data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +64 -51
- data/lib/sequel/adapters/mysql2.rb +15 -9
- data/lib/sequel/adapters/odbc.rb +13 -6
- data/lib/sequel/adapters/odbc/db2.rb +0 -4
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +333 -51
- data/lib/sequel/adapters/postgres.rb +80 -27
- data/lib/sequel/adapters/shared/access.rb +0 -6
- data/lib/sequel/adapters/shared/db2.rb +13 -15
- data/lib/sequel/adapters/shared/firebird.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +23 -18
- data/lib/sequel/adapters/shared/mysql.rb +6 -6
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -30
- data/lib/sequel/adapters/shared/postgres.rb +35 -18
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +116 -37
- data/lib/sequel/adapters/sqlite.rb +16 -8
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/swift/mysql.rb +0 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/tinytds.rb +13 -10
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
- data/lib/sequel/core.rb +40 -0
- data/lib/sequel/database/connecting.rb +1 -2
- data/lib/sequel/database/dataset.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +58 -0
- data/lib/sequel/database/misc.rb +62 -2
- data/lib/sequel/database/query.rb +113 -49
- data/lib/sequel/database/schema_methods.rb +7 -2
- data/lib/sequel/dataset/actions.rb +37 -19
- data/lib/sequel/dataset/features.rb +24 -0
- data/lib/sequel/dataset/graph.rb +7 -6
- data/lib/sequel/dataset/misc.rb +11 -3
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +6 -4
- data/lib/sequel/dataset/query.rb +46 -15
- data/lib/sequel/dataset/sql.rb +28 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +115 -33
- data/lib/sequel/model/base.rb +91 -31
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +6 -10
- data/lib/sequel/plugins/prepared_statements.rb +12 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/sharding.rb +0 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/timezones.rb +42 -42
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +29 -29
- data/spec/adapters/mysql_spec.rb +86 -104
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +98 -33
- data/spec/adapters/spec_helper.rb +0 -5
- data/spec/adapters/sqlite_spec.rb +24 -21
- data/spec/core/connection_pool_spec.rb +9 -15
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +491 -227
- data/spec/core/dataset_spec.rb +638 -1051
- data/spec/core/expression_filters_spec.rb +0 -1
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +51 -114
- data/spec/core/spec_helper.rb +3 -90
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +3 -0
- data/spec/extensions/schema_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/spec_helper.rb +4 -0
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/integration/associations_test.rb +123 -12
- data/spec/integration/dataset_test.rb +140 -47
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +179 -128
- data/spec/integration/prepared_statement_test.rb +92 -91
- data/spec/integration/schema_test.rb +42 -23
- data/spec/integration/spec_helper.rb +25 -31
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +161 -34
- data/spec/integration/type_test.rb +3 -3
- data/spec/model/association_reflection_spec.rb +83 -7
- data/spec/model/associations_spec.rb +393 -676
- data/spec/model/base_spec.rb +186 -116
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +343 -867
- data/spec/model/hooks_spec.rb +160 -79
- data/spec/model/model_spec.rb +118 -165
- data/spec/model/plugins_spec.rb +7 -13
- data/spec/model/record_spec.rb +138 -207
- data/spec/model/spec_helper.rb +10 -73
- metadata +14 -8
|
@@ -3,39 +3,25 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
3
3
|
describe Sequel::Model::DatasetMethods, "#destroy" do
|
|
4
4
|
before do
|
|
5
5
|
@c = Class.new(Sequel::Model(:items)) do
|
|
6
|
-
|
|
6
|
+
self::Destroyed = []
|
|
7
7
|
def destroy
|
|
8
|
-
|
|
9
|
-
end
|
|
10
|
-
def self.destroyed
|
|
11
|
-
class_variable_get(:@@destroyed)
|
|
8
|
+
model::Destroyed << self
|
|
12
9
|
end
|
|
13
10
|
end
|
|
14
11
|
@d = @c.dataset
|
|
12
|
+
@d._fetch = [{:id=>1}, {:id=>2}]
|
|
15
13
|
MODEL_DB.reset
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
it "should instantiate objects in the dataset and call destroy on each" do
|
|
19
|
-
def @d.fetch_rows(sql)
|
|
20
|
-
yield({:id=>1})
|
|
21
|
-
yield({:id=>2})
|
|
22
|
-
end
|
|
23
17
|
@d.destroy
|
|
24
|
-
@c.
|
|
18
|
+
@c::Destroyed.collect{|x| x.values}.should == [{:id=>1}, {:id=>2}]
|
|
25
19
|
end
|
|
26
20
|
|
|
27
21
|
it "should return the number of records destroyed" do
|
|
28
|
-
def @d.fetch_rows(sql)
|
|
29
|
-
yield({:id=>1})
|
|
30
|
-
yield({:id=>2})
|
|
31
|
-
end
|
|
32
22
|
@d.destroy.should == 2
|
|
33
|
-
|
|
34
|
-
yield({:id=>1})
|
|
35
|
-
end
|
|
23
|
+
@d._fetch = [[{:i=>1}], []]
|
|
36
24
|
@d.destroy.should == 1
|
|
37
|
-
def @d.fetch_rows(sql)
|
|
38
|
-
end
|
|
39
25
|
@d.destroy.should == 0
|
|
40
26
|
end
|
|
41
27
|
|
|
@@ -61,10 +47,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
|
|
|
61
47
|
end
|
|
62
48
|
|
|
63
49
|
it "should result in a hash with primary key value keys and model object values" do
|
|
64
|
-
|
|
65
|
-
yield({:name=>1})
|
|
66
|
-
yield({:name=>2})
|
|
67
|
-
end
|
|
50
|
+
@d._fetch = [{:name=>1}, {:name=>2}]
|
|
68
51
|
h = @d.to_hash
|
|
69
52
|
h.should be_a_kind_of(Hash)
|
|
70
53
|
a = h.to_a
|
|
@@ -73,10 +56,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
|
|
|
73
56
|
end
|
|
74
57
|
|
|
75
58
|
it "should result in a hash with given value keys and model object values" do
|
|
76
|
-
|
|
77
|
-
yield({:name=>1, :number=>3})
|
|
78
|
-
yield({:name=>2, :number=>4})
|
|
79
|
-
end
|
|
59
|
+
@d._fetch = [{:name=>1, :number=>3}, {:name=>2, :number=>4}]
|
|
80
60
|
h = @d.to_hash(:number)
|
|
81
61
|
h.should be_a_kind_of(Hash)
|
|
82
62
|
a = h.to_a
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
|
3
3
|
describe Sequel::Model, "#eager" do
|
|
4
|
-
before
|
|
5
|
-
MODEL_DB.reset
|
|
6
|
-
|
|
4
|
+
before do
|
|
7
5
|
class ::EagerAlbum < Sequel::Model(:albums)
|
|
8
6
|
columns :id, :band_id
|
|
9
7
|
many_to_one :band, :class=>'EagerBand', :key=>:band_id
|
|
@@ -48,63 +46,45 @@ describe Sequel::Model, "#eager" do
|
|
|
48
46
|
many_to_many :bands, :class=>'EagerBand', :left_key=>:member_id, :right_key=>:band_id, :join_table=>:bm, :order =>:id
|
|
49
47
|
end
|
|
50
48
|
|
|
51
|
-
EagerAlbum.dataset.
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
EagerAlbum.dataset.columns(:id, :band_id)
|
|
50
|
+
EagerAlbum.dataset._fetch = proc do |sql|
|
|
51
|
+
h = if sql =~ /101/
|
|
52
|
+
{:id => 101, :band_id=> 101}
|
|
53
|
+
else
|
|
54
|
+
{:id => 1, :band_id=> 2}
|
|
54
55
|
end
|
|
56
|
+
h[:x_foreign_key_x] = 4 if sql =~ /ag\.genre_id/
|
|
57
|
+
h
|
|
58
|
+
end
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
@db << sql
|
|
64
|
-
yield h
|
|
65
|
-
end
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
EagerBand.dataset.extend(Module.new {
|
|
69
|
-
def fetch_rows(sql)
|
|
60
|
+
EagerBand.dataset._fetch = proc do |sql|
|
|
61
|
+
case sql
|
|
62
|
+
when /id IN (101)/
|
|
63
|
+
# nothing
|
|
64
|
+
when /id > 100/
|
|
65
|
+
[{:id => 101}, {:id => 102}]
|
|
66
|
+
else
|
|
70
67
|
h = {:id => 2}
|
|
71
|
-
h
|
|
72
|
-
|
|
73
|
-
case sql
|
|
74
|
-
when /id IN (101)/
|
|
75
|
-
when /id > 100/
|
|
76
|
-
yield({:id => 101})
|
|
77
|
-
yield({:id => 102})
|
|
78
|
-
else
|
|
79
|
-
yield h
|
|
80
|
-
end
|
|
68
|
+
h[:x_foreign_key_x] = 5 if sql =~ /bm\.member_id/
|
|
69
|
+
h
|
|
81
70
|
end
|
|
82
|
-
|
|
71
|
+
end
|
|
83
72
|
|
|
84
|
-
EagerTrack.dataset.
|
|
85
|
-
def fetch_rows(sql)
|
|
86
|
-
@db << sql
|
|
87
|
-
yield({:id => 3, :album_id => 1})
|
|
88
|
-
end
|
|
89
|
-
})
|
|
73
|
+
EagerTrack.dataset._fetch = {:id => 3, :album_id => 1}
|
|
90
74
|
|
|
91
|
-
EagerGenre.dataset.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
yield h
|
|
97
|
-
end
|
|
98
|
-
})
|
|
75
|
+
EagerGenre.dataset._fetch = proc do |sql|
|
|
76
|
+
h = {:id => 4}
|
|
77
|
+
h[:x_foreign_key_x] = 1 if sql =~ /ag\.album_id/
|
|
78
|
+
h
|
|
79
|
+
end
|
|
99
80
|
|
|
100
|
-
EagerBandMember.dataset.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
})
|
|
81
|
+
EagerBandMember.dataset._fetch = proc do |sql|
|
|
82
|
+
h = {:id => 5}
|
|
83
|
+
h[:x_foreign_key_x] = 2 if sql =~ /bm\.band_id/
|
|
84
|
+
h
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
MODEL_DB.reset
|
|
108
88
|
end
|
|
109
89
|
after do
|
|
110
90
|
[:EagerAlbum, :EagerBand, :EagerTrack, :EagerGenre, :EagerBandMember].each{|x| Object.send(:remove_const, x)}
|
|
@@ -116,15 +96,10 @@ describe Sequel::Model, "#eager" do
|
|
|
116
96
|
|
|
117
97
|
it "should eagerly load a single many_to_one association" do
|
|
118
98
|
a = EagerAlbum.eager(:band).all
|
|
119
|
-
a.should be_a_kind_of(Array)
|
|
120
|
-
a.size.should == 1
|
|
121
|
-
a.first.should be_a_kind_of(EagerAlbum)
|
|
122
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
123
99
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
124
|
-
a
|
|
125
|
-
a.band.should
|
|
126
|
-
|
|
127
|
-
MODEL_DB.sqls.length.should == 2
|
|
100
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
101
|
+
a.first.band.should == EagerBand.load(:id=>2)
|
|
102
|
+
MODEL_DB.sqls.should == []
|
|
128
103
|
end
|
|
129
104
|
|
|
130
105
|
it "should eagerly load a single one_to_one association" do
|
|
@@ -133,7 +108,7 @@ describe Sequel::Model, "#eager" do
|
|
|
133
108
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
134
109
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
135
110
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
136
|
-
MODEL_DB.sqls.
|
|
111
|
+
MODEL_DB.sqls.should == []
|
|
137
112
|
end
|
|
138
113
|
|
|
139
114
|
it "should eagerly load a single one_to_one association using the :distinct_on strategy" do
|
|
@@ -143,7 +118,7 @@ describe Sequel::Model, "#eager" do
|
|
|
143
118
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
144
119
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT DISTINCT ON (tracks.album_id) * FROM tracks WHERE (tracks.album_id IN (1)) ORDER BY tracks.album_id']
|
|
145
120
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
146
|
-
MODEL_DB.sqls.
|
|
121
|
+
MODEL_DB.sqls.should == []
|
|
147
122
|
end
|
|
148
123
|
|
|
149
124
|
it "should eagerly load a single one_to_one association using the :window_function strategy" do
|
|
@@ -153,7 +128,7 @@ describe Sequel::Model, "#eager" do
|
|
|
153
128
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
154
129
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 1)']
|
|
155
130
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
156
|
-
MODEL_DB.sqls.
|
|
131
|
+
MODEL_DB.sqls.should == []
|
|
157
132
|
end
|
|
158
133
|
|
|
159
134
|
it "should eagerly load a single one_to_one association using the :correlated_subquery strategy" do
|
|
@@ -162,7 +137,7 @@ describe Sequel::Model, "#eager" do
|
|
|
162
137
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
163
138
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY name LIMIT 1))) ORDER BY name']
|
|
164
139
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
165
|
-
MODEL_DB.sqls.
|
|
140
|
+
MODEL_DB.sqls.should == []
|
|
166
141
|
end
|
|
167
142
|
|
|
168
143
|
it "should handle qualified order clauses when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
|
|
@@ -171,7 +146,7 @@ describe Sequel::Model, "#eager" do
|
|
|
171
146
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
172
147
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY t1.name, t1.name DESC, t1.name, t.name, 1 LIMIT 1))) ORDER BY tracks.name, tracks.name DESC, tracks.name, t.name, 1']
|
|
173
148
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
174
|
-
MODEL_DB.sqls.
|
|
149
|
+
MODEL_DB.sqls.should == []
|
|
175
150
|
end
|
|
176
151
|
|
|
177
152
|
it "should handle qualified composite keys when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
|
|
@@ -180,17 +155,12 @@ describe Sequel::Model, "#eager" do
|
|
|
180
155
|
c1.set_primary_key [:id, :band_id]
|
|
181
156
|
c2.set_primary_key [:id, :album_id]
|
|
182
157
|
c1.one_to_one :track, :class=>c2, :key=>[:album_id, :id], :eager_limit_strategy=>:correlated_subquery
|
|
183
|
-
c2.dataset.
|
|
184
|
-
def fetch_rows(sql)
|
|
185
|
-
MODEL_DB << sql
|
|
186
|
-
yield({:id => 2, :album_id=>1})
|
|
187
|
-
end
|
|
188
|
-
end)
|
|
158
|
+
c2.dataset._fetch = {:id => 2, :album_id=>1}
|
|
189
159
|
a = c1.eager(:track).all
|
|
190
160
|
a.should == [c1.load(:id => 1, :band_id => 2)]
|
|
191
161
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (((tracks.album_id, tracks.id) IN ((1, 2))) AND ((tracks.id, tracks.album_id) IN (SELECT t1.id, t1.album_id FROM tracks AS t1 WHERE ((t1.album_id = tracks.album_id) AND (t1.id = tracks.id)) LIMIT 1)))']
|
|
192
162
|
a.first.track.should == c2.load(:id => 2, :album_id=>1)
|
|
193
|
-
MODEL_DB.sqls.
|
|
163
|
+
MODEL_DB.sqls.should == []
|
|
194
164
|
end
|
|
195
165
|
|
|
196
166
|
it "should eagerly load a single one_to_many association" do
|
|
@@ -198,22 +168,15 @@ describe Sequel::Model, "#eager" do
|
|
|
198
168
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
199
169
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
200
170
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
201
|
-
MODEL_DB.sqls.
|
|
171
|
+
MODEL_DB.sqls.should == []
|
|
202
172
|
end
|
|
203
173
|
|
|
204
174
|
it "should eagerly load a single many_to_many association" do
|
|
205
175
|
a = EagerAlbum.eager(:genres).all
|
|
206
|
-
a.should
|
|
207
|
-
a.size.should == 1
|
|
208
|
-
a.first.should be_a_kind_of(EagerAlbum)
|
|
209
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
176
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
210
177
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
211
|
-
a
|
|
212
|
-
|
|
213
|
-
a.genres.size.should == 1
|
|
214
|
-
a.genres.first.should be_a_kind_of(EagerGenre)
|
|
215
|
-
a.genres.first.values.should == {:id => 4}
|
|
216
|
-
MODEL_DB.sqls.length.should == 2
|
|
178
|
+
a.first.genres.should == [EagerGenre.load(:id=>4)]
|
|
179
|
+
MODEL_DB.sqls.should == []
|
|
217
180
|
end
|
|
218
181
|
|
|
219
182
|
it "should correctly handle a :select=>[] option to many_to_many" do
|
|
@@ -222,150 +185,88 @@ describe Sequel::Model, "#eager" do
|
|
|
222
185
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
223
186
|
end
|
|
224
187
|
|
|
188
|
+
it "should correctly handle an aliased join table in many_to_many" do
|
|
189
|
+
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>:ag___ga
|
|
190
|
+
a = EagerAlbum.eager(:sgenres).all
|
|
191
|
+
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON ((ga.genre_id = genres.id) AND (ga.album_id IN (1)))"]
|
|
192
|
+
end
|
|
193
|
+
|
|
225
194
|
it "should eagerly load multiple associations in a single call" do
|
|
226
195
|
a = EagerAlbum.eager(:genres, :tracks, :band).all
|
|
227
|
-
a.should
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT * FROM bands WHERE (bands.id IN (2))'))
|
|
234
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT * FROM tracks WHERE (tracks.album_id IN (1))'))
|
|
235
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))'))
|
|
196
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
197
|
+
sqls = MODEL_DB.sqls
|
|
198
|
+
sqls.shift.should == 'SELECT * FROM albums'
|
|
199
|
+
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
200
|
+
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
|
201
|
+
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))']
|
|
236
202
|
a = a.first
|
|
237
|
-
a.band.should
|
|
238
|
-
a.
|
|
239
|
-
a.
|
|
240
|
-
|
|
241
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
242
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
243
|
-
a.genres.should be_a_kind_of(Array)
|
|
244
|
-
a.genres.size.should == 1
|
|
245
|
-
a.genres.first.should be_a_kind_of(EagerGenre)
|
|
246
|
-
a.genres.first.values.should == {:id => 4}
|
|
247
|
-
MODEL_DB.sqls.length.should == 4
|
|
203
|
+
a.band.should == EagerBand.load(:id=>2)
|
|
204
|
+
a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
205
|
+
a.genres.should == [EagerGenre.load(:id => 4)]
|
|
206
|
+
MODEL_DB.sqls.should == []
|
|
248
207
|
end
|
|
249
208
|
|
|
250
209
|
it "should eagerly load multiple associations in separate calls" do
|
|
251
210
|
a = EagerAlbum.eager(:genres).eager(:tracks).eager(:band).all
|
|
252
|
-
a.should
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT * FROM bands WHERE (bands.id IN (2))'))
|
|
259
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT * FROM tracks WHERE (tracks.album_id IN (1))'))
|
|
260
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))'))
|
|
211
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
212
|
+
sqls = MODEL_DB.sqls
|
|
213
|
+
sqls.shift.should == 'SELECT * FROM albums'
|
|
214
|
+
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
215
|
+
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
|
216
|
+
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))']
|
|
261
217
|
a = a.first
|
|
262
|
-
a.band.should
|
|
263
|
-
a.
|
|
264
|
-
a.
|
|
265
|
-
|
|
266
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
267
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
268
|
-
a.genres.should be_a_kind_of(Array)
|
|
269
|
-
a.genres.size.should == 1
|
|
270
|
-
a.genres.first.should be_a_kind_of(EagerGenre)
|
|
271
|
-
a.genres.first.values.should == {:id => 4}
|
|
272
|
-
MODEL_DB.sqls.length.should == 4
|
|
218
|
+
a.band.should == EagerBand.load(:id=>2)
|
|
219
|
+
a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
220
|
+
a.genres.should == [EagerGenre.load(:id => 4)]
|
|
221
|
+
MODEL_DB.sqls.should == []
|
|
273
222
|
end
|
|
274
223
|
|
|
275
224
|
it "should allow cascading of eager loading for associations of associated models" do
|
|
276
225
|
a = EagerTrack.eager(:album=>{:band=>:members}).all
|
|
277
|
-
a.should
|
|
278
|
-
a.size.should == 1
|
|
279
|
-
a.first.should be_a_kind_of(EagerTrack)
|
|
280
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
281
|
-
MODEL_DB.sqls.length.should == 4
|
|
226
|
+
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
282
227
|
MODEL_DB.sqls.should == ['SELECT * FROM tracks',
|
|
283
228
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
|
284
229
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
285
230
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
|
|
286
231
|
a = a.first
|
|
287
|
-
a.album.should
|
|
288
|
-
a.album.
|
|
289
|
-
a.album.band.should
|
|
290
|
-
|
|
291
|
-
a.album.band.members.should be_a_kind_of(Array)
|
|
292
|
-
a.album.band.members.size.should == 1
|
|
293
|
-
a.album.band.members.first.should be_a_kind_of(EagerBandMember)
|
|
294
|
-
a.album.band.members.first.values.should == {:id => 5}
|
|
295
|
-
MODEL_DB.sqls.length.should == 4
|
|
232
|
+
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
233
|
+
a.album.band.should == EagerBand.load(:id => 2)
|
|
234
|
+
a.album.band.members.should == [EagerBandMember.load(:id => 5)]
|
|
235
|
+
MODEL_DB.sqls.should == []
|
|
296
236
|
end
|
|
297
237
|
|
|
298
238
|
it "should cascade eagerly loading when the :eager association option is used" do
|
|
299
239
|
a = EagerBand.eager(:albums).all
|
|
300
|
-
a.should
|
|
301
|
-
a.size.should == 1
|
|
302
|
-
a.first.should be_a_kind_of(EagerBand)
|
|
303
|
-
a.first.values.should == {:id => 2}
|
|
240
|
+
a.should == [EagerBand.load(:id=>2)]
|
|
304
241
|
MODEL_DB.sqls.should == ['SELECT * FROM bands',
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
a
|
|
308
|
-
a.albums.should
|
|
309
|
-
|
|
310
|
-
a.albums.first.should be_a_kind_of(EagerAlbum)
|
|
311
|
-
a.albums.first.values.should == {:id => 1, :band_id => 2}
|
|
312
|
-
a = a.albums.first
|
|
313
|
-
a.tracks.should be_a_kind_of(Array)
|
|
314
|
-
a.tracks.size.should == 1
|
|
315
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
316
|
-
a.tracks.first.values.should == {:id => 3, :album_id => 1}
|
|
317
|
-
MODEL_DB.sqls.length.should == 3
|
|
242
|
+
'SELECT * FROM albums WHERE (albums.band_id IN (2))',
|
|
243
|
+
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
244
|
+
a.first.albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
245
|
+
a.first.albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
246
|
+
MODEL_DB.sqls.should == []
|
|
318
247
|
end
|
|
319
248
|
|
|
320
249
|
it "should respect :eager when lazily loading an association" do
|
|
321
250
|
a = EagerBand.all
|
|
322
|
-
a.should
|
|
323
|
-
a.size.should == 1
|
|
324
|
-
a.first.should be_a_kind_of(EagerBand)
|
|
325
|
-
a.first.values.should == {:id => 2}
|
|
251
|
+
a.should == [EagerBand.load(:id=>2)]
|
|
326
252
|
MODEL_DB.sqls.should == ['SELECT * FROM bands']
|
|
327
|
-
a = a.first
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
a.albums.size.should == 1
|
|
334
|
-
a.albums.first.should be_a_kind_of(EagerAlbum)
|
|
335
|
-
a.albums.first.values.should == {:id => 1, :band_id => 2}
|
|
336
|
-
a = a.albums.first
|
|
337
|
-
a.tracks.should be_a_kind_of(Array)
|
|
338
|
-
a.tracks.size.should == 1
|
|
339
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
340
|
-
a.tracks.first.values.should == {:id => 3, :album_id => 1}
|
|
341
|
-
MODEL_DB.sqls.length.should == 3
|
|
253
|
+
a = a.first.albums
|
|
254
|
+
MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE (albums.band_id = 2)',
|
|
255
|
+
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
256
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
257
|
+
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
258
|
+
MODEL_DB.sqls.should == []
|
|
342
259
|
end
|
|
343
260
|
|
|
344
261
|
it "should cascade eagerly loading when the :eager_graph association option is used" do
|
|
345
|
-
EagerAlbum.dataset.
|
|
346
|
-
def fetch_rows(sql)
|
|
347
|
-
@db << sql
|
|
348
|
-
yield({:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1})
|
|
349
|
-
end
|
|
350
|
-
})
|
|
262
|
+
EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
351
263
|
a = EagerBand.eager(:graph_albums).all
|
|
352
|
-
a.should
|
|
353
|
-
a.size.should == 1
|
|
354
|
-
a.first.should be_a_kind_of(EagerBand)
|
|
355
|
-
a.first.values.should == {:id => 2}
|
|
264
|
+
a.should == [EagerBand.load(:id=>2)]
|
|
356
265
|
MODEL_DB.sqls.should == ['SELECT * FROM bands',
|
|
357
|
-
|
|
358
|
-
a
|
|
359
|
-
a.graph_albums.should
|
|
360
|
-
|
|
361
|
-
a.graph_albums.first.should be_a_kind_of(EagerAlbum)
|
|
362
|
-
a.graph_albums.first.values.should == {:id => 1, :band_id => 2}
|
|
363
|
-
a = a.graph_albums.first
|
|
364
|
-
a.tracks.should be_a_kind_of(Array)
|
|
365
|
-
a.tracks.size.should == 1
|
|
366
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
367
|
-
a.tracks.first.values.should == {:id => 3, :album_id => 1}
|
|
368
|
-
MODEL_DB.sqls.length.should == 2
|
|
266
|
+
'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) WHERE (albums.band_id IN (2))']
|
|
267
|
+
a.first.graph_albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
268
|
+
a.first.graph_albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
269
|
+
MODEL_DB.sqls.should == []
|
|
369
270
|
end
|
|
370
271
|
|
|
371
272
|
it "should raise an Error when eager loading a many_to_many association with the :eager_graph option" do
|
|
@@ -374,67 +275,36 @@ describe Sequel::Model, "#eager" do
|
|
|
374
275
|
|
|
375
276
|
it "should respect :eager_graph when lazily loading an association" do
|
|
376
277
|
a = EagerBand.all
|
|
377
|
-
a.should
|
|
378
|
-
a.size.should == 1
|
|
379
|
-
a.first.should be_a_kind_of(EagerBand)
|
|
380
|
-
a.first.values.should == {:id => 2}
|
|
278
|
+
a.should == [EagerBand.load(:id=>2)]
|
|
381
279
|
MODEL_DB.sqls.should == ['SELECT * FROM bands']
|
|
382
280
|
a = a.first
|
|
383
|
-
EagerAlbum.dataset.
|
|
384
|
-
def fetch_rows(sql)
|
|
385
|
-
@db << sql
|
|
386
|
-
yield({:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1})
|
|
387
|
-
end
|
|
388
|
-
})
|
|
281
|
+
EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
389
282
|
a.graph_albums
|
|
390
|
-
MODEL_DB.sqls.should == ['SELECT
|
|
391
|
-
|
|
392
|
-
a.graph_albums.should
|
|
393
|
-
|
|
394
|
-
a.graph_albums.first.should be_a_kind_of(EagerAlbum)
|
|
395
|
-
a.graph_albums.first.values.should == {:id => 1, :band_id => 2}
|
|
396
|
-
a = a.graph_albums.first
|
|
397
|
-
a.tracks.should be_a_kind_of(Array)
|
|
398
|
-
a.tracks.size.should == 1
|
|
399
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
400
|
-
a.tracks.first.values.should == {:id => 3, :album_id => 1}
|
|
401
|
-
MODEL_DB.sqls.length.should == 2
|
|
283
|
+
MODEL_DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) WHERE (albums.band_id = 2)']
|
|
284
|
+
a.graph_albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
285
|
+
a.graph_albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
286
|
+
MODEL_DB.sqls.should == []
|
|
402
287
|
end
|
|
403
288
|
|
|
404
289
|
it "should respect :eager_graph when lazily loading a many_to_many association" do
|
|
405
|
-
EagerBandMember.dataset
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
end
|
|
409
|
-
def fetch_rows(sql)
|
|
410
|
-
@db << sql
|
|
411
|
-
yield({:id=>5, :bands_id=>2, :p_k=>6})
|
|
412
|
-
yield({:id=>5, :bands_id=>3, :p_k=>6})
|
|
413
|
-
end
|
|
414
|
-
})
|
|
290
|
+
ds = EagerBandMember.dataset
|
|
291
|
+
def ds.columns() [:id] end
|
|
292
|
+
ds._fetch = [{:id=>5, :bands_id=>2, :p_k=>6}, {:id=>5, :bands_id=>3, :p_k=>6}]
|
|
415
293
|
a = EagerBand.load(:id=>2)
|
|
416
294
|
a.graph_members.should == [EagerBandMember.load(:id=>5)]
|
|
417
295
|
MODEL_DB.sqls.should == ['SELECT members.id, bands.id AS bands_id, bands.p_k FROM (SELECT members.* FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id = 2))) AS members LEFT OUTER JOIN bm AS bm_0 ON (bm_0.member_id = members.id) LEFT OUTER JOIN bands ON (bands.id = bm_0.band_id) ORDER BY bands.id']
|
|
418
296
|
a.graph_members.first.bands.should == [EagerBand.load(:id=>2, :p_k=>6), EagerBand.load(:id=>3, :p_k=>6)]
|
|
419
|
-
MODEL_DB.sqls.
|
|
297
|
+
MODEL_DB.sqls.should == []
|
|
420
298
|
end
|
|
421
299
|
|
|
422
300
|
it "should respect :conditions when eagerly loading" do
|
|
423
301
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>{:a=>32}
|
|
424
302
|
a = EagerBandMember.eager(:good_bands).all
|
|
425
|
-
a.should
|
|
426
|
-
a.size.should == 1
|
|
427
|
-
a.first.should be_a_kind_of(EagerBandMember)
|
|
428
|
-
a.first.values.should == {:id => 5}
|
|
303
|
+
a.should == [EagerBandMember.load(:id => 5)]
|
|
429
304
|
MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (a = 32) ORDER BY id']
|
|
430
|
-
a
|
|
431
|
-
|
|
432
|
-
a.good_bands.size.should == 1
|
|
433
|
-
a.good_bands.first.should be_a_kind_of(EagerBand)
|
|
434
|
-
a.good_bands.first.values.should == {:id => 2}
|
|
435
|
-
MODEL_DB.sqls.length.should == 2
|
|
305
|
+
a.first.good_bands.should == [EagerBand.load(:id => 2)]
|
|
306
|
+
MODEL_DB.sqls.should == []
|
|
436
307
|
|
|
437
|
-
MODEL_DB.sqls.clear
|
|
438
308
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>"x = 1"
|
|
439
309
|
a = EagerBandMember.eager(:good_bands).all
|
|
440
310
|
MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (x = 1) ORDER BY id']
|
|
@@ -442,63 +312,36 @@ describe Sequel::Model, "#eager" do
|
|
|
442
312
|
|
|
443
313
|
it "should respect :order when eagerly loading" do
|
|
444
314
|
a = EagerBandMember.eager(:bands).all
|
|
445
|
-
a.should
|
|
446
|
-
a.size.should == 1
|
|
447
|
-
a.first.should be_a_kind_of(EagerBandMember)
|
|
448
|
-
a.first.values.should == {:id => 5}
|
|
315
|
+
a.should == [EagerBandMember.load(:id => 5)]
|
|
449
316
|
MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) ORDER BY id']
|
|
450
|
-
a
|
|
451
|
-
|
|
452
|
-
a.bands.size.should == 1
|
|
453
|
-
a.bands.first.should be_a_kind_of(EagerBand)
|
|
454
|
-
a.bands.first.values.should == {:id => 2}
|
|
455
|
-
MODEL_DB.sqls.length.should == 2
|
|
317
|
+
a.first.bands.should == [EagerBand.load(:id => 2)]
|
|
318
|
+
MODEL_DB.sqls.should == []
|
|
456
319
|
end
|
|
457
320
|
|
|
458
321
|
it "should populate the reciprocal many_to_one association when eagerly loading the one_to_many association" do
|
|
459
322
|
a = EagerAlbum.eager(:tracks).all
|
|
460
|
-
a.should
|
|
461
|
-
a.size.should == 1
|
|
462
|
-
a.first.should be_a_kind_of(EagerAlbum)
|
|
463
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
323
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
464
324
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
|
|
465
|
-
a
|
|
466
|
-
a.tracks.should
|
|
467
|
-
|
|
468
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
469
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
470
|
-
a.tracks.first.album.should be_a_kind_of(EagerAlbum)
|
|
471
|
-
a.tracks.first.album.should == a
|
|
472
|
-
MODEL_DB.sqls.length.should == 2
|
|
325
|
+
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
326
|
+
a.first.tracks.first.album.should == a.first
|
|
327
|
+
MODEL_DB.sqls.should == []
|
|
473
328
|
end
|
|
474
329
|
|
|
475
330
|
it "should cache the negative lookup when eagerly loading a many_to_one association" do
|
|
476
331
|
a = EagerAlbum.eager(:band).filter(:id=>101).all
|
|
477
|
-
a.should
|
|
478
|
-
a.size.should == 1
|
|
479
|
-
a.first.should be_a_kind_of(EagerAlbum)
|
|
480
|
-
a.first.values.should == {:id => 101, :band_id => 101}
|
|
332
|
+
a.should == [EagerAlbum.load(:id => 101, :band_id => 101)]
|
|
481
333
|
MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE (id = 101)', 'SELECT * FROM bands WHERE (bands.id IN (101))']
|
|
482
|
-
a
|
|
483
|
-
a.
|
|
484
|
-
|
|
485
|
-
MODEL_DB.sqls.length.should == 2
|
|
334
|
+
a.first.associations.fetch(:band, 2).should be_nil
|
|
335
|
+
a.first.band.should be_nil
|
|
336
|
+
MODEL_DB.sqls.should == []
|
|
486
337
|
end
|
|
487
338
|
|
|
488
339
|
it "should cache the negative lookup when eagerly loading a *_to_many associations" do
|
|
489
340
|
a = EagerBand.eager(:albums).filter('id > 100').all
|
|
490
|
-
a.should
|
|
491
|
-
a.size.should == 2
|
|
492
|
-
a.first.should be_a_kind_of(EagerBand)
|
|
493
|
-
a.first.values.should == {:id => 101}
|
|
494
|
-
a.last.values.should == {:id => 102}
|
|
341
|
+
a.should == [EagerBand.load(:id => 101), EagerBand.load(:id =>102)]
|
|
495
342
|
MODEL_DB.sqls.should == ['SELECT * FROM bands WHERE (id > 100)', 'SELECT * FROM albums WHERE (albums.band_id IN (101, 102))', "SELECT * FROM tracks WHERE (tracks.album_id IN (101))"]
|
|
496
|
-
a.
|
|
497
|
-
|
|
498
|
-
a.first.albums.first.should be_a_kind_of(EagerAlbum)
|
|
499
|
-
a.last.associations[:albums].should == []
|
|
500
|
-
a.last.albums.should == []
|
|
501
|
-
MODEL_DB.sqls.length.should == 3
|
|
343
|
+
a.map{|b| b.associations[:albums]}.should == [[EagerAlbum.load({:band_id=>101, :id=>101})], []]
|
|
344
|
+
MODEL_DB.sqls.should == []
|
|
502
345
|
end
|
|
503
346
|
|
|
504
347
|
it "should use the association's block when eager loading by default" do
|
|
@@ -509,7 +352,6 @@ describe Sequel::Model, "#eager" do
|
|
|
509
352
|
it "should use the eager_block option when eager loading if given" do
|
|
510
353
|
EagerBand.eager(:good_albums).all
|
|
511
354
|
MODEL_DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))"]
|
|
512
|
-
MODEL_DB.sqls.clear
|
|
513
355
|
EagerBand.eager(:good_albums=>:good_tracks).all
|
|
514
356
|
MODEL_DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))", "SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (name = 'Good'))"]
|
|
515
357
|
end
|
|
@@ -522,34 +364,31 @@ describe Sequel::Model, "#eager" do
|
|
|
522
364
|
it "should respect the association's :select option" do
|
|
523
365
|
EagerAlbum.eager(:band_name).all
|
|
524
366
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM bands WHERE (bands.id IN (2))"]
|
|
525
|
-
MODEL_DB.sqls.clear
|
|
526
367
|
EagerAlbum.eager(:track_names).all
|
|
527
368
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
528
|
-
MODEL_DB.sqls.clear
|
|
529
369
|
EagerAlbum.eager(:genre_names).all
|
|
530
370
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT id, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
531
371
|
end
|
|
532
372
|
|
|
373
|
+
it "should respect many_to_one association's :qualify option" do
|
|
374
|
+
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :qualify=>false, :key=>:band_id
|
|
375
|
+
EagerBand.dataset._fetch = {:id=>2}
|
|
376
|
+
as = EagerAlbum.eager(:special_band).all
|
|
377
|
+
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (id IN (2))"]
|
|
378
|
+
as.map{|a| a.special_band}.should == [EagerBand.load(:id=>2)]
|
|
379
|
+
MODEL_DB.sqls.should == []
|
|
380
|
+
end
|
|
381
|
+
|
|
533
382
|
it "should respect the association's :primary_key option" do
|
|
534
383
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>:p_k, :key=>:band_id
|
|
535
|
-
EagerBand.dataset.
|
|
536
|
-
def fetch_rows(sql)
|
|
537
|
-
MODEL_DB.sqls << sql
|
|
538
|
-
yield({:p_k=>2, :id=>1})
|
|
539
|
-
end
|
|
540
|
-
})
|
|
384
|
+
EagerBand.dataset._fetch = {:p_k=>2, :id=>1}
|
|
541
385
|
as = EagerAlbum.eager(:special_band).all
|
|
542
386
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (bands.p_k IN (2))"]
|
|
543
387
|
as.length.should == 1
|
|
544
388
|
as.first.special_band.should == EagerBand.load(:p_k=>2, :id=>1)
|
|
545
|
-
|
|
389
|
+
|
|
546
390
|
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id
|
|
547
|
-
EagerTrack.dataset.
|
|
548
|
-
def fetch_rows(sql)
|
|
549
|
-
MODEL_DB.sqls << sql
|
|
550
|
-
yield({:album_id=>2, :id=>1})
|
|
551
|
-
end
|
|
552
|
-
})
|
|
391
|
+
EagerTrack.dataset._fetch = {:album_id=>2, :id=>1}
|
|
553
392
|
as = EagerAlbum.eager(:special_tracks).all
|
|
554
393
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
|
|
555
394
|
as.length.should == 1
|
|
@@ -558,12 +397,7 @@ describe Sequel::Model, "#eager" do
|
|
|
558
397
|
|
|
559
398
|
it "should respect the many_to_one association's composite keys" do
|
|
560
399
|
EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>[:id, :p_k], :key=>[:band_id, :id]
|
|
561
|
-
EagerBand.dataset.
|
|
562
|
-
def fetch_rows(sql)
|
|
563
|
-
MODEL_DB.sqls << sql
|
|
564
|
-
yield({:p_k=>1, :id=>2})
|
|
565
|
-
end
|
|
566
|
-
})
|
|
400
|
+
EagerBand.dataset._fetch = {:p_k=>1, :id=>2}
|
|
567
401
|
as = EagerAlbum.eager(:special_band).all
|
|
568
402
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE ((bands.id, bands.p_k) IN ((2, 1)))"]
|
|
569
403
|
as.length.should == 1
|
|
@@ -572,12 +406,7 @@ describe Sequel::Model, "#eager" do
|
|
|
572
406
|
|
|
573
407
|
it "should respect the one_to_many association's composite keys" do
|
|
574
408
|
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>[:band_id, :id], :key=>[:id, :album_id]
|
|
575
|
-
EagerTrack.dataset.
|
|
576
|
-
def fetch_rows(sql)
|
|
577
|
-
MODEL_DB.sqls << sql
|
|
578
|
-
yield({:album_id=>1, :id=>2})
|
|
579
|
-
end
|
|
580
|
-
})
|
|
409
|
+
EagerTrack.dataset._fetch = {:album_id=>1, :id=>2}
|
|
581
410
|
as = EagerAlbum.eager(:special_tracks).all
|
|
582
411
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.id, tracks.album_id) IN ((2, 1)))"]
|
|
583
412
|
as.length.should == 1
|
|
@@ -586,13 +415,7 @@ describe Sequel::Model, "#eager" do
|
|
|
586
415
|
|
|
587
416
|
it "should respect many_to_many association's composite keys" do
|
|
588
417
|
EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :left_primary_key=>[:band_id, :id], :left_key=>[:l1, :l2], :right_primary_key=>[:xxx, :id], :right_key=>[:r1, :r2], :join_table=>:ag
|
|
589
|
-
EagerGenre.dataset.
|
|
590
|
-
def fetch_rows(sql)
|
|
591
|
-
MODEL_DB.sqls << sql
|
|
592
|
-
yield({:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5})
|
|
593
|
-
yield({:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>6})
|
|
594
|
-
end
|
|
595
|
-
})
|
|
418
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5}, {:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>6}]
|
|
596
419
|
as = EagerAlbum.eager(:special_genres).all
|
|
597
420
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.l1 AS x_foreign_key_0_x, ag.l2 AS x_foreign_key_1_x FROM genres INNER JOIN ag ON ((ag.r1 = genres.xxx) AND (ag.r2 = genres.id) AND ((ag.l1, ag.l2) IN ((2, 1))))"]
|
|
598
421
|
as.length.should == 1
|
|
@@ -601,13 +424,7 @@ describe Sequel::Model, "#eager" do
|
|
|
601
424
|
|
|
602
425
|
it "should respect many_to_many association's :left_primary_key and :right_primary_key options" do
|
|
603
426
|
EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_primary_key=>:xxx, :right_key=>:genre_id, :join_table=>:ag
|
|
604
|
-
EagerGenre.dataset.
|
|
605
|
-
def fetch_rows(sql)
|
|
606
|
-
MODEL_DB.sqls << sql
|
|
607
|
-
yield({:x_foreign_key_x=>2, :id=>5})
|
|
608
|
-
yield({:x_foreign_key_x=>2, :id=>6})
|
|
609
|
-
end
|
|
610
|
-
})
|
|
427
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
611
428
|
as = EagerAlbum.eager(:special_genres).all
|
|
612
429
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.xxx) AND (ag.album_id IN (2)))"]
|
|
613
430
|
as.length.should == 1
|
|
@@ -616,14 +433,7 @@ describe Sequel::Model, "#eager" do
|
|
|
616
433
|
|
|
617
434
|
it "should respect the :limit option on a one_to_many association" do
|
|
618
435
|
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2
|
|
619
|
-
EagerTrack.dataset.
|
|
620
|
-
def fetch_rows(sql)
|
|
621
|
-
MODEL_DB.sqls << sql
|
|
622
|
-
yield({:album_id=>1, :id=>2})
|
|
623
|
-
yield({:album_id=>1, :id=>3})
|
|
624
|
-
yield({:album_id=>1, :id=>4})
|
|
625
|
-
end
|
|
626
|
-
})
|
|
436
|
+
EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2}, {:album_id=>1, :id=>3}, {:album_id=>1, :id=>4}]
|
|
627
437
|
as = EagerAlbum.eager(:first_two_tracks).all
|
|
628
438
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
|
629
439
|
as.length.should == 1
|
|
@@ -644,7 +454,7 @@ describe Sequel::Model, "#eager" do
|
|
|
644
454
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
645
455
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
|
646
456
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
647
|
-
MODEL_DB.sqls.
|
|
457
|
+
MODEL_DB.sqls.should == []
|
|
648
458
|
end
|
|
649
459
|
|
|
650
460
|
it "should respect the :limit option with an offset on a one_to_many association using the :window_function strategy" do
|
|
@@ -654,7 +464,7 @@ describe Sequel::Model, "#eager" do
|
|
|
654
464
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
655
465
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
|
|
656
466
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
657
|
-
MODEL_DB.sqls.
|
|
467
|
+
MODEL_DB.sqls.should == []
|
|
658
468
|
end
|
|
659
469
|
|
|
660
470
|
it "should respect the :limit option on a one_to_many association using the :correlated_subquery strategy" do
|
|
@@ -663,7 +473,7 @@ describe Sequel::Model, "#eager" do
|
|
|
663
473
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
664
474
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY name LIMIT 2))) ORDER BY name']
|
|
665
475
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
666
|
-
MODEL_DB.sqls.
|
|
476
|
+
MODEL_DB.sqls.should == []
|
|
667
477
|
end
|
|
668
478
|
|
|
669
479
|
it "should respect the :limit option with an offset on a one_to_many association using the :correlated_subquery strategy" do
|
|
@@ -672,25 +482,18 @@ describe Sequel::Model, "#eager" do
|
|
|
672
482
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
673
483
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY name LIMIT 2 OFFSET 1))) ORDER BY name']
|
|
674
484
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
675
|
-
MODEL_DB.sqls.
|
|
485
|
+
MODEL_DB.sqls.should == []
|
|
676
486
|
end
|
|
677
487
|
|
|
678
488
|
it "should respect the limit option on a many_to_many association" do
|
|
679
489
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2
|
|
680
|
-
EagerGenre.dataset.
|
|
681
|
-
def fetch_rows(sql)
|
|
682
|
-
MODEL_DB.sqls << sql
|
|
683
|
-
yield({:x_foreign_key_x=>2, :id=>5})
|
|
684
|
-
yield({:x_foreign_key_x=>2, :id=>6})
|
|
685
|
-
yield({:x_foreign_key_x=>2, :id=>7})
|
|
686
|
-
end
|
|
687
|
-
})
|
|
490
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
688
491
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
689
492
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
|
|
690
493
|
as.length.should == 1
|
|
691
494
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
692
495
|
|
|
693
|
-
|
|
496
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
|
694
497
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[2, 1]
|
|
695
498
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
696
499
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
|
|
@@ -701,19 +504,13 @@ describe Sequel::Model, "#eager" do
|
|
|
701
504
|
it "should respect the limit option on a many_to_many association using the :window_function strategy" do
|
|
702
505
|
EagerGenre.dataset.meta_def(:supports_window_functions?){true}
|
|
703
506
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>true, :limit=>2, :order=>:name
|
|
704
|
-
EagerGenre.dataset.
|
|
705
|
-
def fetch_rows(sql)
|
|
706
|
-
MODEL_DB.sqls << sql
|
|
707
|
-
yield({:x_foreign_key_x=>2, :id=>5})
|
|
708
|
-
yield({:x_foreign_key_x=>2, :id=>6})
|
|
709
|
-
end
|
|
710
|
-
})
|
|
507
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
711
508
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
712
509
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE (x_sequel_row_number_x <= 2)"]
|
|
713
510
|
as.length.should == 1
|
|
714
511
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
715
512
|
|
|
716
|
-
|
|
513
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
717
514
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>true, :limit=>[2, 1], :order=>:name
|
|
718
515
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
719
516
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))"]
|
|
@@ -723,19 +520,13 @@ describe Sequel::Model, "#eager" do
|
|
|
723
520
|
|
|
724
521
|
it "should respect the limit option on a many_to_many association using the :correlated_subquery strategy" do
|
|
725
522
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>:correlated_subquery, :limit=>2, :order=>:name
|
|
726
|
-
EagerGenre.dataset.
|
|
727
|
-
def fetch_rows(sql)
|
|
728
|
-
MODEL_DB.sqls << sql
|
|
729
|
-
yield({:x_foreign_key_x=>2, :id=>5})
|
|
730
|
-
yield({:x_foreign_key_x=>2, :id=>6})
|
|
731
|
-
end
|
|
732
|
-
})
|
|
523
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
733
524
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
734
525
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2))) WHERE (genres.id IN (SELECT t1.id FROM genres AS t1 INNER JOIN ag AS t2 ON ((t2.genre_id = t1.id) AND (t2.album_id = ag.album_id)) ORDER BY name LIMIT 2)) ORDER BY name"]
|
|
735
526
|
as.length.should == 1
|
|
736
527
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
|
737
528
|
|
|
738
|
-
|
|
529
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
|
739
530
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>:correlated_subquery, :limit=>[2, 1], :order=>:name
|
|
740
531
|
as = EagerAlbum.eager(:first_two_genres).all
|
|
741
532
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2))) WHERE (genres.id IN (SELECT t1.id FROM genres AS t1 INNER JOIN ag AS t2 ON ((t2.genre_id = t1.id) AND (t2.album_id = ag.album_id)) ORDER BY name LIMIT 2 OFFSET 1)) ORDER BY name"]
|
|
@@ -757,27 +548,17 @@ describe Sequel::Model, "#eager" do
|
|
|
757
548
|
records.each{|r| r.associations[:special_genres] = items}
|
|
758
549
|
end)
|
|
759
550
|
a = EagerAlbum.eager(:special_genres, :special_tracks, :special_band).all
|
|
760
|
-
a.should
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT * FROM bands WHERE (album_id IN (1, 2)) ORDER BY name LIMIT 1'))
|
|
767
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT * FROM tracks WHERE (album_id IN (1, 2))'))
|
|
768
|
-
MODEL_DB.sqls[1..-1].should(include('SELECT * FROM genres INNER JOIN ag USING (genre_id) WHERE (album_id IN (1))'))
|
|
551
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
552
|
+
sqls = MODEL_DB.sqls
|
|
553
|
+
sqls.shift.should == 'SELECT * FROM albums'
|
|
554
|
+
sqls.sort.should == ['SELECT * FROM bands WHERE (album_id IN (1, 2)) ORDER BY name LIMIT 1',
|
|
555
|
+
'SELECT * FROM genres INNER JOIN ag USING (genre_id) WHERE (album_id IN (1))',
|
|
556
|
+
'SELECT * FROM tracks WHERE (album_id IN (1, 2))']
|
|
769
557
|
a = a.first
|
|
770
|
-
a.special_band.should
|
|
771
|
-
a.
|
|
772
|
-
a.
|
|
773
|
-
|
|
774
|
-
a.special_tracks.first.should be_a_kind_of(EagerTrack)
|
|
775
|
-
a.special_tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
776
|
-
a.special_genres.should be_a_kind_of(Array)
|
|
777
|
-
a.special_genres.size.should == 1
|
|
778
|
-
a.special_genres.first.should be_a_kind_of(EagerGenre)
|
|
779
|
-
a.special_genres.first.values.should == {:id => 4}
|
|
780
|
-
MODEL_DB.sqls.length.should == 4
|
|
558
|
+
a.special_band.should == EagerBand.load(:id => 2)
|
|
559
|
+
a.special_tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
560
|
+
a.special_genres.should == [EagerGenre.load(:id => 4)]
|
|
561
|
+
MODEL_DB.sqls.should == []
|
|
781
562
|
end
|
|
782
563
|
|
|
783
564
|
it "should raise an error if you use an :eager_loader proc with the wrong arity" do
|
|
@@ -797,13 +578,7 @@ describe Sequel::Model, "#eager" do
|
|
|
797
578
|
|
|
798
579
|
it "should respect :uniq option when eagerly loading many_to_many associations" do
|
|
799
580
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :uniq=>true
|
|
800
|
-
EagerGenre.dataset.
|
|
801
|
-
def fetch_rows(sql)
|
|
802
|
-
MODEL_DB.sqls << sql
|
|
803
|
-
yield({:x_foreign_key_x=>1, :id=>8})
|
|
804
|
-
yield({:x_foreign_key_x=>1, :id=>8})
|
|
805
|
-
end
|
|
806
|
-
})
|
|
581
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>1, :id=>8}, {:x_foreign_key_x=>1, :id=>8}]
|
|
807
582
|
a = EagerAlbum.eager(:al_genres).all.first
|
|
808
583
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
809
584
|
a.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
@@ -820,15 +595,10 @@ describe Sequel::Model, "#eager" do
|
|
|
820
595
|
|
|
821
596
|
it "should eagerly load a many_to_one association with custom eager block" do
|
|
822
597
|
a = EagerAlbum.eager(:band => proc {|ds| ds.select(:id, :name)}).all
|
|
823
|
-
a.should
|
|
824
|
-
a.size.should == 1
|
|
825
|
-
a.first.should be_a_kind_of(EagerAlbum)
|
|
826
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
598
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
827
599
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT id, name FROM bands WHERE (bands.id IN (2))']
|
|
828
|
-
a
|
|
829
|
-
|
|
830
|
-
a.band.values.should == {:id => 2}
|
|
831
|
-
MODEL_DB.sqls.length.should == 2
|
|
600
|
+
a.first.band.should == EagerBand.load(:id => 2)
|
|
601
|
+
MODEL_DB.sqls.should == []
|
|
832
602
|
end
|
|
833
603
|
|
|
834
604
|
it "should eagerly load a one_to_one association with custom eager block" do
|
|
@@ -837,122 +607,78 @@ describe Sequel::Model, "#eager" do
|
|
|
837
607
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
838
608
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
|
|
839
609
|
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
|
840
|
-
MODEL_DB.sqls.
|
|
610
|
+
MODEL_DB.sqls.should == []
|
|
841
611
|
end
|
|
842
612
|
|
|
843
613
|
it "should eagerly load a one_to_many association with custom eager block" do
|
|
844
614
|
a = EagerAlbum.eager(:tracks => proc {|ds| ds.select(:id)}).all
|
|
845
|
-
a.should
|
|
846
|
-
a.size.should == 1
|
|
847
|
-
a.first.should be_a_kind_of(EagerAlbum)
|
|
848
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
615
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
849
616
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
|
|
850
|
-
a
|
|
851
|
-
|
|
852
|
-
a.tracks.size.should == 1
|
|
853
|
-
a.tracks.first.should be_a_kind_of(EagerTrack)
|
|
854
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
855
|
-
MODEL_DB.sqls.length.should == 2
|
|
617
|
+
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
|
618
|
+
MODEL_DB.sqls.should == []
|
|
856
619
|
end
|
|
857
620
|
|
|
858
621
|
it "should eagerly load a many_to_many association with custom eager block" do
|
|
859
622
|
a = EagerAlbum.eager(:genres => proc {|ds| ds.select(:name)}).all
|
|
860
|
-
a.should
|
|
861
|
-
a.size.should == 1
|
|
862
|
-
a.first.should be_a_kind_of(EagerAlbum)
|
|
863
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
623
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
|
864
624
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
865
|
-
a
|
|
866
|
-
|
|
867
|
-
a.genres.size.should == 1
|
|
868
|
-
a.genres.first.should be_a_kind_of(EagerGenre)
|
|
869
|
-
a.genres.first.values.should == {:id => 4}
|
|
870
|
-
MODEL_DB.sqls.length.should == 2
|
|
625
|
+
a.first.genres.should == [EagerGenre.load(:id => 4)]
|
|
626
|
+
MODEL_DB.sqls.should == []
|
|
871
627
|
end
|
|
872
628
|
|
|
873
629
|
it "should allow cascading of eager loading within a custom eager block" do
|
|
874
630
|
a = EagerTrack.eager(:album => proc {|ds| ds.eager(:band => :members)}).all
|
|
875
|
-
a.should
|
|
876
|
-
a.size.should == 1
|
|
877
|
-
a.first.should be_a_kind_of(EagerTrack)
|
|
878
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
879
|
-
MODEL_DB.sqls.length.should == 4
|
|
631
|
+
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
880
632
|
MODEL_DB.sqls.should == ['SELECT * FROM tracks',
|
|
881
633
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
|
882
634
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
883
635
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
|
|
884
636
|
a = a.first
|
|
885
|
-
a.album.should
|
|
886
|
-
a.album.
|
|
887
|
-
a.album.band.should
|
|
888
|
-
|
|
889
|
-
a.album.band.members.should be_a_kind_of(Array)
|
|
890
|
-
a.album.band.members.size.should == 1
|
|
891
|
-
a.album.band.members.first.should be_a_kind_of(EagerBandMember)
|
|
892
|
-
a.album.band.members.first.values.should == {:id => 5}
|
|
893
|
-
MODEL_DB.sqls.length.should == 4
|
|
637
|
+
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
638
|
+
a.album.band.should == EagerBand.load(:id => 2)
|
|
639
|
+
a.album.band.members.should == [EagerBandMember.load(:id => 5)]
|
|
640
|
+
MODEL_DB.sqls.should == []
|
|
894
641
|
end
|
|
895
642
|
|
|
896
643
|
it "should allow cascading of eager loading with custom callback with hash value" do
|
|
897
644
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>{:band => :members}}).all
|
|
898
|
-
a.should
|
|
899
|
-
a.size.should == 1
|
|
900
|
-
a.first.should be_a_kind_of(EagerTrack)
|
|
901
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
902
|
-
MODEL_DB.sqls.length.should == 4
|
|
645
|
+
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
903
646
|
MODEL_DB.sqls.should == ['SELECT * FROM tracks',
|
|
904
647
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
|
|
905
648
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
906
649
|
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
|
|
907
650
|
a = a.first
|
|
908
|
-
a.album.should
|
|
909
|
-
a.album.
|
|
910
|
-
a.album.band.should
|
|
911
|
-
|
|
912
|
-
a.album.band.members.should be_a_kind_of(Array)
|
|
913
|
-
a.album.band.members.size.should == 1
|
|
914
|
-
a.album.band.members.first.should be_a_kind_of(EagerBandMember)
|
|
915
|
-
a.album.band.members.first.values.should == {:id => 5}
|
|
916
|
-
MODEL_DB.sqls.length.should == 4
|
|
651
|
+
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
652
|
+
a.album.band.should == EagerBand.load(:id => 2)
|
|
653
|
+
a.album.band.members.should == [EagerBandMember.load(:id => 5)]
|
|
654
|
+
MODEL_DB.sqls.should == []
|
|
917
655
|
end
|
|
918
656
|
|
|
919
657
|
it "should allow cascading of eager loading with custom callback with symbol value" do
|
|
920
658
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>:band}).all
|
|
921
|
-
a.should
|
|
922
|
-
a.size.should == 1
|
|
923
|
-
a.first.should be_a_kind_of(EagerTrack)
|
|
924
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
925
|
-
MODEL_DB.sqls.length.should == 3
|
|
659
|
+
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
926
660
|
MODEL_DB.sqls.should == ['SELECT * FROM tracks',
|
|
927
661
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
|
|
928
662
|
'SELECT * FROM bands WHERE (bands.id IN (2))']
|
|
929
663
|
a = a.first
|
|
930
|
-
a.album.should
|
|
931
|
-
a.album.
|
|
932
|
-
|
|
933
|
-
a.album.band.values.should == {:id => 2}
|
|
934
|
-
MODEL_DB.sqls.length.should == 3
|
|
664
|
+
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
665
|
+
a.album.band.should == EagerBand.load(:id => 2)
|
|
666
|
+
MODEL_DB.sqls.should == []
|
|
935
667
|
end
|
|
936
668
|
|
|
937
669
|
it "should allow cascading of eager loading with custom callback with array value" do
|
|
938
670
|
a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>[:band, :band_name]}).all
|
|
939
|
-
a.should
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
943
|
-
MODEL_DB.sqls.length.should == 4
|
|
944
|
-
MODEL_DB.sqls[0..1].should == ['SELECT * FROM tracks',
|
|
671
|
+
a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
|
|
672
|
+
sqls = MODEL_DB.sqls
|
|
673
|
+
sqls.slice!(0..1).should == ['SELECT * FROM tracks',
|
|
945
674
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))']
|
|
946
|
-
|
|
675
|
+
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
|
947
676
|
'SELECT id, name FROM bands WHERE (bands.id IN (2))']
|
|
948
677
|
a = a.first
|
|
949
|
-
a.album.should
|
|
950
|
-
a.album.
|
|
951
|
-
a.album.
|
|
952
|
-
|
|
953
|
-
a.album.band_name.should be_a_kind_of(EagerBand)
|
|
954
|
-
a.album.band_name.values.should == {:id => 2}
|
|
955
|
-
MODEL_DB.sqls.length.should == 4
|
|
678
|
+
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
|
679
|
+
a.album.band.should == EagerBand.load(:id => 2)
|
|
680
|
+
a.album.band_name.should == EagerBand.load(:id => 2)
|
|
681
|
+
MODEL_DB.sqls.should == []
|
|
956
682
|
end
|
|
957
683
|
|
|
958
684
|
it "should call both association and custom eager blocks" do
|
|
@@ -962,28 +688,7 @@ describe Sequel::Model, "#eager" do
|
|
|
962
688
|
end
|
|
963
689
|
|
|
964
690
|
describe Sequel::Model, "#eager_graph" do
|
|
965
|
-
after(:all) do
|
|
966
|
-
class ::MockDataset
|
|
967
|
-
alias clone orig_clone
|
|
968
|
-
end
|
|
969
|
-
end
|
|
970
|
-
|
|
971
691
|
before(:all) do
|
|
972
|
-
class ::MockDataset
|
|
973
|
-
alias orig_clone clone
|
|
974
|
-
def clone(opts = {})
|
|
975
|
-
c = super()
|
|
976
|
-
c.opts = @opts.merge(opts)
|
|
977
|
-
c.instance_variable_set(:@columns, (@columns.dup if @columns))
|
|
978
|
-
c
|
|
979
|
-
end
|
|
980
|
-
def select_columns(*a)
|
|
981
|
-
ds = select(*a)
|
|
982
|
-
ds.instance_variable_set(:@columns, a)
|
|
983
|
-
ds
|
|
984
|
-
end
|
|
985
|
-
end
|
|
986
|
-
|
|
987
692
|
class ::GraphAlbum < Sequel::Model(:albums)
|
|
988
693
|
dataset.opts[:from] = [:albums]
|
|
989
694
|
columns :id, :band_id
|
|
@@ -1020,6 +725,9 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1020
725
|
many_to_many :bands, :class=>'GraphBand', :left_key=>:member_id, :right_key=>:band_id, :join_table=>:bm
|
|
1021
726
|
end
|
|
1022
727
|
end
|
|
728
|
+
after(:all) do
|
|
729
|
+
[:GraphAlbum, :GraphBand, :GraphTrack, :GraphGenre, :GraphBandMember].each{|x| Object.send(:remove_const, x)}
|
|
730
|
+
end
|
|
1023
731
|
|
|
1024
732
|
it "should raise an error if called without a symbol or hash" do
|
|
1025
733
|
proc{GraphAlbum.eager_graph(Object.new)}.should raise_error(Sequel::Error)
|
|
@@ -1028,35 +736,24 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1028
736
|
it "should not split results and assign associations if ungraphed is called" do
|
|
1029
737
|
ds = GraphAlbum.eager_graph(:band).ungraphed
|
|
1030
738
|
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1031
|
-
|
|
1032
|
-
yield({:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3})
|
|
1033
|
-
end
|
|
739
|
+
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
|
|
1034
740
|
ds.all.should == [GraphAlbum.load(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)]
|
|
1035
741
|
end
|
|
1036
742
|
|
|
1037
743
|
it "should eagerly load a single many_to_one association" do
|
|
1038
744
|
ds = GraphAlbum.eager_graph(:band)
|
|
1039
745
|
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1040
|
-
|
|
1041
|
-
yield({:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3})
|
|
1042
|
-
end
|
|
746
|
+
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
|
|
1043
747
|
a = ds.all
|
|
1044
|
-
a.should
|
|
1045
|
-
a.
|
|
1046
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1047
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
1048
|
-
a = a.first
|
|
1049
|
-
a.band.should be_a_kind_of(GraphBand)
|
|
1050
|
-
a.band.values.should == {:id => 2, :vocalist_id=>3}
|
|
748
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
749
|
+
a.first.band.should == GraphBand.load(:id => 2, :vocalist_id=>3)
|
|
1051
750
|
end
|
|
1052
751
|
|
|
1053
752
|
it "should eagerly load a single one_to_one association" do
|
|
1054
753
|
GraphAlbum.one_to_one :track, :class=>'GraphTrack', :key=>:album_id
|
|
1055
754
|
ds = GraphAlbum.eager_graph(:track)
|
|
1056
755
|
ds.sql.should == 'SELECT albums.id, albums.band_id, track.id AS track_id, track.album_id FROM albums LEFT OUTER JOIN tracks AS track ON (track.album_id = albums.id)'
|
|
1057
|
-
|
|
1058
|
-
yield({:id=>1, :band_id=>2, :track_id=>3, :album_id=>1})
|
|
1059
|
-
end
|
|
756
|
+
ds._fetch = {:id=>1, :band_id=>2, :track_id=>3, :album_id=>1}
|
|
1060
757
|
a = ds.all
|
|
1061
758
|
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1062
759
|
a.first.track.should == GraphTrack.load(:id => 3, :album_id=>1)
|
|
@@ -1065,130 +762,88 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1065
762
|
it "should eagerly load a single one_to_many association" do
|
|
1066
763
|
ds = GraphAlbum.eager_graph(:tracks)
|
|
1067
764
|
ds.sql.should == 'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)'
|
|
1068
|
-
|
|
1069
|
-
yield({:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1})
|
|
1070
|
-
end
|
|
765
|
+
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
1071
766
|
a = ds.all
|
|
1072
|
-
a.should
|
|
1073
|
-
a.
|
|
1074
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1075
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
1076
|
-
a = a.first
|
|
1077
|
-
a.tracks.should be_a_kind_of(Array)
|
|
1078
|
-
a.tracks.size.should == 1
|
|
1079
|
-
a.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1080
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
767
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
768
|
+
a.first.tracks.should == [GraphTrack.load(:id => 3, :album_id=>1)]
|
|
1081
769
|
end
|
|
1082
770
|
|
|
1083
771
|
it "should eagerly load a single many_to_many association" do
|
|
1084
772
|
ds = GraphAlbum.eager_graph(:genres)
|
|
1085
773
|
ds.sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id)'
|
|
1086
|
-
|
|
1087
|
-
yield({:id=>1, :band_id=>2, :genres_id=>4})
|
|
1088
|
-
end
|
|
774
|
+
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4}
|
|
1089
775
|
a = ds.all
|
|
1090
|
-
a.should
|
|
1091
|
-
a.
|
|
1092
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1093
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
1094
|
-
a = a.first
|
|
1095
|
-
a.genres.should be_a_kind_of(Array)
|
|
1096
|
-
a.genres.size.should == 1
|
|
1097
|
-
a.genres.first.should be_a_kind_of(GraphGenre)
|
|
1098
|
-
a.genres.first.values.should == {:id => 4}
|
|
776
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
777
|
+
a.first.genres.should == [GraphGenre.load(:id => 4)]
|
|
1099
778
|
end
|
|
1100
779
|
|
|
780
|
+
it "should correctly handle an aliased join table in many_to_many" do
|
|
781
|
+
c = Class.new(GraphAlbum)
|
|
782
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___ga
|
|
783
|
+
c.eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ga.genre_id)'
|
|
784
|
+
|
|
785
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___albums
|
|
786
|
+
c.eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS albums_0 ON (albums_0.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = albums_0.genre_id)'
|
|
787
|
+
|
|
788
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___genres
|
|
789
|
+
c.eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS genres_0 ON (genres_0.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = genres_0.genre_id)'
|
|
790
|
+
end
|
|
791
|
+
|
|
1101
792
|
it "should eagerly load multiple associations in a single call" do
|
|
1102
793
|
ds = GraphAlbum.eager_graph(:genres, :tracks, :band)
|
|
1103
794
|
ds.sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id, tracks.id AS tracks_id, tracks.album_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1104
|
-
|
|
1105
|
-
yield({:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6})
|
|
1106
|
-
end
|
|
795
|
+
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6}
|
|
1107
796
|
a = ds.all
|
|
1108
|
-
a.should
|
|
1109
|
-
a.size.should == 1
|
|
1110
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1111
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
797
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1112
798
|
a = a.first
|
|
1113
|
-
a.band.should
|
|
1114
|
-
a.
|
|
1115
|
-
a.
|
|
1116
|
-
a.tracks.size.should == 1
|
|
1117
|
-
a.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1118
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
1119
|
-
a.genres.should be_a_kind_of(Array)
|
|
1120
|
-
a.genres.size.should == 1
|
|
1121
|
-
a.genres.first.should be_a_kind_of(GraphGenre)
|
|
1122
|
-
a.genres.first.values.should == {:id => 4}
|
|
799
|
+
a.band.should == GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
800
|
+
a.tracks.should == [GraphTrack.load({:id => 3, :album_id=>1})]
|
|
801
|
+
a.genres.should == [GraphGenre.load(:id => 4)]
|
|
1123
802
|
end
|
|
1124
803
|
|
|
1125
804
|
it "should eagerly load multiple associations in separate calls" do
|
|
1126
805
|
ds = GraphAlbum.eager_graph(:genres).eager_graph(:tracks).eager_graph(:band)
|
|
1127
806
|
ds.sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id, tracks.id AS tracks_id, tracks.album_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1128
|
-
|
|
1129
|
-
yield({:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6})
|
|
1130
|
-
end
|
|
807
|
+
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6}
|
|
1131
808
|
a = ds.all
|
|
1132
|
-
a.should
|
|
1133
|
-
a.size.should == 1
|
|
1134
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1135
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
809
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1136
810
|
a = a.first
|
|
1137
|
-
a.band.should
|
|
1138
|
-
a.
|
|
1139
|
-
a.
|
|
1140
|
-
a.tracks.size.should == 1
|
|
1141
|
-
a.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1142
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
1143
|
-
a.genres.should be_a_kind_of(Array)
|
|
1144
|
-
a.genres.size.should == 1
|
|
1145
|
-
a.genres.first.should be_a_kind_of(GraphGenre)
|
|
1146
|
-
a.genres.first.values.should == {:id => 4}
|
|
811
|
+
a.band.should == GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
812
|
+
a.tracks.should == [GraphTrack.load({:id => 3, :album_id=>1})]
|
|
813
|
+
a.genres.should == [GraphGenre.load(:id => 4)]
|
|
1147
814
|
end
|
|
1148
815
|
|
|
1149
816
|
it "should allow cascading of eager loading for associations of associated models" do
|
|
1150
817
|
ds = GraphTrack.eager_graph(:album=>{:band=>:members})
|
|
1151
818
|
ds.sql.should == 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, members.id AS members_id FROM tracks LEFT OUTER JOIN albums AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN bm ON (bm.band_id = band.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1152
|
-
|
|
1153
|
-
yield({:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6})
|
|
1154
|
-
end
|
|
819
|
+
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6}
|
|
1155
820
|
a = ds.all
|
|
1156
|
-
a.should
|
|
1157
|
-
a.size.should == 1
|
|
1158
|
-
a.first.should be_a_kind_of(GraphTrack)
|
|
1159
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
821
|
+
a.should == [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
1160
822
|
a = a.first
|
|
1161
|
-
a.album.should
|
|
1162
|
-
a.album.
|
|
1163
|
-
a.album.band.should
|
|
1164
|
-
a.album.band.values.should == {:id => 2, :vocalist_id=>6}
|
|
1165
|
-
a.album.band.members.should be_a_kind_of(Array)
|
|
1166
|
-
a.album.band.members.size.should == 1
|
|
1167
|
-
a.album.band.members.first.should be_a_kind_of(GraphBandMember)
|
|
1168
|
-
a.album.band.members.first.values.should == {:id => 5}
|
|
823
|
+
a.album.should == GraphAlbum.load(:id => 1, :band_id => 2)
|
|
824
|
+
a.album.band.should == GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
825
|
+
a.album.band.members.should == [GraphBandMember.load(:id => 5)]
|
|
1169
826
|
end
|
|
1170
827
|
|
|
1171
828
|
it "should allow cascading of eager loading for multiple *_to_many associations, eliminating duplicates caused by cartesian products" do
|
|
1172
829
|
ds = GraphBand.eager_graph({:albums=>:tracks}, :members)
|
|
1173
830
|
ds.sql.should == 'SELECT bands.id, bands.vocalist_id, albums.id AS albums_id, albums.band_id, tracks.id AS tracks_id, tracks.album_id, members.id AS members_id FROM bands LEFT OUTER JOIN albums ON (albums.band_id = bands.id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
yield({:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>6})
|
|
1191
|
-
end
|
|
831
|
+
ds._fetch = [{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>4, :album_id=>3, :members_id=>5},
|
|
832
|
+
{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>4, :album_id=>3, :members_id=>6},
|
|
833
|
+
{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>5, :album_id=>3, :members_id=>5},
|
|
834
|
+
{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>5, :album_id=>3, :members_id=>6},
|
|
835
|
+
{:id=>1, :vocalist_id=>2, :albums_id=>4, :band_id=>1, :tracks_id=>6, :album_id=>4, :members_id=>5},
|
|
836
|
+
{:id=>1, :vocalist_id=>2, :albums_id=>4, :band_id=>1, :tracks_id=>6, :album_id=>4, :members_id=>6},
|
|
837
|
+
{:id=>1, :vocalist_id=>2, :albums_id=>4, :band_id=>1, :tracks_id=>7, :album_id=>4, :members_id=>5},
|
|
838
|
+
{:id=>1, :vocalist_id=>2, :albums_id=>4, :band_id=>1, :tracks_id=>7, :album_id=>4, :members_id=>6},
|
|
839
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>5, :band_id=>2, :tracks_id=>8, :album_id=>5, :members_id=>5},
|
|
840
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>5, :band_id=>2, :tracks_id=>8, :album_id=>5, :members_id=>6},
|
|
841
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>5, :band_id=>2, :tracks_id=>9, :album_id=>5, :members_id=>5},
|
|
842
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>5, :band_id=>2, :tracks_id=>9, :album_id=>5, :members_id=>6},
|
|
843
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>1, :album_id=>6, :members_id=>5},
|
|
844
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>1, :album_id=>6, :members_id=>6},
|
|
845
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>5},
|
|
846
|
+
{:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>6}]
|
|
1192
847
|
a = ds.all
|
|
1193
848
|
a.should == [GraphBand.load(:id=>1, :vocalist_id=>2), GraphBand.load(:id=>2, :vocalist_id=>2)]
|
|
1194
849
|
members = a.map{|x| x.members}
|
|
@@ -1203,85 +858,49 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1203
858
|
MODEL_DB.reset
|
|
1204
859
|
ds = GraphAlbum.eager_graph(:tracks)
|
|
1205
860
|
ds.sql.should == 'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)'
|
|
1206
|
-
|
|
1207
|
-
@db << sql
|
|
1208
|
-
yield({:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1})
|
|
1209
|
-
end
|
|
861
|
+
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
1210
862
|
a = ds.all
|
|
1211
|
-
a.should
|
|
1212
|
-
a.size.should == 1
|
|
1213
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1214
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
863
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1215
864
|
a = a.first
|
|
1216
|
-
a.tracks.should
|
|
1217
|
-
a.tracks.size.should == 1
|
|
1218
|
-
a.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1219
|
-
a.tracks.first.values.should == {:id => 3, :album_id=>1}
|
|
1220
|
-
a.tracks.first.album.should be_a_kind_of(GraphAlbum)
|
|
865
|
+
a.tracks.should == [GraphTrack.load(:id => 3, :album_id=>1)]
|
|
1221
866
|
a.tracks.first.album.should == a
|
|
1222
|
-
MODEL_DB.sqls.
|
|
867
|
+
MODEL_DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)']
|
|
1223
868
|
end
|
|
1224
869
|
|
|
1225
870
|
it "should eager load multiple associations from the same table" do
|
|
1226
871
|
ds = GraphBand.eager_graph(:vocalist, :members)
|
|
1227
872
|
ds.sql.should == 'SELECT bands.id, bands.vocalist_id, vocalist.id AS vocalist_id_0, members.id AS members_id FROM bands LEFT OUTER JOIN members AS vocalist ON (vocalist.id = bands.vocalist_id) LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1228
|
-
|
|
1229
|
-
yield({:id=>2, :vocalist_id=>6, :vocalist_id_0=>6, :members_id=>5})
|
|
1230
|
-
end
|
|
873
|
+
ds._fetch = {:id=>2, :vocalist_id=>6, :vocalist_id_0=>6, :members_id=>5}
|
|
1231
874
|
a = ds.all
|
|
1232
|
-
a.should
|
|
1233
|
-
a.size.should == 1
|
|
1234
|
-
a.first.should be_a_kind_of(GraphBand)
|
|
1235
|
-
a.first.values.should == {:id => 2, :vocalist_id => 6}
|
|
875
|
+
a.should == [GraphBand.load(:id => 2, :vocalist_id => 6)]
|
|
1236
876
|
a = a.first
|
|
1237
|
-
a.vocalist.should
|
|
1238
|
-
a.
|
|
1239
|
-
a.members.should be_a_kind_of(Array)
|
|
1240
|
-
a.members.size.should == 1
|
|
1241
|
-
a.members.first.should be_a_kind_of(GraphBandMember)
|
|
1242
|
-
a.members.first.values.should == {:id => 5}
|
|
877
|
+
a.vocalist.should == GraphBandMember.load(:id => 6)
|
|
878
|
+
a.members.should == [GraphBandMember.load(:id => 5)]
|
|
1243
879
|
end
|
|
1244
880
|
|
|
1245
881
|
it "should give you a plain hash when called without .all" do
|
|
1246
882
|
ds = GraphAlbum.eager_graph(:band)
|
|
1247
883
|
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1248
|
-
|
|
1249
|
-
yield({:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3})
|
|
1250
|
-
end
|
|
884
|
+
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
|
|
1251
885
|
ds.first.should == {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
|
|
1252
886
|
end
|
|
1253
887
|
|
|
1254
888
|
it "should not drop any associated objects if the graph could not be a cartesian product" do
|
|
1255
889
|
ds = GraphBand.eager_graph(:members, :vocalist)
|
|
1256
890
|
ds.sql.should == 'SELECT bands.id, bands.vocalist_id, members.id AS members_id, vocalist.id AS vocalist_id_0 FROM bands LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id) LEFT OUTER JOIN members AS vocalist ON (vocalist.id = bands.vocalist_id)'
|
|
1257
|
-
|
|
1258
|
-
yield({:id=>2, :vocalist_id=>6, :members_id=>5, :vocalist_id_0=>6})
|
|
1259
|
-
yield({:id=>2, :vocalist_id=>6, :members_id=>5, :vocalist_id_0=>6})
|
|
1260
|
-
end
|
|
891
|
+
ds._fetch = [{:id=>2, :vocalist_id=>6, :members_id=>5, :vocalist_id_0=>6}, {:id=>2, :vocalist_id=>6, :members_id=>5, :vocalist_id_0=>6}]
|
|
1261
892
|
a = ds.all
|
|
1262
|
-
a.should
|
|
1263
|
-
a.size.should == 1
|
|
1264
|
-
a.first.should be_a_kind_of(GraphBand)
|
|
1265
|
-
a.first.values.should == {:id => 2, :vocalist_id => 6}
|
|
893
|
+
a.should == [GraphBand.load(:id => 2, :vocalist_id => 6)]
|
|
1266
894
|
a = a.first
|
|
1267
|
-
a.vocalist.should
|
|
1268
|
-
a.
|
|
1269
|
-
a.members.should be_a_kind_of(Array)
|
|
1270
|
-
a.members.size.should == 2
|
|
1271
|
-
a.members.first.should be_a_kind_of(GraphBandMember)
|
|
1272
|
-
a.members.first.values.should == {:id => 5}
|
|
1273
|
-
a.members.last.should be_a_kind_of(GraphBandMember)
|
|
1274
|
-
a.members.last.values.should == {:id => 5}
|
|
895
|
+
a.vocalist.should == GraphBandMember.load(:id => 6)
|
|
896
|
+
a.members.should == [GraphBandMember.load(:id => 5), GraphBandMember.load(:id => 5)]
|
|
1275
897
|
end
|
|
1276
898
|
|
|
1277
899
|
it "should respect the :cartesian_product_number option" do
|
|
1278
900
|
GraphBand.many_to_one :other_vocalist, :class=>'GraphBandMember', :key=>:vocalist_id, :cartesian_product_number=>1
|
|
1279
901
|
ds = GraphBand.eager_graph(:members, :other_vocalist)
|
|
1280
902
|
ds.sql.should == 'SELECT bands.id, bands.vocalist_id, members.id AS members_id, other_vocalist.id AS other_vocalist_id FROM bands LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id) LEFT OUTER JOIN members AS other_vocalist ON (other_vocalist.id = bands.vocalist_id)'
|
|
1281
|
-
|
|
1282
|
-
yield({:id=>2, :vocalist_id=>6, :members_id=>5, :other_vocalist_id=>6})
|
|
1283
|
-
yield({:id=>2, :vocalist_id=>6, :members_id=>5, :other_vocalist_id=>6})
|
|
1284
|
-
end
|
|
903
|
+
ds._fetch = [{:id=>2, :vocalist_id=>6, :members_id=>5, :other_vocalist_id=>6}, {:id=>2, :vocalist_id=>6, :members_id=>5, :other_vocalist_id=>6}]
|
|
1285
904
|
a = ds.all
|
|
1286
905
|
a.should == [GraphBand.load(:id=>2, :vocalist_id => 6)]
|
|
1287
906
|
a.first.other_vocalist.should == GraphBandMember.load(:id=>6)
|
|
@@ -1291,57 +910,28 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1291
910
|
it "should drop duplicate items that occur in sequence if the graph could be a cartesian product" do
|
|
1292
911
|
ds = GraphBand.eager_graph(:members, :genres)
|
|
1293
912
|
ds.sql.should == 'SELECT bands.id, bands.vocalist_id, members.id AS members_id, genres.id AS genres_id FROM bands LEFT OUTER JOIN bm ON (bm.band_id = bands.id) LEFT OUTER JOIN members ON (members.id = bm.member_id) LEFT OUTER JOIN bg ON (bg.band_id = bands.id) LEFT OUTER JOIN genres ON (genres.id = bg.genre_id)'
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
yield({:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>8})
|
|
1299
|
-
end
|
|
913
|
+
ds._fetch = [{:id=>2, :vocalist_id=>6, :members_id=>5, :genres_id=>7},
|
|
914
|
+
{:id=>2, :vocalist_id=>6, :members_id=>5, :genres_id=>8},
|
|
915
|
+
{:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>7},
|
|
916
|
+
{:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>8}]
|
|
1300
917
|
a = ds.all
|
|
1301
|
-
a.should
|
|
1302
|
-
a.size.should == 1
|
|
1303
|
-
a.first.should be_a_kind_of(GraphBand)
|
|
1304
|
-
a.first.values.should == {:id => 2, :vocalist_id => 6}
|
|
918
|
+
a.should == [GraphBand.load(:id => 2, :vocalist_id => 6)]
|
|
1305
919
|
a = a.first
|
|
1306
|
-
a.members.should
|
|
1307
|
-
a.
|
|
1308
|
-
a.members.first.should be_a_kind_of(GraphBandMember)
|
|
1309
|
-
a.members.first.values.should == {:id => 5}
|
|
1310
|
-
a.members.last.should be_a_kind_of(GraphBandMember)
|
|
1311
|
-
a.members.last.values.should == {:id => 6}
|
|
1312
|
-
a.genres.size.should == 2
|
|
1313
|
-
a.genres.first.should be_a_kind_of(GraphGenre)
|
|
1314
|
-
a.genres.first.values.should == {:id => 7}
|
|
1315
|
-
a.genres.last.should be_a_kind_of(GraphGenre)
|
|
1316
|
-
a.genres.last.values.should == {:id => 8}
|
|
920
|
+
a.members.should == [GraphBandMember.load(:id => 5), GraphBandMember.load(:id => 6)]
|
|
921
|
+
a.genres.should == [GraphGenre.load(:id => 7), GraphGenre.load(:id => 8)]
|
|
1317
922
|
end
|
|
1318
923
|
|
|
1319
924
|
it "should be able to be used in combination with #eager" do
|
|
1320
925
|
MODEL_DB.reset
|
|
1321
926
|
ds = GraphAlbum.eager_graph(:tracks).eager(:genres)
|
|
1322
|
-
|
|
1323
|
-
@db << sql
|
|
1324
|
-
yield({:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1})
|
|
1325
|
-
end
|
|
927
|
+
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
|
|
1326
928
|
ds2 = GraphGenre.dataset
|
|
1327
|
-
|
|
1328
|
-
@db << sql
|
|
1329
|
-
yield({:id=>6, :x_foreign_key_x=>1})
|
|
1330
|
-
end
|
|
929
|
+
ds2._fetch = {:id=>6, :x_foreign_key_x=>1}
|
|
1331
930
|
a = ds.all
|
|
1332
|
-
a.should
|
|
1333
|
-
a.size.should == 1
|
|
1334
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1335
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
931
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1336
932
|
a = a.first
|
|
1337
|
-
a.tracks.should
|
|
1338
|
-
a.
|
|
1339
|
-
a.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1340
|
-
a.tracks.first.values.should == {:id=>3, :album_id=>1}
|
|
1341
|
-
a.genres.should be_a_kind_of(Array)
|
|
1342
|
-
a.genres.size.should == 1
|
|
1343
|
-
a.genres.first.should be_a_kind_of(GraphGenre)
|
|
1344
|
-
a.genres.first.values.should == {:id=>6}
|
|
933
|
+
a.tracks.should == [GraphTrack.load(:id=>3, :album_id=>1)]
|
|
934
|
+
a.genres.should == [GraphGenre.load(:id => 6)]
|
|
1345
935
|
MODEL_DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)',
|
|
1346
936
|
"SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
|
1347
937
|
end
|
|
@@ -1349,110 +939,65 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1349
939
|
it "should handle no associated records for a single many_to_one association" do
|
|
1350
940
|
ds = GraphAlbum.eager_graph(:band)
|
|
1351
941
|
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1352
|
-
|
|
1353
|
-
yield({:id=>1, :band_id=>2, :band_id_0=>nil, :vocalist_id=>nil})
|
|
1354
|
-
end
|
|
942
|
+
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>nil, :vocalist_id=>nil}
|
|
1355
943
|
a = ds.all
|
|
1356
|
-
a.should
|
|
1357
|
-
a.
|
|
1358
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1359
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
1360
|
-
a.first.associations.fetch(:band, 2).should == nil
|
|
944
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
945
|
+
a.first.band.should == nil
|
|
1361
946
|
end
|
|
1362
947
|
|
|
1363
948
|
it "should handle no associated records for a single one_to_many association" do
|
|
1364
949
|
ds = GraphAlbum.eager_graph(:tracks)
|
|
1365
950
|
ds.sql.should == 'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)'
|
|
1366
|
-
|
|
1367
|
-
yield({:id=>1, :band_id=>2, :tracks_id=>nil, :album_id=>nil})
|
|
1368
|
-
end
|
|
951
|
+
ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>nil, :album_id=>nil}
|
|
1369
952
|
a = ds.all
|
|
1370
|
-
a.should
|
|
1371
|
-
a.size.should == 1
|
|
1372
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1373
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
953
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1374
954
|
a.first.tracks.should == []
|
|
1375
955
|
end
|
|
1376
956
|
|
|
1377
957
|
it "should handle no associated records for a single many_to_many association" do
|
|
1378
958
|
ds = GraphAlbum.eager_graph(:genres)
|
|
1379
959
|
ds.sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id)'
|
|
1380
|
-
|
|
1381
|
-
yield({:id=>1, :band_id=>2, :genres_id=>nil})
|
|
1382
|
-
end
|
|
960
|
+
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>nil}
|
|
1383
961
|
a = ds.all
|
|
1384
|
-
a.should
|
|
1385
|
-
a.size.should == 1
|
|
1386
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1387
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
962
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1388
963
|
a.first.genres.should == []
|
|
1389
964
|
end
|
|
1390
965
|
|
|
1391
966
|
it "should handle missing associated records when loading multiple associations" do
|
|
1392
967
|
ds = GraphAlbum.eager_graph(:genres, :tracks, :band)
|
|
1393
968
|
ds.sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id, tracks.id AS tracks_id, tracks.album_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ag.genre_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
yield({:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>6, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil})
|
|
1399
|
-
end
|
|
969
|
+
ds._fetch = [{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>3, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
|
|
970
|
+
{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>4, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
|
|
971
|
+
{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>5, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
|
|
972
|
+
{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>6, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil}]
|
|
1400
973
|
a = ds.all
|
|
1401
|
-
a.should
|
|
1402
|
-
a.size.should == 1
|
|
1403
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1404
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
974
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1405
975
|
a = a.first
|
|
1406
|
-
a.tracks.should
|
|
1407
|
-
a.
|
|
1408
|
-
a.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1409
|
-
a.tracks.collect{|x|x[:id]}.should == [3,4,5,6]
|
|
1410
|
-
a.associations.fetch(:band, 2).should == nil
|
|
976
|
+
a.tracks.should == [GraphTrack.load(:id => 3, :album_id => 1), GraphTrack.load(:id => 4, :album_id => 1), GraphTrack.load(:id => 5, :album_id => 1), GraphTrack.load(:id => 6, :album_id => 1)]
|
|
977
|
+
a.band.should == nil
|
|
1411
978
|
a.genres.should == []
|
|
1412
979
|
end
|
|
1413
980
|
|
|
1414
981
|
it "should handle missing associated records when cascading eager loading for associations of associated models" do
|
|
1415
982
|
ds = GraphTrack.eager_graph(:album=>{:band=>:members})
|
|
1416
983
|
ds.sql.should == 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, members.id AS members_id FROM tracks LEFT OUTER JOIN albums AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN bm ON (bm.band_id = band.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
yield({:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>6, :band_id_0=>4, :vocalist_id=>8})
|
|
1423
|
-
end
|
|
984
|
+
ds._fetch = [{:id=>2, :album_id=>2, :album_id_0=>nil, :band_id=>nil, :members_id=>nil, :band_id_0=>nil, :vocalist_id=>nil},
|
|
985
|
+
{:id=>3, :album_id=>3, :album_id_0=>3, :band_id=>3, :members_id=>nil, :band_id_0=>nil, :vocalist_id=>nil},
|
|
986
|
+
{:id=>4, :album_id=>4, :album_id_0=>4, :band_id=>2, :members_id=>nil, :band_id_0=>2, :vocalist_id=>6},
|
|
987
|
+
{:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>5, :band_id_0=>4, :vocalist_id=>8},
|
|
988
|
+
{:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>6, :band_id_0=>4, :vocalist_id=>8}]
|
|
1424
989
|
a = ds.all
|
|
1425
|
-
a.should
|
|
1426
|
-
a.
|
|
1427
|
-
a.
|
|
1428
|
-
a.
|
|
1429
|
-
a[0].associations.fetch(:album, 2).should == nil
|
|
1430
|
-
a[1].album.should be_a_kind_of(GraphAlbum)
|
|
1431
|
-
a[1].album.values.should == {:id => 3, :band_id => 3}
|
|
1432
|
-
a[1].album.associations.fetch(:band, 2).should == nil
|
|
1433
|
-
a[2].album.should be_a_kind_of(GraphAlbum)
|
|
1434
|
-
a[2].album.values.should == {:id => 4, :band_id => 2}
|
|
1435
|
-
a[2].album.band.should be_a_kind_of(GraphBand)
|
|
1436
|
-
a[2].album.band.values.should == {:id => 2, :vocalist_id=>6}
|
|
1437
|
-
a[2].album.band.members.should == []
|
|
1438
|
-
a[3].album.should be_a_kind_of(GraphAlbum)
|
|
1439
|
-
a[3].album.values.should == {:id => 1, :band_id => 4}
|
|
1440
|
-
a[3].album.band.should be_a_kind_of(GraphBand)
|
|
1441
|
-
a[3].album.band.values.should == {:id => 4, :vocalist_id=>8}
|
|
1442
|
-
a[3].album.band.members.size.should == 2
|
|
1443
|
-
a[3].album.band.members.first.should be_a_kind_of(GraphBandMember)
|
|
1444
|
-
a[3].album.band.members.first.values.should == {:id => 5}
|
|
1445
|
-
a[3].album.band.members.last.should be_a_kind_of(GraphBandMember)
|
|
1446
|
-
a[3].album.band.members.last.values.should == {:id => 6}
|
|
990
|
+
a.should == [GraphTrack.load(:id => 2, :album_id => 2), GraphTrack.load(:id => 3, :album_id => 3), GraphTrack.load(:id => 4, :album_id => 4), GraphTrack.load(:id => 5, :album_id => 1)]
|
|
991
|
+
a.map{|x| x.album}.should == [nil, GraphAlbum.load(:id => 3, :band_id => 3), GraphAlbum.load(:id => 4, :band_id => 2), GraphAlbum.load(:id => 1, :band_id => 4)]
|
|
992
|
+
a.map{|x| x.album.band if x.album}.should == [nil, nil, GraphBand.load(:id => 2, :vocalist_id=>6), GraphBand.load(:id => 4, :vocalist_id=>8)]
|
|
993
|
+
a.map{|x| x.album.band.members if x.album && x.album.band}.should == [nil, nil, [], [GraphBandMember.load(:id => 5), GraphBandMember.load(:id => 6)]]
|
|
1447
994
|
end
|
|
1448
995
|
|
|
1449
996
|
it "should respect the association's :primary_key option" do
|
|
1450
997
|
GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>:band_id, :primary_key=>:vocalist_id
|
|
1451
998
|
ds = GraphAlbum.eager_graph(:inner_band)
|
|
1452
999
|
ds.sql.should == 'SELECT albums.id, albums.band_id, inner_band.id AS inner_band_id, inner_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS inner_band ON (inner_band.vocalist_id = albums.band_id)'
|
|
1453
|
-
|
|
1454
|
-
yield({:id=>3, :band_id=>2, :inner_band_id=>5, :vocalist_id=>2})
|
|
1455
|
-
end
|
|
1000
|
+
ds._fetch = {:id=>3, :band_id=>2, :inner_band_id=>5, :vocalist_id=>2}
|
|
1456
1001
|
as = ds.all
|
|
1457
1002
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1458
1003
|
as.first.inner_band.should == GraphBand.load(:id=>5, :vocalist_id=>2)
|
|
@@ -1460,10 +1005,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1460
1005
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :primary_key=>:band_id
|
|
1461
1006
|
ds = GraphAlbum.eager_graph(:right_tracks)
|
|
1462
1007
|
ds.sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.band_id)'
|
|
1463
|
-
|
|
1464
|
-
yield({:id=>3, :band_id=>2, :right_tracks_id=>5, :album_id=>2})
|
|
1465
|
-
yield({:id=>3, :band_id=>2, :right_tracks_id=>6, :album_id=>2})
|
|
1466
|
-
end
|
|
1008
|
+
ds._fetch = [{:id=>3, :band_id=>2, :right_tracks_id=>5, :album_id=>2}, {:id=>3, :band_id=>2, :right_tracks_id=>6, :album_id=>2}]
|
|
1467
1009
|
as = ds.all
|
|
1468
1010
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1469
1011
|
as.first.right_tracks.should == [GraphTrack.load(:id=>5, :album_id=>2), GraphTrack.load(:id=>6, :album_id=>2)]
|
|
@@ -1473,9 +1015,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1473
1015
|
GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>[:band_id, :id], :primary_key=>[:vocalist_id, :id]
|
|
1474
1016
|
ds = GraphAlbum.eager_graph(:inner_band)
|
|
1475
1017
|
ds.sql.should == 'SELECT albums.id, albums.band_id, inner_band.id AS inner_band_id, inner_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS inner_band ON ((inner_band.vocalist_id = albums.band_id) AND (inner_band.id = albums.id))'
|
|
1476
|
-
|
|
1477
|
-
yield({:id=>3, :band_id=>2, :inner_band_id=>3, :vocalist_id=>2})
|
|
1478
|
-
end
|
|
1018
|
+
ds._fetch = {:id=>3, :band_id=>2, :inner_band_id=>3, :vocalist_id=>2}
|
|
1479
1019
|
as = ds.all
|
|
1480
1020
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1481
1021
|
as.first.inner_band.should == GraphBand.load(:id=>3, :vocalist_id=>2)
|
|
@@ -1485,9 +1025,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1485
1025
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>[:album_id, :id], :primary_key=>[:band_id, :id]
|
|
1486
1026
|
ds = GraphAlbum.eager_graph(:right_tracks)
|
|
1487
1027
|
ds.sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.band_id) AND (right_tracks.id = albums.id))'
|
|
1488
|
-
|
|
1489
|
-
yield({:id=>3, :band_id=>2, :right_tracks_id=>3, :album_id=>2})
|
|
1490
|
-
end
|
|
1028
|
+
ds._fetch = {:id=>3, :band_id=>2, :right_tracks_id=>3, :album_id=>2}
|
|
1491
1029
|
as = ds.all
|
|
1492
1030
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1493
1031
|
as.first.right_tracks.should == [GraphTrack.load(:id=>3, :album_id=>2)]
|
|
@@ -1497,10 +1035,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1497
1035
|
GraphAlbum.many_to_many :sbands, :class=>'GraphBand', :left_key=>[:l1, :l2], :left_primary_key=>[:band_id, :id], :right_key=>[:r1, :r2], :right_primary_key=>[:vocalist_id, :id], :join_table=>:b
|
|
1498
1036
|
ds = GraphAlbum.eager_graph(:sbands)
|
|
1499
1037
|
ds.sql.should == 'SELECT albums.id, albums.band_id, sbands.id AS sbands_id, sbands.vocalist_id FROM albums LEFT OUTER JOIN b ON ((b.l1 = albums.band_id) AND (b.l2 = albums.id)) LEFT OUTER JOIN bands AS sbands ON ((sbands.vocalist_id = b.r1) AND (sbands.id = b.r2))'
|
|
1500
|
-
|
|
1501
|
-
yield({:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6})
|
|
1502
|
-
yield({:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22})
|
|
1503
|
-
end
|
|
1038
|
+
ds._fetch = [{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6}, {:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22}]
|
|
1504
1039
|
as = ds.all
|
|
1505
1040
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1506
1041
|
as.first.sbands.should == [GraphBand.load(:id=>5, :vocalist_id=>6), GraphBand.load(:id=>6, :vocalist_id=>22)]
|
|
@@ -1510,10 +1045,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1510
1045
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :left_primary_key=>:band_id, :right_key=>:genre_id, :right_primary_key=>:xxx, :join_table=>:ag
|
|
1511
1046
|
ds = GraphAlbum.eager_graph(:inner_genres)
|
|
1512
1047
|
ds.sql.should == 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.band_id) LEFT OUTER JOIN genres AS inner_genres ON (inner_genres.xxx = ag.genre_id)'
|
|
1513
|
-
|
|
1514
|
-
yield({:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12})
|
|
1515
|
-
yield({:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22})
|
|
1516
|
-
end
|
|
1048
|
+
ds._fetch = [{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]
|
|
1517
1049
|
as = ds.all
|
|
1518
1050
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1519
1051
|
as.first.inner_genres.should == [GraphGenre.load(:id=>5), GraphGenre.load(:id=>6)]
|
|
@@ -1528,12 +1060,10 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1528
1060
|
c2.one_to_many :salbums, :class=>c1, :key=>[:band_id, :id]
|
|
1529
1061
|
ds = c1.eager_graph(:sbands=>:salbums)
|
|
1530
1062
|
ds.sql.should == 'SELECT albums.id, albums.band_id, sbands.id AS sbands_id, sbands.vocalist_id, salbums.id AS salbums_id, salbums.band_id AS salbums_band_id FROM albums LEFT OUTER JOIN b ON ((b.l1 = albums.band_id) AND (b.l2 = albums.id)) LEFT OUTER JOIN bands AS sbands ON ((sbands.vocalist_id = b.r1) AND (sbands.id = b.r2)) LEFT OUTER JOIN albums AS salbums ON ((salbums.band_id = sbands.vocalist_id) AND (salbums.id = sbands.id))'
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
yield({:id=>7, :band_id=>8, :sbands_id=>nil, :vocalist_id=>nil, :salbums_id=>nil, :salbums_band_id=>nil})
|
|
1536
|
-
end
|
|
1063
|
+
ds._fetch = [{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6, :salbums_id=>7, :salbums_band_id=>8},
|
|
1064
|
+
{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6, :salbums_id=>9, :salbums_band_id=>10},
|
|
1065
|
+
{:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22, :salbums_id=>nil, :salbums_band_id=>nil},
|
|
1066
|
+
{:id=>7, :band_id=>8, :sbands_id=>nil, :vocalist_id=>nil, :salbums_id=>nil, :salbums_band_id=>nil}]
|
|
1537
1067
|
as = ds.all
|
|
1538
1068
|
as.should == [c1.load(:id=>3, :band_id=>2), c1.load(:id=>7, :band_id=>8)]
|
|
1539
1069
|
as.map{|x| x.sbands}.should == [[c2.load(:id=>5, :vocalist_id=>6), c2.load(:id=>6, :vocalist_id=>22)], []]
|
|
@@ -1703,10 +1233,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1703
1233
|
GraphAlbum.many_to_many :inner_genres, :class=>'GraphGenre', :left_key=>:album_id, :left_primary_key=>:band_id, :right_key=>:genre_id, :right_primary_key=>:xxx, :join_table=>:ag
|
|
1704
1234
|
ds = GraphAlbum.eager_graph(:inner_genres)
|
|
1705
1235
|
ds.sql.should == 'SELECT albums.id, albums.band_id, inner_genres.id AS inner_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.band_id) LEFT OUTER JOIN genres AS inner_genres ON (inner_genres.xxx = ag.genre_id)'
|
|
1706
|
-
|
|
1707
|
-
yield({:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12})
|
|
1708
|
-
yield({:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22})
|
|
1709
|
-
end
|
|
1236
|
+
ds._fetch = [{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]
|
|
1710
1237
|
as = ds.all
|
|
1711
1238
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
|
1712
1239
|
as.first.inner_genres.should == [GraphGenre.load(:id=>5), GraphGenre.load(:id=>6)]
|
|
@@ -1731,7 +1258,8 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1731
1258
|
it "should eagerly load schema qualified tables correctly with joins" do
|
|
1732
1259
|
c1 = Class.new(GraphAlbum)
|
|
1733
1260
|
c2 = Class.new(GraphGenre)
|
|
1734
|
-
c1.dataset = c1.dataset.from(:s__a)
|
|
1261
|
+
ds = c1.dataset = c1.dataset.from(:s__a)
|
|
1262
|
+
def ds.columns() [:id] end
|
|
1735
1263
|
c2.dataset = c2.dataset.from(:s__g)
|
|
1736
1264
|
c1.many_to_many :a_genres, :class=>c2, :left_primary_key=>:id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:s__ag
|
|
1737
1265
|
ds = c1.join(:s__t, [:b_id]).eager_graph(:a_genres)
|
|
@@ -1744,9 +1272,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1744
1272
|
GraphAlbum.many_to_many :al_genres, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :after_load=>proc{|o, os| os.each{|a| a.id *=2}}
|
|
1745
1273
|
ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
|
|
1746
1274
|
ds.sql.should == "SELECT albums.id, albums.band_id, al_band.id AS al_band_id, al_band.vocalist_id, al_tracks.id AS al_tracks_id, al_tracks.album_id, al_genres.id AS al_genres_id FROM albums LEFT OUTER JOIN bands AS al_band ON (al_band.id = albums.band_id) LEFT OUTER JOIN tracks AS al_tracks ON (al_tracks.album_id = albums.id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS al_genres ON (al_genres.id = ag.genre_id)"
|
|
1747
|
-
|
|
1748
|
-
yield({:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7})
|
|
1749
|
-
end
|
|
1275
|
+
ds._fetch = {:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7}
|
|
1750
1276
|
a = ds.all.first
|
|
1751
1277
|
a.should == GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1752
1278
|
a.al_band.should == GraphBand.load(:id=>6, :vocalist_id=>4)
|
|
@@ -1760,11 +1286,9 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1760
1286
|
GraphAlbum.many_to_many :al_genres, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2
|
|
1761
1287
|
ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
|
|
1762
1288
|
ds.sql.should == "SELECT albums.id, albums.band_id, al_band.id AS al_band_id, al_band.vocalist_id, al_tracks.id AS al_tracks_id, al_tracks.album_id, al_genres.id AS al_genres_id FROM albums LEFT OUTER JOIN bands AS al_band ON (al_band.id = albums.band_id) LEFT OUTER JOIN tracks AS al_tracks ON (al_tracks.album_id = albums.id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS al_genres ON (al_genres.id = ag.genre_id)"
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
yield({:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17})
|
|
1767
|
-
end
|
|
1289
|
+
ds._fetch = [{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7},
|
|
1290
|
+
{:id=>1, :band_id=>2, :al_band_id=>8, :vocalist_id=>9, :al_tracks_id=>10, :album_id=>11, :al_genres_id=>12},
|
|
1291
|
+
{:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17}]
|
|
1768
1292
|
a = ds.all.first
|
|
1769
1293
|
a.should == GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1770
1294
|
a.al_band.should == GraphBand.load(:id=>3, :vocalist_id=>4)
|
|
@@ -1773,111 +1297,63 @@ describe Sequel::Model, "#eager_graph" do
|
|
|
1773
1297
|
end
|
|
1774
1298
|
|
|
1775
1299
|
it "should eagerly load a many_to_one association with a custom callback" do
|
|
1776
|
-
ds = GraphAlbum.eager_graph(:band => proc {|ds| ds.
|
|
1300
|
+
ds = GraphAlbum.eager_graph(:band => proc {|ds| ds.select(:id).columns(:id)})
|
|
1777
1301
|
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0 FROM albums LEFT OUTER JOIN (SELECT id FROM bands) AS band ON (band.id = albums.band_id)'
|
|
1778
|
-
|
|
1779
|
-
yield({:id=>1, :band_id=>2, :band_id_0=>2})
|
|
1780
|
-
end
|
|
1302
|
+
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2}
|
|
1781
1303
|
a = ds.all
|
|
1782
|
-
a.should
|
|
1783
|
-
a.
|
|
1784
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1785
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
1786
|
-
a = a.first
|
|
1787
|
-
a.band.should be_a_kind_of(GraphBand)
|
|
1788
|
-
a.band.values.should == {:id => 2}
|
|
1304
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1305
|
+
a.first.band.should == GraphBand.load(:id => 2)
|
|
1789
1306
|
end
|
|
1790
1307
|
|
|
1791
1308
|
it "should eagerly load a one_to_one association with a custom callback" do
|
|
1792
1309
|
GraphAlbum.one_to_one :track, :class=>'GraphTrack', :key=>:album_id
|
|
1793
|
-
ds = GraphAlbum.eager_graph(:track => proc {|ds| ds.
|
|
1310
|
+
ds = GraphAlbum.eager_graph(:track => proc {|ds| ds.select(:album_id).columns(:album_id)})
|
|
1794
1311
|
ds.sql.should == 'SELECT albums.id, albums.band_id, track.album_id FROM albums LEFT OUTER JOIN (SELECT album_id FROM tracks) AS track ON (track.album_id = albums.id)'
|
|
1795
|
-
|
|
1796
|
-
yield({:id=>1, :band_id=>2, :album_id=>1})
|
|
1797
|
-
end
|
|
1312
|
+
ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
|
|
1798
1313
|
a = ds.all
|
|
1799
1314
|
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1800
1315
|
a.first.track.should == GraphTrack.load(:album_id=>1)
|
|
1801
1316
|
end
|
|
1802
1317
|
|
|
1803
1318
|
it "should eagerly load a one_to_many association with a custom callback" do
|
|
1804
|
-
ds = GraphAlbum.eager_graph(:tracks => proc {|ds| ds.
|
|
1319
|
+
ds = GraphAlbum.eager_graph(:tracks => proc {|ds| ds.select(:album_id).columns(:album_id)})
|
|
1805
1320
|
ds.sql.should == 'SELECT albums.id, albums.band_id, tracks.album_id FROM albums LEFT OUTER JOIN (SELECT album_id FROM tracks) AS tracks ON (tracks.album_id = albums.id)'
|
|
1806
|
-
|
|
1807
|
-
yield({:id=>1, :band_id=>2, :album_id=>1})
|
|
1808
|
-
end
|
|
1321
|
+
ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
|
|
1809
1322
|
a = ds.all
|
|
1810
|
-
a.should
|
|
1811
|
-
a.
|
|
1812
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1813
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
1814
|
-
a = a.first
|
|
1815
|
-
a.tracks.should be_a_kind_of(Array)
|
|
1816
|
-
a.tracks.size.should == 1
|
|
1817
|
-
a.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1818
|
-
a.tracks.first.values.should == {:album_id=>1}
|
|
1323
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1324
|
+
a.first.tracks.should == [GraphTrack.load(:album_id=>1)]
|
|
1819
1325
|
end
|
|
1820
1326
|
|
|
1821
1327
|
it "should eagerly load a many_to_many association with a custom callback" do
|
|
1822
|
-
ds = GraphAlbum.eager_graph(:genres => proc {|ds| ds.
|
|
1328
|
+
ds = GraphAlbum.eager_graph(:genres => proc {|ds| ds.select(:id).columns(:id)})
|
|
1823
1329
|
ds.sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN (SELECT id FROM genres) AS genres ON (genres.id = ag.genre_id)'
|
|
1824
|
-
|
|
1825
|
-
yield({:id=>1, :band_id=>2, :genres_id=>4})
|
|
1826
|
-
end
|
|
1330
|
+
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4}
|
|
1827
1331
|
a = ds.all
|
|
1828
|
-
a.should
|
|
1829
|
-
a.
|
|
1830
|
-
a.first.should be_a_kind_of(GraphAlbum)
|
|
1831
|
-
a.first.values.should == {:id => 1, :band_id => 2}
|
|
1832
|
-
a = a.first
|
|
1833
|
-
a.genres.should be_a_kind_of(Array)
|
|
1834
|
-
a.genres.size.should == 1
|
|
1835
|
-
a.genres.first.should be_a_kind_of(GraphGenre)
|
|
1836
|
-
a.genres.first.values.should == {:id => 4}
|
|
1332
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
|
1333
|
+
a.first.genres.should == [GraphGenre.load(:id => 4)]
|
|
1837
1334
|
end
|
|
1838
1335
|
|
|
1839
1336
|
it "should allow cascading of eager loading with a custom callback with hash value" do
|
|
1840
|
-
ds = GraphTrack.eager_graph(:album=>{proc{|ds| ds.
|
|
1337
|
+
ds = GraphTrack.eager_graph(:album=>{proc{|ds| ds.select(:id, :band_id).columns(:id, :band_id)}=>{:band=>:members}})
|
|
1841
1338
|
ds.sql.should == 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, members.id AS members_id FROM tracks LEFT OUTER JOIN (SELECT id, band_id FROM albums) AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN bm ON (bm.band_id = band.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
|
1842
|
-
|
|
1843
|
-
yield({:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6})
|
|
1844
|
-
end
|
|
1339
|
+
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6}
|
|
1845
1340
|
a = ds.all
|
|
1846
|
-
a.should
|
|
1847
|
-
a.size.should == 1
|
|
1848
|
-
a.first.should be_a_kind_of(GraphTrack)
|
|
1849
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
1341
|
+
a.should == [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
1850
1342
|
a = a.first
|
|
1851
|
-
a.album.should
|
|
1852
|
-
a.album.
|
|
1853
|
-
a.album.band.should
|
|
1854
|
-
a.album.band.values.should == {:id => 2, :vocalist_id=>6}
|
|
1855
|
-
a.album.band.members.should be_a_kind_of(Array)
|
|
1856
|
-
a.album.band.members.size.should == 1
|
|
1857
|
-
a.album.band.members.first.should be_a_kind_of(GraphBandMember)
|
|
1858
|
-
a.album.band.members.first.values.should == {:id => 5}
|
|
1343
|
+
a.album.should == GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1344
|
+
a.album.band.should == GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
1345
|
+
a.album.band.members.should == [GraphBandMember.load(:id => 5)]
|
|
1859
1346
|
end
|
|
1860
1347
|
|
|
1861
1348
|
it "should allow cascading of eager loading with a custom callback with array value" do
|
|
1862
|
-
ds = GraphTrack.eager_graph(:album=>{proc{|ds| ds.
|
|
1349
|
+
ds = GraphTrack.eager_graph(:album=>{proc{|ds| ds.select(:id, :band_id).columns(:id, :band_id)}=>[:band, :tracks]})
|
|
1863
1350
|
ds.sql.should == 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, tracks_0.id AS tracks_0_id, tracks_0.album_id AS tracks_0_album_id FROM tracks LEFT OUTER JOIN (SELECT id, band_id FROM albums) AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN tracks AS tracks_0 ON (tracks_0.album_id = album.id)'
|
|
1864
|
-
|
|
1865
|
-
yield({:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>6, :tracks_0_id=>3, :tracks_0_album_id=>1})
|
|
1866
|
-
end
|
|
1351
|
+
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>6, :tracks_0_id=>3, :tracks_0_album_id=>1}
|
|
1867
1352
|
a = ds.all
|
|
1868
|
-
a.should
|
|
1869
|
-
a.size.should == 1
|
|
1870
|
-
a.first.should be_a_kind_of(GraphTrack)
|
|
1871
|
-
a.first.values.should == {:id => 3, :album_id => 1}
|
|
1353
|
+
a.should == [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
1872
1354
|
a = a.first
|
|
1873
|
-
a.album.should
|
|
1874
|
-
a.album.
|
|
1875
|
-
a.album.
|
|
1876
|
-
a.album.band.values.should == {:id => 2, :vocalist_id=>6}
|
|
1877
|
-
a.album.tracks.should be_a_kind_of(Array)
|
|
1878
|
-
a.album.tracks.size.should == 1
|
|
1879
|
-
a.album.tracks.first.should be_a_kind_of(GraphTrack)
|
|
1880
|
-
a.album.tracks.first.values.should == {:id => 3, :album_id => 1}
|
|
1355
|
+
a.album.should == GraphAlbum.load(:id => 1, :band_id => 2)
|
|
1356
|
+
a.album.band.should == GraphBand.load(:id => 2, :vocalist_id=>6)
|
|
1357
|
+
a.album.tracks.should == [GraphTrack.load(:id => 3, :album_id => 1)]
|
|
1881
1358
|
end
|
|
1882
|
-
|
|
1883
1359
|
end
|