diff options
Diffstat (limited to 'lib/active_relation/relations/base.rb')
-rw-r--r-- | lib/active_relation/relations/base.rb | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/active_relation/relations/base.rb b/lib/active_relation/relations/base.rb new file mode 100644 index 0000000000..c4a887eecd --- /dev/null +++ b/lib/active_relation/relations/base.rb @@ -0,0 +1,111 @@ +module ActiveRelation + module Relations + class Base + include SqlBuilder + + module Iteration + include Enumerable + + def each(&block) + connection.select_all(to_s).each(&block) + end + + def first + connection.select_one(to_s) + end + end + include Iteration + + module Operations + def <=>(other) + JoinOperation.new("INNER JOIN", self, other) + end + + def <<(other) + JoinOperation.new("LEFT OUTER JOIN", self, other) + end + + def [](index) + case index + when Symbol + attribute(index) + when ::Range + Range.new(self, index) + end + end + + def include?(attribute) + Predicates::RelationInclusion.new(attribute, self) + end + + def select(*s) + Selection.new(self, *s) + end + + def project(*attributes) + Projection.new(self, *attributes) + end + + def order(*attributes) + Order.new(self, *attributes) + end + + def rename(attribute, aliaz) + Rename.new(self, attribute => aliaz) + end + + def insert(record) + Insertion.new(self, record) + end + + def delete + Deletion.new(self) + end + + class JoinOperation + attr_reader :join_sql, :relation1, :relation2 + + def initialize(join_sql, relation1, relation2) + @join_sql, @relation1, @relation2 = join_sql, relation1, relation2 + end + + def on(*predicates) + Join.new(join_sql, relation1, relation2, *predicates) + end + + def ==(other) + (relation1 == other.relation1 and relation2 == other.relation2) or + (relation1 == other.relation2 and relation2 == other.relation1) + end + end + end + include Operations + + def connection + ActiveRecord::Base.connection + end + + def to_sql(options = {}) + [ + "SELECT #{attributes.collect{ |a| a.to_sql(:use_alias => true) }.join(', ')}", + "FROM #{quote_table_name(table)}", + (joins.to_sql(:quote => false) unless joins.blank?), + ("WHERE #{selects.collect{|s| s.to_sql(:quote => false)}.join("\n\tAND ")}" unless selects.blank?), + ("ORDER BY #{orders.collect(&:to_sql)}" unless orders.blank?), + ("LIMIT #{limit.to_sql}" unless limit.blank?), + ("OFFSET #{offset.to_sql}" unless offset.blank?) + ].compact.join("\n") + end + alias_method :to_s, :to_sql + + protected + def attributes; [] end + def selects; [] end + def orders; [] end + def inserts; [] end + def joins; nil end + def limit; nil end + def offset; nil end + end + end +end
\ No newline at end of file |