sequel 5.90.0 → 5.91.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.
- checksums.yaml +4 -4
- data/lib/sequel/adapters/ado.rb +1 -1
- data/lib/sequel/adapters/jdbc.rb +2 -2
- data/lib/sequel/adapters/shared/mssql.rb +3 -3
- data/lib/sequel/adapters/shared/mysql.rb +3 -3
- data/lib/sequel/adapters/shared/postgres.rb +2 -2
- data/lib/sequel/database/query.rb +11 -11
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +85 -7
- data/lib/sequel/extensions/schema_dumper.rb +1 -1
- data/lib/sequel/model/associations.rb +9 -1
- data/lib/sequel/plugins/forbid_lazy_load.rb +14 -1
- data/lib/sequel/plugins/nested_attributes.rb +9 -4
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +6 -1
- data/lib/sequel/plugins/pg_auto_validate_enums.rb +88 -0
- data/lib/sequel/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d13e0998a9eb78392a4f9f7793b2ceceebf87fa5a4dd6f9fcfd5bbd05a686d83
|
4
|
+
data.tar.gz: d4c7da82fb811928c58a096b2d5fc500cdb7cee1bbff14795817b5bd3f4d3360
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2bbfc37fbd2b97796c96352a0f1d7d41053f91f4b61e3888a5aea712b9a59c7600e8ed58a15919cef7d8b0cc1c35e4bc3d142206ac245ed6f4f13575188f3b9
|
7
|
+
data.tar.gz: 8f4c0b7b95ec967c471455df69e8b5b5ff9c2104790c7c18abaa9601f2e7c4514952d4410aac1e3f720304f30af2d7299ea0f1233a7e083bcb901c8a03f697bb
|
data/lib/sequel/adapters/ado.rb
CHANGED
@@ -179,7 +179,7 @@ module Sequel
|
|
179
179
|
|
180
180
|
def adapter_initialize
|
181
181
|
case @opts[:conn_string]
|
182
|
-
when /Microsoft\.(Jet|ACE)\.OLEDB/
|
182
|
+
when /Microsoft\.(Jet|ACE)\.OLEDB/i
|
183
183
|
require_relative 'ado/access'
|
184
184
|
extend Sequel::ADO::Access::DatabaseMethods
|
185
185
|
self.dataset_class = ADO::Access::Dataset
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -636,11 +636,11 @@ module Sequel
|
|
636
636
|
def schema_column_set_db_type(schema)
|
637
637
|
case schema[:type]
|
638
638
|
when :string
|
639
|
-
if schema[:db_type] =~ /\A(character( varying)?|n?(var)?char2?)\z/
|
639
|
+
if schema[:db_type] =~ /\A(character( varying)?|n?(var)?char2?)\z/i && schema[:column_size] > 0
|
640
640
|
schema[:db_type] += "(#{schema[:column_size]})"
|
641
641
|
end
|
642
642
|
when :decimal
|
643
|
-
if schema[:db_type] =~ /\A(decimal|numeric)\z/
|
643
|
+
if schema[:db_type] =~ /\A(decimal|numeric)\z/i && schema[:column_size] > 0 && schema[:scale] >= 0
|
644
644
|
schema[:db_type] += "(#{schema[:column_size]}, #{schema[:scale]})"
|
645
645
|
end
|
646
646
|
end
|
@@ -480,11 +480,11 @@ module Sequel
|
|
480
480
|
|
481
481
|
def schema_column_type(db_type)
|
482
482
|
case db_type
|
483
|
-
when /\A(?:bit)\z/
|
483
|
+
when /\A(?:bit)\z/i
|
484
484
|
:boolean
|
485
|
-
when /\A(?:(?:small)?money)\z/
|
485
|
+
when /\A(?:(?:small)?money)\z/i
|
486
486
|
:decimal
|
487
|
-
when /\A(timestamp|rowversion)\z/
|
487
|
+
when /\A(timestamp|rowversion)\z/i
|
488
488
|
:blob
|
489
489
|
else
|
490
490
|
super
|
@@ -550,11 +550,11 @@ module Sequel
|
|
550
550
|
|
551
551
|
def schema_column_type(db_type)
|
552
552
|
case db_type
|
553
|
-
when /\Aset/
|
553
|
+
when /\Aset/i
|
554
554
|
:set
|
555
|
-
when /\Amediumint/
|
555
|
+
when /\Amediumint/i
|
556
556
|
:integer
|
557
|
-
when /\Amediumtext/
|
557
|
+
when /\Amediumtext/i
|
558
558
|
:string
|
559
559
|
else
|
560
560
|
super
|
@@ -1663,9 +1663,9 @@ module Sequel
|
|
1663
1663
|
# Handle interval and citext types.
|
1664
1664
|
def schema_column_type(db_type)
|
1665
1665
|
case db_type
|
1666
|
-
when /\Ainterval\z/
|
1666
|
+
when /\Ainterval\z/i
|
1667
1667
|
:interval
|
1668
|
-
when /\Acitext\z/
|
1668
|
+
when /\Acitext\z/i
|
1669
1669
|
:string
|
1670
1670
|
else
|
1671
1671
|
super
|
@@ -170,7 +170,7 @@ module Sequel
|
|
170
170
|
c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type]) unless c.has_key?(:ruby_default)
|
171
171
|
if c[:primary_key] && !auto_increment_set
|
172
172
|
# If adapter didn't set it, assume that integer primary keys are auto incrementing
|
173
|
-
c[:auto_increment] = primary_keys == 1 && !!(c[:db_type] =~ /int/
|
173
|
+
c[:auto_increment] = primary_keys == 1 && !!(c[:db_type] =~ /int/i)
|
174
174
|
end
|
175
175
|
if !c[:max_length] && c[:type] == :string && (max_length = column_schema_max_length(c[:db_type]))
|
176
176
|
c[:max_length] = max_length
|
@@ -390,25 +390,25 @@ module Sequel
|
|
390
390
|
# such as :integer or :string.
|
391
391
|
def schema_column_type(db_type)
|
392
392
|
case db_type
|
393
|
-
when /\A(character( varying)?|n?(var)?char|n?text|string|clob)/
|
393
|
+
when /\A(character( varying)?|n?(var)?char|n?text|string|clob)/i
|
394
394
|
:string
|
395
|
-
when /\A(int(eger)?|(big|small|tiny)int)/
|
395
|
+
when /\A(int(eger)?|(big|small|tiny)int)/i
|
396
396
|
:integer
|
397
|
-
when /\Adate\z/
|
397
|
+
when /\Adate\z/i
|
398
398
|
:date
|
399
|
-
when /\A((small)?datetime
|
399
|
+
when /\A((small)?datetime(\(\d\))?|timestamp(\(\d\))?( with(out)? time zone)?)\z/i
|
400
400
|
:datetime
|
401
|
-
when /\Atime( with(out)? time zone)?\z/
|
401
|
+
when /\Atime( with(out)? time zone)?\z/i
|
402
402
|
:time
|
403
|
-
when /\A(bool(ean)?)\z/
|
403
|
+
when /\A(bool(ean)?)\z/i
|
404
404
|
:boolean
|
405
|
-
when /\A(real|float( unsigned)?|double( precision)?|double\(\d+,\d+\)( unsigned)?)\z/
|
405
|
+
when /\A(real|float( unsigned)?|double( precision)?|double\(\d+,\d+\)( unsigned)?)\z/i
|
406
406
|
:float
|
407
|
-
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(-?\d+|false|true)\))?))\z/
|
407
|
+
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(-?\d+|false|true)\))?))\z/i
|
408
408
|
$1 && ['0', 'false'].include?($1) ? :integer : :decimal
|
409
|
-
when /bytea|blob|image|(var)?binary/
|
409
|
+
when /bytea|blob|image|(var)?binary/i
|
410
410
|
:blob
|
411
|
-
when /\Aenum/
|
411
|
+
when /\Aenum/i
|
412
412
|
:enum
|
413
413
|
end
|
414
414
|
end
|
@@ -21,11 +21,17 @@
|
|
21
21
|
# DateTime :: timestamp (or timestamptz if pg_timestamptz extension is used)
|
22
22
|
# Sequel::SQLTime :: time
|
23
23
|
# Sequel::SQL::Blob :: bytea
|
24
|
+
#
|
25
|
+
# Arrays of string values are not automatically converted by default, because the Ruby
|
26
|
+
# String class can represent a number of different database types. To convert
|
27
|
+
# arrays of Ruby strings to an untyped array (a query parameter with no explicit
|
28
|
+
# type cast), set the +:treat_string_list_as_untyped_array+ Database option
|
29
|
+
# before loading the extension.
|
24
30
|
#
|
25
|
-
#
|
26
|
-
# +:treat_string_list_as_text_array+ Database option is used. This
|
27
|
-
#
|
28
|
-
#
|
31
|
+
# If you will only be using arrays of Ruby strings that represent the +text+ type,
|
32
|
+
# you can use the +:treat_string_list_as_text_array+ Database option is used. This
|
33
|
+
# can break programs, since the type for literal strings in PostgreSQL is +unknown+,
|
34
|
+
# not +text+.
|
29
35
|
#
|
30
36
|
# The conversion is only done for single dimensional arrays that have two or
|
31
37
|
# more elements, where all elements are of the same class (other than
|
@@ -42,6 +48,47 @@ module Sequel
|
|
42
48
|
module Postgres
|
43
49
|
# Enable automatically parameterizing queries.
|
44
50
|
module AutoParameterizeInArray
|
51
|
+
module TreatStringListAsUntypedArray
|
52
|
+
# Sentinal value to use as an auto param type to use auto parameterization
|
53
|
+
# of a string array without an explicit type cast.
|
54
|
+
NO_EXPLICIT_CAST = Object.new.freeze
|
55
|
+
|
56
|
+
# Wrapper for untyped PGArray values that will be parameterized directly
|
57
|
+
# into the query. This should only be used in cases where you know the
|
58
|
+
# value should be added as a query parameter.
|
59
|
+
class ParameterizedUntypedPGArray < SQL::Wrapper
|
60
|
+
def to_s_append(ds, sql)
|
61
|
+
sql.add_arg(@value)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Recognize NO_EXPLICIT_CAST sentinal value and use wrapped
|
68
|
+
# PGArray that will be parameterized into the query.
|
69
|
+
def _convert_array_to_pg_array_with_type(r, type)
|
70
|
+
if NO_EXPLICIT_CAST.equal?(type)
|
71
|
+
ParameterizedUntypedPGArray.new(Sequel.pg_array(r))
|
72
|
+
else
|
73
|
+
super
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Use a query parameter with no type cast for string arrays.
|
78
|
+
def _bound_variable_type_for_string_array(r)
|
79
|
+
NO_EXPLICIT_CAST
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
module TreatStringListAsTextArray
|
84
|
+
private
|
85
|
+
|
86
|
+
# Assume all string arrays used on RHS of IN/NOT IN are for type text[]
|
87
|
+
def _bound_variable_type_for_string_array(r)
|
88
|
+
"text"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
45
92
|
# Transform column IN (...) expressions into column = ANY($)
|
46
93
|
# and column NOT IN (...) expressions into column != ALL($)
|
47
94
|
# using an array bound variable for the ANY/ALL argument,
|
@@ -61,7 +108,7 @@ module Sequel
|
|
61
108
|
op = :!=
|
62
109
|
func = :ALL
|
63
110
|
end
|
64
|
-
args = [l, Sequel.function(func,
|
111
|
+
args = [l, Sequel.function(func, _convert_array_to_pg_array_with_type(r, type))]
|
65
112
|
end
|
66
113
|
end
|
67
114
|
|
@@ -73,7 +120,7 @@ module Sequel
|
|
73
120
|
# The bound variable type string to use for the bound variable array.
|
74
121
|
# Returns nil if a bound variable should not be used for the array.
|
75
122
|
def _bound_variable_type_for_array(r)
|
76
|
-
return unless Array === r && r.size >=
|
123
|
+
return unless Array === r && r.size >= pg_auto_parameterize_min_array_size
|
77
124
|
classes = r.map(&:class)
|
78
125
|
classes.uniq!
|
79
126
|
classes.delete(NilClass)
|
@@ -86,7 +133,7 @@ module Sequel
|
|
86
133
|
# arrays natively (though the SQL used is different)
|
87
134
|
"int8"
|
88
135
|
elsif klass == String
|
89
|
-
|
136
|
+
_bound_variable_type_for_string_array(r)
|
90
137
|
elsif klass == BigDecimal
|
91
138
|
"numeric"
|
92
139
|
elsif klass == Date
|
@@ -105,11 +152,42 @@ module Sequel
|
|
105
152
|
"bytea"
|
106
153
|
end
|
107
154
|
end
|
155
|
+
|
156
|
+
# Do not auto parameterize string arrays by default.
|
157
|
+
def _bound_variable_type_for_string_array(r)
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
|
161
|
+
# The minimium size of array to auto parameterize.
|
162
|
+
def pg_auto_parameterize_min_array_size
|
163
|
+
2
|
164
|
+
end
|
165
|
+
|
166
|
+
# Convert RHS of IN/NOT IN operator to PGArray with given type.
|
167
|
+
def _convert_array_to_pg_array_with_type(r, type)
|
168
|
+
Sequel.pg_array(r, type)
|
169
|
+
end
|
108
170
|
end
|
109
171
|
end
|
110
172
|
|
111
173
|
Database.register_extension(:pg_auto_parameterize_in_array) do |db|
|
112
174
|
db.extension(:pg_array, :pg_auto_parameterize)
|
113
175
|
db.extend_datasets(Postgres::AutoParameterizeInArray)
|
176
|
+
|
177
|
+
if db.typecast_value(:boolean, db.opts[:treat_string_list_as_text_array])
|
178
|
+
db.extend_datasets(Postgres::AutoParameterizeInArray::TreatStringListAsTextArray)
|
179
|
+
elsif db.typecast_value(:boolean, db.opts[:treat_string_list_as_untyped_array])
|
180
|
+
db.extend_datasets(Postgres::AutoParameterizeInArray::TreatStringListAsUntypedArray)
|
181
|
+
end
|
182
|
+
|
183
|
+
if min_array_size = db.opts[:pg_auto_parameterize_min_array_size]
|
184
|
+
min_array_size = db.typecast_value(:integer, min_array_size)
|
185
|
+
mod = Module.new do
|
186
|
+
define_method(:pg_auto_parameterize_min_array_size){min_array_size}
|
187
|
+
private :pg_auto_parameterize_min_array_size
|
188
|
+
end
|
189
|
+
Sequel.set_temp_name(mod){"Sequel::Postgres::AutoParameterizeInArray::_MinArraySize#{min_array_size}"}
|
190
|
+
db.extend_datasets(mod)
|
191
|
+
end
|
114
192
|
end
|
115
193
|
end
|
@@ -257,7 +257,7 @@ END_MIG
|
|
257
257
|
gen.foreign_key(name, table, col_opts)
|
258
258
|
else
|
259
259
|
gen.column(name, type, col_opts)
|
260
|
-
if [Integer, :Bignum, Float, BigDecimal].include?(type) && schema[:db_type] =~ / unsigned\z/
|
260
|
+
if [Integer, :Bignum, Float, BigDecimal].include?(type) && schema[:db_type] =~ / unsigned\z/i
|
261
261
|
gen.check(Sequel::SQL::Identifier.new(name) >= 0)
|
262
262
|
end
|
263
263
|
end
|
@@ -414,6 +414,12 @@ module Sequel
|
|
414
414
|
false
|
415
415
|
end
|
416
416
|
|
417
|
+
# Hash value for the association reflection. This is precomputed to avoid
|
418
|
+
# concurrency issues at runtime.
|
419
|
+
def hash
|
420
|
+
self[:_hash]
|
421
|
+
end
|
422
|
+
|
417
423
|
# Initialize the associations cache for the current association for the given objects.
|
418
424
|
def initialize_association_cache(objects)
|
419
425
|
name = self[:name]
|
@@ -1931,6 +1937,8 @@ module Sequel
|
|
1931
1937
|
# Remove :class entry if it exists and is nil, to work with cached_fetch
|
1932
1938
|
opts.delete(:class) unless opts[:class]
|
1933
1939
|
|
1940
|
+
opts[:_hash] = [self, name].hash
|
1941
|
+
|
1934
1942
|
def_association(opts)
|
1935
1943
|
|
1936
1944
|
orig_opts.delete(:clone)
|
@@ -3608,7 +3616,7 @@ module Sequel
|
|
3608
3616
|
|
3609
3617
|
# Prepare a hash loaders and eager options which will be used to implement the eager loading.
|
3610
3618
|
def prepare_eager_load(a, reflections, eager_assoc)
|
3611
|
-
eager_load_data = {}
|
3619
|
+
eager_load_data = {}.compare_by_identity
|
3612
3620
|
|
3613
3621
|
# Key is foreign/primary key name symbol.
|
3614
3622
|
# Value is hash with keys being foreign/primary key values (generally integers)
|
@@ -39,6 +39,9 @@ module Sequel
|
|
39
39
|
#
|
40
40
|
# Album.first.artist # no error
|
41
41
|
#
|
42
|
+
# This behavior of enabling +forbid_lazy_load+ automatically from dataset
|
43
|
+
# methods can be disabled using the plugin's +:allow_by_default+ option.
|
44
|
+
#
|
42
45
|
# You can allow lazy loading associations for an instance that it
|
43
46
|
# was previously forbidden for:
|
44
47
|
#
|
@@ -98,7 +101,17 @@ module Sequel
|
|
98
101
|
#
|
99
102
|
# # Make the Album class support forbidding lazy load
|
100
103
|
# Album.plugin :forbid_lazy_load
|
104
|
+
#
|
105
|
+
# # Let lazy loading be forbidden by object, but not automatically for any
|
106
|
+
# # object loaded via dataset.
|
107
|
+
# Album.plugin :forbid_lazy_load, allow_by_default: true
|
101
108
|
module ForbidLazyLoad
|
109
|
+
def self.apply(model, opts=OPTS)
|
110
|
+
unless opts[:allow_by_default]
|
111
|
+
model.send(:dataset_extend, ForbidByDefault, :create_class_methods=>false)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
102
115
|
# Error raised when attempting to lazy load an association when
|
103
116
|
# lazy loading has been forbidden.
|
104
117
|
class Error < StandardError
|
@@ -179,7 +192,7 @@ module Sequel
|
|
179
192
|
end
|
180
193
|
end
|
181
194
|
|
182
|
-
module
|
195
|
+
module ForbidByDefault
|
183
196
|
# Mark model instances retrieved in this call as forbidding lazy loading.
|
184
197
|
def each
|
185
198
|
if row_proc
|
@@ -188,11 +188,10 @@ module Sequel
|
|
188
188
|
|
189
189
|
# Create a new associated object with the given attributes, validate
|
190
190
|
# it when the parent is validated, and save it when the object is saved.
|
191
|
-
# Returns the object
|
191
|
+
# Returns the new object.
|
192
192
|
def nested_attributes_create(meta, attributes)
|
193
|
+
obj = nested_attributes_new(meta, attributes)
|
193
194
|
reflection = meta[:reflection]
|
194
|
-
obj = reflection.associated_class.new
|
195
|
-
nested_attributes_set_attributes(meta, obj, attributes)
|
196
195
|
delay_validate_associated_object(reflection, obj)
|
197
196
|
if reflection.returns_array?
|
198
197
|
public_send(reflection[:name]) << obj
|
@@ -254,7 +253,13 @@ module Sequel
|
|
254
253
|
end
|
255
254
|
obj
|
256
255
|
end
|
257
|
-
|
256
|
+
|
257
|
+
# Returns a new object of the associated class with the given attributes set.
|
258
|
+
def nested_attributes_new(meta, attributes)
|
259
|
+
obj = meta[:reflection].associated_class.new
|
260
|
+
nested_attributes_set_attributes(meta, obj, attributes)
|
261
|
+
end
|
262
|
+
|
258
263
|
# Set the fields in the obj based on the association, only allowing
|
259
264
|
# specific :fields if configured.
|
260
265
|
def nested_attributes_set_attributes(meta, obj, attributes)
|
@@ -135,7 +135,12 @@ module Sequel
|
|
135
135
|
raise Error, "No pg_auto_constraint_validations setup" unless file = @pg_auto_constraint_validations_cache_file
|
136
136
|
pg_auto_constraint_validations_cache = {}
|
137
137
|
@pg_auto_constraint_validations_cache.sort.each do |k, v|
|
138
|
-
|
138
|
+
h = {}
|
139
|
+
v.each do |k, entry|
|
140
|
+
entry = Hash[entry.sort] if entry.is_a?(Hash)
|
141
|
+
h[k] = entry
|
142
|
+
end
|
143
|
+
pg_auto_constraint_validations_cache[k] = h
|
139
144
|
end
|
140
145
|
File.open(file, 'wb'){|f| f.write(Marshal.dump(pg_auto_constraint_validations_cache))}
|
141
146
|
nil
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module Plugins
|
5
|
+
# The pg_auto_validate_enums plugin implements automatic validations for
|
6
|
+
# enum columns, ensuring that enum columns have a valid value. With this
|
7
|
+
# plugin, trying to save with an invalid enum value results in
|
8
|
+
# Sequel::ValidationFailed before saving, instead of Sequel::DatabaseError
|
9
|
+
# (wrapping PG::InvalidTextRepresentation or similar exception) during saving.
|
10
|
+
#
|
11
|
+
# class Person < Sequel::Model
|
12
|
+
# # assume state enum column with allowed values active and inactive
|
13
|
+
# plugin :pg_auto_validate_enums
|
14
|
+
# end
|
15
|
+
# p = Person.new(state: "active").valid? # => true
|
16
|
+
# p = Person.new(state: "inactive").valid? # => true
|
17
|
+
# p = Person.new(state: "other").valid? # => false
|
18
|
+
#
|
19
|
+
# While you can load this into individual model classes, typical use would
|
20
|
+
# be to load it into Sequel::Model or the appropriate model base class,
|
21
|
+
# and have all models that inherit from that class automatically pick it up.
|
22
|
+
#
|
23
|
+
# This plugin depends on the validation_helpers plugin.
|
24
|
+
module PgAutoValidateEnums
|
25
|
+
# Load the validation_helpers plugin.
|
26
|
+
def self.apply(model, opts=OPTS)
|
27
|
+
model.plugin(:validation_helpers)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Load the pg_enum extension into the database, and reload the schema
|
31
|
+
# if it is already loaded. The opts given are used for the validates_includes
|
32
|
+
# validations (with allow_nil: true and from: :values enabled by default,
|
33
|
+
# to avoid issues with nullable enum columns and cases where the column
|
34
|
+
# method has been overridden.
|
35
|
+
def self.configure(model, opts=OPTS)
|
36
|
+
model.instance_exec do
|
37
|
+
db.extension(:pg_enum) unless @db.instance_variable_get(:@enum_labels)
|
38
|
+
if @db_schema
|
39
|
+
get_db_schema(true)
|
40
|
+
_get_pg_pg_auto_validate_enums_metadata
|
41
|
+
end
|
42
|
+
@pg_auto_validate_enums_opts = {allow_nil: true, from: :values}.merge!(opts).freeze
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module ClassMethods
|
47
|
+
# Hash with enum column symbol values and arrays of valid string values.
|
48
|
+
attr_reader :pg_auto_validate_enums_metadata
|
49
|
+
|
50
|
+
# Options to pass to the validates_includes calls used by the plugin.
|
51
|
+
attr_reader :pg_auto_validate_enums_opts
|
52
|
+
|
53
|
+
Plugins.after_set_dataset(self, :_get_pg_pg_auto_validate_enums_metadata)
|
54
|
+
|
55
|
+
Plugins.inherited_instance_variables(self,
|
56
|
+
:@pg_auto_validate_enums_metadata=>nil,
|
57
|
+
:@pg_auto_validate_enums_opts=>nil)
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Parse the column schema to find columns with :enum_values entries,
|
62
|
+
# which will be used to setup validations.
|
63
|
+
def _get_pg_pg_auto_validate_enums_metadata
|
64
|
+
metadata = {}
|
65
|
+
@db_schema.each do |key, sch|
|
66
|
+
if enum_values = sch[:enum_values]
|
67
|
+
metadata[key] = enum_values
|
68
|
+
end
|
69
|
+
end
|
70
|
+
@pg_auto_validate_enums_metadata = metadata.freeze
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module InstanceMethods
|
75
|
+
# Validate that all of the model's enum columns have valid values.
|
76
|
+
def validate
|
77
|
+
super
|
78
|
+
|
79
|
+
klass = self.class
|
80
|
+
opts = klass.pg_auto_validate_enums_opts
|
81
|
+
klass.pg_auto_validate_enums_metadata.each do |column, values|
|
82
|
+
validates_includes(values, column, opts)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/sequel/version.rb
CHANGED
@@ -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 =
|
9
|
+
MINOR = 91
|
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,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.91.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-04-01 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bigdecimal
|
@@ -371,6 +371,7 @@ files:
|
|
371
371
|
- lib/sequel/plugins/paged_operations.rb
|
372
372
|
- lib/sequel/plugins/pg_array_associations.rb
|
373
373
|
- lib/sequel/plugins/pg_auto_constraint_validations.rb
|
374
|
+
- lib/sequel/plugins/pg_auto_validate_enums.rb
|
374
375
|
- lib/sequel/plugins/pg_eager_any_typed_array.rb
|
375
376
|
- lib/sequel/plugins/pg_row.rb
|
376
377
|
- lib/sequel/plugins/pg_xmin_optimistic_locking.rb
|