aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel/visitors
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2010-12-03 15:24:30 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2010-12-03 15:24:30 -0800
commit40603729cc1d9a8e636a887446d051390d15fcd8 (patch)
tree569e33bb28ec536341505487e6a3c3fdde0e9153 /lib/arel/visitors
parentdbc1f65244ac0b75f746ea91289f2e36ced435a6 (diff)
downloadrails-40603729cc1d9a8e636a887446d051390d15fcd8.tar.gz
rails-40603729cc1d9a8e636a887446d051390d15fcd8.tar.bz2
rails-40603729cc1d9a8e636a887446d051390d15fcd8.zip
attributes do not need a column member
Diffstat (limited to 'lib/arel/visitors')
-rw-r--r--lib/arel/visitors/join_sql.rb2
-rw-r--r--lib/arel/visitors/to_sql.rb37
-rw-r--r--lib/arel/visitors/visitor.rb3
3 files changed, 31 insertions, 11 deletions
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)