sequel 5.39.0 → 5.72.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 +408 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +59 -27
- data/bin/sequel +11 -3
- data/doc/advanced_associations.rdoc +16 -14
- data/doc/association_basics.rdoc +119 -24
- data/doc/cheat_sheet.rdoc +11 -3
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +13 -6
- data/doc/model_hooks.rdoc +1 -1
- data/doc/object_model.rdoc +8 -8
- data/doc/opening_databases.rdoc +26 -12
- data/doc/postgresql.rdoc +16 -8
- data/doc/querying.rdoc +5 -3
- data/doc/release_notes/5.40.0.txt +40 -0
- data/doc/release_notes/5.41.0.txt +25 -0
- data/doc/release_notes/5.42.0.txt +136 -0
- data/doc/release_notes/5.43.0.txt +98 -0
- data/doc/release_notes/5.44.0.txt +32 -0
- data/doc/release_notes/5.45.0.txt +34 -0
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/release_notes/5.50.0.txt +78 -0
- data/doc/release_notes/5.51.0.txt +47 -0
- data/doc/release_notes/5.52.0.txt +87 -0
- data/doc/release_notes/5.53.0.txt +23 -0
- data/doc/release_notes/5.54.0.txt +27 -0
- data/doc/release_notes/5.55.0.txt +21 -0
- data/doc/release_notes/5.56.0.txt +51 -0
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/release_notes/5.60.0.txt +22 -0
- data/doc/release_notes/5.61.0.txt +43 -0
- data/doc/release_notes/5.62.0.txt +132 -0
- data/doc/release_notes/5.63.0.txt +33 -0
- data/doc/release_notes/5.64.0.txt +50 -0
- data/doc/release_notes/5.65.0.txt +21 -0
- data/doc/release_notes/5.66.0.txt +24 -0
- data/doc/release_notes/5.67.0.txt +32 -0
- data/doc/release_notes/5.68.0.txt +61 -0
- data/doc/release_notes/5.69.0.txt +26 -0
- data/doc/release_notes/5.70.0.txt +35 -0
- data/doc/release_notes/5.71.0.txt +21 -0
- data/doc/release_notes/5.72.0.txt +33 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/security.rdoc +9 -9
- data/doc/sharding.rdoc +3 -1
- data/doc/sql.rdoc +28 -16
- data/doc/testing.rdoc +22 -11
- data/doc/transactions.rdoc +6 -6
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/ado.rb +17 -17
- data/lib/sequel/adapters/amalgalite.rb +3 -5
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc/derby.rb +8 -0
- data/lib/sequel/adapters/jdbc/h2.rb +60 -10
- data/lib/sequel/adapters/jdbc/hsqldb.rb +6 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
- data/lib/sequel/adapters/jdbc.rb +16 -18
- data/lib/sequel/adapters/mysql.rb +92 -67
- data/lib/sequel/adapters/mysql2.rb +54 -49
- data/lib/sequel/adapters/odbc.rb +6 -2
- data/lib/sequel/adapters/oracle.rb +4 -3
- data/lib/sequel/adapters/postgres.rb +83 -40
- data/lib/sequel/adapters/shared/access.rb +11 -1
- data/lib/sequel/adapters/shared/db2.rb +30 -0
- data/lib/sequel/adapters/shared/mssql.rb +90 -9
- data/lib/sequel/adapters/shared/mysql.rb +47 -2
- data/lib/sequel/adapters/shared/oracle.rb +82 -1
- data/lib/sequel/adapters/shared/postgres.rb +496 -178
- data/lib/sequel/adapters/shared/sqlanywhere.rb +11 -1
- data/lib/sequel/adapters/shared/sqlite.rb +116 -11
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +60 -18
- data/lib/sequel/adapters/tinytds.rb +1 -1
- data/lib/sequel/adapters/trilogy.rb +117 -0
- data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/ast_transformer.rb +6 -0
- data/lib/sequel/connection_pool/sharded_single.rb +5 -7
- data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
- data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
- data/lib/sequel/connection_pool/single.rb +6 -8
- data/lib/sequel/connection_pool/threaded.rb +14 -8
- data/lib/sequel/connection_pool/timed_queue.rb +270 -0
- data/lib/sequel/connection_pool.rb +55 -31
- data/lib/sequel/core.rb +28 -18
- data/lib/sequel/database/connecting.rb +27 -3
- data/lib/sequel/database/dataset.rb +16 -6
- data/lib/sequel/database/misc.rb +69 -14
- data/lib/sequel/database/query.rb +73 -2
- data/lib/sequel/database/schema_generator.rb +46 -53
- data/lib/sequel/database/schema_methods.rb +18 -2
- data/lib/sequel/dataset/actions.rb +108 -14
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
- data/lib/sequel/dataset/features.rb +20 -0
- data/lib/sequel/dataset/misc.rb +12 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +171 -44
- data/lib/sequel/dataset/sql.rb +182 -47
- data/lib/sequel/dataset.rb +4 -0
- data/lib/sequel/extensions/_model_pg_row.rb +0 -12
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/any_not_empty.rb +1 -1
- data/lib/sequel/extensions/async_thread_pool.rb +439 -0
- data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/connection_expiration.rb +15 -9
- data/lib/sequel/extensions/connection_validator.rb +16 -11
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/core_refinements.rb +36 -11
- data/lib/sequel/extensions/date_arithmetic.rb +71 -31
- data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
- data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/eval_inspect.rb +2 -0
- data/lib/sequel/extensions/index_caching.rb +5 -1
- data/lib/sequel/extensions/inflector.rb +9 -1
- data/lib/sequel/extensions/is_distinct_from.rb +141 -0
- data/lib/sequel/extensions/looser_typecasting.rb +3 -0
- data/lib/sequel/extensions/migration.rb +11 -2
- data/lib/sequel/extensions/named_timezones.rb +26 -6
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +32 -4
- data/lib/sequel/extensions/pg_array_ops.rb +2 -2
- data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
- data/lib/sequel/extensions/pg_enum.rb +2 -3
- 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 +6 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
- data/lib/sequel/extensions/pg_inet.rb +10 -11
- data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
- data/lib/sequel/extensions/pg_interval.rb +45 -19
- data/lib/sequel/extensions/pg_json.rb +13 -15
- data/lib/sequel/extensions/pg_json_ops.rb +73 -2
- data/lib/sequel/extensions/pg_loose_count.rb +3 -1
- data/lib/sequel/extensions/pg_multirange.rb +367 -0
- data/lib/sequel/extensions/pg_range.rb +11 -24
- data/lib/sequel/extensions/pg_range_ops.rb +37 -9
- data/lib/sequel/extensions/pg_row.rb +21 -19
- data/lib/sequel/extensions/pg_row_ops.rb +1 -1
- data/lib/sequel/extensions/query.rb +2 -0
- data/lib/sequel/extensions/s.rb +2 -1
- data/lib/sequel/extensions/schema_caching.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +45 -11
- data/lib/sequel/extensions/server_block.rb +10 -13
- data/lib/sequel/extensions/set_literalizer.rb +58 -0
- data/lib/sequel/extensions/sql_comments.rb +110 -3
- data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
- data/lib/sequel/extensions/string_agg.rb +1 -1
- data/lib/sequel/extensions/string_date_time.rb +19 -23
- data/lib/sequel/extensions/symbol_aref.rb +2 -0
- data/lib/sequel/model/associations.rb +345 -101
- data/lib/sequel/model/base.rb +51 -27
- data/lib/sequel/model/dataset_module.rb +3 -0
- data/lib/sequel/model/errors.rb +10 -1
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model/plugins.rb +5 -0
- data/lib/sequel/plugins/association_proxies.rb +2 -0
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
- data/lib/sequel/plugins/auto_validations.rb +87 -15
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/composition.rb +10 -4
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +10 -6
- data/lib/sequel/plugins/dataset_associations.rb +4 -1
- data/lib/sequel/plugins/defaults_setter.rb +16 -0
- data/lib/sequel/plugins/dirty.rb +1 -1
- data/lib/sequel/plugins/enum.rb +124 -0
- data/lib/sequel/plugins/finder.rb +4 -2
- data/lib/sequel/plugins/insert_conflict.rb +4 -0
- data/lib/sequel/plugins/instance_specific_default.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +39 -24
- data/lib/sequel/plugins/lazy_attributes.rb +3 -0
- data/lib/sequel/plugins/list.rb +3 -1
- data/lib/sequel/plugins/many_through_many.rb +109 -10
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
- data/lib/sequel/plugins/nested_attributes.rb +12 -7
- data/lib/sequel/plugins/optimistic_locking.rb +9 -42
- data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
- data/lib/sequel/plugins/pg_array_associations.rb +56 -38
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +11 -3
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
- data/lib/sequel/plugins/prepared_statements.rb +12 -2
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
- data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
- data/lib/sequel/plugins/rcte_tree.rb +27 -19
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/serialization.rb +9 -3
- data/lib/sequel/plugins/serialization_modification_detection.rb +2 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
- data/lib/sequel/plugins/sql_comments.rb +189 -0
- data/lib/sequel/plugins/static_cache.rb +39 -1
- data/lib/sequel/plugins/static_cache_cache.rb +5 -1
- data/lib/sequel/plugins/subclasses.rb +28 -11
- data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +1 -1
- data/lib/sequel/plugins/validate_associated.rb +22 -12
- data/lib/sequel/plugins/validation_helpers.rb +46 -12
- data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/timezones.rb +12 -14
- data/lib/sequel/version.rb +1 -1
- metadata +132 -38
@@ -19,7 +19,7 @@ module Sequel
|
|
19
19
|
METHS
|
20
20
|
|
21
21
|
# The clone options to use when retrieving columns for a dataset.
|
22
|
-
COLUMNS_CLONE_OPTIONS = {:distinct => nil, :limit =>
|
22
|
+
COLUMNS_CLONE_OPTIONS = {:distinct => nil, :limit => 0, :offset=>nil, :where=>nil, :having=>nil, :order=>nil, :row_proc=>nil, :graph=>nil, :eager_graph=>nil}.freeze
|
23
23
|
|
24
24
|
# Inserts the given argument into the database. Returns self so it
|
25
25
|
# can be used safely when chaining:
|
@@ -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,9 +344,13 @@ 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.
|
@@ -457,6 +477,55 @@ module Sequel
|
|
457
477
|
_aggregate(:max, arg)
|
458
478
|
end
|
459
479
|
|
480
|
+
# Execute a MERGE statement, which allows for INSERT, UPDATE, and DELETE
|
481
|
+
# behavior in a single query, based on whether rows from a source table
|
482
|
+
# match rows in the current table, based on the join conditions.
|
483
|
+
#
|
484
|
+
# Unless the dataset uses static SQL, to use #merge, you must first have
|
485
|
+
# called #merge_using to specify the merge source and join conditions.
|
486
|
+
# You will then likely to call one or more of the following methods
|
487
|
+
# to specify MERGE behavior by adding WHEN [NOT] MATCHED clauses:
|
488
|
+
#
|
489
|
+
# * #merge_insert
|
490
|
+
# * #merge_update
|
491
|
+
# * #merge_delete
|
492
|
+
#
|
493
|
+
# The WHEN [NOT] MATCHED clauses are added to the SQL in the order these
|
494
|
+
# methods were called on the dataset. If none of these methods are
|
495
|
+
# called, an error is raised.
|
496
|
+
#
|
497
|
+
# Example:
|
498
|
+
#
|
499
|
+
# DB[:m1]
|
500
|
+
# merge_using(:m2, i1: :i2).
|
501
|
+
# merge_insert(i1: :i2, a: Sequel[:b]+11).
|
502
|
+
# merge_delete{a > 30}.
|
503
|
+
# merge_update(i1: Sequel[:i1]+:i2+10, a: Sequel[:a]+:b+20).
|
504
|
+
# merge
|
505
|
+
#
|
506
|
+
# SQL:
|
507
|
+
#
|
508
|
+
# MERGE INTO m1 USING m2 ON (i1 = i2)
|
509
|
+
# WHEN NOT MATCHED THEN INSERT (i1, a) VALUES (i2, (b + 11))
|
510
|
+
# WHEN MATCHED AND (a > 30) THEN DELETE
|
511
|
+
# WHEN MATCHED THEN UPDATE SET i1 = (i1 + i2 + 10), a = (a + b + 20)
|
512
|
+
#
|
513
|
+
# On PostgreSQL, two additional merge methods are supported, for the
|
514
|
+
# PostgreSQL-specific DO NOTHING syntax.
|
515
|
+
#
|
516
|
+
# * #merge_do_nothing_when_matched
|
517
|
+
# * #merge_do_nothing_when_not_matched
|
518
|
+
#
|
519
|
+
# This method is supported on Oracle, but Oracle's MERGE support is
|
520
|
+
# non-standard, and has the following issues:
|
521
|
+
#
|
522
|
+
# * DELETE clause requires UPDATE clause
|
523
|
+
# * DELETE clause requires a condition
|
524
|
+
# * DELETE clause only affects rows updated by UPDATE clause
|
525
|
+
def merge
|
526
|
+
execute_ddl(merge_sql)
|
527
|
+
end
|
528
|
+
|
460
529
|
# Returns the minimum value for the given column/expression.
|
461
530
|
# Uses a virtual row block if no argument is given.
|
462
531
|
#
|
@@ -527,7 +596,7 @@ module Sequel
|
|
527
596
|
# # SELECT * FROM table ORDER BY id LIMIT 1000 OFFSET 1000
|
528
597
|
# # ...
|
529
598
|
#
|
530
|
-
# DB[:table].order(:id).paged_each(:
|
599
|
+
# DB[:table].order(:id).paged_each(rows_per_fetch: 100){|row| }
|
531
600
|
# # SELECT * FROM table ORDER BY id LIMIT 100
|
532
601
|
# # SELECT * FROM table ORDER BY id LIMIT 100 OFFSET 100
|
533
602
|
# # ...
|
@@ -546,7 +615,7 @@ module Sequel
|
|
546
615
|
unless @opts[:order]
|
547
616
|
raise Sequel::Error, "Dataset#paged_each requires the dataset be ordered"
|
548
617
|
end
|
549
|
-
unless
|
618
|
+
unless defined?(yield)
|
550
619
|
return enum_for(:paged_each, opts)
|
551
620
|
end
|
552
621
|
|
@@ -869,6 +938,19 @@ module Sequel
|
|
869
938
|
#
|
870
939
|
# DB[:table].update(x: Sequel[:x]+1, y: 0) # UPDATE table SET x = (x + 1), y = 0
|
871
940
|
# # => 10
|
941
|
+
#
|
942
|
+
# Some databases support using multiple tables in an UPDATE query. This requires
|
943
|
+
# multiple FROM tables (JOINs can also be used). As multiple FROM tables use
|
944
|
+
# an implicit CROSS JOIN, you should make sure your WHERE condition uses the
|
945
|
+
# appropriate filters for the FROM tables:
|
946
|
+
#
|
947
|
+
# DB.from(:a, :b).join(:c, :d=>Sequel[:b][:e]).where{{a[:f]=>b[:g], a[:id]=>10}}.
|
948
|
+
# update(:f=>Sequel[:c][:h])
|
949
|
+
# # UPDATE a
|
950
|
+
# # SET f = c.h
|
951
|
+
# # FROM b
|
952
|
+
# # INNER JOIN c ON (c.d = b.e)
|
953
|
+
# # WHERE ((a.f = b.g) AND (a.id = 10))
|
872
954
|
def update(values=OPTS, &block)
|
873
955
|
sql = update_sql(values)
|
874
956
|
if uses_returning?(:update)
|
@@ -974,18 +1056,19 @@ module Sequel
|
|
974
1056
|
|
975
1057
|
# Internals of #import. If primary key values are requested, use
|
976
1058
|
# separate insert commands for each row. Otherwise, call #multi_insert_sql
|
977
|
-
# and execute each statement it gives separately.
|
1059
|
+
# and execute each statement it gives separately. A transaction is only used
|
1060
|
+
# if there are multiple statements to execute.
|
978
1061
|
def _import(columns, values, opts)
|
979
1062
|
trans_opts = Hash[opts]
|
980
1063
|
trans_opts[:server] = @opts[:server]
|
981
1064
|
if opts[:return] == :primary_key
|
982
|
-
|
1065
|
+
_import_transaction(values, trans_opts){values.map{|v| insert(columns, v)}}
|
983
1066
|
else
|
984
1067
|
stmts = multi_insert_sql(columns, values)
|
985
|
-
|
1068
|
+
_import_transaction(stmts, trans_opts){stmts.each{|st| execute_dui(st)}}
|
986
1069
|
end
|
987
1070
|
end
|
988
|
-
|
1071
|
+
|
989
1072
|
# Return an array of arrays of values given by the symbols in ret_cols.
|
990
1073
|
def _select_map_multiple(ret_cols)
|
991
1074
|
map{|r| r.values_at(*ret_cols)}
|
@@ -1024,6 +1107,17 @@ module Sequel
|
|
1024
1107
|
end
|
1025
1108
|
end
|
1026
1109
|
|
1110
|
+
# Use a transaction when yielding to the block if multiple values/statements
|
1111
|
+
# are provided. When only a single value or statement is provided, then yield
|
1112
|
+
# without using a transaction.
|
1113
|
+
def _import_transaction(values, trans_opts, &block)
|
1114
|
+
if values.length > 1
|
1115
|
+
@db.transaction(trans_opts, &block)
|
1116
|
+
else
|
1117
|
+
yield
|
1118
|
+
end
|
1119
|
+
end
|
1120
|
+
|
1027
1121
|
# Internals of +select_hash+ and +select_hash_groups+
|
1028
1122
|
def _select_hash(meth, key_column, value_column, opts=OPTS)
|
1029
1123
|
select(*(key_column.is_a?(Array) ? key_column : [key_column]) + (value_column.is_a?(Array) ? value_column : [value_column])).
|
@@ -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
|
@@ -51,6 +51,11 @@ module Sequel
|
|
51
51
|
false
|
52
52
|
end
|
53
53
|
|
54
|
+
# Whether deleting from joined datasets is supported, false by default.
|
55
|
+
def supports_deleting_joins?
|
56
|
+
supports_modifying_joins?
|
57
|
+
end
|
58
|
+
|
54
59
|
# Whether the database supports derived column lists (e.g.
|
55
60
|
# "table_expr AS table_alias(column_alias1, column_alias2, ...)"), true by
|
56
61
|
# default.
|
@@ -120,6 +125,11 @@ module Sequel
|
|
120
125
|
false
|
121
126
|
end
|
122
127
|
|
128
|
+
# Whether the MERGE statement is supported, false by default.
|
129
|
+
def supports_merge?
|
130
|
+
false
|
131
|
+
end
|
132
|
+
|
123
133
|
# Whether modifying joined datasets is supported, false by default.
|
124
134
|
def supports_modifying_joins?
|
125
135
|
false
|
@@ -142,6 +152,11 @@ module Sequel
|
|
142
152
|
supports_distinct_on?
|
143
153
|
end
|
144
154
|
|
155
|
+
# Whether placeholder literalizers are supported, true by default.
|
156
|
+
def supports_placeholder_literalizer?
|
157
|
+
true
|
158
|
+
end
|
159
|
+
|
145
160
|
# Whether the dataset supports pattern matching by regular expressions, false by default.
|
146
161
|
def supports_regexp?
|
147
162
|
false
|
@@ -178,6 +193,11 @@ module Sequel
|
|
178
193
|
true
|
179
194
|
end
|
180
195
|
|
196
|
+
# Whether updating joined datasets is supported, false by default.
|
197
|
+
def supports_updating_joins?
|
198
|
+
supports_modifying_joins?
|
199
|
+
end
|
200
|
+
|
181
201
|
# Whether the dataset supports the WINDOW clause to define windows used by multiple
|
182
202
|
# window functions, false by default.
|
183
203
|
def supports_window_clause?
|
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
|
@@ -201,7 +201,9 @@ module Sequel
|
|
201
201
|
when :insert_pk
|
202
202
|
fetch_rows(prepared_sql){|r| return r.values.first}
|
203
203
|
when Array
|
204
|
+
# :nocov:
|
204
205
|
case prepared_type[0]
|
206
|
+
# :nocov:
|
205
207
|
when :map, :as_hash, :to_hash, :to_hash_groups
|
206
208
|
public_send(*prepared_type, &block)
|
207
209
|
end
|