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
@@ -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