sequel 5.60.1 → 5.81.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 +280 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +27 -24
- data/doc/advanced_associations.rdoc +16 -14
- data/doc/association_basics.rdoc +53 -17
- data/doc/cheat_sheet.rdoc +3 -3
- data/doc/code_order.rdoc +5 -3
- data/doc/dataset_basics.rdoc +1 -1
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +15 -0
- data/doc/model_hooks.rdoc +1 -1
- data/doc/object_model.rdoc +8 -8
- data/doc/opening_databases.rdoc +18 -7
- data/doc/postgresql.rdoc +8 -8
- data/doc/querying.rdoc +7 -2
- 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/release_notes/5.78.0.txt +67 -0
- data/doc/release_notes/5.79.0.txt +28 -0
- data/doc/release_notes/5.80.0.txt +40 -0
- data/doc/release_notes/5.81.0.txt +31 -0
- data/doc/schema_modification.rdoc +3 -3
- data/doc/security.rdoc +9 -9
- data/doc/sharding.rdoc +3 -1
- data/doc/sql.rdoc +14 -14
- data/doc/testing.rdoc +16 -12
- data/doc/transactions.rdoc +6 -6
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/ibmdb.rb +1 -1
- data/lib/sequel/adapters/jdbc/h2.rb +3 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -0
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
- data/lib/sequel/adapters/jdbc.rb +10 -6
- data/lib/sequel/adapters/mysql.rb +19 -7
- data/lib/sequel/adapters/mysql2.rb +2 -2
- data/lib/sequel/adapters/odbc/mssql.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +1 -0
- data/lib/sequel/adapters/postgres.rb +10 -5
- data/lib/sequel/adapters/shared/access.rb +9 -1
- data/lib/sequel/adapters/shared/db2.rb +12 -0
- data/lib/sequel/adapters/shared/mssql.rb +71 -9
- data/lib/sequel/adapters/shared/mysql.rb +82 -3
- data/lib/sequel/adapters/shared/oracle.rb +17 -7
- data/lib/sequel/adapters/shared/postgres.rb +469 -160
- data/lib/sequel/adapters/shared/sqlanywhere.rb +18 -5
- data/lib/sequel/adapters/shared/sqlite.rb +39 -3
- data/lib/sequel/adapters/sqlite.rb +42 -3
- data/lib/sequel/adapters/trilogy.rb +117 -0
- 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/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/database/connecting.rb +25 -1
- data/lib/sequel/database/dataset.rb +16 -6
- data/lib/sequel/database/misc.rb +65 -14
- data/lib/sequel/database/query.rb +72 -1
- data/lib/sequel/database/schema_generator.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +12 -5
- data/lib/sequel/database/transactions.rb +6 -0
- data/lib/sequel/dataset/actions.rb +60 -13
- data/lib/sequel/dataset/dataset_module.rb +1 -1
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
- data/lib/sequel/dataset/features.rb +15 -1
- data/lib/sequel/dataset/graph.rb +1 -0
- data/lib/sequel/dataset/misc.rb +12 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
- data/lib/sequel/dataset/query.rb +119 -45
- data/lib/sequel/dataset/sql.rb +58 -36
- data/lib/sequel/dataset.rb +4 -0
- data/lib/sequel/exceptions.rb +5 -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 +21 -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/caller_logging.rb +4 -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/date_arithmetic.rb +1 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +10 -9
- data/lib/sequel/extensions/index_caching.rb +5 -1
- data/lib/sequel/extensions/looser_typecasting.rb +3 -0
- data/lib/sequel/extensions/migration.rb +65 -15
- data/lib/sequel/extensions/named_timezones.rb +22 -6
- data/lib/sequel/extensions/pg_array.rb +33 -4
- 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 +38 -27
- data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
- data/lib/sequel/extensions/pg_hstore.rb +5 -0
- data/lib/sequel/extensions/pg_inet.rb +10 -11
- data/lib/sequel/extensions/pg_interval.rb +10 -11
- data/lib/sequel/extensions/pg_json.rb +10 -10
- data/lib/sequel/extensions/pg_json_ops.rb +3 -3
- data/lib/sequel/extensions/pg_multirange.rb +6 -11
- data/lib/sequel/extensions/pg_range.rb +9 -14
- data/lib/sequel/extensions/pg_row.rb +20 -19
- data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
- data/lib/sequel/extensions/provenance.rb +110 -0
- data/lib/sequel/extensions/round_timestamps.rb +1 -1
- data/lib/sequel/extensions/schema_caching.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +32 -9
- data/lib/sequel/extensions/server_block.rb +2 -1
- data/lib/sequel/extensions/set_literalizer.rb +58 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +76 -18
- data/lib/sequel/extensions/temporarily_release_connection.rb +178 -0
- data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
- data/lib/sequel/model/associations.rb +38 -11
- data/lib/sequel/model/base.rb +32 -18
- data/lib/sequel/model/dataset_module.rb +3 -0
- data/lib/sequel/model/exceptions.rb +15 -3
- data/lib/sequel/plugins/auto_validations.rb +53 -15
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/column_encryption.rb +28 -7
- data/lib/sequel/plugins/composition.rb +2 -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/finder.rb +4 -2
- data/lib/sequel/plugins/input_transformer.rb +1 -1
- data/lib/sequel/plugins/list.rb +5 -2
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- 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_auto_constraint_validations.rb +9 -3
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
- data/lib/sequel/plugins/prepared_statements.rb +2 -1
- 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/single_table_inheritance.rb +8 -0
- data/lib/sequel/plugins/sql_comments.rb +1 -1
- data/lib/sequel/plugins/static_cache.rb +38 -0
- data/lib/sequel/plugins/static_cache_cache.rb +5 -1
- data/lib/sequel/plugins/tactical_eager_loading.rb +14 -14
- data/lib/sequel/plugins/validate_associated.rb +22 -12
- data/lib/sequel/plugins/validation_helpers.rb +29 -2
- data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
- data/lib/sequel/version.rb +2 -2
- metadata +79 -6
|
@@ -127,6 +127,18 @@ module Sequel
|
|
|
127
127
|
#
|
|
128
128
|
# DB[:table].delete # DELETE * FROM table
|
|
129
129
|
# # => 3
|
|
130
|
+
#
|
|
131
|
+
# Some databases support using multiple tables in a DELETE query. This requires
|
|
132
|
+
# multiple FROM tables (JOINs can also be used). As multiple FROM tables use
|
|
133
|
+
# an implicit CROSS JOIN, you should make sure your WHERE condition uses the
|
|
134
|
+
# appropriate filters for the FROM tables:
|
|
135
|
+
#
|
|
136
|
+
# DB.from(:a, :b).join(:c, :d=>Sequel[:b][:e]).where{{a[:f]=>b[:g], a[:id]=>c[:h]}}.
|
|
137
|
+
# delete
|
|
138
|
+
# # DELETE FROM a
|
|
139
|
+
# # USING b
|
|
140
|
+
# # INNER JOIN c ON (c.d = b.e)
|
|
141
|
+
# # WHERE ((a.f = b.g) AND (a.id = c.h))
|
|
130
142
|
def delete(&block)
|
|
131
143
|
sql = delete_sql
|
|
132
144
|
if uses_returning?(:delete)
|
|
@@ -162,7 +174,7 @@ module Sequel
|
|
|
162
174
|
# # => false
|
|
163
175
|
def empty?
|
|
164
176
|
cached_dataset(:_empty_ds) do
|
|
165
|
-
single_value_ds.unordered.select(EMPTY_SELECT)
|
|
177
|
+
(@opts[:sql] ? from_self : self).single_value_ds.unordered.select(EMPTY_SELECT)
|
|
166
178
|
end.single_value!.nil?
|
|
167
179
|
end
|
|
168
180
|
|
|
@@ -313,14 +325,18 @@ module Sequel
|
|
|
313
325
|
|
|
314
326
|
# Inserts multiple records into the associated table. This method can be
|
|
315
327
|
# used to efficiently insert a large number of records into a table in a
|
|
316
|
-
# single query if the database supports it. Inserts
|
|
317
|
-
#
|
|
328
|
+
# single query if the database supports it. Inserts are automatically
|
|
329
|
+
# wrapped in a transaction if necessary.
|
|
318
330
|
#
|
|
319
331
|
# This method is called with a columns array and an array of value arrays:
|
|
320
332
|
#
|
|
321
333
|
# DB[:table].import([:x, :y], [[1, 2], [3, 4]])
|
|
322
334
|
# # INSERT INTO table (x, y) VALUES (1, 2)
|
|
323
|
-
# # INSERT INTO table (x, y) VALUES (3, 4)
|
|
335
|
+
# # INSERT INTO table (x, y) VALUES (3, 4)
|
|
336
|
+
#
|
|
337
|
+
# or, if the database supports it:
|
|
338
|
+
#
|
|
339
|
+
# # INSERT INTO table (x, y) VALUES (1, 2), (3, 4)
|
|
324
340
|
#
|
|
325
341
|
# This method also accepts a dataset instead of an array of value arrays:
|
|
326
342
|
#
|
|
@@ -328,17 +344,23 @@ module Sequel
|
|
|
328
344
|
# # INSERT INTO table (x, y) SELECT a, b FROM table2
|
|
329
345
|
#
|
|
330
346
|
# Options:
|
|
331
|
-
# :commit_every :: Open a new transaction for every given number of
|
|
332
|
-
# For example, if you provide a value of 50,
|
|
333
|
-
# after every 50 records.
|
|
347
|
+
# :commit_every :: Open a new transaction for every given number of
|
|
348
|
+
# records. For example, if you provide a value of 50,
|
|
349
|
+
# will commit after every 50 records. When a
|
|
350
|
+
# transaction is not required, this option controls
|
|
351
|
+
# the maximum number of values to insert with a single
|
|
352
|
+
# statement; it does not force the use of a
|
|
353
|
+
# transaction.
|
|
334
354
|
# :return :: When this is set to :primary_key, returns an array of
|
|
335
355
|
# autoincremented primary key values for the rows inserted.
|
|
336
356
|
# This does not have an effect if +values+ is a Dataset.
|
|
337
357
|
# :server :: Set the server/shard to use for the transaction and insert
|
|
338
358
|
# queries.
|
|
359
|
+
# :skip_transaction :: Do not use a transaction even when using multiple
|
|
360
|
+
# INSERT queries.
|
|
339
361
|
# :slice :: Same as :commit_every, :commit_every takes precedence.
|
|
340
362
|
def import(columns, values, opts=OPTS)
|
|
341
|
-
return
|
|
363
|
+
return insert(columns, values) if values.is_a?(Dataset)
|
|
342
364
|
|
|
343
365
|
return if values.empty?
|
|
344
366
|
raise(Error, 'Using Sequel::Dataset#import with an empty column array is not allowed') if columns.empty?
|
|
@@ -568,6 +590,8 @@ module Sequel
|
|
|
568
590
|
# if your ORDER BY expressions are not simple columns, if they contain
|
|
569
591
|
# qualified identifiers that would be ambiguous unqualified, if they contain
|
|
570
592
|
# any identifiers that are aliased in SELECT, and potentially other cases.
|
|
593
|
+
# :skip_transaction :: Do not use a transaction. This can be useful if you want to prevent
|
|
594
|
+
# a lock on the database table, at the expense of consistency.
|
|
571
595
|
#
|
|
572
596
|
# Examples:
|
|
573
597
|
#
|
|
@@ -576,7 +600,7 @@ module Sequel
|
|
|
576
600
|
# # SELECT * FROM table ORDER BY id LIMIT 1000 OFFSET 1000
|
|
577
601
|
# # ...
|
|
578
602
|
#
|
|
579
|
-
# DB[:table].order(:id).paged_each(:
|
|
603
|
+
# DB[:table].order(:id).paged_each(rows_per_fetch: 100){|row| }
|
|
580
604
|
# # SELECT * FROM table ORDER BY id LIMIT 100
|
|
581
605
|
# # SELECT * FROM table ORDER BY id LIMIT 100 OFFSET 100
|
|
582
606
|
# # ...
|
|
@@ -918,6 +942,19 @@ module Sequel
|
|
|
918
942
|
#
|
|
919
943
|
# DB[:table].update(x: Sequel[:x]+1, y: 0) # UPDATE table SET x = (x + 1), y = 0
|
|
920
944
|
# # => 10
|
|
945
|
+
#
|
|
946
|
+
# Some databases support using multiple tables in an UPDATE query. This requires
|
|
947
|
+
# multiple FROM tables (JOINs can also be used). As multiple FROM tables use
|
|
948
|
+
# an implicit CROSS JOIN, you should make sure your WHERE condition uses the
|
|
949
|
+
# appropriate filters for the FROM tables:
|
|
950
|
+
#
|
|
951
|
+
# DB.from(:a, :b).join(:c, :d=>Sequel[:b][:e]).where{{a[:f]=>b[:g], a[:id]=>10}}.
|
|
952
|
+
# update(:f=>Sequel[:c][:h])
|
|
953
|
+
# # UPDATE a
|
|
954
|
+
# # SET f = c.h
|
|
955
|
+
# # FROM b
|
|
956
|
+
# # INNER JOIN c ON (c.d = b.e)
|
|
957
|
+
# # WHERE ((a.f = b.g) AND (a.id = 10))
|
|
921
958
|
def update(values=OPTS, &block)
|
|
922
959
|
sql = update_sql(values)
|
|
923
960
|
if uses_returning?(:update)
|
|
@@ -1023,18 +1060,19 @@ module Sequel
|
|
|
1023
1060
|
|
|
1024
1061
|
# Internals of #import. If primary key values are requested, use
|
|
1025
1062
|
# separate insert commands for each row. Otherwise, call #multi_insert_sql
|
|
1026
|
-
# and execute each statement it gives separately.
|
|
1063
|
+
# and execute each statement it gives separately. A transaction is only used
|
|
1064
|
+
# if there are multiple statements to execute.
|
|
1027
1065
|
def _import(columns, values, opts)
|
|
1028
1066
|
trans_opts = Hash[opts]
|
|
1029
1067
|
trans_opts[:server] = @opts[:server]
|
|
1030
1068
|
if opts[:return] == :primary_key
|
|
1031
|
-
|
|
1069
|
+
_import_transaction(values, trans_opts){values.map{|v| insert(columns, v)}}
|
|
1032
1070
|
else
|
|
1033
1071
|
stmts = multi_insert_sql(columns, values)
|
|
1034
|
-
|
|
1072
|
+
_import_transaction(stmts, trans_opts){stmts.each{|st| execute_dui(st)}}
|
|
1035
1073
|
end
|
|
1036
1074
|
end
|
|
1037
|
-
|
|
1075
|
+
|
|
1038
1076
|
# Return an array of arrays of values given by the symbols in ret_cols.
|
|
1039
1077
|
def _select_map_multiple(ret_cols)
|
|
1040
1078
|
map{|r| r.values_at(*ret_cols)}
|
|
@@ -1073,6 +1111,15 @@ module Sequel
|
|
|
1073
1111
|
end
|
|
1074
1112
|
end
|
|
1075
1113
|
|
|
1114
|
+
# Use a transaction when yielding to the block if multiple values/statements
|
|
1115
|
+
# are provided. When only a single value or statement is provided, then yield
|
|
1116
|
+
# without using a transaction.
|
|
1117
|
+
def _import_transaction(values, trans_opts, &block)
|
|
1118
|
+
# OK to mutate trans_opts as it is generated by _import
|
|
1119
|
+
trans_opts[:skip_transaction] = true if values.length <= 1
|
|
1120
|
+
@db.transaction(trans_opts, &block)
|
|
1121
|
+
end
|
|
1122
|
+
|
|
1076
1123
|
# Internals of +select_hash+ and +select_hash_groups+
|
|
1077
1124
|
def _select_hash(meth, key_column, value_column, opts=OPTS)
|
|
1078
1125
|
select(*(key_column.is_a?(Array) ? key_column : [key_column]) + (value_column.is_a?(Array) ? value_column : [value_column])).
|
|
@@ -21,7 +21,7 @@ module Sequel
|
|
|
21
21
|
where exclude exclude_having having
|
|
22
22
|
distinct grep group group_and_count group_append
|
|
23
23
|
limit offset order order_append order_prepend reverse
|
|
24
|
-
select select_all select_append select_group server
|
|
24
|
+
select select_all select_append select_group select_prepend server
|
|
25
25
|
METHS
|
|
26
26
|
|
|
27
27
|
# Define a method in the module
|
|
@@ -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
|
|
@@ -25,11 +25,16 @@ module Sequel
|
|
|
25
25
|
false
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
# :nocov:
|
|
29
|
+
|
|
28
30
|
# Whether the dataset requires SQL standard datetimes. False by default,
|
|
29
|
-
# as most allow strings with ISO 8601 format.
|
|
31
|
+
# as most allow strings with ISO 8601 format. Only for backwards compatibility,
|
|
32
|
+
# no longer used internally, do not use in new code.
|
|
30
33
|
def requires_sql_standard_datetimes?
|
|
34
|
+
# SEQUEL6: Remove
|
|
31
35
|
false
|
|
32
36
|
end
|
|
37
|
+
# :nocov:
|
|
33
38
|
|
|
34
39
|
# Whether type specifiers are required for prepared statement/bound
|
|
35
40
|
# variable argument placeholders (i.e. :bv__integer), false by default.
|
|
@@ -152,6 +157,11 @@ module Sequel
|
|
|
152
157
|
supports_distinct_on?
|
|
153
158
|
end
|
|
154
159
|
|
|
160
|
+
# Whether placeholder literalizers are supported, true by default.
|
|
161
|
+
def supports_placeholder_literalizer?
|
|
162
|
+
true
|
|
163
|
+
end
|
|
164
|
+
|
|
155
165
|
# Whether the dataset supports pattern matching by regular expressions, false by default.
|
|
156
166
|
def supports_regexp?
|
|
157
167
|
false
|
|
@@ -178,10 +188,14 @@ module Sequel
|
|
|
178
188
|
true
|
|
179
189
|
end
|
|
180
190
|
|
|
191
|
+
# :nocov:
|
|
192
|
+
|
|
181
193
|
# Whether the dataset supports timezones in literal timestamps, false by default.
|
|
182
194
|
def supports_timestamp_timezones?
|
|
195
|
+
# SEQUEL6: Remove
|
|
183
196
|
false
|
|
184
197
|
end
|
|
198
|
+
# :nocov:
|
|
185
199
|
|
|
186
200
|
# Whether the dataset supports fractional seconds in literal timestamps, true by default.
|
|
187
201
|
def supports_timestamp_usecs?
|
data/lib/sequel/dataset/graph.rb
CHANGED
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,13 +306,13 @@ 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)
|
|
303
313
|
loader = nil
|
|
304
314
|
end
|
|
305
|
-
elsif cache_sql?
|
|
315
|
+
elsif cache_sql? && supports_placeholder_literalizer?
|
|
306
316
|
cache_set(key, 1)
|
|
307
317
|
end
|
|
308
318
|
|
|
@@ -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
|