Permalink
Browse files

added a module for visiting and transforming bind values

  • Loading branch information...
1 parent aa43fe1 commit bb22e84abe262b6e6e0975b3f6c4262929ab8bca @tenderlove tenderlove committed Feb 21, 2012
Showing with 65 additions and 2 deletions.
  1. +24 −0 lib/arel/visitors/bind_visitor.rb
  2. +2 −2 lib/arel/visitors/to_sql.rb
  3. +39 −0 test/visitors/test_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
@@ -108,7 +108,7 @@ def column_cache
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 @@ def visit_Arel_Nodes_SelectCore o
(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 ' '
@@ -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

0 comments on commit bb22e84

Please sign in to comment.