Skip to content

Commit

Permalink
PERF: removing more method missing
Browse files Browse the repository at this point in the history
  • Loading branch information
tenderlove committed Jul 27, 2010
1 parent 1f25ba3 commit e2578f1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 33 deletions.
4 changes: 2 additions & 2 deletions lib/arel/engines/sql/compilers/postgresql_compiler.rb
Expand Up @@ -3,7 +3,7 @@ module SqlCompiler
class PostgreSQLCompiler < GenericCompiler class PostgreSQLCompiler < GenericCompiler


def select_sql def select_sql
if !orders.blank? && using_distinct_on? if !relation.orders.blank? && using_distinct_on?
subquery = build_query \ subquery = build_query \
"SELECT #{select_clauses.kind_of?(::Array) ? select_clauses.join("") : select_clauses.to_s}", "SELECT #{select_clauses.kind_of?(::Array) ? select_clauses.join("") : select_clauses.to_s}",
"FROM #{from_clauses}", "FROM #{from_clauses}",
Expand All @@ -24,7 +24,7 @@ def select_sql
end end


def using_distinct_on? def using_distinct_on?
select_clauses.any? { |x| x =~ /DISTINCT ON/ } relation.select_clauses.any? { |x| x =~ /DISTINCT ON/ }
end end


def aliased_orders(orders) def aliased_orders(orders)
Expand Down
64 changes: 33 additions & 31 deletions lib/arel/engines/sql/relations/compiler.rb
@@ -1,17 +1,21 @@
module Arel module Arel
module SqlCompiler module SqlCompiler
class GenericCompiler class GenericCompiler
attr_reader :relation attr_reader :relation, :engine


def initialize(relation) def initialize(relation)
@relation = relation @relation = relation
@engine = relation.engine @engine = relation.engine
end end


def christener
relation.christener
end

def select_sql def select_sql
if relation.projections.first.is_a?(Count) && relation.projections.size == 1 && if relation.projections.first.is_a?(Count) && relation.projections.size == 1 &&
(taken.present? || wheres.present?) && joins(self).blank? (relation.taken.present? || relation.wheres.present?) && relation.joins(self).blank?
subquery = build_query("SELECT 1 FROM #{from_clauses}", build_clauses) subquery = build_query("SELECT 1 FROM #{relation.from_clauses}", build_clauses)
query = "SELECT COUNT(*) AS count_id FROM (#{subquery}) AS subquery" query = "SELECT COUNT(*) AS count_id FROM (#{subquery}) AS subquery"
else else
query = [ query = [
Expand All @@ -24,7 +28,7 @@ def select_sql
end end


def build_clauses def build_clauses
joins = joins(self) joins = relation.joins(self)
wheres = relation.where_clauses wheres = relation.where_clauses
groups = relation.group_clauses groups = relation.group_clauses
havings = relation.having_clauses havings = relation.having_clauses
Expand All @@ -50,39 +54,39 @@ def build_clauses
def delete_sql def delete_sql
build_query \ build_query \
"DELETE", "DELETE",
"FROM #{table_sql}", "FROM #{relation.table_sql}",
("WHERE #{wheres.collect(&:to_sql).join(' AND ')}" unless wheres.blank? ), ("WHERE #{relation.wheres.collect { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank? ),
(add_limit_on_delete(taken) unless taken.blank? ) (add_limit_on_delete(relation.taken) unless relation.taken.blank? )
end end


def add_limit_on_delete(taken) def add_limit_on_delete(taken)
"LIMIT #{taken}" "LIMIT #{taken}"
end end


def insert_sql(include_returning = true) def insert_sql(include_returning = true)
insertion_attributes_values_sql = if record.is_a?(Value) insertion_attributes_values_sql = if relation.record.is_a?(Value)
record.value relation.record.value
else else
attributes = record.keys.sort_by do |attribute| attributes = relation.record.keys.sort_by do |attribute|
attribute.name.to_s attribute.name.to_s
end end


first = attributes.collect do |key| first = attributes.collect do |key|
engine.connection.quote_column_name(key.name) @engine.connection.quote_column_name(key.name)
end.join(', ') end.join(', ')


second = attributes.collect do |key| second = attributes.collect do |key|
key.format(record[key]) key.format(relation.record[key])
end.join(', ') end.join(', ')


build_query "(#{first})", "VALUES (#{second})" build_query "(#{first})", "VALUES (#{second})"
end end


build_query \ build_query \
"INSERT", "INSERT",
"INTO #{table_sql}", "INTO #{relation.table_sql}",
insertion_attributes_values_sql, insertion_attributes_values_sql,
("RETURNING #{engine.connection.quote_column_name(primary_key)}" if include_returning && compiler.supports_insert_with_returning?) ("RETURNING #{engine.connection.quote_column_name(primary_key)}" if include_returning && relation.compiler.supports_insert_with_returning?)
end end


def supports_insert_with_returning? def supports_insert_with_returning?
Expand All @@ -91,44 +95,42 @@ def supports_insert_with_returning?


def update_sql def update_sql
build_query \ build_query \
"UPDATE #{table_sql} SET", "UPDATE #{relation.table_sql} SET",
assignment_sql, assignment_sql,
build_update_conditions_sql build_update_conditions_sql
end end


protected protected
def method_missing(method, *args)
if block_given? def locked
relation.send(method, *args) { |*block_args| yield(*block_args) } relation.locked
else
relation.send(method, *args)
end
end end


def build_query(*parts) def build_query(*parts)
parts.compact.join(" ") parts.compact.join(" ")
end end


def assignment_sql def assignment_sql
if assignments.respond_to?(:collect) if relation.assignments.respond_to?(:collect)
attributes = assignments.keys.sort_by do |attribute| attributes = relation.assignments.keys.sort_by do |attribute|
attribute.name.to_s attribute.name.to_s
end end


attributes.map do |attribute| attributes.map do |attribute|
value = assignments[attribute] value = relation.assignments[attribute]
"#{engine.connection.quote_column_name(attribute.name)} = #{attribute.format(value)}" "#{@engine.connection.quote_column_name(attribute.name)} = #{attribute.format(value)}"
end.join(", ") end.join(", ")
else else
assignments.value relation.assignments.value
end end
end end


def build_update_conditions_sql def build_update_conditions_sql
conditions = "" conditions = ""
conditions << " WHERE #{wheres.collect(&:to_sql).join(' AND ')}" unless wheres.blank? conditions << " WHERE #{relation.wheres.map { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank?
conditions << " ORDER BY #{order_clauses.join(', ')}" unless orders.blank? conditions << " ORDER BY #{relation.order_clauses.join(', ')}" unless relation.orders.blank?


taken = relation.taken
unless taken.blank? unless taken.blank?
conditions = limited_update_conditions(conditions, taken) conditions = limited_update_conditions(conditions, taken)
end end
Expand All @@ -138,8 +140,8 @@ def build_update_conditions_sql


def limited_update_conditions(conditions, taken) def limited_update_conditions(conditions, taken)
conditions << " LIMIT #{taken}" conditions << " LIMIT #{taken}"
quoted_primary_key = engine.connection.quote_column_name(primary_key) quoted_primary_key = @engine.connection.quote_column_name(relation.primary_key)
"WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{engine.connection.quote_table_name table.name} #{conditions})" "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{@engine.connection.quote_table_name relation.table.name} #{conditions})"
end end


end end
Expand Down

0 comments on commit e2578f1

Please sign in to comment.