sequel 3.47.0 → 3.48.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 (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +230 -0
  3. data/README.rdoc +31 -40
  4. data/Rakefile +1 -14
  5. data/doc/active_record.rdoc +29 -29
  6. data/doc/association_basics.rdoc +4 -13
  7. data/doc/cheat_sheet.rdoc +8 -6
  8. data/doc/code_order.rdoc +89 -0
  9. data/doc/core_extensions.rdoc +3 -3
  10. data/doc/dataset_basics.rdoc +7 -8
  11. data/doc/dataset_filtering.rdoc +7 -2
  12. data/doc/mass_assignment.rdoc +2 -3
  13. data/doc/migration.rdoc +8 -8
  14. data/doc/model_hooks.rdoc +11 -7
  15. data/doc/object_model.rdoc +2 -2
  16. data/doc/opening_databases.rdoc +5 -14
  17. data/doc/prepared_statements.rdoc +5 -9
  18. data/doc/querying.rdoc +23 -28
  19. data/doc/reflection.rdoc +11 -0
  20. data/doc/release_notes/3.48.0.txt +477 -0
  21. data/doc/schema_modification.rdoc +12 -5
  22. data/doc/security.rdoc +2 -2
  23. data/doc/sharding.rdoc +1 -2
  24. data/doc/sql.rdoc +10 -13
  25. data/doc/testing.rdoc +8 -4
  26. data/doc/transactions.rdoc +2 -2
  27. data/doc/validations.rdoc +40 -17
  28. data/doc/virtual_rows.rdoc +2 -2
  29. data/lib/sequel/adapters/ado.rb +25 -20
  30. data/lib/sequel/adapters/ado/access.rb +1 -0
  31. data/lib/sequel/adapters/ado/mssql.rb +1 -0
  32. data/lib/sequel/adapters/db2.rb +9 -7
  33. data/lib/sequel/adapters/dbi.rb +16 -16
  34. data/lib/sequel/adapters/do.rb +17 -18
  35. data/lib/sequel/adapters/do/mysql.rb +1 -0
  36. data/lib/sequel/adapters/do/postgres.rb +2 -0
  37. data/lib/sequel/adapters/do/sqlite.rb +1 -0
  38. data/lib/sequel/adapters/firebird.rb +5 -7
  39. data/lib/sequel/adapters/ibmdb.rb +23 -20
  40. data/lib/sequel/adapters/informix.rb +8 -2
  41. data/lib/sequel/adapters/jdbc.rb +39 -35
  42. data/lib/sequel/adapters/jdbc/as400.rb +1 -0
  43. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
  44. data/lib/sequel/adapters/jdbc/db2.rb +1 -0
  45. data/lib/sequel/adapters/jdbc/derby.rb +1 -0
  46. data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
  47. data/lib/sequel/adapters/jdbc/h2.rb +1 -0
  48. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
  49. data/lib/sequel/adapters/jdbc/informix.rb +1 -0
  50. data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
  51. data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
  52. data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
  53. data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
  54. data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
  55. data/lib/sequel/adapters/jdbc/progress.rb +1 -0
  56. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
  57. data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
  58. data/lib/sequel/adapters/mock.rb +30 -31
  59. data/lib/sequel/adapters/mysql.rb +6 -7
  60. data/lib/sequel/adapters/mysql2.rb +5 -6
  61. data/lib/sequel/adapters/odbc.rb +22 -20
  62. data/lib/sequel/adapters/odbc/mssql.rb +1 -0
  63. data/lib/sequel/adapters/openbase.rb +4 -1
  64. data/lib/sequel/adapters/oracle.rb +10 -8
  65. data/lib/sequel/adapters/postgres.rb +12 -10
  66. data/lib/sequel/adapters/shared/access.rb +6 -0
  67. data/lib/sequel/adapters/shared/cubrid.rb +2 -0
  68. data/lib/sequel/adapters/shared/db2.rb +2 -0
  69. data/lib/sequel/adapters/shared/firebird.rb +2 -0
  70. data/lib/sequel/adapters/shared/informix.rb +2 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +14 -8
  72. data/lib/sequel/adapters/shared/mysql.rb +6 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +2 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +14 -4
  75. data/lib/sequel/adapters/shared/progress.rb +1 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +4 -3
  77. data/lib/sequel/adapters/sqlite.rb +6 -7
  78. data/lib/sequel/adapters/swift.rb +20 -21
  79. data/lib/sequel/adapters/swift/mysql.rb +1 -0
  80. data/lib/sequel/adapters/swift/postgres.rb +2 -0
  81. data/lib/sequel/adapters/swift/sqlite.rb +1 -0
  82. data/lib/sequel/adapters/tinytds.rb +5 -6
  83. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
  84. data/lib/sequel/connection_pool.rb +1 -1
  85. data/lib/sequel/core.rb +57 -50
  86. data/lib/sequel/database/connecting.rb +9 -10
  87. data/lib/sequel/database/dataset.rb +11 -6
  88. data/lib/sequel/database/dataset_defaults.rb +61 -69
  89. data/lib/sequel/database/features.rb +21 -0
  90. data/lib/sequel/database/misc.rb +23 -3
  91. data/lib/sequel/database/query.rb +13 -7
  92. data/lib/sequel/database/schema_methods.rb +6 -6
  93. data/lib/sequel/database/transactions.rb +1 -0
  94. data/lib/sequel/dataset/actions.rb +51 -38
  95. data/lib/sequel/dataset/features.rb +1 -0
  96. data/lib/sequel/dataset/graph.rb +9 -33
  97. data/lib/sequel/dataset/misc.rb +30 -5
  98. data/lib/sequel/dataset/mutation.rb +2 -3
  99. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  100. data/lib/sequel/dataset/query.rb +91 -27
  101. data/lib/sequel/dataset/sql.rb +40 -6
  102. data/lib/sequel/deprecated.rb +74 -0
  103. data/lib/sequel/deprecated_core_extensions.rb +135 -0
  104. data/lib/sequel/extensions/columns_introspection.rb +1 -5
  105. data/lib/sequel/extensions/core_extensions.rb +10 -3
  106. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  107. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
  108. data/lib/sequel/extensions/filter_having.rb +58 -0
  109. data/lib/sequel/extensions/graph_each.rb +63 -0
  110. data/lib/sequel/extensions/hash_aliases.rb +44 -0
  111. data/lib/sequel/extensions/looser_typecasting.rb +14 -3
  112. data/lib/sequel/extensions/migration.rb +2 -3
  113. data/lib/sequel/extensions/named_timezones.rb +14 -1
  114. data/lib/sequel/extensions/null_dataset.rb +7 -1
  115. data/lib/sequel/extensions/pagination.rb +15 -5
  116. data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
  117. data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
  118. data/lib/sequel/extensions/pg_json.rb +7 -7
  119. data/lib/sequel/extensions/pg_range_ops.rb +8 -2
  120. data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
  121. data/lib/sequel/extensions/pretty_table.rb +13 -4
  122. data/lib/sequel/extensions/query.rb +21 -4
  123. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
  124. data/lib/sequel/extensions/schema_caching.rb +10 -7
  125. data/lib/sequel/extensions/schema_dumper.rb +35 -48
  126. data/lib/sequel/extensions/select_remove.rb +13 -4
  127. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
  128. data/lib/sequel/extensions/set_overrides.rb +43 -0
  129. data/lib/sequel/extensions/to_dot.rb +6 -0
  130. data/lib/sequel/model.rb +12 -6
  131. data/lib/sequel/model/associations.rb +80 -38
  132. data/lib/sequel/model/base.rb +137 -52
  133. data/lib/sequel/model/errors.rb +7 -2
  134. data/lib/sequel/plugins/active_model.rb +13 -0
  135. data/lib/sequel/plugins/after_initialize.rb +43 -0
  136. data/lib/sequel/plugins/association_proxies.rb +63 -7
  137. data/lib/sequel/plugins/auto_validations.rb +56 -16
  138. data/lib/sequel/plugins/blacklist_security.rb +63 -0
  139. data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
  140. data/lib/sequel/plugins/constraint_validations.rb +50 -8
  141. data/lib/sequel/plugins/dataset_associations.rb +2 -0
  142. data/lib/sequel/plugins/hook_class_methods.rb +7 -1
  143. data/lib/sequel/plugins/identity_map.rb +4 -0
  144. data/lib/sequel/plugins/json_serializer.rb +32 -13
  145. data/lib/sequel/plugins/optimistic_locking.rb +1 -1
  146. data/lib/sequel/plugins/rcte_tree.rb +4 -4
  147. data/lib/sequel/plugins/scissors.rb +33 -0
  148. data/lib/sequel/plugins/serialization.rb +1 -1
  149. data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
  150. data/lib/sequel/plugins/tree.rb +5 -1
  151. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  152. data/lib/sequel/plugins/validation_helpers.rb +15 -11
  153. data/lib/sequel/plugins/xml_serializer.rb +12 -3
  154. data/lib/sequel/sql.rb +12 -2
  155. data/lib/sequel/timezones.rb +1 -1
  156. data/lib/sequel/version.rb +1 -1
  157. data/lib/sequel_core.rb +1 -0
  158. data/lib/sequel_model.rb +1 -0
  159. data/spec/adapters/mssql_spec.rb +24 -57
  160. data/spec/adapters/postgres_spec.rb +27 -55
  161. data/spec/adapters/spec_helper.rb +1 -1
  162. data/spec/adapters/sqlite_spec.rb +1 -1
  163. data/spec/bin_spec.rb +251 -0
  164. data/spec/core/database_spec.rb +46 -32
  165. data/spec/core/dataset_spec.rb +233 -181
  166. data/spec/core/deprecated_spec.rb +78 -0
  167. data/spec/core/expression_filters_spec.rb +3 -4
  168. data/spec/core/mock_adapter_spec.rb +9 -9
  169. data/spec/core/object_graph_spec.rb +9 -19
  170. data/spec/core/schema_spec.rb +3 -1
  171. data/spec/core/spec_helper.rb +19 -0
  172. data/spec/core_extensions_spec.rb +80 -30
  173. data/spec/extensions/after_initialize_spec.rb +24 -0
  174. data/spec/extensions/association_proxies_spec.rb +37 -1
  175. data/spec/extensions/auto_validations_spec.rb +20 -4
  176. data/spec/extensions/blacklist_security_spec.rb +87 -0
  177. data/spec/extensions/boolean_readers_spec.rb +2 -1
  178. data/spec/extensions/class_table_inheritance_spec.rb +7 -0
  179. data/spec/extensions/columns_introspection_spec.rb +3 -3
  180. data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
  181. data/spec/extensions/core_refinements_spec.rb +7 -7
  182. data/spec/extensions/dataset_associations_spec.rb +2 -2
  183. data/spec/extensions/date_arithmetic_spec.rb +1 -1
  184. data/spec/extensions/defaults_setter_spec.rb +2 -1
  185. data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
  186. data/spec/extensions/filter_having_spec.rb +40 -0
  187. data/spec/extensions/graph_each_spec.rb +109 -0
  188. data/spec/extensions/hash_aliases_spec.rb +16 -0
  189. data/spec/extensions/hook_class_methods_spec.rb +2 -2
  190. data/spec/extensions/identity_map_spec.rb +3 -3
  191. data/spec/extensions/json_serializer_spec.rb +19 -19
  192. data/spec/extensions/lazy_attributes_spec.rb +1 -0
  193. data/spec/extensions/list_spec.rb +13 -13
  194. data/spec/extensions/looser_typecasting_spec.rb +10 -3
  195. data/spec/extensions/many_through_many_spec.rb +1 -1
  196. data/spec/extensions/migration_spec.rb +7 -7
  197. data/spec/extensions/named_timezones_spec.rb +6 -0
  198. data/spec/extensions/nested_attributes_spec.rb +2 -2
  199. data/spec/extensions/null_dataset_spec.rb +1 -1
  200. data/spec/extensions/pagination_spec.rb +2 -2
  201. data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
  202. data/spec/extensions/pg_range_ops_spec.rb +4 -2
  203. data/spec/extensions/pg_row_plugin_spec.rb +1 -1
  204. data/spec/extensions/pretty_table_spec.rb +1 -1
  205. data/spec/extensions/query_literals_spec.rb +1 -1
  206. data/spec/extensions/query_spec.rb +3 -3
  207. data/spec/extensions/schema_caching_spec.rb +3 -3
  208. data/spec/extensions/schema_dumper_spec.rb +27 -2
  209. data/spec/extensions/schema_spec.rb +2 -2
  210. data/spec/extensions/scissors_spec.rb +26 -0
  211. data/spec/extensions/select_remove_spec.rb +1 -1
  212. data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
  213. data/spec/extensions/set_overrides_spec.rb +45 -0
  214. data/spec/extensions/single_table_inheritance_spec.rb +10 -0
  215. data/spec/extensions/spec_helper.rb +24 -1
  216. data/spec/extensions/static_cache_spec.rb +1 -1
  217. data/spec/extensions/string_stripper_spec.rb +2 -1
  218. data/spec/extensions/to_dot_spec.rb +1 -1
  219. data/spec/extensions/typecast_on_load_spec.rb +3 -2
  220. data/spec/extensions/update_primary_key_spec.rb +2 -2
  221. data/spec/extensions/validation_class_methods_spec.rb +19 -19
  222. data/spec/extensions/validation_helpers_spec.rb +30 -21
  223. data/spec/extensions/xml_serializer_spec.rb +5 -5
  224. data/spec/integration/associations_test.rb +10 -30
  225. data/spec/integration/dataset_test.rb +20 -24
  226. data/spec/integration/eager_loader_test.rb +5 -5
  227. data/spec/integration/model_test.rb +3 -3
  228. data/spec/integration/plugin_test.rb +7 -39
  229. data/spec/integration/schema_test.rb +4 -38
  230. data/spec/integration/spec_helper.rb +2 -1
  231. data/spec/model/association_reflection_spec.rb +70 -5
  232. data/spec/model/associations_spec.rb +11 -11
  233. data/spec/model/base_spec.rb +25 -8
  234. data/spec/model/class_dataset_methods_spec.rb +143 -0
  235. data/spec/model/dataset_methods_spec.rb +1 -1
  236. data/spec/model/eager_loading_spec.rb +25 -25
  237. data/spec/model/hooks_spec.rb +1 -1
  238. data/spec/model/model_spec.rb +22 -7
  239. data/spec/model/plugins_spec.rb +1 -6
  240. data/spec/model/record_spec.rb +37 -29
  241. data/spec/model/spec_helper.rb +23 -1
  242. data/spec/model/validations_spec.rb +15 -17
  243. metadata +32 -3
@@ -462,7 +462,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
462
462
  @c.allowed_columns.should == [:x, :y]
463
463
  end
464
464
 
465
- it "should set the restricted columns correctly" do
465
+ qspecify "should set the restricted columns correctly" do
466
466
  @c.restricted_columns.should == nil
467
467
  @c.set_restricted_columns :x
468
468
  @c.restricted_columns.should == [:x]
@@ -484,7 +484,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
484
484
  MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
485
485
  end
486
486
 
487
- it "should not set restricted columns by default" do
487
+ qspecify "should not set restricted columns by default" do
488
488
  @c.set_restricted_columns :z
489
489
  i = @c.new(:x => 1, :y => 2, :z => 3)
490
490
  i.values.should == {:x => 1, :y => 2}
@@ -498,7 +498,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
498
498
  MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
499
499
  end
500
500
 
501
- it "should have allowed take precedence over restricted" do
501
+ qspecify "should have allowed take precedence over restricted" do
502
502
  @c.set_allowed_columns :x, :y
503
503
  @c.set_restricted_columns :y, :z
504
504
  i = @c.new(:x => 1, :y => 2, :z => 3)
@@ -556,7 +556,7 @@ describe Sequel::Model, ".strict_param_setting" do
556
556
  before do
557
557
  @c = Class.new(Sequel::Model(:blahblah)) do
558
558
  columns :x, :y, :z, :id
559
- set_restricted_columns :z
559
+ set_allowed_columns :x, :y
560
560
  end
561
561
  end
562
562
 
@@ -571,10 +571,14 @@ describe Sequel::Model, ".strict_param_setting" do
571
571
  proc{c.set(:z=>1)}.should raise_error(Sequel::Error)
572
572
  proc{c.set_all(:id=>1)}.should raise_error(Sequel::Error)
573
573
  proc{c.set_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
574
- proc{c.set_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
575
574
  proc{c.update(:z=>1)}.should raise_error(Sequel::Error)
576
575
  proc{c.update_all(:id=>1)}.should raise_error(Sequel::Error)
577
576
  proc{c.update_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
577
+ end
578
+
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)
578
582
  proc{c.update_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
579
583
  end
580
584
 
@@ -631,8 +635,6 @@ describe Sequel::Model, ".[] optimization" do
631
635
  it "should have simple_pk be blank if compound or no primary key" do
632
636
  @c.no_primary_key
633
637
  @c.simple_pk.should == nil
634
- @c.set_primary_key :b, :a
635
- @c.simple_pk.should == nil
636
638
  @c.set_primary_key [:b, :a]
637
639
  @c.simple_pk.should == nil
638
640
  end
@@ -701,6 +703,13 @@ describe "Model datasets #with_pk with #with_pk!" do
701
703
  MODEL_DB.reset
702
704
  end
703
705
 
706
+ it "should be callable on the model class with optimized SQL" do
707
+ @c.with_pk(1).should == @c.load(:id=>1)
708
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
709
+ @c.with_pk!(1).should == @c.load(:id=>1)
710
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
711
+ end
712
+
704
713
  it "should return the first record where the primary key matches" do
705
714
  @ds.with_pk(1).should == @c.load(:id=>1)
706
715
  MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
@@ -723,7 +732,7 @@ describe "Model datasets #with_pk with #with_pk!" do
723
732
  end
724
733
 
725
734
  it "should handle an array for composite primary keys" do
726
- @c.set_primary_key :id1, :id2
735
+ @c.set_primary_key [:id1, :id2]
727
736
  @ds.with_pk([1, 2])
728
737
  sqls = MODEL_DB.sqls
729
738
  ["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
@@ -745,6 +754,14 @@ describe "Model datasets #with_pk with #with_pk!" do
745
754
  MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
746
755
  end
747
756
 
757
+ it "should have with_pk return nil and with_pk! raise if no rows match when calling the class method" do
758
+ @ds._fetch = []
759
+ @c.with_pk(1).should == nil
760
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
761
+ proc{@c.with_pk!(1)}.should raise_error(Sequel::NoMatchingRow)
762
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
763
+ end
764
+
748
765
  it "should have #[] consider an integer as a primary key lookup" do
749
766
  @ds[1].should == @c.load(:id=>1)
750
767
  MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
@@ -0,0 +1,143 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe Sequel::Model, "class dataset methods" do
4
+ before do
5
+ @db = Sequel.mock
6
+ @c = Class.new(Sequel::Model(@db[:items]))
7
+ @d = @c.dataset
8
+ @d._fetch = {:id=>1}
9
+ @d.autoid = 1
10
+ @d.numrows = 0
11
+ @db.sqls
12
+ end
13
+
14
+ it "should call the dataset method of the same name with the same args" do
15
+ @c.<<({}).should == @d
16
+ @db.sqls.should == ["INSERT INTO items DEFAULT VALUES"]
17
+ @c.all.should == [@c.load(:id=>1)]
18
+ @db.sqls.should == ["SELECT * FROM items"]
19
+ @c.avg(:id).should == 1
20
+ @db.sqls.should == ["SELECT avg(id) AS avg FROM items LIMIT 1"]
21
+ @c.count.should == 1
22
+ @db.sqls.should == ["SELECT count(*) AS count FROM items LIMIT 1"]
23
+ @c.cross_join(@c).sql.should == "SELECT * FROM items CROSS JOIN items"
24
+ @c.distinct.sql.should == "SELECT DISTINCT * FROM items"
25
+ @c.each{|r| r.should == @c.load(:id=>1)}.should == @d
26
+ @db.sqls.should == ["SELECT * FROM items"]
27
+ @c.each_server{|r| r.opts[:server].should == :default}
28
+ @c.empty?.should be_false
29
+ @db.sqls.should == ["SELECT 1 AS one FROM items LIMIT 1"]
30
+ @c.except(@d, :from_self=>false).sql.should == "SELECT * FROM items EXCEPT SELECT * FROM items"
31
+ @c.exclude(:a).sql.should == "SELECT * FROM items WHERE NOT a"
32
+ @c.exclude_having(:a).sql.should == "SELECT * FROM items HAVING NOT a"
33
+ @c.exclude_where(:a).sql.should == "SELECT * FROM items WHERE NOT a"
34
+ @c.fetch_rows("S"){|r| r.should == {:id=>1}}
35
+ @db.sqls.should == ["S"]
36
+ @c.filter(:a).sql.should == "SELECT * FROM items WHERE a"
37
+ @c.first.should == @c.load(:id=>1)
38
+ @db.sqls.should == ["SELECT * FROM items LIMIT 1"]
39
+ @c.first!.should == @c.load(:id=>1)
40
+ @db.sqls.should == ["SELECT * FROM items LIMIT 1"]
41
+ @c.for_update.sql.should == "SELECT * FROM items FOR UPDATE"
42
+ @c.from.sql.should == "SELECT *"
43
+ @c.from_self.sql.should == "SELECT * FROM (SELECT * FROM items) AS t1"
44
+ @c.full_join(@c).sql.should == "SELECT * FROM items FULL JOIN items"
45
+ @c.full_outer_join(@c).sql.should == "SELECT * FROM items FULL OUTER JOIN items"
46
+ @c.get(:a).should == 1
47
+ @db.sqls.should == ["SELECT a FROM items LIMIT 1"]
48
+ @c.graph(@c, nil, :table_alias=>:a).sql.should == "SELECT * FROM items LEFT OUTER JOIN items AS a"
49
+ @db.sqls
50
+ @c.grep(:id, 'a%').sql.should == "SELECT * FROM items WHERE ((id LIKE 'a%' ESCAPE '\\'))"
51
+ @c.group(:a).sql.should == "SELECT * FROM items GROUP BY a"
52
+ @c.group_and_count(:a).sql.should == "SELECT a, count(*) AS count FROM items GROUP BY a"
53
+ @c.group_by(:a).sql.should == "SELECT * FROM items GROUP BY a"
54
+ @c.having(:a).sql.should == "SELECT * FROM items HAVING a"
55
+ @c.import([:id], [[1]])
56
+ @db.sqls.should == ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
57
+ @c.inner_join(@c).sql.should == "SELECT * FROM items INNER JOIN items"
58
+ @c.insert.should == 2
59
+ @db.sqls.should == ["INSERT INTO items DEFAULT VALUES"]
60
+ @c.intersect(@d, :from_self=>false).sql.should == "SELECT * FROM items INTERSECT SELECT * FROM items"
61
+ @c.interval(:id).should == 1
62
+ @db.sqls.should == ["SELECT (max(id) - min(id)) AS interval FROM items LIMIT 1"]
63
+ @c.join(@c).sql.should == "SELECT * FROM items INNER JOIN items"
64
+ @c.join_table(:inner, @c).sql.should == "SELECT * FROM items INNER JOIN items"
65
+ @c.last.should == @c.load(:id=>1)
66
+ @db.sqls.should == ["SELECT * FROM items ORDER BY id DESC LIMIT 1"]
67
+ @c.left_join(@c).sql.should == "SELECT * FROM items LEFT JOIN items"
68
+ @c.left_outer_join(@c).sql.should == "SELECT * FROM items LEFT OUTER JOIN items"
69
+ @c.limit(2).sql.should == "SELECT * FROM items LIMIT 2"
70
+ @c.lock_style(:update).sql.should == "SELECT * FROM items FOR UPDATE"
71
+ @c.map(:id).should == [1]
72
+ @db.sqls.should == ["SELECT * FROM items"]
73
+ @c.max(:id).should == 1
74
+ @db.sqls.should == ["SELECT max(id) AS max FROM items LIMIT 1"]
75
+ @c.min(:id).should == 1
76
+ @db.sqls.should == ["SELECT min(id) AS min FROM items LIMIT 1"]
77
+ @c.multi_insert([{:id=>1}])
78
+ @db.sqls.should == ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
79
+ @c.naked.row_proc.should == nil
80
+ @c.natural_full_join(@c).sql.should == "SELECT * FROM items NATURAL FULL JOIN items"
81
+ @c.natural_join(@c).sql.should == "SELECT * FROM items NATURAL JOIN items"
82
+ @c.natural_left_join(@c).sql.should == "SELECT * FROM items NATURAL LEFT JOIN items"
83
+ @c.natural_right_join(@c).sql.should == "SELECT * FROM items NATURAL RIGHT JOIN items"
84
+ @c.order(:a).sql.should == "SELECT * FROM items ORDER BY a"
85
+ @c.order_append(:a).sql.should == "SELECT * FROM items ORDER BY a"
86
+ @c.order_by(:a).sql.should == "SELECT * FROM items ORDER BY a"
87
+ @c.order_more(:a).sql.should == "SELECT * FROM items ORDER BY a"
88
+ @c.order_prepend(:a).sql.should == "SELECT * FROM items ORDER BY a"
89
+ @c.paged_each{|r| r.should == @c.load(:id=>1)}
90
+ @db.sqls.should == ["BEGIN", "SELECT * FROM items ORDER BY id LIMIT 1000 OFFSET 0", "COMMIT"]
91
+ @c.qualify.sql.should == 'SELECT items.* FROM items'
92
+ @c.right_join(@c).sql.should == "SELECT * FROM items RIGHT JOIN items"
93
+ @c.right_outer_join(@c).sql.should == "SELECT * FROM items RIGHT OUTER JOIN items"
94
+ @c.select(:a).sql.should == "SELECT a FROM items"
95
+ @c.select_all(:items).sql.should == "SELECT items.* FROM items"
96
+ @c.select_append(:a).sql.should == "SELECT *, a FROM items"
97
+ @c.select_group(:a).sql.should == "SELECT a FROM items GROUP BY a"
98
+ @c.select_hash(:id, :id).should == {1=>1}
99
+ @db.sqls.should == ["SELECT id, id FROM items"]
100
+ @c.select_hash_groups(:id, :id).should == {1=>[1]}
101
+ @db.sqls.should == ["SELECT id, id FROM items"]
102
+ @c.select_map(:id).should == [1]
103
+ @db.sqls.should == ["SELECT id FROM items"]
104
+ @c.select_order_map(:id).should == [1]
105
+ @db.sqls.should == ["SELECT id FROM items ORDER BY id"]
106
+ @c.server(:a).opts[:server].should == :a
107
+ @c.set_graph_aliases(:a=>:b).opts[:graph_aliases].should == {:a=>[:b, :a]}
108
+ @c.single_record.should == @c.load(:id=>1)
109
+ @db.sqls.should == ["SELECT * FROM items LIMIT 1"]
110
+ @c.single_value.should == 1
111
+ @db.sqls.should == ["SELECT * FROM items LIMIT 1"]
112
+ @c.sum(:id).should == 1
113
+ @db.sqls.should == ["SELECT sum(id) AS sum FROM items LIMIT 1"]
114
+ @c.to_hash(:id, :id).should == {1=>1}
115
+ @db.sqls.should == ["SELECT * FROM items"]
116
+ @c.to_hash_groups(:id, :id).should == {1=>[1]}
117
+ @db.sqls.should == ["SELECT * FROM items"]
118
+ @c.truncate
119
+ @db.sqls.should == ["TRUNCATE TABLE items"]
120
+ @c.union(@d, :from_self=>false).sql.should == "SELECT * FROM items UNION SELECT * FROM items"
121
+ @c.where(:a).sql.should == "SELECT * FROM items WHERE a"
122
+ @c.with(:a, @d).sql.should == "WITH a AS (SELECT * FROM items) SELECT * FROM items"
123
+ @c.with_recursive(:a, @d, @d).sql.should == "WITH a AS (SELECT * FROM items UNION ALL SELECT * FROM items) SELECT * FROM items"
124
+ @c.with_sql('S').sql.should == "S"
125
+
126
+ sc = Class.new(@c)
127
+ sc.set_dataset(@d.where(:a).order(:a).select(:a).group(:a).limit(2))
128
+ @db.sqls
129
+ sc.invert.sql.should == 'SELECT a FROM items WHERE NOT a GROUP BY a ORDER BY a LIMIT 2'
130
+ sc.dataset._fetch = {:v1=>1, :v2=>2}
131
+ sc.range(:a).should == (1..2)
132
+ @db.sqls.should == ["SELECT min(a) AS v1, max(a) AS v2 FROM (SELECT a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2) AS t1 LIMIT 1"]
133
+ sc.reverse.sql.should == 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
134
+ sc.reverse_order.sql.should == 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
135
+ sc.select_more(:a).sql.should == 'SELECT a, a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2'
136
+ sc.unfiltered.sql.should == 'SELECT a FROM items GROUP BY a ORDER BY a LIMIT 2'
137
+ sc.ungrouped.sql.should == 'SELECT a FROM items WHERE a ORDER BY a LIMIT 2'
138
+ sc.unordered.sql.should == 'SELECT a FROM items WHERE a GROUP BY a LIMIT 2'
139
+ sc.unlimited.sql.should == 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a'
140
+ sc.dataset.graph!(:a)
141
+ sc.dataset.ungraphed.opts[:graph].should == nil
142
+ end
143
+ end
@@ -92,7 +92,7 @@ describe Sequel::Model::DatasetMethods do
92
92
  end
93
93
 
94
94
  specify "#insert_sql should handle a single model instance as an argument" do
95
- @c.insert_sql(@c.load(:id=>1)).should == 'INSERT INTO items (id) VALUES (1)'
95
+ @c.dataset.insert_sql(@c.load(:id=>1)).should == 'INSERT INTO items (id) VALUES (1)'
96
96
  end
97
97
 
98
98
  specify "#first should handle no primary key" do
@@ -7,7 +7,7 @@ describe Sequel::Model, "#eager" do
7
7
  many_to_one :band, :class=>'EagerBand', :key=>:band_id
8
8
  one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id
9
9
  many_to_many :genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag
10
- one_to_many :good_tracks, :class=>'EagerTrack', :key=>:album_id do |ds|
10
+ one_to_many :good_tracks, :class=>'EagerTrack', :reciprocal=>nil, :key=>:album_id do |ds|
11
11
  ds.filter(:name=>'Good')
12
12
  end
13
13
  many_to_one :band_name, :class=>'EagerBand', :key=>:band_id, :select=>[:id, :name]
@@ -21,11 +21,11 @@ describe Sequel::Model, "#eager" do
21
21
 
22
22
  class ::EagerBand < Sequel::Model(:bands)
23
23
  columns :id, :p_k
24
- one_to_many :albums, :class=>'EagerAlbum', :key=>:band_id, :eager=>:tracks
25
- one_to_many :graph_albums, :class=>'EagerAlbum', :key=>:band_id, :eager_graph=>:tracks
24
+ one_to_many :albums, :class=>'EagerAlbum', :key=>:band_id, :eager=>:tracks, :reciprocal=>:band
25
+ one_to_many :graph_albums, :class=>'EagerAlbum', :key=>:band_id, :eager_graph=>:tracks, :reciprocal=>nil
26
26
  many_to_many :members, :class=>'EagerBandMember', :left_key=>:band_id, :right_key=>:member_id, :join_table=>:bm
27
27
  many_to_many :graph_members, :clone=>:members, :eager_graph=>:bands
28
- one_to_many :good_albums, :class=>'EagerAlbum', :key=>:band_id, :eager_block=>proc{|ds| ds.filter(:name=>'good')} do |ds|
28
+ one_to_many :good_albums, :class=>'EagerAlbum', :key=>:band_id, :reciprocal=>nil, :eager_block=>proc{|ds| ds.filter(:name=>'good')} do |ds|
29
29
  ds.filter(:name=>'Good')
30
30
  end
31
31
  one_to_many :self_titled_albums, :class=>'EagerAlbum', :key=>:band_id, :allow_eager=>false do |ds|
@@ -169,7 +169,7 @@ describe Sequel::Model, "#eager" do
169
169
  MODEL_DB.sqls.should == []
170
170
  end
171
171
 
172
- it "should eagerly load a single one_to_one association using the :correlated_subquery strategy" do
172
+ qspecify "should eagerly load a single one_to_one association using the :correlated_subquery strategy" do
173
173
  EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name
174
174
  a = EagerAlbum.eager(:track).all
175
175
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -178,7 +178,7 @@ describe Sequel::Model, "#eager" do
178
178
  MODEL_DB.sqls.should == []
179
179
  end
180
180
 
181
- it "should handle qualified order clauses when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
181
+ qspecify "should handle qualified order clauses when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
182
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]
183
183
  a = EagerAlbum.eager(:track).all
184
184
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -187,7 +187,7 @@ describe Sequel::Model, "#eager" do
187
187
  MODEL_DB.sqls.should == []
188
188
  end
189
189
 
190
- it "should handle qualified composite keys when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
190
+ qspecify "should handle qualified composite keys when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
191
191
  c1 = Class.new(EagerAlbum)
192
192
  c2 = Class.new(EagerTrack)
193
193
  c1.set_primary_key [:id, :band_id]
@@ -228,7 +228,7 @@ describe Sequel::Model, "#eager" do
228
228
  end
229
229
 
230
230
  it "should support using a custom :primary_key option when eager loading one_to_many associations" do
231
- EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil
231
+ EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil, :reciprocal=>nil
232
232
  EagerBand.dataset._fetch = {:id=>6}
233
233
  a = EagerBand.eager(:salbums).all
234
234
  MODEL_DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE (albums.band_id IN (2))']
@@ -258,7 +258,7 @@ describe Sequel::Model, "#eager" do
258
258
  end
259
259
 
260
260
  it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_to_many associations" do
261
- EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil
261
+ 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
262
  EagerBand.dataset._fetch = {:id=>6}
263
263
  a = EagerBand.eager(:salbums).all
264
264
  MODEL_DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
@@ -501,7 +501,7 @@ describe Sequel::Model, "#eager" do
501
501
  as.length.should == 1
502
502
  as.first.special_band.should == EagerBand.load(:p_k=>2, :id=>1)
503
503
 
504
- EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id
504
+ EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id, :reciprocal=>nil
505
505
  EagerTrack.dataset._fetch = {:album_id=>2, :id=>1}
506
506
  as = EagerAlbum.eager(:special_tracks).all
507
507
  MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
@@ -581,7 +581,7 @@ describe Sequel::Model, "#eager" do
581
581
  MODEL_DB.sqls.should == []
582
582
  end
583
583
 
584
- it "should respect the :limit option on a one_to_many association using the :correlated_subquery strategy" do
584
+ qspecify "should respect the :limit option on a one_to_many association using the :correlated_subquery strategy" do
585
585
  EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name, :limit=>2
586
586
  a = EagerAlbum.eager(:tracks).all
587
587
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -590,7 +590,7 @@ describe Sequel::Model, "#eager" do
590
590
  MODEL_DB.sqls.should == []
591
591
  end
592
592
 
593
- it "should respect the :limit option with an offset on a one_to_many association using the :correlated_subquery strategy" do
593
+ qspecify "should respect the :limit option with an offset on a one_to_many association using the :correlated_subquery strategy" do
594
594
  EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name, :limit=>[2, 1]
595
595
  a = EagerAlbum.eager(:tracks).all
596
596
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -632,7 +632,7 @@ describe Sequel::Model, "#eager" do
632
632
  as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
633
633
  end
634
634
 
635
- it "should respect the limit option on a many_to_many association using the :correlated_subquery strategy" do
635
+ qspecify "should respect the limit option on a many_to_many association using the :correlated_subquery strategy" do
636
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
637
  EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
638
638
  as = EagerAlbum.eager(:first_two_genres).all
@@ -649,17 +649,17 @@ describe Sequel::Model, "#eager" do
649
649
  end
650
650
 
651
651
  it "should use the :eager_loader association option when eager loading" do
652
- EagerAlbum.many_to_one :special_band, :key=>:band_id, :eager_loader=>(proc do |key_hash, records, assocs|
653
- item = EagerBand.filter(:album_id=>records.collect{|r| [r.pk, r.pk*2]}.flatten).order(:name).first
654
- records.each{|r| r.associations[:special_band] = item}
652
+ EagerAlbum.many_to_one :special_band, :key=>:band_id, :eager_loader=>(proc do |eo|
653
+ item = EagerBand.filter(:album_id=>eo[:rows].collect{|r| [r.pk, r.pk*2]}.flatten).order(:name).first
654
+ eo[:rows].each{|r| r.associations[:special_band] = item}
655
655
  end)
656
656
  EagerAlbum.one_to_many :special_tracks, :eager_loader=>(proc do |eo|
657
657
  items = EagerTrack.filter(:album_id=>eo[:rows].collect{|r| [r.pk, r.pk*2]}.flatten).all
658
658
  eo[:rows].each{|r| r.associations[:special_tracks] = items}
659
659
  end)
660
- EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :eager_loader=>(proc do |key_hash, records, assocs|
661
- items = EagerGenre.inner_join(:ag, [:genre_id]).filter(:album_id=>records.collect{|r| r.pk}).all
662
- records.each{|r| r.associations[:special_genres] = items}
660
+ EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :eager_loader=>(proc do |eo|
661
+ items = EagerGenre.inner_join(:ag, [:genre_id]).filter(:album_id=>eo[:rows].collect{|r| r.pk}).all
662
+ eo[:rows].each{|r| r.associations[:special_genres] = items}
663
663
  end)
664
664
  a = EagerAlbum.eager(:special_genres, :special_tracks, :special_band).all
665
665
  a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
@@ -1166,7 +1166,7 @@ describe Sequel::Model, "#eager_graph" do
1166
1166
  as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
1167
1167
  as.first.inner_band.should == GraphBand.load(:id=>5, :vocalist_id=>2)
1168
1168
 
1169
- GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :primary_key=>:band_id
1169
+ GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :primary_key=>:band_id, :reciprocal=>nil
1170
1170
  ds = GraphAlbum.eager_graph(:right_tracks)
1171
1171
  ds.sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.band_id)'
1172
1172
  ds._fetch = [{:id=>3, :band_id=>2, :right_tracks_id=>5, :album_id=>2}, {:id=>3, :band_id=>2, :right_tracks_id=>6, :album_id=>2}]
@@ -1276,7 +1276,7 @@ describe Sequel::Model, "#eager_graph" do
1276
1276
  GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :conditions=>{:active=>true}
1277
1277
  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.id = albums.band_id) AND (active_band.active IS TRUE))"
1278
1278
 
1279
- GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :conditions=>{:id=>(0..100)}
1279
+ GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :conditions=>{:id=>(0..100)}, :reciprocal=>nil
1280
1280
  GraphAlbum.eager_graph(:right_tracks).sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.id) AND (right_tracks.id >= 0) AND (right_tracks.id <= 100))'
1281
1281
 
1282
1282
  GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :conditions=>{true=>:active}
@@ -1322,13 +1322,13 @@ describe Sequel::Model, "#eager_graph" do
1322
1322
  end
1323
1323
 
1324
1324
  it "should respect the association's :eager_grapher option" do
1325
- GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :eager_grapher=>proc{|ds, aa, ta| ds.graph(GraphBand, {:active=>true}, :table_alias=>aa, :join_type=>:inner)}
1325
+ GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphBand, {:active=>true}, :table_alias=>eo[:table_alias], :join_type=>:inner)}
1326
1326
  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 INNER JOIN bands AS active_band ON (active_band.active IS TRUE)"
1327
1327
 
1328
1328
  GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphTrack, nil, :join_type=>:natural, :table_alias=>eo[:table_alias])}
1329
1329
  GraphAlbum.eager_graph(:right_tracks).sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums NATURAL JOIN tracks AS right_tracks'
1330
1330
 
1331
- GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :eager_grapher=>proc{|ds, aa, ta| ds.graph(:ag, {:album_id=>:id}, :table_alias=>:a123, :implicit_qualifier=>ta).graph(GraphGenre, [:album_id], :table_alias=>aa)}
1331
+ GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :eager_grapher=>proc{|eo| eo[:self].graph(:ag, {:album_id=>:id}, :table_alias=>:a123, :implicit_qualifier=>eo[:implicit_qualifier]).graph(GraphGenre, [:album_id], :table_alias=>eo[:table_alias])}
1332
1332
  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
1333
  end
1334
1334
 
@@ -1380,7 +1380,7 @@ describe Sequel::Model, "#eager_graph" do
1380
1380
  end
1381
1381
 
1382
1382
  it "should add the association's :order for cascading associations" do
1383
- GraphBand.one_to_many :a_albums, :class=>'GraphAlbum', :key=>:band_id, :order=>:name
1383
+ GraphBand.one_to_many :a_albums, :class=>'GraphAlbum', :key=>:band_id, :order=>:name, :reciprocal=>nil
1384
1384
  GraphAlbum.one_to_many :b_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:id, :album_id]
1385
1385
  GraphBand.eager_graph(:a_albums=>:b_tracks).sql.should == 'SELECT bands.id, bands.vocalist_id, a_albums.id AS a_albums_id, a_albums.band_id, b_tracks.id AS b_tracks_id, b_tracks.album_id FROM bands LEFT OUTER JOIN albums AS a_albums ON (a_albums.band_id = bands.id) LEFT OUTER JOIN tracks AS b_tracks ON (b_tracks.album_id = a_albums.id) ORDER BY a_albums.name, b_tracks.id, b_tracks.album_id'
1386
1386
  GraphAlbum.one_to_many :albums, :class=>'GraphAlbum', :key=>:band_id, :order=>[:band_id, :id]
@@ -1417,7 +1417,7 @@ describe Sequel::Model, "#eager_graph" do
1417
1417
  GraphAlbum.eager_graph(:band).join(:s__genres, [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
1418
1418
  GraphAlbum.eager_graph(:band).join(Sequel.qualify(:s, :genres), [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
1419
1419
  GraphAlbum.eager_graph(:band).join(Sequel.expr(:s__b).as('genres'), [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
1420
- GraphAlbum.eager_graph(:band).join(:s__b, [:b_id], Sequel.identifier(:genres)).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
1420
+ GraphAlbum.eager_graph(:band).join(:s__b, [:b_id], :table_alias=>Sequel.identifier(:genres)).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
1421
1421
  GraphAlbum.eager_graph(:band).join(Sequel.identifier(:genres), [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
1422
1422
  GraphAlbum.eager_graph(:band).join('genres', [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
1423
1423
  end
@@ -1,7 +1,7 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Model#after_initialize" do
4
- specify "should be called after initialization for both new object and objects retrieved from the database" do
4
+ qspecify "should be called after initialization for both new object and objects retrieved from the database" do
5
5
 
6
6
  a = Class.new(Sequel::Model) do
7
7
  self::Foo = []
@@ -55,7 +55,7 @@ describe "Sequel::Model()" do
55
55
  end
56
56
 
57
57
  it "should return a model subclass associated to the given database if given a database" do
58
- db = Sequel::Database.new
58
+ db = Sequel.mock
59
59
  c = Sequel::Model(db)
60
60
  c.superclass.should == Sequel::Model
61
61
  c.db.should == db
@@ -68,10 +68,10 @@ describe "Sequel::Model()" do
68
68
 
69
69
  describe "reloading" do
70
70
  before do
71
- Sequel::Model.cache_anonymous_models = true
71
+ Sequel.cache_anonymous_models = true
72
72
  end
73
73
  after do
74
- Sequel::Model.cache_anonymous_models = false
74
+ Sequel.cache_anonymous_models = false
75
75
  Object.send(:remove_const, :Album) if defined?(::Album)
76
76
  end
77
77
 
@@ -132,7 +132,7 @@ describe "Sequel::Model()" do
132
132
  end
133
133
 
134
134
  it "should raise an exception if anonymous model caching is disabled" do
135
- Sequel::Model.cache_anonymous_models = false
135
+ Sequel.cache_anonymous_models = false
136
136
  proc do
137
137
  class ::Album < Sequel::Model(@db[Sequel.identifier(:table)]); end
138
138
  class ::Album < Sequel::Model(@db[Sequel.identifier(:table)]); end
@@ -308,7 +308,7 @@ describe Sequel::Model, "constructors" do
308
308
  end
309
309
 
310
310
  it "should have dataset row_proc create an existing object" do
311
- @m.dataset = Sequel::Dataset.new(nil)
311
+ @m.dataset = Sequel.mock.dataset
312
312
  o = @m.dataset.row_proc.call(:a=>1)
313
313
  o.should be_a_kind_of(@m)
314
314
  o.values.should == {:a=>1}
@@ -329,7 +329,7 @@ describe Sequel::Model, "constructors" do
329
329
  o.new?.should be_false
330
330
  end
331
331
 
332
- it "should have .new with a second true argument create an existing object" do
332
+ qspecify "should have .new with a second true argument create an existing object" do
333
333
  o = @m.new({:a=>1}, true)
334
334
  o.should be_a_kind_of(@m)
335
335
  o.values.should == {:a=>1}
@@ -520,6 +520,7 @@ end
520
520
  describe Sequel::Model, "attribute accessors" do
521
521
  before do
522
522
  db = Sequel.mock
523
+ def db.supports_schema_parsing?() true end
523
524
  def db.schema(*)
524
525
  [[:x, {:type=>:integer}], [:z, {:type=>:integer}]]
525
526
  end
@@ -616,7 +617,7 @@ describe Sequel::Model, ".[]" do
616
617
  sqls.first.should =~ /^SELECT \* FROM items WHERE \((\(node_id = 3921\) AND \(kind = 201\))|(\(kind = 201\) AND \(node_id = 3921\))\) LIMIT 1$/
617
618
  end
618
619
 
619
- it "should work correctly for composite primary key specified as separate arguments" do
620
+ qspecify "should work correctly for composite primary key specified as separate arguments" do
620
621
  @c.set_primary_key :node_id, :kind
621
622
  @c[3921, 201].should be_a_kind_of(@c)
622
623
  sqls = MODEL_DB.sqls
@@ -637,9 +638,23 @@ describe "Model.db_schema" do
637
638
  def self.columns; orig_columns; end
638
639
  end
639
640
  @db = Sequel.mock
641
+ def @db.supports_schema_parsing?() true end
640
642
  @dataset = @db[:items]
641
643
  end
642
644
 
645
+ specify "should not call database's schema if it isn't supported" do
646
+ def @db.supports_schema_parsing?() false end
647
+ def @db.schema(table, opts = {})
648
+ raise Sequel::Error
649
+ end
650
+ @dataset.instance_variable_set(:@columns, [:x, :y])
651
+
652
+ @c.dataset = @dataset
653
+ @c.db_schema.should == {:x=>{}, :y=>{}}
654
+ @c.columns.should == [:x, :y]
655
+ @c.dataset.instance_variable_get(:@columns).should == [:x, :y]
656
+ end
657
+
643
658
  specify "should use the database's schema and set the columns and dataset columns" do
644
659
  def @db.schema(table, opts = {})
645
660
  [[:x, {:type=>:integer}], [:y, {:type=>:string}]]