postgresql supports prepare statement deletes
This commit is contained in:
parent
850b3ca477
commit
f1df6b2dce
|
@ -62,6 +62,13 @@ module ActiveRecord
|
|||
exec_query(sql, name, binds)
|
||||
end
|
||||
|
||||
# Executes delete +sql+ statement in the context of this connection using
|
||||
# +binds+ as the bind substitutes. +name+ is the logged along with
|
||||
# the executed +sql+ statement.
|
||||
def exec_delete(sql, name, binds)
|
||||
exec_query(sql, name, binds)
|
||||
end
|
||||
|
||||
# Returns the last auto-generated ID from the affected table.
|
||||
#
|
||||
# +id_value+ will be returned unless the value is nil, in
|
||||
|
@ -82,8 +89,8 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
# Executes the delete statement and returns the number of rows affected.
|
||||
def delete(sql, name = nil)
|
||||
delete_sql(sql, name)
|
||||
def delete(sql, name = nil, binds = [])
|
||||
exec_delete(sql, name, binds)
|
||||
end
|
||||
|
||||
# Checks whether there is currently no transaction active. This is done
|
||||
|
|
|
@ -543,30 +543,26 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def exec_query(sql, name = 'SQL', binds = [])
|
||||
return exec_no_cache(sql, name) if binds.empty?
|
||||
|
||||
log(sql, name, binds) do
|
||||
unless @statements.key? sql
|
||||
nextkey = "a#{@statements.length + 1}"
|
||||
@connection.prepare nextkey, sql
|
||||
@statements[sql] = nextkey
|
||||
end
|
||||
result = binds.empty? ? exec_no_cache(sql, binds) :
|
||||
exec_cache(sql, binds)
|
||||
|
||||
key = @statements[sql]
|
||||
|
||||
# Clear the queue
|
||||
@connection.get_last_result
|
||||
@connection.send_query_prepared(key, binds.map { |col, val|
|
||||
type_cast(val, col)
|
||||
})
|
||||
@connection.block
|
||||
result = @connection.get_last_result
|
||||
ret = ActiveRecord::Result.new(result.fields, result_as_array(result))
|
||||
result.clear
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
def exec_delete(sql, name = 'SQL', binds = [])
|
||||
log(sql, name, binds) do
|
||||
result = binds.empty? ? exec_no_cache(sql, binds) :
|
||||
exec_cache(sql, binds)
|
||||
affected = result.cmd_tuples
|
||||
result.clear
|
||||
affected
|
||||
end
|
||||
end
|
||||
|
||||
def sql_for_insert(sql, pk, id_value, sequence_name, binds)
|
||||
unless pk
|
||||
_, table = extract_schema_and_table(sql.split(" ", 4)[2])
|
||||
|
@ -980,13 +976,26 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
private
|
||||
def exec_no_cache(sql, name)
|
||||
log(sql, name) do
|
||||
result = @connection.async_exec(sql)
|
||||
ret = ActiveRecord::Result.new(result.fields, result_as_array(result))
|
||||
result.clear
|
||||
ret
|
||||
def exec_no_cache(sql, binds)
|
||||
@connection.async_exec(sql)
|
||||
end
|
||||
|
||||
def exec_cache(sql, binds)
|
||||
unless @statements.key? sql
|
||||
nextkey = "a#{@statements.length + 1}"
|
||||
@connection.prepare nextkey, sql
|
||||
@statements[sql] = nextkey
|
||||
end
|
||||
|
||||
key = @statements[sql]
|
||||
|
||||
# Clear the queue
|
||||
@connection.get_last_result
|
||||
@connection.send_query_prepared(key, binds.map { |col, val|
|
||||
type_cast(val, col)
|
||||
})
|
||||
@connection.block
|
||||
@connection.get_last_result
|
||||
end
|
||||
|
||||
# The internal PostgreSQL identifier of the money data type.
|
||||
|
|
|
@ -77,7 +77,15 @@ module ActiveRecord
|
|||
def destroy
|
||||
if persisted?
|
||||
IdentityMap.remove(self) if IdentityMap.enabled?
|
||||
self.class.unscoped.where(self.class.arel_table[self.class.primary_key].eq(id)).delete_all
|
||||
pk = self.class.primary_key
|
||||
column = self.class.columns_hash[pk]
|
||||
substitute = connection.substitute_at(column, 0)
|
||||
|
||||
relation = self.class.unscoped.where(
|
||||
self.class.arel_table[pk].eq(substitute))
|
||||
|
||||
relation.bind_values = [[column, id]]
|
||||
relation.delete_all
|
||||
end
|
||||
|
||||
@destroyed = true
|
||||
|
|
|
@ -338,7 +338,9 @@ module ActiveRecord
|
|||
where(conditions).delete_all
|
||||
else
|
||||
statement = arel.compile_delete
|
||||
affected = @klass.connection.delete statement.to_sql
|
||||
affected = @klass.connection.delete(
|
||||
statement.to_sql, 'SQL', bind_values)
|
||||
|
||||
reset
|
||||
affected
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue