sequel 5.60.0 → 5.61.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +16 -0
  3. data/doc/release_notes/5.61.0.txt +43 -0
  4. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -1
  5. data/lib/sequel/adapters/jdbc.rb +5 -5
  6. data/lib/sequel/adapters/mock.rb +1 -1
  7. data/lib/sequel/adapters/mysql.rb +3 -3
  8. data/lib/sequel/adapters/oracle.rb +1 -1
  9. data/lib/sequel/adapters/postgres.rb +6 -6
  10. data/lib/sequel/adapters/shared/mssql.rb +1 -1
  11. data/lib/sequel/adapters/shared/oracle.rb +1 -1
  12. data/lib/sequel/adapters/shared/postgres.rb +1 -1
  13. data/lib/sequel/adapters/sqlite.rb +1 -1
  14. data/lib/sequel/ast_transformer.rb +1 -1
  15. data/lib/sequel/database/misc.rb +56 -12
  16. data/lib/sequel/dataset/sql.rb +2 -2
  17. data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
  18. data/lib/sequel/extensions/looser_typecasting.rb +3 -0
  19. data/lib/sequel/extensions/pg_array.rb +2 -2
  20. data/lib/sequel/extensions/pg_array_ops.rb +1 -1
  21. data/lib/sequel/extensions/pg_enum.rb +1 -1
  22. data/lib/sequel/extensions/pg_extended_date_support.rb +15 -24
  23. data/lib/sequel/extensions/pg_hstore_ops.rb +3 -3
  24. data/lib/sequel/extensions/pg_inet.rb +3 -3
  25. data/lib/sequel/extensions/pg_interval.rb +2 -2
  26. data/lib/sequel/extensions/pg_json.rb +1 -1
  27. data/lib/sequel/extensions/pg_json_ops.rb +3 -55
  28. data/lib/sequel/extensions/pg_multirange.rb +2 -2
  29. data/lib/sequel/extensions/pg_range.rb +3 -3
  30. data/lib/sequel/extensions/pg_row.rb +2 -2
  31. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  32. data/lib/sequel/model/associations.rb +6 -6
  33. data/lib/sequel/model/base.rb +3 -3
  34. data/lib/sequel/model/exceptions.rb +1 -1
  35. data/lib/sequel/model/inflections.rb +6 -6
  36. data/lib/sequel/plugins/auto_validations.rb +1 -1
  37. data/lib/sequel/plugins/defaults_setter.rb +1 -1
  38. data/lib/sequel/plugins/dirty.rb +1 -1
  39. data/lib/sequel/plugins/insert_conflict.rb +1 -1
  40. data/lib/sequel/plugins/json_serializer.rb +1 -1
  41. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  42. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +1 -1
  43. data/lib/sequel/plugins/serialization.rb +1 -1
  44. data/lib/sequel/plugins/sharding.rb +1 -1
  45. data/lib/sequel/plugins/subclasses.rb +1 -1
  46. data/lib/sequel/plugins/validation_class_methods.rb +3 -3
  47. data/lib/sequel/plugins/validation_helpers.rb +1 -1
  48. data/lib/sequel/sql.rb +1 -1
  49. data/lib/sequel/version.rb +1 -1
  50. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bd9076a491b881827f095bbb1177974861448054cd73376ee76a42ed0f72ee5
4
- data.tar.gz: e2e23f283d2d9f5b29df1510f5f39c8335cc47c37d0f92c848763cd437d4e668
3
+ metadata.gz: f542d5f0e7cca642a8fccd52cb4099101f38dbd1617ff2437b8690766b5f2bdd
4
+ data.tar.gz: 79ff2215f1e38e523e7e64a5779bee695a939a03f046a5e2e9a5974a804a714c
5
5
  SHA512:
6
- metadata.gz: 309b37a25a51bc38c30c20276b7df1df4d21b6b14502b129fc363a0ac9bfc4897be03c21ec1d5b4b333eb6c1944491e4383406bb3f2cb96ba8dd1e98b513de42
7
- data.tar.gz: 58adf4e309a3bd1d921f95d168a79830cce4526767b8ee9379ce69463327b10f0db4ded44a4a8e474cd0dd31036546b120f3e38a07c3057a5290933cffd3b77a
6
+ metadata.gz: 1e0bdc80d388f1bdbf39674624522f7086ca5b0904df2bb28d7b6f3c8f6057df38eca1c0854905a87d920286e578d1e0fe269deb33c3c3f1691d2113a9f23d11
7
+ data.tar.gz: 31ebb15cc504b82c5406c2f7eb6a02a99aa035e9486ecd52698403eff7bd79a99e606229dbbf392ac3fabd1b68c9a7ebc09c127dea3970e2a083c7d781159f33
data/CHANGELOG CHANGED
@@ -1,3 +1,19 @@
1
+ === 5.61.0 (2022-10-01)
2
+
3
+ * Make Database#foreign_key_list on PostgreSQL return results for partitioned tables (jeremyevans)
4
+
5
+ * Add Database#check_string_typecast_bytesize for checking bytesize of strings before typecasting (jeremyevans)
6
+
7
+ * Treat negative hexidecimal strings similar to positive hexidecimal strings when typecasting to integer (jeremyevans)
8
+
9
+ * Remove is_json and is_not_json methods from the pg_json_ops extension, as the support was removed in PostgreSQL 15 beta 4 (jeremyevans)
10
+
11
+ * Fix handling of timestamps before the date of calendar reform when using pg_extended_date_support extension on Ruby 3.2 (jeremyevans)
12
+
13
+ === 5.60.1 (2022-09-02)
14
+
15
+ * Revert conversion of respond_to? to defined?, as it breaks with unused refinements on Ruby 2 (jeremyevans) (#1919)
16
+
1
17
  === 5.60.0 (2022-09-01)
2
18
 
3
19
  * Support arbitrary expressions for date_arithmetic interval values on PostgreSQL 9.4+ (jeremyevans)
@@ -0,0 +1,43 @@
1
+ = Improvements
2
+
3
+ * When typecasting strings to other types, Sequel::Database will now
4
+ by default not typecast strings that are much longer than expected
5
+ for the underlying type. Depending on the underlying type, there
6
+ is a limit of either 100 or 1000 bytes on the input string. This
7
+ avoids potential performance issues when trying to convert
8
+ arbitrary sized user input to specific types.
9
+
10
+ * The respond_to? to defined? change made in 5.60.0 was reverted in
11
+ 5.60.1 as it broke cases on Ruby < 3 where the object had an unused
12
+ refinement that added the method.
13
+
14
+ * When typecasting strings to integer, strings such as -0xa are now
15
+ treated as negative hexidecimal strings, similar to how 0xa is
16
+ treated as a positive hexidecimal string.
17
+
18
+ * Database#foreign_key_list now returns results for partitioned
19
+ tables on PostgreSQL 11+.
20
+
21
+ * Timestamps before the date of calendar reform are now handled
22
+ correctly by the pg_extended_date_support extension when using
23
+ Ruby 3.2 preview 2+.
24
+
25
+ = Backwards Compatibility
26
+
27
+ * The change to not typecast strings that are too long can break
28
+ backwards compatibility for applications that expect typecasting
29
+ for input beyond Sequel's limits. You can disable the string
30
+ bytesize checking by setting:
31
+
32
+ DB.check_string_typecast_bytesize = false
33
+
34
+ or by passing the check_string_typecast_bytesize: false option when
35
+ creating the Database instance.
36
+
37
+ * Code to workaround a bug in JRuby 9.2.0.0 has been removed from the
38
+ pg_extended_date_support extension. Users of the extension should
39
+ upgrade to a newer JRuby version.
40
+
41
+ * The is_json and is_not_json methods have been removed from the
42
+ pg_json_ops extension, as the underlying support was removed in
43
+ PostgreSQL 15 beta 4.
@@ -125,7 +125,7 @@ module Sequel
125
125
 
126
126
  # The result code for the exception, if the jdbc driver supports result codes for exceptions.
127
127
  def sqlite_error_code(exception)
128
- exception.resultCode.code if defined?(exception.resultCode)
128
+ exception.resultCode.code if exception.respond_to?(:resultCode)
129
129
  end
130
130
  end
131
131
  end
@@ -38,7 +38,7 @@ module Sequel
38
38
  else
39
39
  if defined?(::Jdbc) && ( ::Jdbc.const_defined?(name) rescue nil )
40
40
  jdbc_module = ::Jdbc.const_get(name) # e.g. Jdbc::SQLite3
41
- jdbc_module.load_driver if defined?(jdbc_module.load_driver)
41
+ jdbc_module.load_driver if jdbc_module.respond_to?(:load_driver)
42
42
  end
43
43
  end
44
44
 
@@ -396,9 +396,9 @@ module Sequel
396
396
 
397
397
  def database_exception_sqlstate(exception, opts)
398
398
  if database_exception_use_sqlstates?
399
- while defined?(exception.cause)
399
+ while exception.respond_to?(:cause)
400
400
  exception = exception.cause
401
- return exception.getSQLState if defined?(exception.getSQLState)
401
+ return exception.getSQLState if exception.respond_to?(:getSQLState)
402
402
  end
403
403
  end
404
404
  nil
@@ -415,8 +415,8 @@ module Sequel
415
415
 
416
416
  # Raise a disconnect error if the SQL state of the cause of the exception indicates so.
417
417
  def disconnect_error?(exception, opts)
418
- cause = defined?(exception.cause) ? exception.cause : exception
419
- super || (defined?(cause.getSQLState) && cause.getSQLState =~ /^08/)
418
+ cause = exception.respond_to?(:cause) ? exception.cause : exception
419
+ super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
420
420
  end
421
421
 
422
422
  # Execute the prepared statement. If the provided name is a
@@ -257,7 +257,7 @@ module Sequel
257
257
  @shared_adapter = true
258
258
  extend(mod::DatabaseMethods)
259
259
  extend_datasets(mod::DatasetMethods)
260
- if defined?(mod.mock_adapter_setup)
260
+ if mod.respond_to?(:mock_adapter_setup)
261
261
  mod.mock_adapter_setup(self)
262
262
  end
263
263
  end
@@ -72,7 +72,7 @@ module Sequel
72
72
  def connect(server)
73
73
  opts = server_opts(server)
74
74
 
75
- if defined?(Mysql.init)
75
+ if Mysql.respond_to?(:init)
76
76
  conn = Mysql.init
77
77
  conn.options(Mysql::READ_DEFAULT_GROUP, opts[:config_default_group] || "client")
78
78
  conn.options(Mysql::OPT_LOCAL_INFILE, opts[:config_local_infile]) if opts.has_key?(:config_local_infile)
@@ -186,7 +186,7 @@ module Sequel
186
186
  elsif defined?(yield)
187
187
  yield conn
188
188
  end
189
- if defined?(conn.more_results?)
189
+ if conn.respond_to?(:more_results?)
190
190
  while conn.more_results? do
191
191
  if r
192
192
  r.free
@@ -207,7 +207,7 @@ module Sequel
207
207
  ensure
208
208
  r.free if r
209
209
  # Use up all results to avoid a commands out of sync message.
210
- if defined?(conn.more_results?)
210
+ if conn.respond_to?(:more_results?)
211
211
  while conn.more_results? do
212
212
  begin
213
213
  conn.next_result
@@ -149,7 +149,7 @@ module Sequel
149
149
  end
150
150
 
151
151
  def database_specific_error_class(exception, opts)
152
- return super unless defined?(exception.code)
152
+ return super unless exception.respond_to?(:code)
153
153
  case exception.code
154
154
  when 1400, 1407
155
155
  NotNullConstraintViolation
@@ -160,7 +160,7 @@ module Sequel
160
160
  begin
161
161
  defined?(yield) ? yield(q) : q.cmd_tuples
162
162
  ensure
163
- q.clear if q && defined?(q.clear)
163
+ q.clear if q && q.respond_to?(:clear)
164
164
  end
165
165
  end
166
166
 
@@ -258,7 +258,7 @@ module Sequel
258
258
 
259
259
  # :nocov:
260
260
  if encoding = opts[:encoding] || opts[:charset]
261
- if defined?(conn.set_client_encoding)
261
+ if conn.respond_to?(:set_client_encoding)
262
262
  conn.set_client_encoding(encoding)
263
263
  else
264
264
  conn.async_exec("set client_encoding to '#{encoding}'")
@@ -492,12 +492,12 @@ module Sequel
492
492
  opts[:after_listen].call(conn) if opts[:after_listen]
493
493
  timeout = opts[:timeout]
494
494
  if timeout
495
- timeout_block = defined?(timeout.call) ? timeout : proc{timeout}
495
+ timeout_block = timeout.respond_to?(:call) ? timeout : proc{timeout}
496
496
  end
497
497
 
498
498
  if l = opts[:loop]
499
499
  raise Error, 'calling #listen with :loop requires a block' unless block
500
- loop_call = defined?(l.call)
500
+ loop_call = l.respond_to?(:call)
501
501
  catch(:stop) do
502
502
  while true
503
503
  t = timeout_block ? [timeout_block.call] : []
@@ -582,7 +582,7 @@ module Sequel
582
582
 
583
583
  def database_exception_sqlstate(exception, opts)
584
584
  # :nocov:
585
- if defined?(exception.result) && (result = exception.result)
585
+ if exception.respond_to?(:result) && (result = exception.result)
586
586
  # :nocov:
587
587
  result.error_field(PGresult::PG_DIAG_SQLSTATE)
588
588
  end
@@ -625,7 +625,7 @@ module Sequel
625
625
  begin
626
626
  defined?(yield) ? yield(q) : q.cmd_tuples
627
627
  ensure
628
- q.clear if q && defined?(q.clear)
628
+ q.clear if q && q.respond_to?(:clear)
629
629
  end
630
630
  end
631
631
 
@@ -205,7 +205,7 @@ module Sequel
205
205
  return @server_version = Integer(@opts[:server_version])
206
206
  end
207
207
  @server_version = synchronize(server) do |conn|
208
- (conn.server_version rescue nil) if defined?(conn.server_version)
208
+ (conn.server_version rescue nil) if conn.respond_to?(:server_version)
209
209
  end
210
210
  unless @server_version
211
211
  m = /^(\d+)\.(\d+)\.(\d+)/.match(fetch("SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)").single_value.to_s)
@@ -121,7 +121,7 @@ module Sequel
121
121
  def server_version(server=nil)
122
122
  return @server_version if @server_version
123
123
  @server_version = synchronize(server) do |conn|
124
- (conn.server_version rescue nil) if defined?(conn.server_version)
124
+ (conn.server_version rescue nil) if conn.respond_to?(:server_version)
125
125
  end
126
126
  unless @server_version
127
127
  @server_version = if m = /(\d+)\.(\d+)\.?(\d+)?\.?(\d+)?/.match(fetch("select version from PRODUCT_COMPONENT_VERSION where lower(product) like 'oracle%'").single_value)
@@ -586,7 +586,7 @@ module Sequel
586
586
  join(Sequel[:pg_namespace].as(:nsp), :oid=>Sequel[:cl2][:relnamespace]).
587
587
  order{[co[:conname], cpos]}.
588
588
  where{{
589
- cl[:relkind]=>'r',
589
+ cl[:relkind]=>%w'r p',
590
590
  co[:contype]=>'f',
591
591
  cl[:oid]=>oid,
592
592
  cpos=>rpos
@@ -305,7 +305,7 @@ module Sequel
305
305
  if USE_EXTENDED_RESULT_CODES
306
306
  # Support SQLite exception codes if ruby-sqlite3 supports them.
307
307
  def sqlite_error_code(exception)
308
- exception.code if defined?(exception.code)
308
+ exception.code if exception.respond_to?(:code)
309
309
  end
310
310
  end
311
311
  end
@@ -81,7 +81,7 @@ module Sequel
81
81
  when SQL::Wrapper
82
82
  SQL::Wrapper.new(v(o.value))
83
83
  when SQL::Expression
84
- if defined?(o.sequel_ast_transform)
84
+ if o.respond_to?(:sequel_ast_transform)
85
85
  o.sequel_ast_transform(method(:v))
86
86
  else
87
87
  o
@@ -91,6 +91,11 @@ module Sequel
91
91
  # The specific default size of string columns for this Sequel::Database, usually 255 by default.
92
92
  attr_accessor :default_string_column_size
93
93
 
94
+ # Whether to check the bytesize of strings before typecasting (to avoid typecasting strings that
95
+ # would be too long for the given type), true by default. Strings that are too long will raise
96
+ # a typecasting error.
97
+ attr_accessor :check_string_typecast_bytesize
98
+
94
99
  # Constructs a new instance of a database connection with the specified
95
100
  # options hash.
96
101
  #
@@ -98,6 +103,7 @@ module Sequel
98
103
  # :before_preconnect :: Callable that runs after extensions from :preconnect_extensions are loaded,
99
104
  # but before any connections are created.
100
105
  # :cache_schema :: Whether schema should be cached for this Database instance
106
+ # :check_string_typecast_bytesize :: Whether to check the bytesize of strings before typecasting.
101
107
  # :default_string_column_size :: The default size of string columns, 255 by default.
102
108
  # :extensions :: Extensions to load into this Database instance. Can be a symbol, array of symbols,
103
109
  # or string with extensions separated by columns. These extensions are loaded after
@@ -107,7 +113,7 @@ module Sequel
107
113
  # :loggers :: An array of loggers to use.
108
114
  # :log_connection_info :: Whether connection information should be logged when logging queries.
109
115
  # :log_warn_duration :: The number of elapsed seconds after which queries should be logged at warn level.
110
- # :name :: A name to use for the Database object, displayed in PoolTimeout .
116
+ # :name :: A name to use for the Database object, displayed in PoolTimeout.
111
117
  # :preconnect :: Automatically create the maximum number of connections, so that they don't
112
118
  # need to be created as needed. This is useful when connecting takes a long time
113
119
  # and you want to avoid possible latency during runtime.
@@ -116,7 +122,7 @@ module Sequel
116
122
  # :preconnect_extensions :: Similar to the :extensions option, but loads the extensions before the
117
123
  # connections are made by the :preconnect option.
118
124
  # :quote_identifiers :: Whether to quote identifiers.
119
- # :servers :: A hash specifying a server/shard specific options, keyed by shard symbol .
125
+ # :servers :: A hash specifying a server/shard specific options, keyed by shard symbol.
120
126
  # :single_threaded :: Whether to use a single-threaded connection pool.
121
127
  # :sql_log_level :: Method to use to log SQL to a logger, :info by default.
122
128
  #
@@ -132,6 +138,7 @@ module Sequel
132
138
  @opts[:adapter_class] = self.class
133
139
  @opts[:single_threaded] = @single_threaded = typecast_value_boolean(@opts.fetch(:single_threaded, Sequel.single_threaded))
134
140
  @default_string_column_size = @opts[:default_string_column_size] || DEFAULT_STRING_COLUMN_SIZE
141
+ @check_string_typecast_bytesize = typecast_value_boolean(@opts.fetch(:check_string_typecast_bytesize, true))
135
142
 
136
143
  @schemas = {}
137
144
  @prepared_statements = {}
@@ -350,7 +357,7 @@ module Sequel
350
357
  # strings with all whitespace, and ones that respond
351
358
  # true to empty?
352
359
  def blank_object?(obj)
353
- return obj.blank? if defined?(obj.blank?)
360
+ return obj.blank? if obj.respond_to?(:blank?)
354
361
  case obj
355
362
  when NilClass, FalseClass
356
363
  true
@@ -359,7 +366,7 @@ module Sequel
359
366
  when String
360
367
  obj.strip.empty?
361
368
  else
362
- defined?(obj.empty?) ? obj.empty? : false
369
+ obj.respond_to?(:empty?) ? obj.empty? : false
363
370
  end
364
371
  end
365
372
 
@@ -465,6 +472,21 @@ module Sequel
465
472
  # Don't rescue other exceptions, they will be raised normally.
466
473
  end
467
474
 
475
+ # Check the bytesize of a string before conversion. There is no point
476
+ # trying to typecast strings that would be way too long.
477
+ def typecast_check_string_length(string, max_size)
478
+ if @check_string_typecast_bytesize && string.bytesize > max_size
479
+ raise InvalidValue, "string too long to typecast (bytesize: #{string.bytesize}, max: #{max_size})"
480
+ end
481
+ string
482
+ end
483
+
484
+ # Check the bytesize of the string value, if value is a string.
485
+ def typecast_check_length(value, max_size)
486
+ typecast_check_string_length(value, max_size) if String === value
487
+ value
488
+ end
489
+
468
490
  # Typecast the value to an SQL::Blob
469
491
  def typecast_value_blob(value)
470
492
  value.is_a?(Sequel::SQL::Blob) ? value : Sequel::SQL::Blob.new(value)
@@ -488,9 +510,9 @@ module Sequel
488
510
  when Date
489
511
  value
490
512
  when String
491
- Sequel.string_to_date(value)
513
+ Sequel.string_to_date(typecast_check_string_length(value, 100))
492
514
  when Hash
493
- Date.new(*[:year, :month, :day].map{|x| (value[x] || value[x.to_s]).to_i})
515
+ Date.new(*[:year, :month, :day].map{|x| typecast_check_length(value[x] || value[x.to_s], 100).to_i})
494
516
  else
495
517
  raise InvalidValue, "invalid value for Date: #{value.inspect}"
496
518
  end
@@ -498,7 +520,17 @@ module Sequel
498
520
 
499
521
  # Typecast the value to a DateTime or Time depending on Sequel.datetime_class
500
522
  def typecast_value_datetime(value)
501
- Sequel.typecast_to_application_timestamp(value)
523
+ case value
524
+ when String
525
+ Sequel.typecast_to_application_timestamp(typecast_check_string_length(value, 100))
526
+ when Hash
527
+ [:year, :month, :day, :hour, :minute, :second, :nanos, :offset].each do |x|
528
+ typecast_check_length(value[x] || value[x.to_s], 100)
529
+ end
530
+ Sequel.typecast_to_application_timestamp(value)
531
+ else
532
+ Sequel.typecast_to_application_timestamp(value)
533
+ end
502
534
  end
503
535
 
504
536
  if RUBY_VERSION >= '2.4'
@@ -531,18 +563,30 @@ module Sequel
531
563
  when Numeric
532
564
  BigDecimal(value.to_s)
533
565
  when String
534
- _typecast_value_string_to_decimal(value)
566
+ _typecast_value_string_to_decimal(typecast_check_string_length(value, 1000))
535
567
  else
536
568
  raise InvalidValue, "invalid value for BigDecimal: #{value.inspect}"
537
569
  end
538
570
  end
539
571
 
540
572
  # Typecast the value to a Float
541
- alias typecast_value_float Float
573
+ def typecast_value_float(value)
574
+ Float(typecast_check_length(value, 1000))
575
+ end
542
576
 
543
577
  # Typecast the value to an Integer
544
578
  def typecast_value_integer(value)
545
- (value.is_a?(String) && value =~ /\A0+(\d)/) ? Integer(value, 10) : Integer(value)
579
+ case value
580
+ when String
581
+ typecast_check_string_length(value, 100)
582
+ if value =~ /\A-?0+(\d)/
583
+ Integer(value, 10)
584
+ else
585
+ Integer(value)
586
+ end
587
+ else
588
+ Integer(value)
589
+ end
546
590
  end
547
591
 
548
592
  # Typecast the value to a String
@@ -565,9 +609,9 @@ module Sequel
565
609
  SQLTime.create(value.hour, value.min, value.sec, value.nsec/1000.0)
566
610
  end
567
611
  when String
568
- Sequel.string_to_time(value)
612
+ Sequel.string_to_time(typecast_check_string_length(value, 100))
569
613
  when Hash
570
- SQLTime.create(*[:hour, :minute, :second].map{|x| (value[x] || value[x.to_s]).to_i})
614
+ SQLTime.create(*[:hour, :minute, :second].map{|x| typecast_check_length(value[x] || value[x.to_s], 100).to_i})
571
615
  else
572
616
  raise Sequel::InvalidValue, "invalid value for Time: #{value.inspect}"
573
617
  end
@@ -1398,9 +1398,9 @@ module Sequel
1398
1398
  # don't cache SQL for a dataset that uses this.
1399
1399
  disable_sql_caching!
1400
1400
 
1401
- if defined?(v.sql_literal_append)
1401
+ if v.respond_to?(:sql_literal_append)
1402
1402
  v.sql_literal_append(self, sql)
1403
- elsif defined?(v.sql_literal)
1403
+ elsif v.respond_to?(:sql_literal)
1404
1404
  sql << v.sql_literal(self)
1405
1405
  else
1406
1406
  raise Error, "can't express #{v.inspect} as a SQL literal"
@@ -77,7 +77,7 @@ module Sequel
77
77
  def duplicate_columns_handler_type(cols)
78
78
  handler = opts.fetch(:on_duplicate_columns){db.opts.fetch(:on_duplicate_columns, :warn)}
79
79
 
80
- if defined?(handler.call)
80
+ if handler.respond_to?(:call)
81
81
  handler.call(cols)
82
82
  else
83
83
  handler
@@ -8,6 +8,9 @@
8
8
  # :decimal :: use 0.0 for unsupported strings
9
9
  # :string :: silently allow hash and array conversion to string
10
10
  #
11
+ # This also removes bytesize checks for string inputs for float, integer
12
+ # and decimal conversions.
13
+ #
11
14
  # To load the extension into the database:
12
15
  #
13
16
  # DB.extension :looser_typecasting
@@ -301,7 +301,7 @@ module Sequel
301
301
  end
302
302
  end
303
303
 
304
- unless defined?(Sequel::Postgres.parse_pg_array)
304
+ unless Sequel::Postgres.respond_to?(:parse_pg_array)
305
305
  require 'strscan'
306
306
 
307
307
  # PostgreSQL array parser that handles PostgreSQL array output format.
@@ -412,7 +412,7 @@ module Sequel
412
412
  @converter = converter
413
413
  end
414
414
 
415
- if defined?(Sequel::Postgres.parse_pg_array)
415
+ if Sequel::Postgres.respond_to?(:parse_pg_array)
416
416
  # :nocov:
417
417
  # Use sequel_pg's C-based parser if it has already been defined.
418
418
  def call(string)
@@ -158,7 +158,7 @@ module Sequel
158
158
  Sequel.function(:hstore, self, wrap_array(arg))
159
159
  end
160
160
  # :nocov:
161
- if defined?(Sequel.hstore_op)
161
+ if Sequel.respond_to?(:hstore_op)
162
162
  # :nocov:
163
163
  v = Sequel.hstore_op(v)
164
164
  end
@@ -144,7 +144,7 @@ module Sequel
144
144
  select_hash_groups(Sequel.cast(:enumtypid, Integer).as(:v), :enumlabel).freeze
145
145
  enum_labels.each_value(&:freeze)
146
146
 
147
- if defined?(register_array_type)
147
+ if respond_to?(:register_array_type)
148
148
  array_types = metadata_dataset.
149
149
  from(:pg_type).
150
150
  where(:oid=>enum_labels.keys).
@@ -29,6 +29,8 @@ module Sequel
29
29
  INFINITE_DATETIME_VALUES = ([PLUS_INFINITY, MINUS_INFINITY] + INFINITE_TIMESTAMP_STRINGS).freeze
30
30
  PLUS_DATE_INFINITY = Date::Infinity.new
31
31
  MINUS_DATE_INFINITY = -PLUS_DATE_INFINITY
32
+ RATIONAL_60 = Rational(60)
33
+ TIME_CAN_PARSE_BC = RUBY_VERSION >= '2.5'
32
34
 
33
35
  # Add dataset methods and update the conversion proces for dates and timestamps.
34
36
  def self.extended(db)
@@ -86,27 +88,18 @@ module Sequel
86
88
  if value.is_a?(String) && (m = /((?:[-+]\d\d:\d\d)(:\d\d)?)?( BC)?\z/.match(value)) && (m[2] || m[3])
87
89
  if m[3]
88
90
  value = value.sub(' BC', '').sub(' ', ' BC ')
89
- conv = defined?(JRUBY_VERSION) && JRUBY_VERSION == '9.2.0.0'
90
91
  end
91
- if m[2] || conv
92
- dt = DateTime.parse(value)
93
- if conv
94
- # :nocov:
95
- if Sequel.datetime_class == DateTime
96
- dt >>= 12
97
- else
98
- dt >>= 24
99
- end
100
- # :nocov:
101
- end
102
- unless Sequel.datetime_class == DateTime
103
- dt = dt.to_time
104
- if conv && (timezone == nil || timezone == :local) && !m[1]
105
- # :nocov:
106
- dt = Sequel.send(:convert_input_timestamp, dt.strftime("%F %T.%6N"), :local)
107
- # :nocov:
108
- end
92
+ if m[2]
93
+ dt = if Sequel.datetime_class == DateTime
94
+ DateTime.parse(value)
95
+ elsif TIME_CAN_PARSE_BC
96
+ Time.parse(value)
97
+ # :nocov:
98
+ else
99
+ DateTime.parse(value).to_time
100
+ # :nocov:
109
101
  end
102
+
110
103
  Sequel.convert_output_timestamp(dt, Sequel.application_timezone)
111
104
  else
112
105
  super(value)
@@ -223,10 +216,7 @@ module Sequel
223
216
  # Work around JRuby bug #4822 in Time#to_datetime for times before date of calendar reform
224
217
  def literal_time(time)
225
218
  if time < TIME_YEAR_1
226
- dt = DateTime.parse(super)
227
- # Work around JRuby bug #5191
228
- dt >>= 12 if JRUBY_VERSION == '9.2.0.0'
229
- literal_datetime(dt)
219
+ literal_datetime(DateTime.parse(super))
230
220
  else
231
221
  super
232
222
  end
@@ -236,7 +226,8 @@ module Sequel
236
226
  # Handle BC Time objects.
237
227
  def literal_time(time)
238
228
  if time < TIME_YEAR_1
239
- literal_datetime(time.to_datetime)
229
+ time = db.from_application_timestamp(time)
230
+ time.strftime("'#{sprintf('%04i', time.year.abs+1)}-%m-%d %H:%M:%S.%N#{format_timestamp_offset(*(time.utc_offset/RATIONAL_60).divmod(60))} BC'")
240
231
  else
241
232
  super
242
233
  end
@@ -296,7 +296,7 @@ module Sequel
296
296
 
297
297
  # Wrap argument in a PGArray if it is an array
298
298
  def wrap_input_array(obj)
299
- if obj.is_a?(Array) && defined?(Sequel.pg_array)
299
+ if obj.is_a?(Array) && Sequel.respond_to?(:pg_array)
300
300
  Sequel.pg_array(obj)
301
301
  else
302
302
  obj
@@ -305,7 +305,7 @@ module Sequel
305
305
 
306
306
  # Wrap argument in an Hstore if it is a hash
307
307
  def wrap_input_hash(obj)
308
- if obj.is_a?(Hash) && defined?(Sequel.hstore)
308
+ if obj.is_a?(Hash) && Sequel.respond_to?(:hstore)
309
309
  Sequel.hstore(obj)
310
310
  else
311
311
  obj
@@ -314,7 +314,7 @@ module Sequel
314
314
 
315
315
  # Wrap argument in a PGArrayOp if supported
316
316
  def wrap_output_array(obj)
317
- if defined?(Sequel.pg_array_op)
317
+ if Sequel.respond_to?(:pg_array_op)
318
318
  Sequel.pg_array_op(obj)
319
319
  else
320
320
  obj
@@ -49,13 +49,13 @@ module Sequel
49
49
  meth = IPAddr.method(:new)
50
50
  add_conversion_proc(869, meth)
51
51
  add_conversion_proc(650, meth)
52
- if defined?(register_array_type)
52
+ if respond_to?(:register_array_type)
53
53
  register_array_type('inet', :oid=>1041, :scalar_oid=>869)
54
54
  register_array_type('cidr', :oid=>651, :scalar_oid=>650)
55
55
  end
56
56
  end
57
57
 
58
- if defined?(register_array_type)
58
+ if respond_to?(:register_array_type)
59
59
  register_array_type('macaddr', :oid=>1040, :scalar_oid=>829)
60
60
  end
61
61
  @schema_type_classes[:ipaddr] = IPAddr
@@ -111,7 +111,7 @@ module Sequel
111
111
  when IPAddr
112
112
  value
113
113
  when String
114
- IPAddr.new(value)
114
+ IPAddr.new(typecast_check_string_length(value, 100))
115
115
  else
116
116
  raise Sequel::InvalidValue, "invalid value for inet/cidr: #{value.inspect}"
117
117
  end
@@ -144,7 +144,7 @@ module Sequel
144
144
  db.instance_exec do
145
145
  extend_datasets(IntervalDatasetMethods)
146
146
  add_conversion_proc(1186, Postgres::IntervalDatabaseMethods::PARSER)
147
- if defined?(register_array_type)
147
+ if respond_to?(:register_array_type)
148
148
  register_array_type('interval', :oid=>1187, :scalar_oid=>1186)
149
149
  end
150
150
  @schema_type_classes[:interval] = ActiveSupport::Duration
@@ -197,7 +197,7 @@ module Sequel
197
197
  when Numeric
198
198
  ActiveSupport::Duration.new(value, [[:seconds, value]])
199
199
  when String
200
- PARSER.call(value)
200
+ PARSER.call(typecast_check_string_length(value, 1000))
201
201
  else
202
202
  raise Sequel::InvalidValue, "invalid value for interval type: #{value.inspect}"
203
203
  end
@@ -227,7 +227,7 @@ module Sequel
227
227
  db.instance_exec do
228
228
  add_conversion_proc(114, method(:_db_parse_json))
229
229
  add_conversion_proc(3802, method(:_db_parse_jsonb))
230
- if defined?(register_array_type)
230
+ if respond_to?(:register_array_type)
231
231
  register_array_type('json', :oid=>199, :scalar_oid=>114)
232
232
  register_array_type('jsonb', :oid=>3807, :scalar_oid=>3802)
233
233
  end
@@ -123,15 +123,6 @@
123
123
  # c = Sequel.pg_jsonb_op(:c)
124
124
  # DB[:t].update(c['key1'] => 1.to_json, c['key2'] => "a".to_json)
125
125
  #
126
- # On PostgreSQL 15+, the <tt>IS [NOT] JSON</tt> operator is supported:
127
- #
128
- # j.is_json # j IS JSON
129
- # j.is_json(type: :object) # j IS JSON OBJECT
130
- # j.is_json(type: :object, unique: true) # j IS JSON OBJECT WITH UNIQUE
131
- # j.is_not_json # j IS NOT JSON
132
- # j.is_json(type: :array) # j IS NOT JSON ARRAY
133
- # j.is_json(unique: true) # j IS NOT JSON WITH UNIQUE
134
- #
135
126
  # If you are also using the pg_json extension, you should load it before
136
127
  # loading this extension. Doing so will allow you to use the #op method on
137
128
  # JSONHash, JSONHarray, JSONBHash, and JSONBArray, allowing you to perform json/jsonb operations
@@ -160,18 +151,6 @@ module Sequel
160
151
  GET_PATH = ["(".freeze, " #> ".freeze, ")".freeze].freeze
161
152
  GET_PATH_TEXT = ["(".freeze, " #>> ".freeze, ")".freeze].freeze
162
153
 
163
- IS_JSON = ["(".freeze, " IS JSON".freeze, "".freeze, ")".freeze].freeze
164
- IS_NOT_JSON = ["(".freeze, " IS NOT JSON".freeze, "".freeze, ")".freeze].freeze
165
- EMPTY_STRING = Sequel::LiteralString.new('').freeze
166
- WITH_UNIQUE = Sequel::LiteralString.new(' WITH UNIQUE').freeze
167
- IS_JSON_MAP = {
168
- nil => EMPTY_STRING,
169
- :value => Sequel::LiteralString.new(' VALUE').freeze,
170
- :scalar => Sequel::LiteralString.new(' SCALAR').freeze,
171
- :object => Sequel::LiteralString.new(' OBJECT').freeze,
172
- :array => Sequel::LiteralString.new(' ARRAY').freeze
173
- }.freeze
174
-
175
154
  # Get JSON array element or object field as json. If an array is given,
176
155
  # gets the object at the specified path.
177
156
  #
@@ -254,30 +233,6 @@ module Sequel
254
233
  end
255
234
  end
256
235
 
257
- # Return whether the json object can be parsed as JSON.
258
- #
259
- # Options:
260
- # :type :: Check whether the json object can be parsed as a specific type
261
- # of JSON (:value, :scalar, :object, :array).
262
- # :unique :: Check JSON objects for unique keys.
263
- #
264
- # json_op.is_json # json IS JSON
265
- # json_op.is_json(type: :object) # json IS JSON OBJECT
266
- # json_op.is_json(unique: true) # json IS JSON WITH UNIQUE
267
- def is_json(opts=OPTS)
268
- _is_json(IS_JSON, opts)
269
- end
270
-
271
- # Return whether the json object cannot be parsed as JSON. The opposite
272
- # of #is_json. See #is_json for options.
273
- #
274
- # json_op.is_not_json # json IS NOT JSON
275
- # json_op.is_not_json(type: :object) # json IS NOT JSON OBJECT
276
- # json_op.is_not_json(unique: true) # json IS NOT JSON WITH UNIQUE
277
- def is_not_json(opts=OPTS)
278
- _is_json(IS_NOT_JSON, opts)
279
- end
280
-
281
236
  # Returns a set of keys AS text in the json object.
282
237
  #
283
238
  # json_op.keys # json_object_keys(json)
@@ -331,13 +286,6 @@ module Sequel
331
286
 
332
287
  private
333
288
 
334
- # Internals of IS [NOT] JSON support
335
- def _is_json(lit_array, opts)
336
- raise Error, "invalid is_json :type option: #{opts[:type].inspect}" unless type = IS_JSON_MAP[opts[:type]]
337
- unique = opts[:unique] ? WITH_UNIQUE : EMPTY_STRING
338
- Sequel::SQL::BooleanExpression.new(:NOOP, Sequel::SQL::PlaceholderLiteralString.new(lit_array, [self, type, unique]))
339
- end
340
-
341
289
  # Return a placeholder literal with the given str and args, wrapped
342
290
  # in an JSONOp or JSONBOp, used by operators that return json or jsonb.
343
291
  def json_op(str, args)
@@ -358,7 +306,7 @@ module Sequel
358
306
  # Automatically wrap argument in a PGArray if it is a plain Array.
359
307
  # Requires that the pg_array extension has been loaded to work.
360
308
  def wrap_array(arg)
361
- if arg.instance_of?(Array) && defined?(Sequel.pg_array)
309
+ if arg.instance_of?(Array) && Sequel.respond_to?(:pg_array)
362
310
  Sequel.pg_array(arg)
363
311
  else
364
312
  arg
@@ -652,7 +600,7 @@ module Sequel
652
600
 
653
601
  # Wrap argument in a PGArray if it is an array
654
602
  def wrap_input_array(obj)
655
- if obj.is_a?(Array) && defined?(Sequel.pg_array)
603
+ if obj.is_a?(Array) && Sequel.respond_to?(:pg_array)
656
604
  Sequel.pg_array(obj)
657
605
  else
658
606
  obj
@@ -661,7 +609,7 @@ module Sequel
661
609
 
662
610
  # Wrap argument in a JSONBArray or JSONBHash if it is an array or hash.
663
611
  def wrap_input_jsonb(obj)
664
- if defined?(Sequel.pg_jsonb) && (obj.is_a?(Array) || obj.is_a?(Hash))
612
+ if Sequel.respond_to?(:pg_jsonb) && (obj.is_a?(Array) || obj.is_a?(Hash))
665
613
  Sequel.pg_jsonb(obj)
666
614
  else
667
615
  obj
@@ -124,7 +124,7 @@ module Sequel
124
124
  register_multirange_type('datemultirange', :range_oid=>3912, :oid=>4535)
125
125
  register_multirange_type('int8multirange', :range_oid=>3926, :oid=>4536)
126
126
 
127
- if defined?(register_array_type)
127
+ if respond_to?(:register_array_type)
128
128
  register_array_type('int4multirange', :oid=>6150, :scalar_oid=>4451, :scalar_typecast=>:int4multirange)
129
129
  register_array_type('nummultirange', :oid=>6151, :scalar_oid=>4532, :scalar_typecast=>:nummultirange)
130
130
  register_array_type('tsmultirange', :oid=>6152, :scalar_oid=>4533, :scalar_typecast=>:tsmultirange)
@@ -141,7 +141,7 @@ module Sequel
141
141
  add_conversion_proc(4533, PGMultiRange::Creator.new("tsmultirange", procs[3908]))
142
142
  add_conversion_proc(4534, PGMultiRange::Creator.new("tstzmultirange", procs[3910]))
143
143
 
144
- if defined?(register_array_type) && defined?(PGArray::Creator)
144
+ if respond_to?(:register_array_type) && defined?(PGArray::Creator)
145
145
  add_conversion_proc(6152, PGArray::Creator.new("tsmultirange", procs[4533]))
146
146
  add_conversion_proc(6153, PGArray::Creator.new("tstzmultirange", procs[4534]))
147
147
  end
@@ -139,7 +139,7 @@ module Sequel
139
139
  register_range_type('tstzrange', :oid=>3910, :subtype_oid=>1184)
140
140
  register_range_type('daterange', :oid=>3912, :subtype_oid=>1082)
141
141
  register_range_type('int8range', :oid=>3926, :subtype_oid=>20)
142
- if defined?(register_array_type)
142
+ if respond_to?(:register_array_type)
143
143
  register_array_type('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range)
144
144
  register_array_type('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange)
145
145
  register_array_type('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange)
@@ -154,7 +154,7 @@ module Sequel
154
154
  procs = conversion_procs
155
155
  add_conversion_proc(3908, Parser.new("tsrange", procs[1114]))
156
156
  add_conversion_proc(3910, Parser.new("tstzrange", procs[1184]))
157
- if defined?(register_array_type) && defined?(PGArray::Creator)
157
+ if respond_to?(:register_array_type) && defined?(PGArray::Creator)
158
158
  add_conversion_proc(3909, PGArray::Creator.new("tsrange", procs[3908]))
159
159
  add_conversion_proc(3911, PGArray::Creator.new("tstzrange", procs[3910]))
160
160
  end
@@ -282,7 +282,7 @@ module Sequel
282
282
  when Range
283
283
  PGRange.from_range(value, parser.db_type)
284
284
  when String
285
- parser.call(value)
285
+ parser.call(typecast_check_string_length(value, 100))
286
286
  else
287
287
  raise Sequel::InvalidValue, "invalid value for range type: #{value.inspect}"
288
288
  end
@@ -375,7 +375,7 @@ module Sequel
375
375
  @row_schema_types = {}
376
376
  extend(@row_type_method_module = Module.new)
377
377
  add_conversion_proc(2249, PGRow::Parser.new(:converter=>PGRow::ArrayRow))
378
- if defined?(register_array_type)
378
+ if respond_to?(:register_array_type)
379
379
  register_array_type('record', :oid=>2287, :scalar_oid=>2249)
380
380
  end
381
381
  end
@@ -464,7 +464,7 @@ module Sequel
464
464
  parser = Parser.new(parser_opts)
465
465
  add_conversion_proc(parser.oid, parser)
466
466
 
467
- if defined?(register_array_type) && array_oid && array_oid > 0
467
+ if respond_to?(:register_array_type) && array_oid && array_oid > 0
468
468
  array_type_name = if type_schema
469
469
  "#{type_schema}.#{type_name}"
470
470
  else
@@ -115,13 +115,13 @@ SQL
115
115
  # :before_thread_exit :: An object that responds to +call+ that is called before the
116
116
  # the created thread exits.
117
117
  def listen_for_static_cache_updates(models, opts=OPTS)
118
- raise Error, "this database object does not respond to listen, use the postgres adapter with the pg driver" unless defined?(listen)
118
+ raise Error, "this database object does not respond to listen, use the postgres adapter with the pg driver" unless respond_to?(:listen)
119
119
  models = [models] unless models.is_a?(Array)
120
120
  raise Error, "array of models to listen for changes cannot be empty" if models.empty?
121
121
 
122
122
  oid_map = {}
123
123
  models.each do |model|
124
- raise Error, "#{model.inspect} does not use the static_cache plugin" unless defined?(model.load_cache)
124
+ raise Error, "#{model.inspect} does not use the static_cache plugin" unless model.respond_to?(:load_cache)
125
125
  oid_map[get(regclass_oid(model.dataset.first_source_table))] = model
126
126
  end
127
127
 
@@ -3016,7 +3016,7 @@ module Sequel
3016
3016
  def complex_expression_sql_append(sql, op, args)
3017
3017
  r = args[1]
3018
3018
  if (((op == :'=' || op == :'!=') && r.is_a?(Sequel::Model)) ||
3019
- (multiple = ((op == :IN || op == :'NOT IN') && ((is_ds = r.is_a?(Sequel::Dataset)) || (defined?(r.all?) && r.all?{|x| x.is_a?(Sequel::Model)})))))
3019
+ (multiple = ((op == :IN || op == :'NOT IN') && ((is_ds = r.is_a?(Sequel::Dataset)) || (r.respond_to?(:all?) && r.all?{|x| x.is_a?(Sequel::Model)})))))
3020
3020
  l = args[0]
3021
3021
  if ar = model.association_reflections[l]
3022
3022
  raise Error, "filtering by associations is not allowed for #{ar.inspect}" if ar[:allow_filtering_by] == false
@@ -3024,7 +3024,7 @@ module Sequel
3024
3024
  if multiple
3025
3025
  klass = ar.associated_class
3026
3026
  if is_ds
3027
- if defined?(r.model)
3027
+ if r.respond_to?(:model)
3028
3028
  unless r.model <= klass
3029
3029
  # A dataset for a different model class, could be a valid regular query
3030
3030
  return super
@@ -3356,10 +3356,10 @@ module Sequel
3356
3356
  assoc_table_alias = ds.unused_table_alias(alias_base)
3357
3357
  loader = r[:eager_grapher]
3358
3358
  if !associations.empty?
3359
- if defined?(associations.first.call)
3359
+ if associations.first.respond_to?(:call)
3360
3360
  callback = associations.first
3361
3361
  associations = {}
3362
- elsif associations.length == 1 && (assocs = associations.first).is_a?(Hash) && assocs.length == 1 && (pr_assoc = assocs.to_a.first) && defined?(pr_assoc.first.call)
3362
+ elsif associations.length == 1 && (assocs = associations.first).is_a?(Hash) && assocs.length == 1 && (pr_assoc = assocs.to_a.first) && pr_assoc.first.respond_to?(:call)
3363
3363
  callback, assoc = pr_assoc
3364
3364
  associations = assoc.is_a?(Array) ? assoc : [assoc]
3365
3365
  end
@@ -3601,10 +3601,10 @@ module Sequel
3601
3601
  end
3602
3602
 
3603
3603
  associations = eager_assoc[r[:name]]
3604
- if defined?(associations.call)
3604
+ if associations.respond_to?(:call)
3605
3605
  eager_block = associations
3606
3606
  associations = OPTS
3607
- elsif associations.is_a?(Hash) && associations.length == 1 && (pr_assoc = associations.to_a.first) && defined?(pr_assoc.first.call)
3607
+ elsif associations.is_a?(Hash) && associations.length == 1 && (pr_assoc = associations.to_a.first) && pr_assoc.first.respond_to?(:call)
3608
3608
  eager_block, associations = pr_assoc
3609
3609
  end
3610
3610
 
@@ -492,13 +492,13 @@ module Sequel
492
492
  def plugin(plugin, *args, &block)
493
493
  m = plugin.is_a?(Module) ? plugin : plugin_module(plugin)
494
494
 
495
- if !defined?(m.apply) && !defined?(m.configure) && (!args.empty? || block)
495
+ if !m.respond_to?(:apply) && !m.respond_to?(:configure) && (!args.empty? || block)
496
496
  Deprecation.deprecate("Plugin #{plugin} accepts no arguments or block, and passing arguments/block to it", "Remove arguments and block when loading the plugin")
497
497
  end
498
498
 
499
499
  unless @plugins.include?(m)
500
500
  @plugins << m
501
- m.apply(self, *args, &block) if defined?(m.apply)
501
+ m.apply(self, *args, &block) if m.respond_to?(:apply)
502
502
  extend(m::ClassMethods) if m.const_defined?(:ClassMethods, false)
503
503
  include(m::InstanceMethods) if m.const_defined?(:InstanceMethods, false)
504
504
  if m.const_defined?(:DatasetMethods, false)
@@ -506,7 +506,7 @@ module Sequel
506
506
  end
507
507
  end
508
508
 
509
- m.configure(self, *args, &block) if defined?(m.configure)
509
+ m.configure(self, *args, &block) if m.respond_to?(:configure)
510
510
  end
511
511
  # :nocov:
512
512
  ruby2_keywords(:plugin) if respond_to?(:ruby2_keywords, true)
@@ -44,7 +44,7 @@ module Sequel
44
44
  errors = @model.errors
45
45
  end
46
46
 
47
- if defined?(errors.full_messages)
47
+ if errors.respond_to?(:full_messages)
48
48
  @errors = errors
49
49
  super(errors.full_messages.join(', '))
50
50
  else
@@ -99,7 +99,7 @@ module Sequel
99
99
  # Convert the given string to CamelCase. Will also convert '/' to '::' which is useful for converting paths to namespaces.
100
100
  def camelize(s)
101
101
  s = s.to_s
102
- return s.camelize if defined?(s.camelize)
102
+ return s.camelize if s.respond_to?(:camelize)
103
103
  s = s.gsub(/\/(.?)/){|x| "::#{x[-1..-1].upcase unless x == '/'}"}.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
104
104
  s
105
105
  end
@@ -109,7 +109,7 @@ module Sequel
109
109
  # or is not initialized.
110
110
  def constantize(s)
111
111
  s = s.to_s
112
- return s.constantize if defined?(s.constantize)
112
+ return s.constantize if s.respond_to?(:constantize)
113
113
  raise(NameError, "#{s.inspect} is not a valid constant name!") unless m = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.match(s)
114
114
  Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
115
115
  end
@@ -117,14 +117,14 @@ module Sequel
117
117
  # Removes the module part from the expression in the string
118
118
  def demodulize(s)
119
119
  s = s.to_s
120
- return s.demodulize if defined?(s.demodulize)
120
+ return s.demodulize if s.respond_to?(:demodulize)
121
121
  s.gsub(/^.*::/, '')
122
122
  end
123
123
 
124
124
  # Returns the plural form of the word in the string.
125
125
  def pluralize(s)
126
126
  s = s.to_s
127
- return s.pluralize if defined?(s.pluralize)
127
+ return s.pluralize if s.respond_to?(:pluralize)
128
128
  result = s.dup
129
129
  Inflections.plurals.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(s.downcase)
130
130
  result
@@ -133,7 +133,7 @@ module Sequel
133
133
  # The reverse of pluralize, returns the singular form of a word in a string.
134
134
  def singularize(s)
135
135
  s = s.to_s
136
- return s.singularize if defined?(s.singularize)
136
+ return s.singularize if s.respond_to?(:singularize)
137
137
  result = s.dup
138
138
  Inflections.singulars.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(s.downcase)
139
139
  result
@@ -143,7 +143,7 @@ module Sequel
143
143
  # Also changes '::' to '/' to convert namespaces to paths.
144
144
  def underscore(s)
145
145
  s = s.to_s
146
- return s.underscore if defined?(s.underscore)
146
+ return s.underscore if s.respond_to?(:underscore)
147
147
  s.gsub('::', '/').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
148
148
  gsub(/([a-z\d])([A-Z])/, '\1_\2').tr('-', '_').downcase
149
149
  end
@@ -252,7 +252,7 @@ module Sequel
252
252
 
253
253
  unless skip.include?(:unique)
254
254
  unique_opts = Hash[opts[:unique]]
255
- if defined?(model.sti_dataset)
255
+ if model.respond_to?(:sti_dataset)
256
256
  unique_opts[:dataset] = model.sti_dataset
257
257
  end
258
258
  model.auto_validate_unique_columns.each{|cols| validates_unique(cols, unique_opts)}
@@ -117,7 +117,7 @@ module Sequel
117
117
  def [](k)
118
118
  if new? && !values.has_key?(k)
119
119
  v = model.default_values.fetch(k){return}
120
- v = v.call if defined?(v.call)
120
+ v = v.call if v.respond_to?(:call)
121
121
  values[k] = v if model.cache_default_values?
122
122
  v
123
123
  else
@@ -203,7 +203,7 @@ module Sequel
203
203
  get_column_value(column)
204
204
  end
205
205
 
206
- initial_values[column] = if value && value != true && defined?(value.clone)
206
+ initial_values[column] = if value && value != true && value.respond_to?(:clone)
207
207
  begin
208
208
  value.clone
209
209
  rescue TypeError
@@ -36,7 +36,7 @@ module Sequel
36
36
  module InsertConflict
37
37
  def self.configure(model)
38
38
  model.instance_exec do
39
- if @dataset && !defined?(@dataset.insert_conflict)
39
+ if @dataset && !@dataset.respond_to?(:insert_conflict)
40
40
  raise Error, "#{self}'s dataset does not support insert_conflict"
41
41
  end
42
42
  end
@@ -152,7 +152,7 @@ module Sequel
152
152
  if obj.is_a?(Array)
153
153
  obj.map{|x| object_to_json_data(x, *args, &block)}
154
154
  else
155
- if defined?(obj.to_json_data)
155
+ if obj.respond_to?(:to_json_data)
156
156
  obj.to_json_data(*args, &block)
157
157
  else
158
158
  begin
@@ -259,7 +259,7 @@ module Sequel
259
259
  # specific :fields if configured.
260
260
  def nested_attributes_set_attributes(meta, obj, attributes)
261
261
  if fields = meta[:fields]
262
- fields = fields.call(obj) if defined?(fields.call)
262
+ fields = fields.call(obj) if fields.respond_to?(:call)
263
263
  obj.set_fields(attributes, fields, :missing=>:skip)
264
264
  else
265
265
  obj.set(attributes)
@@ -159,7 +159,7 @@ module Sequel
159
159
 
160
160
  case @dataset.first_source_table
161
161
  when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
162
- convert_errors = defined?(db.error_info)
162
+ convert_errors = db.respond_to?(:error_info)
163
163
  end
164
164
 
165
165
  unless convert_errors
@@ -162,7 +162,7 @@ module Sequel
162
162
  if !cc.include?(column) && (new? || get_column_value(column) != v)
163
163
  cc << column
164
164
 
165
- will_change_column(column) if defined?(will_change_column)
165
+ will_change_column(column) if respond_to?(:will_change_column)
166
166
  end
167
167
 
168
168
  deserialized_values[column] = v
@@ -91,7 +91,7 @@ module Sequel
91
91
  # +many_to_many+ association, make sure the associated object is created on the
92
92
  # current object's shard, unless the passed object already has an assigned shard.
93
93
  def ensure_associated_primary_key(opts, o, *args)
94
- o.set_server?(@server) if defined?(o.set_server?)
94
+ o.set_server?(@server) if o.respond_to?(:set_server?)
95
95
  super
96
96
  end
97
97
 
@@ -35,7 +35,7 @@ module Sequel
35
35
  # class B < Sequel::Model; end
36
36
  # a # => [A, B]
37
37
  module Subclasses
38
- NEED_SUBCLASSES = !defined?(Object.subclasses) || Object.method(:subclasses).source_location
38
+ NEED_SUBCLASSES = !Object.respond_to?(:subclasses) || Object.method(:subclasses).source_location
39
39
  private_constant :NEED_SUBCLASSES
40
40
 
41
41
  # Initialize the subclasses instance variable for the model.
@@ -282,7 +282,7 @@ module Sequel
282
282
  o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && v.size == i
283
283
  end
284
284
  if w = opts[:within]
285
- o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && w.public_send(defined?(w.cover?) ? :cover? : :include?, v.size)
285
+ o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && w.public_send(w.respond_to?(:cover?) ? :cover? : :include?, v.size)
286
286
  end
287
287
  end
288
288
  end
@@ -337,14 +337,14 @@ module Sequel
337
337
  def validates_inclusion_of(*atts)
338
338
  opts = extract_options!(atts)
339
339
  n = opts[:in]
340
- unless n && (defined?(n.cover?) || defined?(n.include?))
340
+ unless n && (n.respond_to?(:cover?) || n.respond_to?(:include?))
341
341
  raise ArgumentError, "The :in parameter is required, and must respond to cover? or include?"
342
342
  end
343
343
  opts[:message] ||= "is not in range or set: #{n.inspect}"
344
344
  reflect_validation(:inclusion, opts, atts)
345
345
  atts << opts
346
346
  validates_each(*atts) do |o, a, v|
347
- o.errors.add(a, opts[:message]) unless n.public_send(defined?(n.cover?) ? :cover? : :include?, v)
347
+ o.errors.add(a, opts[:message]) unless n.public_send(n.respond_to?(:cover?) ? :cover? : :include?, v)
348
348
  end
349
349
  end
350
350
 
@@ -107,7 +107,7 @@ module Sequel
107
107
 
108
108
  # Check attribute value(s) is included in the given set.
109
109
  def validates_includes(set, atts, opts=OPTS)
110
- validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.public_send(defined?(set.cover?) ? :cover? : :include?, v)}
110
+ validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.public_send(set.respond_to?(:cover?) ? :cover? : :include?, v)}
111
111
  end
112
112
 
113
113
  # Check attribute value(s) string representation is a valid integer.
data/lib/sequel/sql.rb CHANGED
@@ -1347,7 +1347,7 @@ module Sequel
1347
1347
  # underlying callable only accepts a single argument, call it
1348
1348
  # with the given dataset.
1349
1349
  def call(ds)
1350
- if defined?(@callable.arity) && @callable.arity == 1
1350
+ if @callable.respond_to?(:arity) && @callable.arity == 1
1351
1351
  @callable.call(ds)
1352
1352
  else
1353
1353
  @callable.call
@@ -6,7 +6,7 @@ module Sequel
6
6
 
7
7
  # The minor version of Sequel. Bumped for every non-patch level
8
8
  # release, generally around once a month.
9
- MINOR = 60
9
+ MINOR = 61
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.60.0
4
+ version: 5.61.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-01 00:00:00.000000000 Z
11
+ date: 2022-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -192,6 +192,7 @@ extra_rdoc_files:
192
192
  - doc/release_notes/5.59.0.txt
193
193
  - doc/release_notes/5.6.0.txt
194
194
  - doc/release_notes/5.60.0.txt
195
+ - doc/release_notes/5.61.0.txt
195
196
  - doc/release_notes/5.7.0.txt
196
197
  - doc/release_notes/5.8.0.txt
197
198
  - doc/release_notes/5.9.0.txt
@@ -280,6 +281,7 @@ files:
280
281
  - doc/release_notes/5.59.0.txt
281
282
  - doc/release_notes/5.6.0.txt
282
283
  - doc/release_notes/5.60.0.txt
284
+ - doc/release_notes/5.61.0.txt
283
285
  - doc/release_notes/5.7.0.txt
284
286
  - doc/release_notes/5.8.0.txt
285
287
  - doc/release_notes/5.9.0.txt