refactor exec_delete to reuse the statement cache from exec_query
This commit is contained in:
parent
4c41be9b83
commit
ed775c66bc
@ -401,44 +401,9 @@ def client_encoding
|
||||
|
||||
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]
|
||||
exec_stmt(sql, name, binds) do |cols, stmt|
|
||||
ActiveRecord::Result.new(cols, stmt.to_a) if cols
|
||||
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)
|
||||
end
|
||||
|
||||
stmt.free_result
|
||||
stmt.close if binds.empty?
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
@ -492,40 +457,9 @@ def update_sql(sql, name = nil) #:nodoc:
|
||||
|
||||
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]
|
||||
exec_stmt(sql, name, binds) do |cols, stmt|
|
||||
stmt.affected_rows
|
||||
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
|
||||
end
|
||||
|
||||
result = stmt.affected_rows
|
||||
stmt.free_result
|
||||
stmt.close if binds.empty?
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
@ -882,6 +816,46 @@ def remove_timestamps_sql(table_name)
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user