sequel 4.47.0 → 4.48.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -49,18 +49,18 @@
|
|
49
49
|
#
|
50
50
|
# * \[\]
|
51
51
|
# * \[\]=
|
52
|
-
# * assoc
|
52
|
+
# * assoc
|
53
53
|
# * delete
|
54
54
|
# * fetch
|
55
55
|
# * has_key?
|
56
56
|
# * has_value?
|
57
57
|
# * include?
|
58
|
-
# * key
|
58
|
+
# * key
|
59
59
|
# * key?
|
60
60
|
# * member?
|
61
61
|
# * merge
|
62
62
|
# * merge!
|
63
|
-
# * rassoc
|
63
|
+
# * rassoc
|
64
64
|
# * replace
|
65
65
|
# * store
|
66
66
|
# * update
|
@@ -70,10 +70,7 @@
|
|
70
70
|
#
|
71
71
|
# DB[:table].insert(:column=>Sequel.hstore('foo'=>'bar'))
|
72
72
|
#
|
73
|
-
#
|
74
|
-
# probably want to modify the schema parsing/typecasting so that it
|
75
|
-
# recognizes and correctly handles the hstore columns, which you can
|
76
|
-
# do by:
|
73
|
+
# To use this extension, first load it into your Sequel::Database instance:
|
77
74
|
#
|
78
75
|
# DB.extension :pg_hstore
|
79
76
|
#
|
@@ -95,12 +92,19 @@ module Sequel
|
|
95
92
|
# Parser for PostgreSQL hstore output format.
|
96
93
|
class Parser < StringScanner
|
97
94
|
QUOTE_RE = /"/.freeze
|
95
|
+
Sequel::Deprecation.deprecate_constant(self, :QUOTE_RE)
|
98
96
|
KV_SEP_RE = /"\s*=>\s*/.freeze
|
97
|
+
Sequel::Deprecation.deprecate_constant(self, :KV_SEP_RE)
|
99
98
|
NULL_RE = /NULL/.freeze
|
99
|
+
Sequel::Deprecation.deprecate_constant(self, :NULL_RE)
|
100
100
|
SEP_RE = /,\s*/.freeze
|
101
|
+
Sequel::Deprecation.deprecate_constant(self, :SEP_RE)
|
101
102
|
QUOTED_RE = /(\\"|[^"])*/.freeze
|
103
|
+
Sequel::Deprecation.deprecate_constant(self, :QUOTED_RE)
|
102
104
|
REPLACE_RE = /\\(.)/.freeze
|
105
|
+
Sequel::Deprecation.deprecate_constant(self, :REPLACE_RE)
|
103
106
|
REPLACE_WITH = '\1'.freeze
|
107
|
+
Sequel::Deprecation.deprecate_constant(self, :REPLACE_WITH)
|
104
108
|
|
105
109
|
# Parse the output format that PostgreSQL uses for hstore
|
106
110
|
# columns. Note that this does not attempt to parse all
|
@@ -114,17 +118,17 @@ module Sequel
|
|
114
118
|
return @result if @result
|
115
119
|
hash = {}
|
116
120
|
while !eos?
|
117
|
-
skip(
|
121
|
+
skip(/"/)
|
118
122
|
k = parse_quoted
|
119
|
-
skip(
|
120
|
-
if skip(
|
123
|
+
skip(/"\s*=>\s*/)
|
124
|
+
if skip(/"/)
|
121
125
|
v = parse_quoted
|
122
|
-
skip(
|
126
|
+
skip(/"/)
|
123
127
|
else
|
124
|
-
scan(
|
128
|
+
scan(/NULL/)
|
125
129
|
v = nil
|
126
130
|
end
|
127
|
-
skip(
|
131
|
+
skip(/,\s*/)
|
128
132
|
hash[k] = v
|
129
133
|
end
|
130
134
|
@result = hash
|
@@ -134,7 +138,7 @@ module Sequel
|
|
134
138
|
|
135
139
|
# Parse and unescape a quoted key/value.
|
136
140
|
def parse_quoted
|
137
|
-
scan(
|
141
|
+
scan(/(\\"|[^"])*/).gsub(/\\(.)/, '\1')
|
138
142
|
end
|
139
143
|
end
|
140
144
|
|
@@ -158,6 +162,13 @@ module Sequel
|
|
158
162
|
end
|
159
163
|
end
|
160
164
|
|
165
|
+
# SEQUEL5: Remove
|
166
|
+
def reset_conversion_procs
|
167
|
+
procs = super
|
168
|
+
add_named_conversion_proc(:hstore, &HStore.method(:parse))
|
169
|
+
procs
|
170
|
+
end
|
171
|
+
|
161
172
|
private
|
162
173
|
|
163
174
|
# Recognize the hstore database type.
|
@@ -188,12 +199,19 @@ module Sequel
|
|
188
199
|
DEFAULT_PROC = lambda{|h, k| h[k.to_s] unless k.is_a?(String)}
|
189
200
|
|
190
201
|
QUOTE = '"'.freeze
|
202
|
+
Sequel::Deprecation.deprecate_constant(self, :QUOTE)
|
191
203
|
COMMA = ",".freeze
|
204
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
192
205
|
KV_SEP = "=>".freeze
|
206
|
+
Sequel::Deprecation.deprecate_constant(self, :KV_SEP)
|
193
207
|
NULL = "NULL".freeze
|
208
|
+
Sequel::Deprecation.deprecate_constant(self, :NULL)
|
194
209
|
ESCAPE_RE = /("|\\)/.freeze
|
210
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_RE)
|
195
211
|
ESCAPE_REPLACE = '\\\\\1'.freeze
|
212
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_REPLACE)
|
196
213
|
HSTORE_CAST = '::hstore'.freeze
|
214
|
+
Sequel::Deprecation.deprecate_constant(self, :HSTORE_CAST)
|
197
215
|
|
198
216
|
if RUBY_VERSION >= '1.9'
|
199
217
|
# Undef 1.9 marshal_{dump,load} methods in the delegate class,
|
@@ -258,7 +276,7 @@ module Sequel
|
|
258
276
|
# Append a literalize version of the hstore to the sql.
|
259
277
|
def sql_literal_append(ds, sql)
|
260
278
|
ds.literal_append(sql, unquoted_literal)
|
261
|
-
sql <<
|
279
|
+
sql << '::hstore'
|
262
280
|
end
|
263
281
|
|
264
282
|
# Return a string containing the unquoted, unstring-escaped
|
@@ -267,10 +285,10 @@ module Sequel
|
|
267
285
|
def unquoted_literal
|
268
286
|
str = String.new
|
269
287
|
comma = false
|
270
|
-
commas =
|
271
|
-
quote =
|
272
|
-
kv_sep =
|
273
|
-
null = NULL
|
288
|
+
commas = ","
|
289
|
+
quote = '"'
|
290
|
+
kv_sep = "=>"
|
291
|
+
null = "NULL"
|
274
292
|
each do |k, v|
|
275
293
|
str << commas if comma
|
276
294
|
str << quote << escape_value(k) << quote
|
@@ -303,7 +321,7 @@ module Sequel
|
|
303
321
|
# Escape key/value strings when literalizing to
|
304
322
|
# correctly handle backslash and quote characters.
|
305
323
|
def escape_value(k)
|
306
|
-
k.to_s.gsub(
|
324
|
+
k.to_s.gsub(/("|\\)/, '\\\\\1')
|
307
325
|
end
|
308
326
|
end
|
309
327
|
end
|
@@ -29,7 +29,7 @@
|
|
29
29
|
# Related module: Sequel::Postgres::InetDatabaseMethods
|
30
30
|
|
31
31
|
require 'ipaddr'
|
32
|
-
Sequel.require 'adapters/
|
32
|
+
Sequel.require 'adapters/shared/postgres'
|
33
33
|
|
34
34
|
module Sequel
|
35
35
|
module Postgres
|
@@ -41,7 +41,14 @@ module Sequel
|
|
41
41
|
def self.extended(db)
|
42
42
|
db.instance_eval do
|
43
43
|
extend_datasets(InetDatasetMethods)
|
44
|
-
|
44
|
+
meth = IPAddr.method(:new)
|
45
|
+
add_conversion_proc(869, meth)
|
46
|
+
add_conversion_proc(650, meth)
|
47
|
+
if respond_to?(:register_array_type)
|
48
|
+
register_array_type('inet', :oid=>1041, :scalar_oid=>869)
|
49
|
+
register_array_type('cidr', :oid=>651, :scalar_oid=>650)
|
50
|
+
register_array_type('macaddr', :oid=>1040)
|
51
|
+
end
|
45
52
|
@schema_type_classes[:ipaddr] = IPAddr
|
46
53
|
end
|
47
54
|
end
|
@@ -106,11 +113,16 @@ module Sequel
|
|
106
113
|
end
|
107
114
|
end
|
108
115
|
|
109
|
-
|
116
|
+
# SEQUEL5: Remove
|
117
|
+
meth = IPAddr.method(:new)
|
118
|
+
PG__TYPES[869] = PG__TYPES[650] = lambda do |s|
|
119
|
+
Sequel::Deprecation.deprecate("Conversion proc for inet/cidr added globally by pg_inet extension", "Load the pg_inet extension into the Database instance")
|
120
|
+
IPAddr.new(s)
|
121
|
+
end
|
110
122
|
if defined?(PGArray) && PGArray.respond_to?(:register)
|
111
|
-
PGArray.register('inet', :oid=>1041, :scalar_oid=>869)
|
112
|
-
PGArray.register('cidr', :oid=>651, :scalar_oid=>650)
|
113
|
-
PGArray.register('macaddr', :oid=>1040)
|
123
|
+
PGArray.register('inet', :oid=>1041, :scalar_oid=>869, :skip_deprecation_warning=>true)
|
124
|
+
PGArray.register('cidr', :oid=>651, :scalar_oid=>650, :skip_deprecation_warning=>true)
|
125
|
+
PGArray.register('macaddr', :oid=>1040, :skip_deprecation_warning=>true)
|
114
126
|
end
|
115
127
|
end
|
116
128
|
|
@@ -10,10 +10,7 @@
|
|
10
10
|
# ActiveSupport::Duration that use the standard Sequel literalization
|
11
11
|
# callbacks, so they work on all adapters.
|
12
12
|
#
|
13
|
-
#
|
14
|
-
# probably want to modify the typecasting so that it
|
15
|
-
# recognizes and correctly handles the interval columns, which you can
|
16
|
-
# do by:
|
13
|
+
# To use this extension, load it into the Database instance:
|
17
14
|
#
|
18
15
|
# DB.extension :pg_interval
|
19
16
|
#
|
@@ -36,12 +33,13 @@
|
|
36
33
|
# Related module: Sequel::Postgres::IntervalDatabaseMethods
|
37
34
|
|
38
35
|
require 'active_support/duration'
|
39
|
-
Sequel.require 'adapters/
|
36
|
+
Sequel.require 'adapters/shared/postgres'
|
40
37
|
|
41
38
|
module Sequel
|
42
39
|
module Postgres
|
43
40
|
module IntervalDatabaseMethods
|
44
41
|
EMPTY_INTERVAL = '0'.freeze
|
42
|
+
Sequel::Deprecation.deprecate_constant(self, :EMPTY_INTERVAL)
|
45
43
|
DURATION_UNITS = [:years, :months, :weeks, :days, :hours, :minutes, :seconds].freeze
|
46
44
|
|
47
45
|
# Return an unquoted string version of the duration object suitable for
|
@@ -58,7 +56,7 @@ module Sequel
|
|
58
56
|
end
|
59
57
|
|
60
58
|
if s.empty?
|
61
|
-
|
59
|
+
'0'
|
62
60
|
else
|
63
61
|
s
|
64
62
|
end
|
@@ -67,11 +65,12 @@ module Sequel
|
|
67
65
|
# Creates callable objects that convert strings into ActiveSupport::Duration instances.
|
68
66
|
class Parser
|
69
67
|
# Regexp that parses the full range of PostgreSQL interval type output.
|
70
|
-
PARSER = /\A([+-]?\d+ years?\s?)?([+-]?\d+ mons?\s?)?([+-]?\d+ days?\s?)?(?:(?:([+-])?(\d{2,10}):(\d\d):(\d\d(\.\d+)?))|([+-]?\d+ hours?\s?)?([+-]?\d+ mins?\s?)?([+-]?\d+(\.\d+)? secs?\s?)?)?\z/
|
68
|
+
PARSER = /\A([+-]?\d+ years?\s?)?([+-]?\d+ mons?\s?)?([+-]?\d+ days?\s?)?(?:(?:([+-])?(\d{2,10}):(\d\d):(\d\d(\.\d+)?))|([+-]?\d+ hours?\s?)?([+-]?\d+ mins?\s?)?([+-]?\d+(\.\d+)? secs?\s?)?)?\z/
|
69
|
+
Sequel::Deprecation.deprecate_constant(self, :PARSER)
|
71
70
|
|
72
71
|
# Parse the interval input string into an ActiveSupport::Duration instance.
|
73
72
|
def call(string)
|
74
|
-
raise(InvalidValue, "invalid or unhandled interval format: #{string.inspect}") unless matches =
|
73
|
+
raise(InvalidValue, "invalid or unhandled interval format: #{string.inspect}") unless matches = /\A([+-]?\d+ years?\s?)?([+-]?\d+ mons?\s?)?([+-]?\d+ days?\s?)?(?:(?:([+-])?(\d{2,10}):(\d\d):(\d\d(\.\d+)?))|([+-]?\d+ hours?\s?)?([+-]?\d+ mins?\s?)?([+-]?\d+(\.\d+)? secs?\s?)?)?\z/.match(string)
|
75
74
|
|
76
75
|
value = 0
|
77
76
|
parts = []
|
@@ -124,7 +123,10 @@ module Sequel
|
|
124
123
|
def self.extended(db)
|
125
124
|
db.instance_eval do
|
126
125
|
extend_datasets(IntervalDatasetMethods)
|
127
|
-
|
126
|
+
add_conversion_proc(1186, Postgres::IntervalDatabaseMethods::PARSER)
|
127
|
+
if respond_to?(:register_array_type)
|
128
|
+
register_array_type('interval', :oid=>1187, :scalar_oid=>1186)
|
129
|
+
end
|
128
130
|
@schema_type_classes[:interval] = ActiveSupport::Duration
|
129
131
|
end
|
130
132
|
end
|
@@ -174,6 +176,7 @@ module Sequel
|
|
174
176
|
|
175
177
|
module IntervalDatasetMethods
|
176
178
|
CAST_INTERVAL = '::interval'.freeze
|
179
|
+
Sequel::Deprecation.deprecate_constant(self, :CAST_INTERVAL)
|
177
180
|
|
178
181
|
# Handle literalization of ActiveSupport::Duration objects, treating them as
|
179
182
|
# PostgreSQL intervals.
|
@@ -181,16 +184,20 @@ module Sequel
|
|
181
184
|
case v
|
182
185
|
when ActiveSupport::Duration
|
183
186
|
literal_append(sql, IntervalDatabaseMethods.literal_duration(v))
|
184
|
-
sql <<
|
187
|
+
sql << '::interval'
|
185
188
|
else
|
186
189
|
super
|
187
190
|
end
|
188
191
|
end
|
189
192
|
end
|
190
193
|
|
191
|
-
|
194
|
+
# SEQUEL5: Remove
|
195
|
+
PG__TYPES[1186] = lambda do |s|
|
196
|
+
Sequel::Deprecation.deprecate("Conversion proc for interval added globally by pg_interval extension", "Load the pg_interval extension into the Database instance")
|
197
|
+
Postgres::IntervalDatabaseMethods::PARSER.call(s)
|
198
|
+
end
|
192
199
|
if defined?(PGArray) && PGArray.respond_to?(:register)
|
193
|
-
PGArray.register('interval', :oid=>1187, :scalar_oid=>1186)
|
200
|
+
PGArray.register('interval', :oid=>1187, :scalar_oid=>1186, :skip_deprecation_warning=>true)
|
194
201
|
end
|
195
202
|
end
|
196
203
|
|
@@ -38,10 +38,7 @@
|
|
38
38
|
# DB[:table].insert(:column=>Sequel.pg_json([1, 2, 3]))
|
39
39
|
# DB[:table].insert(:column=>Sequel.pg_json({'a'=>1, 'b'=>2}))
|
40
40
|
#
|
41
|
-
#
|
42
|
-
# objects, you probably want to modify the schema parsing/typecasting
|
43
|
-
# so that it recognizes and correctly handles the json type, which
|
44
|
-
# you can do by:
|
41
|
+
# To use this extension, please load it into the Database instance:
|
45
42
|
#
|
46
43
|
# DB.extension :pg_json
|
47
44
|
#
|
@@ -65,12 +62,14 @@
|
|
65
62
|
|
66
63
|
require 'delegate'
|
67
64
|
require 'json'
|
68
|
-
Sequel.require 'adapters/
|
65
|
+
Sequel.require 'adapters/shared/postgres'
|
69
66
|
|
70
67
|
module Sequel
|
71
68
|
module Postgres
|
72
69
|
CAST_JSON = '::json'.freeze
|
70
|
+
Sequel::Deprecation.deprecate_constant(self, :CAST_JSON)
|
73
71
|
CAST_JSONB = '::jsonb'.freeze
|
72
|
+
Sequel::Deprecation.deprecate_constant(self, :CAST_JSONB)
|
74
73
|
|
75
74
|
# Class representing PostgreSQL JSON/JSONB column array values.
|
76
75
|
class JSONArrayBase < DelegateClass(Array)
|
@@ -88,7 +87,7 @@ module Sequel
|
|
88
87
|
# Cast as json
|
89
88
|
def sql_literal_append(ds, sql)
|
90
89
|
super
|
91
|
-
sql <<
|
90
|
+
sql << '::json'
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
@@ -96,7 +95,7 @@ module Sequel
|
|
96
95
|
# Cast as jsonb
|
97
96
|
def sql_literal_append(ds, sql)
|
98
97
|
super
|
99
|
-
sql <<
|
98
|
+
sql << '::jsonb'
|
100
99
|
end
|
101
100
|
end
|
102
101
|
|
@@ -119,7 +118,7 @@ module Sequel
|
|
119
118
|
# Cast as json
|
120
119
|
def sql_literal_append(ds, sql)
|
121
120
|
super
|
122
|
-
sql <<
|
121
|
+
sql << '::json'
|
123
122
|
end
|
124
123
|
end
|
125
124
|
|
@@ -127,7 +126,7 @@ module Sequel
|
|
127
126
|
# Cast as jsonb
|
128
127
|
def sql_literal_append(ds, sql)
|
129
128
|
super
|
130
|
-
sql <<
|
129
|
+
sql << '::jsonb'
|
131
130
|
end
|
132
131
|
end
|
133
132
|
|
@@ -135,7 +134,12 @@ module Sequel
|
|
135
134
|
module JSONDatabaseMethods
|
136
135
|
def self.extended(db)
|
137
136
|
db.instance_eval do
|
138
|
-
|
137
|
+
add_conversion_proc(114, JSONDatabaseMethods.method(:db_parse_json))
|
138
|
+
add_conversion_proc(3802, JSONDatabaseMethods.method(:db_parse_jsonb))
|
139
|
+
if respond_to?(:register_array_type)
|
140
|
+
register_array_type('json', :oid=>199, :scalar_oid=>114)
|
141
|
+
register_array_type('jsonb', :oid=>3807, :scalar_oid=>3802)
|
142
|
+
end
|
139
143
|
@schema_type_classes[:json] = [JSONHash, JSONArray]
|
140
144
|
@schema_type_classes[:jsonb] = [JSONBHash, JSONBArray]
|
141
145
|
end
|
@@ -257,11 +261,18 @@ module Sequel
|
|
257
261
|
end
|
258
262
|
end
|
259
263
|
|
260
|
-
|
261
|
-
|
264
|
+
# SEQUEL5: Remove
|
265
|
+
PG__TYPES[114] = lambda do |s|
|
266
|
+
Sequel::Deprecation.deprecate("Conversion proc for json added globally by pg_json extension", "Load the pg_json extension into the Database instance")
|
267
|
+
JSONDatabaseMethods.db_parse_json(s)
|
268
|
+
end
|
269
|
+
PG__TYPES[3802] = lambda do |s|
|
270
|
+
Sequel::Deprecation.deprecate("Conversion proc for jsonb added globally by pg_json extension", "Load the pg_json extension into the Database instance")
|
271
|
+
JSONDatabaseMethods.db_parse_jsonb(s)
|
272
|
+
end
|
262
273
|
if defined?(PGArray) && PGArray.respond_to?(:register)
|
263
|
-
PGArray.register('json', :oid=>199, :scalar_oid=>114)
|
264
|
-
PGArray.register('jsonb', :oid=>3807, :scalar_oid=>3802)
|
274
|
+
PGArray.register('json', :oid=>199, :scalar_oid=>114, :skip_deprecation_warning=>true)
|
275
|
+
PGArray.register('jsonb', :oid=>3807, :scalar_oid=>3802, :skip_deprecation_warning=>true)
|
265
276
|
end
|
266
277
|
end
|
267
278
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# The pg_json_ops extension adds support to Sequel's DSL to make
|
4
4
|
# it easier to call PostgreSQL JSON functions and operators (added
|
5
5
|
# first in PostgreSQL 9.3). It also supports the JSONB functions
|
6
|
-
# and operators added in PostgreSQL 9.4
|
6
|
+
# and operators added in PostgreSQL 9.4.
|
7
7
|
#
|
8
8
|
# To load the extension:
|
9
9
|
#
|
@@ -22,7 +22,7 @@
|
|
22
22
|
# jb = Sequel.pg_jsonb(:jsonb_column)
|
23
23
|
#
|
24
24
|
# Also, on most Sequel expression objects, you can call the pg_json
|
25
|
-
# or pg_jsonb
|
25
|
+
# or pg_jsonb method:
|
26
26
|
#
|
27
27
|
# j = Sequel[:json_column].pg_json
|
28
28
|
# jb = Sequel[:jsonb_column].pg_jsonb
|
@@ -40,10 +40,7 @@
|
|
40
40
|
# If you specify the range database type, Sequel will automatically cast
|
41
41
|
# the value to that type when literalizing.
|
42
42
|
#
|
43
|
-
#
|
44
|
-
# probably want to modify the schema parsing/typecasting so that it
|
45
|
-
# recognizes and correctly handles the range type columns, which you can
|
46
|
-
# do by:
|
43
|
+
# To use this extension, load it into the Database instance:
|
47
44
|
#
|
48
45
|
# DB.extension :pg_range
|
49
46
|
#
|
@@ -52,11 +49,10 @@
|
|
52
49
|
#
|
53
50
|
# This extension makes it easy to add support for other range types. In
|
54
51
|
# general, you just need to make sure that the subtype is handled and has the
|
55
|
-
# appropriate converter installed
|
56
|
-
# instance's conversion_procs usingthe appropriate type OID. For user defined
|
52
|
+
# appropriate converter installed. For user defined
|
57
53
|
# types, you can do this via:
|
58
54
|
#
|
59
|
-
# DB.
|
55
|
+
# DB.add_conversion_proc(subtype_oid){|string| }
|
60
56
|
#
|
61
57
|
# Then you can call
|
62
58
|
# Sequel::Postgres::PGRange::DatabaseMethods#register_range_type
|
@@ -66,18 +62,6 @@
|
|
66
62
|
#
|
67
63
|
# DB.register_range_type('timerange')
|
68
64
|
#
|
69
|
-
# You can also register range types on a global basis using
|
70
|
-
# Sequel::Postgres::PGRange.register. In this case, you'll have
|
71
|
-
# to specify the type oids:
|
72
|
-
#
|
73
|
-
# Sequel::Postgres::PG_TYPES[1234] = lambda{|string| }
|
74
|
-
# Sequel::Postgres::PGRange.register('foo', :oid=>4321, :subtype_oid=>1234)
|
75
|
-
#
|
76
|
-
# Both Sequel::Postgres::PGRange::DatabaseMethods#register_range_type
|
77
|
-
# and Sequel::Postgres::PGRange.register support many options to
|
78
|
-
# customize the range type handling. See the Sequel::Postgres::PGRange.register
|
79
|
-
# method documentation.
|
80
|
-
#
|
81
65
|
# This extension integrates with the pg_array extension. If you plan
|
82
66
|
# to use arrays of range types, load the pg_array extension before the
|
83
67
|
# pg_range extension:
|
@@ -86,54 +70,45 @@
|
|
86
70
|
#
|
87
71
|
# Related module: Sequel::Postgres::PGRange
|
88
72
|
|
89
|
-
Sequel.require 'adapters/
|
73
|
+
Sequel.require 'adapters/shared/postgres'
|
90
74
|
|
91
75
|
module Sequel
|
92
76
|
module Postgres
|
93
77
|
class PGRange
|
94
78
|
include Sequel::SQL::AliasMethods
|
95
79
|
|
96
|
-
#
|
97
|
-
# used in the schema parsing.
|
80
|
+
# SEQUEL5: Remove
|
98
81
|
RANGE_TYPES = {}
|
99
82
|
|
100
83
|
EMPTY = 'empty'.freeze
|
84
|
+
Sequel::Deprecation.deprecate_constant(self, :EMPTY)
|
101
85
|
EMPTY_STRING = ''.freeze
|
86
|
+
Sequel::Deprecation.deprecate_constant(self, :EMPTY_STRING)
|
102
87
|
COMMA = ','.freeze
|
88
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
103
89
|
QUOTED_EMPTY_STRING = '""'.freeze
|
90
|
+
Sequel::Deprecation.deprecate_constant(self, :QUOTED_EMPTY_STRING)
|
104
91
|
OPEN_PAREN = "(".freeze
|
92
|
+
Sequel::Deprecation.deprecate_constant(self, :OPEN_PAREN)
|
105
93
|
CLOSE_PAREN = ")".freeze
|
94
|
+
Sequel::Deprecation.deprecate_constant(self, :CLOSE_PAREN)
|
106
95
|
OPEN_BRACKET = "[".freeze
|
96
|
+
Sequel::Deprecation.deprecate_constant(self, :OPEN_BRACKET)
|
107
97
|
CLOSE_BRACKET = "]".freeze
|
98
|
+
Sequel::Deprecation.deprecate_constant(self, :CLOSE_BRACKET)
|
108
99
|
ESCAPE_RE = /("|,|\\|\[|\]|\(|\))/.freeze
|
100
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_RE)
|
109
101
|
ESCAPE_REPLACE = '\\\\\1'.freeze
|
102
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_REPLACE)
|
110
103
|
CAST = '::'.freeze
|
104
|
+
Sequel::Deprecation.deprecate_constant(self, :CAST)
|
111
105
|
|
112
|
-
#
|
113
|
-
# has been extended with DatabaseMethods recognize the range type given and set up the
|
114
|
-
# appropriate typecasting. Also sets up automatic typecasting for the native postgres
|
115
|
-
# adapter, so that on retrieval, the values are automatically converted to PGRange instances.
|
116
|
-
# The db_type argument should be the name of the range type. Accepts the following options:
|
117
|
-
#
|
118
|
-
# :converter :: A callable object (e.g. Proc), that is called with the start or end of the range
|
119
|
-
# (usually a string), and should return the appropriate typecasted object.
|
120
|
-
# :oid :: The PostgreSQL OID for the range type. This is used by the Sequel postgres adapter
|
121
|
-
# to set up automatic type conversion on retrieval from the database.
|
122
|
-
# :subtype_oid :: Should be the PostgreSQL OID for the range's subtype. If given,
|
123
|
-
# automatically sets the :converter option by looking for scalar conversion
|
124
|
-
# proc.
|
125
|
-
# :type_procs :: A hash mapping oids to conversion procs, used for setting the default :converter
|
126
|
-
# for :subtype_oid. Defaults to the global Sequel::Postgres::PG_TYPES.
|
127
|
-
# :typecast_method_map :: The map in which to place the database type string to type symbol mapping.
|
128
|
-
# Defaults to RANGE_TYPES.
|
129
|
-
# :typecast_methods_module :: If given, a module object to add the typecasting method to. Defaults
|
130
|
-
# to DatabaseMethods.
|
131
|
-
#
|
132
|
-
# If a block is given, it is treated as the :converter option.
|
106
|
+
# SEQUEL5: Remove
|
133
107
|
def self.register(db_type, opts=OPTS, &block)
|
108
|
+
Sequel::Deprecation.deprecate("Sequel::Postgres::PGRange.register", "Use Database#register_range_type on a Database instance using the pg_range extension") unless opts[:skip_deprecation_warning]
|
134
109
|
db_type = db_type.to_s.dup.freeze
|
135
110
|
|
136
|
-
type_procs = opts[:type_procs] ||
|
111
|
+
type_procs = opts[:type_procs] || PG__TYPES
|
137
112
|
mod = opts[:typecast_methods_module] || DatabaseMethods
|
138
113
|
typecast_method_map = opts[:typecast_method_map] || RANGE_TYPES
|
139
114
|
|
@@ -155,14 +130,19 @@ module Sequel
|
|
155
130
|
define_range_typecast_method(mod, db_type, parser)
|
156
131
|
|
157
132
|
if oid = opts[:oid]
|
133
|
+
if opts[:skip_deprecation_warning]
|
134
|
+
def parser.call(s)
|
135
|
+
Sequel::Deprecation.deprecate("Conversion proc for #{db_type} added globally by pg_range extension", "Load the pg_range extension into the Database instance")
|
136
|
+
super
|
137
|
+
end
|
138
|
+
end
|
158
139
|
type_procs[oid] = parser
|
159
140
|
end
|
160
141
|
|
161
142
|
nil
|
162
143
|
end
|
163
144
|
|
164
|
-
#
|
165
|
-
# the parser argument to do the type conversion.
|
145
|
+
# SEQUEL5: Remove
|
166
146
|
def self.define_range_typecast_method(mod, type, parser)
|
167
147
|
mod.class_eval do
|
168
148
|
meth = :"typecast_value_#{type}"
|
@@ -174,12 +154,12 @@ module Sequel
|
|
174
154
|
|
175
155
|
# Creates callable objects that convert strings into PGRange instances.
|
176
156
|
class Parser
|
177
|
-
|
178
|
-
|
179
|
-
PARSER = /\A(\[|\()("((?:\\"|[^"])*)"|[^"]*),("((?:\\"|[^"])*)"|[^"]*)(\]|\))\z/o
|
180
|
-
|
157
|
+
PARSER = /\A(\[|\()("((?:\\"|[^"])*)"|[^"]*),("((?:\\"|[^"])*)"|[^"]*)(\]|\))\z/
|
158
|
+
Sequel::Deprecation.deprecate_constant(self, :PARSER)
|
181
159
|
REPLACE_RE = /\\(.)/.freeze
|
160
|
+
Sequel::Deprecation.deprecate_constant(self, :REPLACE_RE)
|
182
161
|
REPLACE_WITH = '\1'.freeze
|
162
|
+
Sequel::Deprecation.deprecate_constant(self, :REPLACE_WITH)
|
183
163
|
|
184
164
|
# The database range type for this parser (e.g. 'int4range'),
|
185
165
|
# automatically setting the db_type for the returned PGRange instances.
|
@@ -197,11 +177,11 @@ module Sequel
|
|
197
177
|
|
198
178
|
# Parse the range type input string into a PGRange value.
|
199
179
|
def call(string)
|
200
|
-
if string ==
|
180
|
+
if string == 'empty'
|
201
181
|
return PGRange.empty(db_type)
|
202
182
|
end
|
203
183
|
|
204
|
-
raise(InvalidValue, "invalid or unhandled range format: #{string.inspect}") unless matches =
|
184
|
+
raise(InvalidValue, "invalid or unhandled range format: #{string.inspect}") unless matches = /\A(\[|\()("((?:\\"|[^"])*)"|[^"]*),("((?:\\"|[^"])*)"|[^"]*)(\]|\))\z/.match(string)
|
205
185
|
|
206
186
|
exclude_begin = matches[1] == '('
|
207
187
|
exclude_end = matches[6] == ')'
|
@@ -215,12 +195,12 @@ module Sequel
|
|
215
195
|
# to always use the quoted output form when characters need to be escaped, so
|
216
196
|
# there isn't a need to unescape unquoted output.
|
217
197
|
if beg = matches[3]
|
218
|
-
beg.gsub!(
|
198
|
+
beg.gsub!(/\\(.)/, '\1')
|
219
199
|
else
|
220
200
|
beg = matches[2] unless matches[2].empty?
|
221
201
|
end
|
222
202
|
if en = matches[5]
|
223
|
-
en.gsub!(
|
203
|
+
en.gsub!(/\\(.)/, '\1')
|
224
204
|
else
|
225
205
|
en = matches[4] unless matches[4].empty?
|
226
206
|
end
|
@@ -241,20 +221,32 @@ module Sequel
|
|
241
221
|
db.instance_eval do
|
242
222
|
@pg_range_schema_types ||= {}
|
243
223
|
extend_datasets(DatasetMethods)
|
244
|
-
|
224
|
+
register_range_type('int4range', :oid=>3904, :subtype_oid=>23)
|
225
|
+
register_range_type('numrange', :oid=>3906, :subtype_oid=>1700)
|
226
|
+
register_range_type('tsrange', :oid=>3908, :subtype_oid=>1114)
|
227
|
+
register_range_type('tstzrange', :oid=>3910, :subtype_oid=>1184)
|
228
|
+
register_range_type('daterange', :oid=>3912, :subtype_oid=>1082)
|
229
|
+
register_range_type('int8range', :oid=>3926, :subtype_oid=>20)
|
230
|
+
if respond_to?(:register_array_type)
|
231
|
+
register_array_type('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range)
|
232
|
+
register_array_type('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange)
|
233
|
+
register_array_type('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange)
|
234
|
+
register_array_type('tstzrange', :oid=>3911, :scalar_oid=>3910, :scalar_typecast=>:tstzrange)
|
235
|
+
register_array_type('daterange', :oid=>3913, :scalar_oid=>3912, :scalar_typecast=>:daterange)
|
236
|
+
register_array_type('int8range', :oid=>3927, :scalar_oid=>3926, :scalar_typecast=>:int8range)
|
237
|
+
end
|
245
238
|
[:int4range, :numrange, :tsrange, :tstzrange, :daterange, :int8range].each do |v|
|
246
239
|
@schema_type_classes[v] = PGRange
|
247
240
|
end
|
248
|
-
end
|
249
241
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
242
|
+
procs = conversion_procs
|
243
|
+
add_conversion_proc(3908, Parser.new("tsrange", procs[1114]))
|
244
|
+
add_conversion_proc(3910, Parser.new("tstzrange", procs[1184]))
|
245
|
+
if defined?(PGArray::Creator)
|
246
|
+
add_conversion_proc(3909, PGArray::Creator.new("tsrange", procs[3908]))
|
247
|
+
add_conversion_proc(3911, PGArray::Creator.new("tstzrange", procs[3910]))
|
248
|
+
end
|
256
249
|
end
|
257
|
-
|
258
250
|
end
|
259
251
|
|
260
252
|
# Handle Range and PGRange values in bound variables
|
@@ -276,20 +268,62 @@ module Sequel
|
|
276
268
|
end
|
277
269
|
|
278
270
|
# Register a database specific range type. This can be used to support
|
279
|
-
# different range types per Database.
|
280
|
-
#
|
281
|
-
#
|
271
|
+
# different range types per Database. Options:
|
272
|
+
#
|
273
|
+
# :converter :: A callable object (e.g. Proc), that is called with the start or end of the range
|
274
|
+
# (usually a string), and should return the appropriate typecasted object.
|
275
|
+
# :oid :: The PostgreSQL OID for the range type. This is used by the Sequel postgres adapter
|
276
|
+
# to set up automatic type conversion on retrieval from the database.
|
277
|
+
# :subtype_oid :: Should be the PostgreSQL OID for the range's subtype. If given,
|
278
|
+
# automatically sets the :converter option by looking for scalar conversion
|
279
|
+
# proc.
|
280
|
+
#
|
281
|
+
# If a block is given, it is treated as the :converter option.
|
282
282
|
def register_range_type(db_type, opts=OPTS, &block)
|
283
|
-
|
284
|
-
|
283
|
+
oid = opts[:oid]
|
284
|
+
soid = opts[:subtype_oid]
|
285
|
+
|
286
|
+
if has_converter = opts.has_key?(:converter)
|
287
|
+
raise Error, "can't provide both a block and :converter option to register_range_type" if block
|
288
|
+
converter = opts[:converter]
|
289
|
+
else
|
290
|
+
has_converter = true if block
|
291
|
+
converter = block
|
292
|
+
end
|
293
|
+
|
294
|
+
unless (soid || has_converter) && oid
|
285
295
|
range_oid, subtype_oid = from(:pg_range).join(:pg_type, :oid=>:rngtypid).where(:typname=>db_type.to_s).get([:rngtypid, :rngsubtype])
|
286
|
-
|
287
|
-
|
296
|
+
soid ||= subtype_oid unless has_converter
|
297
|
+
oid ||= range_oid
|
298
|
+
end
|
299
|
+
|
300
|
+
db_type = db_type.to_s.dup.freeze
|
301
|
+
|
302
|
+
if converter = opts[:converter]
|
303
|
+
raise Error, "can't provide both a block and :converter option to register" if block
|
304
|
+
else
|
305
|
+
converter = block
|
306
|
+
end
|
307
|
+
|
308
|
+
if soid
|
309
|
+
raise Error, "can't provide both a converter and :subtype_oid option to register" if has_converter
|
310
|
+
raise Error, "no conversion proc for :subtype_oid=>#{soid.inspect} in conversion_procs" unless converter = conversion_procs[soid]
|
311
|
+
end
|
312
|
+
|
313
|
+
parser = Parser.new(db_type, converter)
|
314
|
+
add_conversion_proc(oid, parser)
|
315
|
+
|
316
|
+
@pg_range_schema_types[db_type] = db_type.to_sym
|
317
|
+
|
318
|
+
(class << self; self end).class_eval do
|
319
|
+
meth = :"typecast_value_#{db_type}"
|
320
|
+
define_method(meth){|v| typecast_value_pg_range(v, parser)}
|
321
|
+
private meth
|
288
322
|
end
|
289
323
|
|
290
|
-
PGRange.register(db_type, opts, &block)
|
291
324
|
@schema_type_classes[:"#{opts[:type_symbol] || db_type}"] = PGRange
|
292
|
-
conversion_procs_updated
|
325
|
+
conversion_procs_updated # SEQUEL5: Remove
|
326
|
+
nil
|
293
327
|
end
|
294
328
|
|
295
329
|
private
|
@@ -304,9 +338,7 @@ module Sequel
|
|
304
338
|
end
|
305
339
|
end
|
306
340
|
|
307
|
-
#
|
308
|
-
# they use the database's timezone instead of the global Sequel
|
309
|
-
# timezone.
|
341
|
+
# SEQUEL5: Remove
|
310
342
|
def get_conversion_procs
|
311
343
|
procs = super
|
312
344
|
|
@@ -322,7 +354,7 @@ module Sequel
|
|
322
354
|
|
323
355
|
# Recognize the registered database range types.
|
324
356
|
def schema_column_type(db_type)
|
325
|
-
if type = @pg_range_schema_types[db_type] || RANGE_TYPES[db_type]
|
357
|
+
if type = @pg_range_schema_types[db_type] || RANGE_TYPES[db_type] # SEQUEL5: Remove || RANGE_TYPES[db_type]
|
326
358
|
type
|
327
359
|
else
|
328
360
|
super
|
@@ -490,17 +522,17 @@ module Sequel
|
|
490
522
|
# Append a literalize version of the receiver to the sql.
|
491
523
|
def sql_literal_append(ds, sql)
|
492
524
|
if (s = @db_type) && !empty?
|
493
|
-
sql << s.to_s <<
|
525
|
+
sql << s.to_s << "("
|
494
526
|
ds.literal_append(sql, self.begin)
|
495
|
-
sql <<
|
527
|
+
sql << ','
|
496
528
|
ds.literal_append(sql, self.end)
|
497
|
-
sql <<
|
498
|
-
ds.literal_append(sql, "#{exclude_begin? ?
|
499
|
-
sql <<
|
529
|
+
sql << ','
|
530
|
+
ds.literal_append(sql, "#{exclude_begin? ? "(" : "["}#{exclude_end? ? ")" : "]"}")
|
531
|
+
sql << ")"
|
500
532
|
else
|
501
533
|
ds.literal_append(sql, unquoted_literal(ds))
|
502
534
|
if s
|
503
|
-
sql <<
|
535
|
+
sql << '::' << s.to_s
|
504
536
|
end
|
505
537
|
end
|
506
538
|
end
|
@@ -536,9 +568,9 @@ module Sequel
|
|
536
568
|
# Separated out for use by the bound argument code.
|
537
569
|
def unquoted_literal(ds)
|
538
570
|
if empty?
|
539
|
-
|
571
|
+
'empty'
|
540
572
|
else
|
541
|
-
"#{exclude_begin? ?
|
573
|
+
"#{exclude_begin? ? "(" : "["}#{escape_value(self.begin, ds)},#{escape_value(self.end, ds)}#{exclude_end? ? ")" : "]"}"
|
542
574
|
end
|
543
575
|
end
|
544
576
|
|
@@ -549,7 +581,7 @@ module Sequel
|
|
549
581
|
def escape_value(k, ds)
|
550
582
|
case k
|
551
583
|
when nil
|
552
|
-
|
584
|
+
''
|
553
585
|
when Date, Time
|
554
586
|
ds.literal(k)[1...-1]
|
555
587
|
when Integer, Float
|
@@ -560,29 +592,30 @@ module Sequel
|
|
560
592
|
k
|
561
593
|
when String
|
562
594
|
if k.empty?
|
563
|
-
|
595
|
+
'""'
|
564
596
|
else
|
565
|
-
k.gsub(
|
597
|
+
k.gsub(/("|,|\\|\[|\]|\(|\))/, '\\\\\1')
|
566
598
|
end
|
567
599
|
else
|
568
|
-
ds.literal(k).gsub(
|
600
|
+
ds.literal(k).gsub(/("|,|\\|\[|\]|\(|\))/, '\\\\\1')
|
569
601
|
end
|
570
602
|
end
|
571
603
|
end
|
572
604
|
|
573
|
-
|
574
|
-
PGRange.register('
|
575
|
-
PGRange.register('
|
576
|
-
PGRange.register('
|
577
|
-
PGRange.register('
|
578
|
-
PGRange.register('
|
605
|
+
# SEQUEL5: Remove
|
606
|
+
PGRange.register('int4range', :oid=>3904, :subtype_oid=>23, :skip_deprecation_warning=>true)
|
607
|
+
PGRange.register('numrange', :oid=>3906, :subtype_oid=>1700, :skip_deprecation_warning=>true)
|
608
|
+
PGRange.register('tsrange', :oid=>3908, :subtype_oid=>1114, :skip_deprecation_warning=>true)
|
609
|
+
PGRange.register('tstzrange', :oid=>3910, :subtype_oid=>1184, :skip_deprecation_warning=>true)
|
610
|
+
PGRange.register('daterange', :oid=>3912, :subtype_oid=>1082, :skip_deprecation_warning=>true)
|
611
|
+
PGRange.register('int8range', :oid=>3926, :subtype_oid=>20, :skip_deprecation_warning=>true)
|
579
612
|
if defined?(PGArray) && PGArray.respond_to?(:register)
|
580
|
-
PGArray.register('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range)
|
581
|
-
PGArray.register('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange)
|
582
|
-
PGArray.register('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange)
|
583
|
-
PGArray.register('tstzrange', :oid=>3911, :scalar_oid=>3910, :scalar_typecast=>:tstzrange)
|
584
|
-
PGArray.register('daterange', :oid=>3913, :scalar_oid=>3912, :scalar_typecast=>:daterange)
|
585
|
-
PGArray.register('int8range', :oid=>3927, :scalar_oid=>3926, :scalar_typecast=>:int8range)
|
613
|
+
PGArray.register('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range, :skip_deprecation_warning=>true)
|
614
|
+
PGArray.register('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange, :skip_deprecation_warning=>true)
|
615
|
+
PGArray.register('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange, :skip_deprecation_warning=>true)
|
616
|
+
PGArray.register('tstzrange', :oid=>3911, :scalar_oid=>3910, :scalar_typecast=>:tstzrange, :skip_deprecation_warning=>true)
|
617
|
+
PGArray.register('daterange', :oid=>3913, :scalar_oid=>3912, :scalar_typecast=>:daterange, :skip_deprecation_warning=>true)
|
618
|
+
PGArray.register('int8range', :oid=>3927, :scalar_oid=>3926, :scalar_typecast=>:int8range, :skip_deprecation_warning=>true)
|
586
619
|
end
|
587
620
|
end
|
588
621
|
|