sequel 5.108.0 → 5.110.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sequel/adapters/ado.rb +1 -0
  3. data/lib/sequel/adapters/amalgalite.rb +34 -8
  4. data/lib/sequel/adapters/jdbc/mssql.rb +28 -5
  5. data/lib/sequel/adapters/jdbc/postgresql.rb +14 -3
  6. data/lib/sequel/adapters/jdbc.rb +2 -1
  7. data/lib/sequel/adapters/postgres.rb +5 -2
  8. data/lib/sequel/adapters/shared/access.rb +5 -1
  9. data/lib/sequel/adapters/shared/db2.rb +3 -0
  10. data/lib/sequel/adapters/shared/mssql.rb +7 -1
  11. data/lib/sequel/adapters/shared/oracle.rb +7 -0
  12. data/lib/sequel/adapters/shared/postgres.rb +97 -1001
  13. data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -32
  14. data/lib/sequel/adapters/sqlite.rb +13 -9
  15. data/lib/sequel/adapters/trilogy.rb +2 -1
  16. data/lib/sequel/core.rb +71 -23
  17. data/lib/sequel/database/misc.rb +1 -6
  18. data/lib/sequel/database/schema_methods.rb +3 -3
  19. data/lib/sequel/database/transactions.rb +1 -3
  20. data/lib/sequel/dataset/actions.rb +1 -1
  21. data/lib/sequel/dataset/sql.rb +14 -3
  22. data/lib/sequel/extensions/core_refinements.rb +1 -4
  23. data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -2
  24. data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -3
  25. data/lib/sequel/extensions/lit_require_frozen.rb +17 -1
  26. data/lib/sequel/extensions/named_timezones.rb +9 -7
  27. data/lib/sequel/extensions/pg_array.rb +1 -0
  28. data/lib/sequel/extensions/pg_json_ops.rb +4 -2
  29. data/lib/sequel/extensions/pg_loose_count.rb +37 -2
  30. data/lib/sequel/extensions/s.rb +4 -8
  31. data/lib/sequel/extensions/schema_dumper.rb +6 -2
  32. data/lib/sequel/extensions/sql_comments.rb +0 -4
  33. data/lib/sequel/extensions/string_date_time.rb +7 -4
  34. data/lib/sequel/extensions/symbol_aref.rb +11 -31
  35. data/lib/sequel/extensions/symbol_aref_refinement.rb +1 -4
  36. data/lib/sequel/extensions/symbol_as.rb +1 -2
  37. data/lib/sequel/extensions/symbol_as_refinement.rb +1 -5
  38. data/lib/sequel/model/base.rb +4 -9
  39. data/lib/sequel/plugins/caching.rb +27 -2
  40. data/lib/sequel/plugins/csv_serializer.rb +9 -20
  41. data/lib/sequel/plugins/instance_filters.rb +8 -0
  42. data/lib/sequel/plugins/instance_hooks.rb +19 -0
  43. data/lib/sequel/plugins/mssql_optimistic_locking.rb +9 -0
  44. data/lib/sequel/plugins/optimistic_locking.rb +12 -2
  45. data/lib/sequel/plugins/optimistic_locking_base.rb +14 -0
  46. data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +11 -2
  47. data/lib/sequel/plugins/select_on_skipped_update.rb +63 -0
  48. data/lib/sequel/plugins/single_table_inheritance.rb +20 -2
  49. data/lib/sequel/plugins/subset_conditions.rb +5 -16
  50. data/lib/sequel/plugins/throw_failures.rb +1 -1
  51. data/lib/sequel/plugins/validate_associated.rb +7 -1
  52. data/lib/sequel/plugins/validate_associated_context.rb +52 -0
  53. data/lib/sequel/sql.rb +109 -105
  54. data/lib/sequel/version.rb +1 -1
  55. metadata +5 -3
data/lib/sequel/sql.rb CHANGED
@@ -1060,123 +1060,127 @@ module Sequel
1060
1060
  # in a boolean value in SQL.
1061
1061
  class BooleanExpression < ComplexExpression
1062
1062
  include BooleanMethods
1063
-
1064
- # Take pairs of values (e.g. a hash or array of two element arrays)
1065
- # and converts it to a +BooleanExpression+. The operator and args
1066
- # used depends on the case of the right (2nd) argument:
1067
- #
1068
- # 0..10 :: left >= 0 AND left <= 10
1069
- # [1,2] :: left IN (1,2)
1070
- # nil :: left IS NULL
1071
- # true :: left IS TRUE
1072
- # false :: left IS FALSE
1073
- # /as/ :: left ~ 'as'
1074
- # :blah :: left = blah
1075
- # 'blah' :: left = 'blah'
1076
- #
1077
- # If multiple arguments are given, they are joined with the op given (AND
1078
- # by default, OR possible). If negate is set to true,
1079
- # all subexpressions are inverted before used. Therefore, the following
1080
- # expressions are equivalent:
1081
- #
1082
- # ~from_value_pairs(hash)
1083
- # from_value_pairs(hash, :OR, true)
1084
- def self.from_value_pairs(pairs, op=:AND, negate=false)
1085
- pairs = pairs.map{|l,r| from_value_pair(l, r)}
1086
- pairs.map!{|ce| invert(ce)} if negate
1087
- pairs.length == 1 ? pairs[0] : new(op, *pairs)
1088
- end
1089
-
1090
- # Return a BooleanExpression based on the right side of the pair.
1091
- def self.from_value_pair(l, r)
1092
- case r
1093
- when Range
1094
- unless r.begin.nil?
1095
- begin_expr = new(:>=, l, r.begin)
1096
- end
1097
- unless r.end.nil?
1098
- end_expr = new(r.exclude_end? ? :< : :<=, l, r.end)
1099
- end
1100
- if begin_expr
1101
- if end_expr
1102
- new(:AND, begin_expr, end_expr)
1063
+
1064
+ module ClassMethods
1065
+ # Take pairs of values (e.g. a hash or array of two element arrays)
1066
+ # and converts it to a +BooleanExpression+. The operator and args
1067
+ # used depends on the case of the right (2nd) argument:
1068
+ #
1069
+ # 0..10 :: left >= 0 AND left <= 10
1070
+ # [1,2] :: left IN (1,2)
1071
+ # nil :: left IS NULL
1072
+ # true :: left IS TRUE
1073
+ # false :: left IS FALSE
1074
+ # /as/ :: left ~ 'as'
1075
+ # :blah :: left = blah
1076
+ # 'blah' :: left = 'blah'
1077
+ #
1078
+ # If multiple arguments are given, they are joined with the op given (AND
1079
+ # by default, OR possible). If negate is set to true,
1080
+ # all subexpressions are inverted before used. Therefore, the following
1081
+ # expressions are equivalent:
1082
+ #
1083
+ # ~from_value_pairs(hash)
1084
+ # from_value_pairs(hash, :OR, true)
1085
+ def from_value_pairs(pairs, op=:AND, negate=false)
1086
+ pairs = pairs.map{|l,r| from_value_pair(l, r)}
1087
+ pairs.map!{|ce| invert(ce)} if negate
1088
+ pairs.length == 1 ? pairs[0] : new(op, *pairs)
1089
+ end
1090
+
1091
+ # Return a BooleanExpression based on the right side of the pair.
1092
+ def from_value_pair(l, r)
1093
+ case r
1094
+ when Range
1095
+ unless r.begin.nil?
1096
+ begin_expr = new(:>=, l, r.begin)
1097
+ end
1098
+ unless r.end.nil?
1099
+ end_expr = new(r.exclude_end? ? :< : :<=, l, r.end)
1100
+ end
1101
+ if begin_expr
1102
+ if end_expr
1103
+ new(:AND, begin_expr, end_expr)
1104
+ else
1105
+ begin_expr
1106
+ end
1107
+ elsif end_expr
1108
+ end_expr
1103
1109
  else
1104
- begin_expr
1110
+ new(:'=', 1, 1)
1105
1111
  end
1106
- elsif end_expr
1107
- end_expr
1108
- else
1109
- new(:'=', 1, 1)
1110
- end
1111
- when ::Array, ::Set
1112
- r = r.dup.freeze unless r.frozen?
1113
- new(:IN, l, r)
1114
- when ::String
1115
- r = r.dup.freeze unless r.frozen?
1116
- new(:'=', l, r)
1117
- when ::Sequel::Dataset
1118
- new(:IN, l, r)
1119
- when NegativeBooleanConstant
1120
- new(:"IS NOT", l, r.constant)
1121
- when BooleanConstant
1122
- new(:IS, l, r.constant)
1123
- when NilClass, TrueClass, FalseClass
1124
- new(:IS, l, r)
1125
- when Regexp
1126
- StringExpression.like(l, r)
1127
- when DelayedEvaluation
1128
- Sequel.delay{|ds| from_value_pair(l, r.call(ds))}
1129
- when Dataset::PlaceholderLiteralizer::Argument
1130
- prev_transform = r.instance_variable_get(:@transformer)
1131
- r.transform do |v|
1132
- if prev_transform
1133
- v = prev_transform.call(v)
1112
+ when ::Array, ::Set
1113
+ r = r.dup.freeze unless r.frozen?
1114
+ new(:IN, l, r)
1115
+ when ::String
1116
+ r = r.dup.freeze unless r.frozen?
1117
+ new(:'=', l, r)
1118
+ when ::Sequel::Dataset
1119
+ new(:IN, l, r)
1120
+ when NegativeBooleanConstant
1121
+ new(:"IS NOT", l, r.constant)
1122
+ when BooleanConstant
1123
+ new(:IS, l, r.constant)
1124
+ when NilClass, TrueClass, FalseClass
1125
+ new(:IS, l, r)
1126
+ when Regexp
1127
+ StringExpression.like(l, r)
1128
+ when DelayedEvaluation
1129
+ Sequel.delay{|ds| from_value_pair(l, r.call(ds))}
1130
+ when Dataset::PlaceholderLiteralizer::Argument
1131
+ prev_transform = r.instance_variable_get(:@transformer)
1132
+ r.transform do |v|
1133
+ if prev_transform
1134
+ v = prev_transform.call(v)
1135
+ end
1136
+ from_value_pair(l, v)
1134
1137
  end
1135
- from_value_pair(l, v)
1138
+ else
1139
+ new(:'=', l, r)
1136
1140
  end
1137
- else
1138
- new(:'=', l, r)
1139
1141
  end
1140
- end
1141
- private_class_method :from_value_pair
1142
-
1143
- # Invert the expression, if possible. If the expression cannot
1144
- # be inverted, raise an error. An inverted expression should match everything that the
1145
- # uninverted expression did not match, and vice-versa, except for possible issues with
1146
- # SQL NULL (i.e. 1 == NULL is NULL and 1 != NULL is also NULL).
1147
- #
1148
- # BooleanExpression.invert(:a) # NOT "a"
1149
- def self.invert(ce)
1150
- case ce
1151
- when BooleanExpression
1152
- case op = ce.op
1153
- when :AND, :OR
1154
- BooleanExpression.new(OPERATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
1155
- when :IN, :"NOT IN"
1156
- BooleanExpression.new(OPERATOR_INVERSIONS[op], *ce.args.dup)
1157
- else
1158
- if ce.args.length == 2
1159
- case ce.args[1]
1160
- when Function, LiteralString, PlaceholderLiteralString
1161
- # Special behavior to not push down inversion in this case because doing so
1162
- # can result in incorrect behavior for ANY/SOME/ALL operators.
1163
- BooleanExpression.new(:NOT, ce)
1142
+ private :from_value_pair
1143
+
1144
+ # Invert the expression, if possible. If the expression cannot
1145
+ # be inverted, raise an error. An inverted expression should match everything that the
1146
+ # uninverted expression did not match, and vice-versa, except for possible issues with
1147
+ # SQL NULL (i.e. 1 == NULL is NULL and 1 != NULL is also NULL).
1148
+ #
1149
+ # BooleanExpression.invert(:a) # NOT "a"
1150
+ def invert(ce)
1151
+ case ce
1152
+ when BooleanExpression
1153
+ case op = ce.op
1154
+ when :AND, :OR
1155
+ BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
1156
+ when :IN, :"NOT IN"
1157
+ BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.dup)
1158
+ else
1159
+ if ce.args.length == 2
1160
+ case ce.args[1]
1161
+ when Function, LiteralString, PlaceholderLiteralString
1162
+ # Special behavior to not push down inversion in this case because doing so
1163
+ # can result in incorrect behavior for ANY/SOME/ALL operators.
1164
+ BooleanExpression.new(:NOT, ce)
1165
+ else
1166
+ BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.dup)
1167
+ end
1164
1168
  else
1165
- BooleanExpression.new(OPERATOR_INVERSIONS[op], *ce.args.dup)
1169
+ BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.dup)
1166
1170
  end
1167
- else
1168
- BooleanExpression.new(OPERATOR_INVERSIONS[op], *ce.args.dup)
1169
1171
  end
1172
+ when StringExpression, NumericExpression
1173
+ raise(Sequel::Error, "cannot invert #{ce.inspect}")
1174
+ when Constant
1175
+ ComplexExpression::CONSTANT_INVERSIONS[ce] || raise(Sequel::Error, "cannot invert #{ce.inspect}")
1176
+ else
1177
+ BooleanExpression.new(:NOT, ce)
1170
1178
  end
1171
- when StringExpression, NumericExpression
1172
- raise(Sequel::Error, "cannot invert #{ce.inspect}")
1173
- when Constant
1174
- CONSTANT_INVERSIONS[ce] || raise(Sequel::Error, "cannot invert #{ce.inspect}")
1175
- else
1176
- BooleanExpression.new(:NOT, ce)
1177
1179
  end
1178
1180
  end
1179
1181
 
1182
+ extend ClassMethods
1183
+
1180
1184
  # Always use an AND operator for & on BooleanExpressions
1181
1185
  def &(ce)
1182
1186
  BooleanExpression.new(:AND, self, ce)
@@ -6,7 +6,7 @@ module Sequel
6
6
 
7
7
  # The minor version of Sequel. Bumped for every non-patch level
8
8
  # release, generally around once a month.
9
- MINOR = 108
9
+ MINOR = 110
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.108.0
4
+ version: 5.110.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -386,6 +386,7 @@ files:
386
386
  - lib/sequel/plugins/primary_key_lookup_check_values.rb
387
387
  - lib/sequel/plugins/rcte_tree.rb
388
388
  - lib/sequel/plugins/require_valid_schema.rb
389
+ - lib/sequel/plugins/select_on_skipped_update.rb
389
390
  - lib/sequel/plugins/serialization.rb
390
391
  - lib/sequel/plugins/serialization_modification_detection.rb
391
392
  - lib/sequel/plugins/sharding.rb
@@ -416,6 +417,7 @@ files:
416
417
  - lib/sequel/plugins/update_refresh.rb
417
418
  - lib/sequel/plugins/uuid.rb
418
419
  - lib/sequel/plugins/validate_associated.rb
420
+ - lib/sequel/plugins/validate_associated_context.rb
419
421
  - lib/sequel/plugins/validation_class_methods.rb
420
422
  - lib/sequel/plugins/validation_contexts.rb
421
423
  - lib/sequel/plugins/validation_helpers.rb
@@ -448,14 +450,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
448
450
  requirements:
449
451
  - - ">="
450
452
  - !ruby/object:Gem::Version
451
- version: 1.9.2
453
+ version: '2.0'
452
454
  required_rubygems_version: !ruby/object:Gem::Requirement
453
455
  requirements:
454
456
  - - ">="
455
457
  - !ruby/object:Gem::Version
456
458
  version: '0'
457
459
  requirements: []
458
- rubygems_version: 4.0.16
460
+ rubygems_version: 4.0.20
459
461
  specification_version: 4
460
462
  summary: The Database Toolkit for Ruby
461
463
  test_files: []