sequel 3.7.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +50 -0
- data/doc/advanced_associations.rdoc +4 -3
- data/doc/release_notes/3.7.0.txt +2 -2
- data/doc/release_notes/3.8.0.txt +151 -0
- data/lib/sequel/adapters/jdbc.rb +10 -2
- data/lib/sequel/adapters/jdbc/h2.rb +14 -0
- data/lib/sequel/adapters/mysql.rb +36 -26
- data/lib/sequel/adapters/postgres.rb +27 -19
- data/lib/sequel/adapters/shared/mssql.rb +12 -4
- data/lib/sequel/adapters/shared/mysql.rb +16 -0
- data/lib/sequel/connection_pool.rb +178 -57
- data/lib/sequel/database.rb +60 -12
- data/lib/sequel/database/schema_generator.rb +1 -2
- data/lib/sequel/dataset.rb +10 -1
- data/lib/sequel/dataset/actions.rb +4 -8
- data/lib/sequel/dataset/convenience.rb +9 -2
- data/lib/sequel/dataset/query.rb +2 -5
- data/lib/sequel/dataset/sql.rb +0 -1
- data/lib/sequel/exceptions.rb +3 -3
- data/lib/sequel/metaprogramming.rb +4 -18
- data/lib/sequel/model/associations.rb +2 -2
- data/lib/sequel/model/base.rb +15 -18
- data/lib/sequel/model/default_inflections.rb +0 -1
- data/lib/sequel/model/plugins.rb +3 -2
- data/lib/sequel/plugins/boolean_readers.rb +3 -2
- data/lib/sequel/plugins/identity_map.rb +9 -0
- data/lib/sequel/plugins/validation_helpers.rb +8 -1
- data/lib/sequel/sql.rb +21 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +7 -1
- data/spec/adapters/mysql_spec.rb +22 -0
- data/spec/core/connection_pool_spec.rb +211 -3
- data/spec/core/core_sql_spec.rb +7 -0
- data/spec/core/database_spec.rb +159 -7
- data/spec/core/dataset_spec.rb +33 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/extensions/boolean_readers_spec.rb +6 -0
- data/spec/extensions/identity_map_spec.rb +29 -1
- data/spec/extensions/inflector_spec.rb +0 -1
- data/spec/extensions/validation_helpers_spec.rb +23 -0
- data/spec/integration/type_test.rb +1 -1
- metadata +131 -129
data/CHANGELOG
CHANGED
@@ -1,3 +1,53 @@
|
|
1
|
+
=== 3.8.0 (2010-01-04)
|
2
|
+
|
3
|
+
* Catch cases in the postgres adapter where exceptions weren't converted or raised appropriately (jeremyevans)
|
4
|
+
|
5
|
+
* Don't double escape backslashes in string literals in the mssql shared adapter (john_firebaugh)
|
6
|
+
|
7
|
+
* Fix order of ORDER and HAVING clauses in the mssql shared adapter (mluu)
|
8
|
+
|
9
|
+
* Add validates_type to the validation_helpers plugin (mluu)
|
10
|
+
|
11
|
+
* Attempt to detect database disconnects in the JDBC adapter (john_firebaugh)
|
12
|
+
|
13
|
+
* Add Sequel::SQL::Expression#==, so arbtirary expressions can be compared by value (dlee)
|
14
|
+
|
15
|
+
* Respect the :size option for the generic File type on MySQL to create tinyblob, mediumblob, and longblob (ibc)
|
16
|
+
|
17
|
+
* Don't use the OUTPUT clause on SQL Server versions that don't support it (pre-2005) (jeremyevans) (#281)
|
18
|
+
|
19
|
+
* Raise DatabaseConnectionErrors in the single-threaded connection pool if unable to connect (jeremyevans)
|
20
|
+
|
21
|
+
* Fix handling of non-existent server in single-threaded connection pool (jeremyevans)
|
22
|
+
|
23
|
+
* Default to using mysqlplus driver in the native mysql adapter, fall back to mysql driver (ibc, jeremyevans)
|
24
|
+
|
25
|
+
* Handle 64-bit integers in JDBC prepared statements (paulfras)
|
26
|
+
|
27
|
+
* Improve blob support when using the H2 JDBC subadapter (nullstyle, jeremyevans, paulfras)
|
28
|
+
|
29
|
+
* Add Database#each_server, which yields a new Database object for each server in the connection pool which is connected to only that server (jeremyevans)
|
30
|
+
|
31
|
+
* Add Dataset#each_server, which yields a dataset for each server in the connection pool which is will execute on that server (jeremyevans)
|
32
|
+
|
33
|
+
* Remove meta_eval and metaclass private methods from Sequel::Metaprogramming (jeremyevans)
|
34
|
+
|
35
|
+
* Merge Dataset::FROM_SELF_KEEP_OPTS into Dataset::NON_SQL_OPTIONS (jeremyevans)
|
36
|
+
|
37
|
+
* Add Database#remove_servers for removing servers from the pool on the fly (jeremyevans)
|
38
|
+
|
39
|
+
* When disconnecting servers, if there are any connections to the server currently in use, schedule them to be disconnected (jeremyevans)
|
40
|
+
|
41
|
+
* Allow disconnecting specific server(s)/shard(s) in Database#disconnect via a :servers option (jeremyevans)
|
42
|
+
|
43
|
+
* Handle multiple statements in a single query in the native MySQL adapter in all cases, not just when selecting via Dataset#each (jeremyevans)
|
44
|
+
|
45
|
+
* In the boolean_readers plugin, don't raise an error if the model's columns can't be determined (jeremyevans)
|
46
|
+
|
47
|
+
* In the identity_map plugin, remove instances from the cache if they are deleted/destroyed (jeremyevans)
|
48
|
+
|
49
|
+
* Add Database#add_servers, for adding new servers/shards on the fly (chuckremes, jeremyevans)
|
50
|
+
|
1
51
|
=== 3.7.0 (2009-12-01)
|
2
52
|
|
3
53
|
* Add Dataset#sequence to the shared Oracle Adapter, for returning autogenerated primary key values on insert (jeremyevans) (#280)
|
@@ -476,8 +476,8 @@ Let's say you want to store a tree relationship in your database, it's pretty
|
|
476
476
|
simple:
|
477
477
|
|
478
478
|
class Node < Sequel::Model
|
479
|
-
many_to_one :parent
|
480
|
-
one_to_many :children, :key=>:parent_id
|
479
|
+
many_to_one :parent, :class=>self
|
480
|
+
one_to_many :children, :key=>:parent_id, :class=>self
|
481
481
|
end
|
482
482
|
|
483
483
|
You can easily get a node's parent with node.parent, and a node's children with
|
@@ -492,7 +492,8 @@ What if you want to get all ancestors up to the root node, or all descendents,
|
|
492
492
|
without knowing the depth of the tree?
|
493
493
|
|
494
494
|
class Node < Sequel::Model
|
495
|
-
many_to_one :ancestors, :
|
495
|
+
many_to_one :ancestors, :class=>self,
|
496
|
+
:eager_loader=>(proc do |key_hash, nodes, associations|
|
496
497
|
# Handle cases where the root node has the same parent_id as primary_key
|
497
498
|
# and also when it is NULL
|
498
499
|
non_root_nodes = nodes.reject do |n|
|
data/doc/release_notes/3.7.0.txt
CHANGED
@@ -97,8 +97,8 @@ New Features
|
|
97
97
|
database could be changed between retrieving the model object and
|
98
98
|
updating it.
|
99
99
|
|
100
|
-
* The
|
101
|
-
:alias option
|
100
|
+
* The Dataset #union, #intersect, and #except methods now accept an
|
101
|
+
:alias option which is used as the alias for the returned dataset.
|
102
102
|
|
103
103
|
DB[:table].union(DB[:old_table], :alias=>:table)
|
104
104
|
|
@@ -0,0 +1,151 @@
|
|
1
|
+
New Features
|
2
|
+
------------
|
3
|
+
|
4
|
+
* Dataset#each_server was added, allowing you to run the same query
|
5
|
+
(most likely insert/update/delete) on all shards. This is useful
|
6
|
+
if you have a sharded database but have lookup tables that should
|
7
|
+
be identical on all shards. It works by yielding copies of the
|
8
|
+
current dataset that are tied to each server/shard:
|
9
|
+
|
10
|
+
DB[:table].filter(:id=>1).each_server do |ds|
|
11
|
+
ds.update(:name=>'foo')
|
12
|
+
end
|
13
|
+
|
14
|
+
* Database#each_server was added, allowing you to run schema
|
15
|
+
modification methods on all shards. It works by yielding a
|
16
|
+
new Sequel::Database object for each shard, that will connect to
|
17
|
+
only that shard:
|
18
|
+
|
19
|
+
DB.each_server do |db|
|
20
|
+
db.create_table(:t){Integer :num}
|
21
|
+
end
|
22
|
+
|
23
|
+
* You can now add and remove servers/shards from the connection
|
24
|
+
pool while Sequel is running:
|
25
|
+
|
26
|
+
DB.add_servers(:shard1=>{:host=>'s1'}, :shard2=>{:host=>'s2'})
|
27
|
+
DB.remove_servers(:shard1, :shard2)
|
28
|
+
|
29
|
+
* When you attempt to disconnect from a server that has connections
|
30
|
+
currently in use, Sequel will now schedule those connections to
|
31
|
+
be disconnected when they are returned to the pool. Previously,
|
32
|
+
Sequel disconnected available connections, but ignored connections
|
33
|
+
currently in use, so it wasn't possible to guarantee complete
|
34
|
+
disconnection from the server. Even with this new feature, you can
|
35
|
+
only guarantee eventual disconnection, since disconnection of
|
36
|
+
connections in use happens asynchronously.
|
37
|
+
|
38
|
+
* Database#disconnect now accepts a :servers option specifying the
|
39
|
+
server(s) from which to disconnect. This should be a symbol or
|
40
|
+
array of symbols representing servers/shards. Only those specified
|
41
|
+
will be disconnected:
|
42
|
+
|
43
|
+
DB.disconnect(:servers=>[:shard1, :shard2])
|
44
|
+
|
45
|
+
* A validates_type validation was added to the validation_helpers
|
46
|
+
plugin. It allows you to check that a given column contains
|
47
|
+
the correct type. I can be helpful if you are also using the
|
48
|
+
serialization plugin to store serialized ruby objects, by making
|
49
|
+
sure that the objects are of the correct type (e.g. Hash):
|
50
|
+
|
51
|
+
def validate
|
52
|
+
validates_type(Hash, :options)
|
53
|
+
end
|
54
|
+
|
55
|
+
* Sequel::SQL::Expression#== is now supported for all expressions:
|
56
|
+
|
57
|
+
:column.qualify(:table).cast(:type) == \
|
58
|
+
:column.qualify(:table).cast(:type)
|
59
|
+
# => true
|
60
|
+
:column.qualify(:table).cast(:type) == \
|
61
|
+
:other_column.qualify(:table).cast(:type)
|
62
|
+
# => false
|
63
|
+
|
64
|
+
* When using the generic File type to create blob columns on
|
65
|
+
MySQL, you can specify the specific database type by using the
|
66
|
+
:size option (with :tiny, :medium, and :long values recognized):
|
67
|
+
|
68
|
+
DB.create_table(:docs){File :body, :size=>:long} # longblob
|
69
|
+
|
70
|
+
* The mysql adapter will now default to using mysqlplus, falling
|
71
|
+
back to use mysql. mysqlplus is significantly better for threaded
|
72
|
+
code because queries do not block the entire interpreter.
|
73
|
+
|
74
|
+
* The JDBC adapter is now able to detect certain types of disconnect
|
75
|
+
errors.
|
76
|
+
|
77
|
+
* ConnectionPool.servers and Database.servers were added, which
|
78
|
+
return an array of symbols specifying the servers/shards in use.
|
79
|
+
|
80
|
+
Other Improvements
|
81
|
+
------------------
|
82
|
+
|
83
|
+
* The single-threaded connection pool now raises
|
84
|
+
DatabaseConnectionErrors if unable to connect, so it now operates
|
85
|
+
more similarly to the default connection pool.
|
86
|
+
|
87
|
+
* The single-threaded connection pool now operates more similar
|
88
|
+
to the default connection pool when given a nonexistent server.
|
89
|
+
|
90
|
+
* PGErrors are now correctly converted to DatabaseErrors in the
|
91
|
+
postgres adapter when preparing statements or executing prepared
|
92
|
+
statements.
|
93
|
+
|
94
|
+
* DatabaseDisconnectErrors are now raised correctly in the postgres
|
95
|
+
adapter if the connection status is not OK after a query raises an
|
96
|
+
error.
|
97
|
+
|
98
|
+
* In the mysql adapter, multiple statements in a single query should
|
99
|
+
now be handled correctly in the all cases, not just when using
|
100
|
+
Dataset#each. So you can now submit multiple queries in a single
|
101
|
+
string to Database#run.
|
102
|
+
|
103
|
+
* Model object creation on Microsoft SQL Server 2000 once again
|
104
|
+
works correctly. Previously, an optimization was used that was
|
105
|
+
only supported on 2005+.
|
106
|
+
|
107
|
+
* Backslashes are no longer doubled inside string literals when
|
108
|
+
connecting to Microsoft SQL Server.
|
109
|
+
|
110
|
+
* The ORDER clause now correctly comes after the HAVING clause on
|
111
|
+
Microsoft SQL Server.
|
112
|
+
|
113
|
+
* Sequel now checks that there is an active transaction before
|
114
|
+
rolling back transactions on Microsoft SQL Server, since
|
115
|
+
there are cases where Microsoft SQL Server will roll back
|
116
|
+
transactions implicitly.
|
117
|
+
|
118
|
+
* Blobs are now handled correctly when connecting to H2.
|
119
|
+
|
120
|
+
* 64-bit integers are now handled correctly in JDBC prepared
|
121
|
+
statements.
|
122
|
+
|
123
|
+
* In the boolean_readers plugin, correctly handle columns not in
|
124
|
+
the db_schema, and don't raise an error if the model's columns
|
125
|
+
can't be determined.
|
126
|
+
|
127
|
+
* In the identity_map plugin, remove instances from the cache if they
|
128
|
+
are deleted or destroyed.
|
129
|
+
|
130
|
+
Backwards Compatibility
|
131
|
+
-----------------------
|
132
|
+
|
133
|
+
* Dataset::FROM_SELF_KEEP_OPTS was merged into
|
134
|
+
Dataset::NON_SQL_OPTIONS. While used in different places, they
|
135
|
+
were used for the same purpose, and entries missing from one should
|
136
|
+
have been included in the other.
|
137
|
+
|
138
|
+
* The connection pool internals changed substantially. Now,
|
139
|
+
ConnectionPool #allocated and #available_connections will return
|
140
|
+
nil instead of an array or hash if they are called with a
|
141
|
+
nonexistent server. These are generally only used internally,
|
142
|
+
though they are part of the public API. #created_count and #size
|
143
|
+
still return the size of the :default server when called with a
|
144
|
+
nonexistent server, though.
|
145
|
+
|
146
|
+
* The meta_eval and metaclass private methods were removed from
|
147
|
+
Sequel::MetaProgramming (only the meta_def public method remains).
|
148
|
+
If you want these methods, use the metaid gem.
|
149
|
+
|
150
|
+
* The irregular ox->oxen pluralization rule was removed from the
|
151
|
+
default inflections, as it screws up the more common box->boxes.
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -322,7 +322,13 @@ module Sequel
|
|
322
322
|
def metadata(*args, &block)
|
323
323
|
synchronize{|c| metadata_dataset.send(:process_result_set, c.getMetaData.send(*args), &block)}
|
324
324
|
end
|
325
|
-
|
325
|
+
|
326
|
+
# Treat SQLExceptions with a "Connection Error" SQLState as disconnects
|
327
|
+
def raise_error(exception, opts={})
|
328
|
+
cause = exception.respond_to?(:cause) ? exception.cause : exception
|
329
|
+
super(exception, {:disconnect => cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/}.merge(opts))
|
330
|
+
end
|
331
|
+
|
326
332
|
# Close the given statement when removing the transaction
|
327
333
|
def remove_transaction(stmt)
|
328
334
|
stmt.close if stmt && !supports_savepoints?
|
@@ -336,7 +342,7 @@ module Sequel
|
|
336
342
|
def set_ps_arg(cps, arg, i)
|
337
343
|
case arg
|
338
344
|
when Integer
|
339
|
-
cps.
|
345
|
+
cps.setLong(i, arg)
|
340
346
|
when Sequel::SQL::Blob
|
341
347
|
cps.setBytes(i, arg.to_java_bytes)
|
342
348
|
when String
|
@@ -492,6 +498,8 @@ module Sequel
|
|
492
498
|
BigDecimal.new(v.to_string)
|
493
499
|
when Java::byte[]
|
494
500
|
Sequel::SQL::Blob.new(String.from_java_bytes(v))
|
501
|
+
when Java::JavaSQL::Blob
|
502
|
+
convert_type(v.getBytes(0, v.length))
|
495
503
|
else
|
496
504
|
v
|
497
505
|
end
|
@@ -105,6 +105,20 @@ module Sequel
|
|
105
105
|
|
106
106
|
private
|
107
107
|
|
108
|
+
# H2 expects hexadecimal strings for blob values
|
109
|
+
def literal_blob(v)
|
110
|
+
literal_string v.unpack("H*").first
|
111
|
+
end
|
112
|
+
|
113
|
+
def convert_type(v)
|
114
|
+
case v
|
115
|
+
when Java::OrgH2Jdbc::JdbcClob
|
116
|
+
convert_type(v.getSubString(1, v.length))
|
117
|
+
else
|
118
|
+
super(v)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
108
122
|
def select_clause_methods
|
109
123
|
SELECT_CLAUSE_METHODS
|
110
124
|
end
|
@@ -1,5 +1,10 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require "mysqlplus"
|
3
|
+
rescue LoadError
|
4
|
+
require 'mysql'
|
5
|
+
end
|
2
6
|
raise(LoadError, "require 'mysql' did not define Mysql::CLIENT_MULTI_RESULTS!\n You are probably using the pure ruby mysql.rb driver,\n which Sequel does not support. You need to install\n the C based adapter, and make sure that the mysql.so\n file is loaded instead of the mysql.rb file.\n") unless defined?(Mysql::CLIENT_MULTI_RESULTS)
|
7
|
+
|
3
8
|
Sequel.require %w'shared/mysql utils/stored_procedures', 'adapters'
|
4
9
|
|
5
10
|
module Sequel
|
@@ -160,35 +165,40 @@ module Sequel
|
|
160
165
|
r = conn.query(sql)
|
161
166
|
if opts[:type] == :select
|
162
167
|
yield r if r
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
rescue Mysql::Error
|
172
|
-
break
|
173
|
-
end
|
174
|
-
yield r
|
175
|
-
break unless conn.next_result
|
168
|
+
elsif block_given?
|
169
|
+
yield conn
|
170
|
+
end
|
171
|
+
if conn.respond_to?(:more_results?)
|
172
|
+
while conn.more_results? do
|
173
|
+
if r
|
174
|
+
r.free
|
175
|
+
r = nil
|
176
176
|
end
|
177
|
+
begin
|
178
|
+
conn.next_result
|
179
|
+
r = conn.use_result
|
180
|
+
rescue Mysql::Error => e
|
181
|
+
raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
|
182
|
+
break
|
183
|
+
end
|
184
|
+
yield r if opts[:type] == :select
|
177
185
|
end
|
178
|
-
else
|
179
|
-
yield conn if block_given?
|
180
186
|
end
|
181
187
|
rescue Mysql::Error => e
|
182
188
|
raise_error(e, :disconnect=>MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message))
|
183
189
|
ensure
|
184
|
-
if r
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
190
|
+
r.free if r
|
191
|
+
# Use up all results to avoid a commands out of sync message.
|
192
|
+
if conn.respond_to?(:more_results?)
|
193
|
+
while conn.more_results? do
|
194
|
+
begin
|
195
|
+
conn.next_result
|
189
196
|
r = conn.use_result
|
190
|
-
|
197
|
+
rescue Mysql::Error => e
|
198
|
+
raise_error(e, :disconnect=>true) if MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)
|
199
|
+
break
|
191
200
|
end
|
201
|
+
r.free if r
|
192
202
|
end
|
193
203
|
end
|
194
204
|
end
|
@@ -314,7 +324,7 @@ module Sequel
|
|
314
324
|
|
315
325
|
# Delete rows matching this dataset
|
316
326
|
def delete
|
317
|
-
execute_dui(delete_sql){|c| c.affected_rows}
|
327
|
+
execute_dui(delete_sql){|c| return c.affected_rows}
|
318
328
|
end
|
319
329
|
|
320
330
|
# Yield all rows matching this dataset. If the dataset is set to
|
@@ -344,7 +354,7 @@ module Sequel
|
|
344
354
|
|
345
355
|
# Insert a new value into this dataset
|
346
356
|
def insert(*values)
|
347
|
-
execute_dui(insert_sql(*values)){|c| c.insert_id}
|
357
|
+
execute_dui(insert_sql(*values)){|c| return c.insert_id}
|
348
358
|
end
|
349
359
|
|
350
360
|
# Store the given type of prepared statement in the associated database
|
@@ -361,7 +371,7 @@ module Sequel
|
|
361
371
|
|
362
372
|
# Replace (update or insert) the matching row.
|
363
373
|
def replace(*args)
|
364
|
-
execute_dui(replace_sql(*args)){|c| c.insert_id}
|
374
|
+
execute_dui(replace_sql(*args)){|c| return c.insert_id}
|
365
375
|
end
|
366
376
|
|
367
377
|
# Makes each yield arrays of rows, with each array containing the rows
|
@@ -382,7 +392,7 @@ module Sequel
|
|
382
392
|
|
383
393
|
# Update the matching rows.
|
384
394
|
def update(values={})
|
385
|
-
execute_dui(update_sql(values)){|c| c.affected_rows}
|
395
|
+
execute_dui(update_sql(values)){|c| return c.affected_rows}
|
386
396
|
end
|
387
397
|
|
388
398
|
private
|
@@ -138,24 +138,29 @@ module Sequel
|
|
138
138
|
end
|
139
139
|
@prepared_statements = {} if SEQUEL_POSTGRES_USES_PG
|
140
140
|
end
|
141
|
-
|
142
|
-
#
|
143
|
-
#
|
144
|
-
def
|
145
|
-
q = nil
|
141
|
+
|
142
|
+
# Raise a Sequel::DatabaseDisconnectError if a PGError is raised and
|
143
|
+
# the connection status cannot be determined or it is not OK.
|
144
|
+
def check_disconnect_errors
|
146
145
|
begin
|
147
|
-
|
148
|
-
rescue PGError =>
|
146
|
+
yield
|
147
|
+
rescue PGError =>e
|
149
148
|
begin
|
150
149
|
s = status
|
151
150
|
rescue PGError
|
152
151
|
raise Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError)
|
153
152
|
end
|
154
153
|
status_ok = (s == Adapter::CONNECTION_OK)
|
155
|
-
status_ok ? raise : Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError)
|
154
|
+
status_ok ? raise : raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError))
|
156
155
|
ensure
|
157
156
|
block if status_ok
|
158
157
|
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Execute the given SQL with this connection. If a block is given,
|
161
|
+
# yield the results, otherwise, return the number of changed rows.
|
162
|
+
def execute(sql, args=nil)
|
163
|
+
q = check_disconnect_errors{args ? async_exec(sql, args) : async_exec(sql)}
|
159
164
|
begin
|
160
165
|
block_given? ? yield(q) : q.cmd_tuples
|
161
166
|
ensure
|
@@ -218,13 +223,10 @@ module Sequel
|
|
218
223
|
|
219
224
|
# Execute the given SQL with the given args on an available connection.
|
220
225
|
def execute(sql, opts={}, &block)
|
221
|
-
|
222
|
-
|
226
|
+
check_database_errors do
|
227
|
+
return execute_prepared_statement(sql, opts, &block) if Symbol === sql
|
223
228
|
log_info(sql, opts[:arguments])
|
224
229
|
synchronize(opts[:server]){|conn| conn.execute(sql, opts[:arguments], &block)}
|
225
|
-
rescue => e
|
226
|
-
log_info(e.message)
|
227
|
-
raise_error(e, :classes=>CONVERTED_EXCEPTIONS)
|
228
230
|
end
|
229
231
|
end
|
230
232
|
|
@@ -232,19 +234,25 @@ module Sequel
|
|
232
234
|
# automatically generated).
|
233
235
|
def execute_insert(sql, opts={})
|
234
236
|
return execute(sql, opts) if Symbol === sql
|
235
|
-
|
237
|
+
check_database_errors do
|
236
238
|
log_info(sql, opts[:arguments])
|
237
239
|
synchronize(opts[:server]) do |conn|
|
238
240
|
conn.execute(sql, opts[:arguments])
|
239
241
|
insert_result(conn, opts[:table], opts[:values])
|
240
242
|
end
|
241
|
-
rescue => e
|
242
|
-
log_info(e.message)
|
243
|
-
raise_error(e, :classes=>CONVERTED_EXCEPTIONS)
|
244
243
|
end
|
245
244
|
end
|
246
245
|
|
247
246
|
private
|
247
|
+
|
248
|
+
# Convert exceptions raised from the block into DatabaseErrors.
|
249
|
+
def check_database_errors
|
250
|
+
begin
|
251
|
+
yield
|
252
|
+
rescue => e
|
253
|
+
raise_error(e, :classes=>CONVERTED_EXCEPTIONS)
|
254
|
+
end
|
255
|
+
end
|
248
256
|
|
249
257
|
# PostgreSQL doesn't need the connection pool to convert exceptions.
|
250
258
|
def connection_pool_default_options
|
@@ -281,10 +289,10 @@ module Sequel
|
|
281
289
|
end
|
282
290
|
conn.prepared_statements[ps_name] = sql
|
283
291
|
log_info("PREPARE #{ps_name} AS #{sql}")
|
284
|
-
conn.prepare(ps_name, sql)
|
292
|
+
conn.check_disconnect_errors{conn.prepare(ps_name, sql)}
|
285
293
|
end
|
286
294
|
log_info("EXECUTE #{ps_name}", args)
|
287
|
-
q = conn.exec_prepared(ps_name, args)
|
295
|
+
q = conn.check_disconnect_errors{conn.exec_prepared(ps_name, args)}
|
288
296
|
if opts[:table] && opts[:values]
|
289
297
|
insert_result(conn, opts[:table], opts[:values])
|
290
298
|
else
|