From a6a7c75ff486657909e20e2f48764136caa5e87e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 8 Apr 2014 17:01:53 -0700 Subject: push reduction visitors to a reduction base class this lets our old depth first and dot visitors to work normally --- lib/arel/visitors/depth_first.rb | 17 +++-------------- lib/arel/visitors/dot.rb | 3 ++- lib/arel/visitors/reduce.rb | 25 +++++++++++++++++++++++++ lib/arel/visitors/to_sql.rb | 3 ++- lib/arel/visitors/visitor.rb | 8 ++++---- 5 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 lib/arel/visitors/reduce.rb (limited to 'lib') diff --git a/lib/arel/visitors/depth_first.rb b/lib/arel/visitors/depth_first.rb index 458934f854..4d2ecfa5e1 100644 --- a/lib/arel/visitors/depth_first.rb +++ b/lib/arel/visitors/depth_first.rb @@ -5,22 +5,11 @@ module Arel @block = block || Proc.new end - def accept object - visit object - end - private - def visit object - send dispatch[object.class], object - rescue NoMethodError => e - raise e if respond_to?(dispatch[object.class], true) - superklass = object.class.ancestors.find { |klass| - respond_to?(dispatch[klass], true) - } - raise(TypeError, "Cannot visit #{object.class}") unless superklass - dispatch[object.class] = dispatch[superklass] - retry + def visit o + super + @block.call o end def unary o diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb index 99f4c467d2..ba35223ac9 100644 --- a/lib/arel/visitors/dot.rb +++ b/lib/arel/visitors/dot.rb @@ -23,11 +23,12 @@ module Arel end def accept object - super + visit object to_dot end private + def visit_Arel_Nodes_Ordering o visit_edge o, "expr" end diff --git a/lib/arel/visitors/reduce.rb b/lib/arel/visitors/reduce.rb new file mode 100644 index 0000000000..9670cad27c --- /dev/null +++ b/lib/arel/visitors/reduce.rb @@ -0,0 +1,25 @@ +require 'arel/visitors/visitor' + +module Arel + module Visitors + class Reduce < Arel::Visitors::Visitor + def accept object, collector + visit object, collector + end + + private + + def visit object, collector + send dispatch[object.class], object, collector + rescue NoMethodError => e + raise e if respond_to?(dispatch[object.class], true) + superklass = object.class.ancestors.find { |klass| + respond_to?(dispatch[klass], true) + } + raise(TypeError, "Cannot visit #{object.class}") unless superklass + dispatch[object.class] = dispatch[superklass] + retry + end + end + end +end diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index f8b8a9a07c..0dbec61212 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -1,9 +1,10 @@ require 'bigdecimal' require 'date' +require 'arel/visitors/reduce' module Arel module Visitors - class ToSql < Arel::Visitors::Visitor + class ToSql < Arel::Visitors::Reduce ## # This is some roflscale crazy stuff. I'm roflscaling this because # building SQL queries is a hotspot. I will explain the roflscale so that diff --git a/lib/arel/visitors/visitor.rb b/lib/arel/visitors/visitor.rb index 2d4b472ea3..0730c15794 100644 --- a/lib/arel/visitors/visitor.rb +++ b/lib/arel/visitors/visitor.rb @@ -1,8 +1,8 @@ module Arel module Visitors class Visitor - def accept object, collector - visit object, collector + def accept object + visit object end private @@ -18,8 +18,8 @@ module Arel DISPATCH[self.class] end - def visit object, collector - send dispatch[object.class], object, collector + def visit object + send dispatch[object.class], object rescue NoMethodError => e raise e if respond_to?(dispatch[object.class], true) superklass = object.class.ancestors.find { |klass| -- cgit v1.2.3