aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-04-28 15:35:19 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2011-04-29 11:09:37 -0700
commitf1df6b2dce8bda94186d66b9edd5e727e0d05878 (patch)
tree2e9c45f02b204d15ea43b4b18bbe94c2b123e583 /activerecord
parent850b3ca4779da201d4805a12fe29d9d9a491739e (diff)
downloadrails-f1df6b2dce8bda94186d66b9edd5e727e0d05878.tar.gz
rails-f1df6b2dce8bda94186d66b9edd5e727e0d05878.tar.bz2
rails-f1df6b2dce8bda94186d66b9edd5e727e0d05878.zip
postgresql supports prepare statement deletes
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb53
-rw-r--r--activerecord/lib/active_record/persistence.rb10
-rw-r--r--activerecord/lib/active_record/relation.rb4
4 files changed, 52 insertions, 26 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 70da9d5f1e..6d52cc344d 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -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
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 0c2afc180b..255da7d183 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -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.
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 787ac977e0..b4531ed35f 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -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
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 8e5f66ec1d..658a949331 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -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