sequel 3.0.0 → 3.1.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.
- data/CHANGELOG +100 -0
- data/README.rdoc +3 -3
- data/bin/sequel +102 -19
- data/doc/reflection.rdoc +83 -0
- data/doc/release_notes/3.1.0.txt +406 -0
- data/lib/sequel/adapters/ado.rb +11 -0
- data/lib/sequel/adapters/amalgalite.rb +5 -20
- data/lib/sequel/adapters/do.rb +44 -36
- data/lib/sequel/adapters/firebird.rb +29 -43
- data/lib/sequel/adapters/jdbc.rb +17 -27
- data/lib/sequel/adapters/mysql.rb +35 -40
- data/lib/sequel/adapters/odbc.rb +4 -23
- data/lib/sequel/adapters/oracle.rb +22 -19
- data/lib/sequel/adapters/postgres.rb +6 -15
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql.rb +29 -10
- data/lib/sequel/adapters/shared/oracle.rb +6 -8
- data/lib/sequel/adapters/shared/postgres.rb +28 -72
- data/lib/sequel/adapters/shared/sqlite.rb +5 -3
- data/lib/sequel/adapters/sqlite.rb +5 -20
- data/lib/sequel/adapters/utils/savepoint_transactions.rb +80 -0
- data/lib/sequel/adapters/utils/unsupported.rb +0 -12
- data/lib/sequel/core.rb +12 -3
- data/lib/sequel/core_sql.rb +1 -8
- data/lib/sequel/database.rb +107 -43
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +38 -4
- data/lib/sequel/dataset.rb +6 -0
- data/lib/sequel/dataset/convenience.rb +2 -2
- data/lib/sequel/dataset/graph.rb +2 -2
- data/lib/sequel/dataset/prepared_statements.rb +3 -8
- data/lib/sequel/dataset/sql.rb +93 -19
- data/lib/sequel/extensions/blank.rb +2 -1
- data/lib/sequel/extensions/inflector.rb +4 -3
- data/lib/sequel/extensions/migration.rb +13 -2
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pretty_table.rb +4 -0
- data/lib/sequel/extensions/query.rb +4 -0
- data/lib/sequel/extensions/schema_dumper.rb +100 -24
- data/lib/sequel/extensions/string_date_time.rb +3 -4
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +96 -38
- data/lib/sequel/model/base.rb +14 -14
- data/lib/sequel/model/plugins.rb +32 -21
- data/lib/sequel/plugins/caching.rb +13 -15
- data/lib/sequel/plugins/identity_map.rb +107 -0
- data/lib/sequel/plugins/lazy_attributes.rb +65 -0
- data/lib/sequel/plugins/many_through_many.rb +188 -0
- data/lib/sequel/plugins/schema.rb +13 -0
- data/lib/sequel/plugins/serialization.rb +53 -37
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
- data/lib/sequel/plugins/validation_class_methods.rb +28 -7
- data/lib/sequel/plugins/validation_helpers.rb +31 -24
- data/lib/sequel/sql.rb +16 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/ado_spec.rb +47 -1
- data/spec/adapters/firebird_spec.rb +39 -36
- data/spec/adapters/mysql_spec.rb +25 -9
- data/spec/adapters/postgres_spec.rb +11 -24
- data/spec/core/database_spec.rb +54 -13
- data/spec/core/dataset_spec.rb +147 -29
- data/spec/core/object_graph_spec.rb +6 -1
- data/spec/core/schema_spec.rb +34 -0
- data/spec/core/spec_helper.rb +0 -2
- data/spec/extensions/caching_spec.rb +7 -0
- data/spec/extensions/identity_map_spec.rb +158 -0
- data/spec/extensions/lazy_attributes_spec.rb +113 -0
- data/spec/extensions/many_through_many_spec.rb +813 -0
- data/spec/extensions/migration_spec.rb +4 -4
- data/spec/extensions/schema_dumper_spec.rb +114 -13
- data/spec/extensions/schema_spec.rb +19 -3
- data/spec/extensions/serialization_spec.rb +28 -0
- data/spec/extensions/single_table_inheritance_spec.rb +25 -1
- data/spec/extensions/spec_helper.rb +2 -7
- data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
- data/spec/extensions/validation_class_methods_spec.rb +10 -5
- data/spec/integration/dataset_test.rb +39 -6
- data/spec/integration/eager_loader_test.rb +7 -7
- data/spec/integration/spec_helper.rb +0 -1
- data/spec/integration/transaction_test.rb +28 -1
- data/spec/model/association_reflection_spec.rb +29 -3
- data/spec/model/associations_spec.rb +1 -0
- data/spec/model/eager_loading_spec.rb +70 -1
- data/spec/model/plugins_spec.rb +236 -50
- data/spec/model/spec_helper.rb +0 -2
- metadata +18 -5
data/lib/sequel/adapters/ado.rb
CHANGED
@@ -25,10 +25,21 @@ module Sequel
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
# Connect to the database. In addition to the usual database options,
|
29
|
+
# the following option has effect:
|
30
|
+
#
|
31
|
+
# * :command_timout - Sets the time in seconds to wait while attempting
|
32
|
+
# to execute a command before cancelling the attempt and generating
|
33
|
+
# an error. Specificially, it sets the ADO CommandTimeout property.
|
34
|
+
# If this property is not set, the default of 30 seconds is used.
|
35
|
+
# * :provider - Sets the Provider of this ADO connection (for example, "SQLOLEDB")
|
36
|
+
|
28
37
|
def connect(server)
|
29
38
|
opts = server_opts(server)
|
30
39
|
s = "driver=#{opts[:driver]};server=#{opts[:host]};database=#{opts[:database]}#{";uid=#{opts[:user]};pwd=#{opts[:password]}" if opts[:user]}"
|
31
40
|
handle = WIN32OLE.new('ADODB.Connection')
|
41
|
+
handle.CommandTimeout = opts[:command_timeout] if opts[:command_timeout]
|
42
|
+
handle.Provider = opts[:provider] if opts[:provider]
|
32
43
|
handle.Open(s)
|
33
44
|
handle
|
34
45
|
end
|
@@ -119,26 +119,6 @@ module Sequel
|
|
119
119
|
_execute(sql, opts){|conn| conn.first_value_from(sql)}
|
120
120
|
end
|
121
121
|
|
122
|
-
# Use the native driver transaction method if there isn't already a transaction
|
123
|
-
# in progress on the connection, always yielding a connection inside a transaction
|
124
|
-
# transaction.
|
125
|
-
def transaction(opts={})
|
126
|
-
synchronize(opts[:server]) do |conn|
|
127
|
-
return yield(conn) if conn.in_transaction?
|
128
|
-
begin
|
129
|
-
result = nil
|
130
|
-
log_info('Transaction.begin')
|
131
|
-
conn.transaction{result = yield(conn)}
|
132
|
-
result
|
133
|
-
rescue ::Exception => e
|
134
|
-
log_info('Transaction.rollback')
|
135
|
-
transaction_error(e, ::Amalgalite::Error, ::Amalgalite::SQLite3::Error)
|
136
|
-
ensure
|
137
|
-
log_info('Transaction.commit') unless e
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
122
|
private
|
143
123
|
|
144
124
|
# Log the SQL and yield an available connection. Rescue
|
@@ -162,6 +142,11 @@ module Sequel
|
|
162
142
|
o[:max_connections] = 1 if @opts[:database] == ':memory:' || blank_object?(@opts[:database])
|
163
143
|
o
|
164
144
|
end
|
145
|
+
|
146
|
+
# Both main error classes that Amalgalite raises
|
147
|
+
def database_error_classes
|
148
|
+
[::Amalgalite::Error, ::Amalgalite::SQLite3::Error]
|
149
|
+
end
|
165
150
|
|
166
151
|
# Disconnect given connections from the database.
|
167
152
|
def disconnect_connection(c)
|
data/lib/sequel/adapters/do.rb
CHANGED
@@ -116,37 +116,6 @@ module Sequel
|
|
116
116
|
uri.split(":").first
|
117
117
|
end
|
118
118
|
|
119
|
-
# Use DataObject's transaction support for transactions. This
|
120
|
-
# only supports single level transactions, and it always prepares
|
121
|
-
# transactions and commits them immediately after. It's wasteful,
|
122
|
-
# but required by DataObject's API.
|
123
|
-
def transaction(opts={})
|
124
|
-
th = Thread.current
|
125
|
-
synchronize(opts[:server]) do |conn|
|
126
|
-
return yield(conn) if @transactions.include?(th)
|
127
|
-
t = ::DataObjects::Transaction.create_for_uri(uri)
|
128
|
-
t.instance_variable_get(:@connection).close
|
129
|
-
t.instance_variable_set(:@connection, conn)
|
130
|
-
begin
|
131
|
-
log_info("Transaction.begin")
|
132
|
-
t.begin
|
133
|
-
@transactions << th
|
134
|
-
yield(conn)
|
135
|
-
rescue Exception => e
|
136
|
-
log_info("Transaction.rollback")
|
137
|
-
t.rollback
|
138
|
-
transaction_error(e)
|
139
|
-
ensure
|
140
|
-
unless e
|
141
|
-
log_info("Transaction.commit")
|
142
|
-
t.prepare
|
143
|
-
t.commit
|
144
|
-
end
|
145
|
-
@transactions.delete(th)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
119
|
# Return the DataObjects URI for the Sequel URI, removing the do:
|
151
120
|
# prefix.
|
152
121
|
def uri(opts={})
|
@@ -155,22 +124,61 @@ module Sequel
|
|
155
124
|
end
|
156
125
|
|
157
126
|
private
|
127
|
+
|
128
|
+
# DataObjects uses a special transaction object to keep track of
|
129
|
+
# transactions. Unfortunately, it tries to create a new connection
|
130
|
+
# to do a transaction. So we close the connection created and
|
131
|
+
# substitute our own.
|
132
|
+
def begin_transaction(conn)
|
133
|
+
log_info(TRANSACTION_BEGIN)
|
134
|
+
t = ::DataObjects::Transaction.create_for_uri(uri)
|
135
|
+
t.instance_variable_get(:@connection).close
|
136
|
+
t.instance_variable_set(:@connection, conn)
|
137
|
+
t.begin
|
138
|
+
t
|
139
|
+
end
|
140
|
+
|
141
|
+
# DataObjects requires transactions be prepared before being
|
142
|
+
# committed, so we do that.
|
143
|
+
def commit_transaction(t)
|
144
|
+
log_info(TRANSACTION_ROLLBACK)
|
145
|
+
t.prepare
|
146
|
+
t.commit
|
147
|
+
end
|
148
|
+
|
149
|
+
# Method to call on a statement object to execute SQL that does
|
150
|
+
# not return any rows.
|
151
|
+
def connection_execute_method
|
152
|
+
:execute_non_query
|
153
|
+
end
|
154
|
+
|
155
|
+
# The DataObjects adapter should convert exceptions by default.
|
156
|
+
def connection_pool_default_options
|
157
|
+
super.merge(:pool_convert_exceptions=>false)
|
158
|
+
end
|
158
159
|
|
159
160
|
# Close the given database connection.
|
160
161
|
def disconnect_connection(c)
|
161
162
|
c.close
|
162
163
|
end
|
163
164
|
|
165
|
+
# Execute SQL on the connection by creating a command first
|
166
|
+
def log_connection_execute(conn, sql)
|
167
|
+
log_info(sql)
|
168
|
+
conn.create_command(sql).execute_non_query
|
169
|
+
end
|
170
|
+
|
171
|
+
# We use the transactions rollback method to rollback.
|
172
|
+
def rollback_transaction(t)
|
173
|
+
log_info(TRANSACTION_COMMIT)
|
174
|
+
t.rollback
|
175
|
+
end
|
176
|
+
|
164
177
|
# Allow extending the given connection when it is first created.
|
165
178
|
# By default, just returns the connection.
|
166
179
|
def setup_connection(conn)
|
167
180
|
conn
|
168
181
|
end
|
169
|
-
|
170
|
-
# The DataObjects adapter should convert exceptions by default.
|
171
|
-
def connection_pool_default_options
|
172
|
-
super.merge(:pool_convert_exceptions=>false)
|
173
|
-
end
|
174
182
|
end
|
175
183
|
|
176
184
|
# Dataset class for Sequel::DataObjects::Database objects.
|
@@ -31,26 +31,6 @@ module Sequel
|
|
31
31
|
conn
|
32
32
|
end
|
33
33
|
|
34
|
-
# Creates a table with the columns given in the provided block:
|
35
|
-
#
|
36
|
-
# DB.create_table :posts do
|
37
|
-
# primary_key :id, :serial
|
38
|
-
# column :title, :text
|
39
|
-
# column :content, :text
|
40
|
-
# index :title
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# See Schema::Generator.
|
44
|
-
# Firebird gets an override because of the mess of creating a
|
45
|
-
# generator for auto-incrementing primary keys.
|
46
|
-
def create_table(name, options={}, &block)
|
47
|
-
options = {:generator=>options} if options.is_a?(Schema::Generator)
|
48
|
-
generator = options[:generator] || Schema::Generator.new(self, &block)
|
49
|
-
drop_statement, create_statements = create_table_sql_list(name, generator, options)
|
50
|
-
(execute_ddl(drop_statement) rescue nil) if drop_statement
|
51
|
-
(create_statements + index_sql_list(name, generator.indexes)).each{|sql| execute_ddl(sql)}
|
52
|
-
end
|
53
|
-
|
54
34
|
def create_trigger(*args)
|
55
35
|
self << create_trigger_sql(*args)
|
56
36
|
end
|
@@ -103,28 +83,6 @@ module Sequel
|
|
103
83
|
block_given? ? yield(ds) : ds.map{|r| ds.send(:output_identifier, r[:"rdb$relation_name"])}
|
104
84
|
end
|
105
85
|
|
106
|
-
def transaction(opts={})
|
107
|
-
synchronize(opts[:server]) do |conn|
|
108
|
-
return yield(conn) if @transactions.include?(Thread.current)
|
109
|
-
log_info("Transaction.begin")
|
110
|
-
conn.transaction
|
111
|
-
begin
|
112
|
-
@transactions << Thread.current
|
113
|
-
yield(conn)
|
114
|
-
rescue ::Exception => e
|
115
|
-
log_info("Transaction.rollback")
|
116
|
-
conn.rollback
|
117
|
-
transaction_error(e, Fb::Error)
|
118
|
-
ensure
|
119
|
-
unless e
|
120
|
-
log_info("Transaction.commit")
|
121
|
-
conn.commit
|
122
|
-
end
|
123
|
-
@transactions.delete(Thread.current)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
86
|
private
|
129
87
|
|
130
88
|
# Use Firebird specific syntax for add column
|
@@ -147,10 +105,29 @@ module Sequel
|
|
147
105
|
AUTO_INCREMENT
|
148
106
|
end
|
149
107
|
|
108
|
+
def begin_transaction(conn)
|
109
|
+
log_info(TRANSACTION_BEGIN)
|
110
|
+
conn.transaction
|
111
|
+
conn
|
112
|
+
end
|
113
|
+
|
114
|
+
def commit_transaction(conn)
|
115
|
+
log_info(TRANSACTION_COMMIT)
|
116
|
+
conn.commit
|
117
|
+
end
|
118
|
+
|
150
119
|
def create_sequence_sql(name, opts={})
|
151
120
|
"CREATE SEQUENCE #{quote_identifier(name)}"
|
152
121
|
end
|
153
122
|
|
123
|
+
# Firebird gets an override because of the mess of creating a
|
124
|
+
# sequence and trigger for auto-incrementing primary keys.
|
125
|
+
def create_table_from_generator(name, generator, options)
|
126
|
+
drop_statement, create_statements = create_table_sql_list(name, generator, options)
|
127
|
+
(execute_ddl(drop_statement) rescue nil) if drop_statement
|
128
|
+
create_statements.each{|sql| execute_ddl(sql)}
|
129
|
+
end
|
130
|
+
|
154
131
|
def create_table_sql_list(name, generator, options={})
|
155
132
|
statements = [create_table_sql(name, generator, options)]
|
156
133
|
drop_seq_statement = nil
|
@@ -192,6 +169,10 @@ module Sequel
|
|
192
169
|
end_sql
|
193
170
|
sql
|
194
171
|
end
|
172
|
+
|
173
|
+
def database_error_classes
|
174
|
+
[Fb::Error]
|
175
|
+
end
|
195
176
|
|
196
177
|
def disconnect_connection(c)
|
197
178
|
c.close
|
@@ -205,9 +186,14 @@ module Sequel
|
|
205
186
|
seq_name = quote_identifier(name)
|
206
187
|
"ALTER SEQUENCE #{seq_name} RESTART WITH #{opts[:restart_position]}"
|
207
188
|
end
|
189
|
+
|
190
|
+
def rollback_transaction(conn)
|
191
|
+
log_info(TRANSACTION_ROLLBACK)
|
192
|
+
conn.rollback
|
193
|
+
end
|
208
194
|
|
209
195
|
def type_literal_generic_string(column)
|
210
|
-
column[:text] ? :"BLOB
|
196
|
+
column[:text] ? :"BLOB SUB_TYPE TEXT" : super
|
211
197
|
end
|
212
198
|
end
|
213
199
|
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -209,33 +209,6 @@ module Sequel
|
|
209
209
|
ts
|
210
210
|
end
|
211
211
|
|
212
|
-
# Default transaction method that should work on most JDBC
|
213
|
-
# databases. Does not use the JDBC transaction methods, uses
|
214
|
-
# SQL BEGIN/ROLLBACK/COMMIT statements instead.
|
215
|
-
def transaction(opts={})
|
216
|
-
synchronize(opts[:server]) do |conn|
|
217
|
-
return yield(conn) if @transactions.include?(Thread.current)
|
218
|
-
stmt = conn.createStatement
|
219
|
-
begin
|
220
|
-
log_info(begin_transaction_sql)
|
221
|
-
stmt.execute(begin_transaction_sql)
|
222
|
-
@transactions << Thread.current
|
223
|
-
yield(conn)
|
224
|
-
rescue Exception => e
|
225
|
-
log_info(rollback_transaction_sql)
|
226
|
-
stmt.execute(rollback_transaction_sql)
|
227
|
-
transaction_error(e)
|
228
|
-
ensure
|
229
|
-
unless e
|
230
|
-
log_info(commit_transaction_sql)
|
231
|
-
stmt.execute(commit_transaction_sql)
|
232
|
-
end
|
233
|
-
stmt.close
|
234
|
-
@transactions.delete(Thread.current)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
212
|
# The uri for this connection. You can specify the uri
|
240
213
|
# using the :uri, :url, or :database options. You don't
|
241
214
|
# need to worry about this if you use Sequel.connect
|
@@ -248,6 +221,12 @@ module Sequel
|
|
248
221
|
|
249
222
|
private
|
250
223
|
|
224
|
+
# JDBC uses a statement object to execute SQL on the database
|
225
|
+
def begin_transaction(conn)
|
226
|
+
conn = conn.createStatement
|
227
|
+
super
|
228
|
+
end
|
229
|
+
|
251
230
|
# The JDBC adapter should not need the pool to convert exceptions.
|
252
231
|
def connection_pool_default_options
|
253
232
|
super.merge(:pool_convert_exceptions=>false)
|
@@ -323,6 +302,12 @@ module Sequel
|
|
323
302
|
synchronize{|c| metadata_dataset.send(:process_result_set, c.getMetaData.send(*args), &block)}
|
324
303
|
end
|
325
304
|
|
305
|
+
# Close the given statement when removing the transaction
|
306
|
+
def remove_transaction(stmt)
|
307
|
+
stmt.close if stmt
|
308
|
+
super
|
309
|
+
end
|
310
|
+
|
326
311
|
# Java being java, you need to specify the type of each argument
|
327
312
|
# for the prepared statement, and bind it individually. This
|
328
313
|
# guesses which JDBC method to use, and hopefully JRuby will convert
|
@@ -372,6 +357,11 @@ module Sequel
|
|
372
357
|
end
|
373
358
|
ts
|
374
359
|
end
|
360
|
+
|
361
|
+
# Create a statement object to execute transaction statements.
|
362
|
+
def transaction_statement_object(conn)
|
363
|
+
conn.createStatement
|
364
|
+
end
|
375
365
|
end
|
376
366
|
|
377
367
|
class Dataset < Sequel::Dataset
|
@@ -55,6 +55,9 @@ module Sequel
|
|
55
55
|
class Database < Sequel::Database
|
56
56
|
include Sequel::MySQL::DatabaseMethods
|
57
57
|
|
58
|
+
# Mysql::Error messages that indicate the current connection should be disconnected
|
59
|
+
MYSQL_DATABASE_DISCONNECT_ERRORS = /\ACommands out of sync; you can't run this command now\z/
|
60
|
+
|
58
61
|
set_adapter_scheme :mysql
|
59
62
|
|
60
63
|
# Support stored procedures on MySQL
|
@@ -101,8 +104,7 @@ module Sequel
|
|
101
104
|
|
102
105
|
# By default, MySQL 'where id is null' selects the last inserted id
|
103
106
|
conn.query("set SQL_AUTO_IS_NULL=0") unless opts[:auto_is_null]
|
104
|
-
|
105
|
-
conn.query_with_result = false
|
107
|
+
|
106
108
|
class << conn
|
107
109
|
attr_accessor :prepared_statements
|
108
110
|
end
|
@@ -132,29 +134,6 @@ module Sequel
|
|
132
134
|
def server_version(server=nil)
|
133
135
|
@server_version ||= (synchronize(server){|conn| conn.server_version if conn.respond_to?(:server_version)} || super)
|
134
136
|
end
|
135
|
-
|
136
|
-
# Support single level transactions on MySQL.
|
137
|
-
def transaction(opts={})
|
138
|
-
synchronize(opts[:server]) do |conn|
|
139
|
-
return yield(conn) if @transactions.include?(Thread.current)
|
140
|
-
log_info(begin_transaction_sql)
|
141
|
-
conn.query(begin_transaction_sql)
|
142
|
-
begin
|
143
|
-
@transactions << Thread.current
|
144
|
-
yield(conn)
|
145
|
-
rescue ::Exception => e
|
146
|
-
log_info(rollback_transaction_sql)
|
147
|
-
conn.query(rollback_transaction_sql)
|
148
|
-
transaction_error(e, Mysql::Error)
|
149
|
-
ensure
|
150
|
-
unless e
|
151
|
-
log_info(commit_transaction_sql)
|
152
|
-
conn.query(commit_transaction_sql)
|
153
|
-
end
|
154
|
-
@transactions.delete(Thread.current)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
137
|
|
159
138
|
private
|
160
139
|
|
@@ -162,33 +141,49 @@ module Sequel
|
|
162
141
|
# option is :select, yield the result of the query, otherwise
|
163
142
|
# yield the connection if a block is given.
|
164
143
|
def _execute(conn, sql, opts)
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
nil
|
173
|
-
else
|
174
|
-
begin
|
175
|
-
yield r
|
176
|
-
ensure
|
144
|
+
begin
|
145
|
+
log_info(sql)
|
146
|
+
r = conn.query(sql)
|
147
|
+
if opts[:type] == :select
|
148
|
+
yield r if r
|
149
|
+
if conn.respond_to?(:next_result) && conn.next_result
|
150
|
+
loop do
|
177
151
|
r.free
|
152
|
+
r = nil
|
153
|
+
begin
|
154
|
+
r = conn.use_result
|
155
|
+
rescue Mysql::Error
|
156
|
+
break
|
157
|
+
end
|
158
|
+
yield r
|
159
|
+
break unless conn.next_result
|
178
160
|
end
|
179
161
|
end
|
180
|
-
|
162
|
+
else
|
163
|
+
yield conn if block_given?
|
181
164
|
end
|
182
|
-
|
183
|
-
|
165
|
+
rescue Mysql::Error => e
|
166
|
+
raise_error(e, :disconnect=>MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message))
|
167
|
+
ensure
|
168
|
+
r.free if r
|
184
169
|
end
|
185
170
|
end
|
186
171
|
|
172
|
+
# MySQL connections use the query method to execute SQL without a result
|
173
|
+
def connection_execute_method
|
174
|
+
:query
|
175
|
+
end
|
176
|
+
|
187
177
|
# MySQL doesn't need the connection pool to convert exceptions.
|
188
178
|
def connection_pool_default_options
|
189
179
|
super.merge(:pool_convert_exceptions=>false)
|
190
180
|
end
|
191
181
|
|
182
|
+
# The MySQL adapter main error class is Mysql::Error
|
183
|
+
def database_error_classes
|
184
|
+
[Mysql::Error]
|
185
|
+
end
|
186
|
+
|
192
187
|
# The database name when using the native adapter is always stored in
|
193
188
|
# the :database option.
|
194
189
|
def database_name
|