sequel_core 2.2.0 → 3.8.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.
- metadata +30 -101
- data/CHANGELOG +0 -1519
- data/COPYING +0 -19
- data/README +0 -313
- data/Rakefile +0 -158
- data/bin/sequel +0 -117
- data/doc/cheat_sheet.rdoc +0 -225
- data/doc/dataset_filtering.rdoc +0 -182
- data/lib/sequel_core.rb +0 -136
- data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -68
- data/lib/sequel_core/adapters/ado.rb +0 -90
- data/lib/sequel_core/adapters/db2.rb +0 -160
- data/lib/sequel_core/adapters/dbi.rb +0 -127
- data/lib/sequel_core/adapters/informix.rb +0 -89
- data/lib/sequel_core/adapters/jdbc.rb +0 -110
- data/lib/sequel_core/adapters/mysql.rb +0 -486
- data/lib/sequel_core/adapters/odbc.rb +0 -167
- data/lib/sequel_core/adapters/odbc_mssql.rb +0 -106
- data/lib/sequel_core/adapters/openbase.rb +0 -76
- data/lib/sequel_core/adapters/oracle.rb +0 -182
- data/lib/sequel_core/adapters/postgres.rb +0 -560
- data/lib/sequel_core/adapters/sqlite.rb +0 -270
- data/lib/sequel_core/connection_pool.rb +0 -194
- data/lib/sequel_core/core_ext.rb +0 -197
- data/lib/sequel_core/core_sql.rb +0 -184
- data/lib/sequel_core/database.rb +0 -462
- data/lib/sequel_core/database/schema.rb +0 -156
- data/lib/sequel_core/dataset.rb +0 -457
- data/lib/sequel_core/dataset/callback.rb +0 -13
- data/lib/sequel_core/dataset/convenience.rb +0 -245
- data/lib/sequel_core/dataset/pagination.rb +0 -96
- data/lib/sequel_core/dataset/query.rb +0 -41
- data/lib/sequel_core/dataset/schema.rb +0 -15
- data/lib/sequel_core/dataset/sql.rb +0 -889
- data/lib/sequel_core/deprecated.rb +0 -26
- data/lib/sequel_core/exceptions.rb +0 -42
- data/lib/sequel_core/migration.rb +0 -187
- data/lib/sequel_core/object_graph.rb +0 -216
- data/lib/sequel_core/pretty_table.rb +0 -71
- data/lib/sequel_core/schema.rb +0 -2
- data/lib/sequel_core/schema/generator.rb +0 -239
- data/lib/sequel_core/schema/sql.rb +0 -326
- data/lib/sequel_core/sql.rb +0 -812
- data/lib/sequel_core/worker.rb +0 -68
- data/spec/adapters/informix_spec.rb +0 -96
- data/spec/adapters/mysql_spec.rb +0 -765
- data/spec/adapters/oracle_spec.rb +0 -222
- data/spec/adapters/postgres_spec.rb +0 -441
- data/spec/adapters/sqlite_spec.rb +0 -413
- data/spec/connection_pool_spec.rb +0 -363
- data/spec/core_ext_spec.rb +0 -156
- data/spec/core_sql_spec.rb +0 -427
- data/spec/database_spec.rb +0 -963
- data/spec/dataset_spec.rb +0 -2933
- data/spec/expression_filters_spec.rb +0 -316
- data/spec/migration_spec.rb +0 -261
- data/spec/object_graph_spec.rb +0 -230
- data/spec/pretty_table_spec.rb +0 -58
- data/spec/rcov.opts +0 -6
- data/spec/schema_generator_spec.rb +0 -122
- data/spec/schema_spec.rb +0 -422
- data/spec/spec.opts +0 -0
- data/spec/spec_config.rb +0 -7
- data/spec/spec_config.rb.example +0 -8
- data/spec/spec_helper.rb +0 -55
- data/spec/worker_spec.rb +0 -96
@@ -1,270 +0,0 @@
|
|
1
|
-
require 'sqlite3'
|
2
|
-
|
3
|
-
module Sequel
|
4
|
-
module SQLite
|
5
|
-
class Database < Sequel::Database
|
6
|
-
set_adapter_scheme :sqlite
|
7
|
-
|
8
|
-
def serial_primary_key_options
|
9
|
-
{:primary_key => true, :type => :integer, :auto_increment => true}
|
10
|
-
end
|
11
|
-
|
12
|
-
def connect
|
13
|
-
@opts[:database] = ':memory:' if @opts[:database].blank?
|
14
|
-
db = ::SQLite3::Database.new(@opts[:database])
|
15
|
-
db.busy_timeout(@opts.fetch(:timeout, 5000))
|
16
|
-
db.type_translation = true
|
17
|
-
# fix for timestamp translation
|
18
|
-
db.translator.add_translator("timestamp") do |t, v|
|
19
|
-
v =~ /^\d+$/ ? Time.at(v.to_i) : Time.parse(v)
|
20
|
-
end
|
21
|
-
db
|
22
|
-
end
|
23
|
-
|
24
|
-
def disconnect
|
25
|
-
@pool.disconnect {|c| c.close}
|
26
|
-
end
|
27
|
-
|
28
|
-
def dataset(opts = nil)
|
29
|
-
SQLite::Dataset.new(self, opts)
|
30
|
-
end
|
31
|
-
|
32
|
-
TABLES_FILTER = "type = 'table' AND NOT name = 'sqlite_sequence'"
|
33
|
-
|
34
|
-
def tables
|
35
|
-
self[:sqlite_master].filter(TABLES_FILTER).map {|r| r[:name].to_sym}
|
36
|
-
end
|
37
|
-
|
38
|
-
def execute(sql)
|
39
|
-
begin
|
40
|
-
log_info(sql)
|
41
|
-
@pool.hold {|conn| conn.execute_batch(sql); conn.changes}
|
42
|
-
rescue SQLite3::Exception => e
|
43
|
-
raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def execute_insert(sql)
|
48
|
-
begin
|
49
|
-
log_info(sql)
|
50
|
-
@pool.hold {|conn| conn.execute(sql); conn.last_insert_row_id}
|
51
|
-
rescue SQLite3::Exception => e
|
52
|
-
raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def single_value(sql)
|
57
|
-
begin
|
58
|
-
log_info(sql)
|
59
|
-
@pool.hold {|conn| conn.get_first_value(sql)}
|
60
|
-
rescue SQLite3::Exception => e
|
61
|
-
raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def execute_select(sql, &block)
|
66
|
-
begin
|
67
|
-
log_info(sql)
|
68
|
-
@pool.hold {|conn| conn.query(sql, &block)}
|
69
|
-
rescue SQLite3::Exception => e
|
70
|
-
raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def pragma_get(name)
|
75
|
-
single_value("PRAGMA #{name}")
|
76
|
-
end
|
77
|
-
|
78
|
-
def pragma_set(name, value)
|
79
|
-
execute("PRAGMA #{name} = #{value}")
|
80
|
-
end
|
81
|
-
|
82
|
-
AUTO_VACUUM = {'0' => :none, '1' => :full, '2' => :incremental}.freeze
|
83
|
-
|
84
|
-
def auto_vacuum
|
85
|
-
AUTO_VACUUM[pragma_get(:auto_vacuum)]
|
86
|
-
end
|
87
|
-
|
88
|
-
def auto_vacuum=(value)
|
89
|
-
value = AUTO_VACUUM.index(value) || (raise Error, "Invalid value for auto_vacuum option. Please specify one of :none, :full, :incremental.")
|
90
|
-
pragma_set(:auto_vacuum, value)
|
91
|
-
end
|
92
|
-
|
93
|
-
SYNCHRONOUS = {'0' => :off, '1' => :normal, '2' => :full}.freeze
|
94
|
-
|
95
|
-
def synchronous
|
96
|
-
SYNCHRONOUS[pragma_get(:synchronous)]
|
97
|
-
end
|
98
|
-
|
99
|
-
def synchronous=(value)
|
100
|
-
value = SYNCHRONOUS.index(value) || (raise Error, "Invalid value for synchronous option. Please specify one of :off, :normal, :full.")
|
101
|
-
pragma_set(:synchronous, value)
|
102
|
-
end
|
103
|
-
|
104
|
-
TEMP_STORE = {'0' => :default, '1' => :file, '2' => :memory}.freeze
|
105
|
-
|
106
|
-
def temp_store
|
107
|
-
TEMP_STORE[pragma_get(:temp_store)]
|
108
|
-
end
|
109
|
-
|
110
|
-
def temp_store=(value)
|
111
|
-
value = TEMP_STORE.index(value) || (raise Error, "Invalid value for temp_store option. Please specify one of :default, :file, :memory.")
|
112
|
-
pragma_set(:temp_store, value)
|
113
|
-
end
|
114
|
-
|
115
|
-
def alter_table_sql(table, op)
|
116
|
-
case op[:op]
|
117
|
-
when :add_column
|
118
|
-
"ALTER TABLE #{table} ADD #{column_definition_sql(op)}"
|
119
|
-
when :add_index
|
120
|
-
index_definition_sql(table, op)
|
121
|
-
when :drop_column
|
122
|
-
columns_str = (schema_parse_table(table, {}).map {|c| c[0] } - (Array === op[:name] ? op[:name] : [op[:name]])).join(",")
|
123
|
-
sql = "BEGIN TRANSACTION;\n"
|
124
|
-
sql += "CREATE TEMPORARY TABLE #{table}_backup(#{columns_str});\n"
|
125
|
-
sql += "INSERT INTO #{table}_backup SELECT #{columns_str} FROM #{table};\n"
|
126
|
-
sql += "DROP TABLE #{table};\n"
|
127
|
-
sql += "CREATE TABLE #{table}(#{columns_str});\n"
|
128
|
-
sql += "INSERT INTO #{table} SELECT #{columns_str} FROM #{table}_backup;\n"
|
129
|
-
sql += "DROP TABLE #{table}_backup;\n"
|
130
|
-
sql += "COMMIT;\n"
|
131
|
-
else
|
132
|
-
raise Error, "Unsupported ALTER TABLE operation"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def transaction(&block)
|
137
|
-
@pool.hold do |conn|
|
138
|
-
if conn.transaction_active?
|
139
|
-
return yield(conn)
|
140
|
-
end
|
141
|
-
begin
|
142
|
-
result = nil
|
143
|
-
conn.transaction {result = yield(conn)}
|
144
|
-
result
|
145
|
-
rescue ::Exception => e
|
146
|
-
raise (SQLite3::Exception === e ? Error.new(e.message) : e) unless Error::Rollback === e
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
private
|
152
|
-
def connection_pool_default_options
|
153
|
-
o = super.merge(:pool_convert_exceptions=>false)
|
154
|
-
# Default to only a single connection if a memory database is used,
|
155
|
-
# because otherwise each connection will get a separate database
|
156
|
-
o[:max_connections] = 1 if @opts[:database] == ':memory:' || @opts[:database].blank?
|
157
|
-
o
|
158
|
-
end
|
159
|
-
|
160
|
-
SCHEMA_TYPE_RE = /\A(\w+)\((\d+)\)\z/
|
161
|
-
def schema_parse_table(table_name, opts)
|
162
|
-
rows = self["PRAGMA table_info('#{::SQLite3::Database.quote(table_name.to_s)}')"].collect do |row|
|
163
|
-
row.delete(:cid)
|
164
|
-
row[:column] = row.delete(:name)
|
165
|
-
row[:allow_null] = row.delete(:notnull).to_i == 0 ? 'YES' : 'NO'
|
166
|
-
row[:default] = row.delete(:dflt_value)
|
167
|
-
row[:primary_key] = row.delete(:pk).to_i == 1 ? true : false
|
168
|
-
row[:db_type] = row.delete(:type)
|
169
|
-
if m = SCHEMA_TYPE_RE.match(row[:db_type])
|
170
|
-
row[:db_type] = m[1]
|
171
|
-
row[:max_chars] = m[2].to_i
|
172
|
-
else
|
173
|
-
row[:max_chars] = nil
|
174
|
-
end
|
175
|
-
row[:numeric_precision] = nil
|
176
|
-
row
|
177
|
-
end
|
178
|
-
schema_parse_rows(rows)
|
179
|
-
end
|
180
|
-
|
181
|
-
def schema_parse_tables(opts)
|
182
|
-
schemas = {}
|
183
|
-
tables.each{|table| schemas[table] = schema_parse_table(table, opts)}
|
184
|
-
schemas
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
class Dataset < Sequel::Dataset
|
189
|
-
def quoted_identifier(c)
|
190
|
-
"`#{c}`"
|
191
|
-
end
|
192
|
-
|
193
|
-
def literal(v)
|
194
|
-
case v
|
195
|
-
when LiteralString
|
196
|
-
v
|
197
|
-
when String
|
198
|
-
"'#{::SQLite3::Database.quote(v)}'"
|
199
|
-
when Time
|
200
|
-
literal(v.iso8601)
|
201
|
-
when Date, DateTime
|
202
|
-
literal(v.to_s)
|
203
|
-
else
|
204
|
-
super
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def complex_expression_sql(op, args)
|
209
|
-
case op
|
210
|
-
when :~, :'!~', :'~*', :'!~*'
|
211
|
-
raise Error, "SQLite does not support pattern matching via regular expressions"
|
212
|
-
when :LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE'
|
213
|
-
# SQLite is case insensitive for ASCII, and non case sensitive for other character sets
|
214
|
-
"#{'NOT ' if [:'NOT LIKE', :'NOT ILIKE'].include?(op)}(#{literal(args.at(0))} LIKE #{literal(args.at(1))})"
|
215
|
-
else
|
216
|
-
super(op, args)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def insert_sql(*values)
|
221
|
-
if (values.size == 1) && values.first.is_a?(Sequel::Dataset)
|
222
|
-
"INSERT INTO #{source_list(@opts[:from])} #{values.first.sql};"
|
223
|
-
else
|
224
|
-
super(*values)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def fetch_rows(sql, &block)
|
229
|
-
@db.execute_select(sql) do |result|
|
230
|
-
@columns = result.columns.map {|c| c.to_sym}
|
231
|
-
column_count = @columns.size
|
232
|
-
result.each do |values|
|
233
|
-
row = {}
|
234
|
-
column_count.times {|i| row[@columns[i]] = values[i]}
|
235
|
-
block.call(row)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def insert(*values)
|
241
|
-
@db.execute_insert insert_sql(*values)
|
242
|
-
end
|
243
|
-
|
244
|
-
def update(*args, &block)
|
245
|
-
@db.execute update_sql(*args, &block)
|
246
|
-
end
|
247
|
-
|
248
|
-
def delete(opts = nil)
|
249
|
-
# check if no filter is specified
|
250
|
-
unless (opts && opts[:where]) || @opts[:where]
|
251
|
-
@db.transaction do
|
252
|
-
unfiltered_count = count
|
253
|
-
@db.execute delete_sql(opts)
|
254
|
-
unfiltered_count
|
255
|
-
end
|
256
|
-
else
|
257
|
-
@db.execute delete_sql(opts)
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
EXPLAIN = 'EXPLAIN %s'.freeze
|
262
|
-
|
263
|
-
def explain
|
264
|
-
res = []
|
265
|
-
@db.result_set(EXPLAIN % select_sql(opts), nil) {|r| res << r}
|
266
|
-
res
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
@@ -1,194 +0,0 @@
|
|
1
|
-
# A ConnectionPool manages access to database connections by keeping
|
2
|
-
# multiple connections and giving threads exclusive access to each
|
3
|
-
# connection.
|
4
|
-
class Sequel::ConnectionPool
|
5
|
-
# A hash of connections currently being used, key is the Thread,
|
6
|
-
# value is the connection.
|
7
|
-
attr_reader :allocated
|
8
|
-
|
9
|
-
# An array of connections opened but not currently used
|
10
|
-
attr_reader :available_connections
|
11
|
-
|
12
|
-
# The proc used to create a new database connection.
|
13
|
-
attr_accessor :connection_proc
|
14
|
-
|
15
|
-
# The total number of connections opened, should
|
16
|
-
# be equal to available_connections.length +
|
17
|
-
# allocated.length
|
18
|
-
attr_reader :created_count
|
19
|
-
alias_method :size, :created_count
|
20
|
-
|
21
|
-
# The maximum number of connections.
|
22
|
-
attr_reader :max_size
|
23
|
-
|
24
|
-
# The mutex that protects access to the other internal vairables. You must use
|
25
|
-
# this if you want to manipulate the variables safely.
|
26
|
-
attr_reader :mutex
|
27
|
-
|
28
|
-
|
29
|
-
# Constructs a new pool with a maximum size. If a block is supplied, it
|
30
|
-
# is used to create new connections as they are needed.
|
31
|
-
#
|
32
|
-
# pool = ConnectionPool.new(:max_connections=>10) {MyConnection.new(opts)}
|
33
|
-
#
|
34
|
-
# The connection creation proc can be changed at any time by assigning a
|
35
|
-
# Proc to pool#connection_proc.
|
36
|
-
#
|
37
|
-
# pool = ConnectionPool.new(:max_connections=>10)
|
38
|
-
# pool.connection_proc = proc {MyConnection.new(opts)}
|
39
|
-
#
|
40
|
-
# The connection pool takes the following options:
|
41
|
-
#
|
42
|
-
# * :max_connections - The maximum number of connections the connection pool
|
43
|
-
# will open (default 4)
|
44
|
-
# * :pool_convert_exceptions - Whether to convert non-StandardError based exceptions
|
45
|
-
# to RuntimeError exceptions (default true)
|
46
|
-
# * :pool_sleep_time - The amount of time to sleep before attempting to acquire
|
47
|
-
# a connection again (default 0.001)
|
48
|
-
# * :pool_timeout - The amount of seconds to wait to acquire a connection
|
49
|
-
# before raising a PoolTimeoutError (default 5)
|
50
|
-
def initialize(opts = {}, &block)
|
51
|
-
@max_size = opts[:max_connections] || 4
|
52
|
-
@mutex = Mutex.new
|
53
|
-
@connection_proc = block
|
54
|
-
|
55
|
-
@available_connections = []
|
56
|
-
@allocated = {}
|
57
|
-
@created_count = 0
|
58
|
-
@timeout = opts[:pool_timeout] || 5
|
59
|
-
@sleep_time = opts[:pool_sleep_time] || 0.001
|
60
|
-
@convert_exceptions = opts.include?(:pool_convert_exceptions) ? opts[:pool_convert_exceptions] : true
|
61
|
-
end
|
62
|
-
|
63
|
-
# Chooses the first available connection, or if none are available,
|
64
|
-
# creates a new connection. Passes the connection to the supplied block:
|
65
|
-
#
|
66
|
-
# pool.hold {|conn| conn.execute('DROP TABLE posts')}
|
67
|
-
#
|
68
|
-
# Pool#hold is re-entrant, meaning it can be called recursively in
|
69
|
-
# the same thread without blocking.
|
70
|
-
#
|
71
|
-
# If no connection is immediately available and the pool is already using the maximum
|
72
|
-
# number of connections, Pool#hold will block until a connection
|
73
|
-
# is available or the timeout expires. If the timeout expires before a
|
74
|
-
# connection can be acquired, a Sequel::Error::PoolTimeoutError is
|
75
|
-
# raised.
|
76
|
-
def hold
|
77
|
-
begin
|
78
|
-
t = Thread.current
|
79
|
-
time = Time.new
|
80
|
-
timeout = time + @timeout
|
81
|
-
sleep_time = @sleep_time
|
82
|
-
if conn = owned_connection(t)
|
83
|
-
return yield(conn)
|
84
|
-
end
|
85
|
-
until conn = acquire(t)
|
86
|
-
raise(::Sequel::Error::PoolTimeoutError) if Time.new > timeout
|
87
|
-
sleep sleep_time
|
88
|
-
end
|
89
|
-
begin
|
90
|
-
yield conn
|
91
|
-
ensure
|
92
|
-
release(t, conn)
|
93
|
-
end
|
94
|
-
rescue Exception => e
|
95
|
-
raise(@convert_exceptions && !e.is_a?(StandardError) ? RuntimeError.new(e.message) : e)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Removes all connection currently available, optionally yielding each
|
100
|
-
# connection to the given block. This method has the effect of
|
101
|
-
# disconnecting from the database. Once a connection is requested using
|
102
|
-
# #hold, the connection pool creates new connections to the database.
|
103
|
-
def disconnect(&block)
|
104
|
-
@mutex.synchronize do
|
105
|
-
@available_connections.each {|c| block[c]} if block
|
106
|
-
@available_connections = []
|
107
|
-
@created_count = @allocated.size
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
private
|
112
|
-
|
113
|
-
# Returns the connection owned by the supplied thread, if any.
|
114
|
-
def owned_connection(thread)
|
115
|
-
@mutex.synchronize{@allocated[thread]}
|
116
|
-
end
|
117
|
-
|
118
|
-
# Assigns a connection to the supplied thread, if one is available.
|
119
|
-
def acquire(thread)
|
120
|
-
@mutex.synchronize do
|
121
|
-
if conn = available
|
122
|
-
@allocated[thread] = conn
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Returns an available connection. If no connection is available,
|
128
|
-
# tries to create a new connection.
|
129
|
-
def available
|
130
|
-
@available_connections.pop || make_new
|
131
|
-
end
|
132
|
-
|
133
|
-
# Creates a new connection if the size of the pool is less than the
|
134
|
-
# maximum size.
|
135
|
-
def make_new
|
136
|
-
if @created_count < @max_size
|
137
|
-
@created_count += 1
|
138
|
-
@connection_proc ? @connection_proc.call : \
|
139
|
-
(raise Error, "No connection proc specified")
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# Releases the connection assigned to the supplied thread.
|
144
|
-
def release(thread, conn)
|
145
|
-
@mutex.synchronize do
|
146
|
-
@allocated.delete(thread)
|
147
|
-
@available_connections << conn
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
# A SingleThreadedPool acts as a replacement for a ConnectionPool for use
|
153
|
-
# in single-threaded applications. ConnectionPool imposes a substantial
|
154
|
-
# performance penalty, so SingleThreadedPool is used to gain some speed.
|
155
|
-
#
|
156
|
-
# Note that using a single threaded pool with some adapters can cause
|
157
|
-
# errors in certain cases, see Sequel.single_threaded=.
|
158
|
-
class Sequel::SingleThreadedPool
|
159
|
-
# The single database connection for the pool
|
160
|
-
attr_reader :conn
|
161
|
-
|
162
|
-
# The proc used to create a new database connection
|
163
|
-
attr_writer :connection_proc
|
164
|
-
|
165
|
-
# Initializes the instance with the supplied block as the connection_proc.
|
166
|
-
#
|
167
|
-
# The single threaded pool takes the following options:
|
168
|
-
#
|
169
|
-
# * :pool_convert_exceptions - Whether to convert non-StandardError based exceptions
|
170
|
-
# to RuntimeError exceptions (default true)
|
171
|
-
def initialize(opts={}, &block)
|
172
|
-
@connection_proc = block
|
173
|
-
@convert_exceptions = opts.include?(:pool_convert_exceptions) ? opts[:pool_convert_exceptions] : true
|
174
|
-
end
|
175
|
-
|
176
|
-
# Yields the connection to the supplied block. This method simulates the
|
177
|
-
# ConnectionPool#hold API.
|
178
|
-
def hold
|
179
|
-
begin
|
180
|
-
@conn ||= @connection_proc.call
|
181
|
-
yield @conn
|
182
|
-
rescue Exception => e
|
183
|
-
# if the error is not a StandardError it is converted into RuntimeError.
|
184
|
-
raise(@convert_exceptions && !e.is_a?(StandardError) ? RuntimeError.new(e.message) : e)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
# Disconnects from the database. Once a connection is requested using
|
189
|
-
# #hold, the connection is reestablished.
|
190
|
-
def disconnect(&block)
|
191
|
-
block[@conn] if block && @conn
|
192
|
-
@conn = nil
|
193
|
-
end
|
194
|
-
end
|