sequel 5.32.0 → 5.37.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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +84 -0
  3. data/README.rdoc +1 -1
  4. data/doc/association_basics.rdoc +7 -2
  5. data/doc/dataset_filtering.rdoc +2 -2
  6. data/doc/model_plugins.rdoc +1 -1
  7. data/doc/release_notes/5.33.0.txt +24 -0
  8. data/doc/release_notes/5.34.0.txt +40 -0
  9. data/doc/release_notes/5.35.0.txt +56 -0
  10. data/doc/release_notes/5.36.0.txt +60 -0
  11. data/doc/release_notes/5.37.0.txt +30 -0
  12. data/doc/transactions.rdoc +0 -8
  13. data/doc/validations.rdoc +1 -1
  14. data/lib/sequel/adapters/odbc.rb +4 -6
  15. data/lib/sequel/adapters/oracle.rb +2 -1
  16. data/lib/sequel/adapters/shared/mssql.rb +14 -4
  17. data/lib/sequel/adapters/shared/oracle.rb +12 -6
  18. data/lib/sequel/adapters/shared/postgres.rb +39 -1
  19. data/lib/sequel/adapters/shared/sqlite.rb +13 -3
  20. data/lib/sequel/adapters/tinytds.rb +1 -0
  21. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
  22. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  23. data/lib/sequel/connection_pool/sharded_threaded.rb +10 -10
  24. data/lib/sequel/connection_pool/single.rb +1 -1
  25. data/lib/sequel/connection_pool/threaded.rb +1 -1
  26. data/lib/sequel/core.rb +5 -6
  27. data/lib/sequel/database/connecting.rb +1 -1
  28. data/lib/sequel/database/misc.rb +16 -10
  29. data/lib/sequel/database/query.rb +2 -0
  30. data/lib/sequel/database/schema_generator.rb +0 -1
  31. data/lib/sequel/database/schema_methods.rb +15 -16
  32. data/lib/sequel/database/transactions.rb +8 -5
  33. data/lib/sequel/dataset/actions.rb +10 -6
  34. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  35. data/lib/sequel/dataset/query.rb +5 -4
  36. data/lib/sequel/deprecated.rb +3 -1
  37. data/lib/sequel/exceptions.rb +2 -0
  38. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  39. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  40. data/lib/sequel/extensions/core_refinements.rb +2 -0
  41. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  42. data/lib/sequel/extensions/migration.rb +8 -2
  43. data/lib/sequel/extensions/pg_array_ops.rb +4 -0
  44. data/lib/sequel/extensions/pg_enum.rb +2 -0
  45. data/lib/sequel/extensions/pg_extended_date_support.rb +1 -1
  46. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  47. data/lib/sequel/extensions/pg_inet.rb +2 -0
  48. data/lib/sequel/extensions/pg_json_ops.rb +46 -2
  49. data/lib/sequel/extensions/pg_range.rb +3 -7
  50. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  51. data/lib/sequel/extensions/pg_row.rb +0 -1
  52. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  53. data/lib/sequel/extensions/query.rb +1 -0
  54. data/lib/sequel/extensions/run_transaction_hooks.rb +1 -1
  55. data/lib/sequel/extensions/s.rb +2 -0
  56. data/lib/sequel/extensions/schema_dumper.rb +3 -3
  57. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  58. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  59. data/lib/sequel/extensions/to_dot.rb +9 -3
  60. data/lib/sequel/model.rb +3 -1
  61. data/lib/sequel/model/associations.rb +54 -25
  62. data/lib/sequel/model/base.rb +13 -5
  63. data/lib/sequel/model/plugins.rb +3 -3
  64. data/lib/sequel/plugins/association_pks.rb +60 -18
  65. data/lib/sequel/plugins/association_proxies.rb +1 -0
  66. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  67. data/lib/sequel/plugins/class_table_inheritance.rb +3 -3
  68. data/lib/sequel/plugins/csv_serializer.rb +2 -0
  69. data/lib/sequel/plugins/dirty.rb +45 -0
  70. data/lib/sequel/plugins/forbid_lazy_load.rb +2 -0
  71. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  72. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  73. data/lib/sequel/plugins/pg_array_associations.rb +2 -3
  74. data/lib/sequel/plugins/prepared_statements.rb +5 -11
  75. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  76. data/lib/sequel/plugins/rcte_tree.rb +10 -16
  77. data/lib/sequel/plugins/string_stripper.rb +1 -1
  78. data/lib/sequel/plugins/validation_class_methods.rb +5 -1
  79. data/lib/sequel/version.rb +1 -1
  80. metadata +13 -2
@@ -114,10 +114,8 @@ module Sequel
114
114
  prepared_sql << sql
115
115
  prepared_sql << "$#{prepared_args[i]}"
116
116
  end
117
- if final_sql
118
- frags << final_sql
119
- prepared_sql << final_sql
120
- end
117
+ frags << final_sql
118
+ prepared_sql << final_sql
121
119
 
122
120
  [prepared_sql, frags]
123
121
  end
@@ -213,9 +211,7 @@ module Sequel
213
211
  end
214
212
  ds.literal_append(s, v)
215
213
  end
216
- if sql = @final_sql
217
- s << sql
218
- end
214
+ s << @final_sql
219
215
  s
220
216
  end
221
217
  end
@@ -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; nil))
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)
@@ -330,16 +330,17 @@ module Sequel
330
330
  # # SELECT * FROM a WHERE ((a LIKE '%foo%' ESCAPE '\') AND (b LIKE '%foo%' ESCAPE '\')
331
331
  # # AND (a LIKE '%bar%' ESCAPE '\') AND (b LIKE '%bar%' ESCAPE '\'))
332
332
  def grep(columns, patterns, opts=OPTS)
333
+ column_op = opts[:all_columns] ? :AND : :OR
333
334
  if opts[:all_patterns]
334
335
  conds = Array(patterns).map do |pat|
335
- SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
336
+ SQL::BooleanExpression.new(column_op, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
336
337
  end
337
- where(SQL::BooleanExpression.new(opts[:all_patterns] ? :AND : :OR, *conds))
338
+ where(SQL::BooleanExpression.new(:AND, *conds))
338
339
  else
339
340
  conds = Array(columns).map do |c|
340
341
  SQL::BooleanExpression.new(:OR, *Array(patterns).map{|pat| SQL::StringExpression.like(c, pat, opts)})
341
342
  end
342
- where(SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *conds))
343
+ where(SQL::BooleanExpression.new(column_op, *conds))
343
344
  end
344
345
  end
345
346
 
@@ -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 5.1. #{instead}." : method
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
@@ -60,7 +60,9 @@ module Sequel
60
60
  # If using ruby 2.3+, use Module#deprecate_constant to deprecate the constant,
61
61
  # otherwise do nothing as the ruby implementation does not support constant deprecation.
62
62
  def self.deprecate_constant(mod, constant)
63
+ # :nocov:
63
64
  if RUBY_VERSION > '2.3'
65
+ # :nocov:
64
66
  mod.deprecate_constant(constant)
65
67
  end
66
68
  end
@@ -8,7 +8,9 @@ module Sequel
8
8
  # exception is held here.
9
9
  attr_accessor :wrapped_exception
10
10
 
11
+ # :nocov:
11
12
  if RUBY_VERSION >= '2.1'
13
+ # :nocov:
12
14
  # Returned the wrapped exception if one exists, otherwise use
13
15
  # ruby's default behavior.
14
16
  def cause
@@ -41,8 +41,7 @@ module Sequel
41
41
  def self.column_sizes(records, columns) # :nodoc:
42
42
  sizes = Hash.new {0}
43
43
  columns.each do |c|
44
- s = c.to_s.size
45
- sizes[c] = s if s > sizes[c]
44
+ sizes[c] = c.to_s.size
46
45
  end
47
46
  records.each do |r|
48
47
  columns.each do |c|
@@ -75,8 +75,7 @@ module Sequel
75
75
  when SQL::Identifier
76
76
  c.value.to_sym
77
77
  when SQL::QualifiedIdentifier
78
- col = c.column
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
@@ -10,7 +10,9 @@
10
10
  #
11
11
  # using Sequel::CoreRefinements
12
12
 
13
+ # :nocov:
13
14
  raise(Sequel::Error, "Refinements require ruby 2.0.0 or greater") unless RUBY_VERSION >= '2.0.0'
15
+ # :nocov:
14
16
 
15
17
  module Sequel::CoreRefinements
16
18
  refine Array do
@@ -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 database is migrated to the latest version available in 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.
@@ -181,7 +181,9 @@ module Sequel
181
181
  end
182
182
 
183
183
  # support reversible create_enum statements if the migration extension is loaded
184
+ # :nocov:
184
185
  if defined?(MigrationReverser)
186
+ # :nocov:
185
187
  class MigrationReverser
186
188
  private
187
189
  def create_enum(name, _)
@@ -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.is_a?(DateTime) ? date.offset * 1440 : date.utc_offset/60).to_i
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
@@ -312,7 +312,9 @@ module Sequel
312
312
  end
313
313
  end
314
314
 
315
+ # :nocov:
315
316
  if defined?(HStore)
317
+ # :nocov:
316
318
  class HStore
317
319
  # Wrap the receiver in an HStoreOp so you can easily use the PostgreSQL
318
320
  # hstore functions and operators with it.
@@ -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
- # On PostgreSQL 12+ SQL/JSON functions and operators are supported:
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
- # For the PostgreSQL 12+ SQL/JSON functions, one argument is required (+path+) and
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
 
@@ -116,7 +116,9 @@ module Sequel
116
116
  end
117
117
  end
118
118
 
119
+ # :nocov:
119
120
  if defined?(PGRange)
121
+ # :nocov:
120
122
  class PGRange
121
123
  # Wrap the PGRange instance in an RangeOp, allowing you to easily use
122
124
  # the PostgreSQL range functions and operators with literal ranges.
@@ -222,7 +222,6 @@ module Sequel
222
222
  # Split the stored string into an array of strings, handling
223
223
  # the different types of quoting.
224
224
  def parse
225
- return @result if @result
226
225
  values = []
227
226
  skip(/\(/)
228
227
  if skip(/\)/)
@@ -158,6 +158,30 @@ module Sequel
158
158
  end
159
159
  end
160
160
  end
161
+
162
+ # :nocov:
163
+ if defined?(PGRow::ArrayRow)
164
+ # :nocov:
165
+ class PGRow::ArrayRow
166
+ # Wrap the PGRow::ArrayRow instance in an PGRowOp, allowing you to easily use
167
+ # the PostgreSQL row functions and operators with literal rows.
168
+ def op
169
+ Sequel.pg_row_op(self)
170
+ end
171
+ end
172
+ end
173
+
174
+ # :nocov:
175
+ if defined?(PGRow::HashRow)
176
+ # :nocov:
177
+ class PGRow::HashRow
178
+ # Wrap the PGRow::ArrayRow instance in an PGRowOp, allowing you to easily use
179
+ # the PostgreSQL row functions and operators with literal rows.
180
+ def op
181
+ Sequel.pg_row_op(self)
182
+ end
183
+ end
184
+ end
161
185
  end
162
186
 
163
187
  module SQL::Builders
@@ -74,6 +74,7 @@ module Sequel
74
74
  raise(Sequel::Error, "method #{method.inspect} did not return a dataset") unless @dataset.is_a?(Dataset)
75
75
  self
76
76
  end
77
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
77
78
  end
78
79
  end
79
80
 
@@ -48,7 +48,7 @@ class Sequel::Database
48
48
  def _run_transaction_hooks(type, opts)
49
49
  synchronize(opts[:server]) do |conn|
50
50
  unless h = _trans(conn)
51
- raise Error, "Cannot call run_#{type}_hooks outside of a transaction"
51
+ raise Sequel::Error, "Cannot call run_#{type}_hooks outside of a transaction"
52
52
  end
53
53
 
54
54
  if hooks = h[type]
@@ -49,7 +49,9 @@ module Sequel::S
49
49
  Sequel.expr(*a, &block)
50
50
  end
51
51
 
52
+ # :nocov:
52
53
  if RUBY_VERSION >= '2.0.0'
54
+ # :nocov:
53
55
  refine Object do
54
56
  include Sequel::S
55
57
  end