sequel 5.34.0 → 5.39.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +82 -0
- data/README.rdoc +2 -2
- data/doc/association_basics.rdoc +7 -2
- data/doc/cheat_sheet.rdoc +5 -5
- data/doc/code_order.rdoc +0 -12
- data/doc/dataset_filtering.rdoc +2 -2
- data/doc/fork_safety.rdoc +84 -0
- data/doc/model_plugins.rdoc +1 -1
- data/doc/opening_databases.rdoc +5 -1
- data/doc/postgresql.rdoc +1 -1
- data/doc/querying.rdoc +3 -3
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.38.0.txt +28 -0
- data/doc/release_notes/5.39.0.txt +19 -0
- data/doc/transactions.rdoc +0 -8
- data/doc/validations.rdoc +1 -1
- data/lib/sequel/adapters/jdbc.rb +13 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +4 -4
- data/lib/sequel/adapters/odbc.rb +4 -6
- data/lib/sequel/adapters/oracle.rb +2 -1
- data/lib/sequel/adapters/shared/mssql.rb +35 -5
- data/lib/sequel/adapters/shared/oracle.rb +13 -7
- data/lib/sequel/adapters/shared/postgres.rb +40 -2
- data/lib/sequel/adapters/shared/sqlite.rb +8 -2
- data/lib/sequel/adapters/tinytds.rb +1 -0
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
- data/lib/sequel/core.rb +5 -6
- data/lib/sequel/database/connecting.rb +0 -1
- data/lib/sequel/database/misc.rb +14 -0
- data/lib/sequel/database/schema_generator.rb +6 -0
- data/lib/sequel/database/schema_methods.rb +16 -6
- data/lib/sequel/database/transactions.rb +2 -2
- data/lib/sequel/dataset/actions.rb +10 -6
- data/lib/sequel/dataset/query.rb +1 -1
- data/lib/sequel/deprecated.rb +1 -1
- data/lib/sequel/extensions/_pretty_table.rb +1 -2
- data/lib/sequel/extensions/columns_introspection.rb +1 -2
- data/lib/sequel/extensions/core_refinements.rb +2 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
- data/lib/sequel/extensions/migration.rb +8 -2
- data/lib/sequel/extensions/pg_array_ops.rb +4 -0
- data/lib/sequel/extensions/pg_enum.rb +2 -0
- data/lib/sequel/extensions/pg_extended_date_support.rb +1 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
- data/lib/sequel/extensions/pg_inet.rb +2 -0
- data/lib/sequel/extensions/pg_json_ops.rb +46 -2
- data/lib/sequel/extensions/pg_range.rb +3 -7
- data/lib/sequel/extensions/pg_range_ops.rb +2 -0
- data/lib/sequel/extensions/pg_row.rb +0 -1
- data/lib/sequel/extensions/pg_row_ops.rb +24 -0
- data/lib/sequel/extensions/query.rb +1 -0
- data/lib/sequel/extensions/run_transaction_hooks.rb +1 -1
- data/lib/sequel/extensions/s.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +3 -3
- data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
- data/lib/sequel/extensions/to_dot.rb +9 -3
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/associations.rb +24 -7
- data/lib/sequel/model/base.rb +9 -3
- data/lib/sequel/model/plugins.rb +1 -0
- data/lib/sequel/plugins/association_pks.rb +3 -2
- data/lib/sequel/plugins/association_proxies.rb +1 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -2
- data/lib/sequel/plugins/class_table_inheritance.rb +3 -8
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/dirty.rb +44 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +2 -0
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/pg_array_associations.rb +2 -3
- data/lib/sequel/plugins/prepared_statements.rb +5 -11
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
- data/lib/sequel/plugins/rcte_tree.rb +8 -14
- data/lib/sequel/plugins/single_table_inheritance.rb +7 -0
- data/lib/sequel/plugins/string_stripper.rb +1 -1
- data/lib/sequel/plugins/tree.rb +9 -4
- data/lib/sequel/plugins/validation_class_methods.rb +5 -1
- data/lib/sequel/timezones.rb +8 -3
- data/lib/sequel/version.rb +1 -1
- metadata +16 -3
@@ -143,8 +143,14 @@ module Sequel
|
|
143
143
|
# :identity :: Create an identity column.
|
144
144
|
#
|
145
145
|
# MySQL specific options:
|
146
|
+
#
|
146
147
|
# :generated_type :: Set the type of column when using :generated_always_as,
|
147
148
|
# should be :virtual or :stored to force a type.
|
149
|
+
#
|
150
|
+
# Microsoft SQL Server specific options:
|
151
|
+
#
|
152
|
+
# :clustered :: When using :primary_key or :unique, marks the primary key or unique
|
153
|
+
# constraint as CLUSTERED (if true), or NONCLUSTERED (if false).
|
148
154
|
def column(name, type, opts = OPTS)
|
149
155
|
columns << {:name => name, :type => type}.merge!(opts)
|
150
156
|
if index_opts = opts[:index]
|
@@ -240,7 +240,7 @@ module Sequel
|
|
240
240
|
if supports_create_or_replace_view?
|
241
241
|
options = options.merge(:replace=>true)
|
242
242
|
else
|
243
|
-
drop_view(name)
|
243
|
+
swallow_database_error{drop_view(name)}
|
244
244
|
end
|
245
245
|
|
246
246
|
create_view(name, source, options)
|
@@ -580,14 +580,14 @@ module Sequel
|
|
580
580
|
sql << ' NULL'
|
581
581
|
end
|
582
582
|
end
|
583
|
-
|
583
|
+
|
584
584
|
# Add primary key SQL fragment to column creation SQL.
|
585
585
|
def column_definition_primary_key_sql(sql, column)
|
586
586
|
if column[:primary_key]
|
587
587
|
if name = column[:primary_key_constraint_name]
|
588
588
|
sql << " CONSTRAINT #{quote_identifier(name)}"
|
589
589
|
end
|
590
|
-
sql <<
|
590
|
+
sql << " " << primary_key_constraint_sql_fragment(column)
|
591
591
|
constraint_deferrable_sql_append(sql, column[:primary_key_deferrable])
|
592
592
|
end
|
593
593
|
end
|
@@ -608,7 +608,7 @@ module Sequel
|
|
608
608
|
if name = column[:unique_constraint_name]
|
609
609
|
sql << " CONSTRAINT #{quote_identifier(name)}"
|
610
610
|
end
|
611
|
-
sql << '
|
611
|
+
sql << ' ' << unique_constraint_sql_fragment(column)
|
612
612
|
constraint_deferrable_sql_append(sql, column[:unique_deferrable])
|
613
613
|
end
|
614
614
|
end
|
@@ -656,11 +656,11 @@ module Sequel
|
|
656
656
|
check = "(#{check})" unless check[0..0] == '(' && check[-1..-1] == ')'
|
657
657
|
sql << "CHECK #{check}"
|
658
658
|
when :primary_key
|
659
|
-
sql << "
|
659
|
+
sql << "#{primary_key_constraint_sql_fragment(constraint)} #{literal(constraint[:columns])}"
|
660
660
|
when :foreign_key
|
661
661
|
sql << column_references_table_constraint_sql(constraint.merge(:deferrable=>nil))
|
662
662
|
when :unique
|
663
|
-
sql << "
|
663
|
+
sql << "#{unique_constraint_sql_fragment(constraint)} #{literal(constraint[:columns])}"
|
664
664
|
else
|
665
665
|
raise Error, "Invalid constraint type #{constraint[:type]}, should be :check, :primary_key, :foreign_key, or :unique"
|
666
666
|
end
|
@@ -892,6 +892,11 @@ module Sequel
|
|
892
892
|
on_delete_clause(action)
|
893
893
|
end
|
894
894
|
|
895
|
+
# Add fragment for primary key specification, separated for easier overridding.
|
896
|
+
def primary_key_constraint_sql_fragment(_)
|
897
|
+
'PRIMARY KEY'
|
898
|
+
end
|
899
|
+
|
895
900
|
# Proxy the quote_schema_table method to the dataset
|
896
901
|
def quote_schema_table(table)
|
897
902
|
schema_utility_dataset.quote_schema_table(table)
|
@@ -1047,6 +1052,11 @@ module Sequel
|
|
1047
1052
|
"#{type}#{literal(Array(elements)) if elements}#{' UNSIGNED' if column[:unsigned]}"
|
1048
1053
|
end
|
1049
1054
|
|
1055
|
+
# Add fragment for unique specification, separated for easier overridding.
|
1056
|
+
def unique_constraint_sql_fragment(_)
|
1057
|
+
'UNIQUE'
|
1058
|
+
end
|
1059
|
+
|
1050
1060
|
# Whether clob should be used for String text: true columns.
|
1051
1061
|
def uses_clob_for_text?
|
1052
1062
|
false
|
@@ -82,7 +82,7 @@ module Sequel
|
|
82
82
|
# :server :: The server/shard the transaction is being executed on.
|
83
83
|
def rollback_on_exit(opts=OPTS)
|
84
84
|
synchronize(opts[:server]) do |conn|
|
85
|
-
raise Error, "Cannot call Sequel:: Database#rollback_on_exit
|
85
|
+
raise Error, "Cannot call Sequel:: Database#rollback_on_exit unless inside a transaction" unless h = _trans(conn)
|
86
86
|
rollback = !opts[:cancel]
|
87
87
|
|
88
88
|
if supports_savepoints?
|
@@ -154,7 +154,7 @@ module Sequel
|
|
154
154
|
# Note that this should not be used unless the entire transaction
|
155
155
|
# block is idempotent, as otherwise it can cause non-idempotent
|
156
156
|
# behavior to execute multiple times.
|
157
|
-
# :rollback :: Can
|
157
|
+
# :rollback :: Can be set to :reraise to reraise any Sequel::Rollback exceptions
|
158
158
|
# raised, or :always to always rollback even if no exceptions occur
|
159
159
|
# (useful for testing).
|
160
160
|
# :server :: The server to use for the transaction. Set to :default, :read_only, or
|
@@ -607,14 +607,16 @@ module Sequel
|
|
607
607
|
# as_hash, it accepts an optional :hash parameter, into which entries will
|
608
608
|
# be merged.
|
609
609
|
#
|
610
|
-
# DB[:table].select_hash(:id, :name)
|
610
|
+
# DB[:table].select_hash(:id, :name)
|
611
|
+
# # SELECT id, name FROM table
|
611
612
|
# # => {1=>'a', 2=>'b', ...}
|
612
613
|
#
|
613
614
|
# You can also provide an array of column names for either the key_column,
|
614
615
|
# the value column, or both:
|
615
616
|
#
|
616
|
-
# DB[:table].select_hash([:id, :foo], [:name, :bar])
|
617
|
-
# #
|
617
|
+
# DB[:table].select_hash([:id, :foo], [:name, :bar])
|
618
|
+
# # SELECT id, foo, name, bar FROM table
|
619
|
+
# # => {[1, 3]=>['a', 'c'], [2, 4]=>['b', 'd'], ...}
|
618
620
|
#
|
619
621
|
# When using this method, you must be sure that each expression has an alias
|
620
622
|
# that Sequel can determine.
|
@@ -626,14 +628,16 @@ module Sequel
|
|
626
628
|
# Similar to to_hash_groups, but only selects the columns given. Like to_hash_groups,
|
627
629
|
# it accepts an optional :hash parameter, into which entries will be merged.
|
628
630
|
#
|
629
|
-
# DB[:table].select_hash_groups(:name, :id)
|
631
|
+
# DB[:table].select_hash_groups(:name, :id)
|
632
|
+
# # SELECT id, name FROM table
|
630
633
|
# # => {'a'=>[1, 4, ...], 'b'=>[2, ...], ...}
|
631
634
|
#
|
632
635
|
# You can also provide an array of column names for either the key_column,
|
633
636
|
# the value column, or both:
|
634
637
|
#
|
635
|
-
# DB[:table].select_hash_groups([:first, :middle], [:last, :id])
|
636
|
-
# #
|
638
|
+
# DB[:table].select_hash_groups([:first, :middle], [:last, :id])
|
639
|
+
# # SELECT first, middle, last, id FROM table
|
640
|
+
# # => {['a', 'b']=>[['c', 1], ['d', 2], ...], ...}
|
637
641
|
#
|
638
642
|
# When using this method, you must be sure that each expression has an alias
|
639
643
|
# that Sequel can determine.
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -81,7 +81,7 @@ module Sequel
|
|
81
81
|
# If the options changed include options in COLUMN_CHANGE_OPTS, the cached
|
82
82
|
# columns are deleted. This method should generally not be called
|
83
83
|
# directly by user code.
|
84
|
-
def clone(opts = (return self
|
84
|
+
def clone(opts = nil || (return self))
|
85
85
|
# return self used above because clone is called by almost all
|
86
86
|
# other query methods, and it is the fastest approach
|
87
87
|
c = super(:freeze=>false)
|
data/lib/sequel/deprecated.rb
CHANGED
@@ -39,7 +39,7 @@ module Sequel
|
|
39
39
|
# Print the message and possibly backtrace to the output.
|
40
40
|
def self.deprecate(method, instead=nil)
|
41
41
|
return unless output
|
42
|
-
message = instead ? "#{method} is deprecated and will be removed in Sequel
|
42
|
+
message = instead ? "#{method} is deprecated and will be removed in Sequel 6. #{instead}." : method
|
43
43
|
message = "#{prefix}#{message}" if prefix
|
44
44
|
output.puts(message)
|
45
45
|
case b = backtrace_filter
|
@@ -75,8 +75,7 @@ module Sequel
|
|
75
75
|
when SQL::Identifier
|
76
76
|
c.value.to_sym
|
77
77
|
when SQL::QualifiedIdentifier
|
78
|
-
|
79
|
-
col.is_a?(SQL::Identifier) ? col.value.to_sym : col.to_sym
|
78
|
+
c.column.to_sym
|
80
79
|
when SQL::AliasedExpression
|
81
80
|
a = c.alias
|
82
81
|
a.is_a?(SQL::Identifier) ? a.value.to_sym : a.to_sym
|
@@ -39,7 +39,9 @@
|
|
39
39
|
|
40
40
|
module Sequel
|
41
41
|
module DuplicateColumnsHandler
|
42
|
+
# :nocov:
|
42
43
|
CALLER_ARGS = (RUBY_VERSION >= '2.0' ? [0,1] : [0]).freeze
|
44
|
+
# :nocov:
|
43
45
|
|
44
46
|
# Customize handling of duplicate columns for this dataset.
|
45
47
|
def on_duplicate_columns(handler = (raise Error, "Must provide either an argument or a block to on_duplicate_columns" unless block_given?; nil), &block)
|
@@ -68,6 +68,7 @@ module Sequel
|
|
68
68
|
# Allow calling private methods for backwards compatibility
|
69
69
|
@db.send(method_sym, *args, &block)
|
70
70
|
end
|
71
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
71
72
|
|
72
73
|
# This object responds to all methods the database responds to.
|
73
74
|
def respond_to_missing?(meth, include_private)
|
@@ -329,7 +330,8 @@ module Sequel
|
|
329
330
|
# schema_migrations for timestamped migrations). in the database to keep track
|
330
331
|
# of the current migration version. If no migration version is stored in the
|
331
332
|
# database, the version is considered to be 0. If no target version is
|
332
|
-
# specified, the
|
333
|
+
# specified, or the target version specified is greater than the latest
|
334
|
+
# version available, the database is migrated to the latest version available in the
|
333
335
|
# migration directory.
|
334
336
|
#
|
335
337
|
# For example, to migrate the database to the latest version:
|
@@ -518,7 +520,6 @@ module Sequel
|
|
518
520
|
def initialize(db, directory, opts=OPTS)
|
519
521
|
super
|
520
522
|
@current = opts[:current] || current_migration_version
|
521
|
-
raise(Error, "No current version available") unless current
|
522
523
|
|
523
524
|
latest_version = latest_migration_version
|
524
525
|
@target = if opts[:target]
|
@@ -538,6 +539,11 @@ module Sequel
|
|
538
539
|
end
|
539
540
|
|
540
541
|
@direction = current < target ? :up : :down
|
542
|
+
|
543
|
+
if @direction == :down && @current >= @files.length
|
544
|
+
raise Migrator::Error, "Missing migration version(s) needed to migrate down to target version (current: #{current}, target: #{target})"
|
545
|
+
end
|
546
|
+
|
541
547
|
@migrations = get_migrations
|
542
548
|
end
|
543
549
|
|
@@ -157,7 +157,9 @@ module Sequel
|
|
157
157
|
else
|
158
158
|
Sequel.function(:hstore, self, wrap_array(arg))
|
159
159
|
end
|
160
|
+
# :nocov:
|
160
161
|
if Sequel.respond_to?(:hstore_op)
|
162
|
+
# :nocov:
|
161
163
|
v = Sequel.hstore_op(v)
|
162
164
|
end
|
163
165
|
v
|
@@ -283,7 +285,9 @@ module Sequel
|
|
283
285
|
end
|
284
286
|
end
|
285
287
|
|
288
|
+
# :nocov:
|
286
289
|
if defined?(PGArray)
|
290
|
+
# :nocov:
|
287
291
|
class PGArray
|
288
292
|
# Wrap the PGArray instance in an ArrayOp, allowing you to easily use
|
289
293
|
# the PostgreSQL array functions and operators with literal arrays.
|
@@ -189,7 +189,7 @@ module Sequel
|
|
189
189
|
if date < DATETIME_YEAR_1
|
190
190
|
date <<= ((date.year) * 24 - 12)
|
191
191
|
date = db.from_application_timestamp(date)
|
192
|
-
minutes = (date.
|
192
|
+
minutes = (date.offset * 1440).to_i
|
193
193
|
date.strftime("'%Y-%m-%d %H:%M:%S.%N#{format_timestamp_offset(*minutes.divmod(60))} BC'")
|
194
194
|
else
|
195
195
|
super
|
@@ -41,7 +41,9 @@ module Sequel
|
|
41
41
|
db.instance_exec do
|
42
42
|
extend_datasets(InetDatasetMethods)
|
43
43
|
|
44
|
+
# :nocov:
|
44
45
|
if !defined?(SEQUEL_PG_VERSION_INTEGER) || SEQUEL_PG_VERSION_INTEGER >= 11300
|
46
|
+
# :nocov:
|
45
47
|
# sequel_pg 1.13.0+ will use inet/cidr conversion procs, but doing so is
|
46
48
|
# slower, so don't add the conversion procs if using sequel_pg 1.13.0+.
|
47
49
|
meth = IPAddr.method(:new)
|
@@ -73,7 +73,10 @@
|
|
73
73
|
# j.pretty # jsonb_pretty(jsonb_column)
|
74
74
|
# j.set(%w'0 a', :h) # jsonb_set(jsonb_column, ARRAY['0','a'], h, true)
|
75
75
|
#
|
76
|
-
#
|
76
|
+
# j.set_lax(%w'0 a', :h, false, 'raise_exception')
|
77
|
+
# # jsonb_set_lax(jsonb_column, ARRAY['0','a'], h, false, 'raise_exception')
|
78
|
+
#
|
79
|
+
# On PostgreSQL 12+ SQL/JSON path functions and operators are supported:
|
77
80
|
#
|
78
81
|
# j.path_exists('$.foo') # (jsonb_column @? '$.foo')
|
79
82
|
# j.path_match('$.foo') # (jsonb_column @@ '$.foo')
|
@@ -84,7 +87,15 @@
|
|
84
87
|
# j.path_query_array('$.foo') # jsonb_path_query_array(jsonb_column, '$.foo')
|
85
88
|
# j.path_query_first('$.foo') # jsonb_path_query_first(jsonb_column, '$.foo')
|
86
89
|
#
|
87
|
-
#
|
90
|
+
# On PostgreSQL 13+ timezone-aware SQL/JSON path functions and operators are supported:
|
91
|
+
#
|
92
|
+
# j.path_exists_tz!('$.foo') # jsonb_path_exists_tz(jsonb_column, '$.foo')
|
93
|
+
# j.path_match_tz!('$.foo') # jsonb_path_match_tz(jsonb_column, '$.foo')
|
94
|
+
# j.path_query_tz('$.foo') # jsonb_path_query_tz(jsonb_column, '$.foo')
|
95
|
+
# j.path_query_array_tz('$.foo') # jsonb_path_query_array_tz(jsonb_column, '$.foo')
|
96
|
+
# j.path_query_first_tz('$.foo') # jsonb_path_query_first_tz(jsonb_column, '$.foo')
|
97
|
+
#
|
98
|
+
# For the PostgreSQL 12+ SQL/JSON path functions, one argument is required (+path+) and
|
88
99
|
# two more arguments are optional (+vars+ and +silent+). +path+ specifies the JSON path.
|
89
100
|
# +vars+ specifies a hash or a string in JSON format of named variables to be
|
90
101
|
# substituted in +path+. +silent+ specifies whether errors are suppressed. By default,
|
@@ -402,6 +413,11 @@ module Sequel
|
|
402
413
|
Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_exists, path, vars, silent))
|
403
414
|
end
|
404
415
|
|
416
|
+
# The same as #path_exists!, except that timezone-aware conversions are used for date/time values.
|
417
|
+
def path_exists_tz!(path, vars=nil, silent=nil)
|
418
|
+
Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_exists_tz, path, vars, silent))
|
419
|
+
end
|
420
|
+
|
405
421
|
# Returns the first item of the result of JSON path predicate check for the json object.
|
406
422
|
# Returns nil if the first item is not true or false.
|
407
423
|
#
|
@@ -425,6 +441,11 @@ module Sequel
|
|
425
441
|
Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_match, path, vars, silent))
|
426
442
|
end
|
427
443
|
|
444
|
+
# The same as #path_match!, except that timezone-aware conversions are used for date/time values.
|
445
|
+
def path_match_tz!(path, vars=nil, silent=nil)
|
446
|
+
Sequel::SQL::BooleanExpression.new(:NOOP, _path_function(:jsonb_path_match_tz, path, vars, silent))
|
447
|
+
end
|
448
|
+
|
428
449
|
# Returns a set of all jsonb values specified by the JSON path
|
429
450
|
# for the json object.
|
430
451
|
#
|
@@ -440,6 +461,11 @@ module Sequel
|
|
440
461
|
_path_function(:jsonb_path_query, path, vars, silent)
|
441
462
|
end
|
442
463
|
|
464
|
+
# The same as #path_query, except that timezone-aware conversions are used for date/time values.
|
465
|
+
def path_query_tz(path, vars=nil, silent=nil)
|
466
|
+
_path_function(:jsonb_path_query_tz, path, vars, silent)
|
467
|
+
end
|
468
|
+
|
443
469
|
# Returns a jsonb array of all values specified by the JSON path
|
444
470
|
# for the json object.
|
445
471
|
#
|
@@ -455,6 +481,11 @@ module Sequel
|
|
455
481
|
JSONBOp.new(_path_function(:jsonb_path_query_array, path, vars, silent))
|
456
482
|
end
|
457
483
|
|
484
|
+
# The same as #path_query_array, except that timezone-aware conversions are used for date/time values.
|
485
|
+
def path_query_array_tz(path, vars=nil, silent=nil)
|
486
|
+
JSONBOp.new(_path_function(:jsonb_path_query_array_tz, path, vars, silent))
|
487
|
+
end
|
488
|
+
|
458
489
|
# Returns the first item of the result specified by the JSON path
|
459
490
|
# for the json object.
|
460
491
|
#
|
@@ -470,6 +501,11 @@ module Sequel
|
|
470
501
|
JSONBOp.new(_path_function(:jsonb_path_query_first, path, vars, silent))
|
471
502
|
end
|
472
503
|
|
504
|
+
# The same as #path_query_first, except that timezone-aware conversions are used for date/time values.
|
505
|
+
def path_query_first_tz(path, vars=nil, silent=nil)
|
506
|
+
JSONBOp.new(_path_function(:jsonb_path_query_first_tz, path, vars, silent))
|
507
|
+
end
|
508
|
+
|
473
509
|
# Return the receiver, since it is already a JSONBOp.
|
474
510
|
def pg_jsonb
|
475
511
|
self
|
@@ -492,6 +528,12 @@ module Sequel
|
|
492
528
|
self.class.new(function(:set, wrap_input_array(path), wrap_input_jsonb(other), create_missing))
|
493
529
|
end
|
494
530
|
|
531
|
+
# The same as #set, except if +other+ is +nil+, then behaves according to +null_value_treatment+,
|
532
|
+
# which can be one of 'raise_exception', 'use_json_null' (default), 'delete_key', or 'return_target'.
|
533
|
+
def set_lax(path, other, create_missing=true, null_value_treatment='use_json_null')
|
534
|
+
self.class.new(function(:set_lax, wrap_input_array(path), wrap_input_jsonb(other), create_missing, null_value_treatment))
|
535
|
+
end
|
536
|
+
|
495
537
|
private
|
496
538
|
|
497
539
|
# Internals of the jsonb SQL/JSON path functions.
|
@@ -554,7 +596,9 @@ module Sequel
|
|
554
596
|
end
|
555
597
|
end
|
556
598
|
|
599
|
+
# :nocov:
|
557
600
|
if defined?(JSONArray)
|
601
|
+
# :nocov:
|
558
602
|
class JSONArray
|
559
603
|
# Wrap the JSONArray instance in an JSONOp, allowing you to easily use
|
560
604
|
# the PostgreSQL json functions and operators with literal jsons.
|
@@ -158,7 +158,7 @@ module Sequel
|
|
158
158
|
procs = conversion_procs
|
159
159
|
add_conversion_proc(3908, Parser.new("tsrange", procs[1114]))
|
160
160
|
add_conversion_proc(3910, Parser.new("tstzrange", procs[1184]))
|
161
|
-
if defined?(PGArray::Creator)
|
161
|
+
if respond_to?(:register_array_type) && defined?(PGArray::Creator)
|
162
162
|
add_conversion_proc(3909, PGArray::Creator.new("tsrange", procs[3908]))
|
163
163
|
add_conversion_proc(3911, PGArray::Creator.new("tstzrange", procs[3910]))
|
164
164
|
end
|
@@ -215,12 +215,6 @@ module Sequel
|
|
215
215
|
|
216
216
|
db_type = db_type.to_s.dup.freeze
|
217
217
|
|
218
|
-
if converter = opts[:converter]
|
219
|
-
raise Error, "can't provide both a block and :converter option to register" if block
|
220
|
-
else
|
221
|
-
converter = block
|
222
|
-
end
|
223
|
-
|
224
218
|
if soid
|
225
219
|
raise Error, "can't provide both a converter and :subtype_oid option to register" if has_converter
|
226
220
|
raise Error, "no conversion proc for :subtype_oid=>#{soid.inspect} in conversion_procs" unless converter = conversion_procs[soid]
|
@@ -471,8 +465,10 @@ module Sequel
|
|
471
465
|
return @range if @range
|
472
466
|
raise(Error, "cannot create ruby range for an empty PostgreSQL range") if empty?
|
473
467
|
raise(Error, "cannot create ruby range when PostgreSQL range excludes beginning element") if exclude_begin?
|
468
|
+
# :nocov:
|
474
469
|
raise(Error, "cannot create ruby range when PostgreSQL range has unbounded beginning") if STARTLESS_RANGE_NOT_SUPPORTED && !self.begin
|
475
470
|
raise(Error, "cannot create ruby range when PostgreSQL range has unbounded ending") if ENDLESS_RANGE_NOT_SUPPORTED && !self.end
|
471
|
+
# :nocov:
|
476
472
|
@range = Range.new(self.begin, self.end, exclude_end?)
|
477
473
|
end
|
478
474
|
|