aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel/primitives
diff options
context:
space:
mode:
Diffstat (limited to 'lib/arel/primitives')
-rw-r--r--lib/arel/primitives/attribute.rb141
-rw-r--r--lib/arel/primitives/expression.rb44
-rw-r--r--lib/arel/primitives/value.rb27
3 files changed, 212 insertions, 0 deletions
diff --git a/lib/arel/primitives/attribute.rb b/lib/arel/primitives/attribute.rb
new file mode 100644
index 0000000000..280fc9f439
--- /dev/null
+++ b/lib/arel/primitives/attribute.rb
@@ -0,0 +1,141 @@
+module Arel
+ class Attribute
+ attr_reader :relation, :name, :alias, :ancestor
+ delegate :engine, :to => :relation
+
+ def initialize(relation, name, options = {})
+ @relation, @name, @alias, @ancestor = relation, name, options[:alias], options[:ancestor]
+ end
+
+ def alias_or_name
+ @alias || name
+ end
+
+ def aggregation?
+ false
+ end
+
+ module Transformations
+ def as(aliaz = nil)
+ Attribute.new(relation, name, :alias => aliaz, :ancestor => self)
+ end
+
+ def bind(new_relation)
+ relation == new_relation ? self : Attribute.new(new_relation, name, :alias => @alias, :ancestor => self)
+ end
+
+ def to_attribute
+ self
+ end
+ end
+ include Transformations
+
+ def qualified_name
+ "#{prefix}.#{name}"
+ end
+
+ def column
+ relation.column_for(self)
+ end
+
+ def ==(other)
+ self.class == other.class and
+ relation == other.relation and
+ name == other.name and
+ @alias == other.alias and
+ ancestor == other.ancestor
+ end
+
+ module Congruence
+ def self.included(klass)
+ klass.hash_on :name
+ end
+
+ def history
+ [self] + (ancestor ? [ancestor, ancestor.history].flatten : [])
+ end
+
+ def =~(other)
+ !(history & other.history).empty?
+ end
+
+ def %(other)
+ if other then (history - other.history) + (other.history - history)
+ else history
+ end
+ end
+ end
+ include Congruence
+
+ module Predications
+ def eq(other)
+ Equality.new(self, other)
+ end
+
+ def lt(other)
+ LessThan.new(self, other)
+ end
+
+ def lteq(other)
+ LessThanOrEqualTo.new(self, other)
+ end
+
+ def gt(other)
+ GreaterThan.new(self, other)
+ end
+
+ def gteq(other)
+ GreaterThanOrEqualTo.new(self, other)
+ end
+
+ def matches(regexp)
+ Match.new(self, regexp)
+ end
+
+ def in(array)
+ In.new(self, array)
+ end
+ end
+ include Predications
+
+ module Expressions
+ def count
+ Expression.new(self, "COUNT")
+ end
+
+ def sum
+ Expression.new(self, "SUM")
+ end
+
+ def maximum
+ Expression.new(self, "MAX")
+ end
+
+ def minimum
+ Expression.new(self, "MIN")
+ end
+
+ def average
+ Expression.new(self, "AVG")
+ end
+ end
+ include Expressions
+
+ def to_sql(formatter = Sql::WhereCondition.new(engine))
+ formatter.attribute prefix, name, self.alias
+ end
+
+ def format(object)
+ object.to_sql(formatter)
+ end
+
+ private
+ def formatter
+ Sql::Attribute.new(self)
+ end
+
+ def prefix
+ relation.prefix_for(self)
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/arel/primitives/expression.rb b/lib/arel/primitives/expression.rb
new file mode 100644
index 0000000000..bf674cc9e1
--- /dev/null
+++ b/lib/arel/primitives/expression.rb
@@ -0,0 +1,44 @@
+module Arel
+ class Expression < Attribute
+ include Sql::Quoting
+
+ attr_reader :attribute, :function_sql
+ delegate :relation, :to => :attribute
+ alias_method :name, :alias
+
+ def initialize(attribute, function_sql, aliaz = nil, ancestor = nil)
+ @attribute, @function_sql, @alias, @ancestor = attribute, function_sql, aliaz, ancestor
+ end
+
+ module Transformations
+ def as(aliaz)
+ Expression.new(attribute, function_sql, aliaz, self)
+ end
+
+ def bind(new_relation)
+ new_relation == relation ? self : Expression.new(attribute.bind(new_relation), function_sql, @alias, self)
+ end
+
+ def to_attribute
+ Attribute.new(relation, @alias, :ancestor => self)
+ end
+ end
+ include Transformations
+
+ def to_sql(formatter = nil)
+ "#{function_sql}(#{attribute.to_sql})" + (@alias ? " AS #{quote_column_name(@alias)}" : '')
+ end
+
+ def aggregation?
+ true
+ end
+
+ def ==(other)
+ self.class == other.class and
+ attribute == other.attribute and
+ function_sql == other.function_sql and
+ ancestor == other.ancestor and
+ @alias == other.alias
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/arel/primitives/value.rb b/lib/arel/primitives/value.rb
new file mode 100644
index 0000000000..650557559a
--- /dev/null
+++ b/lib/arel/primitives/value.rb
@@ -0,0 +1,27 @@
+module Arel
+ class Value
+ attr_reader :value, :relation
+
+ delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value
+
+ def initialize(value, relation)
+ @value, @relation = value, relation
+ end
+
+ def to_sql(formatter = Sql::WhereCondition.new(relation.engine))
+ formatter.value value
+ end
+
+ def format(object)
+ object.to_sql(Sql::Value.new(relation.engine))
+ end
+
+ def ==(other)
+ value == other.value
+ end
+
+ def bind(relation)
+ Value.new(value, relation)
+ end
+ end
+end \ No newline at end of file