diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/mysql_adapter.rb | 114 |
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 |