diff options
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb | 24 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 5 | ||||
-rw-r--r-- | activerecord/lib/active_record/statement_cache.rb | 28 | ||||
-rw-r--r-- | activerecord/lib/arel/collectors/composite.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/arel/collectors/sql_string.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/arel/collectors/substitute_binds.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/arel/delete_manager.rb | 11 | ||||
-rw-r--r-- | activerecord/lib/arel/nodes/delete_statement.rb | 13 | ||||
-rw-r--r-- | activerecord/lib/arel/nodes/update_statement.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/arel/table.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/arel/tree_manager.rb | 29 | ||||
-rw-r--r-- | activerecord/lib/arel/update_manager.rb | 29 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/depth_first.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/dot.rb | 1 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/mysql.rb | 22 | ||||
-rw-r--r-- | activerecord/lib/arel/visitors/to_sql.rb | 38 |
16 files changed, 110 insertions, 108 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index c10da813ec..feacdf6931 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -35,7 +35,7 @@ module ActiveRecord sql, binds = visitor.compile(arel.ast, collector) query = klass.query(sql) else - collector = PartialQueryCollector.new + collector = klass.partial_query_collector parts, binds = visitor.compile(arel.ast, collector) query = klass.partial_query(parts) end @@ -507,28 +507,6 @@ module ActiveRecord value end end - - class PartialQueryCollector - def initialize - @parts = [] - @binds = [] - end - - def <<(str) - @parts << str - self - end - - def add_bind(obj) - @binds << obj - @parts << Arel::Nodes::BindParam.new(1) - self - end - - def value - [@parts, @binds] - end - end end end end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index db06bd9e26..5bad5bfcc2 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -484,9 +484,12 @@ module ActiveRecord stmt = Arel::DeleteManager.new stmt.from(table) - if has_join_values? || has_limit_or_offset? + if has_join_values? || offset_value @klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key)) else + stmt.key = arel_attribute(primary_key) + stmt.take(arel.limit) + stmt.order(*arel.orders) stmt.wheres = arel.constraints end diff --git a/activerecord/lib/active_record/statement_cache.rb b/activerecord/lib/active_record/statement_cache.rb index b41d3504fd..1b1736dcab 100644 --- a/activerecord/lib/active_record/statement_cache.rb +++ b/activerecord/lib/active_record/statement_cache.rb @@ -44,7 +44,7 @@ module ActiveRecord def initialize(values) @values = values @indexes = values.each_with_index.find_all { |thing, i| - Arel::Nodes::BindParam === thing + Substitute === thing }.map(&:last) end @@ -56,6 +56,28 @@ module ActiveRecord end end + class PartialQueryCollector + def initialize + @parts = [] + @binds = [] + end + + def <<(str) + @parts << str + self + end + + def add_bind(obj) + @binds << obj + @parts << Substitute.new + self + end + + def value + [@parts, @binds] + end + end + def self.query(sql) Query.new(sql) end @@ -64,6 +86,10 @@ module ActiveRecord PartialQuery.new(values) end + def self.partial_query_collector + PartialQueryCollector.new + end + class Params # :nodoc: def bind; Substitute.new; end end diff --git a/activerecord/lib/arel/collectors/composite.rb b/activerecord/lib/arel/collectors/composite.rb index d040d8598d..0533544993 100644 --- a/activerecord/lib/arel/collectors/composite.rb +++ b/activerecord/lib/arel/collectors/composite.rb @@ -24,8 +24,7 @@ module Arel # :nodoc: all [left.value, right.value] end - protected - + private attr_reader :left, :right end end diff --git a/activerecord/lib/arel/collectors/sql_string.rb b/activerecord/lib/arel/collectors/sql_string.rb index c293a89a74..54e1e562c2 100644 --- a/activerecord/lib/arel/collectors/sql_string.rb +++ b/activerecord/lib/arel/collectors/sql_string.rb @@ -15,10 +15,6 @@ module Arel # :nodoc: all @bind_index += 1 self end - - def compile(bvs) - value - end end end end diff --git a/activerecord/lib/arel/collectors/substitute_binds.rb b/activerecord/lib/arel/collectors/substitute_binds.rb index 3f40eec8a8..4b894bc4b1 100644 --- a/activerecord/lib/arel/collectors/substitute_binds.rb +++ b/activerecord/lib/arel/collectors/substitute_binds.rb @@ -21,8 +21,7 @@ module Arel # :nodoc: all delegate.value end - protected - + private attr_reader :quoter, :delegate end end diff --git a/activerecord/lib/arel/delete_manager.rb b/activerecord/lib/arel/delete_manager.rb index 2def581009..fdba937d64 100644 --- a/activerecord/lib/arel/delete_manager.rb +++ b/activerecord/lib/arel/delete_manager.rb @@ -2,6 +2,8 @@ module Arel # :nodoc: all class DeleteManager < Arel::TreeManager + include TreeManager::StatementMethods + def initialize super @ast = Nodes::DeleteStatement.new @@ -12,14 +14,5 @@ module Arel # :nodoc: all @ast.relation = relation self end - - def take(limit) - @ast.limit = Nodes::Limit.new(Nodes.build_quoted(limit)) if limit - self - end - - def wheres=(list) - @ast.wheres = list - end end end diff --git a/activerecord/lib/arel/nodes/delete_statement.rb b/activerecord/lib/arel/nodes/delete_statement.rb index eaac05e2f6..5be42a084a 100644 --- a/activerecord/lib/arel/nodes/delete_statement.rb +++ b/activerecord/lib/arel/nodes/delete_statement.rb @@ -3,8 +3,7 @@ module Arel # :nodoc: all module Nodes class DeleteStatement < Arel::Nodes::Node - attr_accessor :left, :right - attr_accessor :limit + attr_accessor :left, :right, :orders, :limit, :key alias :relation :left alias :relation= :left= @@ -15,6 +14,9 @@ module Arel # :nodoc: all super() @left = relation @right = wheres + @orders = [] + @limit = nil + @key = nil end def initialize_copy(other) @@ -24,13 +26,16 @@ module Arel # :nodoc: all end def hash - [self.class, @left, @right].hash + [self.class, @left, @right, @orders, @limit, @key].hash end def eql?(other) self.class == other.class && self.left == other.left && - self.right == other.right + self.right == other.right && + self.orders == other.orders && + self.limit == other.limit && + self.key == other.key end alias :== :eql? end diff --git a/activerecord/lib/arel/nodes/update_statement.rb b/activerecord/lib/arel/nodes/update_statement.rb index 5184b1180f..017a553c4c 100644 --- a/activerecord/lib/arel/nodes/update_statement.rb +++ b/activerecord/lib/arel/nodes/update_statement.rb @@ -3,8 +3,7 @@ module Arel # :nodoc: all module Nodes class UpdateStatement < Arel::Nodes::Node - attr_accessor :relation, :wheres, :values, :orders, :limit - attr_accessor :key + attr_accessor :relation, :wheres, :values, :orders, :limit, :key def initialize @relation = nil diff --git a/activerecord/lib/arel/table.rb b/activerecord/lib/arel/table.rb index 686fcdf962..c40c68715a 100644 --- a/activerecord/lib/arel/table.rb +++ b/activerecord/lib/arel/table.rb @@ -104,8 +104,7 @@ module Arel # :nodoc: all !type_caster.nil? end - protected - + private attr_reader :type_caster end end diff --git a/activerecord/lib/arel/tree_manager.rb b/activerecord/lib/arel/tree_manager.rb index ed47b09a37..149c69ce7a 100644 --- a/activerecord/lib/arel/tree_manager.rb +++ b/activerecord/lib/arel/tree_manager.rb @@ -4,6 +4,35 @@ module Arel # :nodoc: all class TreeManager include Arel::FactoryMethods + module StatementMethods + def take(limit) + @ast.limit = Nodes::Limit.new(Nodes.build_quoted(limit)) if limit + self + end + + def order(*expr) + @ast.orders = expr + self + end + + def key=(key) + @ast.key = Nodes.build_quoted(key) + end + + def key + @ast.key + end + + def wheres=(exprs) + @ast.wheres = exprs + end + + def where(expr) + @ast.wheres << expr + self + end + end + attr_reader :ast def initialize diff --git a/activerecord/lib/arel/update_manager.rb b/activerecord/lib/arel/update_manager.rb index fe444343ba..a809dbb307 100644 --- a/activerecord/lib/arel/update_manager.rb +++ b/activerecord/lib/arel/update_manager.rb @@ -2,30 +2,14 @@ module Arel # :nodoc: all class UpdateManager < Arel::TreeManager + include TreeManager::StatementMethods + def initialize super @ast = Nodes::UpdateStatement.new @ctx = @ast end - def take(limit) - @ast.limit = Nodes::Limit.new(Nodes.build_quoted(limit)) if limit - self - end - - def key=(key) - @ast.key = Nodes.build_quoted(key) - end - - def key - @ast.key - end - - def order(*expr) - @ast.orders = expr - self - end - ### # UPDATE +table+ def table(table) @@ -33,15 +17,6 @@ module Arel # :nodoc: all self end - def wheres=(exprs) - @ast.wheres = exprs - end - - def where(expr) - @ast.wheres << expr - self - end - def set(values) if String === values @ast.values = [values] diff --git a/activerecord/lib/arel/visitors/depth_first.rb b/activerecord/lib/arel/visitors/depth_first.rb index 5948622aea..8f65d303ac 100644 --- a/activerecord/lib/arel/visitors/depth_first.rb +++ b/activerecord/lib/arel/visitors/depth_first.rb @@ -135,12 +135,10 @@ module Arel # :nodoc: all alias :visit_Arel_Nodes_True :terminal alias :visit_Arel_Nodes_False :terminal alias :visit_BigDecimal :terminal - alias :visit_Bignum :terminal alias :visit_Class :terminal alias :visit_Date :terminal alias :visit_DateTime :terminal alias :visit_FalseClass :terminal - alias :visit_Fixnum :terminal alias :visit_Float :terminal alias :visit_Integer :terminal alias :visit_NilClass :terminal diff --git a/activerecord/lib/arel/visitors/dot.rb b/activerecord/lib/arel/visitors/dot.rb index 76830412d4..9054f0159b 100644 --- a/activerecord/lib/arel/visitors/dot.rb +++ b/activerecord/lib/arel/visitors/dot.rb @@ -211,7 +211,6 @@ module Arel # :nodoc: all alias :visit_TrueClass :visit_String alias :visit_FalseClass :visit_String alias :visit_Integer :visit_String - alias :visit_Fixnum :visit_String alias :visit_BigDecimal :visit_String alias :visit_Float :visit_String alias :visit_Symbol :visit_String diff --git a/activerecord/lib/arel/visitors/mysql.rb b/activerecord/lib/arel/visitors/mysql.rb index ee75b6bb25..0f7d5aa803 100644 --- a/activerecord/lib/arel/visitors/mysql.rb +++ b/activerecord/lib/arel/visitors/mysql.rb @@ -65,6 +65,19 @@ module Arel # :nodoc: all collector = inject_join o.values, collector, ", " end + collect_where_for(o, collector) + end + + def visit_Arel_Nodes_Concat(o, collector) + collector << " CONCAT(" + visit o.left, collector + collector << ", " + visit o.right, collector + collector << ") " + collector + end + + def collect_where_for(o, collector) unless o.wheres.empty? collector << " WHERE " collector = inject_join o.wheres, collector, " AND " @@ -77,15 +90,6 @@ module Arel # :nodoc: all maybe_visit o.limit, collector end - - def visit_Arel_Nodes_Concat(o, collector) - collector << " CONCAT(" - visit o.left, collector - collector << ", " - visit o.right, collector - collector << ") " - collector - end end end end diff --git a/activerecord/lib/arel/visitors/to_sql.rb b/activerecord/lib/arel/visitors/to_sql.rb index 1ed41ff577..575bfd6e36 100644 --- a/activerecord/lib/arel/visitors/to_sql.rb +++ b/activerecord/lib/arel/visitors/to_sql.rb @@ -67,8 +67,8 @@ module Arel # :nodoc: all @connection = connection end - def compile(node, collector = Arel::Collectors::SQLString.new, &block) - accept(node, collector, &block).value + def compile(node, collector = Arel::Collectors::SQLString.new) + accept(node, collector).value end private @@ -76,12 +76,8 @@ module Arel # :nodoc: all def visit_Arel_Nodes_DeleteStatement(o, collector) collector << "DELETE FROM " collector = visit o.relation, collector - if o.wheres.any? - collector << WHERE - collector = inject_join o.wheres, collector, AND - end - maybe_visit o.limit, collector + collect_where_for(o, collector) end # FIXME: we should probably have a 2-pass visitor for this @@ -97,12 +93,6 @@ module Arel # :nodoc: all end def visit_Arel_Nodes_UpdateStatement(o, collector) - if o.orders.empty? && o.limit.nil? - wheres = o.wheres - else - wheres = [Nodes::In.new(o.key, [build_subselect(o.key, o)])] - end - collector << "UPDATE " collector = visit o.relation, collector unless o.values.empty? @@ -110,12 +100,7 @@ module Arel # :nodoc: all collector = inject_join o.values, collector, ", " end - unless wheres.empty? - collector << " WHERE " - collector = inject_join wheres, collector, " AND " - end - - collector + collect_where_for(o, collector) end def visit_Arel_Nodes_InsertStatement(o, collector) @@ -814,6 +799,21 @@ module Arel # :nodoc: all } end + def collect_where_for(o, collector) + if o.orders.empty? && o.limit.nil? + wheres = o.wheres + else + wheres = [Nodes::In.new(o.key, [build_subselect(o.key, o)])] + end + + unless wheres.empty? + collector << " WHERE " + collector = inject_join wheres, collector, " AND " + end + + collector + end + def infix_value(o, collector, value) collector = visit o.left, collector collector << value |