sequel 5.63.0 → 5.65.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|