sequel 3.40.0 → 3.41.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/CHANGELOG +40 -0
  2. data/README.rdoc +2 -2
  3. data/doc/advanced_associations.rdoc +12 -0
  4. data/doc/bin_sequel.rdoc +144 -0
  5. data/doc/migration.rdoc +1 -1
  6. data/doc/object_model.rdoc +29 -0
  7. data/doc/release_notes/3.41.0.txt +155 -0
  8. data/lib/sequel/adapters/ado.rb +4 -4
  9. data/lib/sequel/adapters/amalgalite.rb +0 -5
  10. data/lib/sequel/adapters/cubrid.rb +2 -2
  11. data/lib/sequel/adapters/db2.rb +9 -5
  12. data/lib/sequel/adapters/dbi.rb +4 -6
  13. data/lib/sequel/adapters/do.rb +4 -5
  14. data/lib/sequel/adapters/firebird.rb +8 -4
  15. data/lib/sequel/adapters/ibmdb.rb +2 -3
  16. data/lib/sequel/adapters/informix.rb +0 -6
  17. data/lib/sequel/adapters/jdbc.rb +11 -7
  18. data/lib/sequel/adapters/jdbc/db2.rb +22 -0
  19. data/lib/sequel/adapters/jdbc/derby.rb +5 -5
  20. data/lib/sequel/adapters/jdbc/h2.rb +0 -5
  21. data/lib/sequel/adapters/jdbc/jtds.rb +1 -1
  22. data/lib/sequel/adapters/jdbc/sqlserver.rb +6 -0
  23. data/lib/sequel/adapters/mock.rb +3 -3
  24. data/lib/sequel/adapters/mysql.rb +7 -7
  25. data/lib/sequel/adapters/mysql2.rb +0 -5
  26. data/lib/sequel/adapters/odbc.rb +4 -4
  27. data/lib/sequel/adapters/openbase.rb +4 -6
  28. data/lib/sequel/adapters/oracle.rb +14 -6
  29. data/lib/sequel/adapters/postgres.rb +12 -8
  30. data/lib/sequel/adapters/shared/db2.rb +5 -0
  31. data/lib/sequel/adapters/shared/firebird.rb +10 -0
  32. data/lib/sequel/adapters/shared/mssql.rb +43 -1
  33. data/lib/sequel/adapters/shared/mysql.rb +1 -0
  34. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +1 -1
  35. data/lib/sequel/adapters/shared/postgres.rb +12 -0
  36. data/lib/sequel/adapters/shared/sqlite.rb +32 -0
  37. data/lib/sequel/adapters/sqlite.rb +9 -8
  38. data/lib/sequel/adapters/swift.rb +3 -8
  39. data/lib/sequel/adapters/tinytds.rb +5 -5
  40. data/lib/sequel/connection_pool.rb +13 -19
  41. data/lib/sequel/connection_pool/sharded_single.rb +12 -12
  42. data/lib/sequel/connection_pool/sharded_threaded.rb +37 -17
  43. data/lib/sequel/connection_pool/single.rb +6 -3
  44. data/lib/sequel/connection_pool/threaded.rb +33 -13
  45. data/lib/sequel/database/connecting.rb +28 -1
  46. data/lib/sequel/database/logging.rb +1 -1
  47. data/lib/sequel/database/misc.rb +2 -5
  48. data/lib/sequel/database/query.rb +2 -2
  49. data/lib/sequel/database/schema_generator.rb +1 -1
  50. data/lib/sequel/database/schema_methods.rb +3 -0
  51. data/lib/sequel/dataset/query.rb +8 -4
  52. data/lib/sequel/dataset/sql.rb +7 -0
  53. data/lib/sequel/extensions/arbitrary_servers.rb +1 -1
  54. data/lib/sequel/extensions/connection_validator.rb +109 -0
  55. data/lib/sequel/extensions/pg_array.rb +2 -0
  56. data/lib/sequel/extensions/pg_hstore.rb +2 -0
  57. data/lib/sequel/extensions/pg_json.rb +4 -0
  58. data/lib/sequel/extensions/pg_range.rb +1 -0
  59. data/lib/sequel/extensions/pg_row.rb +4 -0
  60. data/lib/sequel/plugins/prepared_statements.rb +2 -1
  61. data/lib/sequel/plugins/single_table_inheritance.rb +53 -10
  62. data/lib/sequel/plugins/touch.rb +18 -6
  63. data/lib/sequel/plugins/validation_class_methods.rb +1 -0
  64. data/lib/sequel/plugins/validation_helpers.rb +3 -1
  65. data/lib/sequel/sql.rb +61 -19
  66. data/lib/sequel/version.rb +1 -1
  67. data/spec/adapters/firebird_spec.rb +52 -38
  68. data/spec/adapters/mssql_spec.rb +67 -0
  69. data/spec/adapters/mysql_spec.rb +192 -116
  70. data/spec/adapters/postgres_spec.rb +133 -70
  71. data/spec/adapters/spec_helper.rb +7 -0
  72. data/spec/adapters/sqlite_spec.rb +34 -1
  73. data/spec/core/connection_pool_spec.rb +79 -75
  74. data/spec/core/database_spec.rb +9 -4
  75. data/spec/core/dataset_spec.rb +15 -0
  76. data/spec/core/expression_filters_spec.rb +40 -2
  77. data/spec/extensions/connection_validator_spec.rb +118 -0
  78. data/spec/extensions/pg_array_spec.rb +4 -0
  79. data/spec/extensions/single_table_inheritance_spec.rb +42 -0
  80. data/spec/extensions/touch_spec.rb +40 -0
  81. data/spec/extensions/validation_class_methods_spec.rb +19 -1
  82. data/spec/extensions/validation_helpers_spec.rb +17 -0
  83. data/spec/integration/database_test.rb +14 -0
  84. data/spec/integration/dataset_test.rb +3 -3
  85. data/spec/integration/plugin_test.rb +41 -12
  86. data/spec/integration/schema_test.rb +14 -0
  87. data/spec/integration/spec_helper.rb +7 -0
  88. data/spec/integration/type_test.rb +3 -0
  89. metadata +9 -3
@@ -229,6 +229,14 @@ module Sequel
229
229
  conn
230
230
  end
231
231
 
232
+ # Disconnect given connection
233
+ def disconnect_connection(conn)
234
+ begin
235
+ conn.finish
236
+ rescue PGError
237
+ end
238
+ end
239
+
232
240
  # Execute the given SQL with the given args on an available connection.
233
241
  def execute(sql, opts={}, &block)
234
242
  synchronize(opts[:server]){|conn| check_database_errors{_execute(conn, sql, opts, &block)}}
@@ -453,14 +461,10 @@ module Sequel
453
461
  sqls
454
462
  end
455
463
 
456
- # Disconnect given connection
457
- def disconnect_connection(conn)
458
- begin
459
- conn.finish
460
- rescue PGError
461
- end
464
+ def database_error_classes
465
+ [PGError]
462
466
  end
463
-
467
+
464
468
  # Execute the prepared statement with the given name on an available
465
469
  # connection, using the given args. If the connection has not prepared
466
470
  # a statement with the given name yet, prepare it. If the connection
@@ -479,8 +483,8 @@ module Sequel
479
483
 
480
484
  unless conn.prepared_statements[ps_name] == sql
481
485
  conn.execute("DEALLOCATE #{ps_name}") if conn.prepared_statements.include?(ps_name)
482
- conn.prepared_statements[ps_name] = sql
483
486
  conn.check_disconnect_errors{log_yield("PREPARE #{ps_name} AS #{sql}"){conn.prepare(ps_name, sql)}}
487
+ conn.prepared_statements[ps_name] = sql
484
488
  end
485
489
 
486
490
  log_sql = "EXECUTE #{ps_name}"
@@ -176,6 +176,11 @@ module Sequel
176
176
  "CALL ADMIN_CMD(#{literal("REORG TABLE #{table}")})"
177
177
  end
178
178
 
179
+ # Treat clob as blob if use_clob_as_blob is true
180
+ def schema_column_type(db_type)
181
+ (::Sequel::DB2::use_clob_as_blob && db_type.downcase == 'clob') ? :blob : super
182
+ end
183
+
179
184
  # We uses the clob type by default for Files.
180
185
  # Note: if user select to use blob, then insert statement should use
181
186
  # use this for blob value:
@@ -154,6 +154,7 @@ module Sequel
154
154
  INSERT_CLAUSE_METHODS = Dataset.clause_methods(:insert, %w'insert into columns values returning')
155
155
  FIRST = " FIRST ".freeze
156
156
  SKIP = " SKIP ".freeze
157
+ DEFAULT_FROM = " FROM RDB$DATABASE"
157
158
 
158
159
  # Insert given values into the database.
159
160
  def insert(*values)
@@ -206,6 +207,15 @@ module Sequel
206
207
  SELECT_CLAUSE_METHODS
207
208
  end
208
209
 
210
+ # Use a default FROM table if the dataset does not contain a FROM table.
211
+ def select_from_sql(sql)
212
+ if @opts[:from]
213
+ super
214
+ else
215
+ sql << DEFAULT_FROM
216
+ end
217
+ end
218
+
209
219
  def select_limit_sql(sql)
210
220
  if l = @opts[:limit]
211
221
  sql << FIRST
@@ -13,6 +13,7 @@ module Sequel
13
13
  SQL_ROLLBACK_TO_SAVEPOINT = 'IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_%d'.freeze
14
14
  SQL_SAVEPOINT = 'SAVE TRANSACTION autopoint_%d'.freeze
15
15
  MSSQL_DEFAULT_RE = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/
16
+ FOREIGN_KEY_ACTION_MAP = {0 => :no_action, 1 => :cascade, 2 => :set_null, 3 => :set_default}.freeze
16
17
 
17
18
  include Sequel::Database::SplitAlterTable
18
19
 
@@ -36,6 +37,47 @@ module Sequel
36
37
  false
37
38
  end
38
39
 
40
+ # Return foreign key information using the system views, including
41
+ # :name, :on_delete, and :on_update entries in the hashes.
42
+ def foreign_key_list(table, opts={})
43
+ m = output_identifier_meth
44
+ im = input_identifier_meth
45
+ schema, table = schema_and_table(table)
46
+ current_schema = m.call(get(Sequel.function('schema_name')))
47
+ fk_action_map = FOREIGN_KEY_ACTION_MAP
48
+ ds = metadata_dataset.from(:sys__foreign_keys___fk).
49
+ join(:sys__foreign_key_columns___fkc, :constraint_object_id => :object_id).
50
+ join(:sys__all_columns___pc, :object_id => :fkc__parent_object_id, :column_id => :fkc__parent_column_id).
51
+ join(:sys__all_columns___rc, :object_id => :fkc__referenced_object_id, :column_id => :fkc__referenced_column_id).
52
+ where{{object_schema_name(:fk__parent_object_id) => im.call(schema || current_schema)}}.
53
+ where{{object_name(:fk__parent_object_id) => im.call(table)}}.
54
+ select{[:fk__name,
55
+ :fk__delete_referential_action,
56
+ :fk__update_referential_action,
57
+ :pc__name___column,
58
+ :rc__name___referenced_column,
59
+ object_schema_name(:fk__referenced_object_id).as(:schema),
60
+ object_name(:fk__referenced_object_id).as(:table)]}.
61
+ order(:name, :fkc__constraint_column_id)
62
+ h = {}
63
+ ds.each do |row|
64
+ if r = h[row[:name]]
65
+ r[:columns] << m.call(row[:column])
66
+ r[:key] << m.call(row[:referenced_column])
67
+ else
68
+ referenced_schema = m.call(row[:schema])
69
+ referenced_table = m.call(row[:table])
70
+ h[row[:name]] = { :name => m.call(row[:name]),
71
+ :table => (referenced_schema == current_schema) ? referenced_table : :"#{referenced_schema}__#{referenced_table}",
72
+ :columns => [m.call(row[:column])],
73
+ :key => [m.call(row[:referenced_column])],
74
+ :on_update => fk_action_map[row[:update_referential_action]],
75
+ :on_delete => fk_action_map[row[:delete_referential_action]] }
76
+ end
77
+ end
78
+ h.values
79
+ end
80
+
39
81
  # Use the system tables to get index information
40
82
  def indexes(table, opts={})
41
83
  m = output_identifier_meth
@@ -203,7 +245,7 @@ module Sequel
203
245
  if server_version >= 9000000
204
246
  table_name = schema_and_table(table).compact.join('.')
205
247
  self[:sys__default_constraints].
206
- where{{:parent_object_id => object_id(table_name), col_name(:parent_object_id, :parent_column_id) => column_name.to_s}}.
248
+ where{{:parent_object_id => Sequel::SQL::Function.new(:object_id, table_name), col_name(:parent_object_id, :parent_column_id) => column_name.to_s}}.
207
249
  get(:name)
208
250
  end
209
251
  end
@@ -195,6 +195,7 @@ module Sequel
195
195
  opts[:null] = o == :set_column_null ? op[:null] : opts[:allow_null]
196
196
  opts[:default] = o == :set_column_default ? op[:default] : opts[:ruby_default]
197
197
  opts.delete(:default) if opts[:default] == nil
198
+ opts.delete(:primary_key)
198
199
  "CHANGE COLUMN #{quote_identifier(op[:name])} #{column_definition_sql(op.merge(opts))}"
199
200
  when :drop_constraint
200
201
  type = case op[:type]
@@ -56,8 +56,8 @@ module Sequel
56
56
  sql = ps.prepared_sql
57
57
  synchronize(opts[:server]) do |conn|
58
58
  unless conn.prepared_statements[ps_name] == sql
59
- conn.prepared_statements[ps_name] = sql
60
59
  _execute(conn, "PREPARE #{ps_name} FROM #{literal(sql)}", opts)
60
+ conn.prepared_statements[ps_name] = sql
61
61
  end
62
62
  i = 0
63
63
  _execute(conn, "SET " + args.map {|arg| "@sequel_arg_#{i+=1} = #{literal(arg)}"}.join(", "), opts) unless args.empty?
@@ -97,6 +97,7 @@ module Sequel
97
97
  SYSTEM_TABLE_REGEXP = /^pg|sql/.freeze
98
98
  FOREIGN_KEY_LIST_ON_DELETE_MAP = {'a'.freeze=>:no_action, 'r'.freeze=>:restrict, 'c'.freeze=>:cascade, 'n'.freeze=>:set_null, 'd'.freeze=>:set_default}.freeze
99
99
  POSTGRES_DEFAULT_RE = /\A(?:B?('.*')::[^']+|\((-?\d+(?:\.\d+)?)\))\z/
100
+ UNLOGGED = 'UNLOGGED '.freeze
100
101
 
101
102
  # SQL fragment for custom sequences (ones not created by serial primary key),
102
103
  # Returning the schema and literal form of the sequence name, by parsing
@@ -634,6 +635,17 @@ module Sequel
634
635
  "CREATE SCHEMA #{quote_identifier(name)}"
635
636
  end
636
637
 
638
+ # DDL statement for creating a table with the given name, columns, and options
639
+ def create_table_prefix_sql(name, options)
640
+ temp_or_unlogged_sql = if options[:temp]
641
+ raise(Error, "can't provide both :temp and :unlogged to create_table") if options[:unlogged]
642
+ temporary_table_sql
643
+ elsif options[:unlogged]
644
+ UNLOGGED
645
+ end
646
+ "CREATE #{temp_or_unlogged_sql}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)}"
647
+ end
648
+
637
649
  # Use a PostgreSQL-specific create table generator
638
650
  def create_table_generator_class
639
651
  Postgres::CreateTableGenerator
@@ -10,6 +10,12 @@ module Sequel
10
10
  TABLES_FILTER = "type = 'table' AND NOT name = 'sqlite_sequence'".freeze
11
11
  TEMP_STORE = [:default, :file, :memory].freeze
12
12
  VIEWS_FILTER = "type = 'view'".freeze
13
+ TRANSACTION_MODE = {
14
+ :deferred => "BEGIN DEFERRED TRANSACTION".freeze,
15
+ :immediate => "BEGIN IMMEDIATE TRANSACTION".freeze,
16
+ :exclusive => "BEGIN EXCLUSIVE TRANSACTION".freeze,
17
+ nil => Sequel::Database::SQL_BEGIN,
18
+ }.freeze
13
19
 
14
20
  # Whether to use integers for booleans in the database. SQLite recommends
15
21
  # booleans be stored as integers, but historically Sequel has used 't'/'f'.
@@ -35,6 +41,19 @@ module Sequel
35
41
  pragma_set(:case_sensitive_like, !!value ? 'on' : 'off') if sqlite_version >= 30203
36
42
  end
37
43
 
44
+ # A symbol signifying the value of the default transaction mode
45
+ def transaction_mode
46
+ defined?(@transaction_mode) ? @transaction_mode : (@transaction_mode = nil)
47
+ end
48
+
49
+ def transaction_mode=(value)
50
+ if TRANSACTION_MODE.include?(value)
51
+ @transaction_mode = value
52
+ else
53
+ raise Error, "Invalid value for transaction_mode. Please specify one of :deferred, :immediate, :exclusive, nil"
54
+ end
55
+ end
56
+
38
57
  # SQLite uses the :sqlite database type.
39
58
  def database_type
40
59
  :sqlite
@@ -244,6 +263,13 @@ module Sequel
244
263
  end
245
264
  end
246
265
 
266
+ def begin_new_transaction(conn, opts)
267
+ mode = opts[:mode] || @transaction_mode
268
+ sql = TRANSACTION_MODE[mode] or raise Error, "transaction :mode must be one of: :deferred, :immediate, :exclusive, nil"
269
+ log_connection_execute(conn, sql)
270
+ set_transaction_isolation(conn, opts)
271
+ end
272
+
247
273
  # A name to use for the backup table
248
274
  def backup_table_name(table, opts={})
249
275
  table = table.gsub('`', '')
@@ -258,6 +284,12 @@ module Sequel
258
284
  sql << " DEFAULT (#{literal(column[:default])})" if column.include?(:default)
259
285
  end
260
286
 
287
+ # Add null/not null SQL fragment to column creation SQL.
288
+ def column_definition_null_sql(sql, column)
289
+ column = column.merge(:null=>false) if column[:primary_key]
290
+ super(sql, column)
291
+ end
292
+
261
293
  # Array of PRAGMA SQL statements based on the Database options that should be applied to
262
294
  # new connections.
263
295
  def connection_pragmas
@@ -117,6 +117,12 @@ module Sequel
117
117
 
118
118
  db
119
119
  end
120
+
121
+ # Disconnect given connections from the database.
122
+ def disconnect_connection(c)
123
+ c.prepared_statements.each_value{|v| v.first.close}
124
+ c.close
125
+ end
120
126
 
121
127
  # Run the given SQL with the given arguments and yield each row.
122
128
  def execute(sql, opts={}, &block)
@@ -244,15 +250,10 @@ module Sequel
244
250
  end
245
251
  end
246
252
 
247
- # The main error class that SQLite3 raises
253
+ # SQLite3 raises ArgumentError in addition to SQLite3::Exception in
254
+ # some cases, such as operations on a closed database.
248
255
  def database_error_classes
249
- [SQLite3::Exception]
250
- end
251
-
252
- # Disconnect given connections from the database.
253
- def disconnect_connection(c)
254
- c.prepared_statements.each_value{|v| v.first.close}
255
- c.close
256
+ [SQLite3::Exception, ArgumentError]
256
257
  end
257
258
  end
258
259
 
@@ -107,15 +107,10 @@ module Sequel
107
107
  :execute
108
108
  end
109
109
 
110
- # Close the given database connection.
111
- def disconnect_connection(c)
110
+ def database_error_classes
111
+ [::Swift::Error]
112
112
  end
113
-
114
- # Execute SQL on the connection
115
- def log_connection_execute(conn, sql)
116
- log_yield(sql){conn.execute(sql)}
117
- end
118
-
113
+
119
114
  # Set the :db entry to the same as the :database entry, since
120
115
  # Swift uses :db.
121
116
  def server_opts(o)
@@ -108,16 +108,16 @@ module Sequel
108
108
  [TinyTds::Error]
109
109
  end
110
110
 
111
- # Close the TinyTds::Client object.
112
- def disconnect_connection(c)
113
- c.close
114
- end
115
-
116
111
  # Return true if the :conn argument is present and not active.
117
112
  def disconnect_error?(e, opts)
118
113
  super || (opts[:conn] && !opts[:conn].active?)
119
114
  end
120
115
 
116
+ # Dispose of any possible results of execution.
117
+ def log_connection_execute(conn, sql)
118
+ log_yield(sql){conn.execute(sql).each}
119
+ end
120
+
121
121
  # Return a 2 element array with the literal value and type to use
122
122
  # in the prepared statement call for the given value and connection.
123
123
  def ps_arg_type(v)
@@ -2,15 +2,13 @@
2
2
  # on. This class is not instantiated directly, but subclasses should at
3
3
  # the very least implement the following API:
4
4
  #
5
- # initialize(Hash, &block) :: The +block+ is used as the connection proc,
6
- # which should accept a single symbol argument.
5
+ # initialize(Database, Hash) :: Initialize using the passed Sequel::Database
6
+ # object and options hash.
7
7
  # hold(Symbol, &block) :: Yield a connection object (obtained from calling
8
8
  # the block passed to +initialize+) to the current block. For sharded
9
9
  # connection pools, the Symbol passed is the shard/server to use.
10
- # disconnect(Symbol, &block) :: Disconnect the connection object. If a
11
- # block is given, pass the connection option to it, otherwise use the
12
- # <tt>:disconnection_proc</tt> option in the hash passed to initialize. For sharded
13
- # connection pools, the Symbol passed is the shard/server to use.
10
+ # disconnect(Symbol) :: Disconnect the connection object. For sharded
11
+ # connection pools, the Symbol passed is the shard/server to use.
14
12
  # servers :: An array of shard/server symbols for all shards/servers that this
15
13
  # connection pool recognizes.
16
14
  # size :: an integer representing the total number of connections in the pool,
@@ -39,13 +37,13 @@ class Sequel::ConnectionPool
39
37
  # option is provided is provided, use that pool class, otherwise
40
38
  # use a new instance of an appropriate pool subclass based on the
41
39
  # <tt>:single_threaded</tt> and <tt>:servers</tt> options.
42
- def get_pool(opts = {}, &block)
40
+ def get_pool(db, opts = {})
43
41
  case v = connection_pool_class(opts)
44
42
  when Class
45
- v.new(opts, &block)
43
+ v.new(db, opts)
46
44
  when Symbol
47
45
  Sequel.ts_require("connection_pool/#{v}")
48
- connection_pool_class(opts).new(opts, &block) || raise(Sequel::Error, "No connection pool class found")
46
+ connection_pool_class(opts).new(db, opts) || raise(Sequel::Error, "No connection pool class found")
49
47
  end
50
48
  end
51
49
 
@@ -62,10 +60,9 @@ class Sequel::ConnectionPool
62
60
  # connection made, and is usually used to set custom per-connection settings.
63
61
  attr_accessor :after_connect
64
62
 
65
- # The disconnect_proc used for the pool. This is called with each connection
66
- # that is disconnected, usually to clean up related resources.
67
- attr_accessor :disconnection_proc
68
-
63
+ # The Sequel::Database object tied to this connection pool.
64
+ attr_accessor :db
65
+
69
66
  # Instantiates a connection pool with the given options. The block is called
70
67
  # with a single symbol (specifying the server/shard to use) every time a new
71
68
  # connection is needed. The following options are respected for all connection
@@ -73,11 +70,8 @@ class Sequel::ConnectionPool
73
70
  # :after_connect :: The proc called after each new connection is made, with the
74
71
  # connection object, useful for customizations that you want to apply to all
75
72
  # connections.
76
- # :disconnection_proc :: The proc called when removing connections from the pool,
77
- # which is passed the connection to disconnect.
78
- def initialize(opts={}, &block)
79
- raise(Sequel::Error, "No connection proc specified") unless @connection_proc = block
80
- @disconnection_proc = opts[:disconnection_proc]
73
+ def initialize(db, opts={})
74
+ @db = db
81
75
  @after_connect = opts[:after_connect]
82
76
  end
83
77
 
@@ -97,7 +91,7 @@ class Sequel::ConnectionPool
97
91
  # and checking for connection errors.
98
92
  def make_new(server)
99
93
  begin
100
- conn = @connection_proc.call(server)
94
+ conn = @db.connect(server)
101
95
  @after_connect.call(conn) if @after_connect
102
96
  rescue Exception=>exception
103
97
  raise Sequel.convert_exception_class(exception, Sequel::DatabaseConnectionError)
@@ -1,18 +1,15 @@
1
1
  # A ShardedSingleConnectionPool is a single threaded connection pool that
2
2
  # works with multiple shards/servers.
3
3
  class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
4
- # Initializes the instance with the supplied block as the connection_proc.
5
- #
6
4
  # The single threaded pool takes the following options:
7
5
  #
8
6
  # * :servers - A hash of servers to use. Keys should be symbols. If not
9
- # present, will use a single :default server. The server name symbol will
10
- # be passed to the connection_proc.
7
+ # present, will use a single :default server.
11
8
  # * :servers_hash - The base hash to use for the servers. By default,
12
9
  # Sequel uses Hash.new(:default). You can use a hash with a default proc
13
10
  # that raises an error if you want to catch all cases where a nonexistent
14
11
  # server is used.
15
- def initialize(opts={}, &block)
12
+ def initialize(db, opts={})
16
13
  super
17
14
  @conns = {}
18
15
  @servers = opts.fetch(:servers_hash, Hash.new(:default))
@@ -41,9 +38,8 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
41
38
  # #hold, the connection is reestablished. Options:
42
39
  # * :server - Should be a symbol specifing the server to disconnect from,
43
40
  # or an array of symbols to specify multiple servers.
44
- def disconnect(opts={}, &block)
45
- block ||= @disconnection_proc
46
- (opts[:server] ? Array(opts[:server]) : servers).each{|s| disconnect_server(s, &block)}
41
+ def disconnect(opts={})
42
+ (opts[:server] ? Array(opts[:server]) : servers).each{|s| disconnect_server(s)}
47
43
  end
48
44
 
49
45
  # Yields the connection to the supplied block for the given server.
@@ -53,7 +49,7 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
53
49
  server = pick_server(server)
54
50
  yield(@conns[server] ||= make_new(server))
55
51
  rescue Sequel::DatabaseDisconnectError
56
- disconnect_server(server, &@disconnection_proc)
52
+ disconnect_server(server)
57
53
  raise
58
54
  end
59
55
  end
@@ -65,7 +61,7 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
65
61
  def remove_servers(servers)
66
62
  raise(Sequel::Error, "cannot remove default server") if servers.include?(:default)
67
63
  servers.each do |server|
68
- disconnect_server(server, &@disconnection_proc)
64
+ disconnect_server(server)
69
65
  @servers.delete(server)
70
66
  end
71
67
  end
@@ -80,12 +76,16 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
80
76
  @conns.length
81
77
  end
82
78
 
79
+ def pool_type
80
+ :sharded_single
81
+ end
82
+
83
83
  private
84
84
 
85
85
  # Disconnect from the given server, if connected.
86
- def disconnect_server(server, &block)
86
+ def disconnect_server(server)
87
87
  if conn = @conns.delete(server)
88
- block.call(conn) if block
88
+ db.disconnect_connection(conn)
89
89
  end
90
90
  end
91
91