sequel 4.45.0 → 4.46.0

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