Skip to content

Commit

Permalink
added a module for visiting and transforming bind values
Browse files Browse the repository at this point in the history
  • Loading branch information
tenderlove committed Feb 21, 2012
1 parent aa43fe1 commit bb22e84
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
24 changes: 24 additions & 0 deletions 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
4 changes: 2 additions & 2 deletions lib/arel/visitors/to_sql.rb
Expand Up @@ -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
Expand All @@ -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 ' '
Expand Down
39 changes: 39 additions & 0 deletions 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

0 comments on commit bb22e84

Please sign in to comment.