sequel 4.41.0 → 4.42.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +98 -0
  3. data/README.rdoc +23 -10
  4. data/doc/active_record.rdoc +4 -4
  5. data/doc/advanced_associations.rdoc +2 -2
  6. data/doc/association_basics.rdoc +5 -2
  7. data/doc/cheat_sheet.rdoc +3 -3
  8. data/doc/core_extensions.rdoc +2 -2
  9. data/doc/dataset_basics.rdoc +4 -4
  10. data/doc/dataset_filtering.rdoc +1 -1
  11. data/doc/migration.rdoc +19 -1
  12. data/doc/prepared_statements.rdoc +2 -2
  13. data/doc/release_notes/4.42.0.txt +221 -0
  14. data/doc/testing.rdoc +3 -1
  15. data/lib/sequel/adapters/ado/access.rb +0 -1
  16. data/lib/sequel/adapters/ado/mssql.rb +0 -1
  17. data/lib/sequel/adapters/do/mysql.rb +0 -1
  18. data/lib/sequel/adapters/do/postgres.rb +0 -1
  19. data/lib/sequel/adapters/do/sqlite3.rb +0 -1
  20. data/lib/sequel/adapters/ibmdb.rb +21 -25
  21. data/lib/sequel/adapters/jdbc.rb +8 -16
  22. data/lib/sequel/adapters/jdbc/as400.rb +0 -1
  23. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
  24. data/lib/sequel/adapters/jdbc/db2.rb +0 -1
  25. data/lib/sequel/adapters/jdbc/derby.rb +0 -1
  26. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
  27. data/lib/sequel/adapters/jdbc/h2.rb +0 -1
  28. data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
  29. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
  30. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
  31. data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
  32. data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
  33. data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
  34. data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
  35. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
  36. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
  37. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
  38. data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
  39. data/lib/sequel/adapters/mock.rb +54 -12
  40. data/lib/sequel/adapters/mysql.rb +1 -1
  41. data/lib/sequel/adapters/mysql2.rb +11 -17
  42. data/lib/sequel/adapters/odbc/mssql.rb +0 -1
  43. data/lib/sequel/adapters/oracle.rb +8 -20
  44. data/lib/sequel/adapters/postgres.rb +11 -29
  45. data/lib/sequel/adapters/shared/access.rb +5 -12
  46. data/lib/sequel/adapters/shared/cubrid.rb +4 -13
  47. data/lib/sequel/adapters/shared/db2.rb +4 -2
  48. data/lib/sequel/adapters/shared/firebird.rb +2 -4
  49. data/lib/sequel/adapters/shared/informix.rb +4 -2
  50. data/lib/sequel/adapters/shared/mssql.rb +3 -5
  51. data/lib/sequel/adapters/shared/mysql.rb +4 -14
  52. data/lib/sequel/adapters/shared/oracle.rb +1 -3
  53. data/lib/sequel/adapters/shared/postgres.rb +16 -38
  54. data/lib/sequel/adapters/shared/progress.rb +0 -2
  55. data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
  56. data/lib/sequel/adapters/shared/sqlite.rb +20 -16
  57. data/lib/sequel/adapters/sqlite.rb +8 -20
  58. data/lib/sequel/adapters/swift/mysql.rb +0 -1
  59. data/lib/sequel/adapters/swift/postgres.rb +0 -1
  60. data/lib/sequel/adapters/swift/sqlite.rb +0 -1
  61. data/lib/sequel/adapters/tinytds.rb +4 -12
  62. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  63. data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
  64. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
  65. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  66. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
  67. data/lib/sequel/ast_transformer.rb +2 -2
  68. data/lib/sequel/database/dataset.rb +1 -1
  69. data/lib/sequel/database/dataset_defaults.rb +0 -66
  70. data/lib/sequel/database/features.rb +6 -0
  71. data/lib/sequel/database/misc.rb +31 -17
  72. data/lib/sequel/database/query.rb +7 -4
  73. data/lib/sequel/database/schema_methods.rb +1 -1
  74. data/lib/sequel/dataset.rb +8 -8
  75. data/lib/sequel/dataset/actions.rb +140 -46
  76. data/lib/sequel/dataset/features.rb +1 -5
  77. data/lib/sequel/dataset/graph.rb +7 -8
  78. data/lib/sequel/dataset/misc.rb +127 -56
  79. data/lib/sequel/dataset/mutation.rb +9 -20
  80. data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
  81. data/lib/sequel/dataset/prepared_statements.rb +102 -46
  82. data/lib/sequel/dataset/query.rb +155 -72
  83. data/lib/sequel/dataset/sql.rb +26 -9
  84. data/lib/sequel/extensions/columns_introspection.rb +3 -1
  85. data/lib/sequel/extensions/core_extensions.rb +5 -5
  86. data/lib/sequel/extensions/core_refinements.rb +5 -5
  87. data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
  88. data/lib/sequel/extensions/freeze_datasets.rb +69 -0
  89. data/lib/sequel/extensions/identifier_mangling.rb +196 -0
  90. data/lib/sequel/extensions/looser_typecasting.rb +11 -7
  91. data/lib/sequel/extensions/migration.rb +1 -1
  92. data/lib/sequel/extensions/null_dataset.rb +5 -2
  93. data/lib/sequel/extensions/pagination.rb +42 -23
  94. data/lib/sequel/extensions/pg_enum.rb +3 -3
  95. data/lib/sequel/extensions/query.rb +3 -3
  96. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
  97. data/lib/sequel/model/associations.rb +25 -8
  98. data/lib/sequel/model/base.rb +88 -29
  99. data/lib/sequel/model/dataset_module.rb +37 -0
  100. data/lib/sequel/plugins/association_pks.rb +4 -4
  101. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  102. data/lib/sequel/plugins/constraint_validations.rb +1 -2
  103. data/lib/sequel/plugins/csv_serializer.rb +2 -2
  104. data/lib/sequel/plugins/dataset_associations.rb +8 -8
  105. data/lib/sequel/plugins/eager_each.rb +2 -2
  106. data/lib/sequel/plugins/instance_filters.rb +1 -1
  107. data/lib/sequel/plugins/json_serializer.rb +2 -2
  108. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  109. data/lib/sequel/plugins/list.rb +4 -4
  110. data/lib/sequel/plugins/prepared_statements.rb +2 -4
  111. data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
  112. data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
  113. data/lib/sequel/plugins/rcte_tree.rb +13 -13
  114. data/lib/sequel/plugins/sharding.rb +1 -1
  115. data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
  116. data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
  117. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  118. data/lib/sequel/plugins/validation_helpers.rb +1 -1
  119. data/lib/sequel/plugins/xml_serializer.rb +2 -2
  120. data/lib/sequel/sql.rb +69 -36
  121. data/lib/sequel/version.rb +1 -1
  122. data/spec/adapters/db2_spec.rb +10 -0
  123. data/spec/adapters/firebird_spec.rb +1 -1
  124. data/spec/adapters/mssql_spec.rb +4 -5
  125. data/spec/adapters/mysql_spec.rb +9 -9
  126. data/spec/adapters/postgres_spec.rb +67 -68
  127. data/spec/adapters/spec_helper.rb +6 -1
  128. data/spec/adapters/sqlite_spec.rb +29 -15
  129. data/spec/core/connection_pool_spec.rb +14 -14
  130. data/spec/core/database_spec.rb +38 -180
  131. data/spec/core/dataset_mutation_spec.rb +253 -0
  132. data/spec/core/dataset_spec.rb +394 -537
  133. data/spec/core/expression_filters_spec.rb +34 -32
  134. data/spec/core/mock_adapter_spec.rb +27 -35
  135. data/spec/core/placeholder_literalizer_spec.rb +2 -4
  136. data/spec/core/schema_generator_spec.rb +4 -4
  137. data/spec/core/schema_spec.rb +1 -2
  138. data/spec/core_extensions_spec.rb +22 -29
  139. data/spec/extensions/active_model_spec.rb +6 -6
  140. data/spec/extensions/association_dependencies_spec.rb +2 -2
  141. data/spec/extensions/blacklist_security_spec.rb +3 -3
  142. data/spec/extensions/boolean_readers_spec.rb +12 -12
  143. data/spec/extensions/caching_spec.rb +13 -10
  144. data/spec/extensions/class_table_inheritance_spec.rb +38 -43
  145. data/spec/extensions/column_conflicts_spec.rb +1 -3
  146. data/spec/extensions/columns_introspection_spec.rb +2 -3
  147. data/spec/extensions/composition_spec.rb +5 -3
  148. data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
  149. data/spec/extensions/constraint_validations_spec.rb +14 -8
  150. data/spec/extensions/core_refinements_spec.rb +22 -29
  151. data/spec/extensions/csv_serializer_spec.rb +7 -6
  152. data/spec/extensions/date_arithmetic_spec.rb +15 -15
  153. data/spec/extensions/defaults_setter_spec.rb +2 -2
  154. data/spec/extensions/delay_add_association_spec.rb +1 -1
  155. data/spec/extensions/dirty_spec.rb +19 -10
  156. data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
  157. data/spec/extensions/eager_each_spec.rb +12 -16
  158. data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
  159. data/spec/extensions/eval_inspect_spec.rb +4 -3
  160. data/spec/extensions/force_encoding_spec.rb +12 -12
  161. data/spec/extensions/freeze_datasets_spec.rb +31 -0
  162. data/spec/extensions/graph_each_spec.rb +6 -18
  163. data/spec/extensions/hook_class_methods_spec.rb +7 -7
  164. data/spec/extensions/identifier_mangling_spec.rb +307 -0
  165. data/spec/extensions/instance_filters_spec.rb +5 -6
  166. data/spec/extensions/instance_hooks_spec.rb +12 -12
  167. data/spec/extensions/json_serializer_spec.rb +12 -15
  168. data/spec/extensions/lazy_attributes_spec.rb +4 -4
  169. data/spec/extensions/list_spec.rb +19 -21
  170. data/spec/extensions/many_through_many_spec.rb +108 -163
  171. data/spec/extensions/meta_def_spec.rb +7 -2
  172. data/spec/extensions/migration_spec.rb +10 -12
  173. data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
  174. data/spec/extensions/named_timezones_spec.rb +4 -3
  175. data/spec/extensions/nested_attributes_spec.rb +2 -2
  176. data/spec/extensions/null_dataset_spec.rb +17 -12
  177. data/spec/extensions/optimistic_locking_spec.rb +4 -5
  178. data/spec/extensions/pagination_spec.rb +8 -10
  179. data/spec/extensions/pg_array_associations_spec.rb +28 -27
  180. data/spec/extensions/pg_array_ops_spec.rb +2 -1
  181. data/spec/extensions/pg_array_spec.rb +6 -2
  182. data/spec/extensions/pg_enum_spec.rb +5 -3
  183. data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
  184. data/spec/extensions/pg_hstore_spec.rb +7 -6
  185. data/spec/extensions/pg_inet_ops_spec.rb +2 -1
  186. data/spec/extensions/pg_inet_spec.rb +2 -1
  187. data/spec/extensions/pg_interval_spec.rb +2 -1
  188. data/spec/extensions/pg_json_ops_spec.rb +2 -1
  189. data/spec/extensions/pg_json_spec.rb +6 -3
  190. data/spec/extensions/pg_loose_count_spec.rb +1 -0
  191. data/spec/extensions/pg_range_ops_spec.rb +3 -1
  192. data/spec/extensions/pg_range_spec.rb +9 -5
  193. data/spec/extensions/pg_row_ops_spec.rb +2 -1
  194. data/spec/extensions/pg_row_plugin_spec.rb +4 -6
  195. data/spec/extensions/pg_row_spec.rb +5 -3
  196. data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
  197. data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
  198. data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
  199. data/spec/extensions/prepared_statements_spec.rb +12 -11
  200. data/spec/extensions/pretty_table_spec.rb +1 -1
  201. data/spec/extensions/query_spec.rb +8 -5
  202. data/spec/extensions/rcte_tree_spec.rb +39 -39
  203. data/spec/extensions/round_timestamps_spec.rb +2 -2
  204. data/spec/extensions/schema_dumper_spec.rb +3 -2
  205. data/spec/extensions/schema_spec.rb +2 -2
  206. data/spec/extensions/scissors_spec.rb +1 -2
  207. data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
  208. data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
  209. data/spec/extensions/serialization_spec.rb +15 -13
  210. data/spec/extensions/set_overrides_spec.rb +14 -8
  211. data/spec/extensions/sharding_spec.rb +9 -18
  212. data/spec/extensions/shared_caching_spec.rb +3 -4
  213. data/spec/extensions/single_table_inheritance_spec.rb +11 -11
  214. data/spec/extensions/skip_create_refresh_spec.rb +2 -1
  215. data/spec/extensions/spec_helper.rb +1 -1
  216. data/spec/extensions/split_values_spec.rb +2 -2
  217. data/spec/extensions/sql_comments_spec.rb +6 -0
  218. data/spec/extensions/static_cache_spec.rb +7 -9
  219. data/spec/extensions/string_agg_spec.rb +30 -29
  220. data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
  221. data/spec/extensions/thread_local_timezones_spec.rb +2 -2
  222. data/spec/extensions/timestamps_spec.rb +28 -3
  223. data/spec/extensions/to_dot_spec.rb +1 -2
  224. data/spec/extensions/tree_spec.rb +33 -29
  225. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  226. data/spec/extensions/unlimited_update_spec.rb +1 -0
  227. data/spec/extensions/update_primary_key_spec.rb +11 -7
  228. data/spec/extensions/update_refresh_spec.rb +1 -1
  229. data/spec/extensions/uuid_spec.rb +0 -1
  230. data/spec/extensions/validate_associated_spec.rb +1 -1
  231. data/spec/extensions/validation_class_methods_spec.rb +10 -10
  232. data/spec/extensions/validation_helpers_spec.rb +10 -10
  233. data/spec/extensions/xml_serializer_spec.rb +7 -3
  234. data/spec/integration/associations_test.rb +31 -31
  235. data/spec/integration/dataset_test.rb +17 -19
  236. data/spec/integration/eager_loader_test.rb +24 -24
  237. data/spec/integration/model_test.rb +6 -6
  238. data/spec/integration/plugin_test.rb +43 -43
  239. data/spec/integration/prepared_statement_test.rb +6 -6
  240. data/spec/integration/schema_test.rb +63 -52
  241. data/spec/integration/spec_helper.rb +6 -1
  242. data/spec/integration/transaction_test.rb +13 -13
  243. data/spec/model/association_reflection_spec.rb +17 -17
  244. data/spec/model/associations_spec.rb +101 -96
  245. data/spec/model/base_spec.rb +175 -49
  246. data/spec/model/class_dataset_methods_spec.rb +5 -9
  247. data/spec/model/dataset_methods_spec.rb +5 -5
  248. data/spec/model/eager_loading_spec.rb +209 -235
  249. data/spec/model/hooks_spec.rb +15 -15
  250. data/spec/model/model_spec.rb +28 -21
  251. data/spec/model/plugins_spec.rb +4 -5
  252. data/spec/model/record_spec.rb +59 -57
  253. data/spec/model/spec_helper.rb +1 -1
  254. data/spec/model/validations_spec.rb +6 -6
  255. data/spec/spec_config.rb +1 -1
  256. metadata +10 -2
@@ -160,7 +160,7 @@ describe Sequel::Model, ".def_dataset_method" do
160
160
  @c.def_dataset_method(:return_3, :return_4)
161
161
  proc{@c.return_3}.must_raise(NoMethodError)
162
162
  proc{@c.return_4}.must_raise(NoMethodError)
163
- @c.dataset.instance_eval do
163
+ @c.dataset = @c.dataset.with_extend do
164
164
  def return_3; 3; end
165
165
  def return_4; 4; end
166
166
  end
@@ -279,7 +279,122 @@ describe Sequel::Model, ".dataset_module" do
279
279
  @c.where(:foo).released.sql.must_equal 'SELECT * FROM items WHERE (foo AND released)'
280
280
  end
281
281
 
282
- it "should raise error if called with both an argument and ablock" do
282
+ it "should have dataset_module support a where method" do
283
+ @c.dataset_module{where :released, :released}
284
+ @c.released.sql.must_equal 'SELECT * FROM items WHERE released'
285
+ @c.where(:foo).released.sql.must_equal 'SELECT * FROM items WHERE (foo AND released)'
286
+ end
287
+
288
+ it "should have dataset_module support a having method" do
289
+ @c.dataset_module{having(:released){released}}
290
+ @c.released.sql.must_equal 'SELECT * FROM items HAVING released'
291
+ @c.where(:foo).released.sql.must_equal 'SELECT * FROM items WHERE foo HAVING released'
292
+ end
293
+
294
+ it "should have dataset_module support an exclude method" do
295
+ @c.dataset_module{exclude :released, :released}
296
+ @c.released.sql.must_equal 'SELECT * FROM items WHERE NOT released'
297
+ @c.where(:foo).released.sql.must_equal 'SELECT * FROM items WHERE (foo AND NOT released)'
298
+ end
299
+
300
+ it "should have dataset_module support an exclude_having method" do
301
+ @c.dataset_module{exclude_having :released, :released}
302
+ @c.released.sql.must_equal 'SELECT * FROM items HAVING NOT released'
303
+ @c.where(:foo).released.sql.must_equal 'SELECT * FROM items WHERE foo HAVING NOT released'
304
+ end
305
+
306
+ it "should have dataset_module support a distinct method" do
307
+ @c.dataset = @c.dataset.with_extend{def supports_distinct_on?; true end}
308
+ @c.dataset_module{distinct :foo, :baz}
309
+ @c.foo.sql.must_equal 'SELECT DISTINCT ON (baz) * FROM items'
310
+ @c.where(:bar).foo.sql.must_equal 'SELECT DISTINCT ON (baz) * FROM items WHERE bar'
311
+ end
312
+
313
+ it "should have dataset_module support a grep method" do
314
+ @c.dataset_module{grep :foo, :baz, 'quux%'}
315
+ @c.foo.sql.must_equal 'SELECT * FROM items WHERE ((baz LIKE \'quux%\' ESCAPE \'\\\'))'
316
+ @c.where(:bar).foo.sql.must_equal 'SELECT * FROM items WHERE (bar AND ((baz LIKE \'quux%\' ESCAPE \'\\\')))'
317
+ end
318
+
319
+ it "should have dataset_module support a group method" do
320
+ @c.dataset_module{group :foo, :baz}
321
+ @c.foo.sql.must_equal 'SELECT * FROM items GROUP BY baz'
322
+ @c.where(:bar).foo.sql.must_equal 'SELECT * FROM items WHERE bar GROUP BY baz'
323
+ end
324
+
325
+ it "should have dataset_module support a group_and_count method" do
326
+ @c.dataset_module{group_and_count :foo, :baz}
327
+ @c.foo.sql.must_equal 'SELECT baz, count(*) AS count FROM items GROUP BY baz'
328
+ @c.where(:bar).foo.sql.must_equal 'SELECT baz, count(*) AS count FROM items WHERE bar GROUP BY baz'
329
+ end
330
+
331
+ it "should have dataset_module support a group_append method" do
332
+ @c.dataset_module{group_append :foo, :baz}
333
+ @c.foo.sql.must_equal 'SELECT * FROM items GROUP BY baz'
334
+ @c.group(:bar).foo.sql.must_equal 'SELECT * FROM items GROUP BY bar, baz'
335
+ end
336
+
337
+ it "should have dataset_module support a limit method" do
338
+ @c.dataset_module{limit :foo, 1}
339
+ @c.foo.sql.must_equal 'SELECT * FROM items LIMIT 1'
340
+ @c.where(:bar).foo.sql.must_equal 'SELECT * FROM items WHERE bar LIMIT 1'
341
+ end
342
+
343
+ it "should have dataset_module support a offset method" do
344
+ @c.dataset_module{offset :foo, 1}
345
+ @c.foo.sql.must_equal 'SELECT * FROM items OFFSET 1'
346
+ @c.where(:bar).foo.sql.must_equal 'SELECT * FROM items WHERE bar OFFSET 1'
347
+ end
348
+
349
+ it "should have dataset_module support a order method" do
350
+ @c.dataset_module{order(:foo){:baz}}
351
+ @c.foo.sql.must_equal 'SELECT * FROM items ORDER BY baz'
352
+ @c.where(:bar).foo.sql.must_equal 'SELECT * FROM items WHERE bar ORDER BY baz'
353
+ end
354
+
355
+ it "should have dataset_module support a order_append method" do
356
+ @c.dataset_module{order_append :foo, :baz}
357
+ @c.foo.sql.must_equal 'SELECT * FROM items ORDER BY baz'
358
+ @c.order(:bar).foo.sql.must_equal 'SELECT * FROM items ORDER BY bar, baz'
359
+ end
360
+
361
+ it "should have dataset_module support a order_prepend method" do
362
+ @c.dataset_module{order_prepend :foo, :baz}
363
+ @c.foo.sql.must_equal 'SELECT * FROM items ORDER BY baz'
364
+ @c.order(:bar).foo.sql.must_equal 'SELECT * FROM items ORDER BY baz, bar'
365
+ end
366
+
367
+ it "should have dataset_module support a select method" do
368
+ @c.dataset_module{select :foo, :baz}
369
+ @c.foo.sql.must_equal 'SELECT baz FROM items'
370
+ @c.where(:bar).foo.sql.must_equal 'SELECT baz FROM items WHERE bar'
371
+ end
372
+
373
+ it "should have dataset_module support a select_all method" do
374
+ @c.dataset_module{select_all :foo, :baz}
375
+ @c.foo.sql.must_equal 'SELECT baz.* FROM items'
376
+ @c.where(:bar).foo.sql.must_equal 'SELECT baz.* FROM items WHERE bar'
377
+ end
378
+
379
+ it "should have dataset_module support a select_append method" do
380
+ @c.dataset_module{select_append :foo, :baz}
381
+ @c.foo.sql.must_equal 'SELECT *, baz FROM items'
382
+ @c.where(:bar).foo.sql.must_equal 'SELECT *, baz FROM items WHERE bar'
383
+ end
384
+
385
+ it "should have dataset_module support a select_group method" do
386
+ @c.dataset_module{select_group :foo, :baz}
387
+ @c.foo.sql.must_equal 'SELECT baz FROM items GROUP BY baz'
388
+ @c.where(:bar).foo.sql.must_equal 'SELECT baz FROM items WHERE bar GROUP BY baz'
389
+ end
390
+
391
+ it "should have dataset_module support a server method" do
392
+ @c.dataset_module{server :foo, :baz}
393
+ @c.foo.opts[:server].must_equal :baz
394
+ @c.where(:bar).foo.opts[:server].must_equal :baz
395
+ end
396
+
397
+ it "should raise error if called with both an argument and a block" do
283
398
  proc{@c.dataset_module(Module.new{def return_3() 3 end}){}}.must_raise(Sequel::Error)
284
399
  end
285
400
  end
@@ -333,7 +448,7 @@ describe "Model.primary_key" do
333
448
 
334
449
  it "should use nil for no primary key" do
335
450
  @c.no_primary_key
336
- @c.primary_key.must_equal nil
451
+ @c.primary_key.must_be_nil
337
452
  end
338
453
  end
339
454
 
@@ -392,7 +507,7 @@ describe "Model.db" do
392
507
  Sequel::DATABASES.clear
393
508
  end
394
509
  after do
395
- Sequel::Model.instance_variable_get(:@db).must_equal nil
510
+ Sequel::Model.instance_variable_get(:@db).must_be_nil
396
511
  Sequel::DATABASES.replace(@databases)
397
512
  Sequel::Model.db = @model_db
398
513
  end
@@ -470,7 +585,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
470
585
  end
471
586
 
472
587
  it "should set the allowed columns correctly" do
473
- @c.allowed_columns.must_equal nil
588
+ @c.allowed_columns.must_be_nil
474
589
  @c.set_allowed_columns :x
475
590
  @c.allowed_columns.must_equal [:x]
476
591
  @c.set_allowed_columns :x, :y
@@ -484,7 +599,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
484
599
  i.set(:x => 4, :y => 5, :z => 6)
485
600
  i.values.must_equal(:x => 4, :y => 5)
486
601
 
487
- @c.instance_dataset._fetch = @c.dataset._fetch = {:x => 7}
602
+ @c.dataset = @c.dataset.with_fetch(:x => 7)
488
603
  i = @c.new
489
604
  i.update(:x => 7, :z => 9)
490
605
  i.values.must_equal(:x => 7)
@@ -563,10 +678,8 @@ end
563
678
 
564
679
  describe Sequel::Model, ".require_modification" do
565
680
  before do
566
- @ds1 = DB[:items]
567
- def @ds1.provides_accurate_rows_matched?() false end
568
- @ds2 = DB[:items]
569
- def @ds2.provides_accurate_rows_matched?() true end
681
+ @ds1 = DB[:items].with_extend{def provides_accurate_rows_matched?; false end}
682
+ @ds2 = DB[:items].with_extend{def provides_accurate_rows_matched?; true end}
570
683
  end
571
684
  after do
572
685
  Sequel::Model.require_modification = nil
@@ -591,89 +704,74 @@ end
591
704
  describe Sequel::Model, ".[] optimization" do
592
705
  before do
593
706
  @db = Sequel.mock
594
- @db.quote_identifiers = true
595
707
  def @db.schema(*) [[:id, {:primary_key=>true}]] end
596
708
  def @db.supports_schema_parsing?() true end
597
709
  @c = Class.new(Sequel::Model(@db))
710
+ @ds = @db.dataset.with_quote_identifiers(true)
598
711
  end
599
712
 
600
713
  it "should set simple_pk to the literalized primary key column name if a single primary key" do
601
714
  @c.set_primary_key :id
602
- @c.simple_pk.must_equal '"id"'
715
+ @c.simple_pk.must_equal 'id'
603
716
  @c.set_primary_key :b
604
- @c.simple_pk.must_equal '"b"'
717
+ @c.simple_pk.must_equal 'b'
605
718
  @c.set_primary_key Sequel.identifier(:b__a)
606
- @c.simple_pk.must_equal '"b__a"'
719
+ @c.simple_pk.must_equal 'b__a'
607
720
  end
608
721
 
609
722
  it "should have simple_pk be blank if compound or no primary key" do
610
723
  @c.no_primary_key
611
- @c.simple_pk.must_equal nil
724
+ @c.simple_pk.must_be_nil
612
725
  @c.set_primary_key [:b, :a]
613
- @c.simple_pk.must_equal nil
726
+ @c.simple_pk.must_be_nil
614
727
  end
615
728
 
616
729
  it "should have simple table set if passed a Symbol to set_dataset" do
617
730
  @c.set_dataset :a
618
- @c.simple_table.must_equal '"a"'
731
+ @c.simple_table.must_equal 'a'
619
732
  @c.set_dataset :b
620
- @c.simple_table.must_equal '"b"'
733
+ @c.simple_table.must_equal 'b'
621
734
  @c.set_dataset :b__a
622
- @c.simple_table.must_equal '"b"."a"'
735
+ @c.simple_table.must_equal 'b.a'
623
736
  end
624
737
 
625
738
  it "should have simple_table set if passed a simple select all dataset to set_dataset" do
626
- @c.set_dataset @db[:a]
739
+ @c.set_dataset @ds.from(:a)
627
740
  @c.simple_table.must_equal '"a"'
628
- @c.set_dataset @db[:b]
741
+ @c.set_dataset @ds.from(:b)
629
742
  @c.simple_table.must_equal '"b"'
630
- @c.set_dataset @db[:b__a]
743
+ @c.set_dataset @ds.from(:b__a)
631
744
  @c.simple_table.must_equal '"b"."a"'
632
745
  end
633
746
 
634
- it "should have simple_pk and simple_table respect dataset's identifier input methods" do
635
- ds = @db[:ab]
636
- ds.identifier_input_method = :reverse
637
- @c.set_dataset ds
638
- @c.simple_table.must_equal '"ba"'
639
- @c.set_primary_key :cd
640
- @c.simple_pk.must_equal '"dc"'
641
-
642
- @c.set_dataset ds.from(:ef__gh)
643
- @c.simple_table.must_equal '"fe"."hg"'
644
- end
645
-
646
747
  it "should have simple_table = nil if passed a non-simple select all dataset to set_dataset" do
647
748
  @c.set_dataset @c.db[:a].filter(:active)
648
- @c.simple_table.must_equal nil
749
+ @c.simple_table.must_be_nil
649
750
  end
650
751
 
651
752
  it "should have simple_table inherit superclass's setting" do
652
- Class.new(@c).simple_table.must_equal nil
753
+ Class.new(@c).simple_table.must_be_nil
653
754
  @c.set_dataset :a
654
- Class.new(@c).simple_table.must_equal '"a"'
755
+ Class.new(@c).simple_table.must_equal 'a'
655
756
  end
656
757
 
657
758
  it "should use Dataset#with_sql if simple_table and simple_pk are true" do
658
- @c.set_dataset :a
659
- @c.instance_dataset._fetch = @c.dataset._fetch = {:id => 1}
759
+ @c.set_dataset @db[:a].with_fetch(:id=>1)
660
760
  @c[1].must_equal @c.load(:id=>1)
661
- @db.sqls.must_equal ['SELECT * FROM "a" WHERE "id" = 1']
761
+ @db.sqls.must_equal ['SELECT * FROM a WHERE id = 1']
662
762
  end
663
763
 
664
764
  it "should not use Dataset#with_sql if either simple_table or simple_pk is nil" do
665
- @c.set_dataset @db[:a].filter(:active)
666
- @c.dataset._fetch = {:id => 1}
765
+ @c.set_dataset @db[:a].where(:active).with_fetch(:id=>1)
667
766
  @c[1].must_equal @c.load(:id=>1)
668
- @db.sqls.must_equal ['SELECT * FROM "a" WHERE ("active" AND ("id" = 1)) LIMIT 1']
767
+ @db.sqls.must_equal ['SELECT * FROM a WHERE (active AND (id = 1)) LIMIT 1']
669
768
  end
670
769
  end
671
770
 
672
771
  describe "Model datasets #with_pk with #with_pk!" do
673
772
  before do
674
773
  @c = Class.new(Sequel::Model(:a))
675
- @ds = @c.dataset
676
- @ds._fetch = {:id=>1}
774
+ @ds = @c.dataset = @c.dataset.with_fetch(:id=>1)
677
775
  DB.reset
678
776
  end
679
777
 
@@ -691,6 +789,14 @@ describe "Model datasets #with_pk with #with_pk!" do
691
789
  DB.sqls.must_equal ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
692
790
  end
693
791
 
792
+ it "should work when called repeatedly on a frozen dataset" do
793
+ @ds.freeze
794
+ 5.times do
795
+ @ds.with_pk(1).must_equal @c.load(:id=>1)
796
+ DB.sqls.must_equal ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
797
+ end
798
+ end
799
+
694
800
  it "should handle existing filters" do
695
801
  @ds.filter(:a=>2).with_pk(1)
696
802
  DB.sqls.must_equal ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
@@ -720,17 +826,29 @@ describe "Model datasets #with_pk with #with_pk!" do
720
826
  sqls.must_equal []
721
827
  end
722
828
 
829
+ it "should work with composite primary keys when called repeatedly on a frozen dataset with" do
830
+ @c.set_primary_key [:id1, :id2]
831
+ @ds.freeze
832
+ 5.times do
833
+ @ds.with_pk([1,2])
834
+ sqls = DB.sqls
835
+ ["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
836
+ "SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].must_include(sqls.pop)
837
+ sqls.must_equal []
838
+ end
839
+ end
840
+
723
841
  it "should have with_pk return nil and with_pk! raise if no rows match" do
724
- @ds._fetch = []
725
- @ds.with_pk(1).must_equal nil
842
+ @ds = @ds.with_fetch([])
843
+ @ds.with_pk(1).must_be_nil
726
844
  DB.sqls.must_equal ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
727
845
  proc{@ds.with_pk!(1)}.must_raise(Sequel::NoMatchingRow)
728
846
  DB.sqls.must_equal ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
729
847
  end
730
848
 
731
849
  it "should have with_pk return nil and with_pk! raise if no rows match when calling the class method" do
732
- @ds._fetch = []
733
- @c.with_pk(1).must_equal nil
850
+ @c.dataset = @c.dataset.with_fetch([])
851
+ @c.with_pk(1).must_be_nil
734
852
  DB.sqls.must_equal ["SELECT * FROM a WHERE id = 1"]
735
853
  proc{@c.with_pk!(1)}.must_raise(Sequel::NoMatchingRow)
736
854
  DB.sqls.must_equal ["SELECT * FROM a WHERE id = 1"]
@@ -745,6 +863,14 @@ describe "Model datasets #with_pk with #with_pk!" do
745
863
  @ds['foo'].must_equal @c.load(:id=>1)
746
864
  DB.sqls.must_equal ["SELECT * FROM a WHERE (foo) LIMIT 1"]
747
865
  end
866
+
867
+ it "should raise Error if called on a dataset with no primary key" do
868
+ @c.no_primary_key
869
+ @ds.freeze
870
+ 5.times do
871
+ proc{@ds.with_pk(1)}.must_raise Sequel::Error
872
+ end
873
+ end
748
874
  end
749
875
 
750
876
  describe "Model::include" do
@@ -3,12 +3,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe Sequel::Model, "class dataset methods" do
4
4
  before do
5
5
  @db = Sequel.mock
6
- @c = Class.new(Sequel::Model(@db[:items]))
6
+ @c = Class.new(Sequel::Model(@db[:items].with_extend{def supports_cte?(*) true end}.with_fetch(:id=>1).with_autoid(1).with_numrows(0)))
7
7
  @d = @c.dataset
8
- def @d.supports_cte?(*) true end
9
- @d._fetch = {:id=>1}
10
- @d.autoid = 1
11
- @d.numrows = 0
12
8
  @db.sqls
13
9
  end
14
10
 
@@ -78,7 +74,7 @@ describe Sequel::Model, "class dataset methods" do
78
74
  @db.sqls.must_equal ["SELECT min(id) AS min FROM items LIMIT 1"]
79
75
  @c.multi_insert([{:id=>1}])
80
76
  @db.sqls.must_equal ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
81
- @c.naked.row_proc.must_equal nil
77
+ @c.naked.row_proc.must_be_nil
82
78
  @c.natural_full_join(@c).sql.must_equal "SELECT * FROM items NATURAL FULL JOIN items"
83
79
  @c.natural_join(@c).sql.must_equal "SELECT * FROM items NATURAL JOIN items"
84
80
  @c.natural_left_join(@c).sql.must_equal "SELECT * FROM items NATURAL LEFT JOIN items"
@@ -134,7 +130,8 @@ describe Sequel::Model, "class dataset methods" do
134
130
  sc.set_dataset(@d.where(:a).order(:a).select(:a).group(:a).limit(2))
135
131
  @db.sqls
136
132
  sc.invert.sql.must_equal 'SELECT a FROM items WHERE NOT a GROUP BY a ORDER BY a LIMIT 2'
137
- sc.dataset._fetch = {:v1=>1, :v2=>2}
133
+ sc.dataset = sc.dataset.with_fetch(:v1=>1, :v2=>2)
134
+ @db.sqls
138
135
  sc.range(:a).must_equal(1..2)
139
136
  @db.sqls.must_equal ["SELECT min(a) AS v1, max(a) AS v2 FROM (SELECT a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2) AS t1 LIMIT 1"]
140
137
  sc.reverse.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
@@ -144,7 +141,6 @@ describe Sequel::Model, "class dataset methods" do
144
141
  sc.ungrouped.sql.must_equal 'SELECT a FROM items WHERE a ORDER BY a LIMIT 2'
145
142
  sc.unordered.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a LIMIT 2'
146
143
  sc.unlimited.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a'
147
- sc.dataset.graph!(:a)
148
- sc.dataset.ungraphed.opts[:graph].must_equal nil
144
+ sc.dataset.graph(:a).ungraphed.opts[:graph].must_be_nil
149
145
  end
150
146
  end
@@ -9,7 +9,7 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
9
9
  end
10
10
  end
11
11
  @d = @c.dataset
12
- @d._fetch = [{:id=>1}, {:id=>2}]
12
+ @d = @d.with_fetch([{:id=>1}, {:id=>2}])
13
13
  DB.reset
14
14
  end
15
15
 
@@ -20,7 +20,7 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
20
20
 
21
21
  it "should return the number of records destroyed" do
22
22
  @d.destroy.must_equal 2
23
- @d._fetch = [[{:i=>1}], []]
23
+ @d = @d.with_fetch([[{:id=>1}], []])
24
24
  @d.destroy.must_equal 1
25
25
  @d.destroy.must_equal 0
26
26
  end
@@ -47,7 +47,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
47
47
  end
48
48
 
49
49
  it "should result in a hash with primary key value keys and model object values" do
50
- @d._fetch = [{:name=>1}, {:name=>2}]
50
+ @d = @d.with_fetch([{:name=>1}, {:name=>2}])
51
51
  h = @d.to_hash
52
52
  h.must_be_kind_of(Hash)
53
53
  a = h.to_a
@@ -56,7 +56,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
56
56
  end
57
57
 
58
58
  it "should result in a hash with given value keys and model object values" do
59
- @d._fetch = [{:name=>1, :number=>3}, {:name=>2, :number=>4}]
59
+ @d = @d.with_fetch([{:name=>1, :number=>3}, {:name=>2, :number=>4}])
60
60
  h = @d.to_hash(:number)
61
61
  h.must_be_kind_of(Hash)
62
62
  a = h.to_a
@@ -105,7 +105,7 @@ describe Sequel::Model::DatasetMethods do
105
105
  @c.last.must_be_kind_of(@c)
106
106
  @c.db.sqls.must_equal ['SELECT * FROM items ORDER BY id DESC LIMIT 1']
107
107
  @c.where(:id=>2).last(:foo=>2){{bar=>3}}.must_be_kind_of(@c)
108
- @c.db.sqls.must_equal ['SELECT * FROM items WHERE ((id = 2) AND (bar = 3) AND (foo = 2)) ORDER BY id DESC LIMIT 1']
108
+ @c.db.sqls.must_equal ['SELECT * FROM items WHERE ((id = 2) AND (foo = 2) AND (bar = 3)) ORDER BY id DESC LIMIT 1']
109
109
  end
110
110
 
111
111
  it "#last should use existing order if there is one" do
@@ -55,8 +55,7 @@ describe Sequel::Model, "#eager" do
55
55
  many_to_many :bands, :class=>'EagerBand', :left_key=>:member_id, :right_key=>:band_id, :join_table=>:bm, :order =>:id
56
56
  end
57
57
 
58
- EagerAlbum.dataset.columns(:id, :band_id)
59
- EagerAlbum.dataset._fetch = proc do |sql|
58
+ EagerAlbum.dataset = EagerAlbum.dataset.with_fetch(proc do |sql|
60
59
  h = if sql =~ /101/
61
60
  {:id => 101, :band_id=> 101}
62
61
  else
@@ -64,9 +63,10 @@ describe Sequel::Model, "#eager" do
64
63
  end
65
64
  h[:x_foreign_key_x] = 4 if sql =~ /ag\.genre_id/
66
65
  h
67
- end
66
+ end)
67
+ EagerAlbum.dataset.columns(:id, :band_id)
68
68
 
69
- EagerBand.dataset._fetch = proc do |sql|
69
+ EagerBand.dataset = EagerBand.dataset.with_fetch(proc do |sql|
70
70
  case sql
71
71
  when /id IN (101)/
72
72
  # nothing
@@ -77,21 +77,21 @@ describe Sequel::Model, "#eager" do
77
77
  h[:x_foreign_key_x] = 5 if sql =~ /bm\.member_id/
78
78
  h
79
79
  end
80
- end
80
+ end)
81
81
 
82
- EagerTrack.dataset._fetch = {:id => 3, :album_id => 1}
82
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch(:id => 3, :album_id => 1)
83
83
 
84
- EagerGenre.dataset._fetch = proc do |sql|
84
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch(proc do |sql|
85
85
  h = {:id => 4}
86
86
  h[:x_foreign_key_x] = 1 if sql =~ /ag\.album_id/
87
87
  h
88
- end
88
+ end)
89
89
 
90
- EagerBandMember.dataset._fetch = proc do |sql|
90
+ EagerBandMember.dataset = EagerBandMember.dataset.with_fetch(proc do |sql|
91
91
  h = {:id => 5}
92
92
  h[:x_foreign_key_x] = 2 if sql =~ /bm\.band_id/
93
93
  h
94
- end
94
+ end)
95
95
 
96
96
  DB.reset
97
97
  end
@@ -148,12 +148,12 @@ describe Sequel::Model, "#eager" do
148
148
  end
149
149
 
150
150
  it "should skip eager loading for a many_to_one association with no matching keys" do
151
- EagerAlbum.dataset._fetch = [{:id=>1, :band_id=>nil}]
151
+ EagerAlbum.dataset = EagerAlbum.dataset.with_fetch([{:id=>1, :band_id=>nil}])
152
152
  a = EagerAlbum.eager(:band).all
153
153
  DB.sqls.must_equal ['SELECT * FROM albums']
154
154
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => nil)]
155
- a.first.associations.fetch(:band).must_equal nil
156
- a.first.band.must_equal nil
155
+ a.first.associations.fetch(:band).must_be_nil
156
+ a.first.band.must_be_nil
157
157
  DB.sqls.must_equal []
158
158
  end
159
159
 
@@ -185,7 +185,7 @@ describe Sequel::Model, "#eager" do
185
185
 
186
186
  it "should eagerly load a single one_to_one association without an order" do
187
187
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
188
- EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
188
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}])
189
189
  a = EagerAlbum.eager(:track).all
190
190
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
191
191
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
@@ -203,7 +203,7 @@ describe Sequel::Model, "#eager" do
203
203
  end
204
204
 
205
205
  it "should eagerly load a single one_to_one association using the :distinct_on strategy" do
206
- def (EagerTrack.dataset).supports_distinct_on?() true end
206
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_distinct_on?; true end}
207
207
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:a, :eager_limit_strategy=>:distinct_on
208
208
  a = EagerAlbum.eager(:track).all
209
209
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -213,7 +213,7 @@ describe Sequel::Model, "#eager" do
213
213
  end
214
214
 
215
215
  it "should eagerly load a single one_to_one association using the :window_function strategy" do
216
- def (EagerTrack.dataset).supports_window_functions?() true end
216
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_window_functions?; true end}
217
217
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :eager_limit_strategy=>:window_function
218
218
  a = EagerAlbum.eager(:track).all
219
219
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -224,7 +224,7 @@ describe Sequel::Model, "#eager" do
224
224
 
225
225
  it "should automatically use an eager limit stategy if the association has an offset" do
226
226
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1]
227
- EagerTrack.dataset._fetch = [{:id => 4, :album_id=>1}]
227
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([{:id => 4, :album_id=>1}])
228
228
  a = EagerAlbum.eager(:track).all
229
229
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
230
230
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT * FROM tracks WHERE (1 = tracks.album_id) LIMIT 1 OFFSET 1) AS t1']
@@ -234,7 +234,7 @@ describe Sequel::Model, "#eager" do
234
234
 
235
235
  it "should handle offsets when using the :ruby eager limit stategy" do
236
236
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :eager_limit_strategy=>:ruby
237
- EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
237
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}])
238
238
  a = EagerAlbum.eager(:track).all
239
239
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
240
240
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
@@ -244,8 +244,8 @@ describe Sequel::Model, "#eager" do
244
244
 
245
245
  it "should support a :subqueries_per_union option for the number of subqueries in a union" do
246
246
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>1
247
- EagerAlbum.dataset._fetch = [{:id => 1, :band_id => 2}, {:id => 2, :band_id => 3}, {:id => 3, :band_id => 4}]
248
- EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}], [{:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]]
247
+ EagerAlbum.dataset = EagerAlbum.dataset.with_fetch([{:id => 1, :band_id => 2}, {:id => 2, :band_id => 3}, {:id => 3, :band_id => 4}])
248
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([[{:id => 4, :album_id=>1}], [{:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]])
249
249
  a = EagerAlbum.eager(:track).all
250
250
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
251
251
  DB.sqls.must_equal ['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']
@@ -253,7 +253,7 @@ describe Sequel::Model, "#eager" do
253
253
  DB.sqls.must_equal []
254
254
 
255
255
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>2
256
- EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]]
256
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}], [{:id=>6, :album_id=>3}]])
257
257
  a = EagerAlbum.eager(:track).all
258
258
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
259
259
  DB.sqls.must_equal ['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']
@@ -261,7 +261,7 @@ describe Sequel::Model, "#eager" do
261
261
  DB.sqls.must_equal []
262
262
 
263
263
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :subqueries_per_union=>3
264
- EagerTrack.dataset._fetch = [[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}, {:id=>6, :album_id=>3}]]
264
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([[{:id => 4, :album_id=>1}, {:id=>5, :album_id=>2}, {:id=>6, :album_id=>3}]])
265
265
  a = EagerAlbum.eager(:track).all
266
266
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2), EagerAlbum.load(:id => 2, :band_id => 3), EagerAlbum.load(:id => 3, :band_id => 4)]
267
267
  DB.sqls.must_equal ['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']
@@ -286,7 +286,7 @@ describe Sequel::Model, "#eager" do
286
286
  end
287
287
 
288
288
  it "should use first matching entry when eager loading one_through_one association" do
289
- EagerGenre.dataset._fetch = [{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}]
289
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}])
290
290
  a = EagerAlbum.eager(:genre).all
291
291
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
292
292
  DB.sqls.must_equal ['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))"]
@@ -304,7 +304,7 @@ describe Sequel::Model, "#eager" do
304
304
  end
305
305
 
306
306
  it "should eagerly load a single one_through_one association using the :distinct_on strategy" do
307
- def (EagerGenre.dataset).supports_distinct_on?() true end
307
+ EagerGenre.dataset = EagerGenre.dataset.with_extend{def supports_distinct_on?; true end}
308
308
  EagerAlbum.one_through_one :genre, :clone=>:genre, :order=>:a, :eager_limit_strategy=>:distinct_on
309
309
  a = EagerAlbum.eager(:genre).all
310
310
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -314,7 +314,7 @@ describe Sequel::Model, "#eager" do
314
314
  end
315
315
 
316
316
  it "should eagerly load a single one_through_one association using the :window_function strategy" do
317
- def (EagerGenre.dataset).supports_window_functions?() true end
317
+ EagerGenre.dataset = EagerGenre.dataset.with_extend{def supports_window_functions?; true end}
318
318
  EagerAlbum.one_through_one :genre, :clone=>:genre, :eager_limit_strategy=>:window_function
319
319
  a = EagerAlbum.eager(:genre).all
320
320
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -324,7 +324,7 @@ describe Sequel::Model, "#eager" do
324
324
  end
325
325
 
326
326
  it "should automatically use an eager limit stategy if the association has an offset" do
327
- EagerGenre.dataset._fetch = [{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}]
327
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:id => 3, :x_foreign_key_x=>1}, {:id => 4, :x_foreign_key_x=>1}])
328
328
  a = EagerAlbum.eager(:genre).all
329
329
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
330
330
  DB.sqls.must_equal ['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))"]
@@ -342,7 +342,7 @@ describe Sequel::Model, "#eager" do
342
342
 
343
343
  it "should support using a custom :key option when eager loading many_to_one associations" do
344
344
  EagerAlbum.many_to_one :sband, :clone=>:band, :key=>:band_id3
345
- EagerBand.dataset._fetch = {:id=>6}
345
+ EagerBand.dataset = EagerBand.dataset.with_fetch(:id=>6)
346
346
  a = EagerAlbum.eager(:sband).all
347
347
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (6))']
348
348
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -352,7 +352,7 @@ describe Sequel::Model, "#eager" do
352
352
 
353
353
  it "should support using a custom :primary_key option when eager loading one_to_many associations" do
354
354
  EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil, :reciprocal=>nil
355
- EagerBand.dataset._fetch = {:id=>6}
355
+ EagerBand.dataset = EagerBand.dataset.with_fetch(:id=>6)
356
356
  a = EagerBand.eager(:salbums).all
357
357
  DB.sqls.must_equal ['SELECT * FROM bands', 'SELECT * FROM albums WHERE (albums.band_id IN (2))']
358
358
  a.must_equal [EagerBand.load(:id => 6)]
@@ -362,7 +362,7 @@ describe Sequel::Model, "#eager" do
362
362
 
363
363
  it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
364
364
  EagerAlbum.many_to_many :sgenres, :clone=>:genres, :left_primary_key=>:band_id3
365
- EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
365
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch(:id=>4, :x_foreign_key_x=>6)
366
366
  a = EagerAlbum.eager(:sgenres).all
367
367
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
368
368
  DB.sqls.must_equal ['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))"]
@@ -372,7 +372,7 @@ describe Sequel::Model, "#eager" do
372
372
 
373
373
  it "should support using a custom :left_primary_key option when eager loading one_through_one associations" do
374
374
  EagerAlbum.one_through_one :sgenre, :clone=>:genre, :left_primary_key=>:band_id3
375
- EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
375
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch(:id=>4, :x_foreign_key_x=>6)
376
376
  a = EagerAlbum.eager(:sgenre).all
377
377
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
378
378
  DB.sqls.must_equal ['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))"]
@@ -382,7 +382,7 @@ describe Sequel::Model, "#eager" do
382
382
 
383
383
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_one associations" do
384
384
  EagerAlbum.many_to_one :sband, :clone=>:band, :eager_loading_predicate_key=>Sequel./(:bands__id, 3), :primary_key_method=>:id3
385
- EagerBand.dataset._fetch = {:id=>6}
385
+ EagerBand.dataset = EagerBand.dataset.with_fetch(:id=>6)
386
386
  a = EagerAlbum.eager(:sband).all
387
387
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM bands WHERE ((bands.id / 3) IN (2))']
388
388
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -392,7 +392,7 @@ describe Sequel::Model, "#eager" do
392
392
 
393
393
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_to_many associations" do
394
394
  EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil, :reciprocal=>nil
395
- EagerBand.dataset._fetch = {:id=>6}
395
+ EagerBand.dataset = EagerBand.dataset.with_fetch(:id=>6)
396
396
  a = EagerBand.eager(:salbums).all
397
397
  DB.sqls.must_equal ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
398
398
  a.must_equal [EagerBand.load(:id => 6)]
@@ -430,7 +430,7 @@ describe Sequel::Model, "#eager" do
430
430
  ds = EagerAlbum.eager(:sgenres)
431
431
  ds.all
432
432
  eo[:key_hash].must_equal({})
433
- eo[:id_map].must_equal nil
433
+ eo[:id_map].must_be_nil
434
434
  end
435
435
 
436
436
  it "should correctly handle a :select=>[] option to many_to_many" do
@@ -580,7 +580,9 @@ describe Sequel::Model, "#eager" do
580
580
  end
581
581
 
582
582
  it "should cascade eagerly loading when the :eager_graph association option is used" do
583
- EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
583
+ EagerAlbum.dataset = EagerAlbum.dataset.with_fetch(:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1)
584
+ EagerAlbum.dataset.columns(:id, :band_id)
585
+ EagerTrack.dataset.columns(:id, :album_id)
584
586
  a = EagerBand.eager(:graph_albums).all
585
587
  a.must_equal [EagerBand.load(:id=>2)]
586
588
  DB.sqls.must_equal ['SELECT * FROM bands',
@@ -599,7 +601,9 @@ describe Sequel::Model, "#eager" do
599
601
  a.must_equal [EagerBand.load(:id=>2)]
600
602
  DB.sqls.must_equal ['SELECT * FROM bands']
601
603
  a = a.first
602
- EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
604
+ EagerAlbum.dataset = EagerAlbum.dataset.with_fetch(:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1)
605
+ EagerAlbum.dataset.columns(:id, :band_id)
606
+ EagerTrack.dataset.columns(:id, :album_id)
603
607
  a.graph_albums
604
608
  DB.sqls.must_equal ['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)']
605
609
  a.graph_albums.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -608,10 +612,9 @@ describe Sequel::Model, "#eager" do
608
612
  end
609
613
 
610
614
  it "should respect :eager_graph when lazily loading a many_to_many association" do
611
- ds = EagerBandMember.dataset
612
- def ds.columns() [:id] end
613
- ds._fetch = [{:id=>5, :bands_id=>2, :p_k=>6}, {:id=>5, :bands_id=>3, :p_k=>6}]
615
+ EagerBandMember.dataset = EagerBandMember.dataset.with_fetch([{:id=>5, :bands_id=>2, :p_k=>6}, {:id=>5, :bands_id=>3, :p_k=>6}]).with_extend{def columns; [:id] end}
614
616
  a = EagerBand.load(:id=>2)
617
+ EagerBand.dataset.columns(:id, :p_k)
615
618
  a.graph_members.must_equal [EagerBandMember.load(:id=>5)]
616
619
  DB.sqls.must_equal ['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']
617
620
  a.graph_members.first.bands.must_equal [EagerBand.load(:id=>2, :p_k=>6), EagerBand.load(:id=>3, :p_k=>6)]
@@ -652,8 +655,8 @@ describe Sequel::Model, "#eager" do
652
655
  a = EagerAlbum.eager(:band).filter(:id=>101).all
653
656
  a.must_equal [EagerAlbum.load(:id => 101, :band_id => 101)]
654
657
  DB.sqls.must_equal ['SELECT * FROM albums WHERE (id = 101)', 'SELECT * FROM bands WHERE (bands.id IN (101))']
655
- a.first.associations.fetch(:band, 2).must_equal nil
656
- a.first.band.must_equal nil
658
+ a.first.associations.fetch(:band, 2).must_be_nil
659
+ a.first.band.must_be_nil
657
660
  DB.sqls.must_equal []
658
661
  end
659
662
 
@@ -695,7 +698,7 @@ describe Sequel::Model, "#eager" do
695
698
 
696
699
  it "should respect many_to_one association's :qualify option" do
697
700
  EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :qualify=>false, :key=>:band_id
698
- EagerBand.dataset._fetch = {:id=>2}
701
+ EagerBand.dataset = EagerBand.dataset.with_fetch(:id=>2)
699
702
  as = EagerAlbum.eager(:special_band).all
700
703
  DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM bands WHERE (id IN (2))"]
701
704
  as.map{|a| a.special_band}.must_equal [EagerBand.load(:id=>2)]
@@ -704,14 +707,14 @@ describe Sequel::Model, "#eager" do
704
707
 
705
708
  it "should respect the association's :primary_key option" do
706
709
  EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>:p_k, :key=>:band_id
707
- EagerBand.dataset._fetch = {:p_k=>2, :id=>1}
710
+ EagerBand.dataset = EagerBand.dataset.with_fetch(:p_k=>2, :id=>1)
708
711
  as = EagerAlbum.eager(:special_band).all
709
712
  DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM bands WHERE (bands.p_k IN (2))"]
710
713
  as.length.must_equal 1
711
714
  as.first.special_band.must_equal EagerBand.load(:p_k=>2, :id=>1)
712
715
 
713
716
  EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id, :reciprocal=>nil
714
- EagerTrack.dataset._fetch = {:album_id=>2, :id=>1}
717
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch(:album_id=>2, :id=>1)
715
718
  as = EagerAlbum.eager(:special_tracks).all
716
719
  DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
717
720
  as.length.must_equal 1
@@ -720,7 +723,7 @@ describe Sequel::Model, "#eager" do
720
723
 
721
724
  it "should respect the many_to_one association's composite keys" do
722
725
  EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>[:id, :p_k], :key=>[:band_id, :id]
723
- EagerBand.dataset._fetch = {:p_k=>1, :id=>2}
726
+ EagerBand.dataset = EagerBand.dataset.with_fetch(:p_k=>1, :id=>2)
724
727
  as = EagerAlbum.eager(:special_band).all
725
728
  DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM bands WHERE ((bands.id, bands.p_k) IN ((2, 1)))"]
726
729
  as.length.must_equal 1
@@ -729,7 +732,7 @@ describe Sequel::Model, "#eager" do
729
732
 
730
733
  it "should respect the one_to_many association's composite keys" do
731
734
  EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>[:band_id, :id], :key=>[:id, :album_id]
732
- EagerTrack.dataset._fetch = {:album_id=>1, :id=>2}
735
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch(:album_id=>1, :id=>2)
733
736
  as = EagerAlbum.eager(:special_tracks).all
734
737
  DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.id, tracks.album_id) IN ((2, 1)))"]
735
738
  as.length.must_equal 1
@@ -738,7 +741,7 @@ describe Sequel::Model, "#eager" do
738
741
 
739
742
  it "should respect many_to_many association's composite keys" do
740
743
  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
741
- 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}]
744
+ EagerGenre.dataset = EagerGenre.dataset.with_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}])
742
745
  as = EagerAlbum.eager(:special_genres).all
743
746
  DB.sqls.must_equal ['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)))"]
744
747
  as.length.must_equal 1
@@ -747,7 +750,7 @@ describe Sequel::Model, "#eager" do
747
750
 
748
751
  it "should respect one_through_one association's composite keys" do
749
752
  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
750
- EagerGenre.dataset._fetch = [{:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5}]
753
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5}])
751
754
  as = EagerAlbum.eager(:special_genre).all
752
755
  DB.sqls.must_equal ['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)))"]
753
756
  as.length.must_equal 1
@@ -756,7 +759,7 @@ describe Sequel::Model, "#eager" do
756
759
 
757
760
  it "should respect many_to_many association's :left_primary_key and :right_primary_key options" do
758
761
  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
759
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
762
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}])
760
763
  as = EagerAlbum.eager(:special_genres).all
761
764
  DB.sqls.must_equal ['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))"]
762
765
  as.length.must_equal 1
@@ -765,7 +768,7 @@ describe Sequel::Model, "#eager" do
765
768
 
766
769
  it "should respect one_through_one association's :left_primary_key and :right_primary_key options" do
767
770
  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
768
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
771
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}])
769
772
  as = EagerAlbum.eager(:special_genre).all
770
773
  DB.sqls.must_equal ['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))"]
771
774
  as.length.must_equal 1
@@ -774,7 +777,7 @@ describe Sequel::Model, "#eager" do
774
777
 
775
778
  it "should respect the :limit option on a one_to_many association using the :ruby strategy" do
776
779
  EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2, :eager_limit_strategy=>:ruby
777
- EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2}, {:album_id=>1, :id=>3}, {:album_id=>1, :id=>4}]
780
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([{:album_id=>1, :id=>2}, {:album_id=>1, :id=>3}, {:album_id=>1, :id=>4}])
778
781
  as = EagerAlbum.eager(:first_two_tracks).all
779
782
  DB.sqls.must_equal ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
780
783
  as.length.must_equal 1
@@ -828,7 +831,7 @@ describe Sequel::Model, "#eager" do
828
831
  end
829
832
 
830
833
  it "should respect the :limit option on a one_to_many association using the :window_function strategy" do
831
- def (EagerTrack.dataset).supports_window_functions?() true end
834
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_window_functions?; true end}
832
835
  EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2, :eager_limit_strategy=>:window_function
833
836
  a = EagerAlbum.eager(:tracks).all
834
837
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -854,7 +857,8 @@ describe Sequel::Model, "#eager" do
854
857
  it "should use a ruby strategy for limit if :eager_graph option is used" do
855
858
  EagerTrack.many_to_one :album2, :clone=>:album
856
859
  EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2, :eager_graph=>:album2
857
- 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}]
860
+ EagerTrack.dataset = EagerTrack.dataset.with_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}])
861
+ EagerTrack.dataset.columns(:id, :album_id)
858
862
  as = EagerAlbum.eager(:first_two_tracks).all
859
863
  DB.sqls.must_equal ['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))"]
860
864
  as.length.must_equal 1
@@ -865,7 +869,7 @@ describe Sequel::Model, "#eager" do
865
869
  end
866
870
 
867
871
  it "should not use a union strategy for limit by default if providing a per-eager load callback" do
868
- def (EagerTrack.dataset).supports_window_functions?() true end
872
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_window_functions?; true end}
869
873
  EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2
870
874
  a = EagerAlbum.eager(:tracks=>proc{|ds| ds.where(:id=>3)}).all
871
875
  a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -876,20 +880,20 @@ describe Sequel::Model, "#eager" do
876
880
 
877
881
  it "should respect the limit option on a many_to_many association using the :ruby strategy" do
878
882
  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
879
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
883
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}])
880
884
  as = EagerAlbum.eager(:first_two_genres).all
881
885
  DB.sqls.must_equal ['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))"]
882
886
  as.length.must_equal 1
883
887
  as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
884
888
 
885
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
889
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}])
886
890
  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
887
891
  as = EagerAlbum.eager(:first_two_genres).all
888
892
  DB.sqls.must_equal ['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))"]
889
893
  as.length.must_equal 1
890
894
  as.first.first_two_genres.must_equal [EagerGenre.load(:id=>6)]
891
895
 
892
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
896
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}])
893
897
  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
894
898
  as = EagerAlbum.eager(:first_two_genres).all
895
899
  DB.sqls.must_equal ['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))"]
@@ -898,22 +902,21 @@ describe Sequel::Model, "#eager" do
898
902
  end
899
903
 
900
904
  it "should respect the limit option on a many_to_many association" do
901
- def (EagerGenre.dataset).supports_window_functions?() true end
905
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]).with_extend{def supports_window_functions?; true end}
902
906
  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
903
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
904
907
  as = EagerAlbum.eager(:first_two_genres).all
905
908
  DB.sqls.must_equal ['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"]
906
909
  as.length.must_equal 1
907
910
  as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
908
911
 
909
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
912
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}])
910
913
  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
911
914
  as = EagerAlbum.eager(:first_two_genres).all
912
915
  DB.sqls.must_equal ['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"]
913
916
  as.length.must_equal 1
914
917
  as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5)]
915
918
 
916
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
919
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}])
917
920
  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
918
921
  as = EagerAlbum.eager(:first_two_genres).all
919
922
  DB.sqls.must_equal ['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"]
@@ -922,22 +925,21 @@ describe Sequel::Model, "#eager" do
922
925
  end
923
926
 
924
927
  it "should respect the limit option on a many_to_many association using the :window_function strategy" do
925
- def (EagerGenre.dataset).supports_window_functions?() true end
928
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]).with_extend{def supports_window_functions?; true end}
926
929
  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
927
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
928
930
  as = EagerAlbum.eager(:first_two_genres).all
929
931
  DB.sqls.must_equal ['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)"]
930
932
  as.length.must_equal 1
931
933
  as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
932
934
 
933
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
935
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}])
934
936
  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
935
937
  as = EagerAlbum.eager(:first_two_genres).all
936
938
  DB.sqls.must_equal ['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))"]
937
939
  as.length.must_equal 1
938
940
  as.first.first_two_genres.must_equal [EagerGenre.load(:id=>5)]
939
941
 
940
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
942
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}])
941
943
  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
942
944
  as = EagerAlbum.eager(:first_two_genres).all
943
945
  DB.sqls.must_equal ['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)"]
@@ -985,7 +987,7 @@ describe Sequel::Model, "#eager" do
985
987
 
986
988
  it "should respect :uniq option when eagerly loading many_to_many associations" do
987
989
  EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :uniq=>true
988
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>1, :id=>8}, {:x_foreign_key_x=>1, :id=>8}]
990
+ EagerGenre.dataset = EagerGenre.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>8}, {:x_foreign_key_x=>1, :id=>8}])
989
991
  a = EagerAlbum.eager(:al_genres).all.first
990
992
  DB.sqls.must_equal ['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))"]
991
993
  a.must_equal EagerAlbum.load(:id => 1, :band_id => 2)
@@ -1082,8 +1084,8 @@ describe Sequel::Model, "#eager" do
1082
1084
  end
1083
1085
 
1084
1086
  it "should allow cascading of eager loading with custom callback with symbol value when association has a limit" do
1085
- EagerAlbum.dataset._fetch = (1..11).map{|i| {:band_id=>2, :id=>i}}
1086
- EagerTrack.dataset._fetch = [{:id=>3, :album_id=>1}]
1087
+ EagerAlbum.dataset = EagerAlbum.dataset.with_fetch((1..11).map{|i| {:band_id=>2, :id=>i}})
1088
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([{:id=>3, :album_id=>1}])
1087
1089
  a = EagerBand.eager(:top_10_albums=>{proc{|ds| ds.select(:id, :name)}=>:tracks}).all
1088
1090
  a.must_equal [EagerBand.load(:id => 2)]
1089
1091
  sqls = DB.sqls
@@ -1096,9 +1098,8 @@ describe Sequel::Model, "#eager" do
1096
1098
  end
1097
1099
 
1098
1100
  it "should allow cascading of eager loading with custom callback with symbol value when association has a limit when using window function eager limit strategy" do
1099
- def (EagerAlbum.dataset).supports_window_functions?() true end
1100
- EagerAlbum.dataset._fetch = {:band_id=>2, :id=>1}
1101
- EagerTrack.dataset._fetch = [{:id=>3, :album_id=>1}]
1101
+ EagerAlbum.dataset = EagerAlbum.dataset.with_fetch(:band_id=>2, :id=>1).with_extend{def supports_window_functions?; true end}
1102
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch([{:id=>3, :album_id=>1}])
1102
1103
  a = EagerBand.eager(:top_10_albums=>{proc{|ds| ds.select(:id, :name)}=>:tracks}).all
1103
1104
  a.must_equal [EagerBand.load(:id => 2)]
1104
1105
  DB.sqls.must_equal ['SELECT * FROM bands',
@@ -1131,8 +1132,7 @@ describe Sequel::Model, "#eager" do
1131
1132
  end
1132
1133
 
1133
1134
  it "should respect an :eager_limit option passed in a custom callback" do
1134
- # Should default to a window function on its own.
1135
- def (EagerTrack.dataset).supports_window_functions?() true end
1135
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_window_functions?; true end}
1136
1136
  a = EagerAlbum.eager(:tracks=> proc{|ds| ds.clone(:eager_limit=>5)}).all
1137
1137
  a.must_equal [EagerAlbum.load(:id => 1, :band_id=> 2)]
1138
1138
  sqls = DB.sqls
@@ -1143,21 +1143,20 @@ describe Sequel::Model, "#eager" do
1143
1143
  end
1144
1144
 
1145
1145
  it "should respect an :eager_limit option that includes an offset" do
1146
- def (EagerTrack.dataset).supports_window_functions?() true end
1146
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_window_functions?; true end}
1147
1147
  EagerAlbum.eager(:tracks=> proc{|ds| ds.clone(:eager_limit=>[5, 5])}).all
1148
1148
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE ((x_sequel_row_number_x >= 6) AND (x_sequel_row_number_x < 11))']
1149
1149
  end
1150
1150
 
1151
1151
  it "should have an :eager_limit option passed in a custom callback override a :limit defined in the association" do
1152
- def (EagerTrack.dataset).supports_window_functions?() true end
1152
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_window_functions?; true end}
1153
1153
  EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2
1154
1154
  EagerAlbum.eager(:first_two_tracks=> proc{|ds| ds.clone(:eager_limit=>5)}).all
1155
1155
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x <= 5)']
1156
1156
  end
1157
1157
 
1158
1158
  it "should respect an :eager_limit_strategy option passed in a custom callback" do
1159
- def (EagerTrack.dataset).supports_window_functions?() true end
1160
- EagerTrack.dataset._fetch = (1..4).map{|i| {:album_id=>1, :id=>i}}
1159
+ EagerTrack.dataset = EagerTrack.dataset.with_fetch((1..4).map{|i| {:album_id=>1, :id=>i}}).with_extend{def supports_window_functions?; true end}
1161
1160
  a = EagerAlbum.eager(:tracks=> proc{|ds| ds.clone(:eager_limit=>2, :eager_limit_strategy=>:ruby)}).all
1162
1161
  a.must_equal [EagerAlbum.load(:id => 1, :band_id=> 2)]
1163
1162
  sqls = DB.sqls
@@ -1168,17 +1167,32 @@ describe Sequel::Model, "#eager" do
1168
1167
  end
1169
1168
 
1170
1169
  it "should have an :eager_limit_strategy option passed in a custom callback override a :eager_limit_strategy defined in the association" do
1171
- def (EagerTrack.dataset).supports_window_functions?() true end
1170
+ EagerTrack.dataset = EagerTrack.dataset.with_extend{def supports_window_functions?; true end}
1172
1171
  EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2, :eager_limit_strategy=>:ruby
1173
1172
  EagerAlbum.eager(:first_two_tracks=> proc{|ds| ds.clone(:eager_limit_strategy=>:window_function)}).all
1174
1173
  DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
1175
1174
  end
1175
+
1176
+ it "should raise error if using :eager_limit for a singular association" do
1177
+ EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
1178
+ proc{EagerAlbum.eager(:track=> proc{|ds| ds.clone(:eager_limit=>1)}).all}.must_raise Sequel::Error
1179
+ DB.sqls.must_equal ['SELECT * FROM albums']
1180
+ end
1181
+
1182
+ it "should raise error if using :eager_limit for a singular association" do
1183
+ EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:name
1184
+ a = EagerAlbum.eager(:track=> proc{|ds| ds.order(:foo)}).all
1185
+ DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1)) ORDER BY foo']
1186
+ a = a.first
1187
+ a.track.must_equal EagerTrack.load(:id => 3, :album_id => 1)
1188
+ DB.sqls.must_equal []
1189
+ end
1190
+
1176
1191
  end
1177
1192
 
1178
1193
  describe Sequel::Model, "#eager_graph" do
1179
1194
  before(:all) do
1180
1195
  class ::GraphAlbum < Sequel::Model(:albums)
1181
- dataset.opts[:from] = [:albums]
1182
1196
  columns :id, :band_id
1183
1197
  many_to_one :band, :class=>'GraphBand', :key=>:band_id
1184
1198
  one_to_many :tracks, :class=>'GraphTrack', :key=>:album_id
@@ -1189,7 +1203,6 @@ describe Sequel::Model, "#eager_graph" do
1189
1203
  end
1190
1204
 
1191
1205
  class ::GraphBand < Sequel::Model(:bands)
1192
- dataset.opts[:from] = [:bands]
1193
1206
  columns :id, :vocalist_id
1194
1207
  many_to_one :vocalist, :class=>'GraphBandMember', :key=>:vocalist_id
1195
1208
  one_to_many :albums, :class=>'GraphAlbum', :key=>:band_id
@@ -1198,19 +1211,16 @@ describe Sequel::Model, "#eager_graph" do
1198
1211
  end
1199
1212
 
1200
1213
  class ::GraphTrack < Sequel::Model(:tracks)
1201
- dataset.opts[:from] = [:tracks]
1202
1214
  columns :id, :album_id
1203
1215
  many_to_one :album, :class=>'GraphAlbum', :key=>:album_id
1204
1216
  end
1205
1217
 
1206
1218
  class ::GraphGenre < Sequel::Model(:genres)
1207
- dataset.opts[:from] = [:genres]
1208
1219
  columns :id
1209
1220
  many_to_many :albums, :class=>'GraphAlbum', :left_key=>:genre_id, :right_key=>:album_id, :join_table=>:ag
1210
1221
  end
1211
1222
 
1212
1223
  class ::GraphBandMember < Sequel::Model(:members)
1213
- dataset.opts[:from] = [:members]
1214
1224
  columns :id
1215
1225
  many_to_many :bands, :class=>'GraphBand', :left_key=>:member_id, :right_key=>:band_id, :join_table=>:bm
1216
1226
  end
@@ -1228,26 +1238,22 @@ describe Sequel::Model, "#eager_graph" do
1228
1238
 
1229
1239
  it "should work correctly with select_map" do
1230
1240
  ds = GraphAlbum.eager_graph(:band)
1231
- ds._fetch = [{:id=>1}, {:id=>2}]
1232
- ds.select_map(:albums__id).must_equal [1, 2]
1241
+ ds.with_fetch([{:id=>1}, {:id=>2}]).select_map(:albums__id).must_equal [1, 2]
1233
1242
  DB.sqls.must_equal ['SELECT albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)']
1234
- ds._fetch = [{:id=>1}, {:id=>2}]
1235
- ds.select_map([:albums__id, :albums__id]).must_equal [[1, 1], [2, 2]]
1243
+ ds.with_fetch([{:id=>1}, {:id=>2}]).select_map([:albums__id, :albums__id]).must_equal [[1, 1], [2, 2]]
1236
1244
  DB.sqls.must_equal ['SELECT albums.id, albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)']
1237
1245
  end
1238
1246
 
1239
1247
  it "should work correctly with single_value" do
1240
1248
  ds = GraphAlbum.eager_graph(:band).select(:albums__id)
1241
- ds._fetch = [{:id=>1}]
1242
- ds.single_value.must_equal 1
1249
+ ds.with_fetch([{:id=>1}]).single_value.must_equal 1
1243
1250
  DB.sqls.must_equal ['SELECT albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) LIMIT 1']
1244
1251
  end
1245
1252
 
1246
1253
  it "should not split results and assign associations if ungraphed is called" do
1247
1254
  ds = GraphAlbum.eager_graph(:band).ungraphed
1248
1255
  ds.sql.must_equal '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)'
1249
- ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
1250
- ds.all.must_equal [GraphAlbum.load(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)]
1256
+ ds.with_fetch(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3).all.must_equal [GraphAlbum.load(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)]
1251
1257
  end
1252
1258
 
1253
1259
  it "should not modify existing dataset" do
@@ -1261,8 +1267,7 @@ describe Sequel::Model, "#eager_graph" do
1261
1267
  it "should allow manually selecting the alias base per call via an AliasedExpression" do
1262
1268
  ds = GraphAlbum.eager_graph(Sequel.as(:band, :b))
1263
1269
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, b.id AS b_id, b.vocalist_id FROM albums LEFT OUTER JOIN bands AS b ON (b.id = albums.band_id)'
1264
- ds._fetch = {:id=>1, :band_id=>2, :b_id=>2, :vocalist_id=>3}
1265
- a = ds.all
1270
+ a = ds.with_fetch(:id=>1, :band_id=>2, :b_id=>2, :vocalist_id=>3).all
1266
1271
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1267
1272
  a.first.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>3)
1268
1273
  end
@@ -1270,8 +1275,7 @@ describe Sequel::Model, "#eager_graph" do
1270
1275
  it "should handle multiple associations using the same alias base" do
1271
1276
  ds = GraphAlbum.eager_graph(Sequel.as(:genres, :b), Sequel.as(:tracks, :b), Sequel.as(:band, :b))
1272
1277
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, b.id AS b_id, b_0.id AS b_0_id, b_0.album_id, b_1.id AS b_1_id, b_1.vocalist_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS b ON (b.id = ag.genre_id) LEFT OUTER JOIN tracks AS b_0 ON (b_0.album_id = albums.id) LEFT OUTER JOIN bands AS b_1 ON (b_1.id = albums.band_id)'
1273
- ds._fetch = {:id=>1, :band_id=>2, :b_id=>4, :b_0_id=>3, :album_id=>1, :b_1_id=>2, :vocalist_id=>6}
1274
- a = ds.all
1278
+ a = ds.with_fetch(:id=>1, :band_id=>2, :b_id=>4, :b_0_id=>3, :album_id=>1, :b_1_id=>2, :vocalist_id=>6).all
1275
1279
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1276
1280
  a = a.first
1277
1281
  a.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
@@ -1280,8 +1284,7 @@ describe Sequel::Model, "#eager_graph" do
1280
1284
 
1281
1285
  ds = GraphTrack.eager_graph(Sequel.as(:album, :b)=>{Sequel.as(:band, :b)=>Sequel.as(:members, :b)})
1282
1286
  ds.sql.must_equal 'SELECT tracks.id, tracks.album_id, b.id AS b_id, b.band_id, b_0.id AS b_0_id, b_0.vocalist_id, b_1.id AS b_1_id FROM tracks LEFT OUTER JOIN albums AS b ON (b.id = tracks.album_id) LEFT OUTER JOIN bands AS b_0 ON (b_0.id = b.band_id) LEFT OUTER JOIN bm ON (bm.band_id = b_0.id) LEFT OUTER JOIN members AS b_1 ON (b_1.id = bm.member_id)'
1283
- ds._fetch = {:id=>3, :album_id=>1, :b_id=>1, :band_id=>2, :b_1_id=>5, :b_0_id=>2, :vocalist_id=>6}
1284
- a = ds.all
1287
+ a = ds.with_fetch(:id=>3, :album_id=>1, :b_id=>1, :band_id=>2, :b_1_id=>5, :b_0_id=>2, :vocalist_id=>6).all
1285
1288
  a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
1286
1289
  a = a.first
1287
1290
  a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
@@ -1315,8 +1318,7 @@ describe Sequel::Model, "#eager_graph" do
1315
1318
  it "should eagerly load a single many_to_one association" do
1316
1319
  ds = GraphAlbum.eager_graph(:band)
1317
1320
  ds.sql.must_equal '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)'
1318
- ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
1319
- a = ds.all
1321
+ a = ds.with_fetch(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3).all
1320
1322
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1321
1323
  a.first.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>3)
1322
1324
  end
@@ -1326,8 +1328,7 @@ describe Sequel::Model, "#eager_graph" do
1326
1328
  GraphAlbum.many_to_one :band_id, :key_column=>:band_id, :class=>GraphBand
1327
1329
  ds = GraphAlbum.eager_graph(:band_id)
1328
1330
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, band_id.id AS band_id_id, band_id.vocalist_id FROM albums LEFT OUTER JOIN bands AS band_id ON (band_id.id = albums.band_id)'
1329
- ds._fetch = {:id=>1, :band_id=>2, :band_id_id=>2, :vocalist_id=>3}
1330
- a = ds.all
1331
+ a = ds.with_fetch(:id=>1, :band_id=>2, :band_id_id=>2, :vocalist_id=>3).all
1331
1332
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1332
1333
  a.first.band_id.must_equal GraphBand.load(:id => 2, :vocalist_id=>3)
1333
1334
  end
@@ -1335,8 +1336,7 @@ describe Sequel::Model, "#eager_graph" do
1335
1336
  it "should support :join_type eager_graph option one_to_one association" do
1336
1337
  ds = GraphAlbum.eager_graph_with_options(:track, :join_type=>:inner)
1337
1338
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, track.id AS track_id, track.album_id FROM albums INNER JOIN tracks AS track ON (track.album_id = albums.id)'
1338
- ds._fetch = {:id=>1, :band_id=>2, :track_id=>3, :album_id=>1}
1339
- a = ds.all
1339
+ a = ds.with_fetch(:id=>1, :band_id=>2, :track_id=>3, :album_id=>1).all
1340
1340
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1341
1341
  a.first.track.must_equal GraphTrack.load(:id => 3, :album_id=>1)
1342
1342
  end
@@ -1344,47 +1344,49 @@ describe Sequel::Model, "#eager_graph" do
1344
1344
  it "should eagerly load a single one_to_one association" do
1345
1345
  ds = GraphAlbum.eager_graph(:track)
1346
1346
  ds.sql.must_equal '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)'
1347
- ds._fetch = {:id=>1, :band_id=>2, :track_id=>3, :album_id=>1}
1348
- a = ds.all
1347
+ a = ds.with_fetch(:id=>1, :band_id=>2, :track_id=>3, :album_id=>1).all
1349
1348
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1350
1349
  a.first.track.must_equal GraphTrack.load(:id => 3, :album_id=>1)
1351
1350
  end
1352
1351
 
1353
1352
  it "should eagerly graph a single one_to_one association using the :distinct_on strategy" do
1354
1353
  sub = Class.new(GraphTrack)
1355
- def (sub.dataset).supports_distinct_on?() true end
1356
- def (sub.dataset).columns() [:id, :album_id] end
1354
+ sub.dataset = sub.dataset.with_extend do
1355
+ def supports_distinct_on?; true end
1356
+ def columns; [:id, :album_id] end
1357
+ end
1357
1358
  GraphAlbum.one_to_one :ltrack, :clone=>:track, :class=>sub
1358
1359
  ds = GraphAlbum.eager_graph_with_options(:ltrack, :limit_strategy=>true)
1359
1360
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, ltrack.id AS ltrack_id, ltrack.album_id FROM albums LEFT OUTER JOIN (SELECT DISTINCT ON (tracks.album_id) * FROM tracks ORDER BY tracks.album_id) AS ltrack ON (ltrack.album_id = albums.id)'
1360
- ds._fetch = {:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1}
1361
- a = ds.all
1361
+ a = ds.with_fetch(:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1).all
1362
1362
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1363
1363
  a.first.ltrack.must_equal sub.load(:id => 3, :album_id=>1)
1364
1364
  end
1365
1365
 
1366
1366
  it "should eagerly graph a single one_to_one association using the :window_function strategy" do
1367
1367
  sub = Class.new(GraphTrack)
1368
- def (sub.dataset).supports_window_functions?() true end
1369
- def (sub.dataset).columns() [:id, :album_id] end
1368
+ sub.dataset = sub.dataset.with_extend do
1369
+ def supports_window_functions?; true end
1370
+ def columns; [:id, :album_id] end
1371
+ end
1370
1372
  GraphAlbum.one_to_one :ltrack, :clone=>:track, :class=>sub
1371
1373
  ds = GraphAlbum.eager_graph_with_options(:ltrack, :limit_strategy=>true)
1372
1374
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, ltrack.id AS ltrack_id, ltrack.album_id FROM albums LEFT OUTER JOIN (SELECT id, album_id FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id) AS x_sequel_row_number_x FROM tracks) AS t1 WHERE (x_sequel_row_number_x = 1)) AS ltrack ON (ltrack.album_id = albums.id)'
1373
- ds._fetch = {:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1}
1374
- a = ds.all
1375
+ a = ds.with_fetch(:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1).all
1375
1376
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1376
1377
  a.first.ltrack.must_equal sub.load(:id => 3, :album_id=>1)
1377
1378
  end
1378
1379
 
1379
1380
  it "should eagerly graph a single one_to_one association using the :correlated_subquery strategy" do
1380
1381
  sub = Class.new(GraphTrack)
1381
- def (sub.dataset).supports_window_functions?() true end
1382
- def (sub.dataset).columns() [:id, :album_id] end
1382
+ sub.dataset = sub.dataset.with_extend do
1383
+ def supports_window_functions?; true end
1384
+ def columns; [:id, :album_id] end
1385
+ end
1383
1386
  GraphAlbum.one_to_one :ltrack, :clone=>:track, :class=>sub
1384
1387
  ds = GraphAlbum.eager_graph_with_options(:ltrack, :limit_strategy=>:correlated_subquery)
1385
1388
  ds.sql.must_equal '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)'
1386
- ds._fetch = {:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1}
1387
- a = ds.all
1389
+ a = ds.with_fetch(:id=>1, :band_id=>2, :ltrack_id=>3, :album_id=>1).all
1388
1390
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1389
1391
  a.first.ltrack.must_equal sub.load(:id => 3, :album_id=>1)
1390
1392
  end
@@ -1392,21 +1394,21 @@ describe Sequel::Model, "#eager_graph" do
1392
1394
  it "should eagerly load a single one_to_many association" do
1393
1395
  ds = GraphAlbum.eager_graph(:tracks)
1394
1396
  ds.sql.must_equal '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)'
1395
- ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
1396
- a = ds.all
1397
+ a = ds.with_fetch(:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1).all
1397
1398
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1398
1399
  a.first.tracks.must_equal [GraphTrack.load(:id => 3, :album_id=>1)]
1399
1400
  end
1400
1401
 
1401
1402
  it "should eagerly graph a single one_to_many association using the :window_function strategy" do
1402
1403
  sub = Class.new(GraphTrack)
1403
- def (sub.dataset).supports_window_functions?() true end
1404
- def (sub.dataset).columns() [:id, :album_id] end
1404
+ sub.dataset = sub.dataset.with_extend do
1405
+ def supports_window_functions?; true end
1406
+ def columns; [:id, :album_id] end
1407
+ end
1405
1408
  GraphAlbum.one_to_many :ltracks, :clone=>:tracks, :limit=>2, :class=>sub
1406
1409
  ds = GraphAlbum.eager_graph_with_options(:ltracks, :limit_strategy=>true)
1407
1410
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, ltracks.id AS ltracks_id, ltracks.album_id FROM albums LEFT OUTER JOIN (SELECT id, album_id FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id) AS x_sequel_row_number_x FROM tracks) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS ltracks ON (ltracks.album_id = albums.id)'
1408
- ds._fetch = {:id=>1, :band_id=>2, :ltracks_id=>3, :album_id=>1}
1409
- a = ds.all
1411
+ a = ds.with_fetch(:id=>1, :band_id=>2, :ltracks_id=>3, :album_id=>1).all
1410
1412
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1411
1413
  a.first.ltracks.must_equal [sub.load(:id => 3, :album_id=>1)]
1412
1414
  end
@@ -1414,21 +1416,21 @@ describe Sequel::Model, "#eager_graph" do
1414
1416
  it "should eagerly load a single many_to_many association" do
1415
1417
  ds = GraphAlbum.eager_graph(:genres)
1416
1418
  ds.sql.must_equal '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)'
1417
- ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4}
1418
- a = ds.all
1419
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genres_id=>4).all
1419
1420
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1420
1421
  a.first.genres.must_equal [GraphGenre.load(:id => 4)]
1421
1422
  end
1422
1423
 
1423
1424
  it "should eagerly graph a single many_to_many association using the :window_function strategy" do
1424
1425
  sub = Class.new(GraphGenre)
1425
- def (sub.dataset).supports_window_functions?() true end
1426
- def (sub.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1426
+ sub.dataset = sub.dataset.with_extend do
1427
+ def supports_window_functions?; true end
1428
+ def columns; literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1429
+ end
1427
1430
  GraphAlbum.many_to_many :lgenres, :clone=>:genres, :class=>sub, :limit=>2
1428
1431
  ds = GraphAlbum.eager_graph_with_options(:lgenres, :limit_strategy=>true)
1429
1432
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenres.id AS lgenres_id FROM albums LEFT OUTER JOIN (SELECT id, x_foreign_key_x 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)) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS lgenres ON (lgenres.x_foreign_key_x = albums.id)'
1430
- ds._fetch = {:id=>1, :band_id=>2, :lgenres_id=>4}
1431
- a = ds.all
1433
+ a = ds.with_fetch(:id=>1, :band_id=>2, :lgenres_id=>4).all
1432
1434
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1433
1435
  a.first.lgenres.must_equal [sub.load(:id => 4)]
1434
1436
  end
@@ -1436,38 +1438,47 @@ describe Sequel::Model, "#eager_graph" do
1436
1438
  it "should eagerly load a single one_through_one association" do
1437
1439
  ds = GraphAlbum.eager_graph(:genre)
1438
1440
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genre ON (genre.id = ag.genre_id)'
1439
- ds._fetch = {:id=>1, :band_id=>2, :genre_id=>4}
1440
- a = ds.all
1441
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genre_id=>4).all
1441
1442
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1442
1443
  a.first.genre.must_equal GraphGenre.load(:id => 4)
1443
1444
  end
1444
1445
 
1445
1446
  it "should eagerly graph a single one_through_one association using the :distinct_on strategy" do
1446
1447
  sub = Class.new(GraphGenre)
1447
- def (sub.dataset).supports_distinct_on?() true end
1448
- def (sub.dataset).columns() [:id] end
1448
+ sub.dataset = sub.dataset.with_extend do
1449
+ def supports_distinct_on?; true end
1450
+ def columns; [:id] end
1451
+ end
1449
1452
  GraphAlbum.one_through_one :lgenre, :clone=>:genre, :class=>sub
1450
1453
  ds = GraphAlbum.eager_graph_with_options(:lgenre, :limit_strategy=>true)
1451
1454
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenre.id AS lgenre_id FROM albums LEFT OUTER JOIN (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) ORDER BY ag.album_id) AS lgenre ON (lgenre.x_foreign_key_x = albums.id)'
1452
- ds._fetch = {:id=>1, :band_id=>2, :lgenre_id=>4}
1453
- a = ds.all
1455
+ a = ds.with_fetch(:id=>1, :band_id=>2, :lgenre_id=>4).all
1454
1456
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1455
1457
  a.first.lgenre.must_equal sub.load(:id => 4)
1456
1458
  end
1457
1459
 
1458
1460
  it "should eagerly graph a single one_through_one association using the :window_function strategy" do
1459
1461
  sub = Class.new(GraphGenre)
1460
- def (sub.dataset).supports_window_functions?() true end
1461
- def (sub.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1462
+ sub.dataset = sub.dataset.with_extend do
1463
+ def supports_window_functions?; true end
1464
+ def columns; literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1465
+ end
1462
1466
  GraphAlbum.one_through_one :lgenre, :clone=>:genre, :class=>sub
1463
1467
  ds = GraphAlbum.eager_graph_with_options(:lgenre, :limit_strategy=>true)
1464
1468
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenre.id AS lgenre_id FROM albums LEFT OUTER JOIN (SELECT id, x_foreign_key_x 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)) AS t1 WHERE (x_sequel_row_number_x = 1)) AS lgenre ON (lgenre.x_foreign_key_x = albums.id)'
1465
- ds._fetch = {:id=>1, :band_id=>2, :lgenre_id=>4}
1466
- a = ds.all
1469
+ a = ds.with_fetch(:id=>1, :band_id=>2, :lgenre_id=>4).all
1467
1470
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1468
1471
  a.first.lgenre.must_equal sub.load(:id => 4)
1469
1472
  end
1470
1473
 
1474
+ it "should correctly handle an aliased join table in many_to_many and one_through_one" do
1475
+ c = Class.new(GraphAlbum)
1476
+ c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___ga, :conditions=>'true', :ignore_conditions_warning=> true
1477
+ c.eager_graph(:genres).sql.must_equal '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)'
1478
+ c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___ga, :conditions=>'true', :graph_block => proc{true}
1479
+ c.eager_graph(:genres).sql.must_equal '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) AND \'t\')'
1480
+ end
1481
+
1471
1482
  it "should correctly handle an aliased join table in many_to_many and one_through_one" do
1472
1483
  c = Class.new(GraphAlbum)
1473
1484
  c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___ga
@@ -1490,8 +1501,7 @@ describe Sequel::Model, "#eager_graph" do
1490
1501
  it "should eagerly load multiple associations in a single call" do
1491
1502
  ds = GraphAlbum.eager_graph(:genres, :tracks, :band)
1492
1503
  ds.sql.must_equal '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)'
1493
- ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6}
1494
- a = ds.all
1504
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6).all
1495
1505
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1496
1506
  a = a.first
1497
1507
  a.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
@@ -1501,16 +1511,17 @@ describe Sequel::Model, "#eager_graph" do
1501
1511
 
1502
1512
  it "should eagerly load multiple associations with different limit strategies in a single call" do
1503
1513
  subg = Class.new(GraphGenre)
1504
- def (subg.dataset).supports_distinct_on?() true end
1505
- def (subg.dataset).supports_window_functions?() true end
1506
- def (subg.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1514
+ subg.dataset = subg.dataset.with_extend do
1515
+ def supports_distinct_on?; true end
1516
+ def supports_window_functions?; true end
1517
+ def columns; literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1518
+ end
1507
1519
  GraphAlbum.one_through_one :lgenre, :clone=>:genre, :class=>subg
1508
1520
  GraphAlbum.many_to_many :lgenres, :clone=>:genres, :class=>subg, :limit=>2
1509
1521
 
1510
1522
  ds = GraphAlbum.eager_graph_with_options([:lgenre, :lgenres], :limit_strategy=>{:lgenre=>:distinct_on, :lgenres=>:window_function})
1511
1523
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, lgenre.id AS lgenre_id, lgenres.id AS lgenres_id FROM albums LEFT OUTER JOIN (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) ORDER BY ag.album_id) AS lgenre ON (lgenre.x_foreign_key_x = albums.id) LEFT OUTER JOIN (SELECT id, x_foreign_key_x 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)) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS lgenres ON (lgenres.x_foreign_key_x = albums.id)'
1512
- ds._fetch = {:id=>1, :band_id=>2, :lgenres_id=>4, :lgenre_id=>3}
1513
- a = ds.all
1524
+ a = ds.with_fetch(:id=>1, :band_id=>2, :lgenres_id=>4, :lgenre_id=>3).all
1514
1525
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1515
1526
  a = a.first
1516
1527
  a.lgenre.must_equal subg.load(:id => 3)
@@ -1524,8 +1535,7 @@ describe Sequel::Model, "#eager_graph" do
1524
1535
  it "should eagerly load multiple associations in separate calls" do
1525
1536
  ds = GraphAlbum.eager_graph(:genres).eager_graph(:tracks).eager_graph(:band)
1526
1537
  ds.sql.must_equal '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)'
1527
- ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6}
1528
- a = ds.all
1538
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genres_id=>4, :tracks_id=>3, :album_id=>1, :band_id_0=>2, :vocalist_id=>6).all
1529
1539
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1530
1540
  a = a.first
1531
1541
  a.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
@@ -1545,8 +1555,7 @@ describe Sequel::Model, "#eager_graph" do
1545
1555
  it "should allow cascading of eager loading for associations of associated models" do
1546
1556
  ds = GraphTrack.eager_graph(:album=>{:band=>:members})
1547
1557
  ds.sql.must_equal '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)'
1548
- ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6}
1549
- a = ds.all
1558
+ a = ds.with_fetch(:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6).all
1550
1559
  a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
1551
1560
  a = a.first
1552
1561
  a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
@@ -1557,7 +1566,7 @@ describe Sequel::Model, "#eager_graph" do
1557
1566
  it "should allow cascading of eager loading for multiple *_to_many associations, eliminating duplicates caused by cartesian products" do
1558
1567
  ds = GraphBand.eager_graph({:albums=>:tracks}, :members)
1559
1568
  ds.sql.must_equal '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)'
1560
- ds._fetch = [{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>4, :album_id=>3, :members_id=>5},
1569
+ a = ds.with_fetch([{:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>4, :album_id=>3, :members_id=>5},
1561
1570
  {:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>4, :album_id=>3, :members_id=>6},
1562
1571
  {:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>5, :album_id=>3, :members_id=>5},
1563
1572
  {:id=>1, :vocalist_id=>2, :albums_id=>3, :band_id=>1, :tracks_id=>5, :album_id=>3, :members_id=>6},
@@ -1572,8 +1581,7 @@ describe Sequel::Model, "#eager_graph" do
1572
1581
  {:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>1, :album_id=>6, :members_id=>5},
1573
1582
  {:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>1, :album_id=>6, :members_id=>6},
1574
1583
  {:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>5},
1575
- {:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>6}]
1576
- a = ds.all
1584
+ {:id=>2, :vocalist_id=>2, :albums_id=>6, :band_id=>2, :tracks_id=>2, :album_id=>6, :members_id=>6}]).all
1577
1585
  a.must_equal [GraphBand.load(:id=>1, :vocalist_id=>2), GraphBand.load(:id=>2, :vocalist_id=>2)]
1578
1586
  members = a.map{|x| x.members}
1579
1587
  members.must_equal [[GraphBandMember.load(:id=>5), GraphBandMember.load(:id=>6)], [GraphBandMember.load(:id=>5), GraphBandMember.load(:id=>6)]]
@@ -1587,8 +1595,7 @@ describe Sequel::Model, "#eager_graph" do
1587
1595
  DB.reset
1588
1596
  ds = GraphAlbum.eager_graph(:tracks)
1589
1597
  ds.sql.must_equal '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)'
1590
- ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
1591
- a = ds.all
1598
+ a = ds.with_fetch(:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1).all
1592
1599
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1593
1600
  a = a.first
1594
1601
  a.tracks.must_equal [GraphTrack.load(:id => 3, :album_id=>1)]
@@ -1599,8 +1606,7 @@ describe Sequel::Model, "#eager_graph" do
1599
1606
  it "should eager load multiple associations from the same table" do
1600
1607
  ds = GraphBand.eager_graph(:vocalist, :members)
1601
1608
  ds.sql.must_equal '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)'
1602
- ds._fetch = {:id=>2, :vocalist_id=>6, :vocalist_id_0=>6, :members_id=>5}
1603
- a = ds.all
1609
+ a = ds.with_fetch(:id=>2, :vocalist_id=>6, :vocalist_id_0=>6, :members_id=>5).all
1604
1610
  a.must_equal [GraphBand.load(:id => 2, :vocalist_id => 6)]
1605
1611
  a = a.first
1606
1612
  a.vocalist.must_equal GraphBandMember.load(:id => 6)
@@ -1610,15 +1616,13 @@ describe Sequel::Model, "#eager_graph" do
1610
1616
  it "should give you a plain hash when called without .all" do
1611
1617
  ds = GraphAlbum.eager_graph(:band)
1612
1618
  ds.sql.must_equal '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)'
1613
- ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3}
1614
- ds.first.must_equal(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)
1619
+ ds.with_fetch(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3).first.must_equal(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)
1615
1620
  end
1616
1621
 
1617
1622
  it "should not drop any associated objects if the graph could not be a cartesian product" do
1618
1623
  ds = GraphBand.eager_graph(:members, :vocalist)
1619
1624
  ds.sql.must_equal '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)'
1620
- 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}]
1621
- a = ds.all
1625
+ a = ds.with_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}]).all
1622
1626
  a.must_equal [GraphBand.load(:id => 2, :vocalist_id => 6)]
1623
1627
  a = a.first
1624
1628
  a.vocalist.must_equal GraphBandMember.load(:id => 6)
@@ -1629,8 +1633,7 @@ describe Sequel::Model, "#eager_graph" do
1629
1633
  GraphBand.many_to_one :other_vocalist, :class=>'GraphBandMember', :key=>:vocalist_id, :cartesian_product_number=>1
1630
1634
  ds = GraphBand.eager_graph(:members, :other_vocalist)
1631
1635
  ds.sql.must_equal '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)'
1632
- 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}]
1633
- a = ds.all
1636
+ a = ds.with_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}]).all
1634
1637
  a.must_equal [GraphBand.load(:id=>2, :vocalist_id => 6)]
1635
1638
  a.first.other_vocalist.must_equal GraphBandMember.load(:id=>6)
1636
1639
  a.first.members.must_equal [GraphBandMember.load(:id=>5)]
@@ -1639,11 +1642,10 @@ describe Sequel::Model, "#eager_graph" do
1639
1642
  it "should drop duplicate items that occur in sequence if the graph could be a cartesian product" do
1640
1643
  ds = GraphBand.eager_graph(:members, :genres)
1641
1644
  ds.sql.must_equal '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)'
1642
- ds._fetch = [{:id=>2, :vocalist_id=>6, :members_id=>5, :genres_id=>7},
1645
+ a = ds.with_fetch([{:id=>2, :vocalist_id=>6, :members_id=>5, :genres_id=>7},
1643
1646
  {:id=>2, :vocalist_id=>6, :members_id=>5, :genres_id=>8},
1644
1647
  {:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>7},
1645
- {:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>8}]
1646
- a = ds.all
1648
+ {:id=>2, :vocalist_id=>6, :members_id=>6, :genres_id=>8}]).all
1647
1649
  a.must_equal [GraphBand.load(:id => 2, :vocalist_id => 6)]
1648
1650
  a = a.first
1649
1651
  a.members.must_equal [GraphBandMember.load(:id => 5), GraphBandMember.load(:id => 6)]
@@ -1653,10 +1655,8 @@ describe Sequel::Model, "#eager_graph" do
1653
1655
  it "should be able to be used in combination with #eager" do
1654
1656
  DB.reset
1655
1657
  ds = GraphAlbum.eager_graph(:tracks).eager(:genres)
1656
- ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
1657
- ds2 = GraphGenre.dataset
1658
- ds2._fetch = {:id=>6, :x_foreign_key_x=>1}
1659
- a = ds.all
1658
+ GraphGenre.dataset = GraphGenre.dataset.with_fetch(:id=>6, :x_foreign_key_x=>1)
1659
+ a = ds.with_fetch(:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1).all
1660
1660
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1661
1661
  a = a.first
1662
1662
  a.tracks.must_equal [GraphTrack.load(:id=>3, :album_id=>1)]
@@ -1668,26 +1668,23 @@ describe Sequel::Model, "#eager_graph" do
1668
1668
  it "should handle no associated records for a single many_to_one association" do
1669
1669
  ds = GraphAlbum.eager_graph(:band)
1670
1670
  ds.sql.must_equal '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)'
1671
- ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>nil, :vocalist_id=>nil}
1672
- a = ds.all
1671
+ a = ds.with_fetch(:id=>1, :band_id=>2, :band_id_0=>nil, :vocalist_id=>nil).all
1673
1672
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1674
- a.first.band.must_equal nil
1673
+ a.first.band.must_be_nil
1675
1674
  end
1676
1675
 
1677
1676
  it "should handle no associated records for a single one_to_one association" do
1678
1677
  ds = GraphAlbum.eager_graph(:track)
1679
1678
  ds.sql.must_equal '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)'
1680
- ds._fetch = {:id=>1, :band_id=>2, :track_id=>nil, :album_id=>nil}
1681
- a = ds.all
1679
+ a = ds.with_fetch(:id=>1, :band_id=>2, :track_id=>nil, :album_id=>nil).all
1682
1680
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1683
- a.first.track.must_equal nil
1681
+ a.first.track.must_be_nil
1684
1682
  end
1685
1683
 
1686
1684
  it "should handle no associated records for a single one_to_many association" do
1687
1685
  ds = GraphAlbum.eager_graph(:tracks)
1688
1686
  ds.sql.must_equal '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)'
1689
- ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>nil, :album_id=>nil}
1690
- a = ds.all
1687
+ a = ds.with_fetch(:id=>1, :band_id=>2, :tracks_id=>nil, :album_id=>nil).all
1691
1688
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1692
1689
  a.first.tracks.must_equal []
1693
1690
  end
@@ -1695,17 +1692,15 @@ describe Sequel::Model, "#eager_graph" do
1695
1692
  it "should handle no associated records for a single one_through_one association" do
1696
1693
  ds = GraphAlbum.eager_graph(:genre)
1697
1694
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genre ON (genre.id = ag.genre_id)'
1698
- ds._fetch = {:id=>1, :band_id=>2, :genres_id=>nil}
1699
- a = ds.all
1695
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genres_id=>nil).all
1700
1696
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1701
- a.first.genre.must_equal nil
1697
+ a.first.genre.must_be_nil
1702
1698
  end
1703
1699
 
1704
1700
  it "should handle no associated records for a single many_to_many association" do
1705
1701
  ds = GraphAlbum.eager_graph(:genres)
1706
1702
  ds.sql.must_equal '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)'
1707
- ds._fetch = {:id=>1, :band_id=>2, :genres_id=>nil}
1708
- a = ds.all
1703
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genres_id=>nil).all
1709
1704
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1710
1705
  a.first.genres.must_equal []
1711
1706
  end
@@ -1713,27 +1708,25 @@ describe Sequel::Model, "#eager_graph" do
1713
1708
  it "should handle missing associated records when loading multiple associations" do
1714
1709
  ds = GraphAlbum.eager_graph(:genres, :tracks, :band)
1715
1710
  ds.sql.must_equal '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)'
1716
- ds._fetch = [{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>3, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
1711
+ a = ds.with_fetch([{:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>3, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
1717
1712
  {:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>4, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
1718
1713
  {:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>5, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil},
1719
- {:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>6, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil}]
1720
- a = ds.all
1714
+ {:id=>1, :band_id=>2, :genres_id=>nil, :tracks_id=>6, :album_id=>1, :band_id_0=>nil, :vocalist_id=>nil}]).all
1721
1715
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
1722
1716
  a = a.first
1723
1717
  a.tracks.must_equal [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)]
1724
- a.band.must_equal nil
1718
+ a.band.must_be_nil
1725
1719
  a.genres.must_equal []
1726
1720
  end
1727
1721
 
1728
1722
  it "should handle missing associated records when cascading eager loading for associations of associated models" do
1729
1723
  ds = GraphTrack.eager_graph(:album=>{:band=>:members})
1730
1724
  ds.sql.must_equal '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)'
1731
- ds._fetch = [{:id=>2, :album_id=>2, :album_id_0=>nil, :band_id=>nil, :members_id=>nil, :band_id_0=>nil, :vocalist_id=>nil},
1725
+ a = ds.with_fetch([{:id=>2, :album_id=>2, :album_id_0=>nil, :band_id=>nil, :members_id=>nil, :band_id_0=>nil, :vocalist_id=>nil},
1732
1726
  {:id=>3, :album_id=>3, :album_id_0=>3, :band_id=>3, :members_id=>nil, :band_id_0=>nil, :vocalist_id=>nil},
1733
1727
  {:id=>4, :album_id=>4, :album_id_0=>4, :band_id=>2, :members_id=>nil, :band_id_0=>2, :vocalist_id=>6},
1734
1728
  {:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>5, :band_id_0=>4, :vocalist_id=>8},
1735
- {:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>6, :band_id_0=>4, :vocalist_id=>8}]
1736
- a = ds.all
1729
+ {:id=>5, :album_id=>1, :album_id_0=>1, :band_id=>4, :members_id=>6, :band_id_0=>4, :vocalist_id=>8}]).all
1737
1730
  a.must_equal [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)]
1738
1731
  a.map{|x| x.album}.must_equal [nil, GraphAlbum.load(:id => 3, :band_id => 3), GraphAlbum.load(:id => 4, :band_id => 2), GraphAlbum.load(:id => 1, :band_id => 4)]
1739
1732
  a.map{|x| x.album.band if x.album}.must_equal [nil, nil, GraphBand.load(:id => 2, :vocalist_id=>6), GraphBand.load(:id => 4, :vocalist_id=>8)]
@@ -1744,16 +1737,14 @@ describe Sequel::Model, "#eager_graph" do
1744
1737
  GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>:band_id, :primary_key=>:vocalist_id
1745
1738
  ds = GraphAlbum.eager_graph(:inner_band)
1746
1739
  ds.sql.must_equal '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)'
1747
- ds._fetch = {:id=>3, :band_id=>2, :inner_band_id=>5, :vocalist_id=>2}
1748
- as = ds.all
1740
+ as = ds.with_fetch(:id=>3, :band_id=>2, :inner_band_id=>5, :vocalist_id=>2).all
1749
1741
  as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
1750
1742
  as.first.inner_band.must_equal GraphBand.load(:id=>5, :vocalist_id=>2)
1751
1743
 
1752
1744
  GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :primary_key=>:band_id, :reciprocal=>nil
1753
1745
  ds = GraphAlbum.eager_graph(:right_tracks)
1754
1746
  ds.sql.must_equal '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)'
1755
- 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}]
1756
- as = ds.all
1747
+ as = ds.with_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}]).all
1757
1748
  as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
1758
1749
  as.first.right_tracks.must_equal [GraphTrack.load(:id=>5, :album_id=>2), GraphTrack.load(:id=>6, :album_id=>2)]
1759
1750
  end
@@ -1762,8 +1753,7 @@ describe Sequel::Model, "#eager_graph" do
1762
1753
  GraphAlbum.many_to_one :inner_band, :class=>'GraphBand', :key=>[:band_id, :id], :primary_key=>[:vocalist_id, :id]
1763
1754
  ds = GraphAlbum.eager_graph(:inner_band)
1764
1755
  ds.sql.must_equal '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))'
1765
- ds._fetch = {:id=>3, :band_id=>2, :inner_band_id=>3, :vocalist_id=>2}
1766
- as = ds.all
1756
+ as = ds.with_fetch(:id=>3, :band_id=>2, :inner_band_id=>3, :vocalist_id=>2).all
1767
1757
  as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
1768
1758
  as.first.inner_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>2)
1769
1759
  end
@@ -1772,8 +1762,7 @@ describe Sequel::Model, "#eager_graph" do
1772
1762
  GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>[:album_id, :id], :primary_key=>[:band_id, :id]
1773
1763
  ds = GraphAlbum.eager_graph(:right_tracks)
1774
1764
  ds.sql.must_equal '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))'
1775
- ds._fetch = {:id=>3, :band_id=>2, :right_tracks_id=>3, :album_id=>2}
1776
- as = ds.all
1765
+ as = ds.with_fetch(:id=>3, :band_id=>2, :right_tracks_id=>3, :album_id=>2).all
1777
1766
  as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
1778
1767
  as.first.right_tracks.must_equal [GraphTrack.load(:id=>3, :album_id=>2)]
1779
1768
  end
@@ -1782,8 +1771,7 @@ describe Sequel::Model, "#eager_graph" do
1782
1771
  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
1783
1772
  ds = GraphAlbum.eager_graph(:sbands)
1784
1773
  ds.sql.must_equal '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))'
1785
- ds._fetch = [{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6}, {:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22}]
1786
- as = ds.all
1774
+ as = ds.with_fetch([{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6}, {:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22}]).all
1787
1775
  as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
1788
1776
  as.first.sbands.must_equal [GraphBand.load(:id=>5, :vocalist_id=>6), GraphBand.load(:id=>6, :vocalist_id=>22)]
1789
1777
  end
@@ -1792,8 +1780,7 @@ describe Sequel::Model, "#eager_graph" do
1792
1780
  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
1793
1781
  ds = GraphAlbum.eager_graph(:inner_genres)
1794
1782
  ds.sql.must_equal '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)'
1795
- ds._fetch = [{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]
1796
- as = ds.all
1783
+ as = ds.with_fetch([{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]).all
1797
1784
  as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
1798
1785
  as.first.inner_genres.must_equal [GraphGenre.load(:id=>5), GraphGenre.load(:id=>6)]
1799
1786
  end
@@ -1807,11 +1794,10 @@ describe Sequel::Model, "#eager_graph" do
1807
1794
  c2.one_to_many :salbums, :class=>c1, :key=>[:band_id, :id]
1808
1795
  ds = c1.eager_graph(:sbands=>:salbums)
1809
1796
  ds.sql.must_equal '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))'
1810
- ds._fetch = [{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6, :salbums_id=>7, :salbums_band_id=>8},
1797
+ as = ds.with_fetch([{:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6, :salbums_id=>7, :salbums_band_id=>8},
1811
1798
  {:id=>3, :band_id=>2, :sbands_id=>5, :vocalist_id=>6, :salbums_id=>9, :salbums_band_id=>10},
1812
1799
  {:id=>3, :band_id=>2, :sbands_id=>6, :vocalist_id=>22, :salbums_id=>nil, :salbums_band_id=>nil},
1813
- {:id=>7, :band_id=>8, :sbands_id=>nil, :vocalist_id=>nil, :salbums_id=>nil, :salbums_band_id=>nil}]
1814
- as = ds.all
1800
+ {:id=>7, :band_id=>8, :sbands_id=>nil, :vocalist_id=>nil, :salbums_id=>nil, :salbums_band_id=>nil}]).all
1815
1801
  as.must_equal [c1.load(:id=>3, :band_id=>2), c1.load(:id=>7, :band_id=>8)]
1816
1802
  as.map{|x| x.sbands}.must_equal [[c2.load(:id=>5, :vocalist_id=>6), c2.load(:id=>6, :vocalist_id=>22)], []]
1817
1803
  as.map{|x| x.sbands.map{|y| y.salbums}}.must_equal [[[c1.load(:id=>7, :band_id=>8), c1.load(:id=>9, :band_id=>10)], []], []]
@@ -1989,8 +1975,7 @@ describe Sequel::Model, "#eager_graph" do
1989
1975
  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
1990
1976
  ds = GraphAlbum.eager_graph(:inner_genres)
1991
1977
  ds.sql.must_equal '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)'
1992
- ds._fetch = [{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]
1993
- as = ds.all
1978
+ as = ds.with_fetch([{:id=>3, :band_id=>2, :inner_genres_id=>5, :xxx=>12}, {:id=>3, :band_id=>2, :inner_genres_id=>6, :xxx=>22}]).all
1994
1979
  as.must_equal [GraphAlbum.load(:id=>3, :band_id=>2)]
1995
1980
  as.first.inner_genres.must_equal [GraphGenre.load(:id=>5), GraphGenre.load(:id=>6)]
1996
1981
  GraphAlbum.set_primary_key :id
@@ -2014,8 +1999,9 @@ describe Sequel::Model, "#eager_graph" do
2014
1999
  it "should eagerly load schema qualified tables correctly with joins" do
2015
2000
  c1 = Class.new(GraphAlbum)
2016
2001
  c2 = Class.new(GraphGenre)
2017
- ds = c1.dataset = c1.dataset.from(:s__a)
2018
- def ds.columns() [:id] end
2002
+ ds = c1.dataset.from(:s__a).with_extend{def columns; [:id] end}
2003
+ c1.dataset = ds
2004
+ ds = c1.dataset
2019
2005
  c2.dataset = c2.dataset.from(:s__g)
2020
2006
  c1.many_to_many :a_genres, :class=>c2, :left_primary_key=>:id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:s__ag
2021
2007
  ds = c1.join(:s__t, [:b_id]).eager_graph(:a_genres)
@@ -2030,8 +2016,7 @@ describe Sequel::Model, "#eager_graph" do
2030
2016
  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}}
2031
2017
  ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
2032
2018
  ds.sql.must_equal "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)"
2033
- 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}
2034
- a = ds.all.first
2019
+ a = ds.with_fetch(:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7).all.first
2035
2020
  a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
2036
2021
  a.al_band.must_equal GraphBand.load(:id=>6, :vocalist_id=>4)
2037
2022
  a.al_tracks.must_equal [GraphTrack.load(:id=>10, :album_id=>6)]
@@ -2044,10 +2029,9 @@ describe Sequel::Model, "#eager_graph" do
2044
2029
  GraphAlbum.many_to_many :al_genres, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2
2045
2030
  ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
2046
2031
  ds.sql.must_equal "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)"
2047
- 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},
2032
+ a = ds.with_fetch([{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7},
2048
2033
  {:id=>1, :band_id=>2, :al_band_id=>8, :vocalist_id=>9, :al_tracks_id=>10, :album_id=>11, :al_genres_id=>12},
2049
- {:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17}]
2050
- a = ds.all.first
2034
+ {:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17}]).all.first
2051
2035
  a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
2052
2036
  a.al_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>4)
2053
2037
  a.al_tracks.must_equal [GraphTrack.load(:id=>5, :album_id=>6), GraphTrack.load(:id=>10, :album_id=>11)]
@@ -2058,8 +2042,7 @@ describe Sequel::Model, "#eager_graph" do
2058
2042
  GraphAlbum.one_to_many :al_tracks, :class=>GraphTrack, :key=>:album_id, :limit=>[2, 1]
2059
2043
  ds = GraphAlbum.eager_graph(:al_tracks)
2060
2044
  ds.sql.must_equal "SELECT albums.id, albums.band_id, al_tracks.id AS al_tracks_id, al_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS al_tracks ON (al_tracks.album_id = albums.id)"
2061
- ds._fetch = [{:id=>1, :band_id=>2, :al_tracks_id=>nil, :album_id=>nil}]
2062
- a = ds.all.first
2045
+ a = ds.with_fetch([{:id=>1, :band_id=>2, :al_tracks_id=>nil, :album_id=>nil}]).all.first
2063
2046
  a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
2064
2047
  a.al_tracks.must_equal []
2065
2048
  end
@@ -2070,10 +2053,9 @@ describe Sequel::Model, "#eager_graph" do
2070
2053
  GraphAlbum.many_to_many :al_genres, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[1,1]
2071
2054
  ds = GraphAlbum.eager_graph(:al_band, :al_tracks, :al_genres)
2072
2055
  ds.sql.must_equal "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)"
2073
- 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},
2056
+ a = ds.with_fetch([{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_tracks_id=>5, :album_id=>6, :al_genres_id=>7},
2074
2057
  {:id=>1, :band_id=>2, :al_band_id=>8, :vocalist_id=>9, :al_tracks_id=>10, :album_id=>11, :al_genres_id=>12},
2075
- {:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17}]
2076
- a = ds.all.first
2058
+ {:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_tracks_id=>15, :album_id=>16, :al_genres_id=>17}]).all.first
2077
2059
  a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
2078
2060
  a.al_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>4)
2079
2061
  a.al_tracks.must_equal [GraphTrack.load(:id=>10, :album_id=>11)]
@@ -2086,10 +2068,9 @@ describe Sequel::Model, "#eager_graph" do
2086
2068
  GraphAlbum.one_through_one :al_genre, :class=>GraphGenre, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[nil,1]
2087
2069
  ds = GraphAlbum.eager_graph(:al_band, :al_track, :al_genre)
2088
2070
  ds.sql.must_equal "SELECT albums.id, albums.band_id, al_band.id AS al_band_id, al_band.vocalist_id, al_track.id AS al_track_id, al_track.album_id, al_genre.id AS al_genre_id FROM albums LEFT OUTER JOIN bands AS al_band ON (al_band.id = albums.band_id) LEFT OUTER JOIN tracks AS al_track ON (al_track.album_id = albums.id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS al_genre ON (al_genre.id = ag.genre_id)"
2089
- ds._fetch = [{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_track_id=>5, :album_id=>6, :al_genre_id=>7},
2071
+ a = ds.with_fetch([{:id=>1, :band_id=>2, :al_band_id=>3, :vocalist_id=>4, :al_track_id=>5, :album_id=>6, :al_genre_id=>7},
2090
2072
  {:id=>1, :band_id=>2, :al_band_id=>8, :vocalist_id=>9, :al_track_id=>10, :album_id=>11, :al_genre_id=>12},
2091
- {:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_track_id=>15, :album_id=>16, :al_genre_id=>17}]
2092
- a = ds.all.first
2073
+ {:id=>1, :band_id=>2, :al_band_id=>13, :vocalist_id=>14, :al_track_id=>15, :album_id=>16, :al_genre_id=>17}]).all.first
2093
2074
  a.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
2094
2075
  a.al_band.must_equal GraphBand.load(:id=>3, :vocalist_id=>4)
2095
2076
  a.al_track.must_equal GraphTrack.load(:id=>10, :album_id=>11)
@@ -2099,8 +2080,7 @@ describe Sequel::Model, "#eager_graph" do
2099
2080
  it "should eagerly load a many_to_one association with a custom callback" do
2100
2081
  ds = GraphAlbum.eager_graph(:band => proc {|ds1| ds1.select(:id).columns(:id)})
2101
2082
  ds.sql.must_equal '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)'
2102
- ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2}
2103
- a = ds.all
2083
+ a = ds.with_fetch(:id=>1, :band_id=>2, :band_id_0=>2).all
2104
2084
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
2105
2085
  a.first.band.must_equal GraphBand.load(:id => 2)
2106
2086
  end
@@ -2108,8 +2088,7 @@ describe Sequel::Model, "#eager_graph" do
2108
2088
  it "should eagerly load a one_to_one association with a custom callback" do
2109
2089
  ds = GraphAlbum.eager_graph(:track => proc {|ds1| ds1.select(:album_id).columns(:album_id)})
2110
2090
  ds.sql.must_equal '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)'
2111
- ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
2112
- a = ds.all
2091
+ a = ds.with_fetch(:id=>1, :band_id=>2, :album_id=>1).all
2113
2092
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
2114
2093
  a.first.track.must_equal GraphTrack.load(:album_id=>1)
2115
2094
  end
@@ -2117,8 +2096,7 @@ describe Sequel::Model, "#eager_graph" do
2117
2096
  it "should eagerly load a one_to_many association with a custom callback" do
2118
2097
  ds = GraphAlbum.eager_graph(:tracks => proc {|ds1| ds1.select(:album_id).columns(:album_id)})
2119
2098
  ds.sql.must_equal '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)'
2120
- ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
2121
- a = ds.all
2099
+ a = ds.with_fetch(:id=>1, :band_id=>2, :album_id=>1).all
2122
2100
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
2123
2101
  a.first.tracks.must_equal [GraphTrack.load(:album_id=>1)]
2124
2102
  end
@@ -2126,8 +2104,7 @@ describe Sequel::Model, "#eager_graph" do
2126
2104
  it "should eagerly load a one_through_one association with a custom callback" do
2127
2105
  ds = GraphAlbum.eager_graph(:genre => proc {|ds1| ds1.select(:id).columns(:id)})
2128
2106
  ds.sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN (SELECT id FROM genres) AS genre ON (genre.id = ag.genre_id)'
2129
- ds._fetch = {:id=>1, :band_id=>2, :genre_id=>4}
2130
- a = ds.all
2107
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genre_id=>4).all
2131
2108
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
2132
2109
  a.first.genre.must_equal GraphGenre.load(:id => 4)
2133
2110
  end
@@ -2135,8 +2112,7 @@ describe Sequel::Model, "#eager_graph" do
2135
2112
  it "should eagerly load a many_to_many association with a custom callback" do
2136
2113
  ds = GraphAlbum.eager_graph(:genres => proc {|ds1| ds1.select(:id).columns(:id)})
2137
2114
  ds.sql.must_equal '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)'
2138
- ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4}
2139
- a = ds.all
2115
+ a = ds.with_fetch(:id=>1, :band_id=>2, :genres_id=>4).all
2140
2116
  a.must_equal [GraphAlbum.load(:id => 1, :band_id => 2)]
2141
2117
  a.first.genres.must_equal [GraphGenre.load(:id => 4)]
2142
2118
  end
@@ -2144,8 +2120,7 @@ describe Sequel::Model, "#eager_graph" do
2144
2120
  it "should allow cascading of eager loading with a custom callback with hash value" do
2145
2121
  ds = GraphTrack.eager_graph(:album=>{proc{|ds1| ds1.select(:id, :band_id).columns(:id, :band_id)}=>{:band=>:members}})
2146
2122
  ds.sql.must_equal '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)'
2147
- ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6}
2148
- a = ds.all
2123
+ a = ds.with_fetch(:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6).all
2149
2124
  a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
2150
2125
  a = a.first
2151
2126
  a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)
@@ -2156,8 +2131,7 @@ describe Sequel::Model, "#eager_graph" do
2156
2131
  it "should allow cascading of eager loading with a custom callback with array value" do
2157
2132
  ds = GraphTrack.eager_graph(:album=>{proc{|ds1| ds1.select(:id, :band_id).columns(:id, :band_id)}=>[:band, :tracks]})
2158
2133
  ds.sql.must_equal '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)'
2159
- 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}
2160
- a = ds.all
2134
+ a = ds.with_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).all
2161
2135
  a.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
2162
2136
  a = a.first
2163
2137
  a.album.must_equal GraphAlbum.load(:id => 1, :band_id => 2)