sequel 4.45.0 → 4.46.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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +108 -0
  3. data/doc/release_notes/4.46.0.txt +404 -0
  4. data/doc/security.rdoc +9 -0
  5. data/doc/sql.rdoc +2 -2
  6. data/doc/testing.rdoc +1 -1
  7. data/doc/validations.rdoc +1 -2
  8. data/lib/sequel/adapters/ado.rb +8 -3
  9. data/lib/sequel/adapters/ado/access.rb +8 -4
  10. data/lib/sequel/adapters/ado/mssql.rb +3 -1
  11. data/lib/sequel/adapters/amalgalite.rb +5 -0
  12. data/lib/sequel/adapters/cubrid.rb +16 -7
  13. data/lib/sequel/adapters/do.rb +7 -1
  14. data/lib/sequel/adapters/do/mysql.rb +8 -4
  15. data/lib/sequel/adapters/ibmdb.rb +10 -5
  16. data/lib/sequel/adapters/jdbc.rb +8 -2
  17. data/lib/sequel/adapters/jdbc/as400.rb +10 -3
  18. data/lib/sequel/adapters/jdbc/db2.rb +27 -16
  19. data/lib/sequel/adapters/jdbc/derby.rb +47 -20
  20. data/lib/sequel/adapters/jdbc/h2.rb +13 -7
  21. data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
  22. data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
  23. data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
  24. data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
  25. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
  26. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
  27. data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
  28. data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
  29. data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
  30. data/lib/sequel/adapters/mock.rb +5 -0
  31. data/lib/sequel/adapters/mysql.rb +8 -1
  32. data/lib/sequel/adapters/mysql2.rb +6 -1
  33. data/lib/sequel/adapters/odbc.rb +20 -8
  34. data/lib/sequel/adapters/odbc/mssql.rb +6 -3
  35. data/lib/sequel/adapters/oracle.rb +12 -6
  36. data/lib/sequel/adapters/postgres.rb +20 -8
  37. data/lib/sequel/adapters/shared/access.rb +76 -47
  38. data/lib/sequel/adapters/shared/cubrid.rb +16 -11
  39. data/lib/sequel/adapters/shared/db2.rb +46 -19
  40. data/lib/sequel/adapters/shared/firebird.rb +20 -8
  41. data/lib/sequel/adapters/shared/informix.rb +6 -3
  42. data/lib/sequel/adapters/shared/mssql.rb +132 -72
  43. data/lib/sequel/adapters/shared/mysql.rb +112 -65
  44. data/lib/sequel/adapters/shared/oracle.rb +36 -21
  45. data/lib/sequel/adapters/shared/postgres.rb +91 -56
  46. data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
  47. data/lib/sequel/adapters/shared/sqlite.rb +67 -32
  48. data/lib/sequel/adapters/sqlanywhere.rb +9 -1
  49. data/lib/sequel/adapters/sqlite.rb +8 -1
  50. data/lib/sequel/adapters/swift.rb +5 -0
  51. data/lib/sequel/adapters/swift/mysql.rb +4 -2
  52. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  53. data/lib/sequel/adapters/tinytds.rb +10 -3
  54. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  55. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  56. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
  57. data/lib/sequel/adapters/utils/pg_types.rb +14 -6
  58. data/lib/sequel/adapters/utils/replace.rb +4 -2
  59. data/lib/sequel/connection_pool/single.rb +2 -2
  60. data/lib/sequel/core.rb +24 -11
  61. data/lib/sequel/database/connecting.rb +9 -3
  62. data/lib/sequel/database/dataset_defaults.rb +7 -1
  63. data/lib/sequel/database/logging.rb +1 -0
  64. data/lib/sequel/database/misc.rb +5 -2
  65. data/lib/sequel/database/query.rb +7 -5
  66. data/lib/sequel/database/schema_generator.rb +1 -0
  67. data/lib/sequel/database/schema_methods.rb +50 -27
  68. data/lib/sequel/database/transactions.rb +19 -9
  69. data/lib/sequel/dataset/actions.rb +15 -6
  70. data/lib/sequel/dataset/graph.rb +15 -5
  71. data/lib/sequel/dataset/misc.rb +12 -4
  72. data/lib/sequel/dataset/mutation.rb +17 -8
  73. data/lib/sequel/dataset/prepared_statements.rb +3 -2
  74. data/lib/sequel/dataset/query.rb +84 -38
  75. data/lib/sequel/dataset/sql.rb +302 -191
  76. data/lib/sequel/deprecated.rb +26 -17
  77. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
  78. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  79. data/lib/sequel/extensions/from_block.rb +1 -0
  80. data/lib/sequel/extensions/graph_each.rb +1 -1
  81. data/lib/sequel/extensions/identifier_mangling.rb +2 -2
  82. data/lib/sequel/extensions/migration.rb +28 -4
  83. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
  84. data/lib/sequel/extensions/schema_dumper.rb +4 -4
  85. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
  86. data/lib/sequel/extensions/set_overrides.rb +2 -0
  87. data/lib/sequel/extensions/split_array_nil.rb +2 -2
  88. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  89. data/lib/sequel/model.rb +11 -7
  90. data/lib/sequel/model/associations.rb +5 -7
  91. data/lib/sequel/model/base.rb +47 -45
  92. data/lib/sequel/model/dataset_module.rb +9 -14
  93. data/lib/sequel/model/plugins.rb +3 -0
  94. data/lib/sequel/no_core_ext.rb +1 -0
  95. data/lib/sequel/plugins/blacklist_security.rb +1 -1
  96. data/lib/sequel/plugins/boolean_subsets.rb +7 -5
  97. data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
  98. data/lib/sequel/plugins/dataset_associations.rb +1 -1
  99. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  100. data/lib/sequel/plugins/finder.rb +240 -0
  101. data/lib/sequel/plugins/inverted_subsets.rb +19 -12
  102. data/lib/sequel/plugins/many_through_many.rb +1 -1
  103. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  104. data/lib/sequel/plugins/schema.rb +1 -1
  105. data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
  106. data/lib/sequel/plugins/subset_conditions.rb +11 -3
  107. data/lib/sequel/plugins/whitelist_security.rb +118 -0
  108. data/lib/sequel/sql.rb +80 -36
  109. data/lib/sequel/timezones.rb +2 -0
  110. data/lib/sequel/version.rb +1 -1
  111. data/spec/adapters/mssql_spec.rb +20 -0
  112. data/spec/adapters/mysql_spec.rb +1 -1
  113. data/spec/adapters/oracle_spec.rb +12 -8
  114. data/spec/adapters/postgres_spec.rb +1 -1
  115. data/spec/adapters/spec_helper.rb +1 -1
  116. data/spec/adapters/sqlite_spec.rb +36 -34
  117. data/spec/core/connection_pool_spec.rb +2 -1
  118. data/spec/core/database_spec.rb +87 -9
  119. data/spec/core/dataset_spec.rb +501 -129
  120. data/spec/core/deprecated_spec.rb +1 -1
  121. data/spec/core/expression_filters_spec.rb +146 -60
  122. data/spec/core/mock_adapter_spec.rb +1 -1
  123. data/spec/core/object_graph_spec.rb +61 -9
  124. data/spec/core/placeholder_literalizer_spec.rb +20 -2
  125. data/spec/core/schema_generator_spec.rb +6 -6
  126. data/spec/core/schema_spec.rb +54 -5
  127. data/spec/core_extensions_spec.rb +122 -18
  128. data/spec/deprecation_helper.rb +27 -2
  129. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
  130. data/spec/extensions/association_proxies_spec.rb +2 -2
  131. data/spec/extensions/auto_literal_strings_spec.rb +212 -0
  132. data/spec/extensions/blacklist_security_spec.rb +1 -0
  133. data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
  134. data/spec/extensions/column_select_spec.rb +20 -8
  135. data/spec/extensions/columns_introspection_spec.rb +3 -3
  136. data/spec/extensions/core_refinements_spec.rb +29 -12
  137. data/spec/extensions/dataset_associations_spec.rb +12 -12
  138. data/spec/extensions/def_dataset_method_spec.rb +100 -0
  139. data/spec/extensions/error_sql_spec.rb +1 -1
  140. data/spec/extensions/finder_spec.rb +260 -0
  141. data/spec/extensions/graph_each_spec.rb +2 -2
  142. data/spec/extensions/identifier_mangling_spec.rb +14 -8
  143. data/spec/extensions/inverted_subsets_spec.rb +4 -4
  144. data/spec/extensions/lazy_attributes_spec.rb +7 -0
  145. data/spec/extensions/many_through_many_spec.rb +38 -14
  146. data/spec/extensions/nested_attributes_spec.rb +18 -6
  147. data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
  148. data/spec/extensions/pg_enum_spec.rb +16 -1
  149. data/spec/extensions/pg_interval_spec.rb +11 -2
  150. data/spec/extensions/pg_loose_count_spec.rb +5 -0
  151. data/spec/extensions/pg_row_spec.rb +25 -0
  152. data/spec/extensions/prepared_statements_spec.rb +10 -1
  153. data/spec/extensions/query_spec.rb +2 -2
  154. data/spec/extensions/schema_dumper_spec.rb +2 -2
  155. data/spec/extensions/schema_spec.rb +2 -2
  156. data/spec/extensions/set_overrides_spec.rb +7 -3
  157. data/spec/extensions/sql_expr_spec.rb +0 -1
  158. data/spec/extensions/subset_conditions_spec.rb +6 -6
  159. data/spec/extensions/table_select_spec.rb +24 -12
  160. data/spec/extensions/to_dot_spec.rb +4 -4
  161. data/spec/extensions/whitelist_security_spec.rb +131 -0
  162. data/spec/integration/dataset_test.rb +9 -5
  163. data/spec/integration/model_test.rb +2 -0
  164. data/spec/integration/plugin_test.rb +2 -2
  165. data/spec/integration/spec_helper.rb +1 -1
  166. data/spec/model/associations_spec.rb +39 -11
  167. data/spec/model/base_spec.rb +44 -24
  168. data/spec/model/class_dataset_methods_spec.rb +18 -16
  169. data/spec/model/dataset_methods_spec.rb +4 -4
  170. data/spec/model/eager_loading_spec.rb +84 -24
  171. data/spec/model/model_spec.rb +97 -63
  172. data/spec/model/record_spec.rb +21 -13
  173. metadata +13 -2
@@ -141,7 +141,7 @@ module Sequel
141
141
  def apply_window_function_eager_limit_strategy(ds, limit_and_offset=limit_and_offset())
142
142
  rn = ds.row_number_column
143
143
  limit, offset = limit_and_offset
144
- ds = ds.unordered.select_append{|o| o.row_number{}.over(:partition=>predicate_key, :order=>ds.opts[:order]).as(rn)}.from_self
144
+ ds = ds.unordered.select_append{|o| o.row_number.function.over(:partition=>predicate_key, :order=>ds.opts[:order]).as(rn)}.from_self
145
145
  ds = if !returns_array?
146
146
  ds.where(rn => offset ? offset+1 : 1)
147
147
  elsif offset
@@ -694,14 +694,12 @@ module Sequel
694
694
  v = fetch(:filter_limit_strategy, self[:eager_limit_strategy])
695
695
  if v || self[:limit] || !returns_array?
696
696
  case v ||= self[:model].default_eager_limit_strategy
697
- when :union, :ruby
697
+ when true, :union, :ruby
698
698
  # Can't use a union or ruby-based strategy for filtering by associations, switch to default eager graph limit
699
699
  # strategy.
700
700
  true_eager_graph_limit_strategy
701
701
  when Symbol
702
702
  v
703
- when true
704
- true_eager_graph_limit_strategy
705
703
  end
706
704
  end
707
705
  end
@@ -2661,10 +2659,10 @@ END
2661
2659
  # types, this is a simple transformation, but for +many_to_many+ associations this
2662
2660
  # creates a subquery to the join table.
2663
2661
  def complex_expression_sql_append(sql, op, args)
2664
- r = args.at(1)
2662
+ r = args[1]
2665
2663
  if (((op == :'=' || op == :'!=') and r.is_a?(Sequel::Model)) ||
2666
2664
  (multiple = ((op == :IN || op == :'NOT IN') and ((is_ds = r.is_a?(Sequel::Dataset)) or r.all?{|x| x.is_a?(Sequel::Model)}))))
2667
- l = args.at(0)
2665
+ l = args[0]
2668
2666
  if ar = model.association_reflections[l]
2669
2667
  if multiple
2670
2668
  klass = ar.associated_class
@@ -3235,7 +3233,7 @@ END
3235
3233
  @records_map = records_map
3236
3234
 
3237
3235
  datasets = opts[:graph][:table_aliases].to_a.reject{|ta,ds| ds.nil?}
3238
- column_aliases = opts[:graph_aliases] || opts[:graph][:column_aliases]
3236
+ column_aliases = opts[:graph_aliases] || opts[:graph][:column_aliases] # SEQUEL5: Remove :graph_aliases support
3239
3237
  primary_keys = {}
3240
3238
  column_maps = {}
3241
3239
  models = {}
@@ -12,7 +12,7 @@ module Sequel
12
12
  module ClassMethods
13
13
  # Which columns should be the only columns allowed in a call to a mass assignment method (e.g. set)
14
14
  # (default: not set, so all columns not otherwise restricted are allowed).
15
- attr_reader :allowed_columns
15
+ attr_reader :allowed_columns # SEQUEL5: Deprecate after release
16
16
 
17
17
  # Whether to cache the anonymous models created by Sequel::Model(). This is
18
18
  # required for reloading them correctly (avoiding the superclass mismatch). True
@@ -238,7 +238,7 @@ module Sequel
238
238
  # # => #<Artist {:name=>'Bob', ...}>
239
239
  def [](*args)
240
240
  args = args.first if args.size <= 1
241
- args.is_a?(Hash) ? first_where(args) : (primary_key_lookup(args) unless args.nil?)
241
+ args.is_a?(Hash) ? first(args) : (primary_key_lookup(args) unless args.nil?)
242
242
  end
243
243
 
244
244
  # Initializes a model instance as an existing record. This constructor is
@@ -393,7 +393,10 @@ module Sequel
393
393
  # sharding support.
394
394
  def db=(db)
395
395
  @db = db
396
- set_dataset(db.dataset.clone(@dataset.opts)) if @dataset
396
+ if @dataset
397
+ Sequel::Deprecation.deprecate("Sequel::Model.db= when the model has an existing dataset", "Use Sequel::Model.dataset= instead")
398
+ set_dataset(db.dataset.clone(@dataset.opts))
399
+ end
397
400
  end
398
401
 
399
402
  # Returns the cached schema information if available or gets it
@@ -446,8 +449,10 @@ module Sequel
446
449
 
447
450
  if block
448
451
  raise(Error, "Defining a dataset method using a block requires only one argument") if args.length > 1
452
+ Sequel::Deprecation.deprecate("Sequel::Model.def_dataset_method", "Define the method inside a dataset_module block, or use the def_dataset_method_plugin")
449
453
  dataset_module{define_method(args.first, &block)}
450
454
  else
455
+ Sequel::Deprecation.deprecate("Sequel::Model.def_dataset_method", "Define a class method that calls the dataset method, or use the def_dataset_method_plugin")
451
456
  args.each{|arg| def_model_dataset_method(arg)}
452
457
  end
453
458
  end
@@ -461,12 +466,7 @@ module Sequel
461
466
  # Artist.find{name > 'M'}
462
467
  # # SELECT * FROM artists WHERE (name > 'M') LIMIT 1
463
468
  def find(*args, &block)
464
- if args.length == 1 && !block
465
- # Use optimized finder
466
- first_where(args.first)
467
- else
468
- where(*args, &block).first
469
- end
469
+ first(*args, &block)
470
470
  end
471
471
 
472
472
  # Like +find+ but invokes create with given conditions when record does not
@@ -484,7 +484,6 @@ module Sequel
484
484
  def find_or_create(cond, &block)
485
485
  find(cond) || create(cond, &block)
486
486
  end
487
-
488
487
 
489
488
  FINDER_TYPES = [:first, :all, :each, :get].freeze
490
489
 
@@ -544,6 +543,7 @@ module Sequel
544
543
  #
545
544
  # See Dataset::PlaceholderLiteralizer for additional caveats.
546
545
  def finder(meth=OPTS, opts=OPTS, &block)
546
+ Sequel::Deprecation.deprecate("Sequel::Model.finder and Sequel::Model.prepared_finder", "They have been moved to the finder plugin")
547
547
  if block
548
548
  raise Error, "cannot pass both a method name argument and a block of Model.finder" unless meth.is_a?(Hash)
549
549
  raise Error, "cannot pass two option hashes to Model.finder" unless opts.equal?(OPTS)
@@ -607,29 +607,21 @@ module Sequel
607
607
  end
608
608
  end
609
609
 
610
- # An alias for calling first on the model's dataset, but with
611
- # optimized handling of the single argument case.
612
- def first(*args, &block)
613
- if args.length == 1 && !block && !args.first.is_a?(Integer)
614
- # Use optimized finder
615
- first_where(args.first)
610
+ def first_where(cond)
611
+ Sequel::Deprecation.deprecate("Sequel::Model.first_where", "Instead, use Sequel::Model.first")
612
+ if cond.is_a?(Integer)
613
+ dataset.where(cond).first(cond)
616
614
  else
617
- dataset.first(*args, &block)
615
+ dataset.first(cond)
618
616
  end
619
617
  end
620
618
 
621
- # An alias for calling first! on the model's dataset, but with
622
- # optimized handling of the single argument case.
623
- def first!(*args, &block)
624
- first(*args, &block) || raise(Sequel::NoMatchingRow.new(dataset))
625
- end
626
-
627
619
  # Freeze a model class, disallowing any further changes to it.
628
620
  def freeze
629
621
  dataset_module.freeze
630
622
  overridable_methods_module.freeze
631
623
 
632
- @finder_loaders.freeze
624
+ @finder_loaders.freeze # SEQUEL5: Remove
633
625
 
634
626
  if @dataset
635
627
  @dataset.freeze
@@ -637,16 +629,16 @@ module Sequel
637
629
  db_schema.freeze.each_value(&:freeze)
638
630
  columns.freeze
639
631
  setter_methods.freeze
640
- @finder_loaders.each_key{|k| finder_for(k)}
632
+ @finder_loaders.each_key{|k| finder_for(k)} # SEQUEL5: Remove
641
633
  else
642
634
  @setter_methods = [].freeze
643
635
  end
644
636
 
645
637
  @dataset_method_modules.freeze
646
638
  @default_set_fields_options.freeze
647
- @finders.freeze
639
+ @finders.freeze # SEQUEL5: Remove
648
640
  @plugins.freeze
649
- @allowed_columns.freeze if @allowed_columns
641
+ @allowed_columns.freeze if @allowed_columns # SEQUEL5: Remove
650
642
 
651
643
  super
652
644
  end
@@ -802,6 +794,7 @@ module Sequel
802
794
  # exception:
803
795
  # :type :: Specifies the type of prepared statement to create
804
796
  def prepared_finder(meth=OPTS, opts=OPTS, &block)
797
+ # SEQUEL5: Remove
805
798
  if block
806
799
  raise Error, "cannot pass both a method name argument and a block of Model.finder" unless meth.is_a?(Hash)
807
800
  meth = meth.merge(:prepare=>true)
@@ -837,6 +830,7 @@ module Sequel
837
830
  # Artist.set(:name=>'Bob', :hometown=>'Sactown') # No Error
838
831
  # Artist.set(:name=>'Bob', :records_sold=>30000) # Error
839
832
  def set_allowed_columns(*cols)
833
+ Sequel::Deprecation.deprecate("Sequel::Model.set_allowed_columns", "Load the whitelist_security plugin into the model class")
840
834
  clear_setter_methods_cache
841
835
  @allowed_columns = cols
842
836
  end
@@ -945,15 +939,9 @@ module Sequel
945
939
  # This method creates dataset methods that do not accept arguments. To create
946
940
  # dataset methods that accept arguments, you should use define a
947
941
  # method directly inside a #dataset_module block.
948
- def subset(name, *args, &block)
949
- if block || args.flatten.any?{|arg| arg.is_a?(Proc)}
950
- def_dataset_method(name){filter(*args, &block)}
951
- else
952
- key = :"_subset_#{name}_ds"
953
- def_dataset_method(name) do
954
- cached_dataset(key){filter(*args)}
955
- end
956
- end
942
+ def subset(*args, &block)
943
+ Sequel::Deprecation.deprecate("Sequel::Model.subset", "Use the subset method inside a dataset_module block, or use the def_dataset_method plugin")
944
+ dataset_module{where(*args, &block)}
957
945
  end
958
946
 
959
947
  # Returns name of primary table for the dataset. If the table for the dataset
@@ -1011,6 +999,10 @@ module Sequel
1011
999
  self.simple_table = db.literal(ds).freeze
1012
1000
  ds = db.from(ds)
1013
1001
  when Dataset
1002
+ if ds.joined_dataset?
1003
+ Sequel::Deprecation.deprecate("Using a joined dataset as a Sequel::Model dataset", respond_to?(:cti_base_model) ? "Use the class_table_inheritance plugin :alias option in #{cti_base_model.inspect}" : "Call from_self on the dataset to wrap it in a subquery")
1004
+ end
1005
+
1014
1006
  self.simple_table = if ds.send(:simple_select_all?)
1015
1007
  ds.literal(ds.first_source_table).freeze
1016
1008
  end
@@ -1072,12 +1064,14 @@ module Sequel
1072
1064
  # Define a finder method in the given module with the given method name that
1073
1065
  # load rows using the finder with the given name.
1074
1066
  def def_finder_method(mod, meth, type)
1067
+ # SEQUEL5: Remove
1075
1068
  mod.send(:define_method, meth){|*args, &block| finder_for(meth).send(type, *args, &block)}
1076
1069
  end
1077
1070
 
1078
1071
  # Define a prepared_finder method in the given module that will call the associated prepared
1079
1072
  # statement.
1080
1073
  def def_prepare_method(mod, meth)
1074
+ # SEQUEL5: Remove
1081
1075
  mod.send(:define_method, meth){|*args, &block| finder_for(meth).call(prepare_method_arg_hash(args), &block)}
1082
1076
  end
1083
1077
 
@@ -1085,6 +1079,7 @@ module Sequel
1085
1079
  # for the method, load the finder and set correctly in the finders hash, then
1086
1080
  # return the finder.
1087
1081
  def finder_for(meth)
1082
+ # SEQUEL5: Remove
1088
1083
  unless finder = (frozen? ? @finders[meth] : Sequel.synchronize{@finders[meth]})
1089
1084
  finder_loader = @finder_loaders.fetch(meth)
1090
1085
  finder = finder_loader.call(self)
@@ -1143,6 +1138,7 @@ module Sequel
1143
1138
  # that want to modify the methods used.
1144
1139
  def get_setter_methods
1145
1140
  if allowed_columns
1141
+ # SEQUEL5: Remove allowed_columns handling
1146
1142
  allowed_columns.map{|x| "#{x}="}
1147
1143
  else
1148
1144
  meths = instance_methods.collect(&:to_s).grep(SETTER_METHOD_REGEXP) - RESTRICTED_SETTER_METHODS
@@ -1223,6 +1219,7 @@ module Sequel
1223
1219
  # An hash of prepared argument values for the given arguments, with keys
1224
1220
  # starting at a. Used by the methods created by prepared_finder.
1225
1221
  def prepare_method_arg_hash(args)
1222
+ # SEQUEL5: Remove
1226
1223
  h = {}
1227
1224
  prepare_method_args('a', args.length).zip(args).each{|k, v| h[k] = v}
1228
1225
  h
@@ -1230,6 +1227,7 @@ module Sequel
1230
1227
 
1231
1228
  # An array of prepared statement argument names, of length n and starting with base.
1232
1229
  def prepare_method_args(base, n)
1230
+ # SEQUEL5: Remove
1233
1231
  (0...n).map do
1234
1232
  s = base.to_sym
1235
1233
  base = base.next
@@ -1251,9 +1249,9 @@ module Sequel
1251
1249
  ds.fetch_rows(sql){|r| return ds.row_proc.call(r)}
1252
1250
  nil
1253
1251
  elsif dataset.joined_dataset?
1254
- first_where(qualified_primary_key_hash(pk))
1252
+ dataset.first(qualified_primary_key_hash(pk))
1255
1253
  else
1256
- first_where(primary_key_hash(pk))
1254
+ dataset.first(primary_key_hash(pk))
1257
1255
  end
1258
1256
  end
1259
1257
 
@@ -1276,7 +1274,7 @@ module Sequel
1276
1274
  # Reset the instance dataset to a modified copy of the current dataset,
1277
1275
  # should be used whenever the model's dataset is modified.
1278
1276
  def reset_instance_dataset
1279
- Sequel.synchronize{@finders.clear if @finders}
1277
+ Sequel.synchronize{@finders.clear} if @finders && !@finders.frozen?
1280
1278
  @instance_dataset = @dataset.limit(1).naked.skip_limit_check if @dataset
1281
1279
  end
1282
1280
 
@@ -1800,6 +1798,7 @@ module Sequel
1800
1798
  # artist.set_all(:name=>'Jim')
1801
1799
  # artist.name # => 'Jim'
1802
1800
  def set_all(hash)
1801
+ Sequel::Deprecation.deprecate("Sequel::Model#set_all", "Switch to set or load the whitelist_security plugin into the model class")
1803
1802
  set_restricted(hash, :all)
1804
1803
  end
1805
1804
 
@@ -1870,6 +1869,7 @@ module Sequel
1870
1869
  #
1871
1870
  # artist.set_only({:hometown=>'LA'}, :name) # Raise Error
1872
1871
  def set_only(hash, *only)
1872
+ Sequel::Deprecation.deprecate("Sequel::Model#set_only", "Switch to set_fields with the :missing=>:skip option or load the whitelist_security plugin into the model class")
1873
1873
  set_restricted(hash, only.flatten)
1874
1874
  end
1875
1875
 
@@ -1916,6 +1916,7 @@ module Sequel
1916
1916
  # Artist.set_allowed_columns(:num_albums)
1917
1917
  # artist.update_all(:name=>'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
1918
1918
  def update_all(hash)
1919
+ Sequel::Deprecation.deprecate("Sequel::Model#update_all", "Switch to update or load the whitelist_security plugin into the model class")
1919
1920
  update_restricted(hash, :all)
1920
1921
  end
1921
1922
 
@@ -1941,6 +1942,7 @@ module Sequel
1941
1942
  #
1942
1943
  # artist.update_only({:hometown=>'LA'}, :name) # Raise Error
1943
1944
  def update_only(hash, *only)
1945
+ Sequel::Deprecation.deprecate("Sequel::Model#update_only", "Switch to update_fields with the :missing=>:skip option or load the whitelist_security plugin into the model class")
1944
1946
  update_restricted(hash, only.flatten)
1945
1947
  end
1946
1948
 
@@ -2002,8 +2004,6 @@ module Sequel
2002
2004
  # even if validation is skipped. This is a private hook. It exists so that
2003
2005
  # plugins can set values automatically before validation (as the values
2004
2006
  # need to be validated), but should be set even if validation is skipped.
2005
- # Unlike the regular before_validation hook, we do not skip the save/validation
2006
- # if this returns false.
2007
2007
  def _before_validation
2008
2008
  end
2009
2009
 
@@ -2428,7 +2428,7 @@ module Sequel
2428
2428
  # Array :: Only allow setting of columns in the given array.
2429
2429
  def setter_methods(type)
2430
2430
  if type == :default
2431
- if !@singleton_setter_added || model.allowed_columns
2431
+ if !@singleton_setter_added || model.allowed_columns # SEQUEL5: Remove model.allowed_columns
2432
2432
  return model.setter_methods
2433
2433
  end
2434
2434
  end
@@ -2503,7 +2503,7 @@ module Sequel
2503
2503
  #
2504
2504
  # Artist.dataset[1] # SELECT * FROM artists WHERE (id = 1) LIMIT 1
2505
2505
  def [](*args)
2506
- if args.length == 1 && (i = args.at(0)) && i.is_a?(Integer)
2506
+ if args.length == 1 && (i = args[0]) && i.is_a?(Integer)
2507
2507
  with_pk(i)
2508
2508
  else
2509
2509
  super
@@ -2531,6 +2531,7 @@ module Sequel
2531
2531
  # # FROM artists LEFT OUTER JOIN albums ON (albums.artist_id = artists.id)
2532
2532
  def graph(table, *args, &block)
2533
2533
  if table.is_a?(Class) && table < Sequel::Model
2534
+ Sequel::Deprecation.deprecate("Passing Sequel::Model class as first argument to Sequel::Dataset#graph", "Pass the model's dataset as the first argument instead")
2534
2535
  super(table.dataset, *args, &block)
2535
2536
  else
2536
2537
  super
@@ -2544,7 +2545,8 @@ module Sequel
2544
2545
  # Album.insert(Album.load(:name=>'A'))
2545
2546
  # # INSERT INTO albums (name) VALUES ('A')
2546
2547
  def insert_sql(*values)
2547
- if values.size == 1 && (v = values.at(0)).is_a?(Sequel::Model) && !v.respond_to?(:sql_literal_append)
2548
+ if values.size == 1 && (v = values[0]).is_a?(Sequel::Model) && !v.respond_to?(:sql_literal_append)
2549
+ Sequel::Deprecation.deprecate("Passing Sequel::Model instance argument to Sequel::Dataset#insert", "Pass model_instance.values or model_instance.to_hash as the argument instead")
2548
2550
  super(v.to_hash)
2549
2551
  else
2550
2552
  super
@@ -2558,6 +2560,7 @@ module Sequel
2558
2560
  # # SELECT * FROM artists INNER JOIN albums ON (albums.artist_id = artists.id)
2559
2561
  def join_table(type, table, *args, &block)
2560
2562
  if table.is_a?(Class) && table < Sequel::Model
2563
+ Sequel::Deprecation.deprecate("Passing Sequel::Model class to a dataset join method", "Pass the model's table name or dataset as the first argument instead")
2561
2564
  if table.dataset.simple_select_all?
2562
2565
  super(type, table.table_name, *args, &block)
2563
2566
  else
@@ -2721,6 +2724,5 @@ module Sequel
2721
2724
 
2722
2725
  extend ClassMethods
2723
2726
  plugin self
2724
- finder(:where, :arity=>1, :mod=>ClassMethods)
2725
2727
  end
2726
2728
  end
@@ -14,24 +14,18 @@ module Sequel
14
14
  @model = model
15
15
  end
16
16
 
17
- # Define a named filter for this dataset, see
18
- # Model.subset for details.
17
+ # Alias for where.
19
18
  def subset(name, *args, &block)
20
- @model.subset(name, *args, &block)
19
+ where(name, *args, &block)
21
20
  end
22
21
 
23
- # Alias for subset
24
- def where(name, *args, &block)
25
- subset(name, *args, &block)
26
- end
27
-
28
- %w'exclude exclude_having having'.map(&:to_sym).each do |meth|
22
+ %w'where exclude exclude_having having'.map(&:to_sym).each do |meth|
29
23
  define_method(meth) do |name, *args, &block|
30
24
  if block || args.flatten.any?{|arg| arg.is_a?(Proc)}
31
- @model.def_dataset_method(name){send(meth, *args, &block)}
25
+ define_method(name){send(meth, *args, &block)}
32
26
  else
33
27
  key = :"_#{meth}_#{name}_ds"
34
- @model.def_dataset_method(name) do
28
+ define_method(name) do
35
29
  cached_dataset(key){send(meth, *args)}
36
30
  end
37
31
  end
@@ -48,10 +42,10 @@ module Sequel
48
42
  def self.def_dataset_caching_method(mod, meth)
49
43
  mod.send(:define_method, meth) do |name, *args, &block|
50
44
  if block
51
- @model.def_dataset_method(name){send(meth, *args, &block)}
45
+ define_method(name){send(meth, *args, &block)}
52
46
  else
53
47
  key = :"_#{meth}_#{name}_ds"
54
- @model.def_dataset_method(name) do
48
+ define_method(name) do
55
49
  cached_dataset(key){send(meth, *args)}
56
50
  end
57
51
  end
@@ -67,7 +61,8 @@ module Sequel
67
61
  # Add a class method to the related model that
68
62
  # calls the dataset method of the same name.
69
63
  def method_added(meth)
70
- @model.send(:def_model_dataset_method, meth)
64
+ @model.send(:def_model_dataset_method, meth) if public_method_defined?(meth)
65
+ super
71
66
  end
72
67
  end
73
68
 
@@ -25,6 +25,9 @@ module Sequel
25
25
  # In the given module +mod+, define methods that are call the same method
26
26
  # on the dataset. This is designed for plugins to define dataset methods
27
27
  # inside ClassMethods that call the implementations in DatasetMethods.
28
+ #
29
+ # This should not be called with untrusted input or method names that
30
+ # can't be used literally, since it uses class_eval.
28
31
  def self.def_dataset_methods(mod, meths)
29
32
  Array(meths).each do |meth|
30
33
  mod.class_eval("def #{meth}(*args, &block); dataset.#{meth}(*args, &block) end", __FILE__, __LINE__)
@@ -1,3 +1,4 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  require 'sequel'
4
+ Sequel::Deprecation.deprecate("requiring 'sequel/no_core_ext'", "Just require 'sequel' instead")
@@ -58,7 +58,7 @@ module Sequel
58
58
  # restricted_columns.
59
59
  def get_setter_methods
60
60
  meths = super
61
- if !allowed_columns && restricted_columns
61
+ if !(respond_to?(:allowed_columns) && allowed_columns) && restricted_columns
62
62
  meths -= restricted_columns.map{|x| "#{x}="}
63
63
  end
64
64
  meths
@@ -9,7 +9,7 @@ module Sequel
9
9
  # <tt>column IS TRUE</tt> (assuming the database supports that syntax).
10
10
  #
11
11
  # You can provide a block to the plugin, which will be called with column name
12
- # symbol, and should return an array of arguments to pass to +subset+.
12
+ # symbol, and should return an array of arguments to pass to +dataset_module.where+.
13
13
  # Using this, you can change the method name and arguments for each column.
14
14
  # This block is executed in the context of the model class.
15
15
  #
@@ -28,12 +28,11 @@ module Sequel
28
28
  # [column.to_s.sub(/\Ais_/, ''), {column=>'Y'}]
29
29
  # end
30
30
  module BooleanSubsets
31
- # Add the boolean_attribute? class method to the model, and create
32
- # attribute? boolean reader methods for the class's columns if the class has a dataset.
31
+ # Create boolean subset methods for each boolean column.
33
32
  def self.configure(model, &block)
34
33
  model.instance_eval do
35
34
  (class << self; self; end).send(:define_method, :boolean_subset_args, &block) if block
36
- send(:create_boolean_subsets) if @dataset
35
+ create_boolean_subsets if @dataset
37
36
  end
38
37
  end
39
38
 
@@ -50,7 +49,10 @@ module Sequel
50
49
  # Add subset methods for all of the boolean columns in this model.
51
50
  def create_boolean_subsets
52
51
  if cs = check_non_connection_error{columns}
53
- cs.each{|c| subset(*boolean_subset_args(c)) if db_schema[c][:type] == :boolean}
52
+ cs = cs.select{|c| db_schema[c][:type] == :boolean}.map{|c| boolean_subset_args(c)}
53
+ dataset_module do
54
+ cs.each{|c| where(*c)}
55
+ end
54
56
  end
55
57
  end
56
58
  end