sequel 5.59.0 → 5.60.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +10 -0
  3. data/README.rdoc +1 -1
  4. data/bin/sequel +11 -3
  5. data/doc/release_notes/5.60.0.txt +22 -0
  6. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -1
  7. data/lib/sequel/adapters/jdbc.rb +5 -5
  8. data/lib/sequel/adapters/mock.rb +1 -1
  9. data/lib/sequel/adapters/mysql.rb +3 -3
  10. data/lib/sequel/adapters/oracle.rb +1 -1
  11. data/lib/sequel/adapters/postgres.rb +46 -11
  12. data/lib/sequel/adapters/shared/mssql.rb +1 -1
  13. data/lib/sequel/adapters/shared/oracle.rb +1 -1
  14. data/lib/sequel/adapters/shared/postgres.rb +26 -14
  15. data/lib/sequel/adapters/shared/sqlite.rb +1 -1
  16. data/lib/sequel/adapters/sqlite.rb +1 -1
  17. data/lib/sequel/ast_transformer.rb +1 -1
  18. data/lib/sequel/database/misc.rb +2 -2
  19. data/lib/sequel/dataset/sql.rb +2 -2
  20. data/lib/sequel/extensions/date_arithmetic.rb +35 -7
  21. data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
  22. data/lib/sequel/extensions/is_distinct_from.rb +3 -1
  23. data/lib/sequel/extensions/pg_array.rb +2 -2
  24. data/lib/sequel/extensions/pg_array_ops.rb +1 -1
  25. data/lib/sequel/extensions/pg_enum.rb +1 -1
  26. data/lib/sequel/extensions/pg_hstore_ops.rb +3 -3
  27. data/lib/sequel/extensions/pg_inet.rb +2 -2
  28. data/lib/sequel/extensions/pg_interval.rb +1 -1
  29. data/lib/sequel/extensions/pg_json.rb +1 -1
  30. data/lib/sequel/extensions/pg_json_ops.rb +3 -3
  31. data/lib/sequel/extensions/pg_multirange.rb +2 -2
  32. data/lib/sequel/extensions/pg_range.rb +2 -2
  33. data/lib/sequel/extensions/pg_row.rb +2 -2
  34. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  35. data/lib/sequel/extensions/symbol_aref.rb +2 -0
  36. data/lib/sequel/model/associations.rb +6 -6
  37. data/lib/sequel/model/base.rb +3 -3
  38. data/lib/sequel/model/exceptions.rb +1 -1
  39. data/lib/sequel/model/inflections.rb +6 -6
  40. data/lib/sequel/plugins/auto_validations.rb +1 -1
  41. data/lib/sequel/plugins/defaults_setter.rb +1 -1
  42. data/lib/sequel/plugins/dirty.rb +1 -1
  43. data/lib/sequel/plugins/insert_conflict.rb +1 -1
  44. data/lib/sequel/plugins/json_serializer.rb +1 -1
  45. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  46. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +1 -1
  47. data/lib/sequel/plugins/serialization.rb +1 -1
  48. data/lib/sequel/plugins/sharding.rb +1 -1
  49. data/lib/sequel/plugins/sql_comments.rb +4 -4
  50. data/lib/sequel/plugins/subclasses.rb +1 -1
  51. data/lib/sequel/plugins/validation_class_methods.rb +3 -3
  52. data/lib/sequel/plugins/validation_helpers.rb +1 -1
  53. data/lib/sequel/sql.rb +1 -1
  54. data/lib/sequel/version.rb +1 -1
  55. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47d7144911d61be13cc600fc3153c8e30eb384476ea7fb94ce61bd0f2f627c36
4
- data.tar.gz: fa763e2f24d5b6b26feecb405b5a43d8bbf30d2b727590e8fd98031640dfef2a
3
+ metadata.gz: 1bd9076a491b881827f095bbb1177974861448054cd73376ee76a42ed0f72ee5
4
+ data.tar.gz: e2e23f283d2d9f5b29df1510f5f39c8335cc47c37d0f92c848763cd437d4e668
5
5
  SHA512:
6
- metadata.gz: 3855f6fbb47f26bfd0e9570ed8b7e908815bc7de3752751b92708c3e88948719f62dafe26cc1ea83b598c73e1ee84e4dbf12f01437dd1b087eed68ca4281b33d
7
- data.tar.gz: 932fa5c97bc8dcf077a50961b2da7ecd59ae0c077409c2b0c3111d875fe468d5fbb4030f155faf17d3ba3ed0392e264d8e5ebaa11ad04db3ab98c209e2199440
6
+ metadata.gz: 309b37a25a51bc38c30c20276b7df1df4d21b6b14502b129fc363a0ac9bfc4897be03c21ec1d5b4b333eb6c1944491e4383406bb3f2cb96ba8dd1e98b513de42
7
+ data.tar.gz: 58adf4e309a3bd1d921f95d168a79830cce4526767b8ee9379ce69463327b10f0db4ded44a4a8e474cd0dd31036546b120f3e38a07c3057a5290933cffd3b77a
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ === 5.60.0 (2022-09-01)
2
+
3
+ * Support arbitrary expressions for date_arithmetic interval values on PostgreSQL 9.4+ (jeremyevans)
4
+
5
+ * Support native IS DISTINCT FROM on SQLite 3.39+ instead of emulating support in the is_distinct_from extension (jeremyevans)
6
+
7
+ * Support HAVING without GROUP BY on SQLite 3.39+ (jeremyevans)
8
+
9
+ * Convert most respond_to? calls to equivalent defined? for better performance (jeremyevans)
10
+
1
11
  === 5.59.0 (2022-08-01)
2
12
 
3
13
  * Set :allow_eager association option to false for instance specific associations without eager loaders (jeremyevans)
data/README.rdoc CHANGED
@@ -416,7 +416,7 @@ As with +delete+, +update+ affects all rows in the dataset, so +where+ first,
416
416
 
417
417
  === Merging records
418
418
 
419
- Merging records using the SQL MERGE statment is done using <tt>merge*</tt> methods.
419
+ Merging records using the SQL MERGE statement is done using <tt>merge*</tt> methods.
420
420
  You use +merge_using+ to specify the merge source and join conditions.
421
421
  You can use +merge_insert+, +merge_delete+, and/or +merge_update+ to set the
422
422
  INSERT, DELETE, and UPDATE clauses for the merge. +merge_insert+ takes the same
data/bin/sequel CHANGED
@@ -194,7 +194,11 @@ begin
194
194
  TO_DB = connect_proc[db2]
195
195
  same_db = DB.database_type==TO_DB.database_type
196
196
  index_opts = {:same_db=>same_db}
197
+
198
+ # :nocov:
197
199
  index_opts[:index_names] = :namespace if !DB.global_index_namespace? && TO_DB.global_index_namespace?
200
+ # :nocov:
201
+
198
202
  if DB.database_type == :sqlite && !same_db
199
203
  # SQLite integer types allows 64-bit integers
200
204
  TO_DB.extension :integer64
@@ -212,18 +216,20 @@ begin
212
216
  puts "Begin copying data"
213
217
  DB.transaction do
214
218
  TO_DB.transaction do
219
+ all_status_lines = ENV['SEQUEL_BIN_STATUS_ALL_LINES']
220
+
215
221
  DB.tables.each do |table|
216
222
  puts "Begin copying records for table: #{table}"
217
223
  time = Time.now
218
224
  to_ds = TO_DB.from(table)
219
225
  j = 0
220
226
  DB.from(table).each do |record|
221
- if Time.now - time > 5
227
+ to_ds.insert(record)
228
+ j += 1
229
+ if Time.now - time > 5 || all_status_lines
222
230
  puts "Status: #{j} records copied"
223
231
  time = Time.now
224
232
  end
225
- to_ds.insert(record)
226
- j += 1
227
233
  end
228
234
  puts "Finished copying #{j} records for table: #{table}"
229
235
  end
@@ -260,8 +266,10 @@ if !ARGV.empty?
260
266
  ARGV.each{|v| load(v)}
261
267
  elsif !$stdin.isatty
262
268
  eval($stdin.read)
269
+ # :nocov:
263
270
  else
264
271
  require 'irb'
265
272
  puts "Your database is stored in DB..."
266
273
  IRB.start
267
274
  end
275
+ # :nocov:
@@ -0,0 +1,22 @@
1
+ = New Features
2
+
3
+ * The date_arithmetic extension now supports arbitrary expressions
4
+ as interval values on PostgreSQL 9.4+. Previously, only integers
5
+ were supported for the interval values.
6
+
7
+ = Other Improvements
8
+
9
+ * Most Kernel#respond_to? calls have been converted to equivalent
10
+ defined? calls for better performance. defined? is a keyword
11
+ and is about 50% faster for the same behavior.
12
+
13
+ * The is_distinct_from extension now supports the IS DISTINCT FROM
14
+ syntax natively on SQLite 3.39+, instead of emulating it.
15
+
16
+ * HAVING without GROUP BY is now supported on SQLite 3.39+.
17
+
18
+ * Coverage testing has been significantly expanded. Previously,
19
+ the core, model, plugin, and extension code had 100% line/branch
20
+ coverage. 100% line/branch coverage has been added for the
21
+ core extensions, bin/sequel, and the postgres adapter with the
22
+ pg driver.
@@ -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 exception.respond_to?(:resultCode)
128
+ exception.resultCode.code if defined?(exception.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 jdbc_module.respond_to?(:load_driver)
41
+ jdbc_module.load_driver if defined?(jdbc_module.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 exception.respond_to?(:cause)
399
+ while defined?(exception.cause)
400
400
  exception = exception.cause
401
- return exception.getSQLState if exception.respond_to?(:getSQLState)
401
+ return exception.getSQLState if defined?(exception.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 = exception.respond_to?(:cause) ? exception.cause : exception
419
- super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
418
+ cause = defined?(exception.cause) ? exception.cause : exception
419
+ super || (defined?(cause.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 mod.respond_to?(:mock_adapter_setup)
260
+ if defined?(mod.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 Mysql.respond_to?(:init)
75
+ if defined?(Mysql.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 conn.respond_to?(:more_results?)
189
+ if defined?(conn.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 conn.respond_to?(:more_results?)
210
+ if defined?(conn.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 exception.respond_to?(:code)
152
+ return super unless defined?(exception.code)
153
153
  case exception.code
154
154
  when 1400, 1407
155
155
  NotNullConstraintViolation
@@ -5,6 +5,7 @@ require_relative 'shared/postgres'
5
5
  begin
6
6
  require 'pg'
7
7
 
8
+ # :nocov:
8
9
  Sequel::Postgres::PGError = PG::Error if defined?(PG::Error)
9
10
  Sequel::Postgres::PGconn = PG::Connection if defined?(PG::Connection)
10
11
  Sequel::Postgres::PGresult = PG::Result if defined?(PG::Result)
@@ -14,14 +15,17 @@ begin
14
15
  raise LoadError unless defined?(PGconn::CONNECTION_OK)
15
16
  end
16
17
 
17
- Sequel::Postgres::USES_PG = true
18
18
  if defined?(PG::TypeMapByClass)
19
+ # :nocov:
19
20
  type_map = Sequel::Postgres::PG_QUERY_TYPE_MAP = PG::TypeMapByClass.new
20
21
  type_map[Integer] = PG::TextEncoder::Integer.new
21
22
  type_map[FalseClass] = type_map[TrueClass] = PG::TextEncoder::Boolean.new
22
23
  type_map[Float] = PG::TextEncoder::Float.new
23
24
  end
25
+
26
+ Sequel::Postgres::USES_PG = true
24
27
  rescue LoadError => e
28
+ # :nocov:
25
29
  begin
26
30
  require 'sequel/postgres-pr'
27
31
  rescue LoadError
@@ -32,16 +36,19 @@ rescue LoadError => e
32
36
  end
33
37
  end
34
38
  Sequel::Postgres::USES_PG = false
39
+ # :nocov:
35
40
  end
36
41
 
37
42
  module Sequel
38
43
  module Postgres
44
+ # :nocov:
39
45
  if USES_PG
40
46
  # Whether the given sequel_pg version integer is supported.
41
47
  def self.sequel_pg_version_supported?(version)
42
48
  version >= 10617
43
49
  end
44
50
  end
51
+ # :nocov:
45
52
 
46
53
  # PGconn subclass for connection specific methods used with the
47
54
  # pg or postgres-pr driver.
@@ -49,7 +56,9 @@ module Sequel
49
56
  # The underlying exception classes to reraise as disconnect errors
50
57
  # instead of regular database errors.
51
58
  DISCONNECT_ERROR_CLASSES = [IOError, Errno::EPIPE, Errno::ECONNRESET]
59
+ # :nocov:
52
60
  if defined?(::PG::ConnectionBad)
61
+ # :nocov:
53
62
  DISCONNECT_ERROR_CLASSES << ::PG::ConnectionBad
54
63
  end
55
64
  DISCONNECT_ERROR_CLASSES.freeze
@@ -75,6 +84,7 @@ module Sequel
75
84
  # are SQL strings.
76
85
  attr_reader :prepared_statements
77
86
 
87
+ # :nocov:
78
88
  unless public_method_defined?(:async_exec_params)
79
89
  alias async_exec_params async_exec
80
90
  end
@@ -117,6 +127,7 @@ module Sequel
117
127
  alias cmd_tuples cmdtuples
118
128
  end
119
129
  end
130
+ # :nocov:
120
131
 
121
132
  # Raise a Sequel::DatabaseDisconnectError if a one of the disconnect
122
133
  # error classes is raised, or a PGError is raised and the connection
@@ -149,7 +160,7 @@ module Sequel
149
160
  begin
150
161
  defined?(yield) ? yield(q) : q.cmd_tuples
151
162
  ensure
152
- q.clear if q && q.respond_to?(:clear)
163
+ q.clear if q && defined?(q.clear)
153
164
  end
154
165
  end
155
166
 
@@ -210,7 +221,9 @@ module Sequel
210
221
  :sslmode => opts[:sslmode],
211
222
  :sslrootcert => opts[:sslrootcert]
212
223
  }.delete_if { |key, value| blank_object?(value) }
224
+ # :nocov:
213
225
  connection_params.merge!(opts[:driver_options]) if opts[:driver_options]
226
+ # :nocov:
214
227
  conn = Adapter.connect(opts[:conn_str] || connection_params)
215
228
 
216
229
  conn.instance_variable_set(:@prepared_statements, {})
@@ -218,6 +231,13 @@ module Sequel
218
231
  if receiver = opts[:notice_receiver]
219
232
  conn.set_notice_receiver(&receiver)
220
233
  end
234
+
235
+ # :nocov:
236
+ if conn.respond_to?(:type_map_for_queries=) && defined?(PG_QUERY_TYPE_MAP)
237
+ # :nocov:
238
+ conn.type_map_for_queries = PG_QUERY_TYPE_MAP
239
+ end
240
+ # :nocov:
221
241
  else
222
242
  unless typecast_value_boolean(@opts.fetch(:force_standard_strings, true))
223
243
  raise Error, "Cannot create connection using postgres-pr unless force_standard_strings is set"
@@ -232,19 +252,19 @@ module Sequel
232
252
  opts[:password]
233
253
  )
234
254
  end
255
+ # :nocov:
235
256
 
236
257
  conn.instance_variable_set(:@db, self)
237
- if USES_PG && conn.respond_to?(:type_map_for_queries=) && defined?(PG_QUERY_TYPE_MAP)
238
- conn.type_map_for_queries = PG_QUERY_TYPE_MAP
239
- end
240
258
 
259
+ # :nocov:
241
260
  if encoding = opts[:encoding] || opts[:charset]
242
- if conn.respond_to?(:set_client_encoding)
261
+ if defined?(conn.set_client_encoding)
243
262
  conn.set_client_encoding(encoding)
244
263
  else
245
264
  conn.async_exec("set client_encoding to '#{encoding}'")
246
265
  end
247
266
  end
267
+ # :nocov:
248
268
 
249
269
  connection_configuration_sqls(opts).each{|sql| conn.execute(sql)}
250
270
  conn
@@ -271,7 +291,9 @@ module Sequel
271
291
  nil
272
292
  end
273
293
 
294
+ # :nocov:
274
295
  if USES_PG && Object.const_defined?(:PG) && ::PG.const_defined?(:Constants) && ::PG::Constants.const_defined?(:PG_DIAG_SCHEMA_NAME)
296
+ # :nocov:
275
297
  # Return a hash of information about the related PGError (or Sequel::DatabaseError that
276
298
  # wraps a PGError), with the following entries (any of which may be +nil+):
277
299
  #
@@ -322,7 +344,9 @@ module Sequel
322
344
  synchronize(opts[:server]){|conn| check_database_errors{_execute(conn, sql, opts, &block)}}
323
345
  end
324
346
 
347
+ # :nocov:
325
348
  if USES_PG
349
+ # :nocov:
326
350
  # +copy_table+ uses PostgreSQL's +COPY TO STDOUT+ SQL statement to return formatted
327
351
  # results directly to the caller. This method is only supported if pg is the
328
352
  # underlying ruby driver. This method should only be called if you want
@@ -468,12 +492,12 @@ module Sequel
468
492
  opts[:after_listen].call(conn) if opts[:after_listen]
469
493
  timeout = opts[:timeout]
470
494
  if timeout
471
- timeout_block = timeout.respond_to?(:call) ? timeout : proc{timeout}
495
+ timeout_block = defined?(timeout.call) ? timeout : proc{timeout}
472
496
  end
473
497
 
474
498
  if l = opts[:loop]
475
499
  raise Error, 'calling #listen with :loop requires a block' unless block
476
- loop_call = l.respond_to?(:call)
500
+ loop_call = defined?(l.call)
477
501
  catch(:stop) do
478
502
  while true
479
503
  t = timeout_block ? [timeout_block.call] : []
@@ -515,8 +539,10 @@ module Sequel
515
539
  def adapter_initialize
516
540
  @use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, true))
517
541
  initialize_postgres_adapter
542
+ # :nocov:
518
543
  add_conversion_proc(17, method(:unescape_bytea)) if USES_PG
519
544
  add_conversion_proc(1082, TYPE_TRANSLATOR_DATE) if @use_iso_date_format
545
+ # :nocov:
520
546
  self.convert_infinite_timestamps = @opts[:convert_infinite_timestamps]
521
547
  end
522
548
 
@@ -526,19 +552,22 @@ module Sequel
526
552
  rescue => e
527
553
  raise_error(e, :classes=>database_error_classes)
528
554
  end
529
-
530
555
  # Set the DateStyle to ISO if configured, for faster date parsing.
531
556
  def connection_configuration_sqls(opts=@opts)
532
557
  sqls = super
558
+ # :nocov:
533
559
  sqls << "SET DateStyle = 'ISO'" if @use_iso_date_format
560
+ # :nocov:
534
561
  sqls
535
562
  end
536
563
 
564
+ # :nocov:
537
565
  if USES_PG
538
566
  def unescape_bytea(s)
539
567
  ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s))
540
568
  end
541
569
  end
570
+ # :nocov:
542
571
 
543
572
  DATABASE_ERROR_CLASSES = [PGError].freeze
544
573
  def database_error_classes
@@ -552,7 +581,9 @@ module Sequel
552
581
  end
553
582
 
554
583
  def database_exception_sqlstate(exception, opts)
555
- if exception.respond_to?(:result) && (result = exception.result)
584
+ # :nocov:
585
+ if defined?(exception.result) && (result = exception.result)
586
+ # :nocov:
556
587
  result.error_field(PGresult::PG_DIAG_SQLSTATE)
557
588
  end
558
589
  end
@@ -594,7 +625,7 @@ module Sequel
594
625
  begin
595
626
  defined?(yield) ? yield(q) : q.cmd_tuples
596
627
  ensure
597
- q.clear if q && q.respond_to?(:clear)
628
+ q.clear if q && defined?(q.clear)
598
629
  end
599
630
  end
600
631
 
@@ -662,7 +693,9 @@ module Sequel
662
693
  clone(:where=>Sequel.lit(['CURRENT OF '], Sequel.identifier(cursor_name)))
663
694
  end
664
695
 
696
+ # :nocov:
665
697
  if USES_PG
698
+ # :nocov:
666
699
  PREPARED_ARG_PLACEHOLDER = LiteralString.new('$').freeze
667
700
 
668
701
  # PostgreSQL specific argument mapper used for mapping the named
@@ -809,6 +842,7 @@ module Sequel
809
842
  end
810
843
  end
811
844
 
845
+ # :nocov:
812
846
  if Sequel::Postgres::USES_PG && !ENV['NO_SEQUEL_PG']
813
847
  begin
814
848
  require 'sequel_pg'
@@ -820,3 +854,4 @@ if Sequel::Postgres::USES_PG && !ENV['NO_SEQUEL_PG']
820
854
  rescue LoadError
821
855
  end
822
856
  end
857
+ # :nocov:
@@ -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 conn.respond_to?(:server_version)
208
+ (conn.server_version rescue nil) if defined?(conn.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 conn.respond_to?(:server_version)
124
+ (conn.server_version rescue nil) if defined?(conn.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)
@@ -230,7 +230,6 @@ module Sequel
230
230
  module DatabaseMethods
231
231
  include UnmodifiedIdentifiers::DatabaseMethods
232
232
 
233
- PREPARED_ARG_PLACEHOLDER = LiteralString.new('$').freeze
234
233
  FOREIGN_KEY_LIST_ON_DELETE_MAP = {'a'=>:no_action, 'r'=>:restrict, 'c'=>:cascade, 'n'=>:set_null, 'd'=>:set_default}.freeze
235
234
  ON_COMMIT = {:drop => 'DROP', :delete_rows => 'DELETE ROWS', :preserve_rows => 'PRESERVE ROWS'}.freeze
236
235
  ON_COMMIT.each_value(&:freeze)
@@ -365,9 +364,10 @@ module Sequel
365
364
 
366
365
  table_oid = regclass_oid(table)
367
366
  im = input_identifier_meth
368
- unless column = im.call(opts[:column] || ((sch = schema(table).find{|_, sc| sc[:primary_key] && sc[:auto_increment]}) && sch[0]))
367
+ unless column = (opts[:column] || ((sch = schema(table).find{|_, sc| sc[:primary_key] && sc[:auto_increment]}) && sch[0]))
369
368
  raise Error, "could not determine column to convert from serial to identity automatically"
370
369
  end
370
+ column = im.call(column)
371
371
 
372
372
  column_num = ds.from(:pg_attribute).
373
373
  where(:attrelid=>table_oid, :attname=>column).
@@ -569,10 +569,12 @@ module Sequel
569
569
  if server_version >= 90500
570
570
  cpos = Sequel.expr{array_position(co[:conkey], ctable[:attnum])}
571
571
  rpos = Sequel.expr{array_position(co[:confkey], rtable[:attnum])}
572
+ # :nocov:
572
573
  else
573
574
  range = 0...32
574
575
  cpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:conkey], [x]), x]}, 32, ctable[:attnum])}
575
576
  rpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:confkey], [x]), x]}, 32, rtable[:attnum])}
577
+ # :nocov:
576
578
  end
577
579
 
578
580
  ds = metadata_dataset.
@@ -653,9 +655,11 @@ module Sequel
653
655
 
654
656
  if server_version >= 90500
655
657
  order = [Sequel[:indc][:relname], Sequel.function(:array_position, Sequel[:ind][:indkey], Sequel[:att][:attnum])]
658
+ # :nocov:
656
659
  else
657
660
  range = 0...32
658
661
  order = [Sequel[:indc][:relname], SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(Sequel[:ind][:indkey], [x]), x]}, 32, Sequel[:att][:attnum])]
662
+ # :nocov:
659
663
  end
660
664
 
661
665
  attnums = SQL::Function.new(:ANY, Sequel[:ind][:indkey])
@@ -676,8 +680,10 @@ module Sequel
676
680
  select{[indc[:relname].as(:name), ind[:indisunique].as(:unique), att[:attname].as(:column), con[:condeferrable].as(:deferrable)]}
677
681
 
678
682
  ds = ds.where(:indpred=>nil) unless opts[:include_partial]
683
+ # :nocov:
679
684
  ds = ds.where(:indisready=>true) if server_version >= 80300
680
685
  ds = ds.where(:indislive=>true) if server_version >= 90300
686
+ # :nocov:
681
687
 
682
688
  indexes = {}
683
689
  ds.each do |r|
@@ -758,10 +764,12 @@ module Sequel
758
764
  seq_ds = metadata_dataset.from(:pg_sequence).where(:seqrelid=>regclass_oid(LiteralString.new(seq)))
759
765
  increment_by = :seqincrement
760
766
  min_value = :seqmin
767
+ # :nocov:
761
768
  else
762
769
  seq_ds = metadata_dataset.from(LiteralString.new(seq))
763
770
  increment_by = :increment_by
764
771
  min_value = :min_value
772
+ # :nocov:
765
773
  end
766
774
 
767
775
  get{setval(seq, db[table].select(coalesce(max(pk)+seq_ds.select(increment_by), seq_ds.select(min_value))), false)}
@@ -774,7 +782,9 @@ module Sequel
774
782
  # PostgreSQL uses SERIAL psuedo-type instead of AUTOINCREMENT for
775
783
  # managing incrementing primary keys.
776
784
  def serial_primary_key_options
785
+ # :nocov:
777
786
  auto_increment_key = server_version >= 100002 ? :identity : :serial
787
+ # :nocov:
778
788
  {:primary_key => true, auto_increment_key => true, :type=>Integer}
779
789
  end
780
790
 
@@ -1152,7 +1162,7 @@ module Sequel
1152
1162
  when :hash
1153
1163
  mod, remainder = generator.hash_values
1154
1164
  sql << " FOR VALUES WITH (MODULUS #{literal(mod)}, REMAINDER #{literal(remainder)})"
1155
- when :default
1165
+ else # when :default
1156
1166
  sql << " DEFAULT"
1157
1167
  end
1158
1168
 
@@ -1356,11 +1366,6 @@ module Sequel
1356
1366
  end
1357
1367
  end
1358
1368
 
1359
- # Use a dollar sign instead of question mark for the argument placeholder.
1360
- def prepared_arg_placeholder
1361
- PREPARED_ARG_PLACEHOLDER
1362
- end
1363
-
1364
1369
  # Return an expression the oid for the table expr. Used by the metadata parsing
1365
1370
  # code to disambiguate unqualified tables.
1366
1371
  def regclass_oid(expr, opts=OPTS)
@@ -1434,10 +1439,14 @@ module Sequel
1434
1439
  where{{pg_class[:oid]=>oid}}.
1435
1440
  order{pg_attribute[:attnum]}
1436
1441
 
1442
+ # :nocov:
1437
1443
  if server_version > 100000
1444
+ # :nocov:
1438
1445
  ds = ds.select_append{pg_attribute[:attidentity]}
1439
1446
 
1447
+ # :nocov:
1440
1448
  if server_version > 120000
1449
+ # :nocov:
1441
1450
  ds = ds.select_append{Sequel.~(pg_attribute[:attgenerated]=>'').as(:generated)}
1442
1451
  end
1443
1452
  end
@@ -1525,7 +1534,9 @@ module Sequel
1525
1534
 
1526
1535
  # PostgreSQL 9.4+ supports views with check option.
1527
1536
  def view_with_check_option_support
1537
+ # :nocov:
1528
1538
  :local if server_version >= 90400
1539
+ # :nocov:
1529
1540
  end
1530
1541
  end
1531
1542
 
@@ -1921,6 +1932,8 @@ module Sequel
1921
1932
  server_version >= 90000
1922
1933
  when :groups, :exclude
1923
1934
  server_version >= 110000
1935
+ else
1936
+ false
1924
1937
  end
1925
1938
  end
1926
1939
 
@@ -2067,12 +2080,11 @@ module Sequel
2067
2080
 
2068
2081
  # Return the primary key to use for RETURNING in an INSERT statement
2069
2082
  def insert_pk
2070
- if (f = opts[:from]) && !f.empty?
2071
- case t = f.first
2072
- when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
2073
- if pk = db.primary_key(t)
2074
- Sequel::SQL::Identifier.new(pk)
2075
- end
2083
+ (f = opts[:from]) && !f.empty? && (t = f.first)
2084
+ case t
2085
+ when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
2086
+ if pk = db.primary_key(t)
2087
+ Sequel::SQL::Identifier.new(pk)
2076
2088
  end
2077
2089
  end
2078
2090
  end
@@ -663,7 +663,7 @@ module Sequel
663
663
 
664
664
  # HAVING requires GROUP BY on SQLite
665
665
  def having(*cond)
666
- raise(InvalidOperation, "Can only specify a HAVING clause on a grouped dataset") unless @opts[:group]
666
+ raise(InvalidOperation, "Can only specify a HAVING clause on a grouped dataset") if !@opts[:group] && db.sqlite_version < 33900
667
667
  super
668
668
  end
669
669
 
@@ -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 exception.respond_to?(:code)
308
+ exception.code if defined?(exception.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 o.respond_to?(:sequel_ast_transform)
84
+ if defined?(o.sequel_ast_transform)
85
85
  o.sequel_ast_transform(method(:v))
86
86
  else
87
87
  o
@@ -350,7 +350,7 @@ module Sequel
350
350
  # strings with all whitespace, and ones that respond
351
351
  # true to empty?
352
352
  def blank_object?(obj)
353
- return obj.blank? if obj.respond_to?(:blank?)
353
+ return obj.blank? if defined?(obj.blank?)
354
354
  case obj
355
355
  when NilClass, FalseClass
356
356
  true
@@ -359,7 +359,7 @@ module Sequel
359
359
  when String
360
360
  obj.strip.empty?
361
361
  else
362
- obj.respond_to?(:empty?) ? obj.empty? : false
362
+ defined?(obj.empty?) ? obj.empty? : false
363
363
  end
364
364
  end
365
365
 
@@ -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 v.respond_to?(:sql_literal_append)
1401
+ if defined?(v.sql_literal_append)
1402
1402
  v.sql_literal_append(self, sql)
1403
- elsif v.respond_to?(:sql_literal)
1403
+ elsif defined?(v.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"