From 40603729cc1d9a8e636a887446d051390d15fcd8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 3 Dec 2010 15:24:30 -0800 Subject: attributes do not need a column member --- lib/arel/visitors/join_sql.rb | 2 +- lib/arel/visitors/to_sql.rb | 37 ++++++++++++++++++++++++++++--------- lib/arel/visitors/visitor.rb | 3 ++- 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'lib/arel/visitors') diff --git a/lib/arel/visitors/join_sql.rb b/lib/arel/visitors/join_sql.rb index d3fb18d3c6..7ba2bde540 100644 --- a/lib/arel/visitors/join_sql.rb +++ b/lib/arel/visitors/join_sql.rb @@ -8,7 +8,7 @@ module Arel # # This visitor is used in SelectManager#join_sql and is for backwards # compatibility with Arel V1.0 - class JoinSql < Arel::Visitors::ToSql + module JoinSql private def visit_Arel_Nodes_SelectCore o diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index b8a991b965..8db90c376a 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -10,7 +10,8 @@ module Arel @last_column = nil @quoted_tables = {} @quoted_columns = {} - @column_cache = {} + @column_cache = Hash.new { |h,k| h[k] = {} } + @table_exists = {} end def accept object @@ -67,17 +68,35 @@ module Arel o.alias ? " AS #{visit o.alias}" : ''}" end - def column_for relation, name - name = name.to_s - table = relation.name + def table_exists? name + return true if @table_exists.key? name + if @connection.table_exists?(name) + @table_exists[name] = true + else + false + end + end + + def column_for attr + name = attr.name.to_sym + table = attr.relation.name + + return nil unless table_exists? table + + # If we don't have this column cached, get a list of columns and + # cache them for this table + unless @column_cache.key? table + #$stderr.puts "MISS: #{self.class.name} #{object_id} #{table.inspect} : #{name.inspect}" + columns = @connection.columns(table, "#{table}(#{name}) Columns") + @column_cache[table] = Hash[columns.map { |c| [c.name.to_sym, c] }] + end - columns = @connection.columns(table, "#{table} Columns") - columns.find { |col| col.name.to_s == name } + @column_cache[table][name] end def visit_Arel_Nodes_Values o "VALUES (#{o.expressions.zip(o.columns).map { |value, attr| - quote(value, attr && column_for(attr.relation, attr.name)) + quote(value, attr && column_for(attr)) }.join ', '})" end @@ -235,7 +254,7 @@ module Arel end def visit_Arel_Nodes_Assignment o - right = quote(o.right, o.left.column) + right = quote(o.right, column_for(o.left)) "#{visit o.left} = #{right}" end @@ -268,7 +287,7 @@ module Arel end def visit_Arel_Attributes_Attribute o - @last_column = o.column + @last_column = column_for o join_name = o.relation.table_alias || o.relation.name "#{quote_table_name join_name}.#{quote_column_name o.name}" end diff --git a/lib/arel/visitors/visitor.rb b/lib/arel/visitors/visitor.rb index 055acf9765..85359f3e67 100644 --- a/lib/arel/visitors/visitor.rb +++ b/lib/arel/visitors/visitor.rb @@ -13,7 +13,8 @@ module Arel def visit object send DISPATCH[object.class], object - rescue NoMethodError + rescue NoMethodError => e + raise e if respond_to?(DISPATCH[object.class], true) warn "visiting #{object.class} via superclass, this will be removed in arel 2.2.0" if $VERBOSE superklass = object.class.ancestors.find { |klass| respond_to?(DISPATCH[klass], true) -- cgit v1.2.3