sequel 3.40.0 → 3.41.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 (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