sequel 3.21.0 → 3.29.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.
- data/CHANGELOG +413 -3
- data/README.rdoc +20 -6
- data/Rakefile +23 -16
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +210 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +86 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +115 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +15 -7
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +5 -31
- data/lib/sequel/adapters/jdbc/db2.rb +44 -0
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +26 -17
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +67 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +41 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +107 -38
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +78 -182
- data/lib/sequel/adapters/mysql2.rb +24 -23
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +349 -51
- data/lib/sequel/adapters/postgres.rb +169 -21
- data/lib/sequel/adapters/shared/access.rb +21 -6
- data/lib/sequel/adapters/shared/db2.rb +288 -0
- data/lib/sequel/adapters/shared/firebird.rb +214 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +108 -65
- data/lib/sequel/adapters/shared/mysql.rb +56 -13
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -34
- data/lib/sequel/adapters/shared/postgres.rb +107 -58
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +168 -41
- data/lib/sequel/adapters/sqlite.rb +27 -18
- data/lib/sequel/adapters/swift/mysql.rb +9 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +152 -17
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +63 -0
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +46 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +100 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +8 -5
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +194 -57
- data/lib/sequel/dataset/features.rb +81 -8
- data/lib/sequel/dataset/graph.rb +8 -7
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +32 -15
- data/lib/sequel/dataset/query.rb +223 -42
- data/lib/sequel/dataset/sql.rb +58 -61
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +997 -331
- data/lib/sequel/model/base.rb +386 -129
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +65 -7
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +12 -25
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +107 -51
- data/lib/sequel/timezones.rb +44 -35
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +65 -29
- data/spec/adapters/mysql_spec.rb +122 -123
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +213 -61
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +729 -508
- data/spec/core/dataset_spec.rb +980 -1044
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/association_pks_spec.rb +38 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/identity_map_spec.rb +162 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/many_through_many_spec.rb +195 -20
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +4 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +522 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +375 -62
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +200 -120
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +174 -7
- data/spec/model/associations_spec.rb +849 -661
- data/spec/model/base_spec.rb +255 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +640 -676
- data/spec/model/hooks_spec.rb +309 -67
- data/spec/model/model_spec.rb +207 -167
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +321 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +95 -38
|
@@ -241,16 +241,6 @@ module Sequel
|
|
|
241
241
|
self << drop_language_sql(name, opts)
|
|
242
242
|
end
|
|
243
243
|
|
|
244
|
-
# Remove the cached entries for primary keys and sequences when dropping a table.
|
|
245
|
-
def drop_table(*names)
|
|
246
|
-
names.each do |name|
|
|
247
|
-
name = quote_schema_table(name)
|
|
248
|
-
@primary_keys.delete(name)
|
|
249
|
-
@primary_key_sequences.delete(name)
|
|
250
|
-
end
|
|
251
|
-
super
|
|
252
|
-
end
|
|
253
|
-
|
|
254
244
|
# Drops a trigger from the database. Arguments:
|
|
255
245
|
# * table : table from which to drop the trigger
|
|
256
246
|
# * name : name of the trigger to drop
|
|
@@ -294,6 +284,16 @@ module Sequel
|
|
|
294
284
|
dataset.from(:pg_class).join(:pg_locks, :relation=>:relfilenode).select(:pg_class__relname, Sequel::SQL::ColumnAll.new(:pg_locks))
|
|
295
285
|
end
|
|
296
286
|
|
|
287
|
+
# Notifies the given channel. See the PostgreSQL NOTIFY documentation. Options:
|
|
288
|
+
#
|
|
289
|
+
# :payload :: The payload string to use for the NOTIFY statement. Only supported
|
|
290
|
+
# in PostgreSQL 9.0+.
|
|
291
|
+
# :server :: The server to which to send the NOTIFY statement, if the sharding support
|
|
292
|
+
# is being used.
|
|
293
|
+
def notify(channel, opts={})
|
|
294
|
+
execute_ddl("NOTIFY #{channel}#{", #{literal(opts[:payload].to_s)}" if opts[:payload]}", opts)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
297
|
# Return primary key for the given table.
|
|
298
298
|
def primary_key(table, opts={})
|
|
299
299
|
quoted_table = quote_schema_table(table)
|
|
@@ -358,6 +358,11 @@ module Sequel
|
|
|
358
358
|
@supports_prepared_transactions = self['SHOW max_prepared_transactions'].get.to_i > 0
|
|
359
359
|
end
|
|
360
360
|
|
|
361
|
+
# PostgreSQL supports CREATE TABLE IF NOT EXISTS on 9.1+
|
|
362
|
+
def supports_create_table_if_not_exists?
|
|
363
|
+
server_version >= 90100
|
|
364
|
+
end
|
|
365
|
+
|
|
361
366
|
# PostgreSQL supports savepoints
|
|
362
367
|
def supports_savepoints?
|
|
363
368
|
true
|
|
@@ -368,30 +373,24 @@ module Sequel
|
|
|
368
373
|
true
|
|
369
374
|
end
|
|
370
375
|
|
|
371
|
-
#
|
|
376
|
+
# Array of symbols specifying table names in the current database.
|
|
377
|
+
# The dataset used is yielded to the block if one is provided,
|
|
378
|
+
# otherwise, an array of symbols of table names is returned.
|
|
372
379
|
#
|
|
373
380
|
# Options:
|
|
374
381
|
# * :schema - The schema to search (default_schema by default)
|
|
375
382
|
# * :server - The server to use
|
|
376
|
-
def
|
|
377
|
-
|
|
378
|
-
schema, table = schema_and_table(table)
|
|
379
|
-
opts[:schema] ||= schema
|
|
380
|
-
tables(opts){|ds| !ds.first(:relname=>im.call(table)).nil?}
|
|
383
|
+
def tables(opts={}, &block)
|
|
384
|
+
pg_class_relname('r', opts, &block)
|
|
381
385
|
end
|
|
382
|
-
|
|
383
|
-
# Array of symbols specifying
|
|
384
|
-
# The dataset used is yielded to the block if one is provided,
|
|
385
|
-
# otherwise, an array of symbols of table names is returned.
|
|
386
|
+
|
|
387
|
+
# Array of symbols specifying view names in the current database.
|
|
386
388
|
#
|
|
387
389
|
# Options:
|
|
388
390
|
# * :schema - The schema to search (default_schema by default)
|
|
389
391
|
# * :server - The server to use
|
|
390
|
-
def
|
|
391
|
-
|
|
392
|
-
ds = filter_schema(ds, opts)
|
|
393
|
-
m = output_identifier_meth
|
|
394
|
-
block_given? ? yield(ds) : ds.map{|r| m.call(r[:relname])}
|
|
392
|
+
def views(opts={})
|
|
393
|
+
pg_class_relname('v', opts)
|
|
395
394
|
end
|
|
396
395
|
|
|
397
396
|
private
|
|
@@ -399,8 +398,8 @@ module Sequel
|
|
|
399
398
|
# If the :prepare option is given and we aren't in a savepoint,
|
|
400
399
|
# prepare the transaction for a two-phase commit.
|
|
401
400
|
def commit_transaction(conn, opts={})
|
|
402
|
-
if opts[:prepare] &&
|
|
403
|
-
log_connection_execute(conn, "PREPARE TRANSACTION #{literal(
|
|
401
|
+
if (s = opts[:prepare]) && @transactions[conn][:savepoint_level] <= 1
|
|
402
|
+
log_connection_execute(conn, "PREPARE TRANSACTION #{literal(s)}")
|
|
404
403
|
else
|
|
405
404
|
super
|
|
406
405
|
end
|
|
@@ -454,11 +453,6 @@ module Sequel
|
|
|
454
453
|
"DROP LANGUAGE#{' IF EXISTS' if opts[:if_exists]} #{name}#{' CASCADE' if opts[:cascade]}"
|
|
455
454
|
end
|
|
456
455
|
|
|
457
|
-
# Always CASCADE the table drop
|
|
458
|
-
def drop_table_sql(name)
|
|
459
|
-
"DROP TABLE #{quote_schema_table(name)} CASCADE"
|
|
460
|
-
end
|
|
461
|
-
|
|
462
456
|
# SQL for dropping a trigger from the database.
|
|
463
457
|
def drop_trigger_sql(table, name, opts={})
|
|
464
458
|
"DROP TRIGGER#{' IF EXISTS' if opts[:if_exists]} #{name} ON #{quote_schema_table(table)}#{' CASCADE' if opts[:cascade]}"
|
|
@@ -540,12 +534,29 @@ module Sequel
|
|
|
540
534
|
conn.execute(sql)
|
|
541
535
|
end
|
|
542
536
|
|
|
537
|
+
# Backbone of the tables and views support.
|
|
538
|
+
def pg_class_relname(type, opts)
|
|
539
|
+
ds = metadata_dataset.from(:pg_class).filter(:relkind=>type).select(:relname).exclude(SQL::StringExpression.like(:relname, SYSTEM_TABLE_REGEXP)).server(opts[:server]).join(:pg_namespace, :oid=>:relnamespace)
|
|
540
|
+
ds = filter_schema(ds, opts)
|
|
541
|
+
m = output_identifier_meth
|
|
542
|
+
block_given? ? yield(ds) : ds.map{|r| m.call(r[:relname])}
|
|
543
|
+
end
|
|
544
|
+
|
|
543
545
|
# Use a dollar sign instead of question mark for the argument
|
|
544
546
|
# placeholder.
|
|
545
547
|
def prepared_arg_placeholder
|
|
546
548
|
PREPARED_ARG_PLACEHOLDER
|
|
547
549
|
end
|
|
548
550
|
|
|
551
|
+
# Remove the cached entries for primary keys and sequences when a table is
|
|
552
|
+
# changed.
|
|
553
|
+
def remove_cached_schema(table)
|
|
554
|
+
tab = quote_schema_table(table)
|
|
555
|
+
@primary_keys.delete(tab)
|
|
556
|
+
@primary_key_sequences.delete(tab)
|
|
557
|
+
super
|
|
558
|
+
end
|
|
559
|
+
|
|
549
560
|
# SQL DDL statement for renaming a table. PostgreSQL doesn't allow you to change a table's schema in
|
|
550
561
|
# a rename table operation, so speciying a new schema in new_name will not have an effect.
|
|
551
562
|
def rename_table_sql(name, new_name)
|
|
@@ -560,8 +571,8 @@ module Sequel
|
|
|
560
571
|
|
|
561
572
|
# The dataset used for parsing table schemas, using the pg_* system catalogs.
|
|
562
573
|
def schema_parse_table(table_name, opts)
|
|
563
|
-
m = output_identifier_meth
|
|
564
|
-
m2 = input_identifier_meth
|
|
574
|
+
m = output_identifier_meth(opts[:dataset])
|
|
575
|
+
m2 = input_identifier_meth(opts[:dataset])
|
|
565
576
|
ds = metadata_dataset.select(:pg_attribute__attname___name,
|
|
566
577
|
SQL::Function.new(:format_type, :pg_type__oid, :pg_attribute__atttypmod).as(:db_type),
|
|
567
578
|
SQL::Function.new(:pg_get_expr, :pg_attrdef__adbin, :pg_class__oid).as(:default),
|
|
@@ -628,10 +639,14 @@ module Sequel
|
|
|
628
639
|
BOOL_TRUE = 'true'.freeze
|
|
629
640
|
COMMA_SEPARATOR = ', '.freeze
|
|
630
641
|
DELETE_CLAUSE_METHODS = Dataset.clause_methods(:delete, %w'from using where')
|
|
642
|
+
DELETE_CLAUSE_METHODS_91 = Dataset.clause_methods(:delete, %w'with from using where returning')
|
|
631
643
|
EXCLUSIVE = 'EXCLUSIVE'.freeze
|
|
632
644
|
EXPLAIN = 'EXPLAIN '.freeze
|
|
633
645
|
EXPLAIN_ANALYZE = 'EXPLAIN ANALYZE '.freeze
|
|
634
646
|
FOR_SHARE = ' FOR SHARE'.freeze
|
|
647
|
+
INSERT_CLAUSE_METHODS = Dataset.clause_methods(:insert, %w'into columns values')
|
|
648
|
+
INSERT_CLAUSE_METHODS_82 = Dataset.clause_methods(:insert, %w'into columns values returning')
|
|
649
|
+
INSERT_CLAUSE_METHODS_91 = Dataset.clause_methods(:insert, %w'with into columns values returning')
|
|
635
650
|
LOCK = 'LOCK TABLE %s IN %s MODE'.freeze
|
|
636
651
|
NULL = LiteralString.new('NULL').freeze
|
|
637
652
|
PG_TIMESTAMP_FORMAT = "TIMESTAMP '%Y-%m-%d %H:%M:%S".freeze
|
|
@@ -645,17 +660,23 @@ module Sequel
|
|
|
645
660
|
SHARE_UPDATE_EXCLUSIVE = 'SHARE UPDATE EXCLUSIVE'.freeze
|
|
646
661
|
SQL_WITH_RECURSIVE = "WITH RECURSIVE ".freeze
|
|
647
662
|
UPDATE_CLAUSE_METHODS = Dataset.clause_methods(:update, %w'table set from where')
|
|
663
|
+
UPDATE_CLAUSE_METHODS_91 = Dataset.clause_methods(:update, %w'with table set from where returning')
|
|
648
664
|
|
|
649
665
|
# Shared methods for prepared statements when used with PostgreSQL databases.
|
|
650
666
|
module PreparedStatementMethods
|
|
651
667
|
# Override insert action to use RETURNING if the server supports it.
|
|
668
|
+
def run(&block)
|
|
669
|
+
if @prepared_type == :insert && supports_insert_select?
|
|
670
|
+
fetch_rows(prepared_sql){|r| return r.values.first}
|
|
671
|
+
else
|
|
672
|
+
super
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
652
676
|
def prepared_sql
|
|
653
677
|
return @prepared_sql if @prepared_sql
|
|
678
|
+
@opts[:returning] = insert_pk if @prepared_type == :insert && supports_insert_select?
|
|
654
679
|
super
|
|
655
|
-
if @prepared_type == :insert and !@opts[:disable_insert_returning] and server_version >= 80200
|
|
656
|
-
@prepared_sql = insert_returning_pk_sql(*@prepared_modify_values)
|
|
657
|
-
meta_def(:insert_returning_pk_sql){|*args| prepared_sql}
|
|
658
|
-
end
|
|
659
680
|
@prepared_sql
|
|
660
681
|
end
|
|
661
682
|
end
|
|
@@ -680,7 +701,7 @@ module Sequel
|
|
|
680
701
|
def complex_expression_sql(op, args)
|
|
681
702
|
case op
|
|
682
703
|
when :^
|
|
683
|
-
"(#{
|
|
704
|
+
"(#{args.collect{|a| literal(a)}.join(" # ")})"
|
|
684
705
|
else
|
|
685
706
|
super
|
|
686
707
|
end
|
|
@@ -709,25 +730,22 @@ module Sequel
|
|
|
709
730
|
end
|
|
710
731
|
|
|
711
732
|
# Insert given values into the database.
|
|
712
|
-
def insert(*values)
|
|
713
|
-
if @opts[:
|
|
714
|
-
|
|
715
|
-
elsif
|
|
716
|
-
|
|
733
|
+
def insert(*values, &block)
|
|
734
|
+
if @opts[:returning]
|
|
735
|
+
super
|
|
736
|
+
elsif !@opts[:sql] && supports_insert_select?
|
|
737
|
+
returning(insert_pk).insert(*values){|r| return r.values.first}
|
|
738
|
+
elsif (f = opts[:from]) && !f.empty?
|
|
739
|
+
execute_insert(insert_sql(*values), :table=>f.first, :values=>values.size == 1 ? values.first : values)
|
|
717
740
|
else
|
|
718
|
-
|
|
741
|
+
super
|
|
719
742
|
end
|
|
720
743
|
end
|
|
721
744
|
|
|
722
|
-
# Use the RETURNING clause to return the columns listed in returning.
|
|
723
|
-
def insert_returning_sql(returning, *values)
|
|
724
|
-
"#{insert_sql(*values)} RETURNING #{column_list(Array(returning))}"
|
|
725
|
-
end
|
|
726
|
-
|
|
727
745
|
# Insert a record returning the record inserted
|
|
728
746
|
def insert_select(*values)
|
|
729
|
-
return
|
|
730
|
-
|
|
747
|
+
return unless supports_insert_select?
|
|
748
|
+
returning.insert(*values){|r| return r}
|
|
731
749
|
end
|
|
732
750
|
|
|
733
751
|
# Locks all tables in the dataset's FROM clause (but not in JOINs) with
|
|
@@ -752,6 +770,12 @@ module Sequel
|
|
|
752
770
|
[insert_sql(columns, LiteralString.new('VALUES ' + values.map {|r| literal(Array(r))}.join(COMMA_SEPARATOR)))]
|
|
753
771
|
end
|
|
754
772
|
|
|
773
|
+
# PostgreSQL supports using the WITH clause in subqueries if it
|
|
774
|
+
# supports using WITH at all (i.e. on PostgreSQL 8.4+).
|
|
775
|
+
def supports_cte_in_subqueries?
|
|
776
|
+
supports_cte?
|
|
777
|
+
end
|
|
778
|
+
|
|
755
779
|
# DISTINCT ON is a PostgreSQL extension
|
|
756
780
|
def supports_distinct_on?
|
|
757
781
|
true
|
|
@@ -762,6 +786,14 @@ module Sequel
|
|
|
762
786
|
true
|
|
763
787
|
end
|
|
764
788
|
|
|
789
|
+
def supports_returning?(type)
|
|
790
|
+
if type == :insert
|
|
791
|
+
server_version >= 80200 && !opts[:disable_insert_returning]
|
|
792
|
+
else
|
|
793
|
+
server_version >= 90100
|
|
794
|
+
end
|
|
795
|
+
end
|
|
796
|
+
|
|
765
797
|
# PostgreSQL supports timezones in literal timestamps
|
|
766
798
|
def supports_timestamp_timezones?
|
|
767
799
|
true
|
|
@@ -781,7 +813,7 @@ module Sequel
|
|
|
781
813
|
|
|
782
814
|
# PostgreSQL allows deleting from joined datasets
|
|
783
815
|
def delete_clause_methods
|
|
784
|
-
DELETE_CLAUSE_METHODS
|
|
816
|
+
server_version >= 90100 ? DELETE_CLAUSE_METHODS_91 : DELETE_CLAUSE_METHODS
|
|
785
817
|
end
|
|
786
818
|
|
|
787
819
|
# Only include the primary table in the main delete clause
|
|
@@ -794,12 +826,23 @@ module Sequel
|
|
|
794
826
|
join_from_sql(:USING, sql)
|
|
795
827
|
end
|
|
796
828
|
|
|
797
|
-
#
|
|
798
|
-
def
|
|
829
|
+
# PostgreSQL allows a RETURNING clause.
|
|
830
|
+
def insert_clause_methods
|
|
831
|
+
if server_version >= 90100
|
|
832
|
+
INSERT_CLAUSE_METHODS_91
|
|
833
|
+
elsif server_version >= 80200
|
|
834
|
+
INSERT_CLAUSE_METHODS_82
|
|
835
|
+
else
|
|
836
|
+
INSERT_CLAUSE_METHODS
|
|
837
|
+
end
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
# Return the primary key to use for RETURNING in an INSERT statement
|
|
841
|
+
def insert_pk
|
|
799
842
|
pk = db.primary_key(opts[:from].first) if opts[:from] && !opts[:from].empty?
|
|
800
|
-
|
|
843
|
+
pk ? Sequel::SQL::Identifier.new(pk) : NULL
|
|
801
844
|
end
|
|
802
|
-
|
|
845
|
+
|
|
803
846
|
# For multiple table support, PostgreSQL requires at least
|
|
804
847
|
# two from tables, with joins allowed.
|
|
805
848
|
def join_from_sql(type, sql)
|
|
@@ -836,6 +879,12 @@ module Sequel
|
|
|
836
879
|
server_version >= 80400 ? SELECT_CLAUSE_METHODS_84 : SELECT_CLAUSE_METHODS
|
|
837
880
|
end
|
|
838
881
|
|
|
882
|
+
# PostgreSQL requires parentheses around compound datasets if they use
|
|
883
|
+
# CTEs, and using them in other places doesn't hurt.
|
|
884
|
+
def compound_dataset_sql(ds)
|
|
885
|
+
"(#{super})"
|
|
886
|
+
end
|
|
887
|
+
|
|
839
888
|
# Support FOR SHARE locking when using the :share lock style.
|
|
840
889
|
def select_lock_sql(sql)
|
|
841
890
|
@opts[:lock] == :share ? (sql << FOR_SHARE) : super
|
|
@@ -866,7 +915,7 @@ module Sequel
|
|
|
866
915
|
|
|
867
916
|
# PostgreSQL splits the main table from the joined tables
|
|
868
917
|
def update_clause_methods
|
|
869
|
-
UPDATE_CLAUSE_METHODS
|
|
918
|
+
server_version >= 90100 ? UPDATE_CLAUSE_METHODS_91 : UPDATE_CLAUSE_METHODS
|
|
870
919
|
end
|
|
871
920
|
|
|
872
921
|
# Use FROM to specify additional tables in an update query
|