sequel 5.31.0 → 5.36.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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +90 -0
  3. data/README.rdoc +1 -1
  4. data/doc/advanced_associations.rdoc +4 -4
  5. data/doc/association_basics.rdoc +10 -5
  6. data/doc/code_order.rdoc +12 -2
  7. data/doc/dataset_filtering.rdoc +2 -2
  8. data/doc/model_dataset_method_design.rdoc +1 -1
  9. data/doc/model_plugins.rdoc +1 -1
  10. data/doc/release_notes/5.32.0.txt +46 -0
  11. data/doc/release_notes/5.33.0.txt +24 -0
  12. data/doc/release_notes/5.34.0.txt +40 -0
  13. data/doc/release_notes/5.35.0.txt +56 -0
  14. data/doc/release_notes/5.36.0.txt +60 -0
  15. data/doc/testing.rdoc +1 -0
  16. data/doc/validations.rdoc +1 -1
  17. data/lib/sequel/adapters/odbc.rb +4 -6
  18. data/lib/sequel/adapters/oracle.rb +2 -1
  19. data/lib/sequel/adapters/shared/access.rb +6 -6
  20. data/lib/sequel/adapters/shared/mssql.rb +19 -9
  21. data/lib/sequel/adapters/shared/mysql.rb +9 -9
  22. data/lib/sequel/adapters/shared/oracle.rb +28 -22
  23. data/lib/sequel/adapters/shared/postgres.rb +57 -9
  24. data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
  25. data/lib/sequel/adapters/shared/sqlite.rb +14 -3
  26. data/lib/sequel/adapters/tinytds.rb +1 -0
  27. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
  28. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  29. data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
  30. data/lib/sequel/connection_pool/single.rb +1 -1
  31. data/lib/sequel/connection_pool/threaded.rb +2 -2
  32. data/lib/sequel/core.rb +318 -314
  33. data/lib/sequel/database/connecting.rb +1 -1
  34. data/lib/sequel/database/misc.rb +16 -10
  35. data/lib/sequel/database/query.rb +3 -1
  36. data/lib/sequel/database/schema_generator.rb +0 -1
  37. data/lib/sequel/database/schema_methods.rb +15 -16
  38. data/lib/sequel/database/transactions.rb +8 -5
  39. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  40. data/lib/sequel/dataset/query.rb +5 -4
  41. data/lib/sequel/deprecated.rb +3 -1
  42. data/lib/sequel/exceptions.rb +2 -0
  43. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  44. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  45. data/lib/sequel/extensions/connection_expiration.rb +2 -2
  46. data/lib/sequel/extensions/connection_validator.rb +2 -2
  47. data/lib/sequel/extensions/core_refinements.rb +2 -0
  48. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  49. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  50. data/lib/sequel/extensions/index_caching.rb +9 -7
  51. data/lib/sequel/extensions/integer64.rb +2 -0
  52. data/lib/sequel/extensions/migration.rb +1 -1
  53. data/lib/sequel/extensions/pg_array_ops.rb +4 -0
  54. data/lib/sequel/extensions/pg_enum.rb +2 -0
  55. data/lib/sequel/extensions/pg_extended_date_support.rb +1 -1
  56. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  57. data/lib/sequel/extensions/pg_inet.rb +15 -5
  58. data/lib/sequel/extensions/pg_interval.rb +2 -0
  59. data/lib/sequel/extensions/pg_json_ops.rb +46 -2
  60. data/lib/sequel/extensions/pg_range.rb +5 -7
  61. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  62. data/lib/sequel/extensions/pg_row.rb +0 -1
  63. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  64. data/lib/sequel/extensions/query.rb +1 -0
  65. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  66. data/lib/sequel/extensions/s.rb +2 -0
  67. data/lib/sequel/extensions/server_block.rb +3 -3
  68. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  69. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  70. data/lib/sequel/extensions/to_dot.rb +9 -3
  71. data/lib/sequel/model.rb +3 -1
  72. data/lib/sequel/model/associations.rb +54 -25
  73. data/lib/sequel/model/base.rb +60 -51
  74. data/lib/sequel/model/plugins.rb +4 -3
  75. data/lib/sequel/plugins/association_lazy_eager_option.rb +2 -0
  76. data/lib/sequel/plugins/association_multi_add_remove.rb +2 -0
  77. data/lib/sequel/plugins/association_pks.rb +60 -18
  78. data/lib/sequel/plugins/association_proxies.rb +3 -0
  79. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  80. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  81. data/lib/sequel/plugins/class_table_inheritance.rb +28 -28
  82. data/lib/sequel/plugins/csv_serializer.rb +2 -0
  83. data/lib/sequel/plugins/dirty.rb +13 -13
  84. data/lib/sequel/plugins/forbid_lazy_load.rb +2 -0
  85. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  86. data/lib/sequel/plugins/json_serializer.rb +3 -7
  87. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  88. data/lib/sequel/plugins/pg_array_associations.rb +2 -3
  89. data/lib/sequel/plugins/prepared_statements.rb +5 -11
  90. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  91. data/lib/sequel/plugins/rcte_tree.rb +10 -16
  92. data/lib/sequel/plugins/single_table_inheritance.rb +15 -15
  93. data/lib/sequel/plugins/string_stripper.rb +1 -1
  94. data/lib/sequel/plugins/subclasses.rb +2 -0
  95. data/lib/sequel/plugins/validation_class_methods.rb +5 -1
  96. data/lib/sequel/timezones.rb +6 -4
  97. data/lib/sequel/version.rb +1 -1
  98. metadata +15 -2
@@ -162,6 +162,7 @@ SEQUEL_CONNECTION_VALIDATOR :: Use the connection validator extension when runni
162
162
  SEQUEL_DUPLICATE_COLUMNS_HANDLER :: Use the duplicate columns handler extension with value given when running the specs
163
163
  SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
164
164
  SEQUEL_INDEX_CACHING :: Use the index_caching extension when running the specs
165
+ SEQUEL_FIBER_CONCURRENCY :: Use the fiber_concurrency extension when running the adapter and integration specs
165
166
  SEQUEL_FREEZE_DATABASE :: Freeze the database before running the integration specs
166
167
  SEQUEL_IDENTIFIER_MANGLING :: Use the identifier_mangling extension when running the specs
167
168
  SEQUEL_INTEGER64 :: Use the integer64 extension when running the adapter or integration specs
@@ -232,7 +232,7 @@ These methods check that the specified attributes can be valid integers or valid
232
232
 
233
233
  === +validates_operator+
234
234
 
235
- +validates_operator+ checks that a given +operator+ method returns a truthy value when called on attribute with a specified value for comparison. Generally, this is used for inequality checks (>, >=, etc) but any method that can be called on the attribute that accepts an argument and returns a truthy value may be used.
235
+ +validates_operator+ checks that a given +operator+ method returns a truthy value when called on attribute with a specified value for comparison. Generally, this is used for inequality checks (>, >=, etc.) but any method that can be called on the attribute that accepts an argument and returns a truthy value may be used.
236
236
 
237
237
  class Album < Sequel::Model
238
238
  def validate
@@ -92,12 +92,10 @@ module Sequel
92
92
  cols = s.columns(true).map{|c| [output_identifier(c.name), c.type, i+=1]}
93
93
  columns = cols.map{|c| c[0]}
94
94
  self.columns = columns
95
- if rows = s.fetch_all
96
- rows.each do |row|
97
- hash = {}
98
- cols.each{|n,t,j| hash[n] = convert_odbc_value(row[j], t)}
99
- yield hash
100
- end
95
+ s.each do |row|
96
+ hash = {}
97
+ cols.each{|n,t,j| hash[n] = convert_odbc_value(row[j], t)}
98
+ yield hash
101
99
  end
102
100
  end
103
101
  self
@@ -14,7 +14,8 @@ module Sequel
14
14
  # ORA-02396: exceeded maximum idle time, please connect again
15
15
  # ORA-03113: end-of-file on communication channel
16
16
  # ORA-03114: not connected to ORACLE
17
- CONNECTION_ERROR_CODES = [ 28, 1012, 2396, 3113, 3114 ].freeze
17
+ # ORA-03135: connection lost contact
18
+ CONNECTION_ERROR_CODES = [ 28, 1012, 2396, 3113, 3114, 3135 ].freeze
18
19
 
19
20
  ORACLE_TYPES = {
20
21
  :blob=>lambda{|b| Sequel::SQL::Blob.new(b.read)},
@@ -171,6 +171,12 @@ module Sequel
171
171
  clone(:into => table)
172
172
  end
173
173
 
174
+ # Access uses [] for quoting identifiers, and can't handle
175
+ # ] inside identifiers.
176
+ def quoted_identifier_append(sql, v)
177
+ sql << '[' << v.to_s << ']'
178
+ end
179
+
174
180
  # Access does not support derived column lists.
175
181
  def supports_derived_column_lists?
176
182
  false
@@ -279,12 +285,6 @@ module Sequel
279
285
  literal_append(sql, l)
280
286
  end
281
287
  end
282
-
283
- # Access uses [] for quoting identifiers, and can't handle
284
- # ] inside identifiers.
285
- def quoted_identifier_append(sql, v)
286
- sql << '[' << v.to_s << ']'
287
- end
288
288
  end
289
289
  end
290
290
  end
@@ -659,11 +659,11 @@ module Sequel
659
659
  # case by default, and that also adds a default order, so it's better to just
660
660
  # avoid the subquery.
661
661
  def select_sql
662
- if @opts[:offset] && !@opts[:order] && is_2012_or_later?
663
- order(1).select_sql
664
- else
665
- super
662
+ if @opts[:offset]
663
+ raise(Error, "Using with_ties is not supported with an offset on Microsoft SQL Server") if @opts[:limit_with_ties]
664
+ return order(1).select_sql if is_2012_or_later? && !@opts[:order]
666
665
  end
666
+ super
667
667
  end
668
668
 
669
669
  # The version of the database server.
@@ -755,6 +755,12 @@ module Sequel
755
755
  false
756
756
  end
757
757
 
758
+ # Use WITH TIES when limiting the result set to also include additional
759
+ # rows matching the last row.
760
+ def with_ties
761
+ clone(:limit_with_ties=>true)
762
+ end
763
+
758
764
  protected
759
765
 
760
766
  # If returned primary keys are requested, use OUTPUT unless already set on the
@@ -775,11 +781,6 @@ module Sequel
775
781
  end
776
782
  end
777
783
 
778
- # MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
779
- def aggregate_dataset
780
- (options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
781
- end
782
-
783
784
  # If the dataset using a order without a limit or offset or custom SQL,
784
785
  # remove the order. Compounds on Microsoft SQL Server have undefined
785
786
  # order unless the result is specifically ordered. Applying the current
@@ -799,6 +800,11 @@ module Sequel
799
800
 
800
801
  private
801
802
 
803
+ # MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
804
+ def aggregate_dataset
805
+ (options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
806
+ end
807
+
802
808
  # Allow update and delete for unordered, limited datasets only.
803
809
  def check_not_limited!(type)
804
810
  return if @opts[:skip_limit_check] && type != :truncate
@@ -959,6 +965,10 @@ module Sequel
959
965
  sql << " TOP "
960
966
  literal_append(sql, l)
961
967
  end
968
+
969
+ if @opts[:limit_with_ties]
970
+ sql << " WITH TIES"
971
+ end
962
972
  end
963
973
 
964
974
  def update_limit_sql(sql)
@@ -717,15 +717,6 @@ module Sequel
717
717
  SQL::PlaceholderLiteralString.new((opts[:boolean] ? MATCH_AGAINST_BOOLEAN : MATCH_AGAINST), [Array(cols), terms])
718
718
  end
719
719
 
720
- # Transforms :straight to STRAIGHT_JOIN.
721
- def join_type_sql(join_type)
722
- if join_type == :straight
723
- 'STRAIGHT_JOIN'
724
- else
725
- super
726
- end
727
- end
728
-
729
720
  # Sets up the insert methods to use INSERT IGNORE.
730
721
  # Useful if you have a unique key and want to just skip
731
722
  # inserting rows that violate the unique key restriction.
@@ -956,6 +947,15 @@ module Sequel
956
947
  end
957
948
  end
958
949
 
950
+ # Transforms :straight to STRAIGHT_JOIN.
951
+ def join_type_sql(join_type)
952
+ if join_type == :straight
953
+ 'STRAIGHT_JOIN'
954
+ else
955
+ super
956
+ end
957
+ end
958
+
959
959
  # MySQL allows a LIMIT in DELETE and UPDATE statements.
960
960
  def limit_sql(sql)
961
961
  if l = @opts[:limit]
@@ -103,12 +103,18 @@ module Sequel
103
103
  map{|r| m.call(r[:view_name])}
104
104
  end
105
105
 
106
- def view_exists?(name)
107
- m = input_identifier_meth
108
- metadata_dataset.from(:all_views).
109
- exclude(:owner=>IGNORE_OWNERS).
110
- where(:view_name=>m.call(name)).
111
- count > 0
106
+ # Whether a view with a given name exists. By default, looks in all schemas other than system
107
+ # schemas. If the :current_schema option is given, looks in the schema for the current user.
108
+ def view_exists?(name, opts=OPTS)
109
+ ds = metadata_dataset.from(:all_views).where(:view_name=>input_identifier_meth.call(name))
110
+
111
+ if opts[:current_schema]
112
+ ds = ds.where(:owner=>Sequel.function(:SYS_CONTEXT, 'userenv', 'current_schema'))
113
+ else
114
+ ds = ds.exclude(:owner=>IGNORE_OWNERS)
115
+ end
116
+
117
+ ds.count > 0
112
118
  end
113
119
 
114
120
  # The version of the Oracle server, used for determining capability.
@@ -422,22 +428,6 @@ module Sequel
422
428
  end
423
429
  end
424
430
 
425
- def select_limit_sql(sql)
426
- return unless supports_fetch_next_rows?
427
-
428
- if offset = @opts[:offset]
429
- sql << " OFFSET "
430
- literal_append(sql, offset)
431
- sql << " ROWS"
432
- end
433
-
434
- if limit = @opts[:limit]
435
- sql << " FETCH NEXT "
436
- literal_append(sql, limit)
437
- sql << " ROWS ONLY"
438
- end
439
- end
440
-
441
431
  # Oracle requires recursive CTEs to have column aliases.
442
432
  def recursive_cte_requires_column_aliases?
443
433
  true
@@ -624,6 +614,22 @@ module Sequel
624
614
  :union
625
615
  end
626
616
 
617
+ def select_limit_sql(sql)
618
+ return unless supports_fetch_next_rows?
619
+
620
+ if offset = @opts[:offset]
621
+ sql << " OFFSET "
622
+ literal_append(sql, offset)
623
+ sql << " ROWS"
624
+ end
625
+
626
+ if limit = @opts[:limit]
627
+ sql << " FETCH NEXT "
628
+ literal_append(sql, limit)
629
+ sql << " ROWS ONLY"
630
+ end
631
+ end
632
+
627
633
  # Use SKIP LOCKED if skipping locked rows.
628
634
  def select_lock_sql(sql)
629
635
  super
@@ -459,6 +459,16 @@ module Sequel
459
459
  super
460
460
  end
461
461
 
462
+ # Support partitions of tables using the :partition_of option.
463
+ def create_table?(name, options=OPTS, &block)
464
+ if options[:partition_of]
465
+ create_table(name, options.merge!(:if_not_exists=>true), &block)
466
+ return
467
+ end
468
+
469
+ super
470
+ end
471
+
462
472
  # Create a trigger in the database. Arguments:
463
473
  # table :: the table on which this trigger operates
464
474
  # name :: the name of this trigger
@@ -940,7 +950,7 @@ module Sequel
940
950
  # default value is given.
941
951
  def column_definition_default_sql(sql, column)
942
952
  super
943
- if !column[:serial] && !['serial', 'bigserial'].include?(column[:type].to_s) && !column[:default]
953
+ if !column[:serial] && !['smallserial', 'serial', 'bigserial'].include?(column[:type].to_s) && !column[:default]
944
954
  if (identity = column[:identity])
945
955
  sql << " GENERATED "
946
956
  sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
@@ -1875,6 +1885,13 @@ module Sequel
1875
1885
  end
1876
1886
  end
1877
1887
 
1888
+ # Use WITH TIES when limiting the result set to also include additional
1889
+ # rules that have the same results for the order column as the final row.
1890
+ # Requires PostgreSQL 13.
1891
+ def with_ties
1892
+ clone(:limit_with_ties=>true)
1893
+ end
1894
+
1878
1895
  protected
1879
1896
 
1880
1897
  # If returned primary keys are requested, use RETURNING unless already set on the
@@ -1896,6 +1913,14 @@ module Sequel
1896
1913
  end
1897
1914
  end
1898
1915
 
1916
+ def to_prepared_statement(type, *a)
1917
+ if type == :insert && !@opts.has_key?(:returning)
1918
+ returning(insert_pk).send(:to_prepared_statement, :insert_pk, *a)
1919
+ else
1920
+ super
1921
+ end
1922
+ end
1923
+
1899
1924
  private
1900
1925
 
1901
1926
  # Format TRUNCATE statement with PostgreSQL specific options.
@@ -2053,6 +2078,37 @@ module Sequel
2053
2078
  false
2054
2079
  end
2055
2080
 
2081
+ # Support FETCH FIRST WITH TIES on PostgreSQL 13+.
2082
+ def select_limit_sql(sql)
2083
+ l = @opts[:limit]
2084
+ o = @opts[:offset]
2085
+
2086
+ return unless l || o
2087
+
2088
+ if @opts[:limit_with_ties]
2089
+ if o
2090
+ sql << " OFFSET "
2091
+ literal_append(sql, o)
2092
+ end
2093
+
2094
+ if l
2095
+ sql << " FETCH FIRST "
2096
+ literal_append(sql, l)
2097
+ sql << " ROWS WITH TIES"
2098
+ end
2099
+ else
2100
+ if l
2101
+ sql << " LIMIT "
2102
+ literal_append(sql, l)
2103
+ end
2104
+
2105
+ if o
2106
+ sql << " OFFSET "
2107
+ literal_append(sql, o)
2108
+ end
2109
+ end
2110
+ end
2111
+
2056
2112
  # Support FOR SHARE locking when using the :share lock style.
2057
2113
  # Use SKIP LOCKED if skipping locked rows.
2058
2114
  def select_lock_sql(sql)
@@ -2110,14 +2166,6 @@ module Sequel
2110
2166
  true
2111
2167
  end
2112
2168
 
2113
- def to_prepared_statement(type, *a)
2114
- if type == :insert && !@opts.has_key?(:returning)
2115
- returning(insert_pk).send(:to_prepared_statement, :insert_pk, *a)
2116
- else
2117
- super
2118
- end
2119
- end
2120
-
2121
2169
  # Concatenate the expressions with a space in between
2122
2170
  def full_text_string_join(cols)
2123
2171
  cols = Array(cols).map{|x| SQL::Function.new(:COALESCE, x, '')}
@@ -23,15 +23,6 @@ module Sequel
23
23
  to_application_timestamp(v.to_s) if v
24
24
  end
25
25
 
26
- # Convert smallint type to boolean if convert_smallint_to_bool is true
27
- def schema_column_type(db_type)
28
- if convert_smallint_to_bool && db_type =~ /smallint/i
29
- :boolean
30
- else
31
- super
32
- end
33
- end
34
-
35
26
  def schema_parse_table(table, opts)
36
27
  m = output_identifier_meth(opts[:dataset])
37
28
  im = input_identifier_meth(opts[:dataset])
@@ -216,6 +207,15 @@ module Sequel
216
207
  "ALTER TABLE #{quote_schema_table(name)} RENAME #{quote_schema_table(new_name)}"
217
208
  end
218
209
 
210
+ # Convert smallint type to boolean if convert_smallint_to_bool is true
211
+ def schema_column_type(db_type)
212
+ if convert_smallint_to_bool && db_type =~ /smallint/i
213
+ :boolean
214
+ else
215
+ super
216
+ end
217
+ end
218
+
219
219
  def tables_and_views(type, opts=OPTS)
220
220
  m = output_identifier_meth
221
221
  metadata_dataset.
@@ -14,6 +14,7 @@ module Sequel
14
14
  def schema_parse_table(*)
15
15
  []
16
16
  end
17
+ singleton_class.send(:private, :schema_parse_table)
17
18
  end
18
19
  end
19
20
 
@@ -37,6 +38,10 @@ module Sequel
37
38
  # booleans be stored as integers, but historically Sequel has used 't'/'f'.
38
39
  attr_accessor :integer_booleans
39
40
 
41
+ # Whether to keep CURRENT_TIMESTAMP and similar expressions in UTC. By
42
+ # default, the expressions are converted to localtime.
43
+ attr_accessor :current_timestamp_utc
44
+
40
45
  # A symbol signifying the value of the default transaction mode
41
46
  attr_reader :transaction_mode
42
47
 
@@ -264,6 +269,8 @@ module Sequel
264
269
  else
265
270
  duplicate_table(table, :no_foreign_keys=>true)
266
271
  end
272
+ when :unique
273
+ duplicate_table(table, :no_unique=>true)
267
274
  else
268
275
  duplicate_table(table)
269
276
  end
@@ -417,8 +424,12 @@ module Sequel
417
424
  skip_indexes = []
418
425
  indexes(table, :only_autocreated=>true).each do |name, h|
419
426
  skip_indexes << name
420
- if h[:columns].length == 1 && h[:unique]
421
- unique_columns.concat(h[:columns])
427
+ if h[:unique]
428
+ if h[:columns].length == 1
429
+ unique_columns.concat(h[:columns])
430
+ elsif h[:columns].map(&:to_s) != pks && !opts[:no_unique]
431
+ constraints << {:type=>:unique, :columns=>h[:columns]}
432
+ end
422
433
  end
423
434
  end
424
435
  unique_columns -= pks
@@ -614,7 +625,7 @@ module Sequel
614
625
  # SQLite has CURRENT_TIMESTAMP and related constants in UTC instead
615
626
  # of in localtime, so convert those constants to local time.
616
627
  def constant_sql_append(sql, constant)
617
- if c = CONSTANT_MAP[constant]
628
+ if (c = CONSTANT_MAP[constant]) && !db.current_timestamp_utc
618
629
  sql << c
619
630
  else
620
631
  super
@@ -16,6 +16,7 @@ module Sequel
16
16
  c = TinyTds::Client.new(opts)
17
17
  c.query_options.merge!(:cache_rows=>false)
18
18
 
19
+ # SEQUEL6: Default to ansi: true
19
20
  if opts[:ansi]
20
21
  sql = %w(
21
22
  ANSI_NULLS
@@ -18,6 +18,7 @@ module Sequel
18
18
  This connection is still waiting for a result, try again once you have the result
19
19
  closed MySQL connection
20
20
  The MySQL server is running with the --read-only option so it cannot execute this statement
21
+ Connection was killed
21
22
  END
22
23
  # Error messages for mysql and mysql2 that indicate the current connection should be disconnected
23
24
  MYSQL_DATABASE_DISCONNECT_ERRORS = /\A#{Regexp.union(disconnect_errors)}/
@@ -41,7 +41,10 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
41
41
  # :server :: Should be a symbol specifing the server to disconnect from,
42
42
  # or an array of symbols to specify multiple servers.
43
43
  def disconnect(opts=OPTS)
44
- (opts[:server] ? Array(opts[:server]) : servers).each{|s| disconnect_server(s)}
44
+ (opts[:server] ? Array(opts[:server]) : servers).each do |s|
45
+ raise Sequel::Error, "invalid server: #{s}" unless @servers.has_key?(s)
46
+ disconnect_server(s)
47
+ end
45
48
  end
46
49
 
47
50
  def freeze