sequel 4.41.0 → 4.42.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +98 -0
  3. data/README.rdoc +23 -10
  4. data/doc/active_record.rdoc +4 -4
  5. data/doc/advanced_associations.rdoc +2 -2
  6. data/doc/association_basics.rdoc +5 -2
  7. data/doc/cheat_sheet.rdoc +3 -3
  8. data/doc/core_extensions.rdoc +2 -2
  9. data/doc/dataset_basics.rdoc +4 -4
  10. data/doc/dataset_filtering.rdoc +1 -1
  11. data/doc/migration.rdoc +19 -1
  12. data/doc/prepared_statements.rdoc +2 -2
  13. data/doc/release_notes/4.42.0.txt +221 -0
  14. data/doc/testing.rdoc +3 -1
  15. data/lib/sequel/adapters/ado/access.rb +0 -1
  16. data/lib/sequel/adapters/ado/mssql.rb +0 -1
  17. data/lib/sequel/adapters/do/mysql.rb +0 -1
  18. data/lib/sequel/adapters/do/postgres.rb +0 -1
  19. data/lib/sequel/adapters/do/sqlite3.rb +0 -1
  20. data/lib/sequel/adapters/ibmdb.rb +21 -25
  21. data/lib/sequel/adapters/jdbc.rb +8 -16
  22. data/lib/sequel/adapters/jdbc/as400.rb +0 -1
  23. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
  24. data/lib/sequel/adapters/jdbc/db2.rb +0 -1
  25. data/lib/sequel/adapters/jdbc/derby.rb +0 -1
  26. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
  27. data/lib/sequel/adapters/jdbc/h2.rb +0 -1
  28. data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
  29. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
  30. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
  31. data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
  32. data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
  33. data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
  34. data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
  35. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
  36. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
  37. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
  38. data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
  39. data/lib/sequel/adapters/mock.rb +54 -12
  40. data/lib/sequel/adapters/mysql.rb +1 -1
  41. data/lib/sequel/adapters/mysql2.rb +11 -17
  42. data/lib/sequel/adapters/odbc/mssql.rb +0 -1
  43. data/lib/sequel/adapters/oracle.rb +8 -20
  44. data/lib/sequel/adapters/postgres.rb +11 -29
  45. data/lib/sequel/adapters/shared/access.rb +5 -12
  46. data/lib/sequel/adapters/shared/cubrid.rb +4 -13
  47. data/lib/sequel/adapters/shared/db2.rb +4 -2
  48. data/lib/sequel/adapters/shared/firebird.rb +2 -4
  49. data/lib/sequel/adapters/shared/informix.rb +4 -2
  50. data/lib/sequel/adapters/shared/mssql.rb +3 -5
  51. data/lib/sequel/adapters/shared/mysql.rb +4 -14
  52. data/lib/sequel/adapters/shared/oracle.rb +1 -3
  53. data/lib/sequel/adapters/shared/postgres.rb +16 -38
  54. data/lib/sequel/adapters/shared/progress.rb +0 -2
  55. data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
  56. data/lib/sequel/adapters/shared/sqlite.rb +20 -16
  57. data/lib/sequel/adapters/sqlite.rb +8 -20
  58. data/lib/sequel/adapters/swift/mysql.rb +0 -1
  59. data/lib/sequel/adapters/swift/postgres.rb +0 -1
  60. data/lib/sequel/adapters/swift/sqlite.rb +0 -1
  61. data/lib/sequel/adapters/tinytds.rb +4 -12
  62. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  63. data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
  64. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
  65. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  66. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
  67. data/lib/sequel/ast_transformer.rb +2 -2
  68. data/lib/sequel/database/dataset.rb +1 -1
  69. data/lib/sequel/database/dataset_defaults.rb +0 -66
  70. data/lib/sequel/database/features.rb +6 -0
  71. data/lib/sequel/database/misc.rb +31 -17
  72. data/lib/sequel/database/query.rb +7 -4
  73. data/lib/sequel/database/schema_methods.rb +1 -1
  74. data/lib/sequel/dataset.rb +8 -8
  75. data/lib/sequel/dataset/actions.rb +140 -46
  76. data/lib/sequel/dataset/features.rb +1 -5
  77. data/lib/sequel/dataset/graph.rb +7 -8
  78. data/lib/sequel/dataset/misc.rb +127 -56
  79. data/lib/sequel/dataset/mutation.rb +9 -20
  80. data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
  81. data/lib/sequel/dataset/prepared_statements.rb +102 -46
  82. data/lib/sequel/dataset/query.rb +155 -72
  83. data/lib/sequel/dataset/sql.rb +26 -9
  84. data/lib/sequel/extensions/columns_introspection.rb +3 -1
  85. data/lib/sequel/extensions/core_extensions.rb +5 -5
  86. data/lib/sequel/extensions/core_refinements.rb +5 -5
  87. data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
  88. data/lib/sequel/extensions/freeze_datasets.rb +69 -0
  89. data/lib/sequel/extensions/identifier_mangling.rb +196 -0
  90. data/lib/sequel/extensions/looser_typecasting.rb +11 -7
  91. data/lib/sequel/extensions/migration.rb +1 -1
  92. data/lib/sequel/extensions/null_dataset.rb +5 -2
  93. data/lib/sequel/extensions/pagination.rb +42 -23
  94. data/lib/sequel/extensions/pg_enum.rb +3 -3
  95. data/lib/sequel/extensions/query.rb +3 -3
  96. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
  97. data/lib/sequel/model/associations.rb +25 -8
  98. data/lib/sequel/model/base.rb +88 -29
  99. data/lib/sequel/model/dataset_module.rb +37 -0
  100. data/lib/sequel/plugins/association_pks.rb +4 -4
  101. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  102. data/lib/sequel/plugins/constraint_validations.rb +1 -2
  103. data/lib/sequel/plugins/csv_serializer.rb +2 -2
  104. data/lib/sequel/plugins/dataset_associations.rb +8 -8
  105. data/lib/sequel/plugins/eager_each.rb +2 -2
  106. data/lib/sequel/plugins/instance_filters.rb +1 -1
  107. data/lib/sequel/plugins/json_serializer.rb +2 -2
  108. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  109. data/lib/sequel/plugins/list.rb +4 -4
  110. data/lib/sequel/plugins/prepared_statements.rb +2 -4
  111. data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
  112. data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
  113. data/lib/sequel/plugins/rcte_tree.rb +13 -13
  114. data/lib/sequel/plugins/sharding.rb +1 -1
  115. data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
  116. data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
  117. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  118. data/lib/sequel/plugins/validation_helpers.rb +1 -1
  119. data/lib/sequel/plugins/xml_serializer.rb +2 -2
  120. data/lib/sequel/sql.rb +69 -36
  121. data/lib/sequel/version.rb +1 -1
  122. data/spec/adapters/db2_spec.rb +10 -0
  123. data/spec/adapters/firebird_spec.rb +1 -1
  124. data/spec/adapters/mssql_spec.rb +4 -5
  125. data/spec/adapters/mysql_spec.rb +9 -9
  126. data/spec/adapters/postgres_spec.rb +67 -68
  127. data/spec/adapters/spec_helper.rb +6 -1
  128. data/spec/adapters/sqlite_spec.rb +29 -15
  129. data/spec/core/connection_pool_spec.rb +14 -14
  130. data/spec/core/database_spec.rb +38 -180
  131. data/spec/core/dataset_mutation_spec.rb +253 -0
  132. data/spec/core/dataset_spec.rb +394 -537
  133. data/spec/core/expression_filters_spec.rb +34 -32
  134. data/spec/core/mock_adapter_spec.rb +27 -35
  135. data/spec/core/placeholder_literalizer_spec.rb +2 -4
  136. data/spec/core/schema_generator_spec.rb +4 -4
  137. data/spec/core/schema_spec.rb +1 -2
  138. data/spec/core_extensions_spec.rb +22 -29
  139. data/spec/extensions/active_model_spec.rb +6 -6
  140. data/spec/extensions/association_dependencies_spec.rb +2 -2
  141. data/spec/extensions/blacklist_security_spec.rb +3 -3
  142. data/spec/extensions/boolean_readers_spec.rb +12 -12
  143. data/spec/extensions/caching_spec.rb +13 -10
  144. data/spec/extensions/class_table_inheritance_spec.rb +38 -43
  145. data/spec/extensions/column_conflicts_spec.rb +1 -3
  146. data/spec/extensions/columns_introspection_spec.rb +2 -3
  147. data/spec/extensions/composition_spec.rb +5 -3
  148. data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
  149. data/spec/extensions/constraint_validations_spec.rb +14 -8
  150. data/spec/extensions/core_refinements_spec.rb +22 -29
  151. data/spec/extensions/csv_serializer_spec.rb +7 -6
  152. data/spec/extensions/date_arithmetic_spec.rb +15 -15
  153. data/spec/extensions/defaults_setter_spec.rb +2 -2
  154. data/spec/extensions/delay_add_association_spec.rb +1 -1
  155. data/spec/extensions/dirty_spec.rb +19 -10
  156. data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
  157. data/spec/extensions/eager_each_spec.rb +12 -16
  158. data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
  159. data/spec/extensions/eval_inspect_spec.rb +4 -3
  160. data/spec/extensions/force_encoding_spec.rb +12 -12
  161. data/spec/extensions/freeze_datasets_spec.rb +31 -0
  162. data/spec/extensions/graph_each_spec.rb +6 -18
  163. data/spec/extensions/hook_class_methods_spec.rb +7 -7
  164. data/spec/extensions/identifier_mangling_spec.rb +307 -0
  165. data/spec/extensions/instance_filters_spec.rb +5 -6
  166. data/spec/extensions/instance_hooks_spec.rb +12 -12
  167. data/spec/extensions/json_serializer_spec.rb +12 -15
  168. data/spec/extensions/lazy_attributes_spec.rb +4 -4
  169. data/spec/extensions/list_spec.rb +19 -21
  170. data/spec/extensions/many_through_many_spec.rb +108 -163
  171. data/spec/extensions/meta_def_spec.rb +7 -2
  172. data/spec/extensions/migration_spec.rb +10 -12
  173. data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
  174. data/spec/extensions/named_timezones_spec.rb +4 -3
  175. data/spec/extensions/nested_attributes_spec.rb +2 -2
  176. data/spec/extensions/null_dataset_spec.rb +17 -12
  177. data/spec/extensions/optimistic_locking_spec.rb +4 -5
  178. data/spec/extensions/pagination_spec.rb +8 -10
  179. data/spec/extensions/pg_array_associations_spec.rb +28 -27
  180. data/spec/extensions/pg_array_ops_spec.rb +2 -1
  181. data/spec/extensions/pg_array_spec.rb +6 -2
  182. data/spec/extensions/pg_enum_spec.rb +5 -3
  183. data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
  184. data/spec/extensions/pg_hstore_spec.rb +7 -6
  185. data/spec/extensions/pg_inet_ops_spec.rb +2 -1
  186. data/spec/extensions/pg_inet_spec.rb +2 -1
  187. data/spec/extensions/pg_interval_spec.rb +2 -1
  188. data/spec/extensions/pg_json_ops_spec.rb +2 -1
  189. data/spec/extensions/pg_json_spec.rb +6 -3
  190. data/spec/extensions/pg_loose_count_spec.rb +1 -0
  191. data/spec/extensions/pg_range_ops_spec.rb +3 -1
  192. data/spec/extensions/pg_range_spec.rb +9 -5
  193. data/spec/extensions/pg_row_ops_spec.rb +2 -1
  194. data/spec/extensions/pg_row_plugin_spec.rb +4 -6
  195. data/spec/extensions/pg_row_spec.rb +5 -3
  196. data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
  197. data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
  198. data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
  199. data/spec/extensions/prepared_statements_spec.rb +12 -11
  200. data/spec/extensions/pretty_table_spec.rb +1 -1
  201. data/spec/extensions/query_spec.rb +8 -5
  202. data/spec/extensions/rcte_tree_spec.rb +39 -39
  203. data/spec/extensions/round_timestamps_spec.rb +2 -2
  204. data/spec/extensions/schema_dumper_spec.rb +3 -2
  205. data/spec/extensions/schema_spec.rb +2 -2
  206. data/spec/extensions/scissors_spec.rb +1 -2
  207. data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
  208. data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
  209. data/spec/extensions/serialization_spec.rb +15 -13
  210. data/spec/extensions/set_overrides_spec.rb +14 -8
  211. data/spec/extensions/sharding_spec.rb +9 -18
  212. data/spec/extensions/shared_caching_spec.rb +3 -4
  213. data/spec/extensions/single_table_inheritance_spec.rb +11 -11
  214. data/spec/extensions/skip_create_refresh_spec.rb +2 -1
  215. data/spec/extensions/spec_helper.rb +1 -1
  216. data/spec/extensions/split_values_spec.rb +2 -2
  217. data/spec/extensions/sql_comments_spec.rb +6 -0
  218. data/spec/extensions/static_cache_spec.rb +7 -9
  219. data/spec/extensions/string_agg_spec.rb +30 -29
  220. data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
  221. data/spec/extensions/thread_local_timezones_spec.rb +2 -2
  222. data/spec/extensions/timestamps_spec.rb +28 -3
  223. data/spec/extensions/to_dot_spec.rb +1 -2
  224. data/spec/extensions/tree_spec.rb +33 -29
  225. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  226. data/spec/extensions/unlimited_update_spec.rb +1 -0
  227. data/spec/extensions/update_primary_key_spec.rb +11 -7
  228. data/spec/extensions/update_refresh_spec.rb +1 -1
  229. data/spec/extensions/uuid_spec.rb +0 -1
  230. data/spec/extensions/validate_associated_spec.rb +1 -1
  231. data/spec/extensions/validation_class_methods_spec.rb +10 -10
  232. data/spec/extensions/validation_helpers_spec.rb +10 -10
  233. data/spec/extensions/xml_serializer_spec.rb +7 -3
  234. data/spec/integration/associations_test.rb +31 -31
  235. data/spec/integration/dataset_test.rb +17 -19
  236. data/spec/integration/eager_loader_test.rb +24 -24
  237. data/spec/integration/model_test.rb +6 -6
  238. data/spec/integration/plugin_test.rb +43 -43
  239. data/spec/integration/prepared_statement_test.rb +6 -6
  240. data/spec/integration/schema_test.rb +63 -52
  241. data/spec/integration/spec_helper.rb +6 -1
  242. data/spec/integration/transaction_test.rb +13 -13
  243. data/spec/model/association_reflection_spec.rb +17 -17
  244. data/spec/model/associations_spec.rb +101 -96
  245. data/spec/model/base_spec.rb +175 -49
  246. data/spec/model/class_dataset_methods_spec.rb +5 -9
  247. data/spec/model/dataset_methods_spec.rb +5 -5
  248. data/spec/model/eager_loading_spec.rb +209 -235
  249. data/spec/model/hooks_spec.rb +15 -15
  250. data/spec/model/model_spec.rb +28 -21
  251. data/spec/model/plugins_spec.rb +4 -5
  252. data/spec/model/record_spec.rb +59 -57
  253. data/spec/model/spec_helper.rb +1 -1
  254. data/spec/model/validations_spec.rb +6 -6
  255. data/spec/spec_config.rb +1 -1
  256. metadata +10 -2
@@ -3,7 +3,6 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe "instance_filters plugin" do
4
4
  before do
5
5
  @c = Class.new(Sequel::Model(:people))
6
- @c.dataset.quote_identifiers = false
7
6
  @c.columns :id, :name, :num
8
7
  @c.plugin :instance_filters
9
8
  @p = @c.load(:id=>1, :name=>'John', :num=>1)
@@ -14,7 +13,7 @@ describe "instance_filters plugin" do
14
13
  @p.update(:name=>'Bob')
15
14
  DB.sqls.must_equal ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
16
15
  @p.instance_filter(:name=>'Jim')
17
- @p.this.numrows = 0
16
+ @p.instance_variable_set(:@this, @p.this.with_numrows(0))
18
17
  proc{@p.update(:name=>'Joe')}.must_raise(Sequel::Plugins::InstanceFilters::Error)
19
18
  DB.sqls.must_equal ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"]
20
19
  end
@@ -23,7 +22,7 @@ describe "instance_filters plugin" do
23
22
  @p.destroy
24
23
  DB.sqls.must_equal ["DELETE FROM people WHERE id = 1"]
25
24
  @p.instance_filter(:name=>'Jim')
26
- @p.this.numrows = 0
25
+ @p.instance_variable_set(:@this, @p.this.with_numrows(0))
27
26
  proc{@p.destroy}.must_raise(Sequel::Plugins::InstanceFilters::Error)
28
27
  DB.sqls.must_equal ["DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"]
29
28
  end
@@ -34,16 +33,16 @@ describe "instance_filters plugin" do
34
33
  @p.update(:name=>'Bob')
35
34
  DB.sqls.must_equal ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
36
35
  @p.instance_filter(:name=>'Jim')
37
- @p.this.numrows = 0
36
+ @p.instance_variable_set(:@this, @p.this.with_numrows(0))
38
37
  proc{@p.update(:name=>'Joe')}.must_raise(Sequel::Plugins::InstanceFilters::Error)
39
38
  DB.sqls.must_equal ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"]
40
39
 
41
40
  @p = @c.load(:id=>1, :name=>'John', :num=>1)
42
- @p.this.numrows = 1
41
+ @p.instance_variable_set(:@this, @p.this.with_numrows(1))
43
42
  @p.destroy
44
43
  DB.sqls.must_equal ["DELETE FROM people WHERE (id = 1)"]
45
44
  @p.instance_filter(:name=>'Jim')
46
- @p.this.numrows = 0
45
+ @p.instance_variable_set(:@this, @p.this.with_numrows(0))
47
46
  proc{@p.destroy}.must_raise(Sequel::Plugins::InstanceFilters::Error)
48
47
  DB.sqls.must_equal ["DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"]
49
48
 
@@ -28,10 +28,10 @@ describe "InstanceHooks plugin" do
28
28
  @o.after_create_hook{r 1}
29
29
  @o.before_create_hook{r false}
30
30
  @o.before_create_hook{r 4}
31
- @o.save.must_equal nil
31
+ @o.save.must_be_nil
32
32
  @r.must_equal [4, false]
33
33
  @r.clear
34
- @o.save.must_equal nil
34
+ @o.save.must_be_nil
35
35
  @r.must_equal [4, false]
36
36
  end
37
37
 
@@ -50,10 +50,10 @@ describe "InstanceHooks plugin" do
50
50
  @x.after_update_hook{r 1}
51
51
  @x.before_update_hook{r false}
52
52
  @x.before_update_hook{r 4}
53
- @x.save.must_equal nil
53
+ @x.save.must_be_nil
54
54
  @r.must_equal [4, false]
55
55
  @r.clear
56
- @x.save.must_equal nil
56
+ @x.save.must_be_nil
57
57
  @r.must_equal [4, false]
58
58
  end
59
59
 
@@ -80,17 +80,17 @@ describe "InstanceHooks plugin" do
80
80
  @x.after_save_hook{r 1}
81
81
  @x.before_save_hook{r false}
82
82
  @x.before_save_hook{r 4}
83
- @x.save.must_equal nil
83
+ @x.save.must_be_nil
84
84
  @r.must_equal [4, false]
85
85
  @r.clear
86
86
 
87
87
  @x.after_save_hook{r 1}
88
88
  @x.before_save_hook{r false}
89
89
  @x.before_save_hook{r 4}
90
- @x.save.must_equal nil
90
+ @x.save.must_be_nil
91
91
  @r.must_equal [4, false]
92
92
  @r.clear
93
- @x.save.must_equal nil
93
+ @x.save.must_be_nil
94
94
  @r.must_equal [4, false]
95
95
  end
96
96
 
@@ -107,7 +107,7 @@ describe "InstanceHooks plugin" do
107
107
  @x.after_destroy_hook{r 1}
108
108
  @x.before_destroy_hook{r false}
109
109
  @x.before_destroy_hook{r 4}
110
- @x.destroy.must_equal nil
110
+ @x.destroy.must_be_nil
111
111
  @r.must_equal [4, false]
112
112
  end
113
113
 
@@ -180,9 +180,9 @@ describe "InstanceHooks plugin" do
180
180
  it "should not clear validations hooks on successful save" do
181
181
  @x.after_validation_hook{@x.errors.add(:id, 'a') if @x.id == 1; r 1}
182
182
  @x.before_validation_hook{r 2}
183
- @x.save.must_equal nil
183
+ @x.save.must_be_nil
184
184
  @r.must_equal [2, 1]
185
- @x.save.must_equal nil
185
+ @x.save.must_be_nil
186
186
  @r.must_equal [2, 1, 2, 1]
187
187
  @x.id = 2
188
188
  @x.save.must_equal @x
@@ -237,7 +237,7 @@ describe "InstanceHooks plugin with transactions" do
237
237
  it "should support after_rollback_hook" do
238
238
  @or.after_rollback_hook{@db.execute('ar1')}
239
239
  @or.after_rollback_hook{@db.execute('ar2')}
240
- @or.save.must_equal nil
240
+ @or.save.must_be_nil
241
241
  @db.sqls.must_equal ['BEGIN', 'as', 'ROLLBACK', 'ar1', 'ar2']
242
242
  end
243
243
 
@@ -251,7 +251,7 @@ describe "InstanceHooks plugin with transactions" do
251
251
  it "should support after_rollback_hook" do
252
252
  @or.after_destroy_rollback_hook{@db.execute('adr1')}
253
253
  @or.after_destroy_rollback_hook{@db.execute('adr2')}
254
- @or.destroy.must_equal nil
254
+ @or.destroy.must_be_nil
255
255
  @db.sqls.must_equal ['BEGIN', "DELETE FROM items WHERE (id = 1)", 'ad', 'ROLLBACK', 'adr1', 'adr2']
256
256
  end
257
257
 
@@ -174,16 +174,15 @@ describe "Sequel::Plugins::JsonSerializer" do
174
174
  end
175
175
 
176
176
  it "should support a to_json class and dataset method" do
177
- Album.dataset._fetch = {:id=>1, :name=>'RF', :artist_id=>2}
178
- Artist.dataset._fetch = {:id=>2, :name=>'YJM'}
177
+ Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
178
+ Artist.dataset = Artist.dataset.with_fetch(:id=>2, :name=>'YJM')
179
179
  Album.array_from_json(Album.to_json).must_equal [@album]
180
180
  Album.array_from_json(Album.to_json(:include=>:artist), :associations=>:artist).map{|x| x.artist}.must_equal [@artist]
181
181
  Album.array_from_json(Album.dataset.to_json(:only=>:name)).must_equal [Album.load(:name=>@album.name)]
182
182
  end
183
183
 
184
184
  it "should have dataset to_json method work with naked datasets" do
185
- ds = Album.dataset.naked
186
- ds._fetch = {:id=>1, :name=>'RF', :artist_id=>2}
185
+ ds = Album.dataset.naked.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
187
186
  Sequel.parse_json(ds.to_json).must_equal [@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}]
188
187
  end
189
188
 
@@ -227,7 +226,7 @@ describe "Sequel::Plugins::JsonSerializer" do
227
226
  end
228
227
  end
229
228
  Namespace::Album.new({}).to_json(:root=>true).to_s.must_equal '{"album":{}}'
230
- Namespace::Album.dataset._fetch = [{}]
229
+ Namespace::Album.dataset = Namespace::Album.dataset.with_fetch([{}])
231
230
  Namespace::Album.dataset.to_json(:root=>:collection).to_s.must_equal '{"albums":[{}]}'
232
231
  Namespace::Album.dataset.to_json(:root=>:both).to_s.must_equal '{"albums":[{"album":{}}]}'
233
232
  Object.send(:remove_const, :Namespace)
@@ -239,25 +238,23 @@ describe "Sequel::Plugins::JsonSerializer" do
239
238
  end
240
239
 
241
240
  it "should handle the :root=>:both option to qualify a dataset of records" do
242
- Album.dataset._fetch = [{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]
243
- Album.dataset.to_json(:root=>:both, :only => :id).to_s.must_equal '{"albums":[{"album":{"id":1}},{"album":{"id":1}}]}'
241
+ Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]).to_json(:root=>:both, :only => :id).to_s.must_equal '{"albums":[{"album":{"id":1}},{"album":{"id":1}}]}'
244
242
  end
245
243
 
246
244
  it "should handle the :root=>:collection option to qualify just the collection" do
247
- Album.dataset._fetch = [{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]
248
- Album.dataset.to_json(:root=>:collection, :only => :id).to_s.must_equal '{"albums":[{"id":1},{"id":1}]}'
249
- Album.dataset.to_json(:root=>true, :only => :id).to_s.must_equal '{"albums":[{"id":1},{"id":1}]}'
245
+ ds = Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}])
246
+ ds.to_json(:root=>:collection, :only => :id).to_s.must_equal '{"albums":[{"id":1},{"id":1}]}'
247
+ ds.to_json(:root=>true, :only => :id).to_s.must_equal '{"albums":[{"id":1},{"id":1}]}'
250
248
  end
251
249
 
252
250
  it "should handle the :root=>:instance option to qualify just the instances" do
253
- Album.dataset._fetch = [{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]
254
- Album.dataset.to_json(:root=>:instance, :only => :id).to_s.must_equal '[{"album":{"id":1}},{"album":{"id":1}}]'
251
+ Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]).to_json(:root=>:instance, :only => :id).to_s.must_equal '[{"album":{"id":1}},{"album":{"id":1}}]'
255
252
  end
256
253
 
257
254
  it "should handle the :root=>string option to qualify just the collection using the string as the key" do
258
- Album.dataset._fetch = [{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}]
259
- Album.dataset.to_json(:root=>"foos", :only => :id).to_s.must_equal '{"foos":[{"id":1},{"id":1}]}'
260
- Album.dataset.to_json(:root=>"bars", :only => :id).to_s.must_equal '{"bars":[{"id":1},{"id":1}]}'
255
+ ds = Album.dataset.with_fetch([{:id=>1, :name=>'RF'}, {:id=>1, :name=>'RF'}])
256
+ ds.to_json(:root=>"foos", :only => :id).to_s.must_equal '{"foos":[{"id":1},{"id":1}]}'
257
+ ds.to_json(:root=>"bars", :only => :id).to_s.must_equal '{"bars":[{"id":1},{"id":1}]}'
261
258
  end
262
259
 
263
260
  it "should use an alias for an included asscociation to qualify an association" do
@@ -12,7 +12,7 @@ describe "Sequel::Plugins::LazyAttributes" do
12
12
  meta_def(:columns){[:id, :name]}
13
13
  lazy_attributes :name
14
14
  meta_def(:columns){[:id]}
15
- instance_dataset._fetch = dataset._fetch = proc do |sql|
15
+ set_dataset dataset.with_fetch(proc do |sql|
16
16
  if sql !~ /WHERE/
17
17
  if sql =~ /name/
18
18
  [{:id=>1, :name=>'1'}, {:id=>2, :name=>'2'}]
@@ -32,7 +32,7 @@ describe "Sequel::Plugins::LazyAttributes" do
32
32
  end
33
33
  end
34
34
  end
35
- end
35
+ end)
36
36
  end
37
37
  @c = ::LazyAttributesModel
38
38
  @ds = LazyAttributesModel.dataset
@@ -108,7 +108,7 @@ describe "Sequel::Plugins::LazyAttributes" do
108
108
  it "should not lazily load the attribute for a single model object if it is a new record" do
109
109
  m = @c.new
110
110
  m.values.must_equal({})
111
- m.name.must_equal nil
111
+ m.name.must_be_nil
112
112
  @db.sqls.must_equal []
113
113
  end
114
114
 
@@ -148,7 +148,7 @@ describe "Sequel::Plugins::LazyAttributes" do
148
148
 
149
149
  it "should work with the serialization plugin" do
150
150
  @c.plugin :serialization, :yaml, :name
151
- @c.instance_dataset._fetch = @ds._fetch = [[{:id=>1}, {:id=>2}], [{:id=>1, :name=>"--- 3\n"}, {:id=>2, :name=>"--- 6\n"}], [{:id=>1}], [{:name=>"--- 3\n"}]]
151
+ @ds = @c.dataset = @ds.with_fetch([[{:id=>1}, {:id=>2}], [{:id=>1, :name=>"--- 3\n"}, {:id=>2, :name=>"--- 6\n"}], [{:id=>1}], [{:name=>"--- 3\n"}]])
152
152
  ms = @ds.all
153
153
  ms.map{|m| m.values}.must_equal [{:id=>1}, {:id=>2}]
154
154
  ms.map{|m| m.name}.must_equal [3,6]
@@ -56,7 +56,7 @@ describe "List plugin" do
56
56
  end
57
57
 
58
58
  it "should be able to access the scope proc as a class attribute" do
59
- @c.scope_proc.must_equal nil
59
+ @c.scope_proc.must_be_nil
60
60
  @sc.scope_proc[@sc.new(:scope_id=>4)].sql.must_equal 'SELECT * FROM items WHERE (scope_id = 4) ORDER BY scope_id, position'
61
61
  end
62
62
 
@@ -67,17 +67,16 @@ describe "List plugin" do
67
67
  end
68
68
 
69
69
  it "should have at_position return the model object at the given position" do
70
- @c.dataset._fetch = {:id=>1, :position=>1}
70
+ @c.dataset = @c.dataset.with_fetch(:id=>1, :position=>1)
71
71
  @o.at_position(10).must_equal @c.load(:id=>1, :position=>1)
72
- @sc.dataset._fetch = {:id=>2, :position=>2, :scope_id=>5}
72
+ @sc.dataset = @sc.dataset.with_fetch(:id=>2, :position=>2, :scope_id=>5)
73
73
  @so.at_position(20).must_equal @sc.load(:id=>2, :position=>2, :scope_id=>5)
74
74
  @db.sqls.must_equal ["SELECT * FROM items WHERE (position = 10) ORDER BY position LIMIT 1",
75
75
  "SELECT * FROM items WHERE ((scope_id = 5) AND (position = 20)) ORDER BY scope_id, position LIMIT 1"]
76
76
  end
77
77
 
78
78
  it "should have position field set to max+1 when creating if not already set" do
79
- @c.instance_dataset._fetch = @c.dataset._fetch = [[{:pos=>nil}], [{:id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :position=>2}]]
80
- @c.instance_dataset.autoid = @c.dataset.autoid = 1
79
+ @c.dataset = @c.dataset.with_autoid(1).with_fetch([[{:pos=>nil}], [{:id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :position=>2}]])
81
80
  @c.create.values.must_equal(:id=>1, :position=>1)
82
81
  @c.create.values.must_equal(:id=>2, :position=>2)
83
82
  @db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
@@ -89,8 +88,7 @@ describe "List plugin" do
89
88
  end
90
89
 
91
90
  it "should have position field set to max+1 in scope when creating if not already set" do
92
- @sc.instance_dataset._fetch = @sc.dataset._fetch = [[{:pos=>nil}], [{:id=>1, :scope_id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :scope_id=>1, :position=>2}], [{:pos=>nil}], [{:id=>3, :scope_id=>2, :position=>1}]]
93
- @sc.instance_dataset.autoid = @sc.dataset.autoid = 1
91
+ @sc.dataset = @sc.dataset.with_autoid(1).with_fetch([[{:pos=>nil}], [{:id=>1, :scope_id=>1, :position=>1}], [{:pos=>1}], [{:id=>2, :scope_id=>1, :position=>2}], [{:pos=>nil}], [{:id=>3, :scope_id=>2, :position=>1}]])
94
92
  @sc.create(:scope_id=>1).values.must_equal(:id=>1, :scope_id=>1, :position=>1)
95
93
  @sc.create(:scope_id=>1).values.must_equal(:id=>2, :scope_id=>1, :position=>2)
96
94
  @sc.create(:scope_id=>2).values.must_equal(:id=>3, :scope_id=>2, :position=>1)
@@ -112,9 +110,9 @@ describe "List plugin" do
112
110
  end
113
111
 
114
112
  it "should have last_position return the last position in the list" do
115
- @c.dataset._fetch = {:max=>10}
113
+ @c.dataset = @c.dataset.with_fetch(:max=>10)
116
114
  @o.last_position.must_equal 10
117
- @sc.dataset._fetch = {:max=>20}
115
+ @sc.dataset = @sc.dataset.with_fetch(:max=>20)
118
116
  @so.last_position.must_equal 20
119
117
  @db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
120
118
  "SELECT max(position) AS max FROM items WHERE (scope_id = 5) LIMIT 1"]
@@ -129,7 +127,7 @@ describe "List plugin" do
129
127
  end
130
128
 
131
129
  it "should have move_down without an argument move down a single position" do
132
- @c.dataset._fetch = {:max=>10}
130
+ @c.dataset = @c.dataset.with_fetch(:max=>10)
133
131
  @o.move_down.must_equal @o
134
132
  @o.position.must_equal 4
135
133
  @db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
@@ -138,7 +136,7 @@ describe "List plugin" do
138
136
  end
139
137
 
140
138
  it "should have move_down with an argument move down the given number of positions" do
141
- @c.dataset._fetch = {:max=>10}
139
+ @c.dataset = @c.dataset.with_fetch(:max=>10)
142
140
  @o.move_down(3).must_equal @o
143
141
  @o.position.must_equal 6
144
142
  @db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
@@ -156,7 +154,7 @@ describe "List plugin" do
156
154
  it "should have move_to handle out of range targets" do
157
155
  @o.move_to(0)
158
156
  @o.position.must_equal 1
159
- @c.dataset._fetch = {:max=>10}
157
+ @c.dataset = @c.dataset.with_fetch(:max=>10)
160
158
  @o.move_to(11)
161
159
  @o.position.must_equal 10
162
160
  end
@@ -183,13 +181,13 @@ describe "List plugin" do
183
181
  end
184
182
 
185
183
  it "should have move to shift entries correctly between current and target if moving down" do
186
- @c.dataset._fetch = {:max=>10}
184
+ @c.dataset = @c.dataset.with_fetch(:max=>10)
187
185
  @o.move_to(4)
188
186
  @db.sqls[1].must_equal "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 4))"
189
187
  end
190
188
 
191
189
  it "should have move_to_bottom move the item to the last position" do
192
- @c.dataset._fetch = {:max=>10}
190
+ @c.dataset = @c.dataset.with_fetch(:max=>10)
193
191
  @o.move_to_bottom
194
192
  @db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
195
193
  "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 10))",
@@ -217,7 +215,7 @@ describe "List plugin" do
217
215
  end
218
216
 
219
217
  it "should have move_up with a negative argument move down the given number of positions" do
220
- @c.dataset._fetch = {:max=>10}
218
+ @c.dataset = @c.dataset.with_fetch(:max=>10)
221
219
  @o.move_up(-1).must_equal @o
222
220
  @o.position.must_equal 4
223
221
  @db.sqls.must_equal ["SELECT max(position) AS max FROM items LIMIT 1",
@@ -226,19 +224,19 @@ describe "List plugin" do
226
224
  end
227
225
 
228
226
  it "should have next return the next entry in the list if not given an argument" do
229
- @c.dataset._fetch = {:id=>9, :position=>4}
227
+ @c.dataset = @c.dataset.with_fetch(:id=>9, :position=>4)
230
228
  @o.next.must_equal @c.load(:id=>9, :position=>4)
231
229
  @db.sqls.must_equal ["SELECT * FROM items WHERE (position = 4) ORDER BY position LIMIT 1"]
232
230
  end
233
231
 
234
232
  it "should have next return the entry the given number of positions below the instance if given an argument" do
235
- @c.dataset._fetch = {:id=>9, :position=>5}
233
+ @c.dataset = @c.dataset.with_fetch(:id=>9, :position=>5)
236
234
  @o.next(2).must_equal @c.load(:id=>9, :position=>5)
237
235
  @db.sqls.must_equal ["SELECT * FROM items WHERE (position = 5) ORDER BY position LIMIT 1"]
238
236
  end
239
237
 
240
238
  it "should have next return a previous entry if given a negative argument" do
241
- @c.dataset._fetch = {:id=>9, :position=>2}
239
+ @c.dataset = @c.dataset.with_fetch(:id=>9, :position=>2)
242
240
  @o.next(-1).must_equal @c.load(:id=>9, :position=>2)
243
241
  @db.sqls.must_equal ["SELECT * FROM items WHERE (position = 2) ORDER BY position LIMIT 1"]
244
242
  end
@@ -248,19 +246,19 @@ describe "List plugin" do
248
246
  end
249
247
 
250
248
  it "should have prev return the previous entry in the list if not given an argument" do
251
- @c.dataset._fetch = {:id=>9, :position=>2}
249
+ @c.dataset = @c.dataset.with_fetch(:id=>9, :position=>2)
252
250
  @o.prev.must_equal @c.load(:id=>9, :position=>2)
253
251
  @db.sqls.must_equal ["SELECT * FROM items WHERE (position = 2) ORDER BY position LIMIT 1"]
254
252
  end
255
253
 
256
254
  it "should have prev return the entry the given number of positions above the instance if given an argument" do
257
- @c.dataset._fetch = {:id=>9, :position=>1}
255
+ @c.dataset = @c.dataset.with_fetch(:id=>9, :position=>1)
258
256
  @o.prev(2).must_equal @c.load(:id=>9, :position=>1)
259
257
  @db.sqls.must_equal ["SELECT * FROM items WHERE (position = 1) ORDER BY position LIMIT 1"]
260
258
  end
261
259
 
262
260
  it "should have prev return a following entry if given a negative argument" do
263
- @c.dataset._fetch = {:id=>9, :position=>4}
261
+ @c.dataset = @c.dataset.with_fetch(:id=>9, :position=>4)
264
262
  @o.prev(-1).must_equal @c.load(:id=>9, :position=>4)
265
263
  @db.sqls.must_equal ["SELECT * FROM items WHERE (position = 4) ORDER BY position LIMIT 1"]
266
264
  end
@@ -12,8 +12,7 @@ describe Sequel::Model, "many_through_many" do
12
12
  end
13
13
  @c1 = Artist
14
14
  @c2 = Tag
15
- @dataset = @c2.dataset
16
- @dataset._fetch = {:id=>1}
15
+ @dataset = @c2.dataset = @c2.dataset.with_fetch(:id=>1)
17
16
  DB.reset
18
17
  end
19
18
  after do
@@ -50,8 +49,8 @@ describe Sequel::Model, "many_through_many" do
50
49
 
51
50
  it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
52
51
  @c1.send(:define_method, :id3){id*3}
53
- @c1.dataset._fetch = {:id=>1}
54
- @c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>3}
52
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1)
53
+ @c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>3)
55
54
  @c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:id3
56
55
  a = @c1.eager(:tags).all
57
56
  a.must_equal [@c1.load(:id => 1)]
@@ -61,8 +60,8 @@ describe Sequel::Model, "many_through_many" do
61
60
  end
62
61
 
63
62
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
64
- @c1.dataset._fetch = {:id=>1}
65
- @c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>1}
63
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1)
64
+ @c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
66
65
  @c1.many_through_many :tags, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel./(:albums_artists__artist_id, 3)
67
66
  a = @c1.eager(:tags).all
68
67
  a.must_equal [@c1.load(:id => 1)]
@@ -74,12 +73,13 @@ describe Sequel::Model, "many_through_many" do
74
73
  @c1.many_through_many :tags, :through=>[[:myschema__albums_artists, :artist_id, :album_id], [:myschema__albums, :id, :id], [:myschema__albums_tags, :album_id, :tag_id]]
75
74
  @c1.load(:id=>1).tags_dataset.sql.must_equal "SELECT tags.* FROM tags INNER JOIN myschema.albums_tags ON (myschema.albums_tags.tag_id = tags.id) INNER JOIN myschema.albums ON (myschema.albums.id = myschema.albums_tags.album_id) INNER JOIN myschema.albums_artists ON (myschema.albums_artists.album_id = myschema.albums.id) WHERE (myschema.albums_artists.artist_id = 1)"
76
75
 
77
- @c1.dataset._fetch = {:id=>1}
78
- @c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>1}
76
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1)
77
+ @c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
79
78
  a = @c1.eager(:tags).all
80
79
  a.must_equal [@c1.load(:id => 1)]
81
80
  DB.sqls.must_equal ['SELECT * FROM artists', "SELECT tags.*, myschema.albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN myschema.albums_tags ON (myschema.albums_tags.tag_id = tags.id) INNER JOIN myschema.albums ON (myschema.albums.id = myschema.albums_tags.album_id) INNER JOIN myschema.albums_artists ON (myschema.albums_artists.album_id = myschema.albums.id) WHERE (myschema.albums_artists.artist_id IN (1))"]
82
81
 
82
+ Tag.dataset.columns(:id, :h1, :h2)
83
83
  @c1.eager_graph(:tags).sql.must_equal 'SELECT artists.id, tags.id AS tags_id, tags.h1, tags.h2 FROM artists LEFT OUTER JOIN myschema.albums_artists AS albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN myschema.albums AS albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN myschema.albums_tags AS albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)'
84
84
  end
85
85
 
@@ -200,25 +200,25 @@ describe Sequel::Model, "many_through_many" do
200
200
  end
201
201
 
202
202
  it "should allowing filtering by many_through_many associations with :limit" do
203
- def (@c2.dataset).supports_window_functions?; true end
203
+ @c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
204
204
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :limit=>10
205
205
  @c1.filter(:tags=>@c2.load(:id=>1234)).sql.must_equal 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT b, c FROM (SELECT albums_artists.artist_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1234))))'
206
206
  end
207
207
 
208
208
  it "should allowing filtering by many_through_many associations with :limit and composite keys" do
209
- def (@c2.dataset).supports_window_functions?; true end
209
+ @c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
210
210
  @c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :limit=>10
211
211
  @c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT b, c, d FROM (SELECT albums_artists.b1 AS b, albums_artists.b2 AS c, tags.id AS d, row_number() OVER (PARTITION BY albums_artists.b1, albums_artists.b2) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2))) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1))))'
212
212
  end
213
213
 
214
214
  it "should allowing filtering by many_through_many associations with :limit and :conditions" do
215
- def (@c2.dataset).supports_window_functions?; true end
215
+ @c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
216
216
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}, :limit=>10
217
217
  @c1.filter(:tags=>@c2.load(:id=>1234)).sql.must_equal "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT b, c FROM (SELECT albums_artists.artist_id AS b, tags.id AS c, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (name = 'A')) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1234))))"
218
218
  end
219
219
 
220
220
  it "should allowing filtering by many_through_many associations with :limit and :conditions and composite keys" do
221
- def (@c2.dataset).supports_window_functions?; true end
221
+ @c2.dataset = @c2.dataset.with_extend{def supports_window_functions?; true end}
222
222
  @c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}, :limit=>10
223
223
  @c1.filter(:tags=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT b, c, d FROM (SELECT albums_artists.b1 AS b, albums_artists.b2 AS c, tags.id AS d, row_number() OVER (PARTITION BY albums_artists.b1, albums_artists.b2) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE (name = 'A')) AS t1 WHERE (x_sequel_row_number_x <= 10))) AND (tags.id = 1))))"
224
224
  end
@@ -419,7 +419,7 @@ describe Sequel::Model, "many_through_many" do
419
419
  it "should populate cache when accessed" do
420
420
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
421
421
  n = @c1.load(:id => 1234)
422
- n.associations[:tags].must_equal nil
422
+ n.associations[:tags].must_be_nil
423
423
  DB.sqls.must_equal []
424
424
  n.tags.must_equal [@c2.load(:id=>1)]
425
425
  DB.sqls.must_equal ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234)']
@@ -465,7 +465,7 @@ describe Sequel::Model, "many_through_many" do
465
465
  v.each{|x| model::Foo << x.pk * 20}
466
466
  end
467
467
  end
468
- @c2.dataset._fetch = [{:id=>20}, {:id=>30}]
468
+ @c2.dataset = @c2.dataset.with_fetch([{:id=>20}, {:id=>30}])
469
469
  p = @c1.load(:id=>10, :parent_id=>20)
470
470
  p.tags
471
471
  h.must_equal [400, 600]
@@ -474,7 +474,7 @@ describe Sequel::Model, "many_through_many" do
474
474
 
475
475
  it "should support a :uniq option that removes duplicates from the association" do
476
476
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :uniq=>true
477
- @c2.dataset._fetch = [{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}]
477
+ @c2.dataset = @c2.dataset.with_fetch([{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}])
478
478
  @c1.load(:id=>10).tags.must_equal [@c2.load(:id=>20), @c2.load(:id=>30)]
479
479
  end
480
480
  end
@@ -514,7 +514,7 @@ describe 'Sequel::Plugins::ManyThroughMany::ManyThroughManyAssociationReflection
514
514
  end
515
515
 
516
516
  it "#reciprocal should be nil" do
517
- @ar.reciprocal.must_equal nil
517
+ @ar.reciprocal.must_be_nil
518
518
  end
519
519
  end
520
520
 
@@ -535,7 +535,7 @@ describe "many_through_many eager loading methods" do
535
535
  end
536
536
  class ::Track < Sequel::Model
537
537
  end
538
- Artist.dataset.columns(:id)._fetch = proc do |sql|
538
+ Artist.dataset = Artist.dataset.with_fetch(proc do |sql|
539
539
  h = {:id => 1}
540
540
  if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
541
541
  h[:tags_id] = 2
@@ -545,9 +545,10 @@ describe "many_through_many eager loading methods" do
545
545
  h[:artists_0_id] = 10 if sql =~ /artists_0\.id AS artists_0_id/
546
546
  end
547
547
  h
548
- end
548
+ end)
549
+ Artist.dataset.columns(:id)
549
550
 
550
- Tag.dataset._fetch = proc do |sql|
551
+ Tag.dataset = Tag.dataset.with_fetch(proc do |sql|
551
552
  h = {:id => 2}
552
553
  if sql =~ /albums_artists.artist_id IN \(([18])\)/
553
554
  h[:x_foreign_key_x] = $1.to_i
@@ -556,19 +557,19 @@ describe "many_through_many eager loading methods" do
556
557
  end
557
558
  h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
558
559
  h
559
- end
560
+ end)
560
561
 
561
- Album.dataset._fetch = proc do |sql|
562
+ Album.dataset = Album.dataset.with_fetch(proc do |sql|
562
563
  h = {:id => 3}
563
564
  h[:x_foreign_key_x] = 1 if sql =~ /albums_artists.artist_id IN \(1\)/
564
565
  h
565
- end
566
+ end)
566
567
 
567
- Track.dataset._fetch = proc do |sql|
568
+ Track.dataset = Track.dataset.with_fetch(proc do |sql|
568
569
  h = {:id => 4}
569
570
  h[:x_foreign_key_x] = 2 if sql =~ /albums_tags.tag_id IN \(2\)/
570
571
  h
571
- end
572
+ end)
572
573
 
573
574
  @c1 = Artist
574
575
  DB.reset
@@ -654,12 +655,7 @@ describe "many_through_many eager loading methods" do
654
655
  end
655
656
 
656
657
  it "should respect :eager_graph when lazily loading an association" do
657
- Tag.dataset._fetch = {:id=>2, :tracks_id=>4}
658
- Tag.dataset.extend(Module.new {
659
- def columns
660
- [:id]
661
- end
662
- })
658
+ Tag.dataset = Tag.dataset.with_fetch(:id=>2, :tracks_id=>4).with_extend{def columns; [:id] end}
663
659
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:tracks
664
660
  a = @c1.load(:id=>1)
665
661
  a.tags
@@ -711,7 +707,7 @@ describe "many_through_many eager loading methods" do
711
707
 
712
708
  it "should respect the :limit option on a many_through_many association" do
713
709
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2
714
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
710
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}])
715
711
  a = @c1.eager(:first_two_tags).all
716
712
  a.must_equal [@c1.load(:id=>1)]
717
713
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -720,7 +716,7 @@ describe "many_through_many eager loading methods" do
720
716
  DB.sqls.length.must_equal 0
721
717
 
722
718
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[1,1]
723
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>6}]
719
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>6}])
724
720
  a = @c1.eager(:first_two_tags).all
725
721
  a.must_equal [@c1.load(:id=>1)]
726
722
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -729,7 +725,7 @@ describe "many_through_many eager loading methods" do
729
725
  DB.sqls.length.must_equal 0
730
726
 
731
727
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1]
732
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}]
728
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}])
733
729
  a = @c1.eager(:first_two_tags).all
734
730
  a.must_equal [@c1.load(:id=>1)]
735
731
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -740,7 +736,7 @@ describe "many_through_many eager loading methods" do
740
736
 
741
737
  it "should respect the :limit option on a many_through_many association using a :ruby strategy" do
742
738
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>:ruby
743
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}]
739
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}, {:x_foreign_key_x=>1, :id=>7}])
744
740
  a = @c1.eager(:first_two_tags).all
745
741
  a.must_equal [@c1.load(:id=>1)]
746
742
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -766,9 +762,8 @@ describe "many_through_many eager loading methods" do
766
762
  end
767
763
 
768
764
  it "should respect the :limit option on a many_through_many association using a :window_function strategy" do
769
- Tag.dataset.meta_def(:supports_window_functions?){true}
770
765
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name, :eager_limit_strategy=>:window_function
771
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
766
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]).with_extend{def supports_window_functions?; true end}
772
767
  a = @c1.eager(:first_two_tags).all
773
768
  a.must_equal [@c1.load(:id=>1)]
774
769
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -794,12 +789,11 @@ describe "many_through_many eager loading methods" do
794
789
  end
795
790
 
796
791
  it "should respect the :limit option on a many_through_many association with composite primary keys on the main table" do
797
- Tag.dataset.meta_def(:supports_window_functions?){true}
792
+ @c1.dataset = @c1.dataset.with_fetch([{:id1=>1, :id2=>2}])
793
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]).with_extend{def supports_window_functions?; true end}
798
794
  @c1.set_primary_key([:id1, :id2])
799
795
  @c1.columns :id1, :id2
800
796
  @c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name
801
- @c1.dataset._fetch = [{:id1=>1, :id2=>2}]
802
- Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]
803
797
  a = @c1.eager(:first_two_tags).all
804
798
  a.must_equal [@c1.load(:id1=>1, :id2=>2)]
805
799
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -817,12 +811,11 @@ describe "many_through_many eager loading methods" do
817
811
  end
818
812
 
819
813
  it "should respect the :limit option on a many_through_many association with composite primary keys on the main table using a :window_function strategy" do
820
- Tag.dataset.meta_def(:supports_window_functions?){true}
814
+ @c1.dataset = @c1.dataset.with_fetch([{:id1=>1, :id2=>2}])
815
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]).with_extend{def supports_window_functions?; true end}
821
816
  @c1.set_primary_key([:id1, :id2])
822
817
  @c1.columns :id1, :id2
823
818
  @c1.many_through_many :first_two_tags, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :order=>:name, :eager_limit_strategy=>:window_function
824
- @c1.dataset._fetch = [{:id1=>1, :id2=>2}]
825
- Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}, {:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>6}]
826
819
  a = @c1.eager(:first_two_tags).all
827
820
  a.must_equal [@c1.load(:id1=>1, :id2=>2)]
828
821
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -857,8 +850,7 @@ describe "many_through_many eager loading methods" do
857
850
 
858
851
  it "should respect many_through_many association's :left_primary_key and :right_primary_key options" do
859
852
  @c1.send(:define_method, :yyy){values[:yyy]}
860
- @c1.dataset._fetch = {:id=>1, :yyy=>8}
861
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
853
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
862
854
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
863
855
  a = @c1.eager(:tags).all
864
856
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
@@ -870,8 +862,7 @@ describe "many_through_many eager loading methods" do
870
862
 
871
863
  it "should handle composite keys" do
872
864
  @c1.send(:define_method, :yyy){values[:yyy]}
873
- @c1.dataset._fetch = {:id=>1, :yyy=>8}
874
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
865
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
875
866
  @c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
876
867
  a = @c1.eager(:tags).all
877
868
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
@@ -912,12 +903,12 @@ describe "many_through_many eager loading methods" do
912
903
  end
913
904
 
914
905
  it "should eagerly graph a single many_through_many association using the :window_function strategy" do
915
- def (Tag.dataset).supports_window_functions?() true end
916
- def (Tag.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
906
+ Tag.dataset = Tag.dataset.with_extend do
907
+ def supports_window_functions?; true end
908
+ def columns; literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
909
+ end
917
910
  @c1.many_through_many :tags, :clone=>:tags, :limit=>2
918
- ds = @c1.eager_graph_with_options(:tags, :limit_strategy=>true)
919
- ds._fetch = {:id=>1, :tags_id=>2}
920
- a = ds.all
911
+ a = @c1.eager_graph_with_options(:tags, :limit_strategy=>true).with_fetch(:id=>1, :tags_id=>2).all
921
912
  a.must_equal [@c1.load(:id=>1)]
922
913
  DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x <= 2)) AS tags ON (tags.x_foreign_key_x = artists.id)']
923
914
  a.first.tags.must_equal [Tag.load(:id=>2)]
@@ -955,10 +946,7 @@ describe "many_through_many eager loading methods" do
955
946
  end
956
947
 
957
948
  it "eager graphing should eliminate duplicates caused by cartesian products" do
958
- ds = @c1.eager_graph(:tags)
959
- # Assume artist has 2 albums each with 2 tags
960
- ds._fetch = [{:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}, {:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}]
961
- a = ds.all
949
+ a = @c1.eager_graph(:tags).with_fetch([{:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}, {:id=>1, :tags_id=>2}, {:id=>1, :tags_id=>3}]).all
962
950
  a.must_equal [@c1.load(:id=>1)]
963
951
  DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
964
952
  a.first.tags.must_equal [Tag.load(:id=>2), Tag.load(:id=>3)]
@@ -1001,9 +989,7 @@ describe "many_through_many eager loading methods" do
1001
989
  end
1002
990
 
1003
991
  it "should handle no associated records when eagerly graphing a single many_through_many association" do
1004
- ds = @c1.eager_graph(:tags)
1005
- ds._fetch = {:id=>1, :tags_id=>nil}
1006
- a = ds.all
992
+ a = @c1.eager_graph(:tags).with_fetch(:id=>1, :tags_id=>nil).all
1007
993
  a.must_equal [@c1.load(:id=>1)]
1008
994
  DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
1009
995
  a.first.tags.must_equal []
@@ -1011,9 +997,7 @@ describe "many_through_many eager loading methods" do
1011
997
  end
1012
998
 
1013
999
  it "should handle no associated records when eagerly graphing multiple many_through_many associations" do
1014
- ds = @c1.eager_graph(:tags, :albums)
1015
- ds._fetch = [{:id=>1, :tags_id=>nil, :albums_0_id=>3}, {:id=>1, :tags_id=>2, :albums_0_id=>nil}, {:id=>1, :tags_id=>5, :albums_0_id=>6}, {:id=>7, :tags_id=>nil, :albums_0_id=>nil}]
1016
- a = ds.all
1000
+ a = @c1.eager_graph(:tags, :albums).with_fetch([{:id=>1, :tags_id=>nil, :albums_0_id=>3}, {:id=>1, :tags_id=>2, :albums_0_id=>nil}, {:id=>1, :tags_id=>5, :albums_0_id=>6}, {:id=>7, :tags_id=>nil, :albums_0_id=>nil}]).all
1017
1001
  a.must_equal [@c1.load(:id=>1), @c1.load(:id=>7)]
1018
1002
  DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id, albums_0.id AS albums_0_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id)']
1019
1003
  a.first.tags.must_equal [Tag.load(:id=>2), Tag.load(:id=>5)]
@@ -1024,9 +1008,7 @@ describe "many_through_many eager loading methods" do
1024
1008
  end
1025
1009
 
1026
1010
  it "should handle missing associated records when cascading eager graphing for associations of associated models" do
1027
- ds = @c1.eager_graph(:tags=>:tracks)
1028
- ds._fetch = [{:id=>1, :tags_id=>2, :tracks_id=>4}, {:id=>1, :tags_id=>3, :tracks_id=>nil}, {:id=>2, :tags_id=>nil, :tracks_id=>nil}]
1029
- a = ds.all
1011
+ a = @c1.eager_graph(:tags=>:tracks).with_fetch([{:id=>1, :tags_id=>2, :tracks_id=>4}, {:id=>1, :tags_id=>3, :tracks_id=>nil}, {:id=>2, :tags_id=>nil, :tracks_id=>nil}]).all
1030
1012
  a.must_equal [@c1.load(:id=>1), @c1.load(:id=>2)]
1031
1013
  DB.sqls.must_equal ['SELECT artists.id, tags.id AS tags_id, tracks.id AS tracks_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tags.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks ON (tracks.album_id = albums_0.id)']
1032
1014
  a.last.tags.must_equal []
@@ -1039,11 +1021,9 @@ describe "many_through_many eager loading methods" do
1039
1021
 
1040
1022
  it "eager graphing should respect :left_primary_key and :right_primary_key options" do
1041
1023
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
1042
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
1043
- Tag.dataset.meta_def(:columns){[:id, :tag_id]}
1044
- ds = @c1.eager_graph(:tags)
1045
- ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
1046
- a = ds.all
1024
+ @c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
1025
+ Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
1026
+ a = @c1.eager_graph(:tags).with_fetch(:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4).all
1047
1027
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
1048
1028
  DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tags.id AS tags_id, tags.tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.yyy) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.tag_id = albums_tags.tag_id)']
1049
1029
  a.first.tags.must_equal [Tag.load(:id=>2, :tag_id=>4)]
@@ -1052,11 +1032,9 @@ describe "many_through_many eager loading methods" do
1052
1032
 
1053
1033
  it "eager graphing should respect composite keys" do
1054
1034
  @c1.many_through_many :tags, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:id, :tag_id], :left_primary_key=>[:id, :yyy]
1055
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
1056
- Tag.dataset.meta_def(:columns){[:id, :tag_id]}
1057
- ds = @c1.eager_graph(:tags)
1058
- ds._fetch = {:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4}
1059
- a = ds.all
1035
+ @c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
1036
+ Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
1037
+ a = @c1.eager_graph(:tags).with_fetch(:id=>1, :yyy=>8, :tags_id=>2, :tag_id=>4).all
1060
1038
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
1061
1039
  DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tags.id AS tags_id, tags.tag_id FROM artists LEFT OUTER JOIN albums_artists ON ((albums_artists.b1 = artists.id) AND (albums_artists.b2 = artists.yyy)) LEFT OUTER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) LEFT OUTER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) LEFT OUTER JOIN tags ON ((tags.id = albums_tags.g1) AND (tags.tag_id = albums_tags.g2))']
1062
1040
  a.first.tags.must_equal [Tag.load(:id=>2, :tag_id=>4)]
@@ -1065,9 +1043,7 @@ describe "many_through_many eager loading methods" do
1065
1043
 
1066
1044
  it "should respect the association's :graph_select option" do
1067
1045
  @c1.many_through_many :tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_select=>:b
1068
- ds = @c1.eager_graph(:tags)
1069
- ds._fetch = {:id=>1, :b=>2}
1070
- a = ds.all
1046
+ a = @c1.eager_graph(:tags).with_fetch(:id=>1, :b=>2).all
1071
1047
  a.must_equal [@c1.load(:id=>1)]
1072
1048
  DB.sqls.must_equal ['SELECT artists.id, tags.b FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags ON (tags.id = albums_tags.tag_id)']
1073
1049
  a.first.tags.must_equal [Tag.load(:b=>2)]
@@ -1216,8 +1192,7 @@ describe Sequel::Model, "one_through_many" do
1216
1192
  end
1217
1193
  @c1 = Artist
1218
1194
  @c2 = Tag
1219
- @dataset = @c2.dataset
1220
- @dataset._fetch = {:id=>1}
1195
+ @dataset = @c2.dataset = @c2.dataset.with_fetch(:id=>1)
1221
1196
  DB.reset
1222
1197
  end
1223
1198
  after do
@@ -1227,8 +1202,8 @@ describe Sequel::Model, "one_through_many" do
1227
1202
 
1228
1203
  it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
1229
1204
  @c1.send(:define_method, :id3){id*3}
1230
- @c1.dataset._fetch = {:id=>1}
1231
- @c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>3}
1205
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1)
1206
+ @c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>3)
1232
1207
  @c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:id3
1233
1208
  a = @c1.eager(:tag).all
1234
1209
  a.must_equal [@c1.load(:id => 1)]
@@ -1238,8 +1213,8 @@ describe Sequel::Model, "one_through_many" do
1238
1213
  end
1239
1214
 
1240
1215
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup" do
1241
- @c1.dataset._fetch = {:id=>1}
1242
- @c2.dataset._fetch = {:id=>4, :x_foreign_key_x=>1}
1216
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1)
1217
+ @c2.dataset = @c2.dataset.with_fetch(:id=>4, :x_foreign_key_x=>1)
1243
1218
  @c1.one_through_many :tag, :through=>[[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_loading_predicate_key=>Sequel./(:albums_artists__artist_id, 3)
1244
1219
  a = @c1.eager(:tag).all
1245
1220
  a.must_equal [@c1.load(:id => 1)]
@@ -1348,25 +1323,25 @@ describe Sequel::Model, "one_through_many" do
1348
1323
  end
1349
1324
 
1350
1325
  it "should allowing filtering by one_through_many associations with :order" do
1351
- def (@c2.dataset).supports_distinct_on?; true end
1326
+ @c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
1352
1327
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :order=>:name
1353
1328
  @c1.filter(:tag=>@c2.load(:id=>1234)).sql.must_equal 'SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT DISTINCT ON (albums_artists.artist_id) albums_artists.artist_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) ORDER BY albums_artists.artist_id, name)) AND (tags.id = 1234))))'
1354
1329
  end
1355
1330
 
1356
1331
  it "should allowing filtering by one_through_many associations with :order and composite keys" do
1357
- def (@c2.dataset).supports_distinct_on?; true end
1332
+ @c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
1358
1333
  @c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :order=>:name
1359
1334
  @c1.filter(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal 'SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT DISTINCT ON (albums_artists.b1, albums_artists.b2) albums_artists.b1, albums_artists.b2, tags.id FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) ORDER BY albums_artists.b1, albums_artists.b2, name)) AND (tags.id = 1))))'
1360
1335
  end
1361
1336
 
1362
1337
  it "should allowing filtering by one_through_many associations with :order and :conditions" do
1363
- def (@c2.dataset).supports_distinct_on?; true end
1338
+ @c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
1364
1339
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :conditions=>{:name=>'A'}, :order=>:name
1365
1340
  @c1.filter(:tag=>@c2.load(:id=>1234)).sql.must_equal "SELECT * FROM artists WHERE (artists.id IN (SELECT albums_artists.artist_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((name = 'A') AND (albums_artists.artist_id IS NOT NULL) AND ((albums_artists.artist_id, tags.id) IN (SELECT DISTINCT ON (albums_artists.artist_id) albums_artists.artist_id, tags.id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (name = 'A') ORDER BY albums_artists.artist_id, name)) AND (tags.id = 1234))))"
1366
1341
  end
1367
1342
 
1368
1343
  it "should allowing filtering by one_through_many associations with :order and :conditions and composite keys" do
1369
- def (@c2.dataset).supports_distinct_on?; true end
1344
+ @c2.dataset = @c2.dataset.with_extend{def supports_distinct_on?; true end}
1370
1345
  @c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy], :conditions=>{:name=>'A'}, :order=>:name
1371
1346
  @c1.filter(:tag=>@c2.load(:id=>1, :h1=>1234, :h2=>85)).sql.must_equal "SELECT * FROM artists WHERE ((artists.id, artists.yyy) IN (SELECT albums_artists.b1, albums_artists.b2 FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE ((name = 'A') AND (albums_artists.b1 IS NOT NULL) AND (albums_artists.b2 IS NOT NULL) AND ((albums_artists.b1, albums_artists.b2, tags.id) IN (SELECT DISTINCT ON (albums_artists.b1, albums_artists.b2) albums_artists.b1, albums_artists.b2, tags.id FROM tags INNER JOIN albums_tags ON ((albums_tags.g1 = tags.h1) AND (albums_tags.g2 = tags.h2)) INNER JOIN albums ON ((albums.e1 = albums_tags.f1) AND (albums.e2 = albums_tags.f2)) INNER JOIN albums_artists ON ((albums_artists.c1 = albums.d1) AND (albums_artists.c2 = albums.d2)) WHERE (name = 'A') ORDER BY albums_artists.b1, albums_artists.b2, name)) AND (tags.id = 1))))"
1372
1347
  end
@@ -1562,7 +1537,7 @@ describe Sequel::Model, "one_through_many" do
1562
1537
  it "should populate cache when accessed" do
1563
1538
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
1564
1539
  n = @c1.load(:id => 1234)
1565
- n.associations[:tag].must_equal nil
1540
+ n.associations[:tag].must_be_nil
1566
1541
  DB.sqls.must_equal []
1567
1542
  n.tag.must_equal @c2.load(:id=>1)
1568
1543
  DB.sqls.must_equal ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234) LIMIT 1']
@@ -1574,7 +1549,7 @@ describe Sequel::Model, "one_through_many" do
1574
1549
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]]
1575
1550
  n = @c1.load(:id => 1234)
1576
1551
  n.associations[:tag] = nil
1577
- n.tag.must_equal nil
1552
+ n.tag.must_be_nil
1578
1553
  DB.sqls.must_equal []
1579
1554
  end
1580
1555
 
@@ -1608,7 +1583,7 @@ describe Sequel::Model, "one_through_many" do
1608
1583
  model::Foo << v.pk * 20
1609
1584
  end
1610
1585
  end
1611
- @c2.dataset._fetch = [{:id=>20}]
1586
+ @c2.dataset = @c2.dataset.with_fetch(:id=>20)
1612
1587
  p = @c1.load(:id=>10, :parent_id=>20)
1613
1588
  p.tag
1614
1589
  h.must_equal [400]
@@ -1633,7 +1608,7 @@ describe "one_through_many eager loading methods" do
1633
1608
  end
1634
1609
  class ::Track < Sequel::Model
1635
1610
  end
1636
- Artist.dataset.columns(:id)._fetch = proc do |sql|
1611
+ Artist.dataset = Artist.dataset.with_fetch(proc do |sql|
1637
1612
  h = {:id => 1}
1638
1613
  if sql =~ /FROM artists LEFT OUTER JOIN albums_artists/
1639
1614
  h[:tag_id] = 2
@@ -1643,9 +1618,10 @@ describe "one_through_many eager loading methods" do
1643
1618
  h[:artist_id] = 10 if sql =~ /artists_0\.id AS artist_id/
1644
1619
  end
1645
1620
  h
1646
- end
1621
+ end)
1622
+ Artist.dataset.columns(:id)
1647
1623
 
1648
- Tag.dataset._fetch = proc do |sql|
1624
+ Tag.dataset = Tag.dataset.with_fetch(proc do |sql|
1649
1625
  h = {:id => 2}
1650
1626
  if sql =~ /albums_artists.artist_id IN \(([18])\)/
1651
1627
  h[:x_foreign_key_x] = $1.to_i
@@ -1654,19 +1630,19 @@ describe "one_through_many eager loading methods" do
1654
1630
  end
1655
1631
  h[:tag_id] = h.delete(:id) if sql =~ /albums_artists.artist_id IN \(8\)/
1656
1632
  h
1657
- end
1633
+ end)
1658
1634
 
1659
- Album.dataset._fetch = proc do |sql|
1635
+ Album.dataset = Album.dataset.with_fetch(proc do |sql|
1660
1636
  h = {:id => 3}
1661
1637
  h[:x_foreign_key_x] = 1 if sql =~ /albums_artists.artist_id IN \(1\)/
1662
1638
  h
1663
- end
1639
+ end)
1664
1640
 
1665
- Track.dataset._fetch = proc do |sql|
1641
+ Track.dataset = Track.dataset.with_fetch(proc do |sql|
1666
1642
  h = {:id => 4}
1667
1643
  h[:x_foreign_key_x] = 2 if sql =~ /albums_tags.tag_id IN \(2\)/
1668
1644
  h
1669
- end
1645
+ end)
1670
1646
 
1671
1647
  @c1 = Artist
1672
1648
  DB.reset
@@ -1752,12 +1728,7 @@ describe "one_through_many eager loading methods" do
1752
1728
  end
1753
1729
 
1754
1730
  it "should respect :eager_graph when lazily loading an association" do
1755
- Tag.dataset._fetch = {:id=>2, :track_id=>4}
1756
- Tag.dataset.extend(Module.new {
1757
- def columns
1758
- [:id]
1759
- end
1760
- })
1731
+ Tag.dataset = Tag.dataset.with_fetch(:id=>2, :track_id=>4).with_extend{def columns; [:id] end}
1761
1732
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :eager_graph=>:track
1762
1733
  a = @c1.load(:id=>1)
1763
1734
  a.tag
@@ -1809,7 +1780,7 @@ describe "one_through_many eager loading methods" do
1809
1780
 
1810
1781
  it "should respect the :limit option on a one_through_many association" do
1811
1782
  @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1]
1812
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>6}]
1783
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>6}])
1813
1784
  a = @c1.eager(:second_tag).all
1814
1785
  a.must_equal [@c1.load(:id=>1)]
1815
1786
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -1820,7 +1791,7 @@ describe "one_through_many eager loading methods" do
1820
1791
 
1821
1792
  it "should respect the :limit option on a one_through_many association using the :ruby strategy" do
1822
1793
  @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :eager_limit_strategy=>:ruby
1823
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}, {:x_foreign_key_x=>1, :id=>6}]
1794
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5}, {:x_foreign_key_x=>1, :id=>6}])
1824
1795
  a = @c1.eager(:second_tag).all
1825
1796
  a.must_equal [@c1.load(:id=>1)]
1826
1797
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -1830,9 +1801,8 @@ describe "one_through_many eager loading methods" do
1830
1801
  end
1831
1802
 
1832
1803
  it "should eagerly load a single one_through_many association using the :distinct_on strategy" do
1833
- Tag.dataset.meta_def(:supports_distinct_on?){true}
1834
1804
  @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :order=>:name, :eager_limit_strategy=>:distinct_on
1835
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}]
1805
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5}]).with_extend{def supports_distinct_on?; true end}
1836
1806
  a = @c1.eager(:second_tag).all
1837
1807
  a.must_equal [@c1.load(:id=>1)]
1838
1808
  DB.sqls.must_equal ['SELECT * FROM artists', "SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id IN (1)) ORDER BY albums_artists.artist_id, name"]
@@ -1841,9 +1811,8 @@ describe "one_through_many eager loading methods" do
1841
1811
  end
1842
1812
 
1843
1813
  it "should eagerly load a single one_through_many association using the :window_function strategy" do
1844
- Tag.dataset.meta_def(:supports_window_functions?){true}
1845
1814
  @c1.one_through_many :second_tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name, :eager_limit_strategy=>:window_function
1846
- Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5}]
1815
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_x=>1, :id=>5}]).with_extend{def supports_window_functions?; true end}
1847
1816
  a = @c1.eager(:second_tag).all
1848
1817
  a.must_equal [@c1.load(:id=>1)]
1849
1818
  DB.sqls.must_equal ['SELECT * FROM artists',
@@ -1853,15 +1822,12 @@ describe "one_through_many eager loading methods" do
1853
1822
  end
1854
1823
 
1855
1824
  it "should respect the :limit option on a one_through_many association with composite primary keys on the main table" do
1856
- Tag.dataset.meta_def(:supports_window_functions?){true}
1857
1825
  @c1.set_primary_key([:id1, :id2])
1858
1826
  @c1.columns :id1, :id2
1859
1827
 
1860
1828
  @c1.one_through_many :second_tag, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name
1861
- ds = @c1.eager(:second_tag)
1862
- ds._fetch = {:id1=>1, :id2=>2}
1863
- Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]
1864
- a = ds.all
1829
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]).with_extend{def supports_window_functions?; true end}
1830
+ a = @c1.eager(:second_tag).with_fetch(:id1=>1, :id2=>2).all
1865
1831
  a.must_equal [@c1.load(:id1=>1, :id2=>2)]
1866
1832
  DB.sqls.must_equal ['SELECT * FROM artists',
1867
1833
  'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((1 = albums_artists.artist_id1) AND (2 = albums_artists.artist_id2)) ORDER BY name LIMIT 1 OFFSET 1) AS t1']
@@ -1870,15 +1836,12 @@ describe "one_through_many eager loading methods" do
1870
1836
  end
1871
1837
 
1872
1838
  it "should respect the :limit option on a one_through_many association with composite primary keys on the main table using a :window_function strategy" do
1873
- Tag.dataset.meta_def(:supports_window_functions?){true}
1874
1839
  @c1.set_primary_key([:id1, :id2])
1875
1840
  @c1.columns :id1, :id2
1876
1841
 
1877
1842
  @c1.one_through_many :second_tag, [[:albums_artists, [:artist_id1, :artist_id2], :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>[nil,1], :order=>:name, :eager_limit_strategy=>:window_function
1878
- ds = @c1.eager(:second_tag)
1879
- ds._fetch = {:id1=>1, :id2=>2}
1880
- Tag.dataset._fetch = [{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]
1881
- a = ds.all
1843
+ Tag.dataset = Tag.dataset.with_fetch([{:x_foreign_key_0_x=>1, :x_foreign_key_1_x=>2, :id=>5}]).with_extend{def supports_window_functions?; true end}
1844
+ a = @c1.eager(:second_tag).with_fetch(:id1=>1, :id2=>2).all
1882
1845
  a.must_equal [@c1.load(:id1=>1, :id2=>2)]
1883
1846
  DB.sqls.must_equal ['SELECT * FROM artists',
1884
1847
  'SELECT * FROM (SELECT tags.*, albums_artists.artist_id1 AS x_foreign_key_0_x, albums_artists.artist_id2 AS x_foreign_key_1_x, row_number() OVER (PARTITION BY albums_artists.artist_id1, albums_artists.artist_id2 ORDER BY name) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE ((albums_artists.artist_id1, albums_artists.artist_id2) IN ((1, 2)))) AS t1 WHERE (x_sequel_row_number_x = 2)']
@@ -1904,8 +1867,7 @@ describe "one_through_many eager loading methods" do
1904
1867
 
1905
1868
  it "should respect one_through_many association's :left_primary_key and :right_primary_key options" do
1906
1869
  @c1.send(:define_method, :yyy){values[:yyy]}
1907
- @c1.dataset._fetch = {:id=>1, :yyy=>8}
1908
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
1870
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
1909
1871
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
1910
1872
  a = @c1.eager(:tag).all
1911
1873
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
@@ -1917,8 +1879,7 @@ describe "one_through_many eager loading methods" do
1917
1879
 
1918
1880
  it "should handle composite keys" do
1919
1881
  @c1.send(:define_method, :yyy){values[:yyy]}
1920
- @c1.dataset._fetch = {:id=>1, :yyy=>8}
1921
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
1882
+ @c1.dataset = @c1.dataset.with_fetch(:id=>1, :yyy=>8).with_extend{def columns; [:id, :yyy] end}
1922
1883
  @c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:h1, :h2], :left_primary_key=>[:id, :yyy]
1923
1884
  a = @c1.eager(:tag).all
1924
1885
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
@@ -1951,10 +1912,8 @@ describe "one_through_many eager loading methods" do
1951
1912
  end
1952
1913
 
1953
1914
  it "should eagerly graph a single one_through_many association using the :distinct_on strategy" do
1954
- def (Tag.dataset).supports_distinct_on?() true end
1955
- ds = @c1.eager_graph_with_options(:tag, :limit_strategy=>true)
1956
- ds._fetch = {:id=>1, :tag_id=>2}
1957
- a = ds.all
1915
+ Tag.dataset = Tag.dataset.with_extend{def supports_distinct_on?; true end}
1916
+ a = @c1.eager_graph_with_options(:tag, :limit_strategy=>true).with_fetch(:id=>1, :tag_id=>2).all
1958
1917
  a.must_equal [@c1.load(:id=>1)]
1959
1918
  DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN (SELECT DISTINCT ON (albums_artists.artist_id) tags.*, albums_artists.artist_id AS x_foreign_key_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) ORDER BY albums_artists.artist_id) AS tag ON (tag.x_foreign_key_x = artists.id)']
1960
1919
  a.first.tag.must_equal Tag.load(:id=>2)
@@ -1962,11 +1921,11 @@ describe "one_through_many eager loading methods" do
1962
1921
  end
1963
1922
 
1964
1923
  it "should eagerly graph a single one_through_many association using the :window_function strategy" do
1965
- def (Tag.dataset).supports_window_functions?() true end
1966
- def (Tag.dataset).columns() literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1967
- ds = @c1.eager_graph_with_options(:tag, :limit_strategy=>true)
1968
- ds._fetch = {:id=>1, :tag_id=>2}
1969
- a = ds.all
1924
+ Tag.dataset = Tag.dataset.with_extend do
1925
+ def supports_window_functions?; true end
1926
+ def columns; literal(opts[:select]) =~ /x_foreign_key_x/ ? [:id, :x_foreign_key_x] : [:id] end
1927
+ end
1928
+ a = @c1.eager_graph_with_options(:tag, :limit_strategy=>true).with_fetch(:id=>1, :tag_id=>2).all
1970
1929
  a.must_equal [@c1.load(:id=>1)]
1971
1930
  DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN (SELECT id, x_foreign_key_x FROM (SELECT tags.*, albums_artists.artist_id AS x_foreign_key_x, row_number() OVER (PARTITION BY albums_artists.artist_id) AS x_sequel_row_number_x FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id)) AS t1 WHERE (x_sequel_row_number_x = 1)) AS tag ON (tag.x_foreign_key_x = artists.id)']
1972
1931
  a.first.tag.must_equal Tag.load(:id=>2)
@@ -2014,9 +1973,7 @@ describe "one_through_many eager loading methods" do
2014
1973
  end
2015
1974
 
2016
1975
  it "should eager graph a self_referential association" do
2017
- ds = @c1.eager_graph(:tag, :artist)
2018
- ds._fetch = {:id=>1, :tag_id=>2, :artist_id=>10}
2019
- a = ds.all
1976
+ a = @c1.eager_graph(:tag, :artist).with_fetch(:id=>1, :tag_id=>2, :artist_id=>10).all
2020
1977
  a.must_equal [@c1.load(:id=>1)]
2021
1978
  DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id, artist.id AS artist_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_artists_0.album_id) LEFT OUTER JOIN albums_artists AS albums_artists_1 ON (albums_artists_1.album_id = albums_0.id) LEFT OUTER JOIN artists AS artist ON (artist.id = albums_artists_1.artist_id)']
2022
1979
  a = a.first
@@ -2037,48 +1994,40 @@ describe "one_through_many eager loading methods" do
2037
1994
  end
2038
1995
 
2039
1996
  it "should handle no associated records when eagerly graphing a single one_through_many association" do
2040
- ds = @c1.eager_graph(:tag)
2041
- ds._fetch = {:id=>1, :tag_id=>nil}
2042
- a = ds.all
1997
+ a = @c1.eager_graph(:tag).with_fetch(:id=>1, :tag_id=>nil).all
2043
1998
  a.must_equal [@c1.load(:id=>1)]
2044
1999
  DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)']
2045
- a.first.tag.must_equal nil
2000
+ a.first.tag.must_be_nil
2046
2001
  DB.sqls.length.must_equal 0
2047
2002
  end
2048
2003
 
2049
2004
  it "should handle no associated records when eagerly graphing multiple one_through_many associations" do
2050
- ds = @c1.eager_graph(:tag, :album)
2051
- ds._fetch = [{:id=>1, :tag_id=>5, :album_id=>6}, {:id=>7, :tag_id=>nil, :albums_0_id=>nil}]
2052
- a = ds.all
2005
+ a = @c1.eager_graph(:tag, :album).with_fetch([{:id=>1, :tag_id=>5, :album_id=>6}, {:id=>7, :tag_id=>nil, :albums_0_id=>nil}]).all
2053
2006
  a.must_equal [@c1.load(:id=>1), @c1.load(:id=>7)]
2054
2007
  DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id, album.id AS album_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_artists AS albums_artists_0 ON (albums_artists_0.artist_id = artists.id) LEFT OUTER JOIN albums AS album ON (album.id = albums_artists_0.album_id)']
2055
2008
  a.first.tag.must_equal Tag.load(:id=>5)
2056
2009
  a.first.album.must_equal Album.load(:id=>6)
2057
- a.last.tag.must_equal nil
2058
- a.last.album.must_equal nil
2010
+ a.last.tag.must_be_nil
2011
+ a.last.album.must_be_nil
2059
2012
  DB.sqls.length.must_equal 0
2060
2013
  end
2061
2014
 
2062
2015
  it "should handle missing associated records when cascading eager graphing for associations of associated models" do
2063
- ds = @c1.eager_graph(:tag=>:track)
2064
- ds._fetch = [{:id=>1, :tag_id=>2, :track_id=>nil}, {:id=>2, :tag_id=>nil, :tracks_id=>nil}]
2065
- a = ds.all
2016
+ a = @c1.eager_graph(:tag=>:track).with_fetch([{:id=>1, :tag_id=>2, :track_id=>nil}, {:id=>2, :tag_id=>nil, :tracks_id=>nil}]).all
2066
2017
  a.must_equal [@c1.load(:id=>1), @c1.load(:id=>2)]
2067
2018
  DB.sqls.must_equal ['SELECT artists.id, tag.id AS tag_id, track.id AS track_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id) LEFT OUTER JOIN albums_tags AS albums_tags_0 ON (albums_tags_0.tag_id = tag.id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.id = albums_tags_0.album_id) LEFT OUTER JOIN tracks AS track ON (track.album_id = albums_0.id)']
2068
- a.last.tag.must_equal nil
2019
+ a.last.tag.must_be_nil
2069
2020
  a = a.first
2070
2021
  a.tag.must_equal Tag.load(:id=>2)
2071
- a.tag.track.must_equal nil
2022
+ a.tag.track.must_be_nil
2072
2023
  DB.sqls.length.must_equal 0
2073
2024
  end
2074
2025
 
2075
2026
  it "eager graphing should respect :left_primary_key and :right_primary_key options" do
2076
2027
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :left_primary_key=>:yyy, :right_primary_key=>:tag_id
2077
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
2078
- Tag.dataset.meta_def(:columns){[:id, :tag_id]}
2079
- ds = @c1.eager_graph(:tag)
2080
- ds._fetch = {:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4}
2081
- a = ds.all
2028
+ @c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
2029
+ Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
2030
+ a = @c1.eager_graph(:tag).with_fetch(:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4).all
2082
2031
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
2083
2032
  DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tag.id AS tag_id, tag.tag_id AS tag_tag_id FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.yyy) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.tag_id = albums_tags.tag_id)']
2084
2033
  a.first.tag.must_equal Tag.load(:id=>2, :tag_id=>4)
@@ -2087,11 +2036,9 @@ describe "one_through_many eager loading methods" do
2087
2036
 
2088
2037
  it "eager graphing should respect composite keys" do
2089
2038
  @c1.one_through_many :tag, [[:albums_artists, [:b1, :b2], [:c1, :c2]], [:albums, [:d1, :d2], [:e1, :e2]], [:albums_tags, [:f1, :f2], [:g1, :g2]]], :right_primary_key=>[:id, :tag_id], :left_primary_key=>[:id, :yyy]
2090
- @c1.dataset.meta_def(:columns){[:id, :yyy]}
2091
- Tag.dataset.meta_def(:columns){[:id, :tag_id]}
2092
- ds = @c1.eager_graph(:tag)
2093
- ds._fetch = {:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4}
2094
- a = ds.all
2039
+ @c1.dataset = @c1.dataset.with_extend{def columns; [:id, :yyy] end}
2040
+ Tag.dataset = Tag.dataset.with_extend{def columns; [:id, :tag_id] end}
2041
+ a = @c1.eager_graph(:tag).with_fetch(:id=>1, :yyy=>8, :tag_id=>2, :tag_tag_id=>4).all
2095
2042
  a.must_equal [@c1.load(:id=>1, :yyy=>8)]
2096
2043
  DB.sqls.must_equal ['SELECT artists.id, artists.yyy, tag.id AS tag_id, tag.tag_id AS tag_tag_id FROM artists LEFT OUTER JOIN albums_artists ON ((albums_artists.b1 = artists.id) AND (albums_artists.b2 = artists.yyy)) LEFT OUTER JOIN albums ON ((albums.d1 = albums_artists.c1) AND (albums.d2 = albums_artists.c2)) LEFT OUTER JOIN albums_tags ON ((albums_tags.f1 = albums.e1) AND (albums_tags.f2 = albums.e2)) LEFT OUTER JOIN tags AS tag ON ((tag.id = albums_tags.g1) AND (tag.tag_id = albums_tags.g2))']
2097
2044
  a.first.tag.must_equal Tag.load(:id=>2, :tag_id=>4)
@@ -2100,9 +2047,7 @@ describe "one_through_many eager loading methods" do
2100
2047
 
2101
2048
  it "should respect the association's :graph_select option" do
2102
2049
  @c1.one_through_many :tag, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :graph_select=>:b
2103
- ds = @c1.eager_graph(:tag)
2104
- ds._fetch = {:id=>1, :b=>2}
2105
- a = ds.all
2050
+ a = @c1.eager_graph(:tag).with_fetch(:id=>1, :b=>2).all
2106
2051
  a.must_equal [@c1.load(:id=>1)]
2107
2052
  DB.sqls.must_equal ['SELECT artists.id, tag.b FROM artists LEFT OUTER JOIN albums_artists ON (albums_artists.artist_id = artists.id) LEFT OUTER JOIN albums ON (albums.id = albums_artists.album_id) LEFT OUTER JOIN albums_tags ON (albums_tags.album_id = albums.id) LEFT OUTER JOIN tags AS tag ON (tag.id = albums_tags.tag_id)']
2108
2053
  a.first.tag.must_equal Tag.load(:b=>2)