sequel 3.48.0 → 4.0.0

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