aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel
diff options
context:
space:
mode:
Diffstat (limited to 'lib/arel')
-rw-r--r--lib/arel/attributes/attribute.rb2
-rw-r--r--lib/arel/crud.rb45
-rw-r--r--lib/arel/nodes/node.rb2
-rw-r--r--lib/arel/nodes/unqualified_column.rb4
-rw-r--r--lib/arel/select_manager.rb6
-rw-r--r--lib/arel/table.rb34
-rw-r--r--lib/arel/visitors/dot.rb12
-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
10 files changed, 103 insertions, 44 deletions
diff --git a/lib/arel/attributes/attribute.rb b/lib/arel/attributes/attribute.rb
index 5cbe194b41..9a42e5a4da 100644
--- a/lib/arel/attributes/attribute.rb
+++ b/lib/arel/attributes/attribute.rb
@@ -1,6 +1,6 @@
module Arel
module Attributes
- class Attribute < Struct.new :relation, :name, :column
+ class Attribute < Struct.new :relation, :name
include Arel::Expressions
include Arel::Predications
end
diff --git a/lib/arel/crud.rb b/lib/arel/crud.rb
index b3199e6d38..ec58734456 100644
--- a/lib/arel/crud.rb
+++ b/lib/arel/crud.rb
@@ -2,8 +2,7 @@ module Arel
###
# FIXME hopefully we can remove this
module Crud
- # FIXME: this method should go away
- def update values
+ def compile_update values
um = UpdateManager.new @engine
if Nodes::SqlLiteral === values
@@ -16,22 +15,54 @@ module Arel
um.take @ast.limit
um.order(*@ast.orders)
um.wheres = @ctx.wheres
+ um
+ end
+
+ # FIXME: this method should go away
+ def update values
+ if $VERBOSE
+ warn <<-eowarn
+update (#{caller.first}) is deprecated and will be removed in ARel 3.0.0. Please
+switch to `compile_update`
+ eowarn
+ end
+ um = compile_update values
@engine.connection.update um.to_sql, 'AREL'
end
- # FIXME: this method should go away
- def insert values
+ def compile_insert values
im = InsertManager.new @engine
im.insert values
- @engine.connection.insert im.to_sql
+ im
end
- def delete
+ # FIXME: this method should go away
+ def insert values
+ if $VERBOSE
+ warn <<-eowarn
+insert (#{caller.first}) is deprecated and will be removed in ARel 3.0.0. Please
+switch to `compile_insert`
+ eowarn
+ end
+ @engine.connection.insert compile_insert(values).to_sql
+ end
+
+ def compile_delete
dm = DeleteManager.new @engine
dm.wheres = @ctx.wheres
dm.from @ctx.froms
- @engine.connection.delete dm.to_sql, 'AREL'
+ dm
+ end
+
+ def delete
+ if $VERBOSE
+ warn <<-eowarn
+delete (#{caller.first}) is deprecated and will be removed in ARel 3.0.0. Please
+switch to `compile_delete`
+ eowarn
+ end
+ @engine.connection.delete compile_delete.to_sql, 'AREL'
end
end
end
diff --git a/lib/arel/nodes/node.rb b/lib/arel/nodes/node.rb
index 404ad22ece..567221aab2 100644
--- a/lib/arel/nodes/node.rb
+++ b/lib/arel/nodes/node.rb
@@ -3,6 +3,8 @@ module Arel
###
# Abstract base class for all AST nodes
class Node
+ include Enumerable
+
###
# Factory method to create a Nodes::Not node that has the recipient of
# the caller as a child.
diff --git a/lib/arel/nodes/unqualified_column.rb b/lib/arel/nodes/unqualified_column.rb
index f7ba653c11..2820dba9d2 100644
--- a/lib/arel/nodes/unqualified_column.rb
+++ b/lib/arel/nodes/unqualified_column.rb
@@ -4,6 +4,10 @@ module Arel
alias :attribute :expr
alias :attribute= :expr=
+ def relation
+ @expr.relation
+ end
+
def column
@expr.column
end
diff --git a/lib/arel/select_manager.rb b/lib/arel/select_manager.rb
index 08cfd41e7f..de12402e9f 100644
--- a/lib/arel/select_manager.rb
+++ b/lib/arel/select_manager.rb
@@ -143,8 +143,8 @@ module Arel
def join_sql
return nil unless @ctx.froms
- viz = Visitors::JoinSql.new @engine
- Nodes::SqlLiteral.new viz.accept @ctx
+ sql = @visitor.dup.extend(Visitors::JoinSql).accept @ctx
+ Nodes::SqlLiteral.new sql
end
def order_clauses
@@ -155,7 +155,7 @@ module Arel
def joins manager
if $VERBOSE
- warn "joins is deprecated and will be removed in 2.2"
+ warn "joins is deprecated and will be removed in 3.0.0"
warn "please remove your call to joins from #{caller.first}"
end
manager.join_sql
diff --git a/lib/arel/table.rb b/lib/arel/table.rb
index aa23a7d601..e7a626a4c6 100644
--- a/lib/arel/table.rb
+++ b/lib/arel/table.rb
@@ -17,7 +17,6 @@ module Arel
if Hash === engine
@engine = engine[:engine] || Table.engine
- @columns = attributes_for engine[:columns]
# Sometime AR sends an :as parameter to table, to let the table know
# that it is an Alias. We may want to override new, and return a
@@ -46,7 +45,7 @@ module Arel
def joins manager
if $VERBOSE
- warn "joins is deprecated and will be removed in 2.2"
+ warn "joins is deprecated and will be removed in 3.0.0"
warn "please remove your call to joins from #{caller.first}"
end
nil
@@ -93,41 +92,46 @@ module Arel
end
def columns
+ if $VERBOSE
+ warn <<-eowarn
+(#{caller.first}) Arel::Table#columns is deprecated and will be removed in
+Arel 3.0.0 with no replacement. PEW PEW PEW!!!
+ eowarn
+ end
@columns ||=
attributes_for @engine.connection.columns(@name, "#{@name} Columns")
end
def [] name
- return nil unless table_exists?
-
- name = name.to_sym
- columns.find { |column| column.name == name }
+ ::Arel::Attribute.new self, name.to_sym
end
def select_manager
SelectManager.new(@engine)
end
+ def insert_manager
+ InsertManager.new(@engine)
+ end
+
private
def attributes_for columns
return nil unless columns
columns.map do |column|
- Attributes.for(column).new self, column.name.to_sym, column
+ Attributes.for(column).new self, column.name.to_sym
end
end
- def table_exists?
- @table_exists ||= tables.key?(@name) || engine.connection.table_exists?(name)
- end
-
- def tables
- self.class.table_cache(@engine)
- end
-
@@table_cache = nil
def self.table_cache engine # :nodoc:
+ if $VERBOSE
+ warn <<-eowarn
+(#{caller.first}) Arel::Table.table_cache is deprecated and will be removed in
+Arel 3.0.0 with no replacement. PEW PEW PEW!!!
+ eowarn
+ end
@@table_cache ||= Hash[engine.connection.tables.map { |x| [x,true] }]
end
end
diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb
index c515cbe220..eab5e4afdc 100644
--- a/lib/arel/visitors/dot.rb
+++ b/lib/arel/visitors/dot.rb
@@ -28,10 +28,6 @@ module Arel
end
private
- def visit_Arel_Nodes_Grouping o
- visit_edge o, "expr"
- end
-
def visit_Arel_Nodes_Ordering o
visit_edge o, "expr"
visit_edge o, "direction"
@@ -55,10 +51,6 @@ module Arel
visit_edge o, "distinct"
end
- def visit_Arel_Nodes_On o
- visit_edge o, "expr"
- end
-
def visit_Arel_Nodes_Values o
visit_edge o, "expressions"
end
@@ -80,10 +72,6 @@ module Arel
visit_edge o, "wheres"
end
- def visit_Arel_Nodes_UnqualifiedColumn o
- visit_edge o, "attribute"
- end
-
def unary o
visit_edge o, "expr"
end
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 2fb464b265..bd0d664b44 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -10,6 +10,8 @@ module Arel
@last_column = nil
@quoted_tables = {}
@quoted_columns = {}
+ @column_cache = Hash.new { |h,k| h[k] = {} }
+ @table_exists = {}
end
def accept object
@@ -66,9 +68,36 @@ module Arel
o.alias ? " AS #{visit o.alias}" : ''}"
end
+ def table_exists? name
+ return true if @table_exists.key? name
+
+ @connection.tables.each do |table|
+ @table_exists[table] = true
+ end
+
+ @table_exists.key? name
+ 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
+
+ @column_cache[table][name]
+ end
+
def visit_Arel_Nodes_Values o
- "VALUES (#{o.expressions.zip(o.columns).map { |value, column|
- quote(value, column && column.column)
+ "VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
+ quote(value, attr && column_for(attr))
}.join ', '})"
end
@@ -226,7 +255,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
@@ -259,7 +288,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)