diff options
Diffstat (limited to 'lib/arel')
-rw-r--r-- | lib/arel/primitives/expression.rb | 6 | ||||
-rw-r--r-- | lib/arel/relations/join.rb | 11 | ||||
-rw-r--r-- | lib/arel/relations/relation.rb | 2 | ||||
-rw-r--r-- | lib/arel/sql/christener.rb | 14 | ||||
-rw-r--r-- | lib/arel/sql/formatters.rb | 102 |
5 files changed, 120 insertions, 15 deletions
diff --git a/lib/arel/primitives/expression.rb b/lib/arel/primitives/expression.rb index bf674cc9e1..75bf1f2ef0 100644 --- a/lib/arel/primitives/expression.rb +++ b/lib/arel/primitives/expression.rb @@ -1,7 +1,5 @@ module Arel class Expression < Attribute - include Sql::Quoting - attr_reader :attribute, :function_sql delegate :relation, :to => :attribute alias_method :name, :alias @@ -25,8 +23,8 @@ module Arel end include Transformations - def to_sql(formatter = nil) - "#{function_sql}(#{attribute.to_sql})" + (@alias ? " AS #{quote_column_name(@alias)}" : '') + def to_sql(formatter = Sql::SelectClause.new(relation)) + formatter.expression self end def aggregation? diff --git a/lib/arel/relations/join.rb b/lib/arel/relations/join.rb index 0dec80af79..a30c179e4e 100644 --- a/lib/arel/relations/join.rb +++ b/lib/arel/relations/join.rb @@ -30,7 +30,7 @@ module Arel relation2.table.table_sql(formatter) end, ("ON" unless predicates.blank?), - predicates.collect { |p| p.bind(formatter.christener).to_sql }.join(' AND ') + predicates.collect { |p| p.bind(formatter.environment).to_sql }.join(' AND ') ].compact.join(" ") [relation1.joins(formatter), this_join, relation2.joins(formatter)].compact.join(" ") end @@ -39,15 +39,6 @@ module Arel (externalize(relation1).selects + externalize(relation2).selects).collect { |s| s.bind(self) } end - def name_for(relation) - @used_names ||= Hash.new(0) - @relation_names ||= Hash.new do |h, k| - @used_names[k.name] += 1 - h[k] = k.name + (@used_names[k.name] > 1 ? "_#{@used_names[k.name]}" : '') - end - @relation_names[relation] - end - def table relation1.aggregation?? relation1 : relation1.table end diff --git a/lib/arel/relations/relation.rb b/lib/arel/relations/relation.rb index 336960f424..0b20985914 100644 --- a/lib/arel/relations/relation.rb +++ b/lib/arel/relations/relation.rb @@ -159,7 +159,7 @@ module Arel end def christener - self + @christener ||= Sql::Christener.new end def attributes; [] end diff --git a/lib/arel/sql/christener.rb b/lib/arel/sql/christener.rb new file mode 100644 index 0000000000..894f030342 --- /dev/null +++ b/lib/arel/sql/christener.rb @@ -0,0 +1,14 @@ +module Arel + module Sql + class Christener + def name_for(relation) + @used_names ||= Hash.new(0) + @relation_names ||= Hash.new do |h, k| + @used_names[k.name] += 1 + h[k] = k.name + (@used_names[k.name] > 1 ? "_#{@used_names[k.name]}" : '') + end + @relation_names[relation] + end + end + end +end
\ No newline at end of file diff --git a/lib/arel/sql/formatters.rb b/lib/arel/sql/formatters.rb new file mode 100644 index 0000000000..96bab2495c --- /dev/null +++ b/lib/arel/sql/formatters.rb @@ -0,0 +1,102 @@ +module Arel + module Sql + class Formatter + attr_reader :environment + delegate :christener, :engine, :to => :environment + delegate :name_for, :to => :christener + delegate :quote_table_name, :quote_column_name, :quote, :to => :engine + + def initialize(environment) + @environment = environment + end + end + + class SelectClause < Formatter + def attribute(attribute) + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") + end + + def expression(expression) + "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '') + end + + def select(select_sql, name) + "(#{select_sql}) AS #{quote_table_name(name.to_s)}" + end + + def value(value) + value + end + end + + class PassThrough < Formatter + def value(value) + value + end + end + + class WhereClause < PassThrough + end + + class OrderClause < PassThrough + def attribute(attribute) + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + end + end + + class WhereCondition < Formatter + def attribute(attribute) + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + end + + def expression(expression) + "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + end + + def value(value) + value.to_sql(self) + end + + def scalar(value, column = nil) + quote(value, column) + end + + def select(select_sql, name) + "(#{select_sql})" + end + end + + class SelectStatement < Formatter + def select(select_sql, name) + select_sql + end + end + + class TableReference < Formatter + def select(select_sql, name) + "(#{select_sql}) AS #{quote_table_name(name)}" + end + + def table(table) + quote_table_name(table.name) + (table.name != name_for(table) ? " AS " + engine.quote_table_name(name_for(table)) : '') + end + end + + class Attribute < WhereCondition + def scalar(scalar) + quote(scalar, environment.column) + end + + def array(array) + "(" + array.collect { |e| e.to_sql(self) }.join(', ') + ")" + end + + def range(left, right) + "#{left} AND #{right}" + end + end + + class Value < WhereCondition + end + end +end
\ No newline at end of file |