sequel 4.9.0 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +79 -1
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +2 -12
- data/bin/sequel +1 -0
- data/doc/advanced_associations.rdoc +82 -25
- data/doc/association_basics.rdoc +21 -22
- data/doc/core_extensions.rdoc +1 -1
- data/doc/opening_databases.rdoc +7 -0
- data/doc/release_notes/4.10.0.txt +226 -0
- data/doc/security.rdoc +1 -0
- data/doc/testing.rdoc +7 -7
- data/doc/transactions.rdoc +8 -0
- data/lib/sequel/adapters/jdbc.rb +160 -168
- data/lib/sequel/adapters/jdbc/db2.rb +17 -18
- data/lib/sequel/adapters/jdbc/derby.rb +5 -28
- data/lib/sequel/adapters/jdbc/h2.rb +11 -22
- data/lib/sequel/adapters/jdbc/hsqldb.rb +31 -18
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -15
- data/lib/sequel/adapters/jdbc/oracle.rb +36 -35
- data/lib/sequel/adapters/jdbc/postgresql.rb +72 -90
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +18 -16
- data/lib/sequel/adapters/jdbc/sqlite.rb +7 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +10 -30
- data/lib/sequel/adapters/jdbc/transactions.rb +5 -6
- data/lib/sequel/adapters/openbase.rb +1 -7
- data/lib/sequel/adapters/postgres.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +3 -6
- data/lib/sequel/adapters/shared/cubrid.rb +24 -9
- data/lib/sequel/adapters/shared/db2.rb +13 -5
- data/lib/sequel/adapters/shared/firebird.rb +16 -16
- data/lib/sequel/adapters/shared/informix.rb +2 -5
- data/lib/sequel/adapters/shared/mssql.rb +72 -63
- data/lib/sequel/adapters/shared/mysql.rb +72 -40
- data/lib/sequel/adapters/shared/oracle.rb +27 -15
- data/lib/sequel/adapters/shared/postgres.rb +24 -44
- data/lib/sequel/adapters/shared/progress.rb +1 -5
- data/lib/sequel/adapters/shared/sqlanywhere.rb +26 -18
- data/lib/sequel/adapters/shared/sqlite.rb +21 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -2
- data/lib/sequel/adapters/utils/split_alter_table.rb +8 -0
- data/lib/sequel/core.rb +14 -9
- data/lib/sequel/database/dataset_defaults.rb +1 -0
- data/lib/sequel/database/misc.rb +12 -0
- data/lib/sequel/database/query.rb +4 -1
- data/lib/sequel/database/schema_methods.rb +3 -2
- data/lib/sequel/database/transactions.rb +47 -17
- data/lib/sequel/dataset/features.rb +12 -2
- data/lib/sequel/dataset/mutation.rb +2 -0
- data/lib/sequel/dataset/placeholder_literalizer.rb +12 -4
- data/lib/sequel/dataset/prepared_statements.rb +6 -0
- data/lib/sequel/dataset/query.rb +1 -1
- data/lib/sequel/dataset/sql.rb +132 -70
- data/lib/sequel/extensions/columns_introspection.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +8 -4
- data/lib/sequel/extensions/pg_array.rb +4 -4
- data/lib/sequel/extensions/pg_row.rb +1 -0
- data/lib/sequel/model/associations.rb +468 -188
- data/lib/sequel/model/base.rb +88 -13
- data/lib/sequel/plugins/association_pks.rb +23 -64
- data/lib/sequel/plugins/auto_validations.rb +3 -2
- data/lib/sequel/plugins/dataset_associations.rb +1 -3
- data/lib/sequel/plugins/many_through_many.rb +18 -65
- data/lib/sequel/plugins/pg_array_associations.rb +97 -86
- data/lib/sequel/plugins/prepared_statements.rb +2 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +36 -27
- data/lib/sequel/plugins/rcte_tree.rb +12 -16
- data/lib/sequel/plugins/sharding.rb +21 -3
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -1
- data/lib/sequel/plugins/subclasses.rb +1 -9
- data/lib/sequel/plugins/tactical_eager_loading.rb +9 -0
- data/lib/sequel/plugins/tree.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +57 -15
- data/spec/adapters/mysql_spec.rb +11 -0
- data/spec/bin_spec.rb +2 -2
- data/spec/core/database_spec.rb +38 -4
- data/spec/core/dataset_spec.rb +45 -7
- data/spec/core/placeholder_literalizer_spec.rb +17 -0
- data/spec/core/schema_spec.rb +6 -1
- data/spec/extensions/active_model_spec.rb +18 -9
- data/spec/extensions/association_pks_spec.rb +20 -18
- data/spec/extensions/association_proxies_spec.rb +9 -9
- data/spec/extensions/auto_validations_spec.rb +6 -0
- data/spec/extensions/columns_introspection_spec.rb +1 -0
- data/spec/extensions/constraint_validations_spec.rb +3 -1
- data/spec/extensions/many_through_many_spec.rb +191 -111
- data/spec/extensions/pg_array_associations_spec.rb +133 -103
- data/spec/extensions/prepared_statements_associations_spec.rb +23 -4
- data/spec/extensions/rcte_tree_spec.rb +35 -27
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -1
- data/spec/extensions/sharding_spec.rb +2 -2
- data/spec/extensions/tactical_eager_loading_spec.rb +4 -0
- data/spec/extensions/to_dot_spec.rb +1 -0
- data/spec/extensions/touch_spec.rb +2 -2
- data/spec/integration/associations_test.rb +130 -37
- data/spec/integration/dataset_test.rb +17 -0
- data/spec/integration/model_test.rb +17 -0
- data/spec/integration/schema_test.rb +14 -0
- data/spec/integration/transaction_test.rb +25 -1
- data/spec/model/association_reflection_spec.rb +63 -24
- data/spec/model/associations_spec.rb +104 -57
- data/spec/model/base_spec.rb +14 -1
- data/spec/model/class_dataset_methods_spec.rb +1 -0
- data/spec/model/eager_loading_spec.rb +221 -74
- data/spec/model/model_spec.rb +119 -1
- metadata +4 -2
data/spec/model/base_spec.rb
CHANGED
@@ -577,8 +577,10 @@ end
|
|
577
577
|
|
578
578
|
describe Sequel::Model, ".[] optimization" do
|
579
579
|
before do
|
580
|
-
@db =
|
580
|
+
@db = Sequel.mock
|
581
581
|
@db.quote_identifiers = true
|
582
|
+
def @db.schema(*) [[:id, {:primary_key=>true}]] end
|
583
|
+
def @db.supports_schema_parsing?() true end
|
582
584
|
@c = Class.new(Sequel::Model(@db))
|
583
585
|
end
|
584
586
|
|
@@ -731,3 +733,14 @@ describe "Model datasets #with_pk with #with_pk!" do
|
|
731
733
|
DB.sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
|
732
734
|
end
|
733
735
|
end
|
736
|
+
|
737
|
+
describe "Model::include" do
|
738
|
+
it "shouldn't change the signature of Module::include" do
|
739
|
+
mod1 = Module.new
|
740
|
+
mod2 = Module.new
|
741
|
+
including_class = Class.new(Sequel::Model(:items)) do
|
742
|
+
include(mod1, mod2)
|
743
|
+
end
|
744
|
+
including_class.included_modules.should include(mod1, mod2)
|
745
|
+
end
|
746
|
+
end
|
@@ -157,7 +157,7 @@ describe Sequel::Model, "#eager" do
|
|
157
157
|
DB.sqls.should == ['SELECT * FROM albums']
|
158
158
|
end
|
159
159
|
|
160
|
-
it "should
|
160
|
+
it "should eagerly load a single one_to_one association without an order" do
|
161
161
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
|
162
162
|
EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
|
163
163
|
a = EagerAlbum.eager(:track).all
|
@@ -167,9 +167,18 @@ describe Sequel::Model, "#eager" do
|
|
167
167
|
DB.sqls.should == []
|
168
168
|
end
|
169
169
|
|
170
|
+
it "should eagerly load a single one_to_one association with an order" do
|
171
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a
|
172
|
+
a = EagerAlbum.eager(:track).all
|
173
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
174
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1']
|
175
|
+
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
176
|
+
DB.sqls.should == []
|
177
|
+
end
|
178
|
+
|
170
179
|
it "should eagerly load a single one_to_one association using the :distinct_on strategy" do
|
171
180
|
def (EagerTrack.dataset).supports_distinct_on?() true end
|
172
|
-
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a
|
181
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a, :eager_limit_strategy=>:distinct_on
|
173
182
|
a = EagerAlbum.eager(:track).all
|
174
183
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
175
184
|
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, a']
|
@@ -179,7 +188,7 @@ describe Sequel::Model, "#eager" do
|
|
179
188
|
|
180
189
|
it "should eagerly load a single one_to_one association using the :window_function strategy" do
|
181
190
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
182
|
-
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :eager_limit_strategy
|
191
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :eager_limit_strategy=>:window_function
|
183
192
|
a = EagerAlbum.eager(:track).all
|
184
193
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
185
194
|
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)']
|
@@ -187,19 +196,18 @@ describe Sequel::Model, "#eager" do
|
|
187
196
|
DB.sqls.should == []
|
188
197
|
end
|
189
198
|
|
190
|
-
it "should
|
191
|
-
|
192
|
-
|
193
|
-
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :order=>:name
|
199
|
+
it "should automatically use an eager limit stategy if the association has an offset" do
|
200
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1]
|
201
|
+
EagerTrack.dataset._fetch = [{:id => 4, :album_id=>1}]
|
194
202
|
a = EagerAlbum.eager(:track).all
|
195
203
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
196
|
-
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT
|
197
|
-
a.first.track.should == EagerTrack.load(:id =>
|
204
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
205
|
+
a.first.track.should == EagerTrack.load(:id => 4, :album_id=>1)
|
198
206
|
DB.sqls.should == []
|
199
207
|
end
|
200
208
|
|
201
|
-
it "should
|
202
|
-
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1]
|
209
|
+
it "should handle offsets when using the :ruby eager limit stategy" do
|
210
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :eager_limit_strategy=>:ruby
|
203
211
|
EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
|
204
212
|
a = EagerAlbum.eager(:track).all
|
205
213
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -208,6 +216,33 @@ describe Sequel::Model, "#eager" do
|
|
208
216
|
DB.sqls.should == []
|
209
217
|
end
|
210
218
|
|
219
|
+
it "should support a :subqueries_per_union option for the number of subqueries in a union" do
|
220
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>1
|
221
|
+
EagerAlbum.dataset._fetch = [{:id => 1, :band_id => 2}, {:id => 2, :band_id => 3}, {:id => 3, :band_id => 4}]
|
222
|
+
EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}], [{:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]]
|
223
|
+
a = EagerAlbum.eager(:track).all
|
224
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
|
225
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1', 'SELECT * FROM (SELECT * FROM tracks WHERE (2 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1', 'SELECT * FROM (SELECT * FROM tracks WHERE (3 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
226
|
+
a.first.track.should == EagerTrack.load(:id => 4, :album_id=>1)
|
227
|
+
DB.sqls.should == []
|
228
|
+
|
229
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>2
|
230
|
+
EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]]
|
231
|
+
a = EagerAlbum.eager(:track).all
|
232
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
|
233
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM tracks WHERE (2 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1', 'SELECT * FROM (SELECT * FROM tracks WHERE (3 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
234
|
+
a.first.track.should == EagerTrack.load(:id => 4, :album_id=>1)
|
235
|
+
DB.sqls.should == []
|
236
|
+
|
237
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>3
|
238
|
+
EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}, {:id=>6, :album_id=>3}]]
|
239
|
+
a = EagerAlbum.eager(:track).all
|
240
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
|
241
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM tracks WHERE (2 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM tracks WHERE (3 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
|
242
|
+
a.first.track.should == EagerTrack.load(:id => 4, :album_id=>1)
|
243
|
+
DB.sqls.should == []
|
244
|
+
end
|
245
|
+
|
211
246
|
it "should eagerly load a single one_to_many association" do
|
212
247
|
a = EagerAlbum.eager(:tracks).all
|
213
248
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -219,7 +254,7 @@ describe Sequel::Model, "#eager" do
|
|
219
254
|
it "should eagerly load a single one_through_one association" do
|
220
255
|
a = EagerAlbum.eager(:genre).all
|
221
256
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
222
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
257
|
+
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) WHERE (ag.album_id IN (1))"]
|
223
258
|
a.first.genre.should == EagerGenre.load(:id=>4)
|
224
259
|
DB.sqls.should == []
|
225
260
|
end
|
@@ -228,27 +263,36 @@ describe Sequel::Model, "#eager" do
|
|
228
263
|
EagerGenre.dataset._fetch = [{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}]
|
229
264
|
a = EagerAlbum.eager(:genre).all
|
230
265
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
231
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
266
|
+
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) WHERE (ag.album_id IN (1))"]
|
232
267
|
a.first.genre.should == EagerGenre.load(:id=>3)
|
233
268
|
DB.sqls.should == []
|
234
269
|
end
|
235
270
|
|
271
|
+
it "should eagerly load a single one_through_one association" do
|
272
|
+
EagerAlbum.one_through_one :genre, :clone=>:genre, :order=>:a
|
273
|
+
a = EagerAlbum.eager(:genre).all
|
274
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
275
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (1 = ag.album_id) ORDER BY a LIMIT 1) AS t1"]
|
276
|
+
a.first.genre.should == EagerGenre.load(:id=>4)
|
277
|
+
DB.sqls.should == []
|
278
|
+
end
|
279
|
+
|
236
280
|
it "should eagerly load a single one_through_one association using the :distinct_on strategy" do
|
237
281
|
def (EagerGenre.dataset).supports_distinct_on?() true end
|
238
|
-
EagerAlbum.one_through_one :genre, :clone=>:genre, :order=>:a
|
282
|
+
EagerAlbum.one_through_one :genre, :clone=>:genre, :order=>:a, :eager_limit_strategy=>:distinct_on
|
239
283
|
a = EagerAlbum.eager(:genre).all
|
240
284
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
241
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT ON (ag.album_id) genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
285
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT ON (ag.album_id) genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1)) ORDER BY ag.album_id, a"]
|
242
286
|
a.first.genre.should == EagerGenre.load(:id=>4)
|
243
287
|
DB.sqls.should == []
|
244
288
|
end
|
245
289
|
|
246
290
|
it "should eagerly load a single one_through_one association using the :window_function strategy" do
|
247
291
|
def (EagerGenre.dataset).supports_window_functions?() true end
|
248
|
-
EagerAlbum.one_through_one :genre, :clone=>:genre, :eager_limit_strategy
|
292
|
+
EagerAlbum.one_through_one :genre, :clone=>:genre, :eager_limit_strategy=>:window_function
|
249
293
|
a = EagerAlbum.eager(:genre).all
|
250
294
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
251
|
-
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) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON (
|
295
|
+
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) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 1)"]
|
252
296
|
a.first.genre.should == EagerGenre.load(:id=>4)
|
253
297
|
DB.sqls.should == []
|
254
298
|
end
|
@@ -257,7 +301,7 @@ describe Sequel::Model, "#eager" do
|
|
257
301
|
EagerGenre.dataset._fetch = [{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}]
|
258
302
|
a = EagerAlbum.eager(:genre).all
|
259
303
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
260
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
304
|
+
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) WHERE (ag.album_id IN (1))"]
|
261
305
|
a.first.genre.should == EagerGenre.load(:id=>3)
|
262
306
|
DB.sqls.should == []
|
263
307
|
end
|
@@ -265,7 +309,7 @@ describe Sequel::Model, "#eager" do
|
|
265
309
|
it "should eagerly load a single many_to_many association" do
|
266
310
|
a = EagerAlbum.eager(:genres).all
|
267
311
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
268
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
312
|
+
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) WHERE (ag.album_id IN (1))"]
|
269
313
|
a.first.genres.should == [EagerGenre.load(:id=>4)]
|
270
314
|
DB.sqls.should == []
|
271
315
|
end
|
@@ -295,7 +339,7 @@ describe Sequel::Model, "#eager" do
|
|
295
339
|
EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
|
296
340
|
a = EagerAlbum.eager(:sgenres).all
|
297
341
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
298
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
342
|
+
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) WHERE (ag.album_id IN (6))"]
|
299
343
|
a.first.sgenres.should == [EagerGenre.load(:id=>4)]
|
300
344
|
DB.sqls.should == []
|
301
345
|
end
|
@@ -305,7 +349,7 @@ describe Sequel::Model, "#eager" do
|
|
305
349
|
EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
|
306
350
|
a = EagerAlbum.eager(:sgenre).all
|
307
351
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
308
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
352
|
+
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) WHERE (ag.album_id IN (6))"]
|
309
353
|
a.first.sgenre.should == EagerGenre.load(:id=>4)
|
310
354
|
DB.sqls.should == []
|
311
355
|
end
|
@@ -334,7 +378,7 @@ describe Sequel::Model, "#eager" do
|
|
334
378
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loading_predicate_key=>Sequel.*(:ag__album_id, 1)
|
335
379
|
a = EagerAlbum.eager(:sgenres).all
|
336
380
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
337
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
381
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE ((ag.album_id * 1) IN (1))"]
|
338
382
|
a.first.sgenres.should == [EagerGenre.load(:id=>4)]
|
339
383
|
DB.sqls.should == []
|
340
384
|
end
|
@@ -343,7 +387,7 @@ describe Sequel::Model, "#eager" do
|
|
343
387
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :eager_loading_predicate_key=>Sequel.*(:ag__album_id, 1)
|
344
388
|
a = EagerAlbum.eager(:sgenre).all
|
345
389
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
346
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
390
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE ((ag.album_id * 1) IN (1))"]
|
347
391
|
a.first.sgenre.should == EagerGenre.load(:id=>4)
|
348
392
|
DB.sqls.should == []
|
349
393
|
end
|
@@ -366,25 +410,25 @@ describe Sequel::Model, "#eager" do
|
|
366
410
|
it "should correctly handle a :select=>[] option to many_to_many" do
|
367
411
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :select=>[]
|
368
412
|
EagerAlbum.eager(:sgenres).all
|
369
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
413
|
+
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) WHERE (ag.album_id IN (1))"]
|
370
414
|
end
|
371
415
|
|
372
416
|
it "should correctly handle a :select=>[] option to one_through_one" do
|
373
417
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :select=>[]
|
374
418
|
EagerAlbum.eager(:sgenre).all
|
375
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
419
|
+
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) WHERE (ag.album_id IN (1))"]
|
376
420
|
end
|
377
421
|
|
378
422
|
it "should correctly handle an aliased join table in many_to_many" do
|
379
423
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>:ag___ga
|
380
424
|
EagerAlbum.eager(:sgenres).all
|
381
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON (
|
425
|
+
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) WHERE (ga.album_id IN (1))"]
|
382
426
|
end
|
383
427
|
|
384
428
|
it "should correctly handle an aliased join table in one_through_one" do
|
385
429
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :join_table=>:ag___ga
|
386
430
|
EagerAlbum.eager(:sgenre).all
|
387
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON (
|
431
|
+
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) WHERE (ga.album_id IN (1))"]
|
388
432
|
end
|
389
433
|
|
390
434
|
it "should eagerly load multiple associations in a single call" do
|
@@ -394,7 +438,7 @@ describe Sequel::Model, "#eager" do
|
|
394
438
|
sqls.shift.should == 'SELECT * FROM albums'
|
395
439
|
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
396
440
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
397
|
-
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
441
|
+
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))']
|
398
442
|
a = a.first
|
399
443
|
a.band.should == EagerBand.load(:id=>2)
|
400
444
|
a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
@@ -409,7 +453,7 @@ describe Sequel::Model, "#eager" do
|
|
409
453
|
sqls.shift.should == 'SELECT * FROM albums'
|
410
454
|
sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
|
411
455
|
'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
|
412
|
-
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
456
|
+
'SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))']
|
413
457
|
a = a.first
|
414
458
|
a.band.should == EagerBand.load(:id=>2)
|
415
459
|
a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
@@ -423,7 +467,7 @@ describe Sequel::Model, "#eager" do
|
|
423
467
|
DB.sqls.should == ['SELECT * FROM tracks',
|
424
468
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
425
469
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
426
|
-
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (
|
470
|
+
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (bm.member_id = members.id) WHERE (bm.band_id IN (2))"]
|
427
471
|
a = a.first
|
428
472
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
429
473
|
a.album.band.should == EagerBand.load(:id => 2)
|
@@ -431,6 +475,32 @@ describe Sequel::Model, "#eager" do
|
|
431
475
|
DB.sqls.should == []
|
432
476
|
end
|
433
477
|
|
478
|
+
it "should cascade eager loading when using a UNION strategy for eager loading limited associations" do
|
479
|
+
EagerTrack.many_to_one :album2, :clone=>:album
|
480
|
+
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a
|
481
|
+
a = EagerAlbum.eager(:track=>:album2).all
|
482
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
483
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1', 'SELECT * FROM albums WHERE (albums.id IN (1))']
|
484
|
+
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
485
|
+
a.first.track.album2.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
486
|
+
DB.sqls.should == []
|
487
|
+
|
488
|
+
a = EagerAlbum.eager(:track=>[:album2]).all
|
489
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
490
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1', 'SELECT * FROM albums WHERE (albums.id IN (1))']
|
491
|
+
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
492
|
+
a.first.track.album2.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
493
|
+
DB.sqls.should == []
|
494
|
+
|
495
|
+
a = EagerAlbum.eager(:track=>{:album2=>:track}).all
|
496
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
497
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1', 'SELECT * FROM albums WHERE (albums.id IN (1))', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY a LIMIT 1) AS t1']
|
498
|
+
a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
499
|
+
a.first.track.album2.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
500
|
+
a.first.track.album2.track.should == EagerTrack.load(:id => 3, :album_id=>1)
|
501
|
+
DB.sqls.should == []
|
502
|
+
end
|
503
|
+
|
434
504
|
it "should cascade eagerly loading when the :eager association option is used" do
|
435
505
|
a = EagerBand.eager(:albums).all
|
436
506
|
a.should == [EagerBand.load(:id=>2)]
|
@@ -488,7 +558,7 @@ describe Sequel::Model, "#eager" do
|
|
488
558
|
ds._fetch = [{:id=>5, :bands_id=>2, :p_k=>6}, {:id=>5, :bands_id=>3, :p_k=>6}]
|
489
559
|
a = EagerBand.load(:id=>2)
|
490
560
|
a.graph_members.should == [EagerBandMember.load(:id=>5)]
|
491
|
-
DB.sqls.should == ['SELECT members.id, bands.id AS bands_id, bands.p_k FROM (SELECT members.* FROM members INNER JOIN bm ON (
|
561
|
+
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) WHERE (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']
|
492
562
|
a.graph_members.first.bands.should == [EagerBand.load(:id=>2, :p_k=>6), EagerBand.load(:id=>3, :p_k=>6)]
|
493
563
|
DB.sqls.should == []
|
494
564
|
end
|
@@ -497,19 +567,19 @@ describe Sequel::Model, "#eager" do
|
|
497
567
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>{:a=>32}
|
498
568
|
a = EagerBandMember.eager(:good_bands).all
|
499
569
|
a.should == [EagerBandMember.load(:id => 5)]
|
500
|
-
DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON (
|
570
|
+
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) WHERE ((a = 32) AND (bm.member_id IN (5))) ORDER BY id']
|
501
571
|
a.first.good_bands.should == [EagerBand.load(:id => 2)]
|
502
572
|
DB.sqls.should == []
|
503
573
|
|
504
574
|
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>"x = 1"
|
505
575
|
a = EagerBandMember.eager(:good_bands).all
|
506
|
-
DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON (
|
576
|
+
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) WHERE ((x = 1) AND (bm.member_id IN (5))) ORDER BY id']
|
507
577
|
end
|
508
578
|
|
509
579
|
it "should respect :order when eagerly loading" do
|
510
580
|
a = EagerBandMember.eager(:bands).all
|
511
581
|
a.should == [EagerBandMember.load(:id => 5)]
|
512
|
-
DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON (
|
582
|
+
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) WHERE (bm.member_id IN (5)) ORDER BY id']
|
513
583
|
a.first.bands.should == [EagerBand.load(:id => 2)]
|
514
584
|
DB.sqls.should == []
|
515
585
|
end
|
@@ -544,14 +614,14 @@ describe Sequel::Model, "#eager" do
|
|
544
614
|
|
545
615
|
it "should use the association's block when eager loading by default" do
|
546
616
|
EagerAlbum.eager(:good_tracks).all
|
547
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.album_id IN (1))
|
617
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((name = 'Good') AND (tracks.album_id IN (1)))"]
|
548
618
|
end
|
549
619
|
|
550
620
|
it "should use the eager_block option when eager loading if given" do
|
551
621
|
EagerBand.eager(:good_albums).all
|
552
|
-
DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2))
|
622
|
+
DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((name = 'good') AND (albums.band_id IN (2)))"]
|
553
623
|
EagerBand.eager(:good_albums=>:good_tracks).all
|
554
|
-
DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2))
|
624
|
+
DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((name = 'good') AND (albums.band_id IN (2)))", "SELECT * FROM tracks WHERE ((name = 'Good') AND (tracks.album_id IN (1)))"]
|
555
625
|
end
|
556
626
|
|
557
627
|
it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
|
@@ -565,7 +635,7 @@ describe Sequel::Model, "#eager" do
|
|
565
635
|
EagerAlbum.eager(:track_names).all
|
566
636
|
DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM tracks WHERE (tracks.album_id IN (1))"]
|
567
637
|
EagerAlbum.eager(:genre_names).all
|
568
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT id, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
638
|
+
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) WHERE (ag.album_id IN (1))"]
|
569
639
|
end
|
570
640
|
|
571
641
|
it "should respect many_to_one association's :qualify option" do
|
@@ -615,7 +685,7 @@ describe Sequel::Model, "#eager" do
|
|
615
685
|
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
|
616
686
|
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}]
|
617
687
|
as = EagerAlbum.eager(:special_genres).all
|
618
|
-
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)
|
688
|
+
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)) WHERE ((ag.l1, ag.l2) IN ((2, 1)))"]
|
619
689
|
as.length.should == 1
|
620
690
|
as.first.special_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
621
691
|
end
|
@@ -624,7 +694,7 @@ describe Sequel::Model, "#eager" do
|
|
624
694
|
EagerAlbum.one_through_one :special_genre, :class=>:EagerGenre, :left_primary_key=>[:band_id, :id], :left_key=>[:l1, :l2], :right_primary_key=>[:xxx, :id], :right_key=>[:r1, :r2], :join_table=>:ag
|
625
695
|
EagerGenre.dataset._fetch = [{:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5}]
|
626
696
|
as = EagerAlbum.eager(:special_genre).all
|
627
|
-
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)
|
697
|
+
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)) WHERE ((ag.l1, ag.l2) IN ((2, 1)))"]
|
628
698
|
as.length.should == 1
|
629
699
|
as.first.special_genre.should == EagerGenre.load(:id=>5)
|
630
700
|
end
|
@@ -633,7 +703,7 @@ describe Sequel::Model, "#eager" do
|
|
633
703
|
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
|
634
704
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
635
705
|
as = EagerAlbum.eager(:special_genres).all
|
636
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
706
|
+
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) WHERE (ag.album_id IN (2))"]
|
637
707
|
as.length.should == 1
|
638
708
|
as.first.special_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
639
709
|
end
|
@@ -642,13 +712,13 @@ describe Sequel::Model, "#eager" do
|
|
642
712
|
EagerAlbum.one_through_one :special_genre, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_primary_key=>:xxx, :right_key=>:genre_id, :join_table=>:ag
|
643
713
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
|
644
714
|
as = EagerAlbum.eager(:special_genre).all
|
645
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
715
|
+
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) WHERE (ag.album_id IN (2))"]
|
646
716
|
as.length.should == 1
|
647
717
|
as.first.special_genre.should == EagerGenre.load(:id=>5)
|
648
718
|
end
|
649
719
|
|
650
|
-
it "should respect the :limit option on a one_to_many association" do
|
651
|
-
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2
|
720
|
+
it "should respect the :limit option on a one_to_many association using the :ruby strategy" do
|
721
|
+
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2, :eager_limit_strategy=>:ruby
|
652
722
|
EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2}, {:album_id=>1, :id=>3}, {:album_id=>1, :id=>4}]
|
653
723
|
as = EagerAlbum.eager(:first_two_tracks).all
|
654
724
|
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
@@ -656,43 +726,60 @@ describe Sequel::Model, "#eager" do
|
|
656
726
|
as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>2), EagerTrack.load(:album_id=>1, :id=>3)]
|
657
727
|
|
658
728
|
DB.reset
|
659
|
-
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[1,1]
|
729
|
+
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[1,1], :eager_limit_strategy=>:ruby
|
660
730
|
as = EagerAlbum.eager(:first_two_tracks).all
|
661
731
|
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
662
732
|
as.length.should == 1
|
663
733
|
as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>3)]
|
664
734
|
|
665
735
|
DB.reset
|
666
|
-
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[nil,1]
|
736
|
+
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[nil,1], :eager_limit_strategy=>:ruby
|
667
737
|
as = EagerAlbum.eager(:first_two_tracks).all
|
668
738
|
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
|
669
739
|
as.length.should == 1
|
670
740
|
as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>3), EagerTrack.load(:album_id=>1, :id=>4)]
|
671
741
|
end
|
672
742
|
|
673
|
-
it "should respect the :limit option on a one_to_many association
|
674
|
-
def (EagerTrack.dataset).supports_window_functions?() true end
|
743
|
+
it "should respect the :limit option on a one_to_many association" do
|
675
744
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2
|
676
745
|
a = EagerAlbum.eager(:tracks).all
|
677
746
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
678
|
-
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT
|
747
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY name LIMIT 2) AS t1']
|
679
748
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
680
749
|
DB.sqls.should == []
|
681
|
-
end
|
682
750
|
|
683
|
-
it "should respect the :limit option with an offset on a one_to_many association using the :window_function strategy" do
|
684
|
-
def (EagerTrack.dataset).supports_window_functions?() true end
|
685
751
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[2, 1]
|
686
752
|
a = EagerAlbum.eager(:tracks).all
|
687
753
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
688
|
-
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT
|
754
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY name LIMIT 2 OFFSET 1) AS t1']
|
755
|
+
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
756
|
+
DB.sqls.should == []
|
757
|
+
|
758
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[nil, 1]
|
759
|
+
a = EagerAlbum.eager(:tracks).all
|
760
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
761
|
+
DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) ORDER BY name OFFSET 1) AS t1']
|
689
762
|
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
690
763
|
DB.sqls.should == []
|
691
764
|
end
|
692
765
|
|
693
|
-
it "should respect the :limit option
|
766
|
+
it "should respect the :limit option on a one_to_many association using the :window_function strategy" do
|
694
767
|
def (EagerTrack.dataset).supports_window_functions?() true end
|
695
|
-
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>
|
768
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2, :eager_limit_strategy=>:window_function
|
769
|
+
a = EagerAlbum.eager(:tracks).all
|
770
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
771
|
+
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)']
|
772
|
+
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
773
|
+
DB.sqls.should == []
|
774
|
+
|
775
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[2, 1], :eager_limit_strategy=>:window_function
|
776
|
+
a = EagerAlbum.eager(:tracks).all
|
777
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
778
|
+
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))']
|
779
|
+
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
780
|
+
DB.sqls.should == []
|
781
|
+
|
782
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[nil, 1], :eager_limit_strategy=>:window_function
|
696
783
|
a = EagerAlbum.eager(:tracks).all
|
697
784
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
698
785
|
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)']
|
@@ -700,49 +787,96 @@ describe Sequel::Model, "#eager" do
|
|
700
787
|
DB.sqls.should == []
|
701
788
|
end
|
702
789
|
|
703
|
-
it "should
|
704
|
-
|
790
|
+
it "should use a ruby strategy for limit if :eager_graph option is used" do
|
791
|
+
EagerTrack.many_to_one :album2, :clone=>:album
|
792
|
+
EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2, :eager_graph=>:album2
|
793
|
+
EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2, :album2_id=>1, :band_id=>5}, {:album_id=>1, :id=>3, :album2_id=>1, :band_id=>5}, {:album_id=>1, :id=>4, :album2_id=>1, :band_id=>5}]
|
794
|
+
as = EagerAlbum.eager(:first_two_tracks).all
|
795
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT tracks.id, tracks.album_id, album2.id AS album2_id, album2.band_id FROM tracks LEFT OUTER JOIN albums AS album2 ON (album2.id = tracks.album_id) WHERE (tracks.album_id IN (1))"]
|
796
|
+
as.length.should == 1
|
797
|
+
tracks = as.first.first_two_tracks
|
798
|
+
tracks.should == [EagerTrack.load(:album_id=>1, :id=>2), EagerTrack.load(:album_id=>1, :id=>3)]
|
799
|
+
tracks.first.album2.should == EagerAlbum.load(:id=>1, :band_id=>5)
|
800
|
+
tracks.last.album2.should == EagerAlbum.load(:id=>1, :band_id=>5)
|
801
|
+
end
|
802
|
+
|
803
|
+
it "should not use a union strategy for limit by default if providing a per-eager load callback" do
|
804
|
+
def (EagerTrack.dataset).supports_window_functions?() true end
|
805
|
+
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2
|
806
|
+
a = EagerAlbum.eager(:tracks=>proc{|ds| ds.where(:id=>3)}).all
|
807
|
+
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
808
|
+
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)) AND (id = 3))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
|
809
|
+
a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
|
810
|
+
DB.sqls.should == []
|
811
|
+
end
|
812
|
+
|
813
|
+
it "should respect the limit option on a many_to_many association using the :ruby strategy" do
|
814
|
+
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, :eager_limit_strategy=>:ruby
|
705
815
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
706
816
|
as = EagerAlbum.eager(:first_two_genres).all
|
707
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
817
|
+
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) WHERE (ag.album_id IN (2))"]
|
708
818
|
as.length.should == 1
|
709
819
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
710
820
|
|
711
821
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
712
|
-
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=>[1, 1]
|
822
|
+
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=>[1, 1], :eager_limit_strategy=>:ruby
|
713
823
|
as = EagerAlbum.eager(:first_two_genres).all
|
714
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
824
|
+
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) WHERE (ag.album_id IN (2))"]
|
715
825
|
as.length.should == 1
|
716
826
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>6)]
|
717
827
|
|
718
828
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
|
719
|
-
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=>[nil, 1]
|
829
|
+
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=>[nil, 1], :eager_limit_strategy=>:ruby
|
720
830
|
as = EagerAlbum.eager(:first_two_genres).all
|
721
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
831
|
+
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) WHERE (ag.album_id IN (2))"]
|
722
832
|
as.length.should == 1
|
723
833
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>6), EagerGenre.load(:id=>7)]
|
724
834
|
end
|
725
835
|
|
726
|
-
it "should respect the limit option on a many_to_many association
|
836
|
+
it "should respect the limit option on a many_to_many association" do
|
727
837
|
def (EagerGenre.dataset).supports_window_functions?() true end
|
728
838
|
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, :order=>:name
|
729
839
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
730
840
|
as = EagerAlbum.eager(:first_two_genres).all
|
731
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x
|
841
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (2 = ag.album_id) ORDER BY name LIMIT 2) AS t1"]
|
732
842
|
as.length.should == 1
|
733
843
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
734
844
|
|
735
845
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
|
736
846
|
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=>[1, 1], :order=>:name
|
737
847
|
as = EagerAlbum.eager(:first_two_genres).all
|
738
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x
|
848
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (2 = ag.album_id) ORDER BY name LIMIT 1 OFFSET 1) AS t1"]
|
739
849
|
as.length.should == 1
|
740
850
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5)]
|
741
851
|
|
742
852
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
743
853
|
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=>[nil, 1], :order=>:name
|
744
854
|
as = EagerAlbum.eager(:first_two_genres).all
|
745
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x
|
855
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (2 = ag.album_id) ORDER BY name OFFSET 1) AS t1"]
|
856
|
+
as.length.should == 1
|
857
|
+
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
858
|
+
end
|
859
|
+
|
860
|
+
it "should respect the limit option on a many_to_many association using the :window_function strategy" do
|
861
|
+
def (EagerGenre.dataset).supports_window_functions?() true end
|
862
|
+
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, :order=>:name, :eager_limit_strategy=>:window_function
|
863
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
864
|
+
as = EagerAlbum.eager(:first_two_genres).all
|
865
|
+
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) WHERE (ag.album_id IN (2))) AS t1 WHERE (x_sequel_row_number_x <= 2)"]
|
866
|
+
as.length.should == 1
|
867
|
+
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
868
|
+
|
869
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
|
870
|
+
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=>[1, 1], :order=>:name, :eager_limit_strategy=>:window_function
|
871
|
+
as = EagerAlbum.eager(:first_two_genres).all
|
872
|
+
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) WHERE (ag.album_id IN (2))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 3))"]
|
873
|
+
as.length.should == 1
|
874
|
+
as.first.first_two_genres.should == [EagerGenre.load(:id=>5)]
|
875
|
+
|
876
|
+
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
877
|
+
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=>[nil, 1], :order=>:name, :eager_limit_strategy=>:window_function
|
878
|
+
as = EagerAlbum.eager(:first_two_genres).all
|
879
|
+
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) WHERE (ag.album_id IN (2))) AS t1 WHERE (x_sequel_row_number_x >= 2)"]
|
746
880
|
as.length.should == 1
|
747
881
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
748
882
|
end
|
@@ -789,7 +923,7 @@ describe Sequel::Model, "#eager" do
|
|
789
923
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :uniq=>true
|
790
924
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>1, :id=>8}, {:x_foreign_key_x=>1, :id=>8}]
|
791
925
|
a = EagerAlbum.eager(:al_genres).all.first
|
792
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
926
|
+
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) WHERE (ag.album_id IN (1))"]
|
793
927
|
a.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
794
928
|
a.al_genres.should == [EagerGenre.load(:id=>8)]
|
795
929
|
end
|
@@ -797,7 +931,7 @@ describe Sequel::Model, "#eager" do
|
|
797
931
|
it "should respect :distinct option when eagerly loading many_to_many associations" do
|
798
932
|
EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :distinct=>true
|
799
933
|
a = EagerAlbum.eager(:al_genres).all.first
|
800
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
934
|
+
DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
801
935
|
a.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
802
936
|
a.al_genres.should == [EagerGenre.load(:id=>4)]
|
803
937
|
end
|
@@ -830,7 +964,7 @@ describe Sequel::Model, "#eager" do
|
|
830
964
|
it "should eagerly load a many_to_many association with custom eager block" do
|
831
965
|
a = EagerAlbum.eager(:genres => proc {|ds| ds.select(:name)}).all
|
832
966
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
833
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
967
|
+
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) WHERE (ag.album_id IN (1))"]
|
834
968
|
a.first.genres.should == [EagerGenre.load(:id => 4)]
|
835
969
|
DB.sqls.should == []
|
836
970
|
end
|
@@ -838,7 +972,7 @@ describe Sequel::Model, "#eager" do
|
|
838
972
|
it "should eagerly load a one_through_one association with custom eager block" do
|
839
973
|
a = EagerAlbum.eager(:genre => proc {|ds| ds.select(:name)}).all
|
840
974
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
841
|
-
DB.sqls.should == ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
975
|
+
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) WHERE (ag.album_id IN (1))"]
|
842
976
|
a.first.genre.should == EagerGenre.load(:id => 4)
|
843
977
|
DB.sqls.should == []
|
844
978
|
end
|
@@ -849,7 +983,7 @@ describe Sequel::Model, "#eager" do
|
|
849
983
|
DB.sqls.should == ['SELECT * FROM tracks',
|
850
984
|
'SELECT * FROM albums WHERE (albums.id IN (1))',
|
851
985
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
852
|
-
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (
|
986
|
+
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (bm.member_id = members.id) WHERE (bm.band_id IN (2))"]
|
853
987
|
a = a.first
|
854
988
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
855
989
|
a.album.band.should == EagerBand.load(:id => 2)
|
@@ -863,7 +997,7 @@ describe Sequel::Model, "#eager" do
|
|
863
997
|
DB.sqls.should == ['SELECT * FROM tracks',
|
864
998
|
'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
|
865
999
|
'SELECT * FROM bands WHERE (bands.id IN (2))',
|
866
|
-
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (
|
1000
|
+
"SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON (bm.member_id = members.id) WHERE (bm.band_id IN (2))"]
|
867
1001
|
a = a.first
|
868
1002
|
a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
|
869
1003
|
a.album.band.should == EagerBand.load(:id => 2)
|
@@ -900,7 +1034,7 @@ describe Sequel::Model, "#eager" do
|
|
900
1034
|
|
901
1035
|
it "should call both association and custom eager blocks" do
|
902
1036
|
EagerBand.eager(:good_albums => proc {|ds| ds.select(:name)}).all
|
903
|
-
DB.sqls.should == ['SELECT * FROM bands', "SELECT name FROM albums WHERE ((albums.band_id IN (2))
|
1037
|
+
DB.sqls.should == ['SELECT * FROM bands', "SELECT name FROM albums WHERE ((name = 'good') AND (albums.band_id IN (2)))"]
|
904
1038
|
end
|
905
1039
|
end
|
906
1040
|
|
@@ -1094,6 +1228,19 @@ describe Sequel::Model, "#eager_graph" do
|
|
1094
1228
|
a.first.ltrack.should == sub.load(:id => 3, :album_id=>1)
|
1095
1229
|
end
|
1096
1230
|
|
1231
|
+
it "should eagerly graph a single one_to_one association using the :correlated_subquery strategy" do
|
1232
|
+
sub = Class.new(GraphTrack)
|
1233
|
+
def (sub.dataset).supports_window_functions?() true end
|
1234
|
+
def (sub.dataset).columns() [:id, :album_id] end
|
1235
|
+
GraphAlbum.one_to_one :ltrack, :clone=>:track, :class=>sub
|
1236
|
+
ds = GraphAlbum.eager_graph_with_options(:ltrack, :limit_strategy=>:correlated_subquery)
|
1237
|
+
ds.sql.should == 'SELECT albums.id, albums.band_id, ltrack.id AS ltrack_id, ltrack.album_id FROM albums LEFT OUTER JOIN (SELECT * FROM tracks WHERE (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) LIMIT 1))) AS ltrack ON (ltrack.album_id = albums.id)'
|
1238
|
+
ds._fetch = {:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1}
|
1239
|
+
a = ds.all
|
1240
|
+
a.should == [GraphAlbum.load(:id => 1, :band_id => 2)]
|
1241
|
+
a.first.ltrack.should == sub.load(:id => 3, :album_id=>1)
|
1242
|
+
end
|
1243
|
+
|
1097
1244
|
it "should eagerly load a single one_to_many association" do
|
1098
1245
|
ds = GraphAlbum.eager_graph(:tracks)
|
1099
1246
|
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)'
|
@@ -1367,7 +1514,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1367
1514
|
a.tracks.should == [GraphTrack.load(:id=>3, :album_id=>1)]
|
1368
1515
|
a.genres.should == [GraphGenre.load(:id => 6)]
|
1369
1516
|
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)',
|
1370
|
-
"SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (
|
1517
|
+
"SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
1371
1518
|
end
|
1372
1519
|
|
1373
1520
|
it "should handle no associated records for a single many_to_one association" do
|