sequel 5.66.0 → 5.67.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +14 -0
- data/doc/release_notes/5.67.0.txt +32 -0
- data/lib/sequel/adapters/shared/mssql.rb +7 -2
- data/lib/sequel/database/dataset.rb +16 -6
- data/lib/sequel/database/schema_generator.rb +1 -1
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
- data/lib/sequel/dataset/query.rb +53 -28
- data/lib/sequel/dataset.rb +4 -0
- data/lib/sequel/extensions/connection_validator.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +32 -9
- data/lib/sequel/extensions/set_literalizer.rb +58 -0
- data/lib/sequel/plugins/prepared_statements.rb +2 -1
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
- data/lib/sequel/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff5af191af88ca381359503cfd9601ec8f18a9d782b68a3de4a8c9dac080eddc
|
4
|
+
data.tar.gz: 786d20f7eac9325748c259130951643856e34051e64b02aa17493f6d0283eb52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db251488ea0739af5ecf6db332a1cff729cffbf31dfabfc7235f3c27f807366bc9feddf147797e4dd5980348fda6a640cc5ceef7e6255cddcd317acb7172be90
|
7
|
+
data.tar.gz: 45b0e24847ccb365f1d7d06d35c85f05718802375877ab3d0315deb952f72171e26b5676861c25cf1e840f831d216f99eaddcbb717fc752d75077f19ae13980c
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 5.67.0 (2023-04-01)
|
2
|
+
|
3
|
+
* Fix dumping of string column sizes in the schema dumper on MSSQL (jeremyevans) (#2013)
|
4
|
+
|
5
|
+
* Improve dumping of tables in non-default schemas in the schema_dumper extension (jeremyevans) (#2006)
|
6
|
+
|
7
|
+
* Make Database#{tables,views} support :qualify option on Microsoft SQL Server (jeremyevans)
|
8
|
+
|
9
|
+
* Avoid use of singleton classes for datasets instances on Ruby 2.4+ (jeremyevans) (#2007)
|
10
|
+
|
11
|
+
* Deprecate registering datasets extensions using an object other than a module (jeremyevans)
|
12
|
+
|
13
|
+
* Add set_literalizer extension, for treating set usage in datasets similar to array usage (jeremyevans) (#1997)
|
14
|
+
|
1
15
|
=== 5.66.0 (2023-03-01)
|
2
16
|
|
3
17
|
* Recognize SQLite error related to strict tables as a constraint violation when using the amalgalite adapter (jeremyevans)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A set_literalizer extension has been added, for treating Set
|
4
|
+
instances in datasets similar to Array instances:
|
5
|
+
|
6
|
+
DB.extension :set_literalizer
|
7
|
+
DB[:table].where(column: Set.new([1, 2, 3]))
|
8
|
+
# SELECT FROM table WHERE (column IN (1, 2, 3))
|
9
|
+
|
10
|
+
= Improvements
|
11
|
+
|
12
|
+
* Sequel now avoids the use of singleton classes for datasets on Ruby
|
13
|
+
2.4+, instead creating a regular subclass whenever a dataset would
|
14
|
+
be extended via #extension or #with_extend. This significantly
|
15
|
+
improves performance, up to 20-40% for common dataset usage,
|
16
|
+
because it avoids creating new singleton classes for every dataset
|
17
|
+
clone, and it allows for cached method lookup.
|
18
|
+
|
19
|
+
* Database#tables and #views now support a :qualify option on Microsoft
|
20
|
+
SQL Server to returned qualified identifiers.
|
21
|
+
|
22
|
+
* The schema_dumper extension can now dump tables in non-default schemas
|
23
|
+
when using Microsoft SQL Server.
|
24
|
+
|
25
|
+
* The schema_dumper extension now correctly dumps string column sizes
|
26
|
+
when using Microsoft SQL Server.
|
27
|
+
|
28
|
+
= Backwards Compatibility
|
29
|
+
|
30
|
+
* Calling Sequel::Dataset.register_extension where the second argument
|
31
|
+
is not a module now issues a deprecation warning. Support for this
|
32
|
+
will be removed in Sequel 6.
|
@@ -404,10 +404,15 @@ module Sequel
|
|
404
404
|
# Backbone of the tables and views support.
|
405
405
|
def information_schema_tables(type, opts)
|
406
406
|
m = output_identifier_meth
|
407
|
-
|
407
|
+
schema = opts[:schema]||'dbo'
|
408
|
+
tables = metadata_dataset.from(Sequel[:information_schema][:tables].as(:t)).
|
408
409
|
select(:table_name).
|
409
|
-
where(:table_type=>type, :table_schema=>
|
410
|
+
where(:table_type=>type, :table_schema=>schema.to_s).
|
410
411
|
map{|x| m.call(x[:table_name])}
|
412
|
+
|
413
|
+
tables.map!{|t| Sequel.qualify(m.call(schema).to_s, m.call(t).to_s)} if opts[:qualify]
|
414
|
+
|
415
|
+
tables
|
411
416
|
end
|
412
417
|
|
413
418
|
# Always quote identifiers in the metadata_dataset, so schema parsing works.
|
@@ -30,19 +30,29 @@ module Sequel
|
|
30
30
|
@dataset_class.new(self)
|
31
31
|
end
|
32
32
|
|
33
|
-
#
|
34
|
-
# it is used to iterate over the records:
|
33
|
+
# Returns a dataset instance for the given SQL string:
|
35
34
|
#
|
36
|
-
# DB.fetch('SELECT * FROM items')
|
35
|
+
# ds = DB.fetch('SELECT * FROM items')
|
36
|
+
#
|
37
|
+
# You can then call methods on the dataset to retrieve results:
|
37
38
|
#
|
38
|
-
#
|
39
|
+
# ds.all
|
40
|
+
# # SELECT * FROM items
|
41
|
+
# # => [{:column=>value, ...}, ...]
|
39
42
|
#
|
40
|
-
#
|
43
|
+
# If a block is given, it is passed to #each on the resulting dataset to
|
44
|
+
# iterate over the records returned by the query:
|
45
|
+
#
|
46
|
+
# DB.fetch('SELECT * FROM items'){|r| p r}
|
47
|
+
# # {:column=>value, ...}
|
48
|
+
# # ...
|
41
49
|
#
|
42
50
|
# +fetch+ can also perform parameterized queries for protection against SQL
|
43
51
|
# injection:
|
44
52
|
#
|
45
|
-
# DB.fetch('SELECT * FROM items WHERE name = ?',
|
53
|
+
# ds = DB.fetch('SELECT * FROM items WHERE name = ?', "my name")
|
54
|
+
# ds.all
|
55
|
+
# # SELECT * FROM items WHERE name = 'my name'
|
46
56
|
#
|
47
57
|
# See caveats listed in Dataset#with_sql regarding datasets using custom
|
48
58
|
# SQL and the methods that can be called on them.
|
@@ -307,7 +307,7 @@ module Sequel
|
|
307
307
|
# Examples:
|
308
308
|
# primary_key(:id)
|
309
309
|
# primary_key(:id, type: :Bignum, keep_order: true)
|
310
|
-
# primary_key([:street_number, :house_number], name: :
|
310
|
+
# primary_key([:street_number, :house_number], name: :some_constraint_name)
|
311
311
|
def primary_key(name, *args)
|
312
312
|
return composite_primary_key(name, *args) if name.is_a?(Array)
|
313
313
|
column = @db.serial_primary_key_options.merge({:name => name})
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
class Dataset
|
5
|
+
# This module implements methods to support deprecated use of extensions registered
|
6
|
+
# not using a module. In such cases, for backwards compatibility, Sequel has to use
|
7
|
+
# a singleton class for the dataset.
|
8
|
+
module DeprecatedSingletonClassMethods
|
9
|
+
# Load the extension into a clone of the receiver.
|
10
|
+
def extension(*a)
|
11
|
+
c = _clone(:freeze=>false)
|
12
|
+
c.send(:_extension!, a)
|
13
|
+
c.freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
# Extend the cloned of the receiver with the given modules, instead of the default
|
17
|
+
# approach of creating a subclass of the receiver's class and including the modules
|
18
|
+
# into that.
|
19
|
+
def with_extend(*mods, &block)
|
20
|
+
c = _clone(:freeze=>false)
|
21
|
+
c.extend(*mods) unless mods.empty?
|
22
|
+
c.extend(DatasetModule.new(&block)) if block
|
23
|
+
c.freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Load the extensions into the receiver.
|
29
|
+
def _extension!(exts)
|
30
|
+
Sequel.extension(*exts)
|
31
|
+
exts.each do |ext|
|
32
|
+
if pr = Sequel.synchronize{EXTENSIONS[ext]}
|
33
|
+
pr.call(self)
|
34
|
+
else
|
35
|
+
raise(Error, "Extension #{ext} does not have specific support handling individual datasets (try: Sequel.extension #{ext.inspect})")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -12,6 +12,10 @@ module Sequel
|
|
12
12
|
# in the extension).
|
13
13
|
EXTENSIONS = {}
|
14
14
|
|
15
|
+
# Hash of extension name symbols to modules to load to implement the extension.
|
16
|
+
EXTENSION_MODULES = {}
|
17
|
+
private_constant :EXTENSION_MODULES
|
18
|
+
|
15
19
|
EMPTY_ARRAY = [].freeze
|
16
20
|
|
17
21
|
# The dataset options that require the removal of cached columns if changed.
|
@@ -45,12 +49,8 @@ module Sequel
|
|
45
49
|
METHS
|
46
50
|
|
47
51
|
# Register an extension callback for Dataset objects. ext should be the
|
48
|
-
# extension name symbol, and mod should
|
49
|
-
# dataset
|
50
|
-
# object. If mod is not provided, a block can be provided and is treated
|
51
|
-
# as the mod object.
|
52
|
-
#
|
53
|
-
# If mod is a module, this also registers a Database extension that will
|
52
|
+
# extension name symbol, and mod should be a Module that will be
|
53
|
+
# included in the dataset's class. This also registers a Database extension that will
|
54
54
|
# extend all of the database's datasets.
|
55
55
|
def self.register_extension(ext, mod=nil, &block)
|
56
56
|
if mod
|
@@ -58,10 +58,16 @@ module Sequel
|
|
58
58
|
if mod.is_a?(Module)
|
59
59
|
block = proc{|ds| ds.extend(mod)}
|
60
60
|
Sequel::Database.register_extension(ext){|db| db.extend_datasets(mod)}
|
61
|
+
Sequel.synchronize{EXTENSION_MODULES[ext] = mod}
|
61
62
|
else
|
62
63
|
block = mod
|
63
64
|
end
|
64
65
|
end
|
66
|
+
|
67
|
+
unless mod.is_a?(Module)
|
68
|
+
Sequel::Deprecation.deprecate("Providing a block or non-module to Sequel::Dataset.register_extension is deprecated and support for it will be removed in Sequel 6.")
|
69
|
+
end
|
70
|
+
|
65
71
|
Sequel.synchronize{EXTENSIONS[ext] = block}
|
66
72
|
end
|
67
73
|
|
@@ -195,11 +201,15 @@ module Sequel
|
|
195
201
|
if TRUE_FREEZE
|
196
202
|
# Return a clone of the dataset loaded with the given dataset extensions.
|
197
203
|
# If no related extension file exists or the extension does not have
|
198
|
-
# specific support for Dataset objects, an
|
199
|
-
def extension(*
|
200
|
-
|
201
|
-
|
202
|
-
|
204
|
+
# specific support for Dataset objects, an error will be raised.
|
205
|
+
def extension(*exts)
|
206
|
+
Sequel.extension(*exts)
|
207
|
+
mods = exts.map{|ext| Sequel.synchronize{EXTENSION_MODULES[ext]}}
|
208
|
+
if mods.all?
|
209
|
+
with_extend(*mods)
|
210
|
+
else
|
211
|
+
with_extend(DeprecatedSingletonClassMethods).extension(*exts)
|
212
|
+
end
|
203
213
|
end
|
204
214
|
else
|
205
215
|
# :nocov:
|
@@ -1199,16 +1209,27 @@ module Sequel
|
|
1199
1209
|
end
|
1200
1210
|
|
1201
1211
|
if TRUE_FREEZE
|
1202
|
-
#
|
1212
|
+
# Create a subclass of the receiver's class, and include the given modules
|
1213
|
+
# into it. If a block is provided, a DatasetModule is created using the block and
|
1214
|
+
# is included into the subclass. Create an instance of the subclass using the
|
1215
|
+
# same db and opts, so that the returned dataset operates similarly to a clone
|
1216
|
+
# extended with the given modules. This approach is used to avoid singleton
|
1217
|
+
# classes, which significantly improves performance.
|
1218
|
+
#
|
1203
1219
|
# Note that like Object#extend, when multiple modules are provided
|
1204
|
-
# as arguments the
|
1205
|
-
# order. If a block is provided, a DatasetModule is created using the block and
|
1206
|
-
# the clone is extended with that module after any modules given as arguments.
|
1220
|
+
# as arguments the subclass includes the modules in reverse order.
|
1207
1221
|
def with_extend(*mods, &block)
|
1208
|
-
c =
|
1209
|
-
c.
|
1210
|
-
c.
|
1211
|
-
c.freeze
|
1222
|
+
c = Class.new(self.class)
|
1223
|
+
c.include(*mods) unless mods.empty?
|
1224
|
+
c.include(DatasetModule.new(&block)) if block
|
1225
|
+
o = c.freeze.allocate
|
1226
|
+
o.instance_variable_set(:@db, @db)
|
1227
|
+
o.instance_variable_set(:@opts, @opts)
|
1228
|
+
o.instance_variable_set(:@cache, {})
|
1229
|
+
if cols = cache_get(:_columns)
|
1230
|
+
o.send(:columns=, cols)
|
1231
|
+
end
|
1232
|
+
o.freeze
|
1212
1233
|
end
|
1213
1234
|
else
|
1214
1235
|
# :nocov:
|
@@ -1315,18 +1336,22 @@ module Sequel
|
|
1315
1336
|
|
1316
1337
|
private
|
1317
1338
|
|
1318
|
-
#
|
1319
|
-
|
1320
|
-
|
1321
|
-
exts
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1339
|
+
# :nocov:
|
1340
|
+
unless TRUE_FREEZE
|
1341
|
+
# Load the extensions into the receiver, without checking if the receiver is frozen.
|
1342
|
+
def _extension!(exts)
|
1343
|
+
Sequel.extension(*exts)
|
1344
|
+
exts.each do |ext|
|
1345
|
+
if pr = Sequel.synchronize{EXTENSIONS[ext]}
|
1346
|
+
pr.call(self)
|
1347
|
+
else
|
1348
|
+
raise(Error, "Extension #{ext} does not have specific support handling individual datasets (try: Sequel.extension #{ext.inspect})")
|
1349
|
+
end
|
1326
1350
|
end
|
1351
|
+
self
|
1327
1352
|
end
|
1328
|
-
self
|
1329
1353
|
end
|
1354
|
+
# :nocov:
|
1330
1355
|
|
1331
1356
|
# If invert is true, invert the condition.
|
1332
1357
|
def _invert_filter(cond, invert)
|
data/lib/sequel/dataset.rb
CHANGED
@@ -53,4 +53,8 @@ module Sequel
|
|
53
53
|
require_relative "dataset/sql"
|
54
54
|
require_relative "dataset/placeholder_literalizer"
|
55
55
|
require_relative "dataset/dataset_module"
|
56
|
+
|
57
|
+
# :nocov:
|
58
|
+
require_relative "dataset/deprecated_singleton_class_methods" if Dataset::TRUE_FREEZE
|
59
|
+
# :nocov:
|
56
60
|
end
|
@@ -28,7 +28,7 @@
|
|
28
28
|
# connections on every checkout without setting up coarse
|
29
29
|
# connection checkouts will hurt performance, in some cases
|
30
30
|
# significantly. Note that setting up coarse connection
|
31
|
-
# checkouts reduces the concurrency level
|
31
|
+
# checkouts reduces the concurrency level achievable. For
|
32
32
|
# example, in a web application, using Database#synchronize
|
33
33
|
# in a rack middleware will limit the number of concurrent
|
34
34
|
# web requests to the number to connections in the database
|
@@ -88,11 +88,11 @@ module Sequel
|
|
88
88
|
# Note that the migration this produces does not have a down
|
89
89
|
# block, so you cannot reverse it.
|
90
90
|
def dump_foreign_key_migration(options=OPTS)
|
91
|
-
ts =
|
91
|
+
ts = _dump_tables(options)
|
92
92
|
<<END_MIG
|
93
93
|
Sequel.migration do
|
94
94
|
change do
|
95
|
-
#{ts.
|
95
|
+
#{ts.map{|t| dump_table_foreign_keys(t)}.reject{|x| x == ''}.join("\n\n").gsub(/^/, ' ')}
|
96
96
|
end
|
97
97
|
end
|
98
98
|
END_MIG
|
@@ -106,11 +106,11 @@ END_MIG
|
|
106
106
|
# set to :namespace, prepend the table name to the index name if the
|
107
107
|
# database does not use a global index namespace.
|
108
108
|
def dump_indexes_migration(options=OPTS)
|
109
|
-
ts =
|
109
|
+
ts = _dump_tables(options)
|
110
110
|
<<END_MIG
|
111
111
|
Sequel.migration do
|
112
112
|
change do
|
113
|
-
#{ts.
|
113
|
+
#{ts.map{|t| dump_table_indexes(t, :add_index, options)}.reject{|x| x == ''}.join("\n\n").gsub(/^/, ' ')}
|
114
114
|
end
|
115
115
|
end
|
116
116
|
END_MIG
|
@@ -138,7 +138,7 @@ END_MIG
|
|
138
138
|
options[:foreign_keys] = false
|
139
139
|
end
|
140
140
|
|
141
|
-
ts = sort_dumped_tables(
|
141
|
+
ts = sort_dumped_tables(_dump_tables(options), options)
|
142
142
|
skipped_fks = if sfk = options[:skipped_foreign_keys]
|
143
143
|
# Handle skipped foreign keys by adding them at the end via
|
144
144
|
# alter_table/add_foreign_key. Note that skipped foreign keys
|
@@ -166,6 +166,21 @@ END_MIG
|
|
166
166
|
|
167
167
|
private
|
168
168
|
|
169
|
+
# Handle schema option to dump tables in a different schema. Such
|
170
|
+
# tables must be schema qualified for this to work correctly.
|
171
|
+
def _dump_tables(opts)
|
172
|
+
if opts[:schema]
|
173
|
+
_literal_table_sort(tables(opts.merge(:qualify=>true)))
|
174
|
+
else
|
175
|
+
tables(opts).sort
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Sort the given table by the literalized value.
|
180
|
+
def _literal_table_sort(tables)
|
181
|
+
tables.sort_by{|s| literal(s)}
|
182
|
+
end
|
183
|
+
|
169
184
|
# If a database default exists and can't be converted, and we are dumping with :same_db,
|
170
185
|
# return a string with the inspect method modified a literal string is created if the code is evaled.
|
171
186
|
def column_schema_to_ruby_default_fallback(default, options)
|
@@ -204,12 +219,20 @@ END_MIG
|
|
204
219
|
if database_type == :mysql && h[:type] =~ /\Atimestamp/
|
205
220
|
h[:null] = true
|
206
221
|
end
|
222
|
+
if database_type == :mssql && schema[:max_length]
|
223
|
+
h[:size] = schema[:max_length]
|
224
|
+
end
|
207
225
|
h
|
208
226
|
else
|
209
227
|
column_schema_to_ruby_type(schema)
|
210
228
|
end
|
211
229
|
type = col_opts.delete(:type)
|
212
|
-
col_opts.
|
230
|
+
if col_opts.key?(:size) && col_opts[:size].nil?
|
231
|
+
col_opts.delete(:size)
|
232
|
+
if max_length = schema[:max_length]
|
233
|
+
col_opts[:size] = max_length
|
234
|
+
end
|
235
|
+
end
|
213
236
|
if schema[:generated]
|
214
237
|
if options[:same_db] && database_type == :postgres
|
215
238
|
col_opts[:generated_always_as] = column_schema_to_ruby_default_fallback(schema[:default], options)
|
@@ -352,7 +375,7 @@ END_MIG
|
|
352
375
|
options[:skipped_foreign_keys] = skipped_foreign_keys
|
353
376
|
tables
|
354
377
|
else
|
355
|
-
tables
|
378
|
+
tables
|
356
379
|
end
|
357
380
|
end
|
358
381
|
|
@@ -377,14 +400,14 @@ END_MIG
|
|
377
400
|
# outstanding foreign keys and skipping those foreign keys.
|
378
401
|
# The skipped foreign keys will be added at the end of the
|
379
402
|
# migration.
|
380
|
-
skip_table, skip_fks = table_fks.sort_by{|table, fks| [fks.length, table]}.first
|
403
|
+
skip_table, skip_fks = table_fks.sort_by{|table, fks| [fks.length, literal(table)]}.first
|
381
404
|
skip_fks_hash = skipped_foreign_keys[skip_table] = {}
|
382
405
|
skip_fks.each{|fk| skip_fks_hash[fk[:columns]] = fk}
|
383
406
|
this_loop << skip_table
|
384
407
|
end
|
385
408
|
|
386
409
|
# Add sorted tables from this loop to the final list
|
387
|
-
sorted_tables.concat(this_loop
|
410
|
+
sorted_tables.concat(_literal_table_sort(this_loop))
|
388
411
|
|
389
412
|
# Remove tables that were handled this loop
|
390
413
|
this_loop.each{|t| table_fks.delete(t)}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
#
|
3
|
+
# The set_literalizer extension allows for using Set instances in many of the
|
4
|
+
# same places that you would use Array instances:
|
5
|
+
#
|
6
|
+
# DB[:table].where(column: Set.new([1, 2, 3]))
|
7
|
+
# # SELECT FROM table WHERE (column IN (1, 2, 3))
|
8
|
+
#
|
9
|
+
# To load the extension into all datasets created from a given Database:
|
10
|
+
#
|
11
|
+
# DB.extension :set_literalizer
|
12
|
+
#
|
13
|
+
# Related module: Sequel::Dataset::SetLiteralizer
|
14
|
+
|
15
|
+
require 'set'
|
16
|
+
|
17
|
+
module Sequel
|
18
|
+
class Dataset
|
19
|
+
module SetLiteralizer
|
20
|
+
# Try to generate the same SQL for Set instances used in datasets
|
21
|
+
# that would be used for equivalent Array instances.
|
22
|
+
def complex_expression_sql_append(sql, op, args)
|
23
|
+
# Array instances are treated specially by
|
24
|
+
# Sequel::SQL::BooleanExpression.from_value_pairs. That cannot
|
25
|
+
# be modified by a dataset extension, so this tries to convert
|
26
|
+
# the complex expression values generated by default to what would
|
27
|
+
# be the complex expression values used for the equivalent array.
|
28
|
+
case op
|
29
|
+
when :'=', :'!='
|
30
|
+
if (set = args[1]).is_a?(Set)
|
31
|
+
op = op == :'=' ? :IN : :'NOT IN'
|
32
|
+
col = args[0]
|
33
|
+
array = set.to_a
|
34
|
+
if Sequel.condition_specifier?(array) && col.is_a?(Array)
|
35
|
+
array = Sequel.value_list(array)
|
36
|
+
end
|
37
|
+
args = [col, array]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Literalize Set instances by converting the set to array.
|
47
|
+
def literal_other_append(sql, v)
|
48
|
+
if Set === v
|
49
|
+
literal_append(sql, v.to_a)
|
50
|
+
else
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
register_extension(:set_literalizer, SetLiteralizer)
|
57
|
+
end
|
58
|
+
end
|
@@ -3,7 +3,8 @@
|
|
3
3
|
module Sequel
|
4
4
|
module Plugins
|
5
5
|
# The prepared_statements plugin modifies the model to use prepared statements for
|
6
|
-
# instance level inserts and updates.
|
6
|
+
# instance level inserts and updates. This plugin exists for backwards compatibility
|
7
|
+
# and is not recommended for general use.
|
7
8
|
#
|
8
9
|
# Note that this plugin is unsafe in some circumstances, as it can allow up to
|
9
10
|
# 2^N prepared statements to be created for each type of insert and update query, where
|
@@ -5,7 +5,8 @@ module Sequel
|
|
5
5
|
# The prepared_statements_safe plugin modifies the model to reduce the number of
|
6
6
|
# prepared statements that can be created, by setting as many columns as possible
|
7
7
|
# before creating, and by changing +save_changes+ to save all columns instead of
|
8
|
-
# just the changed ones.
|
8
|
+
# just the changed ones. This plugin exists for backwards compatibility
|
9
|
+
# and is not recommended for general use.
|
9
10
|
#
|
10
11
|
# This plugin depends on the +prepared_statements+ plugin.
|
11
12
|
#
|
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 = 67
|
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,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.67.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -198,6 +198,7 @@ extra_rdoc_files:
|
|
198
198
|
- doc/release_notes/5.64.0.txt
|
199
199
|
- doc/release_notes/5.65.0.txt
|
200
200
|
- doc/release_notes/5.66.0.txt
|
201
|
+
- doc/release_notes/5.67.0.txt
|
201
202
|
- doc/release_notes/5.7.0.txt
|
202
203
|
- doc/release_notes/5.8.0.txt
|
203
204
|
- doc/release_notes/5.9.0.txt
|
@@ -292,6 +293,7 @@ files:
|
|
292
293
|
- doc/release_notes/5.64.0.txt
|
293
294
|
- doc/release_notes/5.65.0.txt
|
294
295
|
- doc/release_notes/5.66.0.txt
|
296
|
+
- doc/release_notes/5.67.0.txt
|
295
297
|
- doc/release_notes/5.7.0.txt
|
296
298
|
- doc/release_notes/5.8.0.txt
|
297
299
|
- doc/release_notes/5.9.0.txt
|
@@ -376,6 +378,7 @@ files:
|
|
376
378
|
- lib/sequel/dataset.rb
|
377
379
|
- lib/sequel/dataset/actions.rb
|
378
380
|
- lib/sequel/dataset/dataset_module.rb
|
381
|
+
- lib/sequel/dataset/deprecated_singleton_class_methods.rb
|
379
382
|
- lib/sequel/dataset/features.rb
|
380
383
|
- lib/sequel/dataset/graph.rb
|
381
384
|
- lib/sequel/dataset/misc.rb
|
@@ -461,6 +464,7 @@ files:
|
|
461
464
|
- lib/sequel/extensions/sequel_4_dataset_methods.rb
|
462
465
|
- lib/sequel/extensions/server_block.rb
|
463
466
|
- lib/sequel/extensions/server_logging.rb
|
467
|
+
- lib/sequel/extensions/set_literalizer.rb
|
464
468
|
- lib/sequel/extensions/split_array_nil.rb
|
465
469
|
- lib/sequel/extensions/sql_comments.rb
|
466
470
|
- lib/sequel/extensions/sql_expr.rb
|
@@ -615,7 +619,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
615
619
|
- !ruby/object:Gem::Version
|
616
620
|
version: '0'
|
617
621
|
requirements: []
|
618
|
-
rubygems_version: 3.4.
|
622
|
+
rubygems_version: 3.4.10
|
619
623
|
signing_key:
|
620
624
|
specification_version: 4
|
621
625
|
summary: The Database Toolkit for Ruby
|