sequel 3.48.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +114 -0
  3. data/Rakefile +10 -7
  4. data/doc/association_basics.rdoc +25 -23
  5. data/doc/code_order.rdoc +7 -0
  6. data/doc/core_extensions.rdoc +0 -10
  7. data/doc/object_model.rdoc +4 -1
  8. data/doc/querying.rdoc +3 -3
  9. data/doc/release_notes/4.0.0.txt +262 -0
  10. data/doc/security.rdoc +0 -28
  11. data/doc/testing.rdoc +8 -14
  12. data/lib/sequel/adapters/ado.rb +7 -11
  13. data/lib/sequel/adapters/ado/access.rb +8 -8
  14. data/lib/sequel/adapters/ado/mssql.rb +4 -4
  15. data/lib/sequel/adapters/amalgalite.rb +6 -6
  16. data/lib/sequel/adapters/cubrid.rb +7 -7
  17. data/lib/sequel/adapters/db2.rb +5 -9
  18. data/lib/sequel/adapters/dbi.rb +2 -6
  19. data/lib/sequel/adapters/do.rb +4 -4
  20. data/lib/sequel/adapters/firebird.rb +4 -4
  21. data/lib/sequel/adapters/ibmdb.rb +8 -8
  22. data/lib/sequel/adapters/informix.rb +2 -10
  23. data/lib/sequel/adapters/jdbc.rb +17 -17
  24. data/lib/sequel/adapters/jdbc/as400.rb +2 -2
  25. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
  26. data/lib/sequel/adapters/jdbc/db2.rb +1 -1
  27. data/lib/sequel/adapters/jdbc/derby.rb +1 -1
  28. data/lib/sequel/adapters/jdbc/h2.rb +2 -2
  29. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
  30. data/lib/sequel/adapters/jdbc/informix.rb +1 -1
  31. data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
  32. data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
  33. data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
  35. data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
  36. data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
  37. data/lib/sequel/adapters/mock.rb +7 -7
  38. data/lib/sequel/adapters/mysql.rb +3 -3
  39. data/lib/sequel/adapters/mysql2.rb +4 -4
  40. data/lib/sequel/adapters/odbc.rb +2 -6
  41. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  42. data/lib/sequel/adapters/openbase.rb +1 -5
  43. data/lib/sequel/adapters/oracle.rb +13 -17
  44. data/lib/sequel/adapters/postgres.rb +20 -25
  45. data/lib/sequel/adapters/shared/cubrid.rb +3 -3
  46. data/lib/sequel/adapters/shared/db2.rb +2 -2
  47. data/lib/sequel/adapters/shared/firebird.rb +7 -7
  48. data/lib/sequel/adapters/shared/mssql.rb +9 -9
  49. data/lib/sequel/adapters/shared/mysql.rb +29 -13
  50. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
  51. data/lib/sequel/adapters/shared/oracle.rb +22 -13
  52. data/lib/sequel/adapters/shared/postgres.rb +61 -46
  53. data/lib/sequel/adapters/shared/sqlite.rb +9 -9
  54. data/lib/sequel/adapters/sqlite.rb +17 -11
  55. data/lib/sequel/adapters/swift.rb +3 -3
  56. data/lib/sequel/adapters/swift/mysql.rb +1 -1
  57. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  58. data/lib/sequel/adapters/tinytds.rb +8 -8
  59. data/lib/sequel/ast_transformer.rb +3 -1
  60. data/lib/sequel/connection_pool.rb +4 -2
  61. data/lib/sequel/connection_pool/sharded_single.rb +2 -2
  62. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
  63. data/lib/sequel/connection_pool/threaded.rb +7 -7
  64. data/lib/sequel/core.rb +4 -67
  65. data/lib/sequel/database.rb +1 -0
  66. data/lib/sequel/database/connecting.rb +2 -8
  67. data/lib/sequel/database/dataset.rb +2 -7
  68. data/lib/sequel/database/dataset_defaults.rb +0 -18
  69. data/lib/sequel/database/features.rb +4 -4
  70. data/lib/sequel/database/misc.rb +6 -8
  71. data/lib/sequel/database/query.rb +5 -61
  72. data/lib/sequel/database/schema_generator.rb +22 -20
  73. data/lib/sequel/database/schema_methods.rb +48 -20
  74. data/lib/sequel/database/transactions.rb +7 -17
  75. data/lib/sequel/dataset.rb +2 -0
  76. data/lib/sequel/dataset/actions.rb +23 -91
  77. data/lib/sequel/dataset/features.rb +1 -4
  78. data/lib/sequel/dataset/graph.rb +3 -47
  79. data/lib/sequel/dataset/misc.rb +4 -33
  80. data/lib/sequel/dataset/prepared_statements.rb +3 -1
  81. data/lib/sequel/dataset/query.rb +116 -240
  82. data/lib/sequel/dataset/sql.rb +19 -97
  83. data/lib/sequel/deprecated.rb +0 -16
  84. data/lib/sequel/exceptions.rb +0 -3
  85. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  86. data/lib/sequel/extensions/columns_introspection.rb +1 -12
  87. data/lib/sequel/extensions/constraint_validations.rb +3 -3
  88. data/lib/sequel/extensions/core_extensions.rb +0 -9
  89. data/lib/sequel/extensions/date_arithmetic.rb +1 -2
  90. data/lib/sequel/extensions/graph_each.rb +11 -0
  91. data/lib/sequel/extensions/migration.rb +5 -5
  92. data/lib/sequel/extensions/null_dataset.rb +11 -13
  93. data/lib/sequel/extensions/pagination.rb +3 -6
  94. data/lib/sequel/extensions/pg_array.rb +6 -4
  95. data/lib/sequel/extensions/pg_array_ops.rb +35 -1
  96. data/lib/sequel/extensions/pg_json.rb +12 -2
  97. data/lib/sequel/extensions/pg_json_ops.rb +266 -0
  98. data/lib/sequel/extensions/pg_range.rb +2 -2
  99. data/lib/sequel/extensions/pg_range_ops.rb +0 -8
  100. data/lib/sequel/extensions/pg_row.rb +2 -2
  101. data/lib/sequel/extensions/pretty_table.rb +0 -4
  102. data/lib/sequel/extensions/query.rb +3 -8
  103. data/lib/sequel/extensions/schema_caching.rb +0 -7
  104. data/lib/sequel/extensions/schema_dumper.rb +10 -17
  105. data/lib/sequel/extensions/select_remove.rb +0 -4
  106. data/lib/sequel/extensions/set_overrides.rb +28 -0
  107. data/lib/sequel/extensions/to_dot.rb +6 -10
  108. data/lib/sequel/model.rb +6 -7
  109. data/lib/sequel/model/associations.rb +127 -182
  110. data/lib/sequel/model/base.rb +88 -211
  111. data/lib/sequel/model/errors.rb +0 -13
  112. data/lib/sequel/model/plugins.rb +2 -2
  113. data/lib/sequel/no_core_ext.rb +0 -1
  114. data/lib/sequel/plugins/after_initialize.rb +11 -17
  115. data/lib/sequel/plugins/association_autoreloading.rb +1 -47
  116. data/lib/sequel/plugins/association_dependencies.rb +2 -2
  117. data/lib/sequel/plugins/auto_validations.rb +2 -8
  118. data/lib/sequel/plugins/blacklist_security.rb +32 -2
  119. data/lib/sequel/plugins/caching.rb +1 -1
  120. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  121. data/lib/sequel/plugins/composition.rb +10 -8
  122. data/lib/sequel/plugins/constraint_validations.rb +2 -2
  123. data/lib/sequel/plugins/dataset_associations.rb +4 -0
  124. data/lib/sequel/plugins/defaults_setter.rb +8 -6
  125. data/lib/sequel/plugins/dirty.rb +6 -6
  126. data/lib/sequel/plugins/force_encoding.rb +13 -8
  127. data/lib/sequel/plugins/hook_class_methods.rb +1 -7
  128. data/lib/sequel/plugins/json_serializer.rb +13 -74
  129. data/lib/sequel/plugins/lazy_attributes.rb +2 -4
  130. data/lib/sequel/plugins/list.rb +1 -1
  131. data/lib/sequel/plugins/many_through_many.rb +4 -11
  132. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
  133. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  134. data/lib/sequel/plugins/optimistic_locking.rb +3 -5
  135. data/lib/sequel/plugins/pg_array_associations.rb +453 -0
  136. data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
  137. data/lib/sequel/plugins/prepared_statements.rb +1 -1
  138. data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
  139. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
  140. data/lib/sequel/plugins/rcte_tree.rb +1 -1
  141. data/lib/sequel/plugins/serialization.rb +5 -4
  142. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  143. data/lib/sequel/plugins/sharding.rb +7 -1
  144. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  145. data/lib/sequel/plugins/timestamps.rb +1 -1
  146. data/lib/sequel/plugins/touch.rb +2 -2
  147. data/lib/sequel/plugins/tree.rb +1 -1
  148. data/lib/sequel/plugins/typecast_on_load.rb +19 -4
  149. data/lib/sequel/plugins/validation_class_methods.rb +0 -30
  150. data/lib/sequel/plugins/validation_helpers.rb +13 -31
  151. data/lib/sequel/plugins/xml_serializer.rb +18 -57
  152. data/lib/sequel/sql.rb +20 -22
  153. data/lib/sequel/version.rb +2 -2
  154. data/spec/adapters/db2_spec.rb +14 -23
  155. data/spec/adapters/firebird_spec.rb +25 -29
  156. data/spec/adapters/informix_spec.rb +11 -14
  157. data/spec/adapters/mssql_spec.rb +71 -77
  158. data/spec/adapters/mysql_spec.rb +165 -172
  159. data/spec/adapters/oracle_spec.rb +36 -39
  160. data/spec/adapters/postgres_spec.rb +175 -100
  161. data/spec/adapters/spec_helper.rb +13 -11
  162. data/spec/adapters/sqlite_spec.rb +36 -44
  163. data/spec/core/connection_pool_spec.rb +2 -1
  164. data/spec/core/database_spec.rb +55 -55
  165. data/spec/core/dataset_spec.rb +45 -249
  166. data/spec/core/deprecated_spec.rb +0 -8
  167. data/spec/core/expression_filters_spec.rb +23 -5
  168. data/spec/core/object_graph_spec.rb +4 -66
  169. data/spec/core/schema_spec.rb +35 -12
  170. data/spec/core/spec_helper.rb +3 -2
  171. data/spec/core_extensions_spec.rb +17 -19
  172. data/spec/extensions/arbitrary_servers_spec.rb +2 -3
  173. data/spec/extensions/association_dependencies_spec.rb +14 -14
  174. data/spec/extensions/auto_validations_spec.rb +7 -0
  175. data/spec/extensions/blacklist_security_spec.rb +5 -5
  176. data/spec/extensions/blank_spec.rb +2 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +2 -2
  178. data/spec/extensions/columns_introspection_spec.rb +2 -29
  179. data/spec/extensions/composition_spec.rb +10 -17
  180. data/spec/extensions/core_refinements_spec.rb +5 -1
  181. data/spec/extensions/dataset_associations_spec.rb +18 -0
  182. data/spec/extensions/date_arithmetic_spec.rb +2 -2
  183. data/spec/extensions/defaults_setter_spec.rb +9 -9
  184. data/spec/extensions/dirty_spec.rb +0 -5
  185. data/spec/extensions/eval_inspect_spec.rb +2 -0
  186. data/spec/extensions/force_encoding_spec.rb +2 -18
  187. data/spec/extensions/hash_aliases_spec.rb +8 -0
  188. data/spec/extensions/hook_class_methods_spec.rb +39 -58
  189. data/spec/extensions/inflector_spec.rb +2 -0
  190. data/spec/extensions/instance_filters_spec.rb +8 -8
  191. data/spec/extensions/json_serializer_spec.rb +1 -41
  192. data/spec/extensions/list_spec.rb +1 -1
  193. data/spec/extensions/many_through_many_spec.rb +106 -109
  194. data/spec/extensions/migration_spec.rb +2 -0
  195. data/spec/extensions/named_timezones_spec.rb +1 -0
  196. data/spec/extensions/pg_array_associations_spec.rb +603 -0
  197. data/spec/extensions/pg_array_ops_spec.rb +25 -0
  198. data/spec/extensions/pg_array_spec.rb +9 -1
  199. data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
  200. data/spec/extensions/pg_hstore_spec.rb +1 -0
  201. data/spec/extensions/pg_json_ops_spec.rb +131 -0
  202. data/spec/extensions/pg_json_spec.rb +10 -4
  203. data/spec/extensions/pg_range_ops_spec.rb +2 -5
  204. data/spec/extensions/pg_range_spec.rb +6 -2
  205. data/spec/extensions/pg_row_ops_spec.rb +2 -0
  206. data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
  207. data/spec/extensions/rcte_tree_spec.rb +15 -15
  208. data/spec/extensions/schema_dumper_spec.rb +0 -1
  209. data/spec/extensions/schema_spec.rb +9 -9
  210. data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
  211. data/spec/extensions/serialization_spec.rb +18 -29
  212. data/spec/extensions/set_overrides_spec.rb +4 -0
  213. data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
  214. data/spec/extensions/single_table_inheritance_spec.rb +4 -4
  215. data/spec/extensions/spec_helper.rb +8 -9
  216. data/spec/extensions/sql_expr_spec.rb +2 -0
  217. data/spec/extensions/string_date_time_spec.rb +2 -0
  218. data/spec/extensions/string_stripper_spec.rb +2 -0
  219. data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
  220. data/spec/extensions/thread_local_timezones_spec.rb +2 -0
  221. data/spec/extensions/timestamps_spec.rb +1 -1
  222. data/spec/extensions/to_dot_spec.rb +1 -1
  223. data/spec/extensions/touch_spec.rb +24 -24
  224. data/spec/extensions/tree_spec.rb +7 -7
  225. data/spec/extensions/typecast_on_load_spec.rb +8 -1
  226. data/spec/extensions/update_primary_key_spec.rb +10 -10
  227. data/spec/extensions/validation_class_methods_spec.rb +10 -39
  228. data/spec/extensions/validation_helpers_spec.rb +29 -47
  229. data/spec/extensions/xml_serializer_spec.rb +1 -23
  230. data/spec/integration/associations_test.rb +231 -40
  231. data/spec/integration/database_test.rb +1 -1
  232. data/spec/integration/dataset_test.rb +64 -64
  233. data/spec/integration/eager_loader_test.rb +28 -28
  234. data/spec/integration/migrator_test.rb +1 -1
  235. data/spec/integration/model_test.rb +2 -2
  236. data/spec/integration/plugin_test.rb +21 -21
  237. data/spec/integration/prepared_statement_test.rb +7 -7
  238. data/spec/integration/schema_test.rb +115 -110
  239. data/spec/integration/spec_helper.rb +17 -27
  240. data/spec/integration/timezone_test.rb +1 -1
  241. data/spec/integration/transaction_test.rb +10 -10
  242. data/spec/integration/type_test.rb +2 -2
  243. data/spec/model/association_reflection_spec.rb +2 -28
  244. data/spec/model/associations_spec.rb +239 -188
  245. data/spec/model/base_spec.rb +27 -68
  246. data/spec/model/dataset_methods_spec.rb +4 -4
  247. data/spec/model/eager_loading_spec.rb +160 -172
  248. data/spec/model/hooks_spec.rb +62 -79
  249. data/spec/model/model_spec.rb +36 -51
  250. data/spec/model/plugins_spec.rb +5 -19
  251. data/spec/model/record_spec.rb +125 -151
  252. data/spec/model/spec_helper.rb +8 -6
  253. data/spec/model/validations_spec.rb +4 -17
  254. data/spec/spec_config.rb +2 -10
  255. metadata +50 -56
  256. data/lib/sequel/deprecated_core_extensions.rb +0 -135
  257. data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
  258. data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
  259. data/lib/sequel/plugins/identity_map.rb +0 -260
  260. data/lib/sequel_core.rb +0 -2
  261. data/lib/sequel_model.rb +0 -2
  262. data/spec/extensions/association_autoreloading_spec.rb +0 -102
  263. data/spec/extensions/identity_map_spec.rb +0 -337
  264. data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
  265. data/spec/extensions/pg_statement_cache_spec.rb +0 -208
  266. data/spec/rcov.opts +0 -8
  267. data/spec/spec_config.rb.example +0 -10
@@ -6,7 +6,7 @@ describe "Model attribute setters" do
6
6
  columns :id, :x, :y, :"x y"
7
7
  end
8
8
  @o = @c.new
9
- MODEL_DB.reset
9
+ DB.reset
10
10
  end
11
11
 
12
12
  specify "refresh should return self" do
@@ -47,7 +47,7 @@ describe "Model.def_column_alias" do
47
47
  columns :id
48
48
  def_column_alias(:id2, :id)
49
49
  end.load(:id=>1)
50
- MODEL_DB.reset
50
+ DB.reset
51
51
  end
52
52
 
53
53
  it "should create an getter alias for the column" do
@@ -412,6 +412,8 @@ describe "Model.db" do
412
412
  class ModelTest2 < Sequel::Model(@db[:foo])
413
413
  db.should == @db
414
414
  end
415
+ ModelTest.instance_variable_set(:@db, nil)
416
+ ModelTest.db.should == @db
415
417
  ensure
416
418
  Object.send(:remove_const, :ModelTest)
417
419
  Object.send(:remove_const, :ModelTest2)
@@ -462,14 +464,6 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
462
464
  @c.allowed_columns.should == [:x, :y]
463
465
  end
464
466
 
465
- qspecify "should set the restricted columns correctly" do
466
- @c.restricted_columns.should == nil
467
- @c.set_restricted_columns :x
468
- @c.restricted_columns.should == [:x]
469
- @c.set_restricted_columns :x, :y
470
- @c.restricted_columns.should == [:x, :y]
471
- end
472
-
473
467
  it "should only set allowed columns by default" do
474
468
  @c.set_allowed_columns :x, :y
475
469
  i = @c.new(:x => 1, :y => 2, :z => 3)
@@ -481,36 +475,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
481
475
  i = @c.new
482
476
  i.update(:x => 7, :z => 9)
483
477
  i.values.should == {:x => 7}
484
- MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
485
- end
486
-
487
- qspecify "should not set restricted columns by default" do
488
- @c.set_restricted_columns :z
489
- i = @c.new(:x => 1, :y => 2, :z => 3)
490
- i.values.should == {:x => 1, :y => 2}
491
- i.set(:x => 4, :y => 5, :z => 6)
492
- i.values.should == {:x => 4, :y => 5}
493
-
494
- @c.instance_dataset._fetch = @c.dataset._fetch = {:x => 7}
495
- i = @c.new
496
- i.update(:x => 7, :z => 9)
497
- i.values.should == {:x => 7}
498
- MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
499
- end
500
-
501
- qspecify "should have allowed take precedence over restricted" do
502
- @c.set_allowed_columns :x, :y
503
- @c.set_restricted_columns :y, :z
504
- i = @c.new(:x => 1, :y => 2, :z => 3)
505
- i.values.should == {:x => 1, :y => 2}
506
- i.set(:x => 4, :y => 5, :z => 6)
507
- i.values.should == {:x => 4, :y => 5}
508
-
509
- @c.instance_dataset._fetch = @c.dataset._fetch = {:y => 7}
510
- i = @c.new
511
- i.update(:y => 7, :z => 9)
512
- i.values.should == {:y => 7}
513
- MODEL_DB.sqls.should == ["INSERT INTO blahblah (y) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
478
+ DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
514
479
  end
515
480
  end
516
481
 
@@ -569,19 +534,13 @@ describe Sequel::Model, ".strict_param_setting" do
569
534
  proc{@c.create(:z=>1)}.should raise_error(Sequel::Error)
570
535
  c = @c.new
571
536
  proc{c.set(:z=>1)}.should raise_error(Sequel::Error)
572
- proc{c.set_all(:id=>1)}.should raise_error(Sequel::Error)
537
+ proc{c.set_all(:use_after_commit_rollback => false)}.should raise_error(Sequel::Error)
573
538
  proc{c.set_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
574
539
  proc{c.update(:z=>1)}.should raise_error(Sequel::Error)
575
- proc{c.update_all(:id=>1)}.should raise_error(Sequel::Error)
540
+ proc{c.update_all(:use_after_commit_rollback=>false)}.should raise_error(Sequel::Error)
576
541
  proc{c.update_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
577
542
  end
578
543
 
579
- qspecify "should raise an error if a missing/restricted column/method is accessed by *_except" do
580
- c = @c.new
581
- proc{c.set_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
582
- proc{c.update_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
583
- end
584
-
585
544
  it "should be disabled by strict_param_setting = false" do
586
545
  @c.strict_param_setting = false
587
546
  @c.strict_param_setting.should == false
@@ -591,9 +550,9 @@ end
591
550
 
592
551
  describe Sequel::Model, ".require_modification" do
593
552
  before do
594
- @ds1 = MODEL_DB[:items]
553
+ @ds1 = DB[:items]
595
554
  def @ds1.provides_accurate_rows_matched?() false end
596
- @ds2 = MODEL_DB[:items]
555
+ @ds2 = DB[:items]
597
556
  def @ds2.provides_accurate_rows_matched?() true end
598
557
  end
599
558
  after do
@@ -618,7 +577,7 @@ end
618
577
 
619
578
  describe Sequel::Model, ".[] optimization" do
620
579
  before do
621
- @db = MODEL_DB.clone
580
+ @db = DB.clone
622
581
  @db.quote_identifiers = true
623
582
  @c = Class.new(Sequel::Model(@db))
624
583
  end
@@ -700,47 +659,47 @@ describe "Model datasets #with_pk with #with_pk!" do
700
659
  @c = Class.new(Sequel::Model(:a))
701
660
  @ds = @c.dataset
702
661
  @ds._fetch = {:id=>1}
703
- MODEL_DB.reset
662
+ DB.reset
704
663
  end
705
664
 
706
665
  it "should be callable on the model class with optimized SQL" do
707
666
  @c.with_pk(1).should == @c.load(:id=>1)
708
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
667
+ DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
709
668
  @c.with_pk!(1).should == @c.load(:id=>1)
710
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
669
+ DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
711
670
  end
712
671
 
713
672
  it "should return the first record where the primary key matches" do
714
673
  @ds.with_pk(1).should == @c.load(:id=>1)
715
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
674
+ DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
716
675
  @ds.with_pk!(1).should == @c.load(:id=>1)
717
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
676
+ DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
718
677
  end
719
678
 
720
679
  it "should handle existing filters" do
721
680
  @ds.filter(:a=>2).with_pk(1)
722
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
681
+ DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
723
682
  @ds.filter(:a=>2).with_pk!(1)
724
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
683
+ DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
725
684
  end
726
685
 
727
686
  it "should work with string values" do
728
687
  @ds.with_pk("foo")
729
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
688
+ DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
730
689
  @ds.with_pk!("foo")
731
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
690
+ DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
732
691
  end
733
692
 
734
693
  it "should handle an array for composite primary keys" do
735
694
  @c.set_primary_key [:id1, :id2]
736
695
  @ds.with_pk([1, 2])
737
- sqls = MODEL_DB.sqls
696
+ sqls = DB.sqls
738
697
  ["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
739
698
  "SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
740
699
  sqls.should == []
741
700
 
742
701
  @ds.with_pk!([1, 2])
743
- sqls = MODEL_DB.sqls
702
+ sqls = DB.sqls
744
703
  ["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
745
704
  "SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
746
705
  sqls.should == []
@@ -749,26 +708,26 @@ describe "Model datasets #with_pk with #with_pk!" do
749
708
  it "should have with_pk return nil and with_pk! raise if no rows match" do
750
709
  @ds._fetch = []
751
710
  @ds.with_pk(1).should == nil
752
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
711
+ DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
753
712
  proc{@ds.with_pk!(1)}.should raise_error(Sequel::NoMatchingRow)
754
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
713
+ DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
755
714
  end
756
715
 
757
716
  it "should have with_pk return nil and with_pk! raise if no rows match when calling the class method" do
758
717
  @ds._fetch = []
759
718
  @c.with_pk(1).should == nil
760
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
719
+ DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
761
720
  proc{@c.with_pk!(1)}.should raise_error(Sequel::NoMatchingRow)
762
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
721
+ DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
763
722
  end
764
723
 
765
724
  it "should have #[] consider an integer as a primary key lookup" do
766
725
  @ds[1].should == @c.load(:id=>1)
767
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
726
+ DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
768
727
  end
769
728
 
770
729
  it "should not have #[] consider a string as a primary key lookup" do
771
730
  @ds['foo'].should == @c.load(:id=>1)
772
- MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
731
+ DB.sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
773
732
  end
774
733
  end
@@ -10,7 +10,7 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
10
10
  end
11
11
  @d = @c.dataset
12
12
  @d._fetch = [{:id=>1}, {:id=>2}]
13
- MODEL_DB.reset
13
+ DB.reset
14
14
  end
15
15
 
16
16
  it "should instantiate objects in the dataset and call destroy on each" do
@@ -28,13 +28,13 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
28
28
  it "should use a transaction if use_transactions is true for the model" do
29
29
  @c.use_transactions = true
30
30
  @d.destroy
31
- MODEL_DB.sqls.should == ["BEGIN", "SELECT * FROM items", "COMMIT"]
31
+ DB.sqls.should == ["BEGIN", "SELECT * FROM items", "COMMIT"]
32
32
  end
33
33
 
34
34
  it "should not use a transaction if use_transactions is false for the model" do
35
35
  @c.use_transactions = false
36
36
  @d.destroy
37
- MODEL_DB.sqls.should == ["SELECT * FROM items"]
37
+ DB.sqls.should == ["SELECT * FROM items"]
38
38
  end
39
39
  end
40
40
 
@@ -82,7 +82,7 @@ describe Sequel::Model::DatasetMethods do
82
82
  end
83
83
 
84
84
  specify "#join_table should handle model classes that aren't simple selects using a subselect" do
85
- @c.join(Class.new(Sequel::Model(MODEL_DB[:categories].where(:foo=>1))), :item_id => :id).sql.should == 'SELECT * FROM items INNER JOIN (SELECT * FROM categories WHERE (foo = 1)) AS t1 ON (t1.item_id = items.id)'
85
+ @c.join(Class.new(Sequel::Model(DB[:categories].where(:foo=>1))), :item_id => :id).sql.should == 'SELECT * FROM items INNER JOIN (SELECT * FROM categories WHERE (foo = 1)) AS t1 ON (t1.item_id = items.id)'
86
86
  end
87
87
 
88
88
  specify "#graph should allow use to use a model class when joining" do
@@ -92,7 +92,7 @@ describe Sequel::Model, "#eager" do
92
92
  h
93
93
  end
94
94
 
95
- MODEL_DB.reset
95
+ DB.reset
96
96
  end
97
97
  after do
98
98
  [:EagerAlbum, :EagerBand, :EagerTrack, :EagerGenre, :EagerBandMember].each{|x| Object.send(:remove_const, x)}
@@ -124,29 +124,39 @@ describe Sequel::Model, "#eager" do
124
124
 
125
125
  it "should eagerly load a single many_to_one association" do
126
126
  a = EagerAlbum.eager(:band).all
127
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
127
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
128
128
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
129
129
  a.first.band.should == EagerBand.load(:id=>2)
130
- MODEL_DB.sqls.should == []
130
+ DB.sqls.should == []
131
131
  end
132
132
 
133
133
  it "should eagerly load a single many_to_one association with the same name as the column" do
134
134
  EagerAlbum.def_column_alias(:band_id_id, :band_id)
135
135
  EagerAlbum.many_to_one :band_id, :key_column=>:band_id, :class=>EagerBand
136
136
  a = EagerAlbum.eager(:band_id).all
137
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
137
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (2))']
138
138
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
139
139
  a.first.band_id.should == EagerBand.load(:id=>2)
140
- MODEL_DB.sqls.should == []
140
+ DB.sqls.should == []
141
141
  end
142
142
 
143
143
  it "should eagerly load a single one_to_one association" do
144
144
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
145
145
  a = EagerAlbum.eager(:track).all
146
146
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
147
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
147
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
148
148
  a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
149
- MODEL_DB.sqls.should == []
149
+ DB.sqls.should == []
150
+ end
151
+
152
+ it "should use first matching entry when eager loading one_to_one association" do
153
+ EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
154
+ EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
155
+ a = EagerAlbum.eager(:track).all
156
+ a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
157
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
158
+ a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
159
+ DB.sqls.should == []
150
160
  end
151
161
 
152
162
  it "should eagerly load a single one_to_one association using the :distinct_on strategy" do
@@ -154,87 +164,76 @@ describe Sequel::Model, "#eager" do
154
164
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true
155
165
  a = EagerAlbum.eager(:track).all
156
166
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
157
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT DISTINCT ON (tracks.album_id) * FROM tracks WHERE (tracks.album_id IN (1)) ORDER BY tracks.album_id']
167
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT DISTINCT ON (tracks.album_id) * FROM tracks WHERE (tracks.album_id IN (1)) ORDER BY tracks.album_id']
158
168
  a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
159
- MODEL_DB.sqls.should == []
169
+ DB.sqls.should == []
160
170
  end
161
171
 
162
172
  it "should eagerly load a single one_to_one association using the :window_function strategy" do
163
173
  def (EagerTrack.dataset).supports_window_functions?() true end
164
- EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true, :order=>:name
174
+ EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :eager_limit_strategy=>true
165
175
  a = EagerAlbum.eager(:track).all
166
176
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
167
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 1)']
177
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 1)']
168
178
  a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
169
- MODEL_DB.sqls.should == []
179
+ DB.sqls.should == []
170
180
  end
171
181
 
172
- qspecify "should eagerly load a single one_to_one association using the :correlated_subquery strategy" do
173
- EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name
182
+ it "should not use distinct on eager limit strategy if the association has an offset" do
183
+ def (EagerTrack.dataset).supports_distinct_on?() true end
184
+ def (EagerTrack.dataset).supports_window_functions?() true end
185
+ EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1], :order=>:name
174
186
  a = EagerAlbum.eager(:track).all
175
187
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
176
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY name LIMIT 1))) ORDER BY name']
188
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x = 2)']
177
189
  a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
178
- MODEL_DB.sqls.should == []
190
+ DB.sqls.should == []
179
191
  end
180
192
 
181
- qspecify "should handle qualified order clauses when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
182
- EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>[:tracks__name, Sequel.desc(:tracks__name), Sequel.qualify(:tracks, :name), Sequel.qualify(:t, :name), 1]
193
+ it "should automatically use an eager limit stategy if the association has an offset" do
194
+ EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :limit=>[1,1]
195
+ EagerTrack.dataset._fetch = [{:id => 3, :album_id=>1}, {:id => 4, :album_id=>1}]
183
196
  a = EagerAlbum.eager(:track).all
184
197
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
185
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY t1.name, t1.name DESC, t1.name, t.name, 1 LIMIT 1))) ORDER BY tracks.name, tracks.name DESC, tracks.name, t.name, 1']
186
- a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
187
- MODEL_DB.sqls.should == []
188
- end
189
-
190
- qspecify "should handle qualified composite keys when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
191
- c1 = Class.new(EagerAlbum)
192
- c2 = Class.new(EagerTrack)
193
- c1.set_primary_key [:id, :band_id]
194
- c2.set_primary_key [:id, :album_id]
195
- c1.one_to_one :track, :class=>c2, :key=>[:album_id, :id], :eager_limit_strategy=>:correlated_subquery
196
- c2.dataset._fetch = {:id => 2, :album_id=>1}
197
- a = c1.eager(:track).all
198
- a.should == [c1.load(:id => 1, :band_id => 2)]
199
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (((tracks.album_id, tracks.id) IN ((1, 2))) AND ((tracks.id, tracks.album_id) IN (SELECT t1.id, t1.album_id FROM tracks AS t1 WHERE ((t1.album_id = tracks.album_id) AND (t1.id = tracks.id)) LIMIT 1)))']
200
- a.first.track.should == c2.load(:id => 2, :album_id=>1)
201
- MODEL_DB.sqls.should == []
198
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
199
+ a.first.track.should == EagerTrack.load(:id => 4, :album_id=>1)
200
+ DB.sqls.should == []
202
201
  end
203
202
 
204
203
  it "should eagerly load a single one_to_many association" do
205
204
  a = EagerAlbum.eager(:tracks).all
206
205
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
207
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
206
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
208
207
  a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
209
- MODEL_DB.sqls.should == []
208
+ DB.sqls.should == []
210
209
  end
211
210
 
212
211
  it "should eagerly load a single many_to_many association" do
213
212
  a = EagerAlbum.eager(:genres).all
214
213
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
215
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
214
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
216
215
  a.first.genres.should == [EagerGenre.load(:id=>4)]
217
- MODEL_DB.sqls.should == []
216
+ DB.sqls.should == []
218
217
  end
219
218
 
220
219
  it "should support using a custom :key option when eager loading many_to_one associations" do
221
220
  EagerAlbum.many_to_one :sband, :clone=>:band, :key=>:band_id3
222
221
  EagerBand.dataset._fetch = {:id=>6}
223
222
  a = EagerAlbum.eager(:sband).all
224
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (6))']
223
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE (bands.id IN (6))']
225
224
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
226
225
  a.first.sband.should == EagerBand.load(:id=>6)
227
- MODEL_DB.sqls.should == []
226
+ DB.sqls.should == []
228
227
  end
229
228
 
230
229
  it "should support using a custom :primary_key option when eager loading one_to_many associations" do
231
230
  EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil, :reciprocal=>nil
232
231
  EagerBand.dataset._fetch = {:id=>6}
233
232
  a = EagerBand.eager(:salbums).all
234
- MODEL_DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE (albums.band_id IN (2))']
233
+ DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE (albums.band_id IN (2))']
235
234
  a.should == [EagerBand.load(:id => 6)]
236
235
  a.first.salbums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
237
- MODEL_DB.sqls.should == []
236
+ DB.sqls.should == []
238
237
  end
239
238
 
240
239
  it "should support using a custom :left_primary_key option when eager loading many_to_many associations" do
@@ -242,38 +241,38 @@ describe Sequel::Model, "#eager" do
242
241
  EagerGenre.dataset._fetch = {:id=>4, :x_foreign_key_x=>6}
243
242
  a = EagerAlbum.eager(:sgenres).all
244
243
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
245
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (6)))"]
244
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (6)))"]
246
245
  a.first.sgenres.should == [EagerGenre.load(:id=>4)]
247
- MODEL_DB.sqls.should == []
246
+ DB.sqls.should == []
248
247
  end
249
248
 
250
249
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_one associations" do
251
250
  EagerAlbum.many_to_one :sband, :clone=>:band, :eager_loading_predicate_key=>Sequel./(:bands__id, 3), :primary_key_method=>:id3
252
251
  EagerBand.dataset._fetch = {:id=>6}
253
252
  a = EagerAlbum.eager(:sband).all
254
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE ((bands.id / 3) IN (2))']
253
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM bands WHERE ((bands.id / 3) IN (2))']
255
254
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
256
255
  a.first.sband.should == EagerBand.load(:id=>6)
257
- MODEL_DB.sqls.should == []
256
+ DB.sqls.should == []
258
257
  end
259
258
 
260
259
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_to_many associations" do
261
260
  EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil, :reciprocal=>nil
262
261
  EagerBand.dataset._fetch = {:id=>6}
263
262
  a = EagerBand.eager(:salbums).all
264
- MODEL_DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
263
+ DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
265
264
  a.should == [EagerBand.load(:id => 6)]
266
265
  a.first.salbums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
267
- MODEL_DB.sqls.should == []
266
+ DB.sqls.should == []
268
267
  end
269
268
 
270
269
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_many associations" do
271
270
  EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loading_predicate_key=>Sequel.*(:ag__album_id, 1)
272
271
  a = EagerAlbum.eager(:sgenres).all
273
272
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
274
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND ((ag.album_id * 1) IN (1)))"]
273
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND ((ag.album_id * 1) IN (1)))"]
275
274
  a.first.sgenres.should == [EagerGenre.load(:id=>4)]
276
- MODEL_DB.sqls.should == []
275
+ DB.sqls.should == []
277
276
  end
278
277
 
279
278
  it "should raise an error for an unhandled :eager_loader_key option" do
@@ -294,19 +293,19 @@ describe Sequel::Model, "#eager" do
294
293
  it "should correctly handle a :select=>[] option to many_to_many" do
295
294
  EagerAlbum.many_to_many :sgenres, :clone=>:genres, :select=>[]
296
295
  EagerAlbum.eager(:sgenres).all
297
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
296
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
298
297
  end
299
298
 
300
299
  it "should correctly handle an aliased join table in many_to_many" do
301
300
  EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>:ag___ga
302
301
  EagerAlbum.eager(:sgenres).all
303
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON ((ga.genre_id = genres.id) AND (ga.album_id IN (1)))"]
302
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON ((ga.genre_id = genres.id) AND (ga.album_id IN (1)))"]
304
303
  end
305
304
 
306
305
  it "should eagerly load multiple associations in a single call" do
307
306
  a = EagerAlbum.eager(:genres, :tracks, :band).all
308
307
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
309
- sqls = MODEL_DB.sqls
308
+ sqls = DB.sqls
310
309
  sqls.shift.should == 'SELECT * FROM albums'
311
310
  sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
312
311
  'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
@@ -315,13 +314,13 @@ describe Sequel::Model, "#eager" do
315
314
  a.band.should == EagerBand.load(:id=>2)
316
315
  a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
317
316
  a.genres.should == [EagerGenre.load(:id => 4)]
318
- MODEL_DB.sqls.should == []
317
+ DB.sqls.should == []
319
318
  end
320
319
 
321
320
  it "should eagerly load multiple associations in separate calls" do
322
321
  a = EagerAlbum.eager(:genres).eager(:tracks).eager(:band).all
323
322
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
324
- sqls = MODEL_DB.sqls
323
+ sqls = DB.sqls
325
324
  sqls.shift.should == 'SELECT * FROM albums'
326
325
  sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
327
326
  'SELECT * FROM tracks WHERE (tracks.album_id IN (1))',
@@ -330,13 +329,13 @@ describe Sequel::Model, "#eager" do
330
329
  a.band.should == EagerBand.load(:id=>2)
331
330
  a.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
332
331
  a.genres.should == [EagerGenre.load(:id => 4)]
333
- MODEL_DB.sqls.should == []
332
+ DB.sqls.should == []
334
333
  end
335
334
 
336
335
  it "should allow cascading of eager loading for associations of associated models" do
337
336
  a = EagerTrack.eager(:album=>{:band=>:members}).all
338
337
  a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
339
- MODEL_DB.sqls.should == ['SELECT * FROM tracks',
338
+ DB.sqls.should == ['SELECT * FROM tracks',
340
339
  'SELECT * FROM albums WHERE (albums.id IN (1))',
341
340
  'SELECT * FROM bands WHERE (bands.id IN (2))',
342
341
  "SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
@@ -344,41 +343,41 @@ describe Sequel::Model, "#eager" do
344
343
  a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
345
344
  a.album.band.should == EagerBand.load(:id => 2)
346
345
  a.album.band.members.should == [EagerBandMember.load(:id => 5)]
347
- MODEL_DB.sqls.should == []
346
+ DB.sqls.should == []
348
347
  end
349
348
 
350
349
  it "should cascade eagerly loading when the :eager association option is used" do
351
350
  a = EagerBand.eager(:albums).all
352
351
  a.should == [EagerBand.load(:id=>2)]
353
- MODEL_DB.sqls.should == ['SELECT * FROM bands',
352
+ DB.sqls.should == ['SELECT * FROM bands',
354
353
  'SELECT * FROM albums WHERE (albums.band_id IN (2))',
355
354
  'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
356
355
  a.first.albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
357
356
  a.first.albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
358
- MODEL_DB.sqls.should == []
357
+ DB.sqls.should == []
359
358
  end
360
359
 
361
360
  it "should respect :eager when lazily loading an association" do
362
361
  a = EagerBand.all
363
362
  a.should == [EagerBand.load(:id=>2)]
364
- MODEL_DB.sqls.should == ['SELECT * FROM bands']
363
+ DB.sqls.should == ['SELECT * FROM bands']
365
364
  a = a.first.albums
366
- MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE (albums.band_id = 2)',
365
+ DB.sqls.should == ['SELECT * FROM albums WHERE (albums.band_id = 2)',
367
366
  'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
368
367
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
369
368
  a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
370
- MODEL_DB.sqls.should == []
369
+ DB.sqls.should == []
371
370
  end
372
371
 
373
372
  it "should cascade eagerly loading when the :eager_graph association option is used" do
374
373
  EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
375
374
  a = EagerBand.eager(:graph_albums).all
376
375
  a.should == [EagerBand.load(:id=>2)]
377
- MODEL_DB.sqls.should == ['SELECT * FROM bands',
376
+ DB.sqls.should == ['SELECT * FROM bands',
378
377
  'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) WHERE (albums.band_id IN (2))']
379
378
  a.first.graph_albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
380
379
  a.first.graph_albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
381
- MODEL_DB.sqls.should == []
380
+ DB.sqls.should == []
382
381
  end
383
382
 
384
383
  it "should raise an Error when eager loading a many_to_many association with the :eager_graph option" do
@@ -388,14 +387,14 @@ describe Sequel::Model, "#eager" do
388
387
  it "should respect :eager_graph when lazily loading an association" do
389
388
  a = EagerBand.all
390
389
  a.should == [EagerBand.load(:id=>2)]
391
- MODEL_DB.sqls.should == ['SELECT * FROM bands']
390
+ DB.sqls.should == ['SELECT * FROM bands']
392
391
  a = a.first
393
392
  EagerAlbum.dataset._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
394
393
  a.graph_albums
395
- MODEL_DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) WHERE (albums.band_id = 2)']
394
+ DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id) WHERE (albums.band_id = 2)']
396
395
  a.graph_albums.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
397
396
  a.graph_albums.first.tracks.should == [EagerTrack.load(:id => 3, :album_id => 1)]
398
- MODEL_DB.sqls.should == []
397
+ DB.sqls.should == []
399
398
  end
400
399
 
401
400
  it "should respect :eager_graph when lazily loading a many_to_many association" do
@@ -404,70 +403,70 @@ describe Sequel::Model, "#eager" do
404
403
  ds._fetch = [{:id=>5, :bands_id=>2, :p_k=>6}, {:id=>5, :bands_id=>3, :p_k=>6}]
405
404
  a = EagerBand.load(:id=>2)
406
405
  a.graph_members.should == [EagerBandMember.load(:id=>5)]
407
- MODEL_DB.sqls.should == ['SELECT members.id, bands.id AS bands_id, bands.p_k FROM (SELECT members.* FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id = 2))) AS members LEFT OUTER JOIN bm AS bm_0 ON (bm_0.member_id = members.id) LEFT OUTER JOIN bands ON (bands.id = bm_0.band_id) ORDER BY bands.id']
406
+ DB.sqls.should == ['SELECT members.id, bands.id AS bands_id, bands.p_k FROM (SELECT members.* FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id = 2))) AS members LEFT OUTER JOIN bm AS bm_0 ON (bm_0.member_id = members.id) LEFT OUTER JOIN bands ON (bands.id = bm_0.band_id) ORDER BY bands.id']
408
407
  a.graph_members.first.bands.should == [EagerBand.load(:id=>2, :p_k=>6), EagerBand.load(:id=>3, :p_k=>6)]
409
- MODEL_DB.sqls.should == []
408
+ DB.sqls.should == []
410
409
  end
411
410
 
412
411
  it "should respect :conditions when eagerly loading" do
413
412
  EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>{:a=>32}
414
413
  a = EagerBandMember.eager(:good_bands).all
415
414
  a.should == [EagerBandMember.load(:id => 5)]
416
- MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (a = 32) ORDER BY id']
415
+ DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (a = 32) ORDER BY id']
417
416
  a.first.good_bands.should == [EagerBand.load(:id => 2)]
418
- MODEL_DB.sqls.should == []
417
+ DB.sqls.should == []
419
418
 
420
419
  EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>"x = 1"
421
420
  a = EagerBandMember.eager(:good_bands).all
422
- MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (x = 1) ORDER BY id']
421
+ DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) WHERE (x = 1) ORDER BY id']
423
422
  end
424
423
 
425
424
  it "should respect :order when eagerly loading" do
426
425
  a = EagerBandMember.eager(:bands).all
427
426
  a.should == [EagerBandMember.load(:id => 5)]
428
- MODEL_DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) ORDER BY id']
427
+ DB.sqls.should == ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON ((bm.band_id = bands.id) AND (bm.member_id IN (5))) ORDER BY id']
429
428
  a.first.bands.should == [EagerBand.load(:id => 2)]
430
- MODEL_DB.sqls.should == []
429
+ DB.sqls.should == []
431
430
  end
432
431
 
433
432
  it "should populate the reciprocal many_to_one association when eagerly loading the one_to_many association" do
434
433
  a = EagerAlbum.eager(:tracks).all
435
434
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
436
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
435
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE (tracks.album_id IN (1))']
437
436
  a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
438
437
  a.first.tracks.first.album.should == a.first
439
- MODEL_DB.sqls.should == []
438
+ DB.sqls.should == []
440
439
  end
441
440
 
442
441
  it "should cache the negative lookup when eagerly loading a many_to_one association" do
443
442
  a = EagerAlbum.eager(:band).filter(:id=>101).all
444
443
  a.should == [EagerAlbum.load(:id => 101, :band_id => 101)]
445
- MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE (id = 101)', 'SELECT * FROM bands WHERE (bands.id IN (101))']
444
+ DB.sqls.should == ['SELECT * FROM albums WHERE (id = 101)', 'SELECT * FROM bands WHERE (bands.id IN (101))']
446
445
  a.first.associations.fetch(:band, 2).should be_nil
447
446
  a.first.band.should be_nil
448
- MODEL_DB.sqls.should == []
447
+ DB.sqls.should == []
449
448
  end
450
449
 
451
450
  it "should cache the negative lookup when eagerly loading a *_to_many associations" do
452
451
  a = EagerBand.eager(:albums).filter('id > 100').all
453
452
  a.should == [EagerBand.load(:id => 101), EagerBand.load(:id =>102)]
454
- sqls = MODEL_DB.sqls
453
+ sqls = DB.sqls
455
454
  ['SELECT * FROM albums WHERE (albums.band_id IN (101, 102))', 'SELECT * FROM albums WHERE (albums.band_id IN (102, 101))'].should include(sqls.delete_at(1))
456
455
  sqls.should == ['SELECT * FROM bands WHERE (id > 100)', "SELECT * FROM tracks WHERE (tracks.album_id IN (101))"]
457
456
  a.map{|b| b.associations[:albums]}.should == [[EagerAlbum.load({:band_id=>101, :id=>101})], []]
458
- MODEL_DB.sqls.should == []
457
+ DB.sqls.should == []
459
458
  end
460
459
 
461
460
  it "should use the association's block when eager loading by default" do
462
461
  EagerAlbum.eager(:good_tracks).all
463
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (name = 'Good'))"]
462
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (name = 'Good'))"]
464
463
  end
465
464
 
466
465
  it "should use the eager_block option when eager loading if given" do
467
466
  EagerBand.eager(:good_albums).all
468
- MODEL_DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))"]
467
+ DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))"]
469
468
  EagerBand.eager(:good_albums=>:good_tracks).all
470
- MODEL_DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))", "SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (name = 'Good'))"]
469
+ DB.sqls.should == ['SELECT * FROM bands', "SELECT * FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))", "SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (name = 'Good'))"]
471
470
  end
472
471
 
473
472
  it "should raise an error when attempting to eagerly load an association with the :allow_eager option set to false" do
@@ -477,34 +476,34 @@ describe Sequel::Model, "#eager" do
477
476
 
478
477
  it "should respect the association's :select option" do
479
478
  EagerAlbum.eager(:band_name).all
480
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM bands WHERE (bands.id IN (2))"]
479
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM bands WHERE (bands.id IN (2))"]
481
480
  EagerAlbum.eager(:track_names).all
482
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM tracks WHERE (tracks.album_id IN (1))"]
481
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT id, name FROM tracks WHERE (tracks.album_id IN (1))"]
483
482
  EagerAlbum.eager(:genre_names).all
484
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT id, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
483
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT id, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
485
484
  end
486
485
 
487
486
  it "should respect many_to_one association's :qualify option" do
488
487
  EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :qualify=>false, :key=>:band_id
489
488
  EagerBand.dataset._fetch = {:id=>2}
490
489
  as = EagerAlbum.eager(:special_band).all
491
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (id IN (2))"]
490
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (id IN (2))"]
492
491
  as.map{|a| a.special_band}.should == [EagerBand.load(:id=>2)]
493
- MODEL_DB.sqls.should == []
492
+ DB.sqls.should == []
494
493
  end
495
494
 
496
495
  it "should respect the association's :primary_key option" do
497
496
  EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>:p_k, :key=>:band_id
498
497
  EagerBand.dataset._fetch = {:p_k=>2, :id=>1}
499
498
  as = EagerAlbum.eager(:special_band).all
500
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (bands.p_k IN (2))"]
499
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE (bands.p_k IN (2))"]
501
500
  as.length.should == 1
502
501
  as.first.special_band.should == EagerBand.load(:p_k=>2, :id=>1)
503
502
 
504
503
  EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id, :reciprocal=>nil
505
504
  EagerTrack.dataset._fetch = {:album_id=>2, :id=>1}
506
505
  as = EagerAlbum.eager(:special_tracks).all
507
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
506
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
508
507
  as.length.should == 1
509
508
  as.first.special_tracks.should == [EagerTrack.load(:album_id=>2, :id=>1)]
510
509
  end
@@ -513,7 +512,7 @@ describe Sequel::Model, "#eager" do
513
512
  EagerAlbum.many_to_one :special_band, :class=>:EagerBand, :primary_key=>[:id, :p_k], :key=>[:band_id, :id]
514
513
  EagerBand.dataset._fetch = {:p_k=>1, :id=>2}
515
514
  as = EagerAlbum.eager(:special_band).all
516
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE ((bands.id, bands.p_k) IN ((2, 1)))"]
515
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM bands WHERE ((bands.id, bands.p_k) IN ((2, 1)))"]
517
516
  as.length.should == 1
518
517
  as.first.special_band.should == EagerBand.load(:p_k=>1, :id=>2)
519
518
  end
@@ -522,7 +521,7 @@ describe Sequel::Model, "#eager" do
522
521
  EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>[:band_id, :id], :key=>[:id, :album_id]
523
522
  EagerTrack.dataset._fetch = {:album_id=>1, :id=>2}
524
523
  as = EagerAlbum.eager(:special_tracks).all
525
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.id, tracks.album_id) IN ((2, 1)))"]
524
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE ((tracks.id, tracks.album_id) IN ((2, 1)))"]
526
525
  as.length.should == 1
527
526
  as.first.special_tracks.should == [EagerTrack.load(:album_id=>1, :id=>2)]
528
527
  end
@@ -531,7 +530,7 @@ describe Sequel::Model, "#eager" do
531
530
  EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :left_primary_key=>[:band_id, :id], :left_key=>[:l1, :l2], :right_primary_key=>[:xxx, :id], :right_key=>[:r1, :r2], :join_table=>:ag
532
531
  EagerGenre.dataset._fetch = [{:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>5}, {:x_foreign_key_0_x=>2, :x_foreign_key_1_x=>1, :id=>6}]
533
532
  as = EagerAlbum.eager(:special_genres).all
534
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.l1 AS x_foreign_key_0_x, ag.l2 AS x_foreign_key_1_x FROM genres INNER JOIN ag ON ((ag.r1 = genres.xxx) AND (ag.r2 = genres.id) AND ((ag.l1, ag.l2) IN ((2, 1))))"]
533
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.l1 AS x_foreign_key_0_x, ag.l2 AS x_foreign_key_1_x FROM genres INNER JOIN ag ON ((ag.r1 = genres.xxx) AND (ag.r2 = genres.id) AND ((ag.l1, ag.l2) IN ((2, 1))))"]
535
534
  as.length.should == 1
536
535
  as.first.special_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
537
536
  end
@@ -540,7 +539,7 @@ describe Sequel::Model, "#eager" do
540
539
  EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_primary_key=>:xxx, :right_key=>:genre_id, :join_table=>:ag
541
540
  EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
542
541
  as = EagerAlbum.eager(:special_genres).all
543
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.xxx) AND (ag.album_id IN (2)))"]
542
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.xxx) AND (ag.album_id IN (2)))"]
544
543
  as.length.should == 1
545
544
  as.first.special_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
546
545
  end
@@ -549,101 +548,98 @@ describe Sequel::Model, "#eager" do
549
548
  EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>2
550
549
  EagerTrack.dataset._fetch = [{:album_id=>1, :id=>2}, {:album_id=>1, :id=>3}, {:album_id=>1, :id=>4}]
551
550
  as = EagerAlbum.eager(:first_two_tracks).all
552
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
551
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
553
552
  as.length.should == 1
554
553
  as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>2), EagerTrack.load(:album_id=>1, :id=>3)]
555
554
 
556
- MODEL_DB.reset
557
- EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[2,1]
555
+ DB.reset
556
+ EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[1,1]
557
+ as = EagerAlbum.eager(:first_two_tracks).all
558
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
559
+ as.length.should == 1
560
+ as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>3)]
561
+
562
+ DB.reset
563
+ EagerAlbum.one_to_many :first_two_tracks, :class=>:EagerTrack, :key=>:album_id, :limit=>[nil,1]
558
564
  as = EagerAlbum.eager(:first_two_tracks).all
559
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
565
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (1))"]
560
566
  as.length.should == 1
561
567
  as.first.first_two_tracks.should == [EagerTrack.load(:album_id=>1, :id=>3), EagerTrack.load(:album_id=>1, :id=>4)]
562
568
  end
563
569
 
564
570
  it "should respect the :limit option on a one_to_many association using the :window_function strategy" do
565
571
  def (EagerTrack.dataset).supports_window_functions?() true end
566
- EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true, :order=>:name, :limit=>2
572
+ EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>2
567
573
  a = EagerAlbum.eager(:tracks).all
568
574
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
569
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
575
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x <= 2)']
570
576
  a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
571
- MODEL_DB.sqls.should == []
577
+ DB.sqls.should == []
572
578
  end
573
579
 
574
580
  it "should respect the :limit option with an offset on a one_to_many association using the :window_function strategy" do
575
581
  def (EagerTrack.dataset).supports_window_functions?() true end
576
- EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>true, :order=>:name, :limit=>[2, 1]
577
- a = EagerAlbum.eager(:tracks).all
578
- a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
579
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
580
- a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
581
- MODEL_DB.sqls.should == []
582
- end
583
-
584
- qspecify "should respect the :limit option on a one_to_many association using the :correlated_subquery strategy" do
585
- EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name, :limit=>2
582
+ EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[2, 1]
586
583
  a = EagerAlbum.eager(:tracks).all
587
584
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
588
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY name LIMIT 2))) ORDER BY name']
585
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))']
589
586
  a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
590
- MODEL_DB.sqls.should == []
587
+ DB.sqls.should == []
591
588
  end
592
589
 
593
- qspecify "should respect the :limit option with an offset on a one_to_many association using the :correlated_subquery strategy" do
594
- EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name, :limit=>[2, 1]
590
+ it "should respect the :limit option with just an offset on a one_to_many association using the :window_function strategy" do
591
+ def (EagerTrack.dataset).supports_window_functions?() true end
592
+ EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :order=>:name, :limit=>[nil, 1]
595
593
  a = EagerAlbum.eager(:tracks).all
596
594
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
597
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM tracks WHERE ((tracks.album_id IN (1)) AND (tracks.id IN (SELECT t1.id FROM tracks AS t1 WHERE (t1.album_id = tracks.album_id) ORDER BY name LIMIT 2 OFFSET 1))) ORDER BY name']
595
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY tracks.album_id ORDER BY name) AS x_sequel_row_number_x FROM tracks WHERE (tracks.album_id IN (1))) AS t1 WHERE (x_sequel_row_number_x >= 2)']
598
596
  a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
599
- MODEL_DB.sqls.should == []
597
+ DB.sqls.should == []
600
598
  end
601
599
 
602
600
  it "should respect the limit option on a many_to_many association" do
603
601
  EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2
604
602
  EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
605
603
  as = EagerAlbum.eager(:first_two_genres).all
606
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
604
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
607
605
  as.length.should == 1
608
606
  as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
609
607
 
610
608
  EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
611
- EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[2, 1]
609
+ EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[1, 1]
612
610
  as = EagerAlbum.eager(:first_two_genres).all
613
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
611
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
612
+ as.length.should == 1
613
+ as.first.first_two_genres.should == [EagerGenre.load(:id=>6)]
614
+
615
+ EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}, {:x_foreign_key_x=>2, :id=>7}]
616
+ EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[nil, 1]
617
+ as = EagerAlbum.eager(:first_two_genres).all
618
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))"]
614
619
  as.length.should == 1
615
620
  as.first.first_two_genres.should == [EagerGenre.load(:id=>6), EagerGenre.load(:id=>7)]
616
621
  end
617
622
 
618
623
  it "should respect the limit option on a many_to_many association using the :window_function strategy" do
619
624
  def (EagerGenre.dataset).supports_window_functions?() true end
620
- EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>true, :limit=>2, :order=>:name
621
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
622
- as = EagerAlbum.eager(:first_two_genres).all
623
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE (x_sequel_row_number_x <= 2)"]
624
- as.length.should == 1
625
- as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
626
-
625
+ EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>2, :order=>:name
627
626
  EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
628
- EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>true, :limit=>[2, 1], :order=>:name
629
627
  as = EagerAlbum.eager(:first_two_genres).all
630
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 4))"]
628
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE (x_sequel_row_number_x <= 2)"]
631
629
  as.length.should == 1
632
630
  as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
633
- end
634
631
 
635
- qspecify "should respect the limit option on a many_to_many association using the :correlated_subquery strategy" do
636
- EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>:correlated_subquery, :limit=>2, :order=>:name
637
- EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
632
+ EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}]
633
+ EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[1, 1], :order=>:name
638
634
  as = EagerAlbum.eager(:first_two_genres).all
639
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2))) WHERE (genres.id IN (SELECT t1.id FROM genres AS t1 INNER JOIN ag AS t2 ON ((t2.genre_id = t1.id) AND (t2.album_id = ag.album_id)) ORDER BY name LIMIT 2)) ORDER BY name"]
635
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE ((x_sequel_row_number_x >= 2) AND (x_sequel_row_number_x < 3))"]
640
636
  as.length.should == 1
641
- as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
637
+ as.first.first_two_genres.should == [EagerGenre.load(:id=>5)]
642
638
 
643
639
  EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
644
- EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>:correlated_subquery, :limit=>[2, 1], :order=>:name
640
+ EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :limit=>[nil, 1], :order=>:name
645
641
  as = EagerAlbum.eager(:first_two_genres).all
646
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2))) WHERE (genres.id IN (SELECT t1.id FROM genres AS t1 INNER JOIN ag AS t2 ON ((t2.genre_id = t1.id) AND (t2.album_id = ag.album_id)) ORDER BY name LIMIT 2 OFFSET 1)) ORDER BY name"]
642
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM (SELECT genres.*, ag.album_id AS x_foreign_key_x, row_number() OVER (PARTITION BY ag.album_id ORDER BY name) AS x_sequel_row_number_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (2)))) AS t1 WHERE (x_sequel_row_number_x >= 2)"]
647
643
  as.length.should == 1
648
644
  as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
649
645
  end
@@ -663,7 +659,7 @@ describe Sequel::Model, "#eager" do
663
659
  end)
664
660
  a = EagerAlbum.eager(:special_genres, :special_tracks, :special_band).all
665
661
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
666
- sqls = MODEL_DB.sqls
662
+ sqls = DB.sqls
667
663
  sqls.shift.should == 'SELECT * FROM albums'
668
664
  sqls.sort.should == ['SELECT * FROM bands WHERE (album_id IN (1, 2)) ORDER BY name LIMIT 1',
669
665
  'SELECT * FROM genres INNER JOIN ag USING (genre_id) WHERE (album_id IN (1))',
@@ -672,13 +668,9 @@ describe Sequel::Model, "#eager" do
672
668
  a.special_band.should == EagerBand.load(:id => 2)
673
669
  a.special_tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
674
670
  a.special_genres.should == [EagerGenre.load(:id => 4)]
675
- MODEL_DB.sqls.should == []
671
+ DB.sqls.should == []
676
672
  end
677
673
 
678
- it "should raise an error if you use an :eager_loader proc with the wrong arity" do
679
- proc{EagerAlbum.many_to_one :special_band, :eager_loader=>proc{|a, b|}}.should raise_error(Sequel::Error)
680
- end
681
-
682
674
  it "should respect :after_load callbacks on associations when eager loading" do
683
675
  EagerAlbum.many_to_one :al_band, :class=>'EagerBand', :key=>:band_id, :after_load=>proc{|o, a| a.id *=2}
684
676
  EagerAlbum.one_to_many :al_tracks, :class=>'EagerTrack', :key=>:album_id, :after_load=>proc{|o, os| os.each{|a| a.id *=2}}
@@ -694,7 +686,7 @@ describe Sequel::Model, "#eager" do
694
686
  EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :uniq=>true
695
687
  EagerGenre.dataset._fetch = [{:x_foreign_key_x=>1, :id=>8}, {:x_foreign_key_x=>1, :id=>8}]
696
688
  a = EagerAlbum.eager(:al_genres).all.first
697
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
689
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
698
690
  a.should == EagerAlbum.load(:id => 1, :band_id => 2)
699
691
  a.al_genres.should == [EagerGenre.load(:id=>8)]
700
692
  end
@@ -702,7 +694,7 @@ describe Sequel::Model, "#eager" do
702
694
  it "should respect :distinct option when eagerly loading many_to_many associations" do
703
695
  EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :distinct=>true
704
696
  a = EagerAlbum.eager(:al_genres).all.first
705
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
697
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
706
698
  a.should == EagerAlbum.load(:id => 1, :band_id => 2)
707
699
  a.al_genres.should == [EagerGenre.load(:id=>4)]
708
700
  end
@@ -710,40 +702,40 @@ describe Sequel::Model, "#eager" do
710
702
  it "should eagerly load a many_to_one association with custom eager block" do
711
703
  a = EagerAlbum.eager(:band => proc {|ds| ds.select(:id, :name)}).all
712
704
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
713
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT id, name FROM bands WHERE (bands.id IN (2))']
705
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT id, name FROM bands WHERE (bands.id IN (2))']
714
706
  a.first.band.should == EagerBand.load(:id => 2)
715
- MODEL_DB.sqls.should == []
707
+ DB.sqls.should == []
716
708
  end
717
709
 
718
710
  it "should eagerly load a one_to_one association with custom eager block" do
719
711
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id
720
712
  a = EagerAlbum.eager(:track => proc {|ds| ds.select(:id)}).all
721
713
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
722
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
714
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
723
715
  a.first.track.should == EagerTrack.load(:id => 3, :album_id=>1)
724
- MODEL_DB.sqls.should == []
716
+ DB.sqls.should == []
725
717
  end
726
718
 
727
719
  it "should eagerly load a one_to_many association with custom eager block" do
728
720
  a = EagerAlbum.eager(:tracks => proc {|ds| ds.select(:id)}).all
729
721
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
730
- MODEL_DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
722
+ DB.sqls.should == ['SELECT * FROM albums', 'SELECT id FROM tracks WHERE (tracks.album_id IN (1))']
731
723
  a.first.tracks.should == [EagerTrack.load(:id => 3, :album_id=>1)]
732
- MODEL_DB.sqls.should == []
724
+ DB.sqls.should == []
733
725
  end
734
726
 
735
727
  it "should eagerly load a many_to_many association with custom eager block" do
736
728
  a = EagerAlbum.eager(:genres => proc {|ds| ds.select(:name)}).all
737
729
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
738
- MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
730
+ DB.sqls.should == ['SELECT * FROM albums', "SELECT name, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
739
731
  a.first.genres.should == [EagerGenre.load(:id => 4)]
740
- MODEL_DB.sqls.should == []
732
+ DB.sqls.should == []
741
733
  end
742
734
 
743
735
  it "should allow cascading of eager loading within a custom eager block" do
744
736
  a = EagerTrack.eager(:album => proc {|ds| ds.eager(:band => :members)}).all
745
737
  a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
746
- MODEL_DB.sqls.should == ['SELECT * FROM tracks',
738
+ DB.sqls.should == ['SELECT * FROM tracks',
747
739
  'SELECT * FROM albums WHERE (albums.id IN (1))',
748
740
  'SELECT * FROM bands WHERE (bands.id IN (2))',
749
741
  "SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
@@ -751,13 +743,13 @@ describe Sequel::Model, "#eager" do
751
743
  a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
752
744
  a.album.band.should == EagerBand.load(:id => 2)
753
745
  a.album.band.members.should == [EagerBandMember.load(:id => 5)]
754
- MODEL_DB.sqls.should == []
746
+ DB.sqls.should == []
755
747
  end
756
748
 
757
749
  it "should allow cascading of eager loading with custom callback with hash value" do
758
750
  a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>{:band => :members}}).all
759
751
  a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
760
- MODEL_DB.sqls.should == ['SELECT * FROM tracks',
752
+ DB.sqls.should == ['SELECT * FROM tracks',
761
753
  'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
762
754
  'SELECT * FROM bands WHERE (bands.id IN (2))',
763
755
  "SELECT members.*, bm.band_id AS x_foreign_key_x FROM members INNER JOIN bm ON ((bm.member_id = members.id) AND (bm.band_id IN (2)))"]
@@ -765,25 +757,25 @@ describe Sequel::Model, "#eager" do
765
757
  a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
766
758
  a.album.band.should == EagerBand.load(:id => 2)
767
759
  a.album.band.members.should == [EagerBandMember.load(:id => 5)]
768
- MODEL_DB.sqls.should == []
760
+ DB.sqls.should == []
769
761
  end
770
762
 
771
763
  it "should allow cascading of eager loading with custom callback with symbol value" do
772
764
  a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>:band}).all
773
765
  a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
774
- MODEL_DB.sqls.should == ['SELECT * FROM tracks',
766
+ DB.sqls.should == ['SELECT * FROM tracks',
775
767
  'SELECT id, band_id FROM albums WHERE (albums.id IN (1))',
776
768
  'SELECT * FROM bands WHERE (bands.id IN (2))']
777
769
  a = a.first
778
770
  a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
779
771
  a.album.band.should == EagerBand.load(:id => 2)
780
- MODEL_DB.sqls.should == []
772
+ DB.sqls.should == []
781
773
  end
782
774
 
783
775
  it "should allow cascading of eager loading with custom callback with array value" do
784
776
  a = EagerTrack.eager(:album=>{proc{|ds| ds.select(:id, :band_id)}=>[:band, :band_name]}).all
785
777
  a.should == [EagerTrack.load(:id => 3, :album_id => 1)]
786
- sqls = MODEL_DB.sqls
778
+ sqls = DB.sqls
787
779
  sqls.slice!(0..1).should == ['SELECT * FROM tracks',
788
780
  'SELECT id, band_id FROM albums WHERE (albums.id IN (1))']
789
781
  sqls.sort.should == ['SELECT * FROM bands WHERE (bands.id IN (2))',
@@ -792,12 +784,12 @@ describe Sequel::Model, "#eager" do
792
784
  a.album.should == EagerAlbum.load(:id => 1, :band_id => 2)
793
785
  a.album.band.should == EagerBand.load(:id => 2)
794
786
  a.album.band_name.should == EagerBand.load(:id => 2)
795
- MODEL_DB.sqls.should == []
787
+ DB.sqls.should == []
796
788
  end
797
789
 
798
790
  it "should call both association and custom eager blocks" do
799
791
  EagerBand.eager(:good_albums => proc {|ds| ds.select(:name)}).all
800
- MODEL_DB.sqls.should == ['SELECT * FROM bands', "SELECT name FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))"]
792
+ DB.sqls.should == ['SELECT * FROM bands', "SELECT name FROM albums WHERE ((albums.band_id IN (2)) AND (name = 'good'))"]
801
793
  end
802
794
  end
803
795
 
@@ -1019,7 +1011,7 @@ describe Sequel::Model, "#eager_graph" do
1019
1011
  end
1020
1012
 
1021
1013
  it "should populate the reciprocal many_to_one association when eagerly loading the one_to_many association" do
1022
- MODEL_DB.reset
1014
+ DB.reset
1023
1015
  ds = GraphAlbum.eager_graph(:tracks)
1024
1016
  ds.sql.should == 'SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)'
1025
1017
  ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
@@ -1028,7 +1020,7 @@ describe Sequel::Model, "#eager_graph" do
1028
1020
  a = a.first
1029
1021
  a.tracks.should == [GraphTrack.load(:id => 3, :album_id=>1)]
1030
1022
  a.tracks.first.album.should == a
1031
- MODEL_DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)']
1023
+ DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)']
1032
1024
  end
1033
1025
 
1034
1026
  it "should eager load multiple associations from the same table" do
@@ -1086,7 +1078,7 @@ describe Sequel::Model, "#eager_graph" do
1086
1078
  end
1087
1079
 
1088
1080
  it "should be able to be used in combination with #eager" do
1089
- MODEL_DB.reset
1081
+ DB.reset
1090
1082
  ds = GraphAlbum.eager_graph(:tracks).eager(:genres)
1091
1083
  ds._fetch = {:id=>1, :band_id=>2, :tracks_id=>3, :album_id=>1}
1092
1084
  ds2 = GraphGenre.dataset
@@ -1096,7 +1088,7 @@ describe Sequel::Model, "#eager_graph" do
1096
1088
  a = a.first
1097
1089
  a.tracks.should == [GraphTrack.load(:id=>3, :album_id=>1)]
1098
1090
  a.genres.should == [GraphGenre.load(:id => 6)]
1099
- MODEL_DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)',
1091
+ DB.sqls.should == ['SELECT albums.id, albums.band_id, tracks.id AS tracks_id, tracks.album_id FROM albums LEFT OUTER JOIN tracks ON (tracks.album_id = albums.id)',
1100
1092
  "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
1101
1093
  end
1102
1094
 
@@ -1332,10 +1324,6 @@ describe Sequel::Model, "#eager_graph" do
1332
1324
  GraphAlbum.eager_graph(:active_genres).sql.should == "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag AS a123 ON (a123.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres USING (album_id)"
1333
1325
  end
1334
1326
 
1335
- it "should raise an error if you use an :eager_grapher proc with the wrong arity" do
1336
- proc{GraphAlbum.many_to_one :special_band, :eager_grapher=>proc{|a, b|}}.should raise_error(Sequel::Error)
1337
- end
1338
-
1339
1327
  it "should respect the association's :graph_only_conditions option" do
1340
1328
  GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :graph_only_conditions=>{:active=>true}
1341
1329
  GraphAlbum.eager_graph(:active_band).sql.should == "SELECT albums.id, albums.band_id, active_band.id AS active_band_id, active_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS active_band ON (active_band.active IS TRUE)"