aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2012-02-21 15:01:27 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2012-02-21 15:01:27 -0800
commitbb22e84abe262b6e6e0975b3f6c4262929ab8bca (patch)
tree4bb98cb7d8c7ba2028e7c67a38d4738663ef23f2
parentaa43fe1eb7db56f333698033e02b5e879b85145b (diff)
downloadrails-bb22e84abe262b6e6e0975b3f6c4262929ab8bca.tar.gz
rails-bb22e84abe262b6e6e0975b3f6c4262929ab8bca.tar.bz2
rails-bb22e84abe262b6e6e0975b3f6c4262929ab8bca.zip
added a module for visiting and transforming bind values
-rw-r--r--lib/arel/visitors/bind_visitor.rb24
-rw-r--r--lib/arel/visitors/to_sql.rb4
-rw-r--r--test/visitors/test_bind_visitor.rb39
3 files changed, 65 insertions, 2 deletions
diff --git a/lib/arel/visitors/bind_visitor.rb b/lib/arel/visitors/bind_visitor.rb
new file mode 100644
index 0000000000..0f1e38315b
--- /dev/null
+++ b/lib/arel/visitors/bind_visitor.rb
@@ -0,0 +1,24 @@
+module Arel
+ module Visitors
+ module BindVisitor
+ def initialize target
+ @block = nil
+ super
+ end
+
+ def accept node, &block
+ @block = block if block_given?
+ super
+ end
+
+ private
+ def visit_Arel_Nodes_BindParam o
+ if @block
+ @block.call
+ else
+ super
+ end
+ end
+ end
+ end
+end
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 29df72ff97..64f96b44dd 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -108,7 +108,7 @@ key on UpdateManager using UpdateManager#key=
def visit_Arel_Nodes_Values o
"VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
if Nodes::SqlLiteral === value
- visit_Arel_Nodes_SqlLiteral value
+ visit value
else
quote(value, attr && column_for(attr))
end
@@ -133,7 +133,7 @@ key on UpdateManager using UpdateManager#key=
(visit(o.set_quantifier) if o.set_quantifier),
("#{o.projections.map { |x| visit x }.join ', '}" unless o.projections.empty?),
("FROM #{visit(o.source)}" if o.source && !o.source.empty?),
- ("WHERE #{o.wheres.map { |x| accept x }.join ' AND ' }" unless o.wheres.empty?),
+ ("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.empty?),
("GROUP BY #{o.groups.map { |x| visit x }.join ', ' }" unless o.groups.empty?),
(visit(o.having) if o.having),
].compact.join ' '
diff --git a/test/visitors/test_bind_visitor.rb b/test/visitors/test_bind_visitor.rb
new file mode 100644
index 0000000000..92e5d1612c
--- /dev/null
+++ b/test/visitors/test_bind_visitor.rb
@@ -0,0 +1,39 @@
+require 'helper'
+require 'arel/visitors/bind_visitor'
+
+module Arel
+ module Visitors
+ class TestBindVisitor < MiniTest::Unit::TestCase
+ def test_visitor_yields_on_binds
+ visitor = Class.new(Arel::Visitors::Visitor) {
+ def initialize omg
+ end
+
+ include Arel::Visitors::BindVisitor
+ }.new nil
+
+ bp = Nodes::BindParam.new 'omg'
+ called = false
+ visitor.accept(bp) { called = true }
+ assert called
+ end
+
+ def test_visitor_only_yields_on_binds
+ visitor = Class.new(Arel::Visitors::Visitor) {
+ def initialize omg
+ end
+
+ include Arel::Visitors::BindVisitor
+ }.new(nil)
+
+ bp = Arel.sql 'omg'
+ called = false
+
+ assert_raises(TypeError) {
+ visitor.accept(bp) { called = true }
+ }
+ refute called
+ end
+ end
+ end
+end