sequel 3.48.0 → 4.0.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 (267) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +114 -0
  3. data/Rakefile +10 -7
  4. data/doc/association_basics.rdoc +25 -23
  5. data/doc/code_order.rdoc +7 -0
  6. data/doc/core_extensions.rdoc +0 -10
  7. data/doc/object_model.rdoc +4 -1
  8. data/doc/querying.rdoc +3 -3
  9. data/doc/release_notes/4.0.0.txt +262 -0
  10. data/doc/security.rdoc +0 -28
  11. data/doc/testing.rdoc +8 -14
  12. data/lib/sequel/adapters/ado.rb +7 -11
  13. data/lib/sequel/adapters/ado/access.rb +8 -8
  14. data/lib/sequel/adapters/ado/mssql.rb +4 -4
  15. data/lib/sequel/adapters/amalgalite.rb +6 -6
  16. data/lib/sequel/adapters/cubrid.rb +7 -7
  17. data/lib/sequel/adapters/db2.rb +5 -9
  18. data/lib/sequel/adapters/dbi.rb +2 -6
  19. data/lib/sequel/adapters/do.rb +4 -4
  20. data/lib/sequel/adapters/firebird.rb +4 -4
  21. data/lib/sequel/adapters/ibmdb.rb +8 -8
  22. data/lib/sequel/adapters/informix.rb +2 -10
  23. data/lib/sequel/adapters/jdbc.rb +17 -17
  24. data/lib/sequel/adapters/jdbc/as400.rb +2 -2
  25. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
  26. data/lib/sequel/adapters/jdbc/db2.rb +1 -1
  27. data/lib/sequel/adapters/jdbc/derby.rb +1 -1
  28. data/lib/sequel/adapters/jdbc/h2.rb +2 -2
  29. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
  30. data/lib/sequel/adapters/jdbc/informix.rb +1 -1
  31. data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
  32. data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
  33. data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
  35. data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
  36. data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
  37. data/lib/sequel/adapters/mock.rb +7 -7
  38. data/lib/sequel/adapters/mysql.rb +3 -3
  39. data/lib/sequel/adapters/mysql2.rb +4 -4
  40. data/lib/sequel/adapters/odbc.rb +2 -6
  41. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  42. data/lib/sequel/adapters/openbase.rb +1 -5
  43. data/lib/sequel/adapters/oracle.rb +13 -17
  44. data/lib/sequel/adapters/postgres.rb +20 -25
  45. data/lib/sequel/adapters/shared/cubrid.rb +3 -3
  46. data/lib/sequel/adapters/shared/db2.rb +2 -2
  47. data/lib/sequel/adapters/shared/firebird.rb +7 -7
  48. data/lib/sequel/adapters/shared/mssql.rb +9 -9
  49. data/lib/sequel/adapters/shared/mysql.rb +29 -13
  50. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
  51. data/lib/sequel/adapters/shared/oracle.rb +22 -13
  52. data/lib/sequel/adapters/shared/postgres.rb +61 -46
  53. data/lib/sequel/adapters/shared/sqlite.rb +9 -9
  54. data/lib/sequel/adapters/sqlite.rb +17 -11
  55. data/lib/sequel/adapters/swift.rb +3 -3
  56. data/lib/sequel/adapters/swift/mysql.rb +1 -1
  57. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  58. data/lib/sequel/adapters/tinytds.rb +8 -8
  59. data/lib/sequel/ast_transformer.rb +3 -1
  60. data/lib/sequel/connection_pool.rb +4 -2
  61. data/lib/sequel/connection_pool/sharded_single.rb +2 -2
  62. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
  63. data/lib/sequel/connection_pool/threaded.rb +7 -7
  64. data/lib/sequel/core.rb +4 -67
  65. data/lib/sequel/database.rb +1 -0
  66. data/lib/sequel/database/connecting.rb +2 -8
  67. data/lib/sequel/database/dataset.rb +2 -7
  68. data/lib/sequel/database/dataset_defaults.rb +0 -18
  69. data/lib/sequel/database/features.rb +4 -4
  70. data/lib/sequel/database/misc.rb +6 -8
  71. data/lib/sequel/database/query.rb +5 -61
  72. data/lib/sequel/database/schema_generator.rb +22 -20
  73. data/lib/sequel/database/schema_methods.rb +48 -20
  74. data/lib/sequel/database/transactions.rb +7 -17
  75. data/lib/sequel/dataset.rb +2 -0
  76. data/lib/sequel/dataset/actions.rb +23 -91
  77. data/lib/sequel/dataset/features.rb +1 -4
  78. data/lib/sequel/dataset/graph.rb +3 -47
  79. data/lib/sequel/dataset/misc.rb +4 -33
  80. data/lib/sequel/dataset/prepared_statements.rb +3 -1
  81. data/lib/sequel/dataset/query.rb +116 -240
  82. data/lib/sequel/dataset/sql.rb +19 -97
  83. data/lib/sequel/deprecated.rb +0 -16
  84. data/lib/sequel/exceptions.rb +0 -3
  85. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  86. data/lib/sequel/extensions/columns_introspection.rb +1 -12
  87. data/lib/sequel/extensions/constraint_validations.rb +3 -3
  88. data/lib/sequel/extensions/core_extensions.rb +0 -9
  89. data/lib/sequel/extensions/date_arithmetic.rb +1 -2
  90. data/lib/sequel/extensions/graph_each.rb +11 -0
  91. data/lib/sequel/extensions/migration.rb +5 -5
  92. data/lib/sequel/extensions/null_dataset.rb +11 -13
  93. data/lib/sequel/extensions/pagination.rb +3 -6
  94. data/lib/sequel/extensions/pg_array.rb +6 -4
  95. data/lib/sequel/extensions/pg_array_ops.rb +35 -1
  96. data/lib/sequel/extensions/pg_json.rb +12 -2
  97. data/lib/sequel/extensions/pg_json_ops.rb +266 -0
  98. data/lib/sequel/extensions/pg_range.rb +2 -2
  99. data/lib/sequel/extensions/pg_range_ops.rb +0 -8
  100. data/lib/sequel/extensions/pg_row.rb +2 -2
  101. data/lib/sequel/extensions/pretty_table.rb +0 -4
  102. data/lib/sequel/extensions/query.rb +3 -8
  103. data/lib/sequel/extensions/schema_caching.rb +0 -7
  104. data/lib/sequel/extensions/schema_dumper.rb +10 -17
  105. data/lib/sequel/extensions/select_remove.rb +0 -4
  106. data/lib/sequel/extensions/set_overrides.rb +28 -0
  107. data/lib/sequel/extensions/to_dot.rb +6 -10
  108. data/lib/sequel/model.rb +6 -7
  109. data/lib/sequel/model/associations.rb +127 -182
  110. data/lib/sequel/model/base.rb +88 -211
  111. data/lib/sequel/model/errors.rb +0 -13
  112. data/lib/sequel/model/plugins.rb +2 -2
  113. data/lib/sequel/no_core_ext.rb +0 -1
  114. data/lib/sequel/plugins/after_initialize.rb +11 -17
  115. data/lib/sequel/plugins/association_autoreloading.rb +1 -47
  116. data/lib/sequel/plugins/association_dependencies.rb +2 -2
  117. data/lib/sequel/plugins/auto_validations.rb +2 -8
  118. data/lib/sequel/plugins/blacklist_security.rb +32 -2
  119. data/lib/sequel/plugins/caching.rb +1 -1
  120. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  121. data/lib/sequel/plugins/composition.rb +10 -8
  122. data/lib/sequel/plugins/constraint_validations.rb +2 -2
  123. data/lib/sequel/plugins/dataset_associations.rb +4 -0
  124. data/lib/sequel/plugins/defaults_setter.rb +8 -6
  125. data/lib/sequel/plugins/dirty.rb +6 -6
  126. data/lib/sequel/plugins/force_encoding.rb +13 -8
  127. data/lib/sequel/plugins/hook_class_methods.rb +1 -7
  128. data/lib/sequel/plugins/json_serializer.rb +13 -74
  129. data/lib/sequel/plugins/lazy_attributes.rb +2 -4
  130. data/lib/sequel/plugins/list.rb +1 -1
  131. data/lib/sequel/plugins/many_through_many.rb +4 -11
  132. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
  133. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  134. data/lib/sequel/plugins/optimistic_locking.rb +3 -5
  135. data/lib/sequel/plugins/pg_array_associations.rb +453 -0
  136. data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
  137. data/lib/sequel/plugins/prepared_statements.rb +1 -1
  138. data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
  139. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
  140. data/lib/sequel/plugins/rcte_tree.rb +1 -1
  141. data/lib/sequel/plugins/serialization.rb +5 -4
  142. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  143. data/lib/sequel/plugins/sharding.rb +7 -1
  144. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  145. data/lib/sequel/plugins/timestamps.rb +1 -1
  146. data/lib/sequel/plugins/touch.rb +2 -2
  147. data/lib/sequel/plugins/tree.rb +1 -1
  148. data/lib/sequel/plugins/typecast_on_load.rb +19 -4
  149. data/lib/sequel/plugins/validation_class_methods.rb +0 -30
  150. data/lib/sequel/plugins/validation_helpers.rb +13 -31
  151. data/lib/sequel/plugins/xml_serializer.rb +18 -57
  152. data/lib/sequel/sql.rb +20 -22
  153. data/lib/sequel/version.rb +2 -2
  154. data/spec/adapters/db2_spec.rb +14 -23
  155. data/spec/adapters/firebird_spec.rb +25 -29
  156. data/spec/adapters/informix_spec.rb +11 -14
  157. data/spec/adapters/mssql_spec.rb +71 -77
  158. data/spec/adapters/mysql_spec.rb +165 -172
  159. data/spec/adapters/oracle_spec.rb +36 -39
  160. data/spec/adapters/postgres_spec.rb +175 -100
  161. data/spec/adapters/spec_helper.rb +13 -11
  162. data/spec/adapters/sqlite_spec.rb +36 -44
  163. data/spec/core/connection_pool_spec.rb +2 -1
  164. data/spec/core/database_spec.rb +55 -55
  165. data/spec/core/dataset_spec.rb +45 -249
  166. data/spec/core/deprecated_spec.rb +0 -8
  167. data/spec/core/expression_filters_spec.rb +23 -5
  168. data/spec/core/object_graph_spec.rb +4 -66
  169. data/spec/core/schema_spec.rb +35 -12
  170. data/spec/core/spec_helper.rb +3 -2
  171. data/spec/core_extensions_spec.rb +17 -19
  172. data/spec/extensions/arbitrary_servers_spec.rb +2 -3
  173. data/spec/extensions/association_dependencies_spec.rb +14 -14
  174. data/spec/extensions/auto_validations_spec.rb +7 -0
  175. data/spec/extensions/blacklist_security_spec.rb +5 -5
  176. data/spec/extensions/blank_spec.rb +2 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +2 -2
  178. data/spec/extensions/columns_introspection_spec.rb +2 -29
  179. data/spec/extensions/composition_spec.rb +10 -17
  180. data/spec/extensions/core_refinements_spec.rb +5 -1
  181. data/spec/extensions/dataset_associations_spec.rb +18 -0
  182. data/spec/extensions/date_arithmetic_spec.rb +2 -2
  183. data/spec/extensions/defaults_setter_spec.rb +9 -9
  184. data/spec/extensions/dirty_spec.rb +0 -5
  185. data/spec/extensions/eval_inspect_spec.rb +2 -0
  186. data/spec/extensions/force_encoding_spec.rb +2 -18
  187. data/spec/extensions/hash_aliases_spec.rb +8 -0
  188. data/spec/extensions/hook_class_methods_spec.rb +39 -58
  189. data/spec/extensions/inflector_spec.rb +2 -0
  190. data/spec/extensions/instance_filters_spec.rb +8 -8
  191. data/spec/extensions/json_serializer_spec.rb +1 -41
  192. data/spec/extensions/list_spec.rb +1 -1
  193. data/spec/extensions/many_through_many_spec.rb +106 -109
  194. data/spec/extensions/migration_spec.rb +2 -0
  195. data/spec/extensions/named_timezones_spec.rb +1 -0
  196. data/spec/extensions/pg_array_associations_spec.rb +603 -0
  197. data/spec/extensions/pg_array_ops_spec.rb +25 -0
  198. data/spec/extensions/pg_array_spec.rb +9 -1
  199. data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
  200. data/spec/extensions/pg_hstore_spec.rb +1 -0
  201. data/spec/extensions/pg_json_ops_spec.rb +131 -0
  202. data/spec/extensions/pg_json_spec.rb +10 -4
  203. data/spec/extensions/pg_range_ops_spec.rb +2 -5
  204. data/spec/extensions/pg_range_spec.rb +6 -2
  205. data/spec/extensions/pg_row_ops_spec.rb +2 -0
  206. data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
  207. data/spec/extensions/rcte_tree_spec.rb +15 -15
  208. data/spec/extensions/schema_dumper_spec.rb +0 -1
  209. data/spec/extensions/schema_spec.rb +9 -9
  210. data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
  211. data/spec/extensions/serialization_spec.rb +18 -29
  212. data/spec/extensions/set_overrides_spec.rb +4 -0
  213. data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
  214. data/spec/extensions/single_table_inheritance_spec.rb +4 -4
  215. data/spec/extensions/spec_helper.rb +8 -9
  216. data/spec/extensions/sql_expr_spec.rb +2 -0
  217. data/spec/extensions/string_date_time_spec.rb +2 -0
  218. data/spec/extensions/string_stripper_spec.rb +2 -0
  219. data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
  220. data/spec/extensions/thread_local_timezones_spec.rb +2 -0
  221. data/spec/extensions/timestamps_spec.rb +1 -1
  222. data/spec/extensions/to_dot_spec.rb +1 -1
  223. data/spec/extensions/touch_spec.rb +24 -24
  224. data/spec/extensions/tree_spec.rb +7 -7
  225. data/spec/extensions/typecast_on_load_spec.rb +8 -1
  226. data/spec/extensions/update_primary_key_spec.rb +10 -10
  227. data/spec/extensions/validation_class_methods_spec.rb +10 -39
  228. data/spec/extensions/validation_helpers_spec.rb +29 -47
  229. data/spec/extensions/xml_serializer_spec.rb +1 -23
  230. data/spec/integration/associations_test.rb +231 -40
  231. data/spec/integration/database_test.rb +1 -1
  232. data/spec/integration/dataset_test.rb +64 -64
  233. data/spec/integration/eager_loader_test.rb +28 -28
  234. data/spec/integration/migrator_test.rb +1 -1
  235. data/spec/integration/model_test.rb +2 -2
  236. data/spec/integration/plugin_test.rb +21 -21
  237. data/spec/integration/prepared_statement_test.rb +7 -7
  238. data/spec/integration/schema_test.rb +115 -110
  239. data/spec/integration/spec_helper.rb +17 -27
  240. data/spec/integration/timezone_test.rb +1 -1
  241. data/spec/integration/transaction_test.rb +10 -10
  242. data/spec/integration/type_test.rb +2 -2
  243. data/spec/model/association_reflection_spec.rb +2 -28
  244. data/spec/model/associations_spec.rb +239 -188
  245. data/spec/model/base_spec.rb +27 -68
  246. data/spec/model/dataset_methods_spec.rb +4 -4
  247. data/spec/model/eager_loading_spec.rb +160 -172
  248. data/spec/model/hooks_spec.rb +62 -79
  249. data/spec/model/model_spec.rb +36 -51
  250. data/spec/model/plugins_spec.rb +5 -19
  251. data/spec/model/record_spec.rb +125 -151
  252. data/spec/model/spec_helper.rb +8 -6
  253. data/spec/model/validations_spec.rb +4 -17
  254. data/spec/spec_config.rb +2 -10
  255. metadata +50 -56
  256. data/lib/sequel/deprecated_core_extensions.rb +0 -135
  257. data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
  258. data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
  259. data/lib/sequel/plugins/identity_map.rb +0 -260
  260. data/lib/sequel_core.rb +0 -2
  261. data/lib/sequel_model.rb +0 -2
  262. data/spec/extensions/association_autoreloading_spec.rb +0 -102
  263. data/spec/extensions/identity_map_spec.rb +0 -337
  264. data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
  265. data/spec/extensions/pg_statement_cache_spec.rb +0 -208
  266. data/spec/rcov.opts +0 -8
  267. data/spec/spec_config.rb.example +0 -10
@@ -12,16 +12,6 @@ module Sequel
12
12
  # (default: not set, so all columns not otherwise restricted are allowed).
13
13
  attr_reader :allowed_columns
14
14
 
15
- # REMOVE40
16
- def cache_anonymous_models
17
- Sequel::Deprecation.deprecate('Model.cache_anonymous_models', 'Please switch to Sequel.cache_anonymous_models')
18
- Sequel.cache_anonymous_models
19
- end
20
- def cache_anonymous_models=(v)
21
- Sequel::Deprecation.deprecate('Model.cache_anonymous_models=', 'Please switch to Sequel.cache_anonymous_models=')
22
- Sequel.cache_anonymous_models = v
23
- end
24
-
25
15
  # Array of modules that extend this model's dataset. Stored
26
16
  # so that if the model's dataset is changed, it will be extended
27
17
  # with all of these modules.
@@ -68,15 +58,6 @@ module Sequel
68
58
  # Sequel will not check the number of rows modified (default: true).
69
59
  attr_accessor :require_modification
70
60
 
71
- # REMOVE40
72
- def restricted_columns
73
- Sequel::Deprecation.deprecate('Model.restricted_columns', 'Please load the blacklist_security plugin to continue using it')
74
- @restricted_columns
75
- end
76
- def _restricted_columns
77
- @restricted_columns
78
- end
79
-
80
61
  # Should be the literal primary key column name if this Model's table has a simple primary key, or
81
62
  # nil if the model has a compound primary key or no primary key.
82
63
  attr_reader :simple_pk
@@ -135,8 +116,7 @@ module Sequel
135
116
  # probably should not be used by external code.
136
117
  def call(values)
137
118
  o = allocate
138
- o.set_values(values)
139
- o.after_initialize
119
+ o.instance_variable_set(:@values, values)
140
120
  o
141
121
  end
142
122
 
@@ -351,8 +331,6 @@ module Sequel
351
331
  # may contain setter methods.
352
332
  def include(mod)
353
333
  clear_setter_methods_cache
354
- check_deprecated_after_initialize(mod.instance_methods) unless allowed_after_initialize_implementation?(mod)
355
- Sequel::Deprecation.deprecate('Model#set_values', 'Please override Model.call, Model#_refresh_set_values, and/or Model#_create_set_values depending on the type of behavior you want to change') if mod.public_instance_methods.map{|x| x.to_s}.include?('set_values') && mod.name.to_s !~ /\ASequel::(Model|Model::Associations|Plugins::(ForceEncoding|Serialization|TypecastOnLoad|Composition|PreparedStatementsSafe|Dirty|PgTypecastOnLoad))::InstanceMethods\z/
356
334
  super
357
335
  end
358
336
 
@@ -416,8 +394,6 @@ module Sequel
416
394
  # Clear the setter_methods cache when a setter method is added
417
395
  def method_added(meth)
418
396
  clear_setter_methods_cache if meth.to_s =~ SETTER_METHOD_REGEXP
419
- check_deprecated_after_initialize(meth)
420
- Sequel::Deprecation.deprecate('Model#set_values', 'Please override Model.call, Model#_refresh_set_values, and/or Model#_create_set_values depending on the type of behavior you want to change') if meth.to_s == 'set_values'
421
397
  super
422
398
  end
423
399
 
@@ -442,19 +418,10 @@ module Sequel
442
418
  unless @plugins.include?(m)
443
419
  @plugins << m
444
420
  m.apply(self, *args, &block) if m.respond_to?(:apply)
421
+ extend(m::ClassMethods) if plugin_module_defined?(m, :ClassMethods)
445
422
  include(m::InstanceMethods) if plugin_module_defined?(m, :InstanceMethods)
446
- extend(m::ClassMethods)if plugin_module_defined?(m, :ClassMethods)
447
423
  if plugin_module_defined?(m, :DatasetMethods)
448
424
  dataset_extend(m::DatasetMethods, :create_class_methods=>false)
449
- # REMOVE40
450
- m::DatasetMethods.public_instance_methods.each do |meth|
451
- unless respond_to?(meth, true)
452
- (class << self; self; end).send(:define_method, meth) do |*args, &block|
453
- Sequel::Deprecation.deprecate('Automatically defining Model class methods for plugin public dataset methods', "Please modify the plugin to use Plugins.def_dataset_method for #{meth}")
454
- dataset.send(meth, *args, &block)
455
- end
456
- end
457
- end
458
425
  end
459
426
  end
460
427
  m.configure(self, *args, &block) if m.respond_to?(:configure)
@@ -543,7 +510,7 @@ module Sequel
543
510
  # Note that you should not use this to change the model's dataset
544
511
  # at runtime. If you have that need, you should look into Sequel's
545
512
  # sharding support.
546
- def set_dataset(ds, opts={})
513
+ def set_dataset(ds, opts=OPTS)
547
514
  inherited = opts[:inherited]
548
515
  case ds
549
516
  when Symbol, SQL::Identifier, SQL::QualifiedIdentifier, SQL::AliasedExpression, LiteralString
@@ -588,51 +555,22 @@ module Sequel
588
555
  # # composite key
589
556
  # set_primary_key [:taggable_id, :tag_id]
590
557
  # end
591
- def set_primary_key(*key)
592
- Sequel::Deprecation.deprecate('Calling set_primary_key without arguments is deprecated and will raise an exception in Sequel 4. Please use no_primary_key to mark the model as not having a primary key.') if key.length == 0
593
- Sequel::Deprecation.deprecate('Calling set_primary_key with multiple arguments is deprecated and will raise an exception in Sequel 4. Please pass an array of keys to setup a composite primary key.') if key.length > 1
594
-
558
+ def set_primary_key(key)
595
559
  clear_setter_methods_cache
596
- key = key.flatten
597
- self.simple_pk = if key.length == 1
598
- (@dataset || db).literal(key.first)
599
- else
600
- nil
560
+ if key.is_a?(Array) && key.length < 2
561
+ key = key.first
601
562
  end
602
- @primary_key = (key.length == 1) ? key[0] : key
563
+ self.simple_pk = if key && !key.is_a?(Array)
564
+ (@dataset || db).literal(key)
565
+ end
566
+ @primary_key = key
603
567
  end
604
568
 
605
- # Set the columns to restrict when using mass assignment (e.g. +set+). Using this means that
606
- # attempts to call setter methods for the columns listed here will cause an
607
- # exception or be silently skipped (based on the +strict_param_setting+ setting).
608
- # If you have any virtual setter methods (methods that end in =) that you
609
- # want not to be used during mass assignment, they need to be listed here as well (without the =).
610
- #
611
- # It's generally a bad idea to rely on a blacklist approach for security. Using a whitelist
612
- # approach such as set_allowed_columns or the instance level set_only or set_fields methods
613
- # is usually a better choice. So use of this method is generally a bad idea.
614
- #
615
- # Artist.set_restricted_columns(:records_sold)
616
- # Artist.set(:name=>'Bob', :hometown=>'Sactown') # No Error
617
- # Artist.set(:name=>'Bob', :records_sold=>30000) # Error
618
- def set_restricted_columns(*cols)
619
- clear_setter_methods_cache
620
- Sequel::Deprecation.deprecate('Model.set_restricted_columns', 'Please switch to Model.set_allowed_columns or use the blacklist_security plugin')
621
- @restricted_columns = cols
622
- end
623
-
624
569
  # Cache of setter methods to allow by default, in order to speed up new/set/update instance methods.
625
570
  def setter_methods
626
- @setter_methods ||= if allowed_columns
627
- allowed_columns.map{|x| "#{x}="}
628
- else
629
- meths = instance_methods.collect{|x| x.to_s}.grep(SETTER_METHOD_REGEXP) - RESTRICTED_SETTER_METHODS
630
- meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && restrict_primary_key?
631
- meths -= _restricted_columns.map{|x| "#{x}="} if _restricted_columns
632
- meths
633
- end
571
+ @setter_methods ||= get_setter_methods
634
572
  end
635
-
573
+
636
574
  # Sets up a dataset method that returns a filtered dataset.
637
575
  # Sometimes thought of as a scope, and like most dataset methods,
638
576
  # they can be chained.
@@ -692,24 +630,6 @@ module Sequel
692
630
 
693
631
  # Add model methods that call dataset methods
694
632
  Plugins.def_dataset_methods(self, DATASET_METHODS)
695
-
696
- # REMOVE40
697
- %w'print each_page set add_graph_aliases insert_multiple query set_overrides set_defaults to_csv paginate'.each do |meth|
698
- class_eval(<<-END, __FILE__, __LINE__+1)
699
- def #{meth}(*args, &block)
700
- Sequel::Deprecation.deprecate('Model.#{meth}', 'Please use Model.dataset.#{meth} instead')
701
- dataset.#{meth}(*args, &block)
702
- end
703
- END
704
- end
705
- %w'destroy delete update'.each do |meth|
706
- class_eval(<<-END, __FILE__, __LINE__+1)
707
- def #{meth}(*args, &block)
708
- Sequel::Deprecation.deprecate('Model.#{meth}', 'Please use the scissors plugin or Model.dataset.#{meth} instead')
709
- dataset.#{meth}(*args, &block)
710
- end
711
- END
712
- end
713
633
 
714
634
  private
715
635
 
@@ -724,22 +644,10 @@ module Sequel
724
644
  end
725
645
  end
726
646
 
727
- # REMOVE40
728
- def allowed_after_initialize_implementation?(mod)
729
- mod == InstanceMethods || mod.to_s == 'Sequel::Plugins::HookClassMethods::InstanceMethods'
730
- end
731
-
732
- # REMOVE40
733
- def check_deprecated_after_initialize(meths)
734
- Array(meths).each do |meth|
735
- Sequel::Deprecation.deprecate('The Model after_initialize hook', 'Please use the after_initialize plugin to continue using the hook') if meth.to_s == 'after_initialize'
736
- end
737
- end
738
-
739
647
  # Add the module to the class's dataset_method_modules. Extend the dataset with the
740
648
  # module if the model has a dataset. Add dataset methods to the class for all
741
649
  # public dataset methods.
742
- def dataset_extend(mod, opts={})
650
+ def dataset_extend(mod, opts=OPTS)
743
651
  @dataset.extend(mod) if @dataset
744
652
  reset_instance_dataset
745
653
  dataset_method_modules << mod
@@ -827,6 +735,18 @@ module Sequel
827
735
  schema_hash
828
736
  end
829
737
 
738
+ # Uncached version of setter_methods, to be overridden by plugins
739
+ # that want to modify the methods used.
740
+ def get_setter_methods
741
+ if allowed_columns
742
+ allowed_columns.map{|x| "#{x}="}
743
+ else
744
+ meths = instance_methods.collect{|x| x.to_s}.grep(SETTER_METHOD_REGEXP) - RESTRICTED_SETTER_METHODS
745
+ meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && restrict_primary_key?
746
+ meths
747
+ end
748
+ end
749
+
830
750
  # A hash of instance variables to automatically set up in subclasses.
831
751
  # See Sequel::Model::INHERITED_INSTANCE_VARIABLES. It is safe to modify
832
752
  # the hash returned by this method, though it may not be safe to modify
@@ -971,18 +891,6 @@ module Sequel
971
891
  HOOKS.each{|h| class_eval("def #{h}; end", __FILE__, __LINE__)}
972
892
  AROUND_HOOKS.each{|h| class_eval("def #{h}; yield end", __FILE__, __LINE__)}
973
893
 
974
- # REMOVE40
975
- def self.class_attr_overridable(*meths) # :nodoc:
976
- Sequel::Deprecation.deprecate('Model::InstanceMethods.class_attr_overridable', "There is no replacement planned")
977
- meths.each{|meth| class_eval("def #{meth}; !defined?(@#{meth}) ? (frozen? ? self.class.#{meth} : (@#{meth} = self.class.#{meth})) : @#{meth} end", __FILE__, __LINE__)}
978
- attr_writer(*meths)
979
- end
980
- def self.class_attr_reader(*meths) # :nodoc:
981
- Sequel::Deprecation.deprecate('Model::InstanceMethods.class_attr_reader', "There is no replacement planned")
982
- meths.each{|meth| class_eval("def #{meth}; self.class.#{meth} end", __FILE__, __LINE__)}
983
- end
984
- private_class_method :class_attr_overridable, :class_attr_reader
985
-
986
894
  # Define instance method(s) that calls class method(s) of the
987
895
  # same name. Replaces the construct:
988
896
  #
@@ -1006,8 +914,6 @@ module Sequel
1006
914
  # Creates new instance and passes the given values to set.
1007
915
  # If a block is given, yield the instance to the block unless
1008
916
  # from_db is true.
1009
- # This method runs the after_initialize hook after
1010
- # it has optionally yielded itself to the block.
1011
917
  #
1012
918
  # Arguments:
1013
919
  # values :: should be a hash to pass to set.
@@ -1018,19 +924,13 @@ module Sequel
1018
924
  # Artist.new do |a|
1019
925
  # a.name = 'Bob'
1020
926
  # end
1021
- def initialize(values = {}, from_db = false)
1022
- if from_db
1023
- Sequel::Deprecation.deprecate('Passing two arguments to Model.new', 'Please use Model.call instead')
1024
- set_values(values)
1025
- else
1026
- @values = {}
1027
- @new = true
1028
- @modified = true
1029
- initialize_set(values)
1030
- changed_columns.clear
1031
- yield self if block_given?
1032
- end
1033
- after_initialize
927
+ def initialize(values = {})
928
+ @values = {}
929
+ @new = true
930
+ @modified = true
931
+ initialize_set(values)
932
+ changed_columns.clear
933
+ yield self if block_given?
1034
934
  end
1035
935
 
1036
936
  # Returns value of the column's attribute.
@@ -1121,7 +1021,7 @@ module Sequel
1121
1021
  #
1122
1022
  # Artist[1].destroy # BEGIN; DELETE FROM artists WHERE (id = 1); COMMIT;
1123
1023
  # # => #<Artist {:id=>1, ...}>
1124
- def destroy(opts = {})
1024
+ def destroy(opts = OPTS)
1125
1025
  raise Sequel::Error, "can't destroy frozen object" if frozen?
1126
1026
  checked_save_failure(opts){checked_transaction(opts){_destroy(opts)}}
1127
1027
  end
@@ -1373,13 +1273,8 @@ module Sequel
1373
1273
  # :transaction :: set to true or false to override the current
1374
1274
  # +use_transactions+ setting
1375
1275
  # :validate :: set to false to skip validation
1376
- def save(*columns)
1276
+ def save(opts=OPTS)
1377
1277
  raise Sequel::Error, "can't save frozen object" if frozen?
1378
- opts = columns.last.is_a?(Hash) ? columns.pop : {}
1379
-
1380
- Sequel::Deprecation.deprecate('Passing columns as separate arguments to Model#save', 'Instead, provide a :columns option with the array of columns to save.') unless columns.empty?
1381
- columns.concat(Array(opts[:columns])) if opts[:columns]
1382
-
1383
1278
  set_server(opts[:server]) if opts[:server]
1384
1279
  if opts[:validate] != false
1385
1280
  unless checked_save_failure(opts){_valid?(true, opts)}
@@ -1387,7 +1282,7 @@ module Sequel
1387
1282
  return
1388
1283
  end
1389
1284
  end
1390
- checked_save_failure(opts){checked_transaction(opts){_save(columns, opts)}}
1285
+ checked_save_failure(opts){checked_transaction(opts){_save(opts)}}
1391
1286
  end
1392
1287
 
1393
1288
  # Saves only changed columns if the object has been modified.
@@ -1399,7 +1294,7 @@ module Sequel
1399
1294
  # a.name = 'Jim'
1400
1295
  # a.save_changes # UPDATE artists SET name = 'Bob' WHERE (id = 1)
1401
1296
  # # => #<Artist {:id=>1, :name=>'Jim', ...}
1402
- def save_changes(opts={})
1297
+ def save_changes(opts=OPTS)
1403
1298
  save(opts.merge(:changed=>true)) || false if modified?
1404
1299
  end
1405
1300
 
@@ -1411,7 +1306,7 @@ module Sequel
1411
1306
  # artist.set(:name=>'Jim')
1412
1307
  # artist.name # => 'Jim'
1413
1308
  def set(hash)
1414
- set_restricted(hash, nil, nil)
1309
+ set_restricted(hash, :default)
1415
1310
  end
1416
1311
 
1417
1312
  # Set all values using the entries in the hash, ignoring any setting of
@@ -1421,18 +1316,7 @@ module Sequel
1421
1316
  # artist.set_all(:name=>'Jim')
1422
1317
  # artist.name # => 'Jim'
1423
1318
  def set_all(hash)
1424
- set_restricted(hash, false, false)
1425
- end
1426
-
1427
- # Set all values using the entries in the hash, except for the keys
1428
- # given in except. You should probably use +set_fields+ or +set_only+
1429
- # instead of this method, as blacklist approaches to security are a bad idea.
1430
- #
1431
- # artist.set_except({:name=>'Jim'}, :hometown)
1432
- # artist.name # => 'Jim'
1433
- def set_except(hash, *except)
1434
- Sequel::Deprecation.deprecate('Model#set_except', 'Please switch to Model#set_only or use the blacklist_security plugin')
1435
- set_restricted(hash, false, except.flatten)
1319
+ set_restricted(hash, :all)
1436
1320
  end
1437
1321
 
1438
1322
  # For each of the fields in the given array +fields+, call the setter
@@ -1502,7 +1386,7 @@ module Sequel
1502
1386
  #
1503
1387
  # artist.set_only({:hometown=>'LA'}, :name) # Raise Error
1504
1388
  def set_only(hash, *only)
1505
- set_restricted(hash, only.flatten, false)
1389
+ set_restricted(hash, only.flatten)
1506
1390
  end
1507
1391
 
1508
1392
  # Set the shard that this object is tied to. Returns self.
@@ -1512,10 +1396,9 @@ module Sequel
1512
1396
  self
1513
1397
  end
1514
1398
 
1515
- # Replace the current values with hash. Should definitely not be
1516
- # used with untrusted input, and should probably not be called
1517
- # directly by user code.
1399
+ # REMOVE41
1518
1400
  def set_values(hash)
1401
+ Sequel::Deprecation.deprecate('Model#set_values is deprecreated and will be removed in Sequel 4.1. Please use _refresh_set_values or _save_set_values or set the values directly.')
1519
1402
  @values = hash
1520
1403
  end
1521
1404
 
@@ -1537,7 +1420,7 @@ module Sequel
1537
1420
  #
1538
1421
  # artist.update(:name=>'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
1539
1422
  def update(hash)
1540
- update_restricted(hash, nil, nil)
1423
+ update_restricted(hash, :default)
1541
1424
  end
1542
1425
 
1543
1426
  # Update all values using the entries in the hash, ignoring any setting of
@@ -1546,17 +1429,7 @@ module Sequel
1546
1429
  # Artist.set_allowed_columns(:num_albums)
1547
1430
  # artist.update_all(:name=>'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
1548
1431
  def update_all(hash)
1549
- update_restricted(hash, false, false)
1550
- end
1551
-
1552
- # Update all values using the entries in the hash, except for the keys
1553
- # given in except. You should probably use +update_fields+ or +update_only+
1554
- # instead of this method, as blacklist approaches to security are a bad idea.
1555
- #
1556
- # artist.update_except({:name=>'Jim'}, :hometown) # UPDATE artists SET name = 'Jim' WHERE (id = 1)
1557
- def update_except(hash, *except)
1558
- Sequel::Deprecation.deprecate('Model#update_except', 'Please switch to Model#update_only or use the blacklist_security plugin')
1559
- update_restricted(hash, false, except.flatten)
1432
+ update_restricted(hash, :all)
1560
1433
  end
1561
1434
 
1562
1435
  # Update the instances values by calling +set_fields+ with the arguments, then
@@ -1581,7 +1454,7 @@ module Sequel
1581
1454
  #
1582
1455
  # artist.update_only({:hometown=>'LA'}, :name) # Raise Error
1583
1456
  def update_only(hash, *only)
1584
- update_restricted(hash, only.flatten, false)
1457
+ update_restricted(hash, only.flatten)
1585
1458
  end
1586
1459
 
1587
1460
  # Validates the object. If the object is invalid, errors should be added
@@ -1598,7 +1471,7 @@ module Sequel
1598
1471
  # artist(:name=>'Valid').valid? # => true
1599
1472
  # artist(:name=>'Invalid').valid? # => false
1600
1473
  # artist.errors.full_messages # => ['name cannot be Invalid']
1601
- def valid?(opts = {})
1474
+ def valid?(opts = OPTS)
1602
1475
  _valid?(false, opts)
1603
1476
  end
1604
1477
 
@@ -1660,7 +1533,7 @@ module Sequel
1660
1533
  def _insert
1661
1534
  ds = _insert_dataset
1662
1535
  if !ds.opts[:select] and ds.supports_insert_select? and h = _insert_select_raw(ds)
1663
- set_values(h)
1536
+ _save_set_values(h)
1664
1537
  nil
1665
1538
  else
1666
1539
  iid = _insert_raw(ds)
@@ -1692,7 +1565,7 @@ module Sequel
1692
1565
  # Refresh using a particular dataset, used inside save to make sure the same server
1693
1566
  # is used for reading newly inserted values from the database
1694
1567
  def _refresh(dataset)
1695
- set_values(_refresh_get(dataset) || raise(Error, "Record not found"))
1568
+ _refresh_set_values(_refresh_get(dataset) || raise(Error, "Record not found"))
1696
1569
  changed_columns.clear
1697
1570
  end
1698
1571
 
@@ -1701,9 +1574,14 @@ module Sequel
1701
1574
  dataset.first
1702
1575
  end
1703
1576
 
1577
+ # Set the refreshed values after
1578
+ def _refresh_set_values(h)
1579
+ @values = h
1580
+ end
1581
+
1704
1582
  # Internal version of save, split from save to allow running inside
1705
1583
  # it's own transaction.
1706
- def _save(columns, opts)
1584
+ def _save(opts)
1707
1585
  sh = {:server=>this_server}
1708
1586
  db.after_rollback(sh){after_rollback} if uacr = use_after_commit_rollback
1709
1587
  was_new = false
@@ -1730,7 +1608,8 @@ module Sequel
1730
1608
  around_update do
1731
1609
  called_cu = true
1732
1610
  raise_hook_failure(:before_update) if before_update == false
1733
- if columns.empty?
1611
+ columns = opts[:columns]
1612
+ if columns.nil?
1734
1613
  @columns_updated = if opts[:changed]
1735
1614
  @values.reject{|k,v| !changed_columns.include?(k)}
1736
1615
  else
@@ -1738,6 +1617,7 @@ module Sequel
1738
1617
  end
1739
1618
  changed_columns.clear
1740
1619
  else # update only the specified columns
1620
+ columns = Array(columns)
1741
1621
  @columns_updated = @values.reject{|k, v| !columns.include?(k)}
1742
1622
  changed_columns.reject!{|c| columns.include?(c)}
1743
1623
  end
@@ -1767,7 +1647,14 @@ module Sequel
1767
1647
  # default values of all columns. Separated from _save so it
1768
1648
  # can be overridden to avoid the refresh.
1769
1649
  def _save_refresh
1770
- _refresh(this.opts[:server] ? this : this.server(:default))
1650
+ _save_set_values(_refresh_get(this.opts[:server] ? this : this.server(:default)) || raise(Error, "Record not found"))
1651
+ changed_columns.clear
1652
+ end
1653
+
1654
+ # Set values to the provided hash. Called after a create,
1655
+ # to set the full values from the database in the model instance.
1656
+ def _save_set_values(h)
1657
+ @values = h
1771
1658
  end
1772
1659
 
1773
1660
  # Return a hash of values used when saving all columns of an
@@ -1858,7 +1745,7 @@ module Sequel
1858
1745
  end
1859
1746
 
1860
1747
  # If transactions should be used, wrap the yield in a transaction block.
1861
- def checked_transaction(opts={})
1748
+ def checked_transaction(opts=OPTS)
1862
1749
  use_transaction?(opts) ? db.transaction({:server=>this_server}.merge(opts)){yield} : yield
1863
1750
  end
1864
1751
 
@@ -1907,14 +1794,11 @@ module Sequel
1907
1794
  end
1908
1795
  end
1909
1796
 
1910
- # Set the columns, filtered by the only and except arrays.
1911
- def set_restricted(hash, only, except)
1797
+ # Call setter methods based on keys in hash, with the appropriate values.
1798
+ # Restrict which methods can be called based on the provided type.
1799
+ def set_restricted(hash, type)
1912
1800
  return self if hash.empty?
1913
- meths = if only.nil? && except.nil? && !@singleton_setter_added
1914
- model.setter_methods
1915
- else
1916
- setter_methods(only, except)
1917
- end
1801
+ meths = setter_methods(type)
1918
1802
  strict = strict_param_setting
1919
1803
  hash.each do |k,v|
1920
1804
  m = "#{k}="
@@ -1936,31 +1820,24 @@ module Sequel
1936
1820
  self
1937
1821
  end
1938
1822
 
1939
- # Returns all methods that can be used for attribute
1940
- # assignment (those that end with =), modified by the only
1941
- # and except arguments:
1942
- #
1943
- # * only
1944
- # * false - Don't modify the results
1945
- # * nil - if the model has allowed_columns, use only these, otherwise, don't modify
1946
- # * Array - allow only the given methods to be used
1947
- # * except
1948
- # * false - Don't modify the results
1949
- # * nil - if the model has restricted_columns, remove these, otherwise, don't modify
1950
- # * Array - remove the given methods
1951
- #
1952
- # only takes precedence over except, and if only is not used, certain methods are always
1953
- # restricted (RESTRICTED_SETTER_METHODS). The primary key is restricted by default as
1954
- # well, see Model.unrestrict_primary_key to change this.
1955
- def setter_methods(only, except)
1956
- only = only.nil? ? model.allowed_columns : only
1957
- except = except.nil? ? model._restricted_columns : except
1958
- if only
1959
- only.map{|x| "#{x}="}
1823
+ # Returns all methods that can be used for attribute assignment (those that end with =),
1824
+ # depending on the type:
1825
+ #
1826
+ # :default :: Use the default methods allowed in th model class.
1827
+ # :all :: Allow setting all setters, except those specifically restricted (such as ==).
1828
+ # Array :: Only allow setting of columns in the given array.
1829
+ def setter_methods(type)
1830
+ if type == :default
1831
+ if !@singleton_setter_added || model.allowed_columns
1832
+ return model.setter_methods
1833
+ end
1834
+ end
1835
+
1836
+ if type.is_a?(Array)
1837
+ type.map{|x| "#{x}="}
1960
1838
  else
1961
1839
  meths = methods.collect{|x| x.to_s}.grep(SETTER_METHOD_REGEXP) - RESTRICTED_SETTER_METHODS
1962
- meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && model.restrict_primary_key?
1963
- meths -= except.map{|x| "#{x}="} if except
1840
+ meths -= Array(primary_key).map{|x| "#{x}="} if type != :all && primary_key && model.restrict_primary_key?
1964
1841
  meths
1965
1842
  end
1966
1843
  end
@@ -1992,8 +1869,8 @@ module Sequel
1992
1869
  end
1993
1870
 
1994
1871
  # Set the columns, filtered by the only and except arrays.
1995
- def update_restricted(hash, only, except)
1996
- set_restricted(hash, only, except)
1872
+ def update_restricted(hash, type)
1873
+ set_restricted(hash, type)
1997
1874
  save_changes
1998
1875
  end
1999
1876
 
@@ -2005,7 +1882,7 @@ module Sequel
2005
1882
  # Whether to use a transaction for this action. If the :transaction
2006
1883
  # option is present in the hash, use that, otherwise, fallback to the
2007
1884
  # object's default (if set), or class's default (if not).
2008
- def use_transaction?(opts = {})
1885
+ def use_transaction?(opts = OPTS)
2009
1886
  opts.fetch(:transaction, use_transactions)
2010
1887
  end
2011
1888
  end