sequel 4.47.0 → 4.48.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 +134 -0
- data/Rakefile +1 -1
- data/doc/release_notes/4.48.0.txt +293 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +24 -7
- data/lib/sequel/adapters/jdbc.rb +36 -22
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
- data/lib/sequel/adapters/mock.rb +24 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +4 -5
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +89 -102
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +75 -24
- data/lib/sequel/adapters/shared/postgres.rb +196 -94
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +18 -10
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +19 -8
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +6 -6
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +24 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model.rb +25 -57
- data/lib/sequel/model/associations.rb +14 -5
- data/lib/sequel/model/base.rb +96 -32
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +1 -1
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/defaults_setter.rb +10 -0
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +17 -10
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +5 -1
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/serialization.rb +3 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +2 -4
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mysql_spec.rb +78 -28
- data/spec/adapters/oracle_spec.rb +24 -24
- data/spec/adapters/postgres_spec.rb +38 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/core/connection_pool_spec.rb +17 -0
- data/spec/core/database_spec.rb +6 -0
- data/spec/core/dataset_spec.rb +46 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +48 -2
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +8 -8
- data/spec/extensions/defaults_setter_spec.rb +1 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +96 -98
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +9 -3
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/plugin_test.rb +20 -0
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/class_dataset_methods_spec.rb +14 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/model_spec.rb +8 -0
- metadata +6 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
|
@@ -75,13 +75,14 @@ module Sequel
|
|
|
75
75
|
:starts_after => ["(".freeze, " &> ".freeze, ")".freeze].freeze,
|
|
76
76
|
:adjacent_to => ["(".freeze, " -|- ".freeze, ")".freeze].freeze,
|
|
77
77
|
:overlaps => ["(".freeze, " && ".freeze, ")".freeze].freeze,
|
|
78
|
-
}
|
|
78
|
+
}#.freeze # SEQUEL5
|
|
79
79
|
FUNCTIONS = %w'lower upper isempty lower_inc upper_inc lower_inf upper_inf'
|
|
80
|
+
Sequel::Deprecation.deprecate_constant(self, :FUNCTIONS)
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
%w'lower upper isempty lower_inc upper_inc lower_inf upper_inf'.each do |f|
|
|
82
83
|
class_eval("def #{f}; function(:#{f}) end", __FILE__, __LINE__)
|
|
83
84
|
end
|
|
84
|
-
OPERATORS.
|
|
85
|
+
OPERATORS.each_key do |f|
|
|
85
86
|
class_eval("def #{f}(v); operator(:#{f}, v) end", __FILE__, __LINE__)
|
|
86
87
|
end
|
|
87
88
|
|
|
@@ -18,11 +18,14 @@
|
|
|
18
18
|
# for HashRow and ArrayRow using the standard Sequel literalization callbacks, so
|
|
19
19
|
# they work with on all adapters.
|
|
20
20
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
21
|
+
# To use this extension, first load it into the Database instance:
|
|
22
|
+
#
|
|
23
|
+
# DB.extension :pg_row
|
|
24
|
+
#
|
|
25
|
+
# If you plan to use arrays of composite types, make sure you load the
|
|
26
|
+
# pg_array extension first:
|
|
24
27
|
#
|
|
25
|
-
# DB.extension
|
|
28
|
+
# DB.extension :pg_array, :pg_row
|
|
26
29
|
#
|
|
27
30
|
# You can create an anonymous row type by calling the Sequel.pg_row with
|
|
28
31
|
# an array:
|
|
@@ -85,13 +88,15 @@
|
|
|
85
88
|
|
|
86
89
|
require 'delegate'
|
|
87
90
|
require 'strscan'
|
|
88
|
-
Sequel.require 'adapters/
|
|
91
|
+
Sequel.require 'adapters/shared/postgres'
|
|
89
92
|
|
|
90
93
|
module Sequel
|
|
91
94
|
module Postgres
|
|
92
95
|
module PGRow
|
|
93
96
|
ROW = 'ROW'.freeze
|
|
97
|
+
Sequel::Deprecation.deprecate_constant(self, :ROW)
|
|
94
98
|
CAST = '::'.freeze
|
|
99
|
+
Sequel::Deprecation.deprecate_constant(self, :CAST)
|
|
95
100
|
|
|
96
101
|
# Class for row-valued/composite types that are treated as arrays. By default,
|
|
97
102
|
# this is only used for generic PostgreSQL record types, as registered
|
|
@@ -130,10 +135,10 @@ module Sequel
|
|
|
130
135
|
|
|
131
136
|
# Append SQL fragment related to this object to the sql.
|
|
132
137
|
def sql_literal_append(ds, sql)
|
|
133
|
-
sql << ROW
|
|
138
|
+
sql << 'ROW'
|
|
134
139
|
ds.literal_append(sql, to_a)
|
|
135
140
|
if db_type
|
|
136
|
-
sql <<
|
|
141
|
+
sql << '::'
|
|
137
142
|
ds.quote_schema_table_append(sql, db_type)
|
|
138
143
|
end
|
|
139
144
|
end
|
|
@@ -202,16 +207,16 @@ module Sequel
|
|
|
202
207
|
# Append SQL fragment related to this object to the sql.
|
|
203
208
|
def sql_literal_append(ds, sql)
|
|
204
209
|
check_columns!
|
|
205
|
-
sql << ROW
|
|
210
|
+
sql << 'ROW'
|
|
206
211
|
ds.literal_append(sql, values_at(*columns))
|
|
207
212
|
if db_type
|
|
208
|
-
sql <<
|
|
213
|
+
sql << '::'
|
|
209
214
|
ds.quote_schema_table_append(sql, db_type)
|
|
210
215
|
end
|
|
211
216
|
end
|
|
212
217
|
end
|
|
213
218
|
|
|
214
|
-
ROW_TYPE_CLASSES = [HashRow, ArrayRow]
|
|
219
|
+
ROW_TYPE_CLASSES = [HashRow, ArrayRow]#.freeze # SEQUEL5
|
|
215
220
|
|
|
216
221
|
# This parser-like class splits the PostgreSQL
|
|
217
222
|
# row-valued/composite type output string format
|
|
@@ -221,32 +226,41 @@ module Sequel
|
|
|
221
226
|
# PostgreSQL uses.
|
|
222
227
|
class Splitter < StringScanner
|
|
223
228
|
OPEN_PAREN = /\(/.freeze
|
|
229
|
+
Sequel::Deprecation.deprecate_constant(self, :OPEN_PAREN)
|
|
224
230
|
CLOSE_PAREN = /\)/.freeze
|
|
231
|
+
Sequel::Deprecation.deprecate_constant(self, :CLOSE_PAREN)
|
|
225
232
|
UNQUOTED_RE = /[^,)]*/.freeze
|
|
233
|
+
Sequel::Deprecation.deprecate_constant(self, :UNQUOTED_RE)
|
|
226
234
|
SEP_RE = /[,)]/.freeze
|
|
235
|
+
Sequel::Deprecation.deprecate_constant(self, :SEP_RE)
|
|
227
236
|
QUOTE_RE = /"/.freeze
|
|
237
|
+
Sequel::Deprecation.deprecate_constant(self, :QUOTE_RE)
|
|
228
238
|
QUOTE_SEP_RE = /"[,)]/.freeze
|
|
239
|
+
Sequel::Deprecation.deprecate_constant(self, :QUOTE_SEP_RE)
|
|
229
240
|
QUOTED_RE = /(\\.|""|[^"])*/.freeze
|
|
241
|
+
Sequel::Deprecation.deprecate_constant(self, :QUOTED_RE)
|
|
230
242
|
REPLACE_RE = /\\(.)|"(")/.freeze
|
|
243
|
+
Sequel::Deprecation.deprecate_constant(self, :REPLACE_RE)
|
|
231
244
|
REPLACE_WITH = '\1\2'.freeze
|
|
245
|
+
Sequel::Deprecation.deprecate_constant(self, :REPLACE_WITH)
|
|
232
246
|
|
|
233
247
|
# Split the stored string into an array of strings, handling
|
|
234
248
|
# the different types of quoting.
|
|
235
249
|
def parse
|
|
236
250
|
return @result if @result
|
|
237
251
|
values = []
|
|
238
|
-
skip(
|
|
239
|
-
if skip(
|
|
252
|
+
skip(/\(/)
|
|
253
|
+
if skip(/\)/)
|
|
240
254
|
values << nil
|
|
241
255
|
else
|
|
242
256
|
until eos?
|
|
243
|
-
if skip(
|
|
244
|
-
values << scan(
|
|
245
|
-
skip(
|
|
257
|
+
if skip(/"/)
|
|
258
|
+
values << scan(/(\\.|""|[^"])*/).gsub(/\\(.)|"(")/, '\1\2')
|
|
259
|
+
skip(/"[,)]/)
|
|
246
260
|
else
|
|
247
|
-
v = scan(
|
|
261
|
+
v = scan(/[^,)]*/)
|
|
248
262
|
values << (v unless v.empty?)
|
|
249
|
-
skip(
|
|
263
|
+
skip(/[,)]/)
|
|
250
264
|
end
|
|
251
265
|
end
|
|
252
266
|
end
|
|
@@ -374,8 +388,11 @@ module Sequel
|
|
|
374
388
|
|
|
375
389
|
module DatabaseMethods
|
|
376
390
|
ESCAPE_RE = /("|\\)/.freeze
|
|
391
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_RE)
|
|
377
392
|
ESCAPE_REPLACEMENT = '\\\\\1'.freeze
|
|
393
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_REPLACEMENT)
|
|
378
394
|
COMMA = ','.freeze
|
|
395
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
|
379
396
|
|
|
380
397
|
# A hash mapping row type keys (usually symbols), to option
|
|
381
398
|
# hashes. At the least, the values will contain the :parser
|
|
@@ -384,17 +401,14 @@ module Sequel
|
|
|
384
401
|
|
|
385
402
|
# Do some setup for the data structures the module uses.
|
|
386
403
|
def self.extended(db)
|
|
387
|
-
# Return right away if row_types has already been set. This
|
|
388
|
-
# makes things not break if a user extends the database with
|
|
389
|
-
# this module more than once (since extended is called every
|
|
390
|
-
# time).
|
|
391
|
-
return if db.row_types
|
|
392
|
-
|
|
393
404
|
db.instance_eval do
|
|
394
405
|
@row_types = {}
|
|
395
406
|
@row_schema_types = {}
|
|
396
407
|
extend(@row_type_method_module = Module.new)
|
|
397
|
-
|
|
408
|
+
add_conversion_proc(2249, PGRow::Parser.new(:converter=>PGRow::ArrayRow))
|
|
409
|
+
if respond_to?(:register_array_type)
|
|
410
|
+
register_array_type('record', :oid=>2287, :scalar_oid=>2249)
|
|
411
|
+
end
|
|
398
412
|
end
|
|
399
413
|
end
|
|
400
414
|
|
|
@@ -402,10 +416,10 @@ module Sequel
|
|
|
402
416
|
def bound_variable_arg(arg, conn)
|
|
403
417
|
case arg
|
|
404
418
|
when ArrayRow
|
|
405
|
-
"(#{arg.map{|v| bound_variable_array(v) if v}.join(
|
|
419
|
+
"(#{arg.map{|v| bound_variable_array(v) if v}.join(',')})"
|
|
406
420
|
when HashRow
|
|
407
421
|
arg.check_columns!
|
|
408
|
-
"(#{arg.values_at(*arg.columns).map{|v| bound_variable_array(v) if v}.join(
|
|
422
|
+
"(#{arg.values_at(*arg.columns).map{|v| bound_variable_array(v) if v}.join(',')})"
|
|
409
423
|
else
|
|
410
424
|
super
|
|
411
425
|
end
|
|
@@ -419,6 +433,8 @@ module Sequel
|
|
|
419
433
|
super
|
|
420
434
|
end
|
|
421
435
|
|
|
436
|
+
STRING_TYPES = [18, 19, 25, 1042, 1043].freeze
|
|
437
|
+
|
|
422
438
|
# Register a new row type for the Database instance. db_type should be the type
|
|
423
439
|
# symbol. This parses the PostgreSQL system tables to get information the
|
|
424
440
|
# composite type, and by default has the type return instances of a subclass
|
|
@@ -471,12 +487,22 @@ module Sequel
|
|
|
471
487
|
|
|
472
488
|
# Using the conversion_procs, lookup converters for each member of the composite type
|
|
473
489
|
parser_opts[:column_converters] = parser_opts[:column_oids].map do |oid|
|
|
490
|
+
# procs[oid] # SEQUEL5
|
|
491
|
+
|
|
492
|
+
# SEQUEL5: Remove
|
|
474
493
|
if pr = procs[oid]
|
|
475
494
|
pr
|
|
476
|
-
elsif !
|
|
495
|
+
elsif !STRING_TYPES.include?(oid)
|
|
477
496
|
# It's not a string type, and it's possible a conversion proc for this
|
|
478
497
|
# oid will be added later, so do a runtime check for it.
|
|
479
|
-
lambda
|
|
498
|
+
lambda do |s|
|
|
499
|
+
if (pr = procs[oid])
|
|
500
|
+
Sequel::Deprecation.deprecate("Calling conversion proc for subtype (oid: #{oid}) of composite type (oid: #{parser_opts[:oid]}) not added until after composite type registration", "Register subtype conversion procs before registering composite type")
|
|
501
|
+
pr.call(s)
|
|
502
|
+
else
|
|
503
|
+
s
|
|
504
|
+
end
|
|
505
|
+
end
|
|
480
506
|
end
|
|
481
507
|
end
|
|
482
508
|
|
|
@@ -485,15 +511,15 @@ module Sequel
|
|
|
485
511
|
parser_opts[:typecaster] = opts.fetch(:typecaster, parser_opts[:converter])
|
|
486
512
|
|
|
487
513
|
parser = Parser.new(parser_opts)
|
|
488
|
-
|
|
514
|
+
add_conversion_proc(parser.oid, parser)
|
|
489
515
|
|
|
490
|
-
if
|
|
516
|
+
if respond_to?(:register_array_type) && array_oid && array_oid > 0
|
|
491
517
|
array_type_name = if type_schema
|
|
492
518
|
"#{type_schema}.#{type_name}"
|
|
493
519
|
else
|
|
494
520
|
type_name
|
|
495
521
|
end
|
|
496
|
-
|
|
522
|
+
register_array_type(array_type_name, :oid=>array_oid, :converter=>parser, :scalar_typecast=>schema_type_symbol)
|
|
497
523
|
end
|
|
498
524
|
|
|
499
525
|
@row_types[literal(db_type)] = opts.merge(:parser=>parser, :type=>db_type)
|
|
@@ -507,12 +533,11 @@ module Sequel
|
|
|
507
533
|
private meth
|
|
508
534
|
end
|
|
509
535
|
|
|
510
|
-
conversion_procs_updated
|
|
536
|
+
conversion_procs_updated # SEQUEL5: Remove
|
|
511
537
|
nil
|
|
512
538
|
end
|
|
513
539
|
|
|
514
|
-
#
|
|
515
|
-
# the system tables are introspected again, picking up database changes.
|
|
540
|
+
# SEQUEL5: Remove
|
|
516
541
|
def reset_conversion_procs
|
|
517
542
|
procs = super
|
|
518
543
|
|
|
@@ -558,10 +583,10 @@ module Sequel
|
|
|
558
583
|
def bound_variable_array(arg)
|
|
559
584
|
case arg
|
|
560
585
|
when ArrayRow
|
|
561
|
-
"\"(#{arg.map{|v| bound_variable_array(v) if v}.join(
|
|
586
|
+
"\"(#{arg.map{|v| bound_variable_array(v) if v}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
|
|
562
587
|
when HashRow
|
|
563
588
|
arg.check_columns!
|
|
564
|
-
"\"(#{arg.values_at(*arg.columns).map{|v| bound_variable_array(v) if v}.join(
|
|
589
|
+
"\"(#{arg.values_at(*arg.columns).map{|v| bound_variable_array(v) if v}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
|
|
565
590
|
else
|
|
566
591
|
super
|
|
567
592
|
end
|
|
@@ -578,10 +603,14 @@ module Sequel
|
|
|
578
603
|
end
|
|
579
604
|
end
|
|
580
605
|
|
|
581
|
-
#
|
|
582
|
-
|
|
606
|
+
# SEQUEL5: Remove
|
|
607
|
+
parser = PGRow::Parser.new(:converter=>PGRow::ArrayRow)
|
|
608
|
+
PG__TYPES[2249] = lambda do |s|
|
|
609
|
+
Sequel::Deprecation.deprecate("Conversion proc for record added globally by pg_row extension", "Load the pg_row extension into the Database instance")
|
|
610
|
+
parser.call(s)
|
|
611
|
+
end
|
|
583
612
|
if defined?(PGArray) && PGArray.respond_to?(:register)
|
|
584
|
-
PGArray.register('record', :oid=>2287, :scalar_oid=>2249)
|
|
613
|
+
PGArray.register('record', :oid=>2287, :scalar_oid=>2249, :skip_deprecation_warning=>true)
|
|
585
614
|
end
|
|
586
615
|
end
|
|
587
616
|
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
#
|
|
71
71
|
# By casting the expression, you can get a composite type returned:
|
|
72
72
|
#
|
|
73
|
-
# DB[:a].select(a.splat).first # SELECT (a.*)::a FROM a
|
|
73
|
+
# DB[:a].select(a.splat(:a)).first # SELECT (a.*)::a FROM a
|
|
74
74
|
# # => {:a=>"(1,2)"} # or {:a=>{:a=>1, :b=>2}} if the "a" type has been registered
|
|
75
75
|
# # with the pg_row extension
|
|
76
76
|
#
|
|
@@ -89,14 +89,20 @@ module Sequel
|
|
|
89
89
|
# This class represents a composite type expression reference.
|
|
90
90
|
class PGRowOp < SQL::PlaceholderLiteralString
|
|
91
91
|
OPEN = '('.freeze
|
|
92
|
+
Sequel::Deprecation.deprecate_constant(self, :OPEN)
|
|
92
93
|
CLOSE_DOT = ').'.freeze
|
|
94
|
+
Sequel::Deprecation.deprecate_constant(self, :CLOSE_DOT)
|
|
93
95
|
CLOSE_STAR = '.*)'.freeze
|
|
96
|
+
Sequel::Deprecation.deprecate_constant(self, :CLOSE_STAR)
|
|
94
97
|
CLOSE_STAR_CAST = '.*)::'.freeze
|
|
98
|
+
Sequel::Deprecation.deprecate_constant(self, :CLOSE_STAR_CAST)
|
|
95
99
|
EMPTY = "".freeze
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
Sequel::Deprecation.deprecate_constant(self, :EMPTY)
|
|
101
|
+
|
|
102
|
+
ROW = ['(', '.*)'].freeze.each(&:freeze)
|
|
103
|
+
ROW_CAST = ['(', '.*)::'].freeze.each(&:freeze)
|
|
104
|
+
QUALIFY = ['(', ').'].freeze.each(&:freeze)
|
|
105
|
+
WRAP = [""].freeze.each(&:freeze)
|
|
100
106
|
|
|
101
107
|
# Wrap the expression in a PGRowOp, without changing the
|
|
102
108
|
# SQL it would use.
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
#
|
|
36
36
|
# Related module: Sequel::QueryLiterals
|
|
37
37
|
|
|
38
|
+
Sequel::Deprecation.deprecate("The query_literals extension", "Please consider maintaining it yourself as an external gem if you want to continue using it")
|
|
39
|
+
|
|
38
40
|
#
|
|
39
41
|
module Sequel
|
|
40
42
|
# The QueryLiterals module can be used to make select, group, and
|
data/lib/sequel/extensions/s.rb
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
#
|
|
28
28
|
# or just into Object if you want it available everywhere:
|
|
29
29
|
#
|
|
30
|
-
# Object.send(:include, Sequel::
|
|
30
|
+
# Object.send(:include, Sequel::S)
|
|
31
31
|
#
|
|
32
32
|
# If you are using Ruby 2+, and you would like to use refinements, you
|
|
33
33
|
# can use Sequel::S as a refinement, in which case the private #S method
|
|
@@ -25,7 +25,7 @@ module Sequel
|
|
|
25
25
|
type = type.sub(/ not null\z/, '')
|
|
26
26
|
end
|
|
27
27
|
case type
|
|
28
|
-
when /\A(medium|small)?int(?:eger)?(?:\((\d+)\))?( unsigned)?\z/
|
|
28
|
+
when /\A(medium|small)?int(?:eger)?(?:\((\d+)\))?( unsigned)?\z/
|
|
29
29
|
if !$1 && $2 && $2.to_i >= 10 && $3
|
|
30
30
|
# Unsigned integer type with 10 digits can potentially contain values which
|
|
31
31
|
# don't fit signed integer type, so use bigint type in target database.
|
|
@@ -33,36 +33,36 @@ module Sequel
|
|
|
33
33
|
else
|
|
34
34
|
{:type=>Integer}
|
|
35
35
|
end
|
|
36
|
-
when /\Atinyint(?:\((\d+)\))?(?: unsigned)?\z/
|
|
36
|
+
when /\Atinyint(?:\((\d+)\))?(?: unsigned)?\z/
|
|
37
37
|
{:type =>schema[:type] == :boolean ? TrueClass : Integer}
|
|
38
|
-
when /\Abigint(?:\((?:\d+)\))?(?: unsigned)?\z/
|
|
38
|
+
when /\Abigint(?:\((?:\d+)\))?(?: unsigned)?\z/
|
|
39
39
|
{:type=>:Bignum}
|
|
40
|
-
when /\A(?:real|float|double(?: precision)?|double\(\d+,\d+\)(?: unsigned)?)\z/
|
|
40
|
+
when /\A(?:real|float|double(?: precision)?|double\(\d+,\d+\)(?: unsigned)?)\z/
|
|
41
41
|
{:type=>Float}
|
|
42
42
|
when 'boolean', 'bit', 'bool'
|
|
43
43
|
{:type=>TrueClass}
|
|
44
|
-
when /\A(?:(?:tiny|medium|long|n)?text|clob)\z/
|
|
44
|
+
when /\A(?:(?:tiny|medium|long|n)?text|clob)\z/
|
|
45
45
|
{:type=>String, :text=>true}
|
|
46
46
|
when 'date'
|
|
47
47
|
{:type=>Date}
|
|
48
|
-
when /\A(?:small)?datetime\z/
|
|
48
|
+
when /\A(?:small)?datetime\z/
|
|
49
49
|
{:type=>DateTime}
|
|
50
|
-
when /\Atimestamp(?:\((\d+)\))?(?: with(?:out)? time zone)?\z/
|
|
50
|
+
when /\Atimestamp(?:\((\d+)\))?(?: with(?:out)? time zone)?\z/
|
|
51
51
|
{:type=>DateTime, :size=>($1.to_i if $1)}
|
|
52
|
-
when /\Atime(?: with(?:out)? time zone)?\z/
|
|
52
|
+
when /\Atime(?: with(?:out)? time zone)?\z/
|
|
53
53
|
{:type=>Time, :only_time=>true}
|
|
54
|
-
when /\An?char(?:acter)?(?:\((\d+)\))?\z/
|
|
54
|
+
when /\An?char(?:acter)?(?:\((\d+)\))?\z/
|
|
55
55
|
{:type=>String, :size=>($1.to_i if $1), :fixed=>true}
|
|
56
|
-
when /\A(?:n?varchar2?|character varying|bpchar|string)(?:\((\d+)\))?\z/
|
|
56
|
+
when /\A(?:n?varchar2?|character varying|bpchar|string)(?:\((\d+)\))?\z/
|
|
57
57
|
{:type=>String, :size=>($1.to_i if $1)}
|
|
58
|
-
when /\A(?:small)?money\z/
|
|
58
|
+
when /\A(?:small)?money\z/
|
|
59
59
|
{:type=>BigDecimal, :size=>[19,2]}
|
|
60
|
-
when /\A(?:decimal|numeric|number)(?:\((\d+)(?:,\s*(\d+))?\))?\z/
|
|
60
|
+
when /\A(?:decimal|numeric|number)(?:\((\d+)(?:,\s*(\d+))?\))?\z/
|
|
61
61
|
s = [($1.to_i if $1), ($2.to_i if $2)].compact
|
|
62
62
|
{:type=>BigDecimal, :size=>(s.empty? ? nil : s)}
|
|
63
|
-
when /\A(?:bytea|(?:tiny|medium|long)?blob|(?:var)?binary)(?:\((\d+)\))?\z/
|
|
63
|
+
when /\A(?:bytea|(?:tiny|medium|long)?blob|(?:var)?binary)(?:\((\d+)\))?\z/
|
|
64
64
|
{:type=>File, :size=>($1.to_i if $1)}
|
|
65
|
-
when /\A(?:year|(?:int )?identity)\z/
|
|
65
|
+
when /\A(?:year|(?:int )?identity)\z/
|
|
66
66
|
{:type=>Integer}
|
|
67
67
|
else
|
|
68
68
|
{:type=>String}
|
|
@@ -81,7 +81,7 @@ module Sequel
|
|
|
81
81
|
<<END_MIG
|
|
82
82
|
Sequel.migration do
|
|
83
83
|
change do
|
|
84
|
-
#{ts.sort_by(&:to_s).map{|t| dump_table_foreign_keys(t)}.reject{|x| x == ''}.join("\n\n").gsub(
|
|
84
|
+
#{ts.sort_by(&:to_s).map{|t| dump_table_foreign_keys(t)}.reject{|x| x == ''}.join("\n\n").gsub(/^/, ' ')}
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
END_MIG
|
|
@@ -99,7 +99,7 @@ END_MIG
|
|
|
99
99
|
<<END_MIG
|
|
100
100
|
Sequel.migration do
|
|
101
101
|
change do
|
|
102
|
-
#{ts.sort_by(&:to_s).map{|t| dump_table_indexes(t, :add_index, options)}.reject{|x| x == ''}.join("\n\n").gsub(
|
|
102
|
+
#{ts.sort_by(&:to_s).map{|t| dump_table_indexes(t, :add_index, options)}.reject{|x| x == ''}.join("\n\n").gsub(/^/, ' ')}
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
105
|
END_MIG
|
|
@@ -133,13 +133,13 @@ END_MIG
|
|
|
133
133
|
# alter_table/add_foreign_key. Note that skipped foreign keys
|
|
134
134
|
# probably result in a broken down migration.
|
|
135
135
|
sfka = sfk.sort_by{|table, fks| table.to_s}.map{|table, fks| dump_add_fk_constraints(table, fks.values)}
|
|
136
|
-
sfka.join("\n\n").gsub(
|
|
136
|
+
sfka.join("\n\n").gsub(/^/, ' ') unless sfka.empty?
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
<<END_MIG
|
|
140
140
|
Sequel.migration do
|
|
141
141
|
change do
|
|
142
|
-
#{ts.map{|t| dump_table_schema(t, options)}.join("\n\n").gsub(
|
|
142
|
+
#{ts.map{|t| dump_table_schema(t, options)}.join("\n\n").gsub(/^/, ' ')}#{"\n \n" if skipped_fks}#{skipped_fks}
|
|
143
143
|
end
|
|
144
144
|
end
|
|
145
145
|
END_MIG
|
|
@@ -150,7 +150,7 @@ END_MIG
|
|
|
150
150
|
def dump_table_schema(table, options=OPTS)
|
|
151
151
|
gen = dump_table_generator(table, options)
|
|
152
152
|
commands = [gen.dump_columns, gen.dump_constraints, gen.dump_indexes].reject{|x| x == ''}.join("\n\n")
|
|
153
|
-
"create_table(#{table.inspect}#{', :ignore_index_errors=>true' if !options[:same_db] && options[:indexes] != false && !gen.indexes.empty?}) do\n#{commands.gsub(
|
|
153
|
+
"create_table(#{table.inspect}#{', :ignore_index_errors=>true' if !options[:same_db] && options[:indexes] != false && !gen.indexes.empty?}) do\n#{commands.gsub(/^/, ' ')}\nend"
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
private
|
|
@@ -458,11 +458,11 @@ END_MIG
|
|
|
458
458
|
|
|
459
459
|
# Dump this generator's indexes to a string that could be evaled inside
|
|
460
460
|
# another instance to represent the same indexes. Options:
|
|
461
|
-
#
|
|
462
|
-
#
|
|
463
|
-
#
|
|
464
|
-
#
|
|
465
|
-
#
|
|
461
|
+
# :add_index :: Use add_index instead of index, so the methods
|
|
462
|
+
# can be called outside of a generator but inside a migration.
|
|
463
|
+
# The value of this option should be the table name to use.
|
|
464
|
+
# :drop_index :: Same as add_index, but create drop_index statements.
|
|
465
|
+
# :ignore_errors :: Add the ignore_errors option to the outputted indexes
|
|
466
466
|
def dump_indexes(options=OPTS)
|
|
467
467
|
is = indexes.map do |c|
|
|
468
468
|
c = c.dup
|