aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb114
1 files changed, 44 insertions, 70 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index f173bab51d..1fd286622b 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -401,44 +401,9 @@ module ActiveRecord
def exec_query(sql, name = 'SQL', binds = [])
log(sql, name, binds) do
- result = nil
-
- cache = {}
- if binds.empty?
- stmt = @connection.prepare(sql)
- else
- cache = @statements[sql] ||= {
- :stmt => @connection.prepare(sql)
- }
- stmt = cache[:stmt]
- end
-
-
- begin
- stmt.execute(*binds.map { |col, val| type_cast(val, col) })
- rescue Mysql::Error => e
- # Older versions of MySQL leave the prepared statement in a bad
- # place when an error occurs. To support older mysql versions, we
- # need to close the statement and delete the statement from the
- # cache.
- stmt.close
- @statements.delete sql
- raise e
- end
-
- if metadata = stmt.result_metadata
- cols = cache[:cols] ||= metadata.fetch_fields.map { |field|
- field.name
- }
-
- metadata.free
- result = ActiveRecord::Result.new(cols, stmt.to_a)
+ exec_stmt(sql, name, binds) do |cols, stmt|
+ ActiveRecord::Result.new(cols, stmt.to_a) if cols
end
-
- stmt.free_result
- stmt.close if binds.empty?
-
- result
end
end
@@ -492,40 +457,9 @@ module ActiveRecord
def exec_delete(sql, name, binds)
log(sql, name, binds) do
- result = nil
-
- cache = {}
- if binds.empty?
- stmt = @connection.prepare(sql)
- else
- cache = @statements[sql] ||= {
- :stmt => @connection.prepare(sql)
- }
- stmt = cache[:stmt]
- end
-
-
- begin
- stmt.execute(*binds.map { |col, val| type_cast(val, col) })
- rescue Mysql::Error => e
- # Older versions of MySQL leave the prepared statement in a bad
- # place when an error occurs. To support older mysql versions, we
- # need to close the statement and delete the statement from the
- # cache.
- stmt.close
- @statements.delete sql
- raise e
- end
-
- if metadata = stmt.result_metadata
- metadata.free
+ exec_stmt(sql, name, binds) do |cols, stmt|
+ stmt.affected_rows
end
-
- result = stmt.affected_rows
- stmt.free_result
- stmt.close if binds.empty?
-
- result
end
end
@@ -882,6 +816,46 @@ module ActiveRecord
end
private
+ def exec_stmt(sql, name, binds)
+ cache = {}
+ if binds.empty?
+ stmt = @connection.prepare(sql)
+ else
+ cache = @statements[sql] ||= {
+ :stmt => @connection.prepare(sql)
+ }
+ stmt = cache[:stmt]
+ end
+
+
+ begin
+ stmt.execute(*binds.map { |col, val| type_cast(val, col) })
+ rescue Mysql::Error => e
+ # Older versions of MySQL leave the prepared statement in a bad
+ # place when an error occurs. To support older mysql versions, we
+ # need to close the statement and delete the statement from the
+ # cache.
+ stmt.close
+ @statements.delete sql
+ raise e
+ end
+
+ cols = nil
+ if metadata = stmt.result_metadata
+ cols = cache[:cols] ||= metadata.fetch_fields.map { |field|
+ field.name
+ }
+ end
+
+ result = yield [cols, stmt]
+
+ stmt.result_metadata.free if cols
+ stmt.free_result
+ stmt.close if binds.empty?
+
+ result
+ end
+
def connect
encoding = @config[:encoding]
if encoding