1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Unprepared Visitor + unprepared_statement

This commit is contained in:
Cédric FABIANSKI 2013-01-16 20:08:07 +01:00
parent b67043393b
commit 9f549212c3
6 changed files with 33 additions and 3 deletions

View file

@ -1,5 +1,17 @@
## Rails 4.0.0 (unreleased) ## ## Rails 4.0.0 (unreleased) ##
* Created block to by-pass the prepared statement bindings.
This will allow to compose fragments of large SQL statements to
avoid multiple round-trips between Ruby and the DB.
Example:
sql = Post.connection.unprepared_statement do
Post.first.comments.to_sql
end
*Cédric Fabianski*
* Expand `#cache_key` to consult all relevant updated timestamps. * Expand `#cache_key` to consult all relevant updated timestamps.
Previously only `updated_at` column was checked, now it will Previously only `updated_at` column was checked, now it will

View file

@ -118,6 +118,17 @@ module ActiveRecord
@in_use = false @in_use = false
end end
def unprepared_visitor
self.class::BindSubstitution.new self
end
def unprepared_statement
old, @visitor = @visitor, unprepared_visitor
yield
ensure
@visitor = old
end
# Returns the human-readable name of the adapter. Use mixed case - one # Returns the human-readable name of the adapter. Use mixed case - one
# can always use downcase if needed. # can always use downcase if needed.
def adapter_name def adapter_name

View file

@ -143,7 +143,7 @@ module ActiveRecord
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true }) if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
@visitor = Arel::Visitors::MySQL.new self @visitor = Arel::Visitors::MySQL.new self
else else
@visitor = BindSubstitution.new self @visitor = unprepared_visitor
end end
end end

View file

@ -489,7 +489,7 @@ module ActiveRecord
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true }) if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
@visitor = Arel::Visitors::PostgreSQL.new self @visitor = Arel::Visitors::PostgreSQL.new self
else else
@visitor = BindSubstitution.new self @visitor = unprepared_visitor
end end
@connection_parameters, @config = connection_parameters, config @connection_parameters, @config = connection_parameters, config

View file

@ -113,7 +113,7 @@ module ActiveRecord
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true }) if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
@visitor = Arel::Visitors::SQLite.new self @visitor = Arel::Visitors::SQLite.new self
else else
@visitor = BindSubstitution.new self @visitor = unprepared_visitor
end end
end end

View file

@ -714,6 +714,13 @@ class RelationTest < ActiveRecord::TestCase
assert_equal [developers(:poor_jamis)], dev_with_count.to_a assert_equal [developers(:poor_jamis)], dev_with_count.to_a
end end
def test_relation_to_sql
sql = Post.connection.unprepared_statement do
Post.first.comments.to_sql
end
assert_no_match(/\?/, sql)
end
def test_relation_merging_with_arel_equalities_keeps_last_equality def test_relation_merging_with_arel_equalities_keeps_last_equality
devs = Developer.where(Developer.arel_table[:salary].eq(80000)).merge( devs = Developer.where(Developer.arel_table[:salary].eq(80000)).merge(
Developer.where(Developer.arel_table[:salary].eq(9000)) Developer.where(Developer.arel_table[:salary].eq(9000))