sequel 3.48.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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)"