aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb50
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb4
3 files changed, 36 insertions, 22 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 f2715cdab0..f687d3a7e8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -9,30 +9,36 @@ module ActiveRecord
end
# Converts an arel AST to SQL
- def to_sql(arel, binds = [])
- if arel.respond_to?(:ast)
- collected = visitor.accept(arel.ast, collector)
- collected.compile(binds, self).freeze
+ def to_sql(arel_or_sql_string, binds = [])
+ if arel_or_sql_string.respond_to?(:ast)
+ unless binds.empty?
+ raise "Passing bind parameters with an arel AST is forbidden. " \
+ "The values must be stored on the AST directly"
+ end
+ sql, binds = visitor.accept(arel_or_sql_string.ast, collector).value
+ [sql.freeze, binds || []]
else
- arel.dup.freeze
+ [arel_or_sql_string.dup.freeze, binds]
end
end
# This is used in the StatementCache object. It returns an object that
# can be used to query the database repeatedly.
def cacheable_query(klass, arel) # :nodoc:
- collected = visitor.accept(arel.ast, collector)
if prepared_statements
- klass.query(collected.value)
+ sql, binds = visitor.accept(arel.ast, collector).value
+ query = klass.query(sql)
else
- klass.partial_query(collected.value)
+ query = klass.partial_query(arel.ast)
+ binds = []
end
+ [query, binds]
end
# Returns an ActiveRecord::Result instance.
def select_all(arel, name = nil, binds = [], preparable: nil)
- arel, binds = binds_from_relation arel, binds
- sql = to_sql(arel, binds)
+ arel = arel_from_relation(arel)
+ sql, binds = to_sql(arel, binds)
if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
preparable = false
else
@@ -131,20 +137,23 @@ module ActiveRecord
#
# If the next id was calculated in advance (as in Oracle), it should be
# passed in as +id_value+.
- def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
- value = exec_insert(to_sql(arel, binds), name, binds, pk, sequence_name)
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil)
+ sql, binds = to_sql(arel)
+ value = exec_insert(sql, name, binds, pk, sequence_name)
id_value || last_inserted_id(value)
end
alias create insert
# Executes the update statement and returns the number of rows affected.
- def update(arel, name = nil, binds = [])
- exec_update(to_sql(arel, binds), name, binds)
+ def update(arel, name = nil)
+ sql, binds = to_sql(arel)
+ exec_update(sql, name, binds)
end
# Executes the delete statement and returns the number of rows affected.
- def delete(arel, name = nil, binds = [])
- exec_delete(to_sql(arel, binds), name, binds)
+ def delete(arel, name = nil)
+ sql, binds = to_sql(arel)
+ exec_delete(sql, name, binds)
end
# Returns +true+ when the connection adapter supports prepared statement
@@ -430,11 +439,12 @@ module ActiveRecord
row && row.first
end
- def binds_from_relation(relation, binds)
- if relation.is_a?(Relation) && binds.empty?
- relation, binds = relation.arel, relation.bound_attributes
+ def arel_from_relation(relation)
+ if relation.is_a?(Relation)
+ relation.arel
+ else
+ relation
end
- [relation, binds]
end
# Fixture value is quoted by Arel, however scalar values
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
index 077e8beba9..ecf5201d12 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
@@ -92,8 +92,8 @@ module ActiveRecord
def select_all(arel, name = nil, binds = [], preparable: nil)
if @query_cache_enabled && !locked?(arel)
- arel, binds = binds_from_relation arel, binds
- sql = to_sql(arel, binds)
+ arel = arel_from_relation(arel)
+ sql, binds = to_sql(arel, binds)
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
else
super
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index b637518fc8..7b83bc319c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -24,6 +24,10 @@ module ActiveRecord
return value.quoted_id
end
+ if value.respond_to?(:value_for_database)
+ value = value.value_for_database
+ end
+
_quote(value)
end