From 80ad95bae41f4f5923faeb2e7b9cab4287e54fe9 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 23 Sep 2010 15:26:08 -0700 Subject: [PATCH] moving visitors around --- lib/arel.rb | 7 +------ lib/arel/select_manager.rb | 5 +++-- lib/arel/table.rb | 4 ++-- lib/arel/tree_manager.rb | 22 +++++++++++++++------- lib/arel/update_manager.rb | 6 +----- lib/arel/visitors.rb | 6 ++++++ lib/arel/visitors/mysql.rb | 16 ++++++++++++++++ lib/arel/visitors/to_sql.rb | 18 ++++++++++++++---- lib/arel/visitors/update_sql.rb | 26 -------------------------- 9 files changed, 58 insertions(+), 52 deletions(-) create mode 100644 lib/arel/visitors.rb create mode 100644 lib/arel/visitors/mysql.rb delete mode 100644 lib/arel/visitors/update_sql.rb diff --git a/lib/arel.rb b/lib/arel.rb index 85a866b0ce160..afef2019d4b3c 100644 --- a/lib/arel.rb +++ b/lib/arel.rb @@ -12,12 +12,7 @@ require 'arel/expression' #### -require 'arel/visitors/to_sql' -require 'arel/visitors/postgresql' -require 'arel/visitors/update_sql' -require 'arel/visitors/join_sql' -require 'arel/visitors/order_clauses' -require 'arel/visitors/dot' +require 'arel/visitors' require 'arel/tree_manager' require 'arel/insert_manager' diff --git a/lib/arel/select_manager.rb b/lib/arel/select_manager.rb index 4866ea66c933d..21b9395120969 100644 --- a/lib/arel/select_manager.rb +++ b/lib/arel/select_manager.rb @@ -2,10 +2,11 @@ module Arel class SelectManager < Arel::TreeManager include Arel::Crud - def initialize engine - super + def initialize engine, table = nil + super(engine) @head = Nodes::SelectStatement.new @ctx = @head.cores.last + from table end def taken diff --git a/lib/arel/table.rb b/lib/arel/table.rb index a709a3d717766..025ef30e55cd4 100644 --- a/lib/arel/table.rb +++ b/lib/arel/table.rb @@ -37,11 +37,11 @@ def alias end def tm - SelectManager.new(@engine).from(self) + SelectManager.new(@engine, self) end def from table - SelectManager.new(@engine).from table + SelectManager.new(@engine, table) end def joins manager diff --git a/lib/arel/tree_manager.rb b/lib/arel/tree_manager.rb index 11d34ec1380b4..4ee4a6f21910e 100644 --- a/lib/arel/tree_manager.rb +++ b/lib/arel/tree_manager.rb @@ -4,23 +4,31 @@ class TreeManager include Arel::Relation VISITORS = { - 'postgresql' => Arel::Visitors::PostgreSQL + 'postgresql' => Arel::Visitors::PostgreSQL, + 'mysql' => Arel::Visitors::MySQL, + 'mysql2' => Arel::Visitors::MySQL, } + attr_accessor :visitor + def initialize engine - @engine = engine - @pool = engine.connection_pool - @adapter = @pool.spec.config[:adapter] - @visitor_klass = VISITORS[@adapter] || Visitors::ToSql + @engine = engine + @visitor = nil end def to_dot Visitors::Dot.new.accept @head end + def visitor + return @visitor if @visitor + pool = @engine.connection_pool + adapter = pool.spec.config[:adapter] + @visitor = (VISITORS[adapter] || Visitors::ToSql).new(@engine) + end + def to_sql - viz = @visitor_klass.new @engine - viz.accept @head + visitor.accept @head end def initialize_copy other diff --git a/lib/arel/update_manager.rb b/lib/arel/update_manager.rb index 0cb55549540ad..b74e0f2a27763 100644 --- a/lib/arel/update_manager.rb +++ b/lib/arel/update_manager.rb @@ -46,11 +46,7 @@ def set values end def to_sql - viz = @visitor_klass.new @engine - unless @engine.connection_pool.spec.config[:adapter] =~ /^mysql/ - viz.extend(Visitors::UpdateSql) - end - viz.accept @head + visitor.accept @head end end end diff --git a/lib/arel/visitors.rb b/lib/arel/visitors.rb new file mode 100644 index 0000000000000..22077d59436c0 --- /dev/null +++ b/lib/arel/visitors.rb @@ -0,0 +1,6 @@ +require 'arel/visitors/to_sql' +require 'arel/visitors/postgresql' +require 'arel/visitors/mysql' +require 'arel/visitors/join_sql' +require 'arel/visitors/order_clauses' +require 'arel/visitors/dot' diff --git a/lib/arel/visitors/mysql.rb b/lib/arel/visitors/mysql.rb new file mode 100644 index 0000000000000..455122359185c --- /dev/null +++ b/lib/arel/visitors/mysql.rb @@ -0,0 +1,16 @@ +module Arel + module Visitors + class MySQL < Arel::Visitors::ToSql + def visit_Arel_Nodes_UpdateStatement o + [ + "UPDATE #{visit o.relation}", + ("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?), + ("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?), + ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?), + ("LIMIT #{o.limit}" if o.limit), + ].compact.join ' ' + end + + end + end +end diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 2ccc9d7d3f7d9..d1cb115238387 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -22,15 +22,25 @@ def visit_Arel_Nodes_DeleteStatement o end def visit_Arel_Nodes_UpdateStatement o + if o.orders.empty? && o.limit.nil? + wheres = o.wheres + else + stmt = Nodes::SelectStatement.new + core = stmt.cores.first + core.froms = o.relation + core.projections = [o.relation.primary_key] + stmt.limit = o.limit + stmt.orders = o.orders + + wheres = [Nodes::In.new(o.relation.primary_key, [stmt])] + end + [ "UPDATE #{visit o.relation}", ("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?), - ("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?), - ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?), - ("LIMIT #{o.limit}" if o.limit), + ("WHERE #{wheres.map { |x| visit x }.join ' AND '}" unless wheres.empty?) ].compact.join ' ' end - def visit_Arel_Nodes_InsertStatement o [ "INSERT INTO #{visit o.relation}", diff --git a/lib/arel/visitors/update_sql.rb b/lib/arel/visitors/update_sql.rb deleted file mode 100644 index 02196a0fb0a67..0000000000000 --- a/lib/arel/visitors/update_sql.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Arel - module Visitors - module UpdateSql - def visit_Arel_Nodes_UpdateStatement o - if o.orders.empty? && o.limit.nil? - wheres = o.wheres - else - stmt = Nodes::SelectStatement.new - core = stmt.cores.first - core.froms = o.relation - core.projections = [o.relation.primary_key] - stmt.limit = o.limit - stmt.orders = o.orders - - wheres = [Nodes::In.new(o.relation.primary_key, [stmt])] - end - - [ - "UPDATE #{visit o.relation}", - ("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?), - ("WHERE #{wheres.map { |x| visit x }.join ' AND '}" unless wheres.empty?) - ].compact.join ' ' - end - end - end -end