sequel 3.46.0 → 3.47.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 +96 -0
- data/Rakefile +7 -1
- data/bin/sequel +6 -4
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +14 -35
- data/doc/association_basics.rdoc +66 -4
- data/doc/migration.rdoc +4 -0
- data/doc/opening_databases.rdoc +6 -0
- data/doc/postgresql.rdoc +302 -0
- data/doc/release_notes/3.47.0.txt +270 -0
- data/doc/security.rdoc +6 -0
- data/lib/sequel/adapters/ibmdb.rb +9 -9
- data/lib/sequel/adapters/jdbc.rb +22 -7
- data/lib/sequel/adapters/jdbc/postgresql.rb +7 -2
- data/lib/sequel/adapters/mock.rb +2 -0
- data/lib/sequel/adapters/postgres.rb +44 -13
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +94 -55
- data/lib/sequel/adapters/shared/sqlite.rb +3 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/adapters/utils/pg_types.rb +1 -14
- data/lib/sequel/adapters/utils/split_alter_table.rb +3 -3
- data/lib/sequel/connection_pool/threaded.rb +1 -1
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +2 -2
- data/lib/sequel/database/features.rb +5 -0
- data/lib/sequel/database/misc.rb +47 -5
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/dataset/actions.rb +4 -2
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +8 -6
- data/lib/sequel/dataset/sql.rb +8 -6
- data/lib/sequel/extensions/constraint_validations.rb +5 -2
- data/lib/sequel/extensions/migration.rb +10 -8
- data/lib/sequel/extensions/pagination.rb +3 -0
- data/lib/sequel/extensions/pg_array.rb +85 -25
- data/lib/sequel/extensions/pg_hstore.rb +8 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +4 -1
- data/lib/sequel/extensions/pg_inet.rb +16 -13
- data/lib/sequel/extensions/pg_interval.rb +6 -2
- data/lib/sequel/extensions/pg_json.rb +18 -11
- data/lib/sequel/extensions/pg_range.rb +17 -2
- data/lib/sequel/extensions/pg_range_ops.rb +7 -5
- data/lib/sequel/extensions/pg_row.rb +29 -12
- data/lib/sequel/extensions/pretty_table.rb +3 -0
- data/lib/sequel/extensions/query.rb +3 -0
- data/lib/sequel/extensions/schema_caching.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +3 -1
- data/lib/sequel/extensions/select_remove.rb +3 -0
- data/lib/sequel/model.rb +8 -2
- data/lib/sequel/model/associations.rb +39 -27
- data/lib/sequel/model/base.rb +99 -38
- data/lib/sequel/model/plugins.rb +25 -0
- data/lib/sequel/plugins/association_autoreloading.rb +27 -22
- data/lib/sequel/plugins/association_dependencies.rb +1 -7
- data/lib/sequel/plugins/auto_validations.rb +110 -0
- data/lib/sequel/plugins/boolean_readers.rb +1 -6
- data/lib/sequel/plugins/caching.rb +6 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +14 -7
- data/lib/sequel/plugins/constraint_validations.rb +2 -13
- data/lib/sequel/plugins/defaults_setter.rb +1 -6
- data/lib/sequel/plugins/dirty.rb +8 -0
- data/lib/sequel/plugins/error_splitter.rb +54 -0
- data/lib/sequel/plugins/force_encoding.rb +1 -5
- data/lib/sequel/plugins/hook_class_methods.rb +1 -6
- data/lib/sequel/plugins/input_transformer.rb +79 -0
- data/lib/sequel/plugins/instance_filters.rb +7 -1
- data/lib/sequel/plugins/instance_hooks.rb +7 -1
- data/lib/sequel/plugins/json_serializer.rb +5 -10
- data/lib/sequel/plugins/lazy_attributes.rb +20 -7
- data/lib/sequel/plugins/list.rb +1 -6
- data/lib/sequel/plugins/many_through_many.rb +1 -2
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +23 -39
- data/lib/sequel/plugins/optimistic_locking.rb +1 -5
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -7
- data/lib/sequel/plugins/prepared_statements.rb +1 -5
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -11
- data/lib/sequel/plugins/rcte_tree.rb +2 -2
- data/lib/sequel/plugins/serialization.rb +11 -13
- data/lib/sequel/plugins/serialization_modification_detection.rb +13 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/static_cache.rb +67 -19
- data/lib/sequel/plugins/string_stripper.rb +7 -27
- data/lib/sequel/plugins/subclasses.rb +3 -5
- data/lib/sequel/plugins/tactical_eager_loading.rb +2 -2
- data/lib/sequel/plugins/timestamps.rb +2 -7
- data/lib/sequel/plugins/touch.rb +5 -8
- data/lib/sequel/plugins/tree.rb +1 -6
- data/lib/sequel/plugins/typecast_on_load.rb +1 -5
- data/lib/sequel/plugins/update_primary_key.rb +26 -14
- data/lib/sequel/plugins/validation_class_methods.rb +31 -16
- data/lib/sequel/plugins/validation_helpers.rb +50 -26
- data/lib/sequel/plugins/xml_serializer.rb +3 -6
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +131 -15
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/core/connection_pool_spec.rb +16 -17
- data/spec/core/database_spec.rb +111 -40
- data/spec/core/dataset_spec.rb +65 -74
- data/spec/core/expression_filters_spec.rb +6 -5
- data/spec/core/object_graph_spec.rb +0 -1
- data/spec/core/schema_spec.rb +23 -23
- data/spec/core/spec_helper.rb +5 -1
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_validations_spec.rb +90 -0
- data/spec/extensions/caching_spec.rb +6 -0
- data/spec/extensions/class_table_inheritance_spec.rb +8 -1
- data/spec/extensions/composition_spec.rb +12 -5
- data/spec/extensions/constraint_validations_spec.rb +4 -4
- data/spec/extensions/core_refinements_spec.rb +29 -79
- data/spec/extensions/dirty_spec.rb +14 -0
- data/spec/extensions/error_splitter_spec.rb +18 -0
- data/spec/extensions/identity_map_spec.rb +0 -1
- data/spec/extensions/input_transformer_spec.rb +54 -0
- data/spec/extensions/instance_filters_spec.rb +6 -0
- data/spec/extensions/instance_hooks_spec.rb +12 -1
- data/spec/extensions/json_serializer_spec.rb +0 -1
- data/spec/extensions/lazy_attributes_spec.rb +64 -55
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +3 -4
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +53 -15
- data/spec/extensions/migration_spec.rb +16 -0
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +48 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +10 -2
- data/spec/extensions/pg_hstore_spec.rb +5 -0
- data/spec/extensions/pg_inet_spec.rb +5 -0
- data/spec/extensions/pg_interval_spec.rb +7 -3
- data/spec/extensions/pg_json_spec.rb +6 -1
- data/spec/extensions/pg_range_ops_spec.rb +4 -1
- data/spec/extensions/pg_range_spec.rb +5 -0
- data/spec/extensions/pg_row_plugin_spec.rb +13 -0
- data/spec/extensions/pg_row_spec.rb +28 -19
- data/spec/extensions/pg_typecast_on_load_spec.rb +6 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/rcte_tree_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/serialization_modification_detection_spec.rb +8 -0
- data/spec/extensions/serialization_spec.rb +15 -1
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +59 -9
- data/spec/extensions/tactical_eager_loading_spec.rb +19 -4
- data/spec/extensions/update_primary_key_spec.rb +17 -1
- data/spec/extensions/validation_class_methods_spec.rb +25 -0
- data/spec/extensions/validation_helpers_spec.rb +59 -3
- data/spec/integration/associations_test.rb +5 -5
- data/spec/integration/eager_loader_test.rb +32 -63
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/plugin_test.rb +88 -56
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +1 -1
- data/spec/integration/timezone_test.rb +0 -1
- data/spec/integration/transaction_test.rb +0 -1
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +106 -84
- data/spec/model/base_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +27 -9
- data/spec/model/plugins_spec.rb +71 -0
- data/spec/model/record_spec.rb +99 -13
- metadata +12 -2
data/lib/sequel/adapters/mock.rb
CHANGED
|
@@ -96,6 +96,15 @@ module Sequel
|
|
|
96
96
|
def bytea(s) ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s)) end
|
|
97
97
|
end.new.method(:bytea)
|
|
98
98
|
|
|
99
|
+
@use_iso_date_format = true
|
|
100
|
+
|
|
101
|
+
class << self
|
|
102
|
+
# As an optimization, Sequel sets the date style to ISO, so that PostgreSQL provides
|
|
103
|
+
# the date in a known format that Sequel can parse faster. This can be turned off
|
|
104
|
+
# if you require a date style other than ISO.
|
|
105
|
+
attr_accessor :use_iso_date_format
|
|
106
|
+
end
|
|
107
|
+
|
|
99
108
|
# PGconn subclass for connection specific methods used with the
|
|
100
109
|
# pg, postgres, or postgres-pr driver.
|
|
101
110
|
class Adapter < ::PGconn
|
|
@@ -160,18 +169,20 @@ module Sequel
|
|
|
160
169
|
|
|
161
170
|
set_adapter_scheme :postgres
|
|
162
171
|
|
|
163
|
-
# Whether infinite timestamps should be converted on retrieval. By default, no
|
|
172
|
+
# Whether infinite timestamps/dates should be converted on retrieval. By default, no
|
|
164
173
|
# conversion is done, so an error is raised if you attempt to retrieve an infinite
|
|
165
|
-
# timestamp. You can set this to :nil to convert to nil, :string to leave
|
|
174
|
+
# timestamp/date. You can set this to :nil to convert to nil, :string to leave
|
|
166
175
|
# as a string, or :float to convert to an infinite float.
|
|
167
176
|
attr_reader :convert_infinite_timestamps
|
|
168
|
-
|
|
177
|
+
|
|
169
178
|
# Add the primary_keys and primary_key_sequences instance variables,
|
|
170
179
|
# so we can get the correct return values for inserted rows.
|
|
171
180
|
def initialize(*args)
|
|
172
181
|
super
|
|
173
|
-
@
|
|
182
|
+
@use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, Postgres.use_iso_date_format))
|
|
174
183
|
initialize_postgres_adapter
|
|
184
|
+
conversion_procs[1082] = TYPE_TRANSLATOR.method(:date) if @use_iso_date_format
|
|
185
|
+
self.convert_infinite_timestamps = @opts[:convert_infinite_timestamps]
|
|
175
186
|
end
|
|
176
187
|
|
|
177
188
|
# Convert given argument so that it can be used directly by pg. Currently, pg doesn't
|
|
@@ -233,16 +244,32 @@ module Sequel
|
|
|
233
244
|
conn
|
|
234
245
|
end
|
|
235
246
|
|
|
247
|
+
# Set whether to allow infinite timestamps/dates. Make sure the
|
|
248
|
+
# conversion proc for date reflects that setting.
|
|
236
249
|
def convert_infinite_timestamps=(v)
|
|
237
|
-
@convert_infinite_timestamps = v
|
|
238
|
-
|
|
250
|
+
@convert_infinite_timestamps = case v
|
|
251
|
+
when Symbol
|
|
252
|
+
v
|
|
253
|
+
when 'nil'
|
|
254
|
+
:nil
|
|
255
|
+
when 'string'
|
|
256
|
+
:string
|
|
257
|
+
when 'float'
|
|
258
|
+
:float
|
|
259
|
+
when String
|
|
260
|
+
typecast_value_boolean(v)
|
|
261
|
+
else
|
|
262
|
+
false
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
pr = old_pr = @use_iso_date_format ? TYPE_TRANSLATOR.method(:date) : Sequel.method(:string_to_date)
|
|
239
266
|
if v
|
|
240
|
-
pr = lambda do |
|
|
241
|
-
case
|
|
267
|
+
pr = lambda do |val|
|
|
268
|
+
case val
|
|
242
269
|
when *INFINITE_TIMESTAMP_STRINGS
|
|
243
|
-
infinite_timestamp_value(
|
|
270
|
+
infinite_timestamp_value(val)
|
|
244
271
|
else
|
|
245
|
-
old_pr.call(
|
|
272
|
+
old_pr.call(val)
|
|
246
273
|
end
|
|
247
274
|
end
|
|
248
275
|
end
|
|
@@ -345,7 +372,7 @@ module Sequel
|
|
|
345
372
|
conn.put_copy_data(buf)
|
|
346
373
|
end
|
|
347
374
|
else
|
|
348
|
-
data.each{|
|
|
375
|
+
data.each{|buff| conn.put_copy_data(buff)}
|
|
349
376
|
end
|
|
350
377
|
rescue Exception => e
|
|
351
378
|
conn.put_copy_end("ruby exception occurred while copying data into PostgreSQL")
|
|
@@ -385,7 +412,11 @@ module Sequel
|
|
|
385
412
|
synchronize(opts[:server]) do |conn|
|
|
386
413
|
begin
|
|
387
414
|
channels = Array(channels)
|
|
388
|
-
channels.each
|
|
415
|
+
channels.each do |channel|
|
|
416
|
+
sql = "LISTEN "
|
|
417
|
+
dataset.send(:identifier_append, sql, channel)
|
|
418
|
+
conn.execute(sql)
|
|
419
|
+
end
|
|
389
420
|
opts[:after_listen].call(conn) if opts[:after_listen]
|
|
390
421
|
timeout = opts[:timeout] ? [opts[:timeout]] : []
|
|
391
422
|
if l = opts[:loop]
|
|
@@ -452,7 +483,7 @@ module Sequel
|
|
|
452
483
|
# Set the DateStyle to ISO if configured, for faster date parsing.
|
|
453
484
|
def connection_configuration_sqls
|
|
454
485
|
sqls = super
|
|
455
|
-
sqls << "SET DateStyle = 'ISO'" if
|
|
486
|
+
sqls << "SET DateStyle = 'ISO'" if @use_iso_date_format
|
|
456
487
|
sqls
|
|
457
488
|
end
|
|
458
489
|
|
|
@@ -203,7 +203,7 @@ module Sequel
|
|
|
203
203
|
opts.delete(:auto_increment) if op[:auto_increment] == false
|
|
204
204
|
"CHANGE COLUMN #{quote_identifier(op[:name])} #{column_definition_sql(opts)}"
|
|
205
205
|
when :drop_constraint
|
|
206
|
-
|
|
206
|
+
case op[:type]
|
|
207
207
|
when :primary_key
|
|
208
208
|
"DROP PRIMARY KEY"
|
|
209
209
|
when :foreign_key
|
|
@@ -881,7 +881,7 @@ module Sequel
|
|
|
881
881
|
def limit_sql(sql)
|
|
882
882
|
if l = @opts[:limit]
|
|
883
883
|
sql << LIMIT
|
|
884
|
-
literal_append(sql,
|
|
884
|
+
literal_append(sql, l)
|
|
885
885
|
end
|
|
886
886
|
end
|
|
887
887
|
alias delete_limit_sql limit_sql
|
|
@@ -11,25 +11,17 @@ module Sequel
|
|
|
11
11
|
# a per instance basis via the :client_min_messages option.
|
|
12
12
|
# force_standard_strings :: Set to false to not force the use of standard strings. Overridable
|
|
13
13
|
# on a per instance basis via the :force_standard_strings option.
|
|
14
|
-
# use_iso_date_format :: (only available when using the native adapter)
|
|
15
|
-
# Set to false to not change the date format to
|
|
16
|
-
# ISO. This disables one of Sequel's optimizations.
|
|
17
14
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# after the Database object is instantiated and before a connection
|
|
21
|
-
# is actually made. For example, to use whatever the server defaults are:
|
|
15
|
+
# It is not recommened you use these module-level accessors. Instead,
|
|
16
|
+
# use the database option to make the setting per-Database.
|
|
22
17
|
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# Sequel::Postgres.force_standard_strings = false
|
|
26
|
-
# Sequel::Postgres.use_iso_date_format = false
|
|
27
|
-
# # A connection to the server is not made until here
|
|
28
|
-
# DB[:t].all
|
|
18
|
+
# All adapters that connect to PostgreSQL support the following option in
|
|
19
|
+
# addition to those mentioned above:
|
|
29
20
|
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
21
|
+
# :search_path :: Set the schema search_path for this Database's connections.
|
|
22
|
+
# Allows to to set which schemas do not need explicit
|
|
23
|
+
# qualification, and in which order to check the schemas when
|
|
24
|
+
# an unqualified object is referenced.
|
|
33
25
|
module Postgres
|
|
34
26
|
# Array of exceptions that need to be converted. JDBC
|
|
35
27
|
# uses NativeExceptions, the native adapter uses PGError.
|
|
@@ -155,9 +147,6 @@ module Sequel
|
|
|
155
147
|
end_sql
|
|
156
148
|
).strip.gsub(/\s+/, ' ').freeze
|
|
157
149
|
|
|
158
|
-
# The Sequel extensions that require reseting of the conversion procs.
|
|
159
|
-
RESET_PROCS_EXTENSIONS = [:pg_array, :pg_hstore, :pg_inet, :pg_interval, :pg_json, :pg_range].freeze
|
|
160
|
-
|
|
161
150
|
# A hash of conversion procs, keyed by type integer (oid) and
|
|
162
151
|
# having callable values for the conversion proc for that type.
|
|
163
152
|
attr_reader :conversion_procs
|
|
@@ -276,17 +265,6 @@ module Sequel
|
|
|
276
265
|
self << drop_trigger_sql(table, name, opts)
|
|
277
266
|
end
|
|
278
267
|
|
|
279
|
-
# If any of the extensions that require reseting the conversion procs
|
|
280
|
-
# is loaded, reset them. This is done here so that if you load
|
|
281
|
-
# multiple pg_* extensions in the same call, the conversion procs are
|
|
282
|
-
# only reset once instead of once for every extension.
|
|
283
|
-
def extension(*exts)
|
|
284
|
-
super
|
|
285
|
-
unless (RESET_PROCS_EXTENSIONS & exts).empty?
|
|
286
|
-
reset_conversion_procs
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
|
|
290
268
|
# Return full foreign key information using the pg system tables, including
|
|
291
269
|
# :name, :on_delete, :on_update, and :deferrable entries in the hashes.
|
|
292
270
|
def foreign_key_list(table, opts={})
|
|
@@ -379,7 +357,13 @@ module Sequel
|
|
|
379
357
|
# :server :: The server to which to send the NOTIFY statement, if the sharding support
|
|
380
358
|
# is being used.
|
|
381
359
|
def notify(channel, opts={})
|
|
382
|
-
|
|
360
|
+
sql = "NOTIFY "
|
|
361
|
+
dataset.send(:identifier_append, sql, channel)
|
|
362
|
+
if payload = opts[:payload]
|
|
363
|
+
sql << ", "
|
|
364
|
+
dataset.literal_append(sql, payload.to_s)
|
|
365
|
+
end
|
|
366
|
+
execute_ddl(sql, opts)
|
|
383
367
|
end
|
|
384
368
|
|
|
385
369
|
# Return primary key for the given table.
|
|
@@ -530,6 +514,16 @@ module Sequel
|
|
|
530
514
|
|
|
531
515
|
private
|
|
532
516
|
|
|
517
|
+
# Do a type name-to-oid lookup using the database and update the procs
|
|
518
|
+
# with the related proc if the database supports the type.
|
|
519
|
+
def add_named_conversion_procs(procs, named_procs)
|
|
520
|
+
unless (named_procs).empty?
|
|
521
|
+
convert_named_procs_to_procs(named_procs).each do |oid, pr|
|
|
522
|
+
procs[oid] ||= pr
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
533
527
|
# Use a PostgreSQL-specific alter table generator
|
|
534
528
|
def alter_table_generator_class
|
|
535
529
|
Postgres::AlterTableGenerator
|
|
@@ -596,13 +590,29 @@ module Sequel
|
|
|
596
590
|
(super || op[:op] == :validate_constraint) && op[:op] != :rename_column
|
|
597
591
|
end
|
|
598
592
|
|
|
593
|
+
VALID_CLIENT_MIN_MESSAGES = %w'DEBUG5 DEBUG4 DEBUG3 DEBUG2 DEBUG1 LOG NOTICE WARNING ERROR FATAL PANIC'.freeze
|
|
599
594
|
# The SQL queries to execute when starting a new connection.
|
|
600
595
|
def connection_configuration_sqls
|
|
601
596
|
sqls = []
|
|
597
|
+
|
|
602
598
|
sqls << "SET standard_conforming_strings = ON" if typecast_value_boolean(@opts.fetch(:force_standard_strings, Postgres.force_standard_strings))
|
|
599
|
+
|
|
603
600
|
if (cmm = @opts.fetch(:client_min_messages, Postgres.client_min_messages)) && !cmm.to_s.empty?
|
|
604
601
|
sqls << "SET client_min_messages = '#{cmm.to_s.upcase}'"
|
|
605
602
|
end
|
|
603
|
+
|
|
604
|
+
if search_path = @opts[:search_path]
|
|
605
|
+
case search_path
|
|
606
|
+
when String
|
|
607
|
+
search_path = search_path.split(",").map{|s| s.strip}
|
|
608
|
+
when Array
|
|
609
|
+
# nil
|
|
610
|
+
else
|
|
611
|
+
raise Error, "unrecognized value for :search_path option: #{search_path.inspect}"
|
|
612
|
+
end
|
|
613
|
+
sqls << "SET search_path = #{search_path.map{|s| "\"#{s.gsub('"', '""')}\""}.join(',')}"
|
|
614
|
+
end
|
|
615
|
+
|
|
606
616
|
sqls
|
|
607
617
|
end
|
|
608
618
|
|
|
@@ -623,6 +633,24 @@ module Sequel
|
|
|
623
633
|
end
|
|
624
634
|
end
|
|
625
635
|
|
|
636
|
+
# Convert the hash of named conversion procs into a hash a oid conversion procs.
|
|
637
|
+
def convert_named_procs_to_procs(named_procs)
|
|
638
|
+
h = {}
|
|
639
|
+
from(:pg_type).where(:typtype=>'b', :typname=>named_procs.keys.map{|t| t.to_s}).select_map([:oid, :typname]).each do |oid, name|
|
|
640
|
+
h[oid.to_i] = named_procs[name.untaint.to_sym]
|
|
641
|
+
end
|
|
642
|
+
h
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
# Copy the conversion procs related to the given oids from PG_TYPES into
|
|
646
|
+
# the conversion procs for this instance.
|
|
647
|
+
def copy_conversion_procs(oids)
|
|
648
|
+
procs = conversion_procs
|
|
649
|
+
oids.each do |oid|
|
|
650
|
+
procs[oid] = PG_TYPES[oid]
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
|
|
626
654
|
EXCLUSION_CONSTRAINT_SQL_STATE = '23P01'.freeze
|
|
627
655
|
def database_specific_error_class_from_sqlstate(sqlstate)
|
|
628
656
|
if sqlstate == EXCLUSION_CONSTRAINT_SQL_STATE
|
|
@@ -665,23 +693,23 @@ module Sequel
|
|
|
665
693
|
|
|
666
694
|
# SQL for doing fast table output to stdout.
|
|
667
695
|
def copy_table_sql(table, opts)
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
696
|
+
if table.is_a?(String)
|
|
697
|
+
table
|
|
698
|
+
else
|
|
699
|
+
if opts[:options] || opts[:format]
|
|
700
|
+
options = " ("
|
|
701
|
+
options << "FORMAT #{opts[:format]}" if opts[:format]
|
|
702
|
+
options << "#{', ' if opts[:format]}#{opts[:options]}" if opts[:options]
|
|
703
|
+
options << ')'
|
|
704
|
+
end
|
|
705
|
+
table = if table.is_a?(::Sequel::Dataset)
|
|
706
|
+
"(#{table.sql})"
|
|
707
|
+
else
|
|
708
|
+
literal(table)
|
|
709
|
+
end
|
|
710
|
+
"COPY #{table} TO STDOUT#{options}"
|
|
711
|
+
end
|
|
712
|
+
end
|
|
685
713
|
|
|
686
714
|
# SQL statement to create database function.
|
|
687
715
|
def create_function_sql(name, definition, opts={})
|
|
@@ -786,11 +814,7 @@ module Sequel
|
|
|
786
814
|
def get_conversion_procs
|
|
787
815
|
procs = PG_TYPES.dup
|
|
788
816
|
procs[1184] = procs[1114] = method(:to_application_timestamp)
|
|
789
|
-
|
|
790
|
-
from(:pg_type).where(:typtype=>'b', :typname=>pgnt.keys.map{|t| t.to_s}).select_map([:oid, :typname]).each do |oid, name|
|
|
791
|
-
procs[oid.to_i] ||= pgnt[name.untaint.to_sym]
|
|
792
|
-
end
|
|
793
|
-
end
|
|
817
|
+
add_named_conversion_procs(procs, PG_NAMED_TYPES)
|
|
794
818
|
procs
|
|
795
819
|
end
|
|
796
820
|
|
|
@@ -915,6 +939,8 @@ module Sequel
|
|
|
915
939
|
m = output_identifier_meth(opts[:dataset])
|
|
916
940
|
ds = metadata_dataset.select(:pg_attribute__attname___name,
|
|
917
941
|
SQL::Cast.new(:pg_attribute__atttypid, :integer).as(:oid),
|
|
942
|
+
SQL::Cast.new(:basetype__oid, :integer).as(:base_oid),
|
|
943
|
+
SQL::Function.new(:format_type, :basetype__oid, :pg_type__typtypmod).as(:db_base_type),
|
|
918
944
|
SQL::Function.new(:format_type, :pg_type__oid, :pg_attribute__atttypmod).as(:db_type),
|
|
919
945
|
SQL::Function.new(:pg_get_expr, :pg_attrdef__adbin, :pg_class__oid).as(:default),
|
|
920
946
|
SQL::BooleanExpression.new(:NOT, :pg_attribute__attnotnull).as(:allow_null),
|
|
@@ -922,6 +948,7 @@ module Sequel
|
|
|
922
948
|
from(:pg_class).
|
|
923
949
|
join(:pg_attribute, :attrelid=>:oid).
|
|
924
950
|
join(:pg_type, :oid=>:atttypid).
|
|
951
|
+
left_outer_join(:pg_type___basetype, :oid=>:typbasetype).
|
|
925
952
|
left_outer_join(:pg_attrdef, :adrelid=>:pg_class__oid, :adnum=>:pg_attribute__attnum).
|
|
926
953
|
left_outer_join(:pg_index, :indrelid=>:pg_class__oid, :indisprimary=>true).
|
|
927
954
|
filter(:pg_attribute__attisdropped=>false).
|
|
@@ -930,6 +957,15 @@ module Sequel
|
|
|
930
957
|
order(:pg_attribute__attnum)
|
|
931
958
|
ds.map do |row|
|
|
932
959
|
row[:default] = nil if blank_object?(row[:default])
|
|
960
|
+
if row[:base_oid]
|
|
961
|
+
row[:domain_oid] = row[:oid]
|
|
962
|
+
row[:oid] = row.delete(:base_oid)
|
|
963
|
+
row[:db_domain_type] = row[:db_type]
|
|
964
|
+
row[:db_type] = row.delete(:db_base_type)
|
|
965
|
+
else
|
|
966
|
+
row.delete(:base_oid)
|
|
967
|
+
row.delete(:db_base_type)
|
|
968
|
+
end
|
|
933
969
|
row[:type] = schema_column_type(row[:db_type])
|
|
934
970
|
[m.call(row.delete(:name)), row]
|
|
935
971
|
end
|
|
@@ -1009,7 +1045,6 @@ module Sequel
|
|
|
1009
1045
|
FOR_SHARE = ' FOR SHARE'.freeze
|
|
1010
1046
|
INSERT_CLAUSE_METHODS = Dataset.clause_methods(:insert, %w'insert into columns values returning')
|
|
1011
1047
|
INSERT_CLAUSE_METHODS_91 = Dataset.clause_methods(:insert, %w'with insert into columns values returning')
|
|
1012
|
-
LOCK = 'LOCK TABLE %s IN %s MODE'.freeze
|
|
1013
1048
|
NULL = LiteralString.new('NULL').freeze
|
|
1014
1049
|
PG_TIMESTAMP_FORMAT = "TIMESTAMP '%Y-%m-%d %H:%M:%S".freeze
|
|
1015
1050
|
QUERY_PLAN = 'QUERY PLAN'.to_sym
|
|
@@ -1039,6 +1074,7 @@ module Sequel
|
|
|
1039
1074
|
BLOB_RE = /[\000-\037\047\134\177-\377]/n.freeze
|
|
1040
1075
|
WINDOW = " WINDOW ".freeze
|
|
1041
1076
|
EMPTY_STRING = ''.freeze
|
|
1077
|
+
LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each{|s| s.freeze}
|
|
1042
1078
|
|
|
1043
1079
|
# Shared methods for prepared statements when used with PostgreSQL databases.
|
|
1044
1080
|
module PreparedStatementMethods
|
|
@@ -1140,7 +1176,10 @@ module Sequel
|
|
|
1140
1176
|
if block_given? # perform locking inside a transaction and yield to block
|
|
1141
1177
|
@db.transaction(opts){lock(mode, opts); yield}
|
|
1142
1178
|
else
|
|
1143
|
-
|
|
1179
|
+
sql = 'LOCK TABLE '
|
|
1180
|
+
source_list_append(sql, @opts[:from])
|
|
1181
|
+
sql << " IN #{mode} MODE"
|
|
1182
|
+
@db.execute(sql, opts) # lock without a transaction
|
|
1144
1183
|
end
|
|
1145
1184
|
nil
|
|
1146
1185
|
end
|
|
@@ -661,7 +661,9 @@ module Sequel
|
|
|
661
661
|
SELECT_CLAUSE_METHODS
|
|
662
662
|
end
|
|
663
663
|
|
|
664
|
-
#
|
|
664
|
+
# SQLite does not support FOR UPDATE, but silently ignore it
|
|
665
|
+
# instead of raising an error for compatibility with other
|
|
666
|
+
# databases.
|
|
665
667
|
def select_lock_sql(sql)
|
|
666
668
|
super unless @opts[:lock] == :update
|
|
667
669
|
end
|
|
@@ -356,8 +356,8 @@ module Sequel
|
|
|
356
356
|
@columns = cols.map{|c| c.first}
|
|
357
357
|
result.each do |values|
|
|
358
358
|
row = {}
|
|
359
|
-
cols.each do |name,
|
|
360
|
-
v = values[
|
|
359
|
+
cols.each do |name,id,type_proc|
|
|
360
|
+
v = values[id]
|
|
361
361
|
if type_proc && v
|
|
362
362
|
v = type_proc.call(v)
|
|
363
363
|
end
|
|
@@ -59,23 +59,10 @@ module Sequel
|
|
|
59
59
|
[700, 701] => tt.method(:float),
|
|
60
60
|
[1700] => ::BigDecimal.method(:new),
|
|
61
61
|
[1083, 1266] => ::Sequel.method(:string_to_time),
|
|
62
|
+
[1082] => ::Sequel.method(:string_to_date),
|
|
62
63
|
[1184, 1114] => ::Sequel.method(:database_to_application_timestamp),
|
|
63
64
|
}.each do |k,v|
|
|
64
65
|
k.each{|n| PG_TYPES[n] = v}
|
|
65
66
|
end
|
|
66
|
-
|
|
67
|
-
class << self
|
|
68
|
-
# As an optimization, Sequel sets the date style to ISO, so that PostgreSQL provides
|
|
69
|
-
# the date in a known format that Sequel can parse faster. This can be turned off
|
|
70
|
-
# if you require a date style other than ISO.
|
|
71
|
-
attr_reader :use_iso_date_format
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# Modify the type translator for the date type depending on the value given.
|
|
75
|
-
def self.use_iso_date_format=(v)
|
|
76
|
-
PG_TYPES[1082] = v ? TYPE_TRANSLATOR.method(:date) : Sequel.method(:string_to_date)
|
|
77
|
-
@use_iso_date_format = v
|
|
78
|
-
end
|
|
79
|
-
self.use_iso_date_format = true
|
|
80
67
|
end
|
|
81
68
|
end
|