sequel 4.41.0 → 4.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)