sequel 5.45.0 → 5.77.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/CHANGELOG +434 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +59 -27
- data/bin/sequel +11 -3
- data/doc/advanced_associations.rdoc +16 -14
- data/doc/association_basics.rdoc +119 -24
- data/doc/cheat_sheet.rdoc +11 -3
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +27 -6
- data/doc/model_hooks.rdoc +1 -1
- data/doc/object_model.rdoc +8 -8
- data/doc/opening_databases.rdoc +28 -12
- data/doc/postgresql.rdoc +16 -8
- data/doc/querying.rdoc +5 -3
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/release_notes/5.50.0.txt +78 -0
- data/doc/release_notes/5.51.0.txt +47 -0
- data/doc/release_notes/5.52.0.txt +87 -0
- data/doc/release_notes/5.53.0.txt +23 -0
- data/doc/release_notes/5.54.0.txt +27 -0
- data/doc/release_notes/5.55.0.txt +21 -0
- data/doc/release_notes/5.56.0.txt +51 -0
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/release_notes/5.60.0.txt +22 -0
- data/doc/release_notes/5.61.0.txt +43 -0
- data/doc/release_notes/5.62.0.txt +132 -0
- data/doc/release_notes/5.63.0.txt +33 -0
- data/doc/release_notes/5.64.0.txt +50 -0
- data/doc/release_notes/5.65.0.txt +21 -0
- data/doc/release_notes/5.66.0.txt +24 -0
- data/doc/release_notes/5.67.0.txt +32 -0
- data/doc/release_notes/5.68.0.txt +61 -0
- data/doc/release_notes/5.69.0.txt +26 -0
- data/doc/release_notes/5.70.0.txt +35 -0
- data/doc/release_notes/5.71.0.txt +21 -0
- data/doc/release_notes/5.72.0.txt +33 -0
- data/doc/release_notes/5.73.0.txt +66 -0
- data/doc/release_notes/5.74.0.txt +45 -0
- data/doc/release_notes/5.75.0.txt +35 -0
- data/doc/release_notes/5.76.0.txt +86 -0
- data/doc/release_notes/5.77.0.txt +63 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/security.rdoc +9 -9
- data/doc/sharding.rdoc +3 -1
- data/doc/sql.rdoc +27 -15
- data/doc/testing.rdoc +23 -13
- data/doc/transactions.rdoc +6 -6
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/ado.rb +1 -1
- data/lib/sequel/adapters/amalgalite.rb +3 -5
- data/lib/sequel/adapters/ibmdb.rb +3 -3
- data/lib/sequel/adapters/jdbc/derby.rb +8 -0
- data/lib/sequel/adapters/jdbc/h2.rb +63 -10
- data/lib/sequel/adapters/jdbc/hsqldb.rb +8 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
- data/lib/sequel/adapters/jdbc.rb +24 -22
- data/lib/sequel/adapters/mysql.rb +92 -67
- data/lib/sequel/adapters/mysql2.rb +56 -51
- data/lib/sequel/adapters/odbc/mssql.rb +1 -1
- data/lib/sequel/adapters/odbc.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +4 -3
- data/lib/sequel/adapters/postgres.rb +89 -45
- data/lib/sequel/adapters/shared/access.rb +11 -1
- data/lib/sequel/adapters/shared/db2.rb +42 -0
- data/lib/sequel/adapters/shared/mssql.rb +91 -10
- data/lib/sequel/adapters/shared/mysql.rb +78 -3
- data/lib/sequel/adapters/shared/oracle.rb +86 -7
- data/lib/sequel/adapters/shared/postgres.rb +576 -171
- data/lib/sequel/adapters/shared/sqlanywhere.rb +21 -5
- data/lib/sequel/adapters/shared/sqlite.rb +92 -8
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +99 -18
- data/lib/sequel/adapters/tinytds.rb +1 -1
- data/lib/sequel/adapters/trilogy.rb +117 -0
- data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/ast_transformer.rb +6 -0
- data/lib/sequel/connection_pool/sharded_single.rb +5 -7
- data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
- data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
- data/lib/sequel/connection_pool/single.rb +6 -8
- data/lib/sequel/connection_pool/threaded.rb +14 -8
- data/lib/sequel/connection_pool/timed_queue.rb +270 -0
- data/lib/sequel/connection_pool.rb +57 -31
- data/lib/sequel/core.rb +17 -18
- data/lib/sequel/database/connecting.rb +27 -3
- data/lib/sequel/database/dataset.rb +16 -6
- data/lib/sequel/database/misc.rb +70 -14
- data/lib/sequel/database/query.rb +73 -2
- data/lib/sequel/database/schema_generator.rb +11 -6
- data/lib/sequel/database/schema_methods.rb +23 -4
- data/lib/sequel/database/transactions.rb +6 -0
- data/lib/sequel/dataset/actions.rb +111 -15
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
- data/lib/sequel/dataset/features.rb +20 -1
- data/lib/sequel/dataset/misc.rb +12 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
- data/lib/sequel/dataset/query.rb +170 -41
- data/lib/sequel/dataset/sql.rb +190 -71
- data/lib/sequel/dataset.rb +4 -0
- data/lib/sequel/extensions/_model_pg_row.rb +0 -12
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/any_not_empty.rb +2 -2
- data/lib/sequel/extensions/async_thread_pool.rb +14 -13
- data/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
- data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/connection_expiration.rb +15 -9
- data/lib/sequel/extensions/connection_validator.rb +16 -11
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/core_refinements.rb +36 -11
- data/lib/sequel/extensions/date_arithmetic.rb +36 -8
- data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
- data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +11 -10
- data/lib/sequel/extensions/index_caching.rb +5 -1
- data/lib/sequel/extensions/inflector.rb +1 -1
- data/lib/sequel/extensions/is_distinct_from.rb +141 -0
- data/lib/sequel/extensions/looser_typecasting.rb +3 -0
- data/lib/sequel/extensions/migration.rb +57 -15
- data/lib/sequel/extensions/named_timezones.rb +22 -6
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +33 -4
- data/lib/sequel/extensions/pg_array_ops.rb +2 -2
- data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
- data/lib/sequel/extensions/pg_enum.rb +1 -2
- data/lib/sequel/extensions/pg_extended_date_support.rb +39 -28
- data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
- data/lib/sequel/extensions/pg_hstore.rb +6 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
- data/lib/sequel/extensions/pg_inet.rb +10 -11
- data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
- data/lib/sequel/extensions/pg_interval.rb +11 -11
- data/lib/sequel/extensions/pg_json.rb +13 -15
- data/lib/sequel/extensions/pg_json_ops.rb +125 -2
- data/lib/sequel/extensions/pg_multirange.rb +367 -0
- data/lib/sequel/extensions/pg_range.rb +13 -26
- data/lib/sequel/extensions/pg_range_ops.rb +37 -9
- data/lib/sequel/extensions/pg_row.rb +20 -19
- data/lib/sequel/extensions/pg_row_ops.rb +1 -1
- data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
- data/lib/sequel/extensions/round_timestamps.rb +1 -1
- data/lib/sequel/extensions/s.rb +2 -1
- data/lib/sequel/extensions/schema_caching.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +45 -11
- data/lib/sequel/extensions/server_block.rb +10 -13
- data/lib/sequel/extensions/set_literalizer.rb +58 -0
- data/lib/sequel/extensions/sql_comments.rb +110 -3
- data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
- data/lib/sequel/extensions/string_agg.rb +1 -1
- data/lib/sequel/extensions/string_date_time.rb +19 -23
- data/lib/sequel/extensions/symbol_aref.rb +2 -0
- data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
- data/lib/sequel/model/associations.rb +286 -92
- data/lib/sequel/model/base.rb +53 -33
- data/lib/sequel/model/dataset_module.rb +3 -0
- data/lib/sequel/model/errors.rb +10 -1
- data/lib/sequel/model/exceptions.rb +15 -3
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
- data/lib/sequel/plugins/auto_validations.rb +74 -16
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/column_encryption.rb +29 -8
- data/lib/sequel/plugins/composition.rb +3 -2
- data/lib/sequel/plugins/concurrent_eager_loading.rb +4 -4
- data/lib/sequel/plugins/constraint_validations.rb +8 -5
- data/lib/sequel/plugins/defaults_setter.rb +16 -0
- data/lib/sequel/plugins/dirty.rb +1 -1
- data/lib/sequel/plugins/enum.rb +124 -0
- data/lib/sequel/plugins/finder.rb +4 -2
- data/lib/sequel/plugins/insert_conflict.rb +4 -0
- data/lib/sequel/plugins/instance_specific_default.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/lazy_attributes.rb +3 -0
- data/lib/sequel/plugins/list.rb +8 -3
- data/lib/sequel/plugins/many_through_many.rb +109 -10
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
- data/lib/sequel/plugins/nested_attributes.rb +4 -4
- data/lib/sequel/plugins/optimistic_locking.rb +9 -42
- data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
- data/lib/sequel/plugins/paged_operations.rb +181 -0
- data/lib/sequel/plugins/pg_array_associations.rb +46 -34
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +9 -3
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
- data/lib/sequel/plugins/prepared_statements.rb +12 -2
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
- data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
- data/lib/sequel/plugins/rcte_tree.rb +7 -4
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/serialization.rb +1 -0
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
- data/lib/sequel/plugins/sql_comments.rb +189 -0
- data/lib/sequel/plugins/static_cache.rb +39 -1
- data/lib/sequel/plugins/static_cache_cache.rb +5 -1
- data/lib/sequel/plugins/subclasses.rb +28 -11
- data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +1 -1
- data/lib/sequel/plugins/validate_associated.rb +22 -12
- data/lib/sequel/plugins/validation_helpers.rb +41 -11
- data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/timezones.rb +12 -14
- data/lib/sequel/version.rb +1 -1
- metadata +109 -19
data/lib/sequel/model/base.rb
CHANGED
@@ -606,6 +606,7 @@ module Sequel
|
|
606
606
|
@db_schema = get_db_schema
|
607
607
|
end
|
608
608
|
|
609
|
+
@fast_pk_lookup_sql = @fast_instance_delete_sql = nil unless @dataset.supports_placeholder_literalizer?
|
609
610
|
reset_instance_dataset
|
610
611
|
self
|
611
612
|
end
|
@@ -680,24 +681,26 @@ module Sequel
|
|
680
681
|
|
681
682
|
private
|
682
683
|
|
683
|
-
# Yield to the passed block and if do_raise is false, swallow
|
684
|
+
# Yield to the passed block and if do_raise is false, swallow Sequel::Errors other than DatabaseConnectionError
|
685
|
+
# and DatabaseDisconnectError.
|
684
686
|
def check_non_connection_error(do_raise=require_valid_table)
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
raise if do_raise
|
691
|
-
end
|
687
|
+
db.transaction(:savepoint=>:only){yield}
|
688
|
+
rescue Sequel::DatabaseConnectionError, Sequel::DatabaseDisconnectError
|
689
|
+
raise
|
690
|
+
rescue Sequel::Error
|
691
|
+
raise if do_raise
|
692
692
|
end
|
693
693
|
|
694
694
|
# Convert the given object to a Dataset that should be used as
|
695
695
|
# this model's dataset.
|
696
696
|
def convert_input_dataset(ds)
|
697
697
|
case ds
|
698
|
-
when Symbol, SQL::Identifier, SQL::QualifiedIdentifier
|
698
|
+
when Symbol, SQL::Identifier, SQL::QualifiedIdentifier
|
699
699
|
self.simple_table = db.literal(ds).freeze
|
700
700
|
ds = db.from(ds)
|
701
|
+
when SQL::AliasedExpression, LiteralString
|
702
|
+
self.simple_table = nil
|
703
|
+
ds = db.from(ds)
|
701
704
|
when Dataset
|
702
705
|
ds = ds.from_self(:alias=>ds.first_source) if ds.joined_dataset?
|
703
706
|
|
@@ -786,7 +789,7 @@ module Sequel
|
|
786
789
|
schema_hash = {}
|
787
790
|
ds_opts = dataset.opts
|
788
791
|
get_columns = proc{check_non_connection_error{columns} || []}
|
789
|
-
schema_array =
|
792
|
+
schema_array = get_db_schema_array(reload) if db.supports_schema_parsing?
|
790
793
|
if schema_array
|
791
794
|
schema_array.each{|k,v| schema_hash[k] = v}
|
792
795
|
|
@@ -823,6 +826,12 @@ module Sequel
|
|
823
826
|
schema_hash
|
824
827
|
end
|
825
828
|
|
829
|
+
# Get the array of schema information for the dataset. Returns nil if
|
830
|
+
# the schema information cannot be determined.
|
831
|
+
def get_db_schema_array(reload)
|
832
|
+
check_non_connection_error(false){db.schema(dataset, :reload=>reload)}
|
833
|
+
end
|
834
|
+
|
826
835
|
# Uncached version of setter_methods, to be overridden by plugins
|
827
836
|
# that want to modify the methods used.
|
828
837
|
def get_setter_methods
|
@@ -1093,7 +1102,7 @@ module Sequel
|
|
1093
1102
|
@modified = true
|
1094
1103
|
initialize_set(values)
|
1095
1104
|
_clear_changed_columns(:initialize)
|
1096
|
-
yield self if
|
1105
|
+
yield self if defined?(yield)
|
1097
1106
|
end
|
1098
1107
|
|
1099
1108
|
# Returns value of the column's attribute.
|
@@ -1133,7 +1142,7 @@ module Sequel
|
|
1133
1142
|
#
|
1134
1143
|
# Artist[1] === Artist[1] # => true
|
1135
1144
|
# Artist.new === Artist.new # => false
|
1136
|
-
# Artist[1].set(:
|
1145
|
+
# Artist[1].set(name: 'Bob') === Artist[1] # => true
|
1137
1146
|
def ===(obj)
|
1138
1147
|
case pkv = pk
|
1139
1148
|
when nil
|
@@ -1152,7 +1161,7 @@ module Sequel
|
|
1152
1161
|
#
|
1153
1162
|
# Artist[1].pk_equal?(Artist[1]) # => true
|
1154
1163
|
# Artist.new.pk_equal?(Artist.new) # => false
|
1155
|
-
# Artist[1].set(:
|
1164
|
+
# Artist[1].set(name: 'Bob').pk_equal?(Artist[1]) # => true
|
1156
1165
|
alias pk_equal? ===
|
1157
1166
|
|
1158
1167
|
# class is defined in Object, but it is also a keyword,
|
@@ -1224,7 +1233,7 @@ module Sequel
|
|
1224
1233
|
#
|
1225
1234
|
# Artist[1] == Artist[1] # => true
|
1226
1235
|
# Artist.new == Artist.new # => true
|
1227
|
-
# Artist[1].set(:
|
1236
|
+
# Artist[1].set(name: 'Bob') == Artist[1] # => false
|
1228
1237
|
def eql?(obj)
|
1229
1238
|
(obj.class == model) && (obj.values == @values)
|
1230
1239
|
end
|
@@ -1235,18 +1244,21 @@ module Sequel
|
|
1235
1244
|
@errors ||= errors_class.new
|
1236
1245
|
end
|
1237
1246
|
|
1247
|
+
EXISTS_SELECT_ = SQL::AliasedExpression.new(1, :one)
|
1248
|
+
private_constant :EXISTS_SELECT_
|
1249
|
+
|
1238
1250
|
# Returns true when current instance exists, false otherwise.
|
1239
1251
|
# Generally an object that isn't new will exist unless it has
|
1240
1252
|
# been deleted. Uses a database query to check for existence,
|
1241
1253
|
# unless the model object is new, in which case this is always
|
1242
1254
|
# false.
|
1243
1255
|
#
|
1244
|
-
# Artist[1].exists? # SELECT 1 FROM artists WHERE (id = 1)
|
1256
|
+
# Artist[1].exists? # SELECT 1 AS one FROM artists WHERE (id = 1)
|
1245
1257
|
# # => true
|
1246
1258
|
# Artist.new.exists?
|
1247
1259
|
# # => false
|
1248
1260
|
def exists?
|
1249
|
-
new? ? false : !this.get(
|
1261
|
+
new? ? false : !this.get(EXISTS_SELECT_).nil?
|
1250
1262
|
end
|
1251
1263
|
|
1252
1264
|
# Ignore the model's setter method cache when this instances extends a module, as the
|
@@ -1326,13 +1338,13 @@ module Sequel
|
|
1326
1338
|
# a = Artist[1]
|
1327
1339
|
# Artist.db.transaction do
|
1328
1340
|
# a.lock!
|
1329
|
-
# a.update(:
|
1341
|
+
# a.update(name: 'A')
|
1330
1342
|
# end
|
1331
1343
|
#
|
1332
1344
|
# a = Artist[2]
|
1333
1345
|
# Artist.db.transaction do
|
1334
1346
|
# a.lock!('FOR NO KEY UPDATE')
|
1335
|
-
# a.update(:
|
1347
|
+
# a.update(name: 'B')
|
1336
1348
|
# end
|
1337
1349
|
def lock!(style=:update)
|
1338
1350
|
_refresh(this.lock_style(style)) unless new?
|
@@ -1630,11 +1642,9 @@ module Sequel
|
|
1630
1642
|
# artist.set(name: 'Invalid').valid? # => false
|
1631
1643
|
# artist.errors.full_messages # => ['name cannot be Invalid']
|
1632
1644
|
def valid?(opts = OPTS)
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
false
|
1637
|
-
end
|
1645
|
+
_valid?(opts)
|
1646
|
+
rescue HookFailed
|
1647
|
+
false
|
1638
1648
|
end
|
1639
1649
|
|
1640
1650
|
private
|
@@ -1938,8 +1948,10 @@ module Sequel
|
|
1938
1948
|
end
|
1939
1949
|
|
1940
1950
|
# If transactions should be used, wrap the yield in a transaction block.
|
1941
|
-
def checked_transaction(opts=OPTS)
|
1942
|
-
|
1951
|
+
def checked_transaction(opts=OPTS, &block)
|
1952
|
+
h = {:server=>this_server}.merge!(opts)
|
1953
|
+
h[:skip_transaction] = true unless use_transaction?(opts)
|
1954
|
+
db.transaction(h, &block)
|
1943
1955
|
end
|
1944
1956
|
|
1945
1957
|
# Change the value of the column to given value, recording the change.
|
@@ -2024,19 +2036,20 @@ module Sequel
|
|
2024
2036
|
meths = setter_methods(type)
|
2025
2037
|
strict = strict_param_setting
|
2026
2038
|
hash.each do |k,v|
|
2039
|
+
k = k.to_s
|
2027
2040
|
m = "#{k}="
|
2028
2041
|
if meths.include?(m)
|
2029
2042
|
set_column_value(m, v)
|
2030
2043
|
elsif strict
|
2031
2044
|
# Avoid using respond_to? or creating symbols from user input
|
2032
2045
|
if public_methods.map(&:to_s).include?(m)
|
2033
|
-
if Array(model.primary_key).map(&:to_s).member?(k
|
2034
|
-
raise MassAssignmentRestriction
|
2046
|
+
if Array(model.primary_key).map(&:to_s).member?(k) && model.restrict_primary_key?
|
2047
|
+
raise MassAssignmentRestriction.create("#{k} is a restricted primary key", self, k)
|
2035
2048
|
else
|
2036
|
-
raise MassAssignmentRestriction
|
2049
|
+
raise MassAssignmentRestriction.create("#{k} is a restricted column", self, k)
|
2037
2050
|
end
|
2038
2051
|
else
|
2039
|
-
raise MassAssignmentRestriction
|
2052
|
+
raise MassAssignmentRestriction.create("method #{m} doesn't exist", self, k)
|
2040
2053
|
end
|
2041
2054
|
end
|
2042
2055
|
end
|
@@ -2140,8 +2153,9 @@ module Sequel
|
|
2140
2153
|
# # DELETE FROM artists WHERE (id = 2)
|
2141
2154
|
# # ...
|
2142
2155
|
def destroy
|
2143
|
-
|
2144
|
-
|
2156
|
+
@db.transaction(:server=>opts[:server], :skip_transaction=>model.use_transactions == false) do
|
2157
|
+
all(&:destroy).length
|
2158
|
+
end
|
2145
2159
|
end
|
2146
2160
|
|
2147
2161
|
# If there is no order already defined on this dataset, order it by
|
@@ -2221,11 +2235,17 @@ module Sequel
|
|
2221
2235
|
|
2222
2236
|
private
|
2223
2237
|
|
2238
|
+
# Return the dataset ordered by the model's primary key. This should not
|
2239
|
+
# be used if the model does not have a primary key.
|
2240
|
+
def _force_primary_key_order
|
2241
|
+
cached_dataset(:_pk_order_ds){order(*model.primary_key)}
|
2242
|
+
end
|
2243
|
+
|
2224
2244
|
# If the dataset is not already ordered, and the model has a primary key,
|
2225
2245
|
# return a clone ordered by the primary key.
|
2226
2246
|
def _primary_key_order
|
2227
|
-
if @opts[:order].nil? && model &&
|
2228
|
-
|
2247
|
+
if @opts[:order].nil? && model && model.primary_key
|
2248
|
+
_force_primary_key_order
|
2229
2249
|
end
|
2230
2250
|
end
|
2231
2251
|
|
@@ -8,6 +8,9 @@ module Sequel
|
|
8
8
|
# automatically creates class methods for public dataset
|
9
9
|
# methods.
|
10
10
|
class DatasetModule < Dataset::DatasetModule
|
11
|
+
# The model class related to this dataset module.
|
12
|
+
attr_reader :model
|
13
|
+
|
11
14
|
# Store the model related to this dataset module.
|
12
15
|
def initialize(model)
|
13
16
|
@model = model
|
data/lib/sequel/model/errors.rb
CHANGED
@@ -38,7 +38,7 @@ module Sequel
|
|
38
38
|
def full_messages
|
39
39
|
inject([]) do |m, kv|
|
40
40
|
att, errors = *kv
|
41
|
-
errors.each {|e| m << (e.is_a?(LiteralString) ? e :
|
41
|
+
errors.each {|e| m << (e.is_a?(LiteralString) ? e : full_message(att, e))}
|
42
42
|
m
|
43
43
|
end
|
44
44
|
end
|
@@ -53,6 +53,15 @@ module Sequel
|
|
53
53
|
v
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# Create full error message to use for the given attribute (or array of attributes)
|
60
|
+
# and error message. This can be overridden for easier internalization.
|
61
|
+
def full_message(att, error_msg)
|
62
|
+
att = att.join(' and ') if att.is_a?(Array)
|
63
|
+
"#{att} #{error_msg}"
|
64
|
+
end
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
@@ -24,11 +24,23 @@ module Sequel
|
|
24
24
|
UndefinedAssociation = Class.new(Error)
|
25
25
|
).name
|
26
26
|
|
27
|
-
(
|
28
27
|
# Raised when a mass assignment method is called in strict mode with either a restricted column
|
29
28
|
# or a column without a setter method.
|
30
|
-
MassAssignmentRestriction
|
31
|
-
|
29
|
+
class MassAssignmentRestriction < Error
|
30
|
+
# The Sequel::Model object related to this exception.
|
31
|
+
attr_reader :model
|
32
|
+
|
33
|
+
# The column related to this exception, as a string.
|
34
|
+
attr_reader :column
|
35
|
+
|
36
|
+
# Create an instance of this class with the model and column set.
|
37
|
+
def self.create(msg, model, column)
|
38
|
+
e = new("#{msg} for class #{model.class.inspect}")
|
39
|
+
e.instance_variable_set(:@model, model)
|
40
|
+
e.instance_variable_set(:@column, column)
|
41
|
+
e
|
42
|
+
end
|
43
|
+
end
|
32
44
|
|
33
45
|
# Exception class raised when +raise_on_save_failure+ is set and validation fails
|
34
46
|
class ValidationFailed < Error
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module Plugins
|
5
|
+
# The auto_restrict_eager_graph plugin will automatically disallow the use
|
6
|
+
# of eager_graph for associations that have associated blocks but no :graph_*
|
7
|
+
# association options. The reason for this is the block will have an effect
|
8
|
+
# during regular and eager loading, but not loading via eager_graph, and it
|
9
|
+
# is likely that whatever the block is doing should have an equivalent done
|
10
|
+
# when eager_graphing. Most likely, not including a :graph_* option was either
|
11
|
+
# an oversight (and one should be added), or use with eager_graph was never
|
12
|
+
# intended (and usage should be forbidden). Disallowing eager_graph in this
|
13
|
+
# case prevents likely unexpected behavior during eager_graph.
|
14
|
+
#
|
15
|
+
# As an example of this, consider the following code:
|
16
|
+
#
|
17
|
+
# Album.one_to_many :popular_tracks, class: :Track do |ds|
|
18
|
+
# ds = ds.where(popular: true)
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Album.eager(:popular_tracks).all
|
22
|
+
# # SELECT * FROM albums
|
23
|
+
# # SELECT * FROM tracks WHERE ((popular IS TRUE) AND (album_id IN (...)))
|
24
|
+
#
|
25
|
+
# # Notice that no condition for tracks.popular is added.
|
26
|
+
# Album.eager_graph(:popular_tracks).all
|
27
|
+
# # SELECT ... FROM albums LEFT JOIN tracks ON (tracks.album_id = albums.id)
|
28
|
+
#
|
29
|
+
# With the auto_restrict_eager_graph plugin, the eager_graph call above will
|
30
|
+
# raise an error, alerting you to the fact that you either should not be
|
31
|
+
# using eager_graph with the association, or that you should be adding an
|
32
|
+
# appropriate :graph_* option, such as:
|
33
|
+
#
|
34
|
+
# Album.one_to_many :popular_tracks, class: :Track, graph_conditions: {popular: true} do |ds|
|
35
|
+
# ds = ds.where(popular: true)
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Usage:
|
39
|
+
#
|
40
|
+
# # Automatically restrict eager_graph for associations if appropriate for all
|
41
|
+
# # model subclasses (called before loading subclasses)
|
42
|
+
# Sequel::Model.plugin :auto_restrict_eager_graph
|
43
|
+
#
|
44
|
+
# # Automatically restrict eager_graph for associations in Album class
|
45
|
+
# Album.plugin :auto_restrict_eager_graph
|
46
|
+
module AutoRestrictEagerGraph
|
47
|
+
module ClassMethods
|
48
|
+
# When defining an association, if a block is given for the association, but
|
49
|
+
# a :graph_* option is not used, disallow the use of eager_graph.
|
50
|
+
def associate(type, name, opts = OPTS, &block)
|
51
|
+
opts = super
|
52
|
+
|
53
|
+
if opts[:block] && !opts.has_key?(:allow_eager_graph) && !opts[:orig_opts].any?{|k,| /\Agraph_/ =~ k}
|
54
|
+
opts[:allow_eager_graph] = false
|
55
|
+
end
|
56
|
+
|
57
|
+
opts
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -9,14 +9,16 @@ module Sequel
|
|
9
9
|
# 2. not_null validations on NOT NULL columns (optionally, presence validations)
|
10
10
|
# 3. unique validations on columns or sets of columns with unique indexes
|
11
11
|
# 4. max length validations on string columns
|
12
|
+
# 5. no null byte validations on string columns
|
13
|
+
# 6. minimum and maximum values on columns
|
12
14
|
#
|
13
|
-
# To determine the columns to use for the type/not_null/max_length validations,
|
15
|
+
# To determine the columns to use for the type/not_null/max_length/no_null_byte/max_value/min_value validations,
|
14
16
|
# the plugin looks at the database schema for the model's table. To determine
|
15
17
|
# the unique validations, Sequel looks at the indexes on the table. In order
|
16
18
|
# for this plugin to be fully functional, the underlying database adapter needs
|
17
19
|
# to support both schema and index parsing. Additionally, unique validations are
|
18
20
|
# only added for models that select from a simple table, they are not added for models
|
19
|
-
# that select from a subquery
|
21
|
+
# that select from a subquery.
|
20
22
|
#
|
21
23
|
# This plugin uses the validation_helpers plugin underneath to implement the
|
22
24
|
# validations. It does not allow for any per-column validation message
|
@@ -50,7 +52,7 @@ module Sequel
|
|
50
52
|
#
|
51
53
|
# Model.plugin :auto_validations, unique_opts: {only_if_modified: true}
|
52
54
|
#
|
53
|
-
# This works for unique_opts, max_length_opts, schema_types_opts,
|
55
|
+
# This works for unique_opts, max_length_opts, schema_types_opts, max_value_opts, min_value_opts, no_null_byte_opts,
|
54
56
|
# explicit_not_null_opts, and not_null_opts.
|
55
57
|
#
|
56
58
|
# If you only want auto_validations to add validations to columns that do not already
|
@@ -71,25 +73,35 @@ module Sequel
|
|
71
73
|
MAX_LENGTH_OPTIONS = {:from=>:values, :allow_nil=>true}.freeze
|
72
74
|
SCHEMA_TYPES_OPTIONS = NOT_NULL_OPTIONS
|
73
75
|
UNIQUE_OPTIONS = NOT_NULL_OPTIONS
|
76
|
+
NO_NULL_BYTE_OPTIONS = MAX_LENGTH_OPTIONS
|
77
|
+
MAX_VALUE_OPTIONS = {:from=>:values, :allow_nil=>true, :skip_invalid=>true}.freeze
|
78
|
+
MIN_VALUE_OPTIONS = MAX_VALUE_OPTIONS
|
79
|
+
AUTO_VALIDATE_OPTIONS = {
|
80
|
+
:no_null_byte=>NO_NULL_BYTE_OPTIONS,
|
81
|
+
:not_null=>NOT_NULL_OPTIONS,
|
82
|
+
:explicit_not_null=>EXPLICIT_NOT_NULL_OPTIONS,
|
83
|
+
:max_length=>MAX_LENGTH_OPTIONS,
|
84
|
+
:max_value=>MAX_VALUE_OPTIONS,
|
85
|
+
:min_value=>MIN_VALUE_OPTIONS,
|
86
|
+
:schema_types=>SCHEMA_TYPES_OPTIONS,
|
87
|
+
:unique=>UNIQUE_OPTIONS
|
88
|
+
}.freeze
|
89
|
+
|
74
90
|
EMPTY_ARRAY = [].freeze
|
75
91
|
|
76
92
|
def self.apply(model, opts=OPTS)
|
77
93
|
model.instance_exec do
|
78
94
|
plugin :validation_helpers
|
79
95
|
@auto_validate_presence = false
|
96
|
+
@auto_validate_no_null_byte_columns = []
|
80
97
|
@auto_validate_not_null_columns = []
|
81
98
|
@auto_validate_explicit_not_null_columns = []
|
82
99
|
@auto_validate_max_length_columns = []
|
100
|
+
@auto_validate_max_value_columns = []
|
101
|
+
@auto_validate_min_value_columns = []
|
83
102
|
@auto_validate_unique_columns = []
|
84
103
|
@auto_validate_types = true
|
85
|
-
|
86
|
-
@auto_validate_options = {
|
87
|
-
:not_null=>NOT_NULL_OPTIONS,
|
88
|
-
:explicit_not_null=>EXPLICIT_NOT_NULL_OPTIONS,
|
89
|
-
:max_length=>MAX_LENGTH_OPTIONS,
|
90
|
-
:schema_types=>SCHEMA_TYPES_OPTIONS,
|
91
|
-
:unique=>UNIQUE_OPTIONS
|
92
|
-
}.freeze
|
104
|
+
@auto_validate_options = AUTO_VALIDATE_OPTIONS
|
93
105
|
end
|
94
106
|
end
|
95
107
|
|
@@ -102,14 +114,14 @@ module Sequel
|
|
102
114
|
end
|
103
115
|
|
104
116
|
h = @auto_validate_options.dup
|
105
|
-
[:not_null, :explicit_not_null, :max_length, :schema_types, :unique].each do |type|
|
117
|
+
[:not_null, :explicit_not_null, :max_length, :max_value, :min_value, :no_null_byte, :schema_types, :unique].each do |type|
|
106
118
|
if type_opts = opts[:"#{type}_opts"]
|
107
119
|
h[type] = h[type].merge(type_opts).freeze
|
108
120
|
end
|
109
121
|
end
|
110
122
|
|
111
123
|
if opts[:skip_invalid]
|
112
|
-
[:not_null, :explicit_not_null, :max_length, :schema_types].each do |type|
|
124
|
+
[:not_null, :explicit_not_null, :no_null_byte, :max_length, :schema_types].each do |type|
|
113
125
|
h[type] = h[type].merge(:skip_invalid=>true).freeze
|
114
126
|
end
|
115
127
|
end
|
@@ -119,6 +131,9 @@ module Sequel
|
|
119
131
|
end
|
120
132
|
|
121
133
|
module ClassMethods
|
134
|
+
# The columns with automatic no_null_byte validations
|
135
|
+
attr_reader :auto_validate_no_null_byte_columns
|
136
|
+
|
122
137
|
# The columns with automatic not_null validations
|
123
138
|
attr_reader :auto_validate_not_null_columns
|
124
139
|
|
@@ -129,13 +144,31 @@ module Sequel
|
|
129
144
|
# pairs, with the first entry being the column name and second entry being the maximum length.
|
130
145
|
attr_reader :auto_validate_max_length_columns
|
131
146
|
|
147
|
+
# The columns with automatch max value validations, as an array of
|
148
|
+
# pairs, with the first entry being the column name and second entry being the maximum value.
|
149
|
+
attr_reader :auto_validate_max_value_columns
|
150
|
+
|
151
|
+
# The columns with automatch min value validations, as an array of
|
152
|
+
# pairs, with the first entry being the column name and second entry being the minimum value.
|
153
|
+
attr_reader :auto_validate_min_value_columns
|
154
|
+
|
132
155
|
# The columns or sets of columns with automatic unique validations
|
133
156
|
attr_reader :auto_validate_unique_columns
|
134
157
|
|
135
158
|
# Inherited options
|
136
159
|
attr_reader :auto_validate_options
|
137
160
|
|
138
|
-
Plugins.inherited_instance_variables(self,
|
161
|
+
Plugins.inherited_instance_variables(self,
|
162
|
+
:@auto_validate_presence=>nil,
|
163
|
+
:@auto_validate_types=>nil,
|
164
|
+
:@auto_validate_no_null_byte_columns=>:dup,
|
165
|
+
:@auto_validate_not_null_columns=>:dup,
|
166
|
+
:@auto_validate_explicit_not_null_columns=>:dup,
|
167
|
+
:@auto_validate_max_length_columns=>:dup,
|
168
|
+
:@auto_validate_max_value_columns=>:dup,
|
169
|
+
:@auto_validate_min_value_columns=>:dup,
|
170
|
+
:@auto_validate_unique_columns=>:dup,
|
171
|
+
:@auto_validate_options => :dup)
|
139
172
|
Plugins.after_set_dataset(self, :setup_auto_validations)
|
140
173
|
|
141
174
|
# Whether to use a presence validation for not null columns
|
@@ -150,20 +183,27 @@ module Sequel
|
|
150
183
|
|
151
184
|
# Freeze auto_validation settings when freezing model class.
|
152
185
|
def freeze
|
186
|
+
@auto_validate_no_null_byte_columns.freeze
|
153
187
|
@auto_validate_not_null_columns.freeze
|
154
188
|
@auto_validate_explicit_not_null_columns.freeze
|
155
189
|
@auto_validate_max_length_columns.freeze
|
190
|
+
@auto_validate_max_value_columns.freeze
|
191
|
+
@auto_validate_min_value_columns.freeze
|
156
192
|
@auto_validate_unique_columns.freeze
|
157
193
|
|
158
194
|
super
|
159
195
|
end
|
160
196
|
|
161
|
-
# Skip automatic validations for the given validation type
|
197
|
+
# Skip automatic validations for the given validation type
|
198
|
+
# (:not_null, :no_null_byte, :types, :unique, :max_length, :max_value, :min_value).
|
162
199
|
# If :all is given as the type, skip all auto validations.
|
200
|
+
#
|
201
|
+
# Skipping types validation automatically skips max_value and min_value validations,
|
202
|
+
# since those validations require valid types.
|
163
203
|
def skip_auto_validations(type)
|
164
204
|
case type
|
165
205
|
when :all
|
166
|
-
[:not_null, :types, :unique, :max_length].each{|v| skip_auto_validations(v)}
|
206
|
+
[:not_null, :no_null_byte, :types, :unique, :max_length, :max_value, :min_value].each{|v| skip_auto_validations(v)}
|
167
207
|
when :not_null
|
168
208
|
auto_validate_not_null_columns.clear
|
169
209
|
auto_validate_explicit_not_null_columns.clear
|
@@ -183,6 +223,9 @@ module Sequel
|
|
183
223
|
explicit_not_null_cols += Array(primary_key)
|
184
224
|
@auto_validate_explicit_not_null_columns = explicit_not_null_cols.uniq
|
185
225
|
@auto_validate_max_length_columns = db_schema.select{|col, sch| sch[:type] == :string && sch[:max_length].is_a?(Integer)}.map{|col, sch| [col, sch[:max_length]]}
|
226
|
+
@auto_validate_max_value_columns = db_schema.select{|col, sch| sch[:max_value]}.map{|col, sch| [col, sch[:max_value]]}
|
227
|
+
@auto_validate_min_value_columns = db_schema.select{|col, sch| sch[:min_value]}.map{|col, sch| [col, sch[:min_value]]}
|
228
|
+
@auto_validate_no_null_byte_columns = db_schema.select{|_, sch| sch[:type] == :string}.map{|col, _| col}
|
186
229
|
table = dataset.first_source_table
|
187
230
|
@auto_validate_unique_columns = if db.supports_index_parsing? && [Symbol, SQL::QualifiedIdentifier, SQL::Identifier, String].any?{|c| table.is_a?(c)}
|
188
231
|
db.indexes(table).select{|name, idx| idx[:unique] == true}.map{|name, idx| idx[:columns].length == 1 ? idx[:columns].first : idx[:columns]}
|
@@ -209,6 +252,9 @@ module Sequel
|
|
209
252
|
return if skip.include?(:all)
|
210
253
|
opts = model.auto_validate_options
|
211
254
|
|
255
|
+
unless skip.include?(:no_null_byte) || (no_null_byte_columns = model.auto_validate_no_null_byte_columns).empty?
|
256
|
+
validates_no_null_byte(no_null_byte_columns, opts[:no_null_byte])
|
257
|
+
end
|
212
258
|
|
213
259
|
unless skip.include?(:not_null)
|
214
260
|
not_null_method = model.auto_validate_presence? ? :validates_presence : :validates_not_null
|
@@ -228,6 +274,18 @@ module Sequel
|
|
228
274
|
|
229
275
|
unless skip.include?(:types) || !model.auto_validate_types?
|
230
276
|
validates_schema_types(keys, opts[:schema_types])
|
277
|
+
|
278
|
+
unless skip.include?(:max_value) || ((max_value_columns = model.auto_validate_max_value_columns).empty?)
|
279
|
+
max_value_columns.each do |col, max|
|
280
|
+
validates_max_value(max, col, opts[:max_value])
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
unless skip.include?(:min_value) || ((min_value_columns = model.auto_validate_min_value_columns).empty?)
|
285
|
+
min_value_columns.each do |col, min|
|
286
|
+
validates_min_value(min, col, opts[:min_value])
|
287
|
+
end
|
288
|
+
end
|
231
289
|
end
|
232
290
|
|
233
291
|
unless skip.include?(:unique)
|
@@ -104,7 +104,7 @@ module Sequel
|
|
104
104
|
# should reference the subquery alias (and qualified identifiers should not be needed
|
105
105
|
# unless joining to another table):
|
106
106
|
#
|
107
|
-
# a = Executive.where(:
|
107
|
+
# a = Executive.where(id: 1).first # works
|
108
108
|
# a = Executive.where{{employees[:id]=>1}}.first # works
|
109
109
|
# a = Executive.where{{executives[:id]=>1}}.first # doesn't work
|
110
110
|
#
|
@@ -115,7 +115,7 @@ module Sequel
|
|
115
115
|
#
|
116
116
|
# pks = Executive.where{num_staff < 10}.select_map(:id)
|
117
117
|
# Executive.cti_tables.reverse_each do |table|
|
118
|
-
# DB.from(table).where(:
|
118
|
+
# DB.from(table).where(id: pks).delete
|
119
119
|
# end
|
120
120
|
#
|
121
121
|
# = Usage
|
@@ -31,7 +31,6 @@ rescue RuntimeError, OpenSSL::Cipher::CipherError
|
|
31
31
|
# :nocov:
|
32
32
|
end
|
33
33
|
|
34
|
-
require 'base64'
|
35
34
|
require 'securerandom'
|
36
35
|
|
37
36
|
module Sequel
|
@@ -326,7 +325,7 @@ module Sequel
|
|
326
325
|
# DB.alter_table(:ce_test) do
|
327
326
|
# c = Sequel[:encrypted_column_name]
|
328
327
|
# add_constraint(:enc_base64) do
|
329
|
-
# octet_length(decode(regexp_replace(regexp_replace(c, '_', '/', 'g'), '-', '+', 'g'), 'base64')) >= 65
|
328
|
+
# octet_length(decode(regexp_replace(regexp_replace(c, '_', '/', 'g'), '-', '+', 'g'), 'base64')) >= 65
|
330
329
|
# end
|
331
330
|
# end
|
332
331
|
#
|
@@ -356,7 +355,7 @@ module Sequel
|
|
356
355
|
|
357
356
|
# Keys should be an array of arrays containing key_id, key string, auth_data, and padding.
|
358
357
|
def initialize(keys)
|
359
|
-
if keys.empty?
|
358
|
+
if !keys || keys.empty?
|
360
359
|
raise Error, "Cannot initialize encryptor without encryption key"
|
361
360
|
end
|
362
361
|
|
@@ -375,7 +374,7 @@ module Sequel
|
|
375
374
|
# Decrypt using any supported format and any available key.
|
376
375
|
def decrypt(data)
|
377
376
|
begin
|
378
|
-
data =
|
377
|
+
data = urlsafe_decode64(data)
|
379
378
|
rescue ArgumentError
|
380
379
|
raise Error, "Unable to decode encrypted column: invalid base64"
|
381
380
|
end
|
@@ -448,7 +447,7 @@ module Sequel
|
|
448
447
|
# The prefix string of columns for the given search type and the first configured encryption key.
|
449
448
|
# Used to find values that do not use this prefix in order to perform reencryption.
|
450
449
|
def current_key_prefix(search_type)
|
451
|
-
|
450
|
+
urlsafe_encode64("#{search_type.chr}\0#{@key_id.chr}")
|
452
451
|
end
|
453
452
|
|
454
453
|
# The prefix values to search for the given data (an array of strings), assuming the column uses
|
@@ -472,11 +471,33 @@ module Sequel
|
|
472
471
|
|
473
472
|
private
|
474
473
|
|
474
|
+
if RUBY_VERSION >= '2.4'
|
475
|
+
def decode64(str)
|
476
|
+
str.unpack1("m0")
|
477
|
+
end
|
478
|
+
# :nocov:
|
479
|
+
else
|
480
|
+
def decode64(str)
|
481
|
+
str.unpack("m0")[0]
|
482
|
+
end
|
483
|
+
# :nocov:
|
484
|
+
end
|
485
|
+
|
486
|
+
def urlsafe_encode64(bin)
|
487
|
+
str = [bin].pack("m0")
|
488
|
+
str.tr!("+/", "-_")
|
489
|
+
str
|
490
|
+
end
|
491
|
+
|
492
|
+
def urlsafe_decode64(str)
|
493
|
+
decode64(str.tr("-_", "+/"))
|
494
|
+
end
|
495
|
+
|
475
496
|
# An array of strings, one for each configured encryption key, to find encypted values matching
|
476
497
|
# the given data and search format.
|
477
498
|
def _search_prefixes(data, search_type)
|
478
499
|
@key_map.map do |key_id, (key, _)|
|
479
|
-
|
500
|
+
urlsafe_encode64(_search_prefix(data, search_type, key_id, key))
|
480
501
|
end
|
481
502
|
end
|
482
503
|
|
@@ -509,7 +530,7 @@ module Sequel
|
|
509
530
|
cipher_text << cipher.update(data) if data_size > 0
|
510
531
|
cipher_text << cipher.final
|
511
532
|
|
512
|
-
|
533
|
+
urlsafe_encode64("#{prefix}#{random_data}#{cipher_iv}#{cipher.auth_tag}#{cipher_text}")
|
513
534
|
end
|
514
535
|
end
|
515
536
|
|
@@ -608,7 +629,7 @@ module Sequel
|
|
608
629
|
|
609
630
|
# Setup encryption for the given column.
|
610
631
|
def _encrypt_column(column, opts)
|
611
|
-
cryptor ||= if
|
632
|
+
cryptor ||= if defined?(yield)
|
612
633
|
dsl = ColumnDSL.new
|
613
634
|
yield dsl
|
614
635
|
Cryptor.new(dsl.keys)
|