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
@@ -50,7 +50,7 @@ describe "Simple Dataset operations" do
50
50
  end
51
51
 
52
52
  specify "should have insert_multiple return primary key values" do
53
- @ds.insert_multiple([{:number=>20}, {:number=>30}]).should == [2, 3]
53
+ @ds.extension(:sequel_3_dataset_methods).insert_multiple([{:number=>20}, {:number=>30}]).should == [2, 3]
54
54
  @ds.filter(:id=>2).get(:number).should == 20
55
55
  @ds.filter(:id=>3).get(:number).should == 30
56
56
  end
@@ -65,11 +65,11 @@ describe "Simple Dataset operations" do
65
65
  end
66
66
 
67
67
  specify "should graph correctly" do
68
- @ds.graph(:items, {:id=>:id}, :table_alias=>:b).all.should == [{:items=>{:id=>1, :number=>10}, :b=>{:id=>1, :number=>10}}]
68
+ @ds.graph(:items, {:id=>:id}, :table_alias=>:b).extension(:graph_each).all.should == [{:items=>{:id=>1, :number=>10}, :b=>{:id=>1, :number=>10}}]
69
69
  end
70
70
 
71
71
  specify "should graph correctly with a subselect" do
72
- @ds.from_self(:alias=>:items).graph(@ds.from_self, {:id=>:id}, :table_alias=>:b).all.should == [{:items=>{:id=>1, :number=>10}, :b=>{:id=>1, :number=>10}}]
72
+ @ds.from_self(:alias=>:items).graph(@ds.from_self, {:id=>:id}, :table_alias=>:b).extension(:graph_each).all.should == [{:items=>{:id=>1, :number=>10}, :b=>{:id=>1, :number=>10}}]
73
73
  end
74
74
 
75
75
  cspecify "should have insert work correctly when inserting a row with all NULL values", :hsqldb do
@@ -893,7 +893,7 @@ describe "Sequel::Dataset convenience methods" do
893
893
 
894
894
  it "#[]= should update matching rows" do
895
895
  @ds.insert(20, 10)
896
- @ds[:a=>20] = {:b=>30}
896
+ @ds.extension(:sequel_3_dataset_methods)[:a=>20] = {:b=>30}
897
897
  @ds.all.should == [{:a=>20, :b=>30}]
898
898
  end
899
899
 
@@ -1335,25 +1335,21 @@ describe "Sequel::Dataset DSL support" do
1335
1335
  end
1336
1336
  end
1337
1337
 
1338
- specify "should work empty arrays with nulls and Sequel.empty_array_null_handling = true" do
1339
- begin
1340
- Sequel.empty_array_handle_nulls = false
1341
- @ds.insert(nil, nil)
1342
- @ds.filter(:a=>[]).all.should == []
1343
- @ds.exclude(:a=>[]).all.should == [{:a=>nil, :b=>nil}]
1344
- @ds.filter([:a, :b]=>[]).all.should == []
1345
- @ds.exclude([:a, :b]=>[]).all.should == [{:a=>nil, :b=>nil}]
1346
-
1347
- unless Sequel.guarded?(:mssql, :oracle, :db2)
1348
- # Some databases don't like boolean results in the select list
1349
- pr = proc{|r| r.is_a?(Integer) ? (r != 0) : r}
1350
- pr[@ds.get(Sequel.expr(:a=>[]))].should == false
1351
- pr[@ds.get(~Sequel.expr(:a=>[]))].should == true
1352
- pr[@ds.get(Sequel.expr([:a, :b]=>[]))].should == false
1353
- pr[@ds.get(~Sequel.expr([:a, :b]=>[]))].should == true
1354
- end
1355
- ensure
1356
- Sequel.empty_array_handle_nulls = true
1338
+ specify "should work empty arrays with nulls and the empty_array_ignore_nulls extension" do
1339
+ ds = @ds.extension(:empty_array_ignore_nulls)
1340
+ ds.insert(nil, nil)
1341
+ ds.filter(:a=>[]).all.should == []
1342
+ ds.exclude(:a=>[]).all.should == [{:a=>nil, :b=>nil}]
1343
+ ds.filter([:a, :b]=>[]).all.should == []
1344
+ ds.exclude([:a, :b]=>[]).all.should == [{:a=>nil, :b=>nil}]
1345
+
1346
+ unless Sequel.guarded?(:mssql, :oracle, :db2)
1347
+ # Some databases don't like boolean results in the select list
1348
+ pr = proc{|r| r.is_a?(Integer) ? (r != 0) : r}
1349
+ pr[ds.get(Sequel.expr(:a=>[]))].should == false
1350
+ pr[ds.get(~Sequel.expr(:a=>[]))].should == true
1351
+ pr[ds.get(Sequel.expr([:a, :b]=>[]))].should == false
1352
+ pr[ds.get(~Sequel.expr([:a, :b]=>[]))].should == true
1357
1353
  end
1358
1354
  end
1359
1355
 
@@ -1583,7 +1579,7 @@ describe "Dataset defaults and overrides" do
1583
1579
  before(:all) do
1584
1580
  @db = INTEGRATION_DB
1585
1581
  @db.create_table!(:a){Integer :a}
1586
- @ds = @db[:a].order(:a)
1582
+ @ds = @db[:a].order(:a).extension(:set_overrides)
1587
1583
  end
1588
1584
  before do
1589
1585
  @ds.delete
@@ -496,8 +496,8 @@ describe "many_to_one/one_to_many not referencing primary key" do
496
496
  end
497
497
  end
498
498
  before do
499
- Client.delete
500
- Invoice.delete
499
+ Client.dataset.delete
500
+ Invoice.dataset.delete
501
501
  @client1 = Client.create(:name=>'X')
502
502
  @client2 = Client.create(:name=>'Y')
503
503
  @invoice1 = Invoice.create(:client_name=>'X')
@@ -639,8 +639,8 @@ describe "one to one associations" do
639
639
  primary_key :id
640
640
  end
641
641
  class ::Book < Sequel::Model
642
- one_to_one :first_page, :class=>:Page, :conditions=>{:page_number=>1}
643
- one_to_one :second_page, :class=>:Page, :conditions=>{:page_number=>2}
642
+ one_to_one :first_page, :class=>:Page, :conditions=>{:page_number=>1}, :reciprocal=>nil
643
+ one_to_one :second_page, :class=>:Page, :conditions=>{:page_number=>2}, :reciprocal=>nil
644
644
  end
645
645
 
646
646
  INTEGRATION_DB.create_table!(:pages) do
@@ -649,7 +649,7 @@ describe "one to one associations" do
649
649
  Integer :page_number
650
650
  end
651
651
  class ::Page < Sequel::Model
652
- many_to_one :book
652
+ many_to_one :book, :reciprocal=>nil
653
653
  end
654
654
 
655
655
  @book1 = Book.create
@@ -125,7 +125,7 @@ describe "Sequel::Model basic support" do
125
125
  specify "#exists? should return whether the item is still in the database" do
126
126
  i = Item.create(:name=>'J')
127
127
  i.exists?.should == true
128
- Item.delete
128
+ Item.dataset.delete
129
129
  i.exists?.should == false
130
130
  end
131
131
 
@@ -139,10 +139,10 @@ describe "Sequel::Model basic support" do
139
139
  i = Item.create(:name=>'J', :num=>1)
140
140
  Item.all.should == [Item.load(:id=>1, :name=>'J', :num=>1)]
141
141
  i.set(:name=>'K', :num=>2)
142
- i.save(:name)
142
+ i.save(:columns=>:name)
143
143
  Item.all.should == [Item.load(:id=>1, :name=>'K', :num=>1)]
144
144
  i.set(:name=>'L')
145
- i.save(:num)
145
+ i.save(:columns=>:num)
146
146
  Item.all.should == [Item.load(:id=>1, :name=>'K', :num=>2)]
147
147
  end
148
148
 
@@ -493,38 +493,6 @@ describe "Tactical Eager Loading Plugin" do
493
493
  end
494
494
  end
495
495
 
496
- describe "Identity Map plugin" do
497
- before do
498
- @db = INTEGRATION_DB
499
- @db.create_table!(:items) do
500
- primary_key :id
501
- String :name
502
- Integer :num
503
- end
504
- class ::Item < Sequel::Model(@db)
505
- plugin :identity_map
506
- end
507
- Item.create(:name=>'J', :num=>3)
508
- end
509
- after do
510
- @db.drop_table?(:items)
511
- Object.send(:remove_const, :Item)
512
- end
513
-
514
- specify "should return the same instance if retrieved more than once" do
515
- Item.with_identity_map{Item.first.object_id.should == Item.first.object_id}
516
- end
517
-
518
- specify "should merge attributes that don't exist in the model" do
519
- Item.with_identity_map do
520
- i = Item.select(:id, :name).first
521
- i.values.should == {:id=>1, :name=>'J'}
522
- Item.first
523
- i.values.should == {:id=>1, :name=>'J', :num=>3}
524
- end
525
- end
526
- end
527
-
528
496
  describe "Touch plugin" do
529
497
  before(:all) do
530
498
  @db = INTEGRATION_DB
@@ -1060,7 +1028,7 @@ describe "UpdatePrimaryKey plugin" do
1060
1028
  @db[:t].all.should == [{:a=>1, :b=>4}]
1061
1029
  @c.first.set(:b=>5).save
1062
1030
  @db[:t].all.should == [{:a=>1, :b=>5}]
1063
- @c.first.set(:b=>6).save(:b)
1031
+ @c.first.set(:b=>6).save(:columns=>:b)
1064
1032
  @db[:t].all.should == [{:a=>1, :b=>6}]
1065
1033
  end
1066
1034
 
@@ -1072,7 +1040,7 @@ describe "UpdatePrimaryKey plugin" do
1072
1040
  specify "should handle updating just the primary key field when saving changes" do
1073
1041
  @c.first.update(:a=>2)
1074
1042
  @db[:t].all.should == [{:a=>2, :b=>3}]
1075
- @c.first.set(:a=>3).save(:a)
1043
+ @c.first.set(:a=>3).save(:columns=>:a)
1076
1044
  @db[:t].all.should == [{:a=>3, :b=>3}]
1077
1045
  end
1078
1046
 
@@ -1430,7 +1398,7 @@ describe "List plugin without a scope" do
1430
1398
  @c.plugin :list
1431
1399
  end
1432
1400
  before do
1433
- @c.delete
1401
+ @c.dataset.delete
1434
1402
  @c.create :name => "abc"
1435
1403
  @c.create :name => "def"
1436
1404
  @c.create :name => "hig"
@@ -1505,7 +1473,7 @@ describe "List plugin with a scope" do
1505
1473
  @c.plugin :list, :field => :pos, :scope => :parent_id
1506
1474
  end
1507
1475
  before do
1508
- @c.delete
1476
+ @c.dataset.delete
1509
1477
  p1 = @c.create :name => "Hm", :parent_id => 0
1510
1478
  p2 = @c.create :name => "Ps", :parent_id => p1.id
1511
1479
  @c.create :name => "P1", :parent_id => p2.id
@@ -1746,7 +1714,7 @@ describe "Sequel::Plugins::PreparedStatements" do
1746
1714
  @c.plugin :prepared_statements_with_pk
1747
1715
  end
1748
1716
  before do
1749
- @c.delete
1717
+ @c.dataset.delete
1750
1718
  @foo = @c.create(:name=>'foo', :i=>10)
1751
1719
  @bar = @c.create(:name=>'bar', :i=>20)
1752
1720
  end
@@ -1942,13 +1910,13 @@ describe "Sequel::Plugins::ConstraintValidations" do
1942
1910
  it "should set up automatic validations inside the model" do
1943
1911
  c = Class.new(Sequel::Model(@ds))
1944
1912
  c.plugin :constraint_validations
1945
- c.delete
1913
+ c.dataset.delete
1946
1914
  proc{c.create(@valid_row)}.should_not raise_error
1947
1915
 
1948
1916
  # Test for unique validation
1949
1917
  c.new(@valid_row).should_not be_valid
1950
1918
 
1951
- c.delete
1919
+ c.dataset.delete
1952
1920
  @violations.each do |col, vals|
1953
1921
  try = @valid_row.dup
1954
1922
  vals.each do |val|
@@ -4,13 +4,11 @@ describe "Database schema parser" do
4
4
  before do
5
5
  @iom = INTEGRATION_DB.identifier_output_method
6
6
  @iim = INTEGRATION_DB.identifier_input_method
7
- @defsch = INTEGRATION_DB.default_schema
8
7
  @qi = INTEGRATION_DB.quote_identifiers?
9
8
  end
10
9
  after do
11
10
  INTEGRATION_DB.identifier_output_method = @iom
12
11
  INTEGRATION_DB.identifier_input_method = @iim
13
- INTEGRATION_DB.default_schema = @defsch
14
12
  INTEGRATION_DB.quote_identifiers = @qi
15
13
  INTEGRATION_DB.drop_table?(:items)
16
14
  end
@@ -19,7 +17,6 @@ describe "Database schema parser" do
19
17
  INTEGRATION_DB.identifier_output_method = :reverse
20
18
  INTEGRATION_DB.identifier_input_method = :reverse
21
19
  INTEGRATION_DB.quote_identifiers = true
22
- INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
23
20
  INTEGRATION_DB.create_table!(:items){Integer :number}
24
21
  begin
25
22
  INTEGRATION_DB.schema(:items, :reload=>true).should be_a_kind_of(Array)
@@ -33,7 +30,6 @@ describe "Database schema parser" do
33
30
  INTEGRATION_DB.identifier_output_method = :reverse
34
31
  INTEGRATION_DB.identifier_input_method = :reverse
35
32
  INTEGRATION_DB.quote_identifiers = true
36
- INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
37
33
  INTEGRATION_DB.create_table!(:items){Integer :number}
38
34
  INTEGRATION_DB.identifier_output_method = @iom
39
35
  INTEGRATION_DB.identifier_input_method = @iim
@@ -148,15 +144,6 @@ describe "Database schema parser" do
148
144
  end
149
145
  end if INTEGRATION_DB.supports_schema_parsing?
150
146
 
151
- test_indexes = begin
152
- INTEGRATION_DB.drop_table?(:blah)
153
- INTEGRATION_DB.indexes(:blah)
154
- true
155
- rescue Sequel::NotImplemented
156
- false
157
- rescue
158
- true
159
- end
160
147
  describe "Database index parsing" do
161
148
  after do
162
149
  INTEGRATION_DB.drop_table?(:items)
@@ -188,17 +175,8 @@ describe "Database index parsing" do
188
175
  INTEGRATION_DB.create_table!(:items){Integer :n; Integer :a; primary_key [:n, :a]}
189
176
  INTEGRATION_DB.indexes(:items).should == {}
190
177
  end
191
- end if test_indexes
178
+ end if INTEGRATION_DB.supports_index_parsing?
192
179
 
193
- test_foreign_key_list = begin
194
- INTEGRATION_DB.drop_table?(:blah)
195
- INTEGRATION_DB.foreign_key_list(:blah)
196
- true
197
- rescue Sequel::NotImplemented
198
- false
199
- rescue
200
- true
201
- end
202
180
  describe "Database foreign key parsing" do
203
181
  before do
204
182
  @db = INTEGRATION_DB
@@ -253,7 +231,7 @@ describe "Database foreign key parsing" do
253
231
  @db.create_table!(:b, :engine=>:InnoDB){Integer :e; Integer :f; foreign_key [:e, :f], :a; foreign_key [:f, :e], :a, :key=>[:c, :b]}
254
232
  @pr[:b, [[:e, :f], :a, [:pk, :b, :c]], [[:f, :e], :a, [:c, :b]]]
255
233
  end
256
- end if test_foreign_key_list
234
+ end if INTEGRATION_DB.supports_foreign_key_parsing?
257
235
 
258
236
  describe "Database schema modifiers" do
259
237
  before do
@@ -686,12 +664,6 @@ describe "Database schema modifiers" do
686
664
  end if INTEGRATION_DB.supports_deferrable_constraints?
687
665
  end
688
666
 
689
- test_tables = begin
690
- INTEGRATION_DB.tables
691
- true
692
- rescue Sequel::NotImplemented
693
- false
694
- end
695
667
  describe "Database#tables" do
696
668
  before do
697
669
  class ::String
@@ -726,14 +698,8 @@ describe "Database#tables" do
726
698
  @db.identifier_input_method = :xxxxx
727
699
  @db.tables.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
728
700
  end
729
- end if test_tables
701
+ end if INTEGRATION_DB.supports_table_listing?
730
702
 
731
- test_views = begin
732
- INTEGRATION_DB.views
733
- true
734
- rescue Sequel::NotImplemented
735
- false
736
- end
737
703
  describe "Database#views" do
738
704
  before do
739
705
  class ::String
@@ -768,4 +734,4 @@ describe "Database#views" do
768
734
  @db.identifier_input_method = :xxxxx
769
735
  @db.views.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
770
736
  end
771
- end if test_views
737
+ end if INTEGRATION_DB.supports_view_listing?
@@ -14,6 +14,7 @@ begin
14
14
  require File.join(File.dirname(File.dirname(__FILE__)), 'spec_config.rb') unless defined?(INTEGRATION_DB)
15
15
  rescue LoadError
16
16
  end
17
+ Sequel::Deprecation.backtrace_filter = lambda{|line, lineno| lineno < 4 || line =~ /_(spec|test)\.rb/}
17
18
 
18
19
  if ENV['SEQUEL_COLUMNS_INTROSPECTION']
19
20
  Sequel.extension :columns_introspection
@@ -21,7 +22,7 @@ if ENV['SEQUEL_COLUMNS_INTROSPECTION']
21
22
  end
22
23
 
23
24
  Sequel::Model.use_transactions = false
24
- Sequel::Model.cache_anonymous_models = false
25
+ Sequel.cache_anonymous_models = false
25
26
 
26
27
  unless defined?(RSpec)
27
28
  module Spec::Matchers
@@ -115,6 +115,75 @@ describe Sequel::Model::Associations::AssociationReflection, "#reciprocal" do
115
115
  ParParentThree.association_reflection(:par_parents).keys.should_not include(:reciprocal)
116
116
  ParParentThree.association_reflection(:par_parents).reciprocal.should == :par_parent_threes
117
117
  end
118
+
119
+ qspecify "should handle ambiguous reciprocals" do
120
+ ParParent.many_to_one :par_parent_two, :class=>ParParentTwo, :key=>:par_parent_two_id
121
+ ParParent.many_to_one :par_parent_two2, :clone=>:par_parent_two
122
+ ParParentTwo.one_to_many :par_parents, :class=>ParParent, :key=>:par_parent_two_id
123
+ ParParentTwo.one_to_many :par_parents2, :clone=>:par_parents
124
+ ParParent.many_to_many :par_parent_threes, :class=>ParParentThree, :right_key=>:par_parent_three_id
125
+ ParParent.many_to_many :par_parent_threes2, :clone=>:par_parent_threes
126
+ ParParentThree.many_to_many :par_parents
127
+
128
+ [:par_parent_two, :par_parent_two2].should include(ParParentTwo.association_reflection(:par_parents).reciprocal)
129
+ [:par_parents, :par_parents2].should include(ParParent.association_reflection(:par_parent_two).reciprocal)
130
+ [:par_parent_threes, :par_parent_threes2].should include(ParParentThree.association_reflection(:par_parents).reciprocal)
131
+ end
132
+
133
+ it "should handle ambiguous reciprocals where only one doesn't have conditions/blocks" do
134
+ ParParent.many_to_one :par_parent_two, :class=>ParParentTwo, :key=>:par_parent_two_id
135
+ ParParent.many_to_one :par_parent_two2, :clone=>:par_parent_two, :conditions=>{:id=>:id}
136
+ ParParentTwo.one_to_many :par_parents
137
+ ParParent.many_to_many :par_parent_threes, :class=>ParParentThree, :right_key=>:par_parent_three_id
138
+ ParParent.many_to_many :par_parent_threes2, :clone=>:par_parent_threes do |ds|
139
+ ds
140
+ end
141
+ ParParentThree.many_to_many :par_parents
142
+
143
+ ParParentTwo.association_reflection(:par_parents).reciprocal.should == :par_parent_two
144
+ ParParentThree.association_reflection(:par_parents).reciprocal.should == :par_parent_threes
145
+ end
146
+
147
+ it "should handle ambiguous reciprocals where only one has matching primary keys" do
148
+ ParParent.many_to_one :par_parent_two, :class=>ParParentTwo, :key=>:par_parent_two_id
149
+ ParParent.many_to_one :par_parent_two2, :clone=>:par_parent_two, :primary_key=>:foo
150
+ ParParentTwo.one_to_many :par_parents, :class=>ParParent, :key=>:par_parent_two_id
151
+ ParParentTwo.one_to_many :par_parents2, :clone=>:par_parents, :primary_key=>:foo
152
+ ParParent.many_to_many :par_parent_threes, :class=>ParParentThree, :right_key=>:par_parent_three_id
153
+ ParParent.many_to_many :par_parent_threes2, :clone=>:par_parent_threes, :right_primary_key=>:foo
154
+ ParParent.many_to_many :par_parent_threes3, :clone=>:par_parent_threes, :left_primary_key=>:foo
155
+ ParParentThree.many_to_many :par_parents
156
+
157
+ ParParent.association_reflection(:par_parent_two).reciprocal.should == :par_parents
158
+ ParParent.association_reflection(:par_parent_two2).reciprocal.should == :par_parents2
159
+ ParParentTwo.association_reflection(:par_parents).reciprocal.should == :par_parent_two
160
+ ParParentTwo.association_reflection(:par_parents2).reciprocal.should == :par_parent_two2
161
+ ParParentThree.association_reflection(:par_parents).reciprocal.should == :par_parent_threes
162
+ end
163
+
164
+ specify "should handle reciprocals where current association has conditions/block" do
165
+ ParParent.many_to_one :par_parent_two, :conditions=>{:id=>:id}
166
+ ParParentTwo.one_to_many :par_parents
167
+ ParParent.many_to_many :par_parent_threes do |ds|
168
+ ds
169
+ end
170
+ ParParentThree.many_to_many :par_parents
171
+
172
+ ParParent.association_reflection(:par_parent_two).reciprocal.should == :par_parents
173
+ ParParent.association_reflection(:par_parent_threes).reciprocal.should == :par_parents
174
+ end
175
+
176
+ qspecify "should handle reciprocals where reciprocal association has conditions/block" do
177
+ ParParent.many_to_one :par_parent_two, :conditions=>{:id=>:id}
178
+ ParParentTwo.one_to_many :par_parents
179
+ ParParent.many_to_many :par_parent_threes do |ds|
180
+ ds
181
+ end
182
+ ParParentThree.many_to_many :par_parents
183
+
184
+ ParParentTwo.association_reflection(:par_parents).reciprocal.should == :par_parent_two
185
+ ParParentThree.association_reflection(:par_parents).reciprocal.should == :par_parent_threes
186
+ end
118
187
  end
119
188
 
120
189
  describe Sequel::Model::Associations::AssociationReflection, "#select" do
@@ -317,14 +386,10 @@ describe Sequel::Model::Associations::AssociationReflection, "#eager_limit_strat
317
386
  def (c.dataset).supports_window_functions?() true end
318
387
  c.many_to_many :cs, :class=>c, :limit=>1
319
388
  c.association_reflection(:cs).eager_limit_strategy.should == :window_function
320
-
321
- c.default_eager_limit_strategy = :correlated_subquery
322
- c.many_to_many :cs, :class=>c, :limit=>1
323
- c.association_reflection(:cs).eager_limit_strategy.should == :correlated_subquery
324
389
  end
325
390
 
326
391
  it "should ignore Model.default_eager_limit_strategy for one_to_one associations" do
327
- @c.default_eager_limit_strategy = :correlated_subquery
392
+ @c.default_eager_limit_strategy = :window_function
328
393
  @c.one_to_one :c, :class=>@c
329
394
  @c.association_reflection(:c).eager_limit_strategy.should be_nil
330
395
  end
@@ -1301,7 +1301,7 @@ describe Sequel::Model, "one_to_many" do
1301
1301
  end
1302
1302
 
1303
1303
  it "should have add_ method accept a composite key" do
1304
- @c1.set_primary_key :id, :z
1304
+ @c1.set_primary_key [:id, :z]
1305
1305
  @c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :y], :primary_key=>[:id, :x]
1306
1306
  @c1.dataset._fetch = {:id => 2345, :z => 8, :node_id => 1234, :y=>5}
1307
1307
 
@@ -1326,7 +1326,7 @@ describe Sequel::Model, "one_to_many" do
1326
1326
  end
1327
1327
 
1328
1328
  it "should accept a array of composite primary key values for the remove_ method and remove an existing record" do
1329
- @c1.set_primary_key :id, :y
1329
+ @c1.set_primary_key [:id, :y]
1330
1330
  @c2.one_to_many :attributes, :class => @c1, :key=>:node_id, :primary_key=>:id
1331
1331
  n = @c2.new(:id => 123)
1332
1332
  @c1.dataset._fetch = {:id=>234, :node_id=>123, :y=>5}
@@ -1682,7 +1682,7 @@ describe Sequel::Model, "one_to_many" do
1682
1682
  end
1683
1683
 
1684
1684
  it "should allow additional arguments given to the remove_ method and pass them onwards to the _remove_ method" do
1685
- @c2.one_to_many :attributes, :class => @c1
1685
+ @c2.one_to_many :attributes, :class => @c1, :reciprocal=>nil
1686
1686
  p = @c2.load(:id=>10)
1687
1687
  c = @c1.load(:id=>123)
1688
1688
  def p._remove_attribute(x,*y)
@@ -1801,7 +1801,7 @@ describe Sequel::Model, "one_to_many" do
1801
1801
  p.attributes.should == [c]
1802
1802
  end
1803
1803
 
1804
- it "should raise an error if trying to use the :one_to_one option" do
1804
+ qspecify "should raise an error if trying to use the :one_to_one option" do
1805
1805
  proc{@c2.one_to_many :attribute, :class => @c1, :one_to_one=>true}.should raise_error(Sequel::Error)
1806
1806
  proc{@c2.associate :one_to_many, :attribute, :class => @c1, :one_to_one=>true}.should raise_error(Sequel::Error)
1807
1807
  end
@@ -2371,13 +2371,13 @@ describe Sequel::Model, "many_to_many" do
2371
2371
  end
2372
2372
 
2373
2373
  it "add, remove, and remove_all methods should respect :join_table_block option" do
2374
- @c2.many_to_many :attributes, :class => @c1, :join_table_block=>proc{|ds| ds.filter(:x=>123).set_overrides(:x=>123)}
2374
+ @c2.many_to_many :attributes, :class => @c1, :join_table_block=>proc{|ds| ds.filter(:x=>123)}
2375
2375
  o = @c2.load(:id => 1234)
2376
2376
  o.add_attribute(@c1.load(:id=>44))
2377
2377
  o.remove_attribute(@c1.load(:id=>45))
2378
2378
  o.remove_all_attributes
2379
2379
  sqls = MODEL_DB.sqls
2380
- sqls.shift =~ /INSERT INTO attributes_nodes \((node_id|attribute_id|x), (node_id|attribute_id|x), (node_id|attribute_id|x)\) VALUES \((1234|123|44), (1234|123|44), (1234|123|44)\)/
2380
+ sqls.shift =~ /INSERT INTO attributes_nodes \((node_id|attribute_id), (node_id|attribute_id)\) VALUES \((1234|44), (1234|44)\)/
2381
2381
  sqls.should == ["DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234) AND (attribute_id = 45))",
2382
2382
  "DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234))"]
2383
2383
  end
@@ -3148,7 +3148,7 @@ describe "Sequel::Model Associations with non-column expression keys" do
3148
3148
  @Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>Sequel.subscript(:object_ids, 0), :key=>Sequel.subscript(:object_ids, 0), :key_method=>:obj_id, :class=>@Bar
3149
3149
  @Bar.many_to_one :foo, :key=>:obj_id, :key_column=>Sequel.subscript(:object_ids, 0), :primary_key=>Sequel.subscript(:object_ids, 0), :primary_key_method=>:obj_id, :class=>@Foo
3150
3150
  @Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id, :left_key=>Sequel.subscript(:foo_ids, 0), :right_key=>Sequel.subscript(:bar_ids, 0), :class=>@Bar
3151
- @Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id, :left_key=>Sequel.subscript(:bar_ids, 0), :right_key=>Sequel.subscript(:foo_ids, 0), :class=>@Foo
3151
+ @Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id, :left_key=>Sequel.subscript(:bar_ids, 0), :right_key=>Sequel.subscript(:foo_ids, 0), :class=>@Foo, :reciprocal=>nil
3152
3152
  @foo = @Foo.load(:id=>1, :object_ids=>[2])
3153
3153
  @bar = @Bar.load(:id=>1, :object_ids=>[2])
3154
3154
  @db.sqls
@@ -3233,24 +3233,24 @@ describe "Model#pk_or_nil" do
3233
3233
  @m.columns :id, :x, :y
3234
3234
  end
3235
3235
 
3236
- it "should be default return the value of the :id column" do
3236
+ qspecify "should be default return the value of the :id column" do
3237
3237
  m = @m.load(:id => 111, :x => 2, :y => 3)
3238
3238
  m.pk_or_nil.should == 111
3239
3239
  end
3240
3240
 
3241
- it "should be return the primary key value for custom primary key" do
3241
+ qspecify "should be return the primary key value for custom primary key" do
3242
3242
  @m.set_primary_key :x
3243
3243
  m = @m.load(:id => 111, :x => 2, :y => 3)
3244
3244
  m.pk_or_nil.should == 2
3245
3245
  end
3246
3246
 
3247
- it "should be return the primary key value for composite primary key" do
3247
+ qspecify "should be return the primary key value for composite primary key" do
3248
3248
  @m.set_primary_key [:y, :x]
3249
3249
  m = @m.load(:id => 111, :x => 2, :y => 3)
3250
3250
  m.pk_or_nil.should == [3, 2]
3251
3251
  end
3252
3252
 
3253
- it "should raise if no primary key" do
3253
+ qspecify "should not raise if no primary key" do
3254
3254
  @m.set_primary_key nil
3255
3255
  m = @m.new(:id => 111, :x => 2, :y => 3)
3256
3256
  m.pk_or_nil.should be_nil