sequel 3.47.0 → 3.48.0

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