From bb22e84abe262b6e6e0975b3f6c4262929ab8bca Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 21 Feb 2012 15:01:27 -0800 Subject: [PATCH] added a module for visiting and transforming bind values --- lib/arel/visitors/bind_visitor.rb | 24 ++++++++++++++++++ lib/arel/visitors/to_sql.rb | 4 +-- test/visitors/test_bind_visitor.rb | 39 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 lib/arel/visitors/bind_visitor.rb create mode 100644 test/visitors/test_bind_visitor.rb diff --git a/lib/arel/visitors/bind_visitor.rb b/lib/arel/visitors/bind_visitor.rb new file mode 100644 index 00000000..0f1e3831 --- /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 29df72ff..64f96b44 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -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 ' ' diff --git a/test/visitors/test_bind_visitor.rb b/test/visitors/test_bind_visitor.rb new file mode 100644 index 00000000..92e5d161 --- /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