sequel 5.63.0 → 5.65.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 +18 -0
- data/MIT-LICENSE +1 -1
- data/doc/association_basics.rdoc +32 -2
- data/doc/release_notes/5.64.0.txt +50 -0
- data/doc/release_notes/5.65.0.txt +21 -0
- data/doc/sql.rdoc +1 -1
- data/lib/sequel/adapters/oracle.rb +1 -0
- data/lib/sequel/adapters/shared/access.rb +2 -2
- data/lib/sequel/adapters/shared/mysql.rb +8 -1
- data/lib/sequel/adapters/shared/oracle.rb +5 -5
- data/lib/sequel/adapters/shared/postgres.rb +1 -1
- data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/shared/sqlite.rb +3 -2
- data/lib/sequel/database/query.rb +38 -4
- data/lib/sequel/dataset/misc.rb +11 -1
- data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
- data/lib/sequel/extensions/pg_auto_parameterize.rb +35 -4
- data/lib/sequel/model/associations.rb +20 -5
- data/lib/sequel/plugins/finder.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +1 -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: 24bfe7c123337539140b0385dd9a828fe0fec4d6ad4e39e5fd8f150258ae7a03
|
4
|
+
data.tar.gz: d820be46e60ba7b08b1129f0a6b67a24a550a27d5b682a84730172bc256f4118
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd5c7dacdf48f8ada7c34c88210ac804faa1b47741f946ca16cd6f645c1f86055eb85ac6b601e9cef2ab4aa8a5cba3dc444e3005d6ed61d324c1158f2e03a70e
|
7
|
+
data.tar.gz: d17eb580a3f50f4b0c33561aed320c2ea3089044b905f4dc845ea8682afe1cdbf2798c6cd202f1233b1d168d06c9686a94728d41e0f47264245a33da5a99b251
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
=== 5.65.0 (2023-02-01)
|
2
|
+
|
3
|
+
* Allow pg_auto_parameterize extension to use placeholder loaders (jeremyevans)
|
4
|
+
|
5
|
+
* Do not include :min_value and :max_value schema entries for decimal/numeric columns on MySQL versions not supporting check constraints (jeremyevans)
|
6
|
+
|
7
|
+
* Make Database#indexes return indexes for partitioned tables on PostgreSQL 11+ (jeremyevans)
|
8
|
+
|
9
|
+
=== 5.64.0 (2023-01-01)
|
10
|
+
|
11
|
+
* Make :db_type column schema entries on SQLAnywhere include precision/scale information (jeremyevans)
|
12
|
+
|
13
|
+
* Include :min_value and :max_value schema entries for decimal/numeric columns on most databases (rolftimmermans, jeremyevans) (#1975)
|
14
|
+
|
15
|
+
* Support :graph_use_association_block association option to make eager_graph use the association block (jeremyevans)
|
16
|
+
|
17
|
+
* Make many_through_many and many_through_one associations support eager_graph callbacks (jeremyevans)
|
18
|
+
|
1
19
|
=== 5.63.0 (2022-12-01)
|
2
20
|
|
3
21
|
* Make validates_associated plugin avoid database type errors for non-integer association keys (jeremyevans) (#1968)
|
data/MIT-LICENSE
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Copyright (c) 2007-2008 Sharon Rosner
|
2
|
-
Copyright (c) 2008-
|
2
|
+
Copyright (c) 2008-2023 Jeremy Evans
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to
|
data/doc/association_basics.rdoc
CHANGED
@@ -864,14 +864,14 @@ You can set this to +nil+ to not create a remove_all_<i>association</i> method.
|
|
864
864
|
|
865
865
|
=== :no_dataset_method
|
866
866
|
|
867
|
-
Setting this to true will
|
867
|
+
Setting this to true will result in the <i>association</i>_dataset method
|
868
868
|
not being defined. This can save memory if you only use the <i>association</i>
|
869
869
|
method and do not call the <i>association</i>_dataset method directly or
|
870
870
|
indirectly.
|
871
871
|
|
872
872
|
=== :no_association_method
|
873
873
|
|
874
|
-
Setting this to true will
|
874
|
+
Setting this to true will result in the <i>association</i> method
|
875
875
|
not being defined. This can save memory if you only use the
|
876
876
|
<i>association</i>_dataset method and do not call the <i>association</i> method
|
877
877
|
directly or indirectly.
|
@@ -1498,6 +1498,36 @@ as the qualifiers may not match the aliases automatically used by eager_graph.
|
|
1498
1498
|
This should contain unqualified identifiers, and eager_graph will automatically
|
1499
1499
|
qualify them with the appropriate alias.
|
1500
1500
|
|
1501
|
+
==== :graph_use_association_block
|
1502
|
+
|
1503
|
+
Setting this to true makes eager_graph apply the association block to the
|
1504
|
+
associated dataset before graphing the associated dataset into the receiver.
|
1505
|
+
In most cases when this option is used and the association has a block, the
|
1506
|
+
dataset returned by eager_graph will contain a JOIN to a subquery.
|
1507
|
+
|
1508
|
+
By default (when this option is not used), the association block will be ignored
|
1509
|
+
when using eager_graph:
|
1510
|
+
|
1511
|
+
Artist.one_to_many :tracks do |ds|
|
1512
|
+
ds.where(foo: 3)
|
1513
|
+
end
|
1514
|
+
Artist.eager_graph(:tracks)
|
1515
|
+
# SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
|
1516
|
+
# FROM albums
|
1517
|
+
# LEFT OUTER JOIN tracks
|
1518
|
+
# ON (tracks.album_id = albums.id)
|
1519
|
+
|
1520
|
+
When this option is used, the block will be respected:
|
1521
|
+
|
1522
|
+
Artist.one_to_many :tracks, graph_use_association_block: true do |ds|
|
1523
|
+
ds.where(foo: 3)
|
1524
|
+
end
|
1525
|
+
Artist.eager_graph(:tracks)
|
1526
|
+
# SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
|
1527
|
+
# FROM albums
|
1528
|
+
# LEFT OUTER JOIN (SELECT * FROM tracks WHERE (foo = 3)) AS tracks
|
1529
|
+
# ON (tracks.album_id = albums.id)
|
1530
|
+
|
1501
1531
|
==== :graph_join_table_conditions [+many_to_many+, +one_through_one+]
|
1502
1532
|
|
1503
1533
|
The additional conditions to use on the SQL join for the join table when
|
@@ -0,0 +1,50 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A :graph_use_association_block association option has been added,
|
4
|
+
which makes eager_graph use the association block (as eager does),
|
5
|
+
generally resulting in a JOIN to a subquery:
|
6
|
+
|
7
|
+
Artist.one_to_many :tracks, graph_use_association_block: true do |ds|
|
8
|
+
ds.where(foo: 3)
|
9
|
+
end
|
10
|
+
Artist.eager_graph(:tracks)
|
11
|
+
# SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
|
12
|
+
# FROM albums
|
13
|
+
# LEFT OUTER JOIN (SELECT * FROM tracks WHERE (foo = 3)) AS tracks
|
14
|
+
# ON (tracks.album_id = albums.id)
|
15
|
+
|
16
|
+
Assuming that the database can optimize the query correctly, using
|
17
|
+
the :graph_use_association_block option is probably simpler than
|
18
|
+
than using other :graph_* options to duplicate the conditions added
|
19
|
+
by the association block.
|
20
|
+
|
21
|
+
* Numeric/Decimal column schema entries now include :min_value and
|
22
|
+
:max_value entries on most databases, indicating the minimum and
|
23
|
+
maximum values supported for the column. Similar to the support
|
24
|
+
for integer columns added in 5.62.0, this allows the
|
25
|
+
auto_validations plugin to automatically validate the values of
|
26
|
+
the columns are in the allowed range.
|
27
|
+
|
28
|
+
= Other Improvements
|
29
|
+
|
30
|
+
* many_through_{one,many} associations now support eager_graph
|
31
|
+
callbacks.
|
32
|
+
|
33
|
+
* The :db_type column schema entries on SQLAnywhere now include
|
34
|
+
precision/scale information, to work with the numeric/decimal
|
35
|
+
column min_value/max_value support.
|
36
|
+
|
37
|
+
* The oracle adapter now includes a :column_size column schema
|
38
|
+
entry containing the precision of the columns, to work with the
|
39
|
+
numeric/decimal column min_value/max_value support.
|
40
|
+
|
41
|
+
= Backwards Compatibility
|
42
|
+
|
43
|
+
* The private Database#column_schema_integer_min_max_values method
|
44
|
+
added in 5.62.0 now takes a column schema hash instead of a
|
45
|
+
database type string.
|
46
|
+
|
47
|
+
* Code that previously looked at the :db_type column schema entry on
|
48
|
+
SQLAnywhere should be updated to look at the :domain_name entry, and
|
49
|
+
code that looked at the :domain_name_with_size entry should be
|
50
|
+
updated to look at the :db_type entry.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
= Improvements
|
2
|
+
|
3
|
+
* The pg_auto_parameterize extension now uses a modified placeholder
|
4
|
+
literalizer for speeding up the generation of SQL queries in the same
|
5
|
+
cases where a standard dataset would use a placeholder literalizer.
|
6
|
+
This can provide a 4% speedup for simple queries, with greater
|
7
|
+
speedups for more complex queries.
|
8
|
+
|
9
|
+
* Database#indexes now returns indexes for partitioned tables on
|
10
|
+
PostgreSQL 11+.
|
11
|
+
|
12
|
+
* MySQL versions not supporting CHECK constraints no longer include
|
13
|
+
:min_value/:max_value schema entries for decimal/numeric columns.
|
14
|
+
|
15
|
+
= Backwards Compatibility
|
16
|
+
|
17
|
+
* The Dataset::PlaceholderLiterlizer::Record.loader API has changed,
|
18
|
+
it now accepts the Dataset::PlaceholderLiterlizer class to use as
|
19
|
+
the first argument. This makes it easier to create
|
20
|
+
Dataset::PlaceholderLiterlizer subclasses, such as the one now used
|
21
|
+
by the pg_auto_parameterize extension.
|
data/doc/sql.rdoc
CHANGED
@@ -59,7 +59,7 @@ Then, you call the +insert+, +update+, or +delete+ method on the returned datase
|
|
59
59
|
update_ds.update
|
60
60
|
delete_ds.delete
|
61
61
|
|
62
|
-
+update+ and +delete+
|
62
|
+
+update+ and +delete+ generally return the number of rows affected, and +insert+ generally returns the autogenerated primary key integer for the row inserted (if any), but not all adapters/databases support this behavior for datasets using custom SQL (notably it is not supported for +insert+ on PostgreSQL).
|
63
63
|
|
64
64
|
=== Other Queries
|
65
65
|
|
@@ -312,6 +312,7 @@ module Sequel
|
|
312
312
|
:char_used => column.char_used?,
|
313
313
|
:char_size => column.char_size,
|
314
314
|
:data_size => column.data_size,
|
315
|
+
:column_size => column.precision,
|
315
316
|
:precision => column.precision,
|
316
317
|
:scale => column.scale,
|
317
318
|
:fsprecision => column.fsprecision,
|
@@ -60,8 +60,8 @@ module Sequel
|
|
60
60
|
# Access's Byte type will accept much larger values,
|
61
61
|
# even though it only stores 0-255. Do not set min/max
|
62
62
|
# values for the Byte type.
|
63
|
-
def column_schema_integer_min_max_values(
|
64
|
-
return if /byte/i =~ db_type
|
63
|
+
def column_schema_integer_min_max_values(column)
|
64
|
+
return if /byte/i =~ column[:db_type]
|
65
65
|
super
|
66
66
|
end
|
67
67
|
|
@@ -553,7 +553,14 @@ module Sequel
|
|
553
553
|
# Return nil if CHECK constraints are not supported, because
|
554
554
|
# versions that don't support check constraints don't raise
|
555
555
|
# errors for values outside of range.
|
556
|
-
def column_schema_integer_min_max_values(
|
556
|
+
def column_schema_integer_min_max_values(column)
|
557
|
+
super if supports_check_constraints?
|
558
|
+
end
|
559
|
+
|
560
|
+
# Return nil if CHECK constraints are not supported, because
|
561
|
+
# versions that don't support check constraints don't raise
|
562
|
+
# errors for values outside of range.
|
563
|
+
def column_schema_decimal_min_max_values(column)
|
557
564
|
super if supports_check_constraints?
|
558
565
|
end
|
559
566
|
|
@@ -178,11 +178,11 @@ module Sequel
|
|
178
178
|
''
|
179
179
|
end
|
180
180
|
|
181
|
-
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
def column_schema_integer_min_max_values(
|
185
|
-
|
181
|
+
# Support min/max integer values on Oracle only if
|
182
|
+
# they use a NUMBER column with a fixed precision
|
183
|
+
# and no scale.
|
184
|
+
def column_schema_integer_min_max_values(column)
|
185
|
+
super if column[:db_type] =~ /NUMBER\(\d+\)/i || (column[:db_type] == 'NUMBER' && column[:column_size].is_a?(Integer) && column[:scale] == 0)
|
186
186
|
end
|
187
187
|
|
188
188
|
def create_sequence_sql(name, opts=OPTS)
|
@@ -919,7 +919,7 @@ module Sequel
|
|
919
919
|
join(Sequel[:pg_attribute].as(:att), :attrelid=>Sequel[:tab][:oid], :attnum=>attnums).
|
920
920
|
left_join(Sequel[:pg_constraint].as(:con), :conname=>Sequel[:indc][:relname]).
|
921
921
|
where{{
|
922
|
-
indc[:relkind]
|
922
|
+
indc[:relkind]=>%w'i I',
|
923
923
|
ind[:indisprimary]=>false,
|
924
924
|
:indexprs=>nil,
|
925
925
|
:indisvalid=>true}}.
|
@@ -37,7 +37,7 @@ module Sequel
|
|
37
37
|
row[:auto_increment] = auto_increment == 1 || auto_increment == true
|
38
38
|
row[:primary_key] = row.delete(:pkey) == 'Y'
|
39
39
|
row[:allow_null] = row[:nulls_allowed].is_a?(Integer) ? row.delete(:nulls_allowed) == 1 : row.delete(:nulls_allowed)
|
40
|
-
row[:db_type] = row.delete(:
|
40
|
+
row[:db_type] = row.delete(:domain_name_with_size)
|
41
41
|
row[:type] = if row[:db_type] =~ /numeric/i and (row[:scale].is_a?(Integer) ? row[:scale] == 0 : !row[:scale])
|
42
42
|
:integer
|
43
43
|
else
|
@@ -320,10 +320,11 @@ module Sequel
|
|
320
320
|
end
|
321
321
|
end
|
322
322
|
|
323
|
-
# SQLite does not restrict the integer type to a specific range.
|
324
|
-
def column_schema_integer_min_max_values(
|
323
|
+
# SQLite does not restrict the integer or decimal type to a specific range.
|
324
|
+
def column_schema_integer_min_max_values(column)
|
325
325
|
nil
|
326
326
|
end
|
327
|
+
alias column_schema_decimal_min_max_values column_schema_integer_min_max_values
|
327
328
|
|
328
329
|
# Array of PRAGMA SQL statements based on the Database options that should be applied to
|
329
330
|
# new connections.
|
@@ -175,8 +175,14 @@ module Sequel
|
|
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
|
177
177
|
end
|
178
|
-
if !c[:max_value] && !c[:min_value]
|
179
|
-
|
178
|
+
if !c[:max_value] && !c[:min_value]
|
179
|
+
min_max = case c[:type]
|
180
|
+
when :integer
|
181
|
+
column_schema_integer_min_max_values(c)
|
182
|
+
when :decimal
|
183
|
+
column_schema_decimal_min_max_values(c)
|
184
|
+
end
|
185
|
+
c[:min_value], c[:max_value] = min_max if min_max
|
180
186
|
end
|
181
187
|
end
|
182
188
|
schema_post_process(cols)
|
@@ -288,7 +294,15 @@ module Sequel
|
|
288
294
|
|
289
295
|
# Look at the db_type and guess the minimum and maximum integer values for
|
290
296
|
# the column.
|
291
|
-
def column_schema_integer_min_max_values(
|
297
|
+
def column_schema_integer_min_max_values(column)
|
298
|
+
db_type = column[:db_type]
|
299
|
+
if /decimal|numeric|number/i =~ db_type
|
300
|
+
if min_max = column_schema_decimal_min_max_values(column)
|
301
|
+
min_max.map!(&:to_i)
|
302
|
+
end
|
303
|
+
return min_max
|
304
|
+
end
|
305
|
+
|
292
306
|
unsigned = /unsigned/i =~ db_type
|
293
307
|
case db_type
|
294
308
|
when /big|int8/i
|
@@ -304,6 +318,26 @@ module Sequel
|
|
304
318
|
end
|
305
319
|
end
|
306
320
|
|
321
|
+
# Look at the db_type and guess the minimum and maximum decimal values for
|
322
|
+
# the column.
|
323
|
+
def column_schema_decimal_min_max_values(column)
|
324
|
+
if column[:column_size] && column[:scale]
|
325
|
+
precision = column[:column_size]
|
326
|
+
scale = column[:scale]
|
327
|
+
elsif /\((\d+)(?:,\s*(-?\d+))?\)/ =~ column[:db_type]
|
328
|
+
precision = $1.to_i
|
329
|
+
scale = $2.to_i if $2
|
330
|
+
end
|
331
|
+
|
332
|
+
if precision
|
333
|
+
limit = BigDecimal("9" * precision)
|
334
|
+
if scale
|
335
|
+
limit /= 10**(scale)
|
336
|
+
end
|
337
|
+
[-limit, limit]
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
307
341
|
# Whether the tinyint type (if supported by the database) is unsigned by default.
|
308
342
|
def column_schema_tinyint_type_is_unsigned?
|
309
343
|
false
|
@@ -370,7 +404,7 @@ module Sequel
|
|
370
404
|
:boolean
|
371
405
|
when /\A(real|float( unsigned)?|double( precision)?|double\(\d+,\d+\)( unsigned)?)\z/io
|
372
406
|
:float
|
373
|
-
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(
|
407
|
+
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(-?\d+|false|true)\))?))\z/io
|
374
408
|
$1 && ['0', 'false'].include?($1) ? :integer : :decimal
|
375
409
|
when /bytea|blob|image|(var)?binary/io
|
376
410
|
:blob
|
data/lib/sequel/dataset/misc.rb
CHANGED
@@ -158,6 +158,16 @@ module Sequel
|
|
158
158
|
!!((opts[:from].is_a?(Array) && opts[:from].size > 1) || opts[:join])
|
159
159
|
end
|
160
160
|
|
161
|
+
# The class to use for placeholder literalizers for the current dataset.
|
162
|
+
def placeholder_literalizer_class
|
163
|
+
::Sequel::Dataset::PlaceholderLiteralizer
|
164
|
+
end
|
165
|
+
|
166
|
+
# A placeholder literalizer loader for the current dataset.
|
167
|
+
def placeholder_literalizer_loader(&block)
|
168
|
+
placeholder_literalizer_class.loader(self, &block)
|
169
|
+
end
|
170
|
+
|
161
171
|
# The alias to use for the row_number column, used when emulating OFFSET
|
162
172
|
# support and for eager limit strategies
|
163
173
|
def row_number_column
|
@@ -296,7 +306,7 @@ module Sequel
|
|
296
306
|
loader += 1
|
297
307
|
|
298
308
|
if loader >= 3
|
299
|
-
loader =
|
309
|
+
loader = placeholder_literalizer_loader{|pl, _| yield pl}
|
300
310
|
cache_set(key, loader)
|
301
311
|
else
|
302
312
|
cache_set(key, loader + 1)
|
@@ -77,8 +77,8 @@ module Sequel
|
|
77
77
|
# Yields the receiver and the dataset to the block, which should
|
78
78
|
# call #arg on the receiver for each placeholder argument, and
|
79
79
|
# return the dataset that you want to load.
|
80
|
-
def loader(dataset, &block)
|
81
|
-
|
80
|
+
def loader(pl, dataset, &block)
|
81
|
+
pl.new(*process(dataset, &block))
|
82
82
|
end
|
83
83
|
|
84
84
|
# Return an Argument with the specified position, or the next position. In
|
@@ -145,7 +145,7 @@ module Sequel
|
|
145
145
|
# given block, recording the offsets at which the recorders arguments
|
146
146
|
# are used in the query.
|
147
147
|
def self.loader(dataset, &block)
|
148
|
-
Recorder.new.loader(dataset, &block)
|
148
|
+
Recorder.new.loader(self, dataset, &block)
|
149
149
|
end
|
150
150
|
|
151
151
|
# Save the dataset, array of SQL fragments, and ending SQL string.
|
@@ -199,20 +199,31 @@ module Sequel
|
|
199
199
|
# Return the SQL query to use for the given arguments.
|
200
200
|
def sql(*args)
|
201
201
|
raise Error, "wrong number of arguments (#{args.length} for #{@arity})" unless args.length == @arity
|
202
|
-
s =
|
202
|
+
s = sql_origin
|
203
|
+
append_sql(s, *args)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Append the SQL query to use for the given arguments to the given SQL string.
|
207
|
+
def append_sql(sql, *args)
|
203
208
|
ds = @dataset
|
204
|
-
@fragments.each do |
|
205
|
-
|
209
|
+
@fragments.each do |s, i, transformer|
|
210
|
+
sql << s
|
206
211
|
if i.is_a?(Integer)
|
207
212
|
v = args.fetch(i)
|
208
213
|
v = transformer.call(v) if transformer
|
209
214
|
else
|
210
215
|
v = i.call
|
211
216
|
end
|
212
|
-
ds.literal_append(
|
217
|
+
ds.literal_append(sql, v)
|
213
218
|
end
|
214
|
-
|
215
|
-
|
219
|
+
sql << @final_sql
|
220
|
+
sql
|
221
|
+
end
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
def sql_origin
|
226
|
+
String.new
|
216
227
|
end
|
217
228
|
end
|
218
229
|
end
|
@@ -148,7 +148,10 @@ module Sequel
|
|
148
148
|
|
149
149
|
# Freeze the stored arguments when freezing the query string.
|
150
150
|
def freeze
|
151
|
-
|
151
|
+
if @args
|
152
|
+
@args.freeze
|
153
|
+
@arg_map.freeze
|
154
|
+
end
|
152
155
|
super
|
153
156
|
end
|
154
157
|
|
@@ -156,6 +159,14 @@ module Sequel
|
|
156
159
|
def inspect
|
157
160
|
@args ? "#{self}; #{@args.inspect}".inspect : super
|
158
161
|
end
|
162
|
+
|
163
|
+
def initialize_copy(other)
|
164
|
+
super
|
165
|
+
if args = other.instance_variable_get(:@args)
|
166
|
+
@args = args.dup
|
167
|
+
@arg_map = other.instance_variable_get(:@arg_map).dup
|
168
|
+
end
|
169
|
+
end
|
159
170
|
end
|
160
171
|
|
161
172
|
# Wrapper class that skips auto parameterization for the wrapped object.
|
@@ -169,6 +180,22 @@ module Sequel
|
|
169
180
|
end
|
170
181
|
end
|
171
182
|
|
183
|
+
# PlacholderLiteralizer subclass with support for stored auto parameters.
|
184
|
+
class PlaceholderLiteralizer < ::Sequel::Dataset::PlaceholderLiteralizer
|
185
|
+
def initialize(dataset, fragments, final_sql, arity)
|
186
|
+
s = dataset.sql.dup
|
187
|
+
s.clear
|
188
|
+
@sql_origin = s.freeze
|
189
|
+
super
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def sql_origin
|
195
|
+
@sql_origin.dup
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
172
199
|
module DatabaseMethods
|
173
200
|
def self.extended(db)
|
174
201
|
unless (db.adapter_scheme == :postgres && USES_PG) || (db.adapter_scheme == :mock && db.database_type == :postgres)
|
@@ -282,9 +309,13 @@ module Sequel
|
|
282
309
|
end
|
283
310
|
end
|
284
311
|
|
285
|
-
#
|
286
|
-
def
|
287
|
-
@opts[:no_auto_parameterize]
|
312
|
+
# The class to use for placeholder literalizers.
|
313
|
+
def placeholder_literalizer_class
|
314
|
+
if @opts[:no_auto_parameterize]
|
315
|
+
super
|
316
|
+
else
|
317
|
+
PlaceholderLiteralizer
|
318
|
+
end
|
288
319
|
end
|
289
320
|
|
290
321
|
# Disable automatic parameterization when using a cursor.
|
@@ -310,7 +310,17 @@ module Sequel
|
|
310
310
|
loader = union_eager_loader
|
311
311
|
joiner = " UNION ALL "
|
312
312
|
ids.each_slice(subqueries_per_union).each do |slice|
|
313
|
-
|
313
|
+
sql = loader.send(:sql_origin)
|
314
|
+
join = false
|
315
|
+
slice.each do |k|
|
316
|
+
if join
|
317
|
+
sql << joiner
|
318
|
+
else
|
319
|
+
join = true
|
320
|
+
end
|
321
|
+
loader.append_sql(sql, *k)
|
322
|
+
end
|
323
|
+
objects.concat(ds.with_sql(sql).to_a)
|
314
324
|
end
|
315
325
|
ds = ds.eager(cascade) if cascade
|
316
326
|
ds.send(:post_load, objects)
|
@@ -446,7 +456,7 @@ module Sequel
|
|
446
456
|
def placeholder_loader
|
447
457
|
if use_placeholder_loader?
|
448
458
|
cached_fetch(:placeholder_loader) do
|
449
|
-
|
459
|
+
associated_dataset.placeholder_literalizer_loader do |pl, ds|
|
450
460
|
ds = ds.where(Sequel.&(*predicate_keys.map{|k| SQL::BooleanExpression.new(:'=', k, pl.arg)}))
|
451
461
|
if self[:block]
|
452
462
|
ds = self[:block].call(ds)
|
@@ -748,8 +758,8 @@ module Sequel
|
|
748
758
|
# A placeholder literalizer used to speed up eager loading.
|
749
759
|
def placeholder_eager_loader
|
750
760
|
cached_fetch(:placeholder_eager_loader) do
|
751
|
-
|
752
|
-
apply_eager_limit_strategy(
|
761
|
+
eager_loading_dataset.placeholder_literalizer_loader do |pl, ds|
|
762
|
+
apply_eager_limit_strategy(ds.where(predicate_key=>pl.arg), eager_limit_strategy)
|
753
763
|
end
|
754
764
|
end
|
755
765
|
end
|
@@ -808,7 +818,7 @@ module Sequel
|
|
808
818
|
# loading a limited association.
|
809
819
|
def union_eager_loader
|
810
820
|
cached_fetch(:union_eager_loader) do
|
811
|
-
|
821
|
+
associated_dataset.placeholder_literalizer_loader do |pl, ds|
|
812
822
|
ds = self[:eager_block].call(ds) if self[:eager_block]
|
813
823
|
keys = predicate_keys
|
814
824
|
ds = ds.where(keys.map{pl.arg}.zip(keys))
|
@@ -1722,6 +1732,8 @@ module Sequel
|
|
1722
1732
|
# :graph_select :: A column or array of columns to select from the associated table
|
1723
1733
|
# when eagerly loading the association via +eager_graph+. Defaults to all
|
1724
1734
|
# columns in the associated table.
|
1735
|
+
# :graph_use_association_block :: Makes eager_graph consider the association block. Without this, eager_graph
|
1736
|
+
# ignores the bock and only use the :graph_* options.
|
1725
1737
|
# :instance_specific :: Marks the association as instance specific. Should be used if the association block
|
1726
1738
|
# uses instance specific state, or transient state (accessing current date/time, etc.).
|
1727
1739
|
# :limit :: Limit the number of records to the provided value. Use
|
@@ -2461,6 +2473,9 @@ module Sequel
|
|
2461
2473
|
# Return dataset to graph into given the association reflection, applying the :callback option if set.
|
2462
2474
|
def eager_graph_dataset(opts, eager_options)
|
2463
2475
|
ds = opts.associated_class.dataset
|
2476
|
+
if opts[:graph_use_association_block] && (b = opts[:block])
|
2477
|
+
ds = b.call(ds)
|
2478
|
+
end
|
2464
2479
|
if cb = eager_options[:callback]
|
2465
2480
|
ds = cb.call(ds)
|
2466
2481
|
end
|
@@ -385,7 +385,7 @@ module Sequel
|
|
385
385
|
iq = nil
|
386
386
|
end
|
387
387
|
fe = opts.final_edge
|
388
|
-
ds.graph(opts
|
388
|
+
ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
|
389
389
|
end
|
390
390
|
end
|
391
391
|
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 = 65
|
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.65.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:
|
11
|
+
date: 2023-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -195,6 +195,8 @@ extra_rdoc_files:
|
|
195
195
|
- doc/release_notes/5.61.0.txt
|
196
196
|
- doc/release_notes/5.62.0.txt
|
197
197
|
- doc/release_notes/5.63.0.txt
|
198
|
+
- doc/release_notes/5.64.0.txt
|
199
|
+
- doc/release_notes/5.65.0.txt
|
198
200
|
- doc/release_notes/5.7.0.txt
|
199
201
|
- doc/release_notes/5.8.0.txt
|
200
202
|
- doc/release_notes/5.9.0.txt
|
@@ -286,6 +288,8 @@ files:
|
|
286
288
|
- doc/release_notes/5.61.0.txt
|
287
289
|
- doc/release_notes/5.62.0.txt
|
288
290
|
- doc/release_notes/5.63.0.txt
|
291
|
+
- doc/release_notes/5.64.0.txt
|
292
|
+
- doc/release_notes/5.65.0.txt
|
289
293
|
- doc/release_notes/5.7.0.txt
|
290
294
|
- doc/release_notes/5.8.0.txt
|
291
295
|
- doc/release_notes/5.9.0.txt
|
@@ -609,7 +613,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
609
613
|
- !ruby/object:Gem::Version
|
610
614
|
version: '0'
|
611
615
|
requirements: []
|
612
|
-
rubygems_version: 3.
|
616
|
+
rubygems_version: 3.4.1
|
613
617
|
signing_key:
|
614
618
|
specification_version: 4
|
615
619
|
summary: The Database Toolkit for Ruby
|