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
@@ -57,6 +57,8 @@ module Sequel
57
57
  def_dataset_method(meth){associated(name)}
58
58
  ret
59
59
  end
60
+
61
+ Plugins.def_dataset_methods(self, :associated)
60
62
  end
61
63
 
62
64
  module DatasetMethods
@@ -39,7 +39,13 @@ module Sequel
39
39
  end
40
40
 
41
41
  module ClassMethods
42
- Model::HOOKS.each{|h| class_eval("def #{h}(method = nil, &block); add_hook(:#{h}, method, &block) end", __FILE__, __LINE__)}
42
+ (Model::HOOKS - [:after_initialize]).each{|h| class_eval("def #{h}(method = nil, &block); add_hook(:#{h}, method, &block) end", __FILE__, __LINE__)}
43
+
44
+ # REMOVE40
45
+ def after_initialize(method = nil, &block)
46
+ Sequel::Deprecation.deprecate('The Model after_initialize hook', 'The hook_class_methods plugin will no longer support the hook. Please use the after_initialize plugin and define the after_initialize hook directly')
47
+ add_hook(:after_initialize, method, &block)
48
+ end
43
49
 
44
50
  # This adds a new hook type. It will define both a class
45
51
  # method that you can use to add hooks, as well as an instance method
@@ -33,6 +33,10 @@ module Sequel
33
33
  # Album.plugin :identity_map
34
34
  # # would need to do Album.with_identity_map{} to use the identity map
35
35
  module IdentityMap
36
+ def self.apply(mod)
37
+ Sequel::Deprecation.deprecate('The identity_map plugin', 'Please stop loading it') unless defined?(SEQUEL_EXTENSIONS_NO_DEPRECATION_WARNING)
38
+ end
39
+
36
40
  module ClassMethods
37
41
  # Override the default :eager_loader option for many_*_many associations to work
38
42
  # with an identity_map. If the :eager_graph association option is used, you'll probably have to use
@@ -1,6 +1,6 @@
1
- module Sequel
2
- tsk_require 'json'
1
+ require 'json'
3
2
 
3
+ module Sequel
4
4
  module Plugins
5
5
  # The json_serializer plugin handles serializing entire Sequel::Model
6
6
  # objects to JSON, as well as support for deserializing JSON directly
@@ -143,6 +143,9 @@ module Sequel
143
143
  # Attempt to parse a single instance from the given JSON string,
144
144
  # with options passed to InstanceMethods#from_json_node.
145
145
  def from_json(json, opts={})
146
+ if opts[:all_associations] || opts[:all_columns]
147
+ Sequel::Deprecation.deprecate("The from_json :all_associations and :all_columns", 'You need to explicitly specify the associations and columns via the :associations and :fields options')
148
+ end
146
149
  v = Sequel.parse_json(json)
147
150
  case v
148
151
  when self
@@ -157,6 +160,9 @@ module Sequel
157
160
  # Attempt to parse an array of instances from the given JSON string,
158
161
  # with options passed to InstanceMethods#from_json_node.
159
162
  def array_from_json(json, opts={})
163
+ if opts[:all_associations] || opts[:all_columns]
164
+ Sequel::Deprecation.deprecate("The from_json :all_associations and :all_columns", 'You need to explicitly specify the associations and columns via the :associations and :fields options')
165
+ end
160
166
  v = Sequel.parse_json(json)
161
167
  if v.is_a?(Array)
162
168
  raise(Error, 'parsed json returned an array containing non-hashes') unless v.all?{|ve| ve.is_a?(Hash) || ve.is_a?(self)}
@@ -172,6 +178,7 @@ module Sequel
172
178
  # :all_columns and :all_associations options. Not recommended for usage
173
179
  # in new code, consider calling the from_json method directly with the JSON string.
174
180
  def json_create(hash, opts={})
181
+ Sequel::Deprecation.deprecate("Model.json_create", 'Switch to Model.from_json')
175
182
  new.from_json_node(hash, {:all_columns=>true, :all_associations=>true}.merge(opts))
176
183
  end
177
184
 
@@ -188,6 +195,9 @@ module Sequel
188
195
  # Parse the provided JSON, which should return a hash,
189
196
  # and process the hash with from_json_node.
190
197
  def from_json(json, opts={})
198
+ if opts[:all_associations] || opts[:all_columns]
199
+ Sequel::Deprecation.deprecate("The from_json :all_associations and :all_columns", 'You need to explicitly specify the associations and columns via the :associations and :fields options')
200
+ end
191
201
  from_json_node(Sequel.parse_json(json), opts)
192
202
  end
193
203
 
@@ -214,7 +224,10 @@ module Sequel
214
224
  unless hash.is_a?(Hash)
215
225
  raise Error, "parsed json doesn't return a hash"
216
226
  end
217
- hash.delete(JSON.create_id)
227
+ if hash.has_key?(JSON.create_id)
228
+ Sequel::Deprecation.deprecate('Attempting to use Model#from_json with a hash value that includes JSON.create_id is deprecated. Starting in Sequel 4.0, the create_id will not be removed automatically.')
229
+ hash.delete(JSON.create_id)
230
+ end
218
231
 
219
232
  unless assocs = opts[:associations]
220
233
  if opts[:all_associations]
@@ -289,9 +302,6 @@ module Sequel
289
302
  # to include in the JSON output. Using a nested
290
303
  # hash, you can pass options to associations
291
304
  # to affect the JSON used for associated objects.
292
- # :naked :: Not to add the JSON.create_id (json_class) key to the JSON
293
- # output hash, so when the JSON is parsed, it
294
- # will yield a hash instead of a model object.
295
305
  # :only :: Symbol or Array of Symbols of columns to only
296
306
  # include in the JSON output, ignoring all other
297
307
  # columns.
@@ -310,7 +320,13 @@ module Sequel
310
320
  else
311
321
  vals.keys - Array(opts[:except])
312
322
  end
313
- h = (JSON.create_id && !opts[:naked] && !opts[:root]) ? {JSON.create_id=>model.name} : {}
323
+
324
+ h = {}
325
+ if JSON.create_id && !opts[:naked] && !opts[:root]
326
+ Sequel::Deprecation.deprecate('The :naked and :root options have not been used, so adding JSON.create_id to the to_json output. This is deprecated, starting in Sequel 4, the JSON.create_id will never be added.')
327
+ h[JSON.create_id] = model.name
328
+ end
329
+
314
330
  cols.each{|c| h[c.to_s] = send(c)}
315
331
  if inc = opts[:include]
316
332
  if inc.is_a?(Hash)
@@ -318,9 +334,9 @@ module Sequel
318
334
  v = v.empty? ? [] : [v]
319
335
  h[k.to_s] = case objs = send(k)
320
336
  when Array
321
- objs.map{|obj| Literal.new(obj.to_json(*v))}
337
+ objs.map{|obj| Literal.new(Sequel.object_to_json(obj, *v))}
322
338
  else
323
- Literal.new(objs.to_json(*v))
339
+ Literal.new(Sequel.object_to_json(objs, *v))
324
340
  end
325
341
  end
326
342
  else
@@ -328,7 +344,7 @@ module Sequel
328
344
  end
329
345
  end
330
346
  h = {model.send(:underscore, model.to_s) => h} if opts[:root]
331
- h.to_json(*a)
347
+ Sequel.object_to_json(h, *a)
332
348
  end
333
349
  end
334
350
 
@@ -366,7 +382,10 @@ module Sequel
366
382
  opts.delete(:root)
367
383
  opts[:naked] = true unless opts.has_key?(:naked)
368
384
  true
385
+ when :both
386
+ true
369
387
  else
388
+ Sequel::Deprecation.deprecate('The to_json :root=>true option will mean :root=>:collection starting in Sequel 4. Use :root=>:both if you want to wrap both the collection and each item in a wrapper.')
370
389
  true
371
390
  end
372
391
 
@@ -377,15 +396,15 @@ module Sequel
377
396
  else
378
397
  all
379
398
  end
380
- array.map{|obj| Literal.new(obj.to_json(opts))}
399
+ array.map{|obj| Literal.new(Sequel.object_to_json(obj, opts))}
381
400
  else
382
401
  all
383
402
  end
384
403
 
385
404
  if collection_root
386
- {model.send(:pluralize, model.send(:underscore, model.to_s)) => res}.to_json(*a)
405
+ Sequel.object_to_json({model.send(:pluralize, model.send(:underscore, model.to_s)) => res}, *a)
387
406
  else
388
- res.to_json(*a)
407
+ Sequel.object_to_json(res, *a)
389
408
  end
390
409
  end
391
410
  end
@@ -1,5 +1,5 @@
1
1
  module Sequel
2
- tsk_require 'sequel/plugins/instance_filters'
2
+ require 'plugins/instance_filters'
3
3
 
4
4
  module Plugins
5
5
  # This plugin implements a simple database-independent locking mechanism
@@ -132,7 +132,7 @@ module Sequel
132
132
  end
133
133
  end
134
134
  table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
135
- model.from(t => table_alias).
135
+ model.from(SQL::AliasedExpression.new(t, table_alias)).
136
136
  with_recursive(t, col_aliases ? base_ds.select(*col_aliases) : base_ds.select_all,
137
137
  recursive_ds.select(*c_all),
138
138
  :args=>col_aliases)
@@ -181,7 +181,7 @@ module Sequel
181
181
  end
182
182
  table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
183
183
  elds = model.eager_loading_dataset(r,
184
- model.from(t => table_alias).
184
+ model.from(SQL::AliasedExpression.new(t, table_alias)).
185
185
  with_recursive(t, base_case,
186
186
  recursive_case,
187
187
  :args=>(([ka] + col_aliases) if col_aliases)),
@@ -232,7 +232,7 @@ module Sequel
232
232
  end
233
233
  end
234
234
  table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
235
- model.from(t => table_alias).
235
+ model.from(SQL::AliasedExpression.new(t, table_alias)).
236
236
  with_recursive(t, col_aliases ? base_ds.select(*col_aliases) : base_ds.select_all,
237
237
  recursive_ds.select(*c_all),
238
238
  :args=>col_aliases)
@@ -287,7 +287,7 @@ module Sequel
287
287
  end
288
288
  table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
289
289
  elds = model.eager_loading_dataset(r,
290
- model.from(t => table_alias).with_recursive(t, base_case, recursive_case,
290
+ model.from(SQL::AliasedExpression.new(t, table_alias)).with_recursive(t, base_case, recursive_case,
291
291
  :args=>(([ka] + col_aliases + (level ? [la] : [])) if col_aliases)),
292
292
  r.select,
293
293
  associations, eo)
@@ -0,0 +1,33 @@
1
+ module Sequel
2
+ module Plugins
3
+ # The scissors plugin adds class methods for update, delete, and destroy.
4
+ # It is so named because this is considered dangerous, since it is easy
5
+ # to write:
6
+ #
7
+ # Album.delete
8
+ #
9
+ # and delete all rows in the table, when you meant to write:
10
+ #
11
+ # album.delete
12
+ #
13
+ # and only delete a single row.
14
+ #
15
+ # This plugin is mostly useful for backwards compatibility, and not
16
+ # recommended for use in production. However, it can cut down on
17
+ # verbosity in non-transactional test code, so it may be appropriate
18
+ # to use when testing.
19
+ #
20
+ # Usage:
21
+ #
22
+ # # Make all model subclass run with scissors
23
+ # Sequel::Model.plugin :scissors
24
+ #
25
+ # # Make the Album class run with scissors
26
+ # Album.plugin :scissors
27
+ module Scissors
28
+ module ClassMethods
29
+ Plugins.def_dataset_methods(self, [:update, :delete, :destroy])
30
+ end
31
+ end
32
+ end
33
+ end
@@ -96,7 +96,7 @@ module Sequel
96
96
  end
97
97
  end)
98
98
  register_format(:yaml, lambda{|v| v.to_yaml}, lambda{|v| YAML.load(v)})
99
- register_format(:json, lambda{|v| v.to_json}, lambda{|v| Sequel.parse_json(v)})
99
+ register_format(:json, lambda{|v| Sequel.object_to_json(v)}, lambda{|v| Sequel.parse_json(v)})
100
100
 
101
101
  module ClassMethods
102
102
  # A hash with column name symbols and callable values, with the value
@@ -181,6 +181,12 @@ module Sequel
181
181
 
182
182
  private
183
183
 
184
+ # If calling set_dataset manually, make sure to set the dataset
185
+ # row proc to one that handles inheritance correctly.
186
+ def set_dataset_row_proc(ds)
187
+ ds.row_proc = @dataset.row_proc if @dataset
188
+ end
189
+
184
190
  # Return a class object. If a class is given, return it directly.
185
191
  # Treat strings and symbols as class names. If nil is given or
186
192
  # an invalid class name string or symbol is used, return self.
@@ -38,10 +38,14 @@ module Sequel
38
38
 
39
39
  par = opts.merge(opts.fetch(:parent, {}))
40
40
  parent = par.fetch(:name, :parent)
41
- model.many_to_one parent, par
42
41
 
43
42
  chi = opts.merge(opts.fetch(:children, {}))
44
43
  children = chi.fetch(:name, :children)
44
+
45
+ par[:reciprocal] = children
46
+ chi[:recripocal] = parent
47
+
48
+ model.many_to_one parent, par
45
49
  model.one_to_many children, chi
46
50
 
47
51
  model.plugin SingleRoot if opts[:single_root]
@@ -76,7 +76,7 @@ module Sequel
76
76
 
77
77
  # Instructs the model to skip validations defined in superclasses
78
78
  def skip_superclass_validations?
79
- defined?(@skip_superclass_validations) && @skip_superclass_validations
79
+ @skip_superclass_validations
80
80
  end
81
81
 
82
82
  # Defines validations by converting a longhand block into a series of
@@ -274,6 +274,7 @@ module Sequel
274
274
  # Possible Options:
275
275
  # * :message - The message to use (default: 'is a string' or 'is not a valid (integer|datetime|etc.)' if the type is known)
276
276
  def validates_not_string(*atts)
277
+ Sequel::Deprecation.deprecate('validates_not_string', "Please switch to validates_schema_type")
277
278
  opts = {
278
279
  :tag => :not_string,
279
280
  }.merge!(extract_options!(atts))
@@ -11,8 +11,7 @@ module Sequel
11
11
  # end
12
12
  # end
13
13
  #
14
- # The validates_unique and validates_schema_types methods have a unique API, but the other
15
- # validations have the API explained here:
14
+ # The validates_unique method has a unique API, but the other validations have the API explained here:
16
15
  #
17
16
  # Arguments:
18
17
  # atts :: Single attribute symbol or an array of attribute symbols specifying the
@@ -95,7 +94,7 @@ module Sequel
95
94
  module InstanceMethods
96
95
  # Check that the attribute values are the given exact length.
97
96
  def validates_exact_length(exact, atts, opts={})
98
- validatable_attributes_for_type(:exact_length, atts, opts){|a,v,m| validation_error_message(m, exact) unless v && v.length == exact}
97
+ validatable_attributes_for_type(:exact_length, atts, opts){|a,v,m| validation_error_message(m, exact) if v.nil? || v.length != exact}
99
98
  end
100
99
 
101
100
  # Check the string representation of the attribute value(s) against the regular expression with.
@@ -122,7 +121,7 @@ module Sequel
122
121
 
123
122
  # Check that the attribute values length is in the specified range.
124
123
  def validates_length_range(range, atts, opts={})
125
- validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) unless v && range.send(range.respond_to?(:cover?) ? :cover? : :include?, v.length)}
124
+ validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) if v.nil? || !range.send(range.respond_to?(:cover?) ? :cover? : :include?, v.length)}
126
125
  end
127
126
 
128
127
  # Check that the attribute values are not longer than the given max length.
@@ -130,12 +129,12 @@ module Sequel
130
129
  # Accepts a :nil_message option that is the error message to use when the
131
130
  # value is nil instead of being too long.
132
131
  def validates_max_length(max, atts, opts={})
133
- validatable_attributes_for_type(:max_length, atts, opts){|a,v,m| v ? validation_error_message(m, max) : validation_error_message(opts[:nil_message] || DEFAULT_OPTIONS[:max_length][:nil_message]) unless v && v.length <= max}
132
+ validatable_attributes_for_type(:max_length, atts, opts){|a,v,m| v ? validation_error_message(m, max) : validation_error_message(opts[:nil_message] || DEFAULT_OPTIONS[:max_length][:nil_message]) if v.nil? || v.length > max}
134
133
  end
135
134
 
136
135
  # Check that the attribute values are not shorter than the given min length.
137
136
  def validates_min_length(min, atts, opts={})
138
- validatable_attributes_for_type(:min_length, atts, opts){|a,v,m| validation_error_message(m, min) unless v && v.length >= min}
137
+ validatable_attributes_for_type(:min_length, atts, opts){|a,v,m| validation_error_message(m, min) if v.nil? || v.length < min}
139
138
  end
140
139
 
141
140
  # Check attribute value(s) are not NULL/nil.
@@ -150,6 +149,7 @@ module Sequel
150
149
  # be a string in an invalid format, and if typecasting succeeds, the value will
151
150
  # not be a string.
152
151
  def validates_not_string(atts, opts={})
152
+ Sequel::Deprecation.deprecate('validates_not_string', "Please switch to validates_schema_types")
153
153
  validatable_attributes_for_type(:not_string, atts, opts){|a,v,m| validation_error_message(m, (db_schema[a]||{})[:type]) if v.is_a?(String)}
154
154
  end
155
155
 
@@ -168,10 +168,11 @@ module Sequel
168
168
  # Validates for all of the model columns (or just the given columns)
169
169
  # that the column value is an instance of the expected class based on
170
170
  # the column's schema type.
171
- def validates_schema_types(atts=keys)
171
+ def validates_schema_types(atts=keys, opts={})
172
172
  Array(atts).each do |k|
173
- next unless type = schema_type_class(k)
174
- validates_type(type, k)
173
+ if type = schema_type_class(k)
174
+ validates_type(type, k, {:allow_nil=>true}.merge(opts))
175
+ end
175
176
  end
176
177
  end
177
178
 
@@ -180,7 +181,10 @@ module Sequel
180
181
  def validates_type(klass, atts, opts={})
181
182
  klass = klass.to_s.constantize if klass.is_a?(String) || klass.is_a?(Symbol)
182
183
  validatable_attributes_for_type(:type, atts, opts) do |a,v,m|
183
- next if v.nil?
184
+ if v.nil?
185
+ Sequel::Deprecation.deprecate('validates_type will no longer allow nil values by default in Sequel 4. Use the :allow_nil=>true option to allow nil values.')
186
+ next
187
+ end
184
188
  if klass.is_a?(Array) ? !klass.any?{|kls| v.is_a?(kls)} : !v.is_a?(klass)
185
189
  validation_error_message(m, klass)
186
190
  end
@@ -249,7 +253,7 @@ module Sequel
249
253
  where.call(model.dataset, self, arr)
250
254
  else
251
255
  vals = arr.map{|x| send(x)}
252
- next unless vals.all?
256
+ next if vals.any?{|v| v.nil?}
253
257
  model.where(arr.zip(vals))
254
258
  end
255
259
  ds = yield(ds) if block_given?
@@ -1,6 +1,6 @@
1
- module Sequel
2
- tsk_require 'nokogiri'
1
+ require 'nokogiri'
3
2
 
3
+ module Sequel
4
4
  module Plugins
5
5
  # The xml_serializer plugin handles serializing entire Sequel::Model
6
6
  # objects to XML, and deserializing XML into a single Sequel::Model
@@ -45,7 +45,7 @@ module Sequel
45
45
  # You can use a hash value with <tt>:include</tt> to pass options
46
46
  # to associations:
47
47
  #
48
- # album.to_json(:include=>{:artist=>{:only=>:name}})
48
+ # album.to_xml(:include=>{:artist=>{:only=>:name}})
49
49
  # # Output:
50
50
  # <?xml version="1.0"?>
51
51
  # <album>
@@ -131,6 +131,9 @@ module Sequel
131
131
  # Return an array of instances of this class based on
132
132
  # the provided XML.
133
133
  def array_from_xml(xml, opts={})
134
+ if opts[:all_associations] || opts[:all_columns]
135
+ Sequel::Deprecation.deprecate("The array_from_xml :all_associations and :all_columns", 'You need to explicitly specify the associations and columns via the :associations and :fields options')
136
+ end
134
137
  node = Nokogiri::XML(xml).children.first
135
138
  unless node
136
139
  raise Error, "Malformed XML used"
@@ -141,6 +144,9 @@ module Sequel
141
144
  # Return an instance of this class based on the provided
142
145
  # XML.
143
146
  def from_xml(xml, opts={})
147
+ if opts[:all_associations] || opts[:all_columns]
148
+ Sequel::Deprecation.deprecate("The from_xml :all_associations and :all_columns", 'You need to explicitly specify the associations and columns via the :associations and :fields options')
149
+ end
144
150
  from_xml_node(Nokogiri::XML(xml).children.first, opts)
145
151
  end
146
152
 
@@ -211,6 +217,9 @@ module Sequel
211
217
  # on the input string. Requires that you load the inflector
212
218
  # extension or another library that adds String#underscore.
213
219
  def from_xml(xml, opts={})
220
+ if opts[:all_associations] || opts[:all_columns]
221
+ Sequel::Deprecation.deprecate("The from_xml :all_associations and :all_columns", 'You need to explicitly specify the associations and columns via the :associations and :fields options')
222
+ end
214
223
  from_xml_node(Nokogiri::XML(xml).children.first, opts)
215
224
  end
216
225
 
@@ -93,7 +93,15 @@ module Sequel
93
93
  # Do not call this method with untrusted input, as that can result in
94
94
  # arbitrary code execution.
95
95
  def to_s_method(meth, args=:self) # :nodoc:
96
- class_eval("def to_s(ds) ds.#{meth}(#{args}) end", __FILE__, __LINE__)
96
+ # REMOVE40
97
+ class_eval(<<-END, __FILE__, __LINE__+1)
98
+ def to_s(ds)
99
+ Sequel::Deprecation.deprecate('SQL::Expression#to_s', "Please switch to using Dataset#literal to literalize expressions")
100
+ s = ''
101
+ to_s_append(ds, s)
102
+ s
103
+ end
104
+ END
97
105
  class_eval("def to_s_append(ds, sql) ds.#{meth}_append(sql, #{args}) end", __FILE__, __LINE__)
98
106
  end
99
107
  end
@@ -127,7 +135,9 @@ module Sequel
127
135
 
128
136
  # Alias of +to_s+
129
137
  def sql_literal(ds)
130
- to_s(ds)
138
+ s = ''
139
+ to_s_append(ds, s)
140
+ s
131
141
  end
132
142
  end
133
143