aboutsummaryrefslogtreecommitdiffstats
path: root/lib/active_relation/relations/base.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/active_relation/relations/base.rb')
-rw-r--r--lib/active_relation/relations/base.rb111
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