aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBryan Helmkamp <bryan@brynary.com>2008-01-14 10:50:46 -0500
committerBryan Helmkamp <bryan@brynary.com>2008-01-14 10:50:46 -0500
commit553eb0ad490abc7f85d9836c3ba959ab771d3cf4 (patch)
treebaa9714465488d77980e8d252a82849b32844d3b /lib
parent17a5fd13bc4ba8405d95e90d12b87dcd7e5bea5b (diff)
downloadrails-553eb0ad490abc7f85d9836c3ba959ab771d3cf4.tar.gz
rails-553eb0ad490abc7f85d9836c3ba959ab771d3cf4.tar.bz2
rails-553eb0ad490abc7f85d9836c3ba959ab771d3cf4.zip
Remove ActiveRelation sub-modules and refactor specs
Diffstat (limited to 'lib')
-rw-r--r--lib/active_relation/extensions/base.rb2
-rw-r--r--lib/active_relation/predicates.rb136
-rw-r--r--lib/active_relation/primitives/aggregation.rb28
-rw-r--r--lib/active_relation/primitives/attribute.rb134
-rw-r--r--lib/active_relation/relations.rb2
-rw-r--r--lib/active_relation/relations/alias.rb56
-rw-r--r--lib/active_relation/relations/base.rb105
-rw-r--r--lib/active_relation/relations/compound.rb10
-rw-r--r--lib/active_relation/relations/deletion.rb24
-rw-r--r--lib/active_relation/relations/insertion.rb36
-rw-r--r--lib/active_relation/relations/join.rb80
-rw-r--r--lib/active_relation/relations/order.rb28
-rw-r--r--lib/active_relation/relations/projection.rb28
-rw-r--r--lib/active_relation/relations/range.rb36
-rw-r--r--lib/active_relation/relations/relation.rb103
-rw-r--r--lib/active_relation/relations/rename.rb64
-rw-r--r--lib/active_relation/relations/selection.rb40
-rw-r--r--lib/active_relation/relations/table.rb62
18 files changed, 471 insertions, 503 deletions
diff --git a/lib/active_relation/extensions/base.rb b/lib/active_relation/extensions/base.rb
index 0115586b00..c1b823f9a7 100644
--- a/lib/active_relation/extensions/base.rb
+++ b/lib/active_relation/extensions/base.rb
@@ -5,7 +5,7 @@ class ActiveRecord::Base
end
def relation
- @relation ||= ActiveRelation::Relations::Table.new(table_name)
+ @relation ||= ActiveRelation::Table.new(table_name)
end
end
diff --git a/lib/active_relation/predicates.rb b/lib/active_relation/predicates.rb
index 84db60e3b9..55a6c852e2 100644
--- a/lib/active_relation/predicates.rb
+++ b/lib/active_relation/predicates.rb
@@ -1,87 +1,85 @@
module ActiveRelation
- module Predicates
- class Base
- def ==(other)
- self.class == other.class
- end
+ class Predicate
+ def ==(other)
+ self.class == other.class
end
-
- class Binary < Base
- attr_reader :attribute, :operand
+ end
+
+ class Binary < Predicate
+ attr_reader :attribute, :operand
- def initialize(attribute, operand)
- @attribute, @operand = attribute, operand
- end
+ def initialize(attribute, operand)
+ @attribute, @operand = attribute, operand
+ end
+
+ def ==(other)
+ super and @attribute == other.attribute and @operand == other.operand
+ end
- def ==(other)
- super and @attribute == other.attribute and @operand == other.operand
- end
+ def qualify
+ self.class.new(attribute.qualify, operand.qualify)
+ end
- def qualify
- self.class.new(attribute.qualify, operand.qualify)
- end
+ def to_sql(strategy = Sql::Predicate.new)
+ "#{attribute.to_sql(strategy)} #{predicate_sql} #{operand.to_sql(strategy)}"
+ end
+ end
- def to_sql(strategy = Sql::Predicate.new)
- "#{attribute.to_sql(strategy)} #{predicate_sql} #{operand.to_sql(strategy)}"
- end
+ class Equality < Binary
+ def ==(other)
+ self.class == other.class and
+ ((attribute == other.attribute and operand == other.operand) or
+ (attribute == other.operand and operand == other.attribute))
end
-
- class Equality < Binary
- def ==(other)
- self.class == other.class and
- ((attribute == other.attribute and operand == other.operand) or
- (attribute == other.operand and operand == other.attribute))
- end
- protected
- def predicate_sql
- '='
- end
+ protected
+ def predicate_sql
+ '='
end
-
- class GreaterThanOrEqualTo < Binary
- protected
- def predicate_sql
- '>='
- end
+ end
+
+ class GreaterThanOrEqualTo < Binary
+ protected
+ def predicate_sql
+ '>='
end
-
- class GreaterThan < Binary
- protected
- def predicate_sql
- '>'
- end
+ end
+
+ class GreaterThan < Binary
+ protected
+ def predicate_sql
+ '>'
end
-
- class LessThanOrEqualTo < Binary
- protected
- def predicate_sql
- '<='
- end
+ end
+
+ class LessThanOrEqualTo < Binary
+ protected
+ def predicate_sql
+ '<='
end
-
- class LessThan < Binary
- protected
- def predicate_sql
- '<'
- end
+ end
+
+ class LessThan < Binary
+ protected
+ def predicate_sql
+ '<'
end
-
- class Match < Binary
- alias_method :regexp, :operand
+ end
+
+ class Match < Binary
+ alias_method :regexp, :operand
- def initialize(attribute, regexp)
- @attribute, @regexp = attribute, regexp
- end
+ def initialize(attribute, regexp)
+ @attribute, @regexp = attribute, regexp
end
-
- class RelationInclusion < Binary
- alias_method :relation, :operand
-
- protected
- def predicate_sql
- 'IN'
- end
+ end
+
+ class RelationInclusion < Binary
+ alias_method :relation, :operand
+
+ protected
+ def predicate_sql
+ 'IN'
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/primitives/aggregation.rb b/lib/active_relation/primitives/aggregation.rb
index 189eb33ac9..48f8946835 100644
--- a/lib/active_relation/primitives/aggregation.rb
+++ b/lib/active_relation/primitives/aggregation.rb
@@ -1,19 +1,17 @@
module ActiveRelation
- module Primitives
- class Aggregation
- attr_reader :attribute, :function_sql
-
- def initialize(attribute, function_sql)
- @attribute, @function_sql = attribute, function_sql
- end
-
- def to_sql(strategy = nil)
- "#{function_sql}(#{attribute.to_sql})"
- end
-
- def ==(other)
- self.class == other.class and attribute == other.attribute and function_sql == other.function_sql
- end
+ class Aggregation
+ attr_reader :attribute, :function_sql
+
+ def initialize(attribute, function_sql)
+ @attribute, @function_sql = attribute, function_sql
+ end
+
+ def to_sql(strategy = nil)
+ "#{function_sql}(#{attribute.to_sql})"
+ end
+
+ def ==(other)
+ self.class == other.class and attribute == other.attribute and function_sql == other.function_sql
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb
index 6ebaf1b292..90bbe8012b 100644
--- a/lib/active_relation/primitives/attribute.rb
+++ b/lib/active_relation/primitives/attribute.rb
@@ -1,83 +1,79 @@
module ActiveRelation
- module Primitives
- class Attribute
- attr_reader :relation, :name, :alias
-
- def initialize(relation, name, aliaz = nil)
- @relation, @name, @alias = relation, name, aliaz
+ class Attribute
+ attr_reader :relation, :name, :alias
+
+ def initialize(relation, name, aliaz = nil)
+ @relation, @name, @alias = relation, name, aliaz
+ end
+
+ def as(aliaz = nil)
+ Attribute.new(relation, name, aliaz)
+ end
+
+ def qualified_name
+ "#{relation.name}.#{name}"
+ end
+
+ def qualify
+ self.as(qualified_name)
+ end
+
+ def ==(other)
+ relation == other.relation and name == other.name and @alias == other.alias
+ end
+
+ module Predications
+ def equals(other)
+ Equality.new(self, other)
end
-
- def as(aliaz = nil)
- Attribute.new(relation, name, aliaz)
+
+ def less_than(other)
+ LessThan.new(self, other)
end
-
- def qualified_name
- "#{relation.name}.#{name}"
+
+ def less_than_or_equal_to(other)
+ LessThanOrEqualTo.new(self, other)
end
-
- def qualify
- self.as(qualified_name)
+
+ def greater_than(other)
+ GreaterThan.new(self, other)
end
-
- def ==(other)
- relation == other.relation and name == other.name and @alias == other.alias
+
+ def greater_than_or_equal_to(other)
+ GreaterThanOrEqualTo.new(self, other)
end
- module Predications
- include Predicates
-
- def equals(other)
- Equality.new(self, other)
- end
-
- def less_than(other)
- LessThan.new(self, other)
- end
-
- def less_than_or_equal_to(other)
- LessThanOrEqualTo.new(self, other)
- end
-
- def greater_than(other)
- GreaterThan.new(self, other)
- end
-
- def greater_than_or_equal_to(other)
- GreaterThanOrEqualTo.new(self, other)
- end
-
- def matches(regexp)
- Match.new(self, regexp)
- end
+ def matches(regexp)
+ Match.new(self, regexp)
+ end
+ end
+ include Predications
+
+ module Aggregations
+ def count
+ Aggregation.new(self, "COUNT")
+ end
+
+ def sum
+ Aggregation.new(self, "SUM")
+ end
+
+ def maximum
+ Aggregation.new(self, "MAX")
end
- include Predications
- module Aggregations
- def count
- Aggregation.new(self, "COUNT")
- end
-
- def sum
- Aggregation.new(self, "SUM")
- end
-
- def maximum
- Aggregation.new(self, "MAX")
- end
-
- def minimum
- Aggregation.new(self, "MIN")
- end
-
- def average
- Aggregation.new(self, "AVG")
- end
+ def minimum
+ Aggregation.new(self, "MIN")
end
- include Aggregations
-
- def to_sql(strategy = Sql::Predicate.new)
- strategy.attribute relation.name, name, self.alias
+
+ def average
+ Aggregation.new(self, "AVG")
end
end
+ include Aggregations
+
+ def to_sql(strategy = Sql::Predicate.new)
+ strategy.attribute relation.name, name, self.alias
+ end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations.rb b/lib/active_relation/relations.rb
index 1eb58d3b42..9ae8f16524 100644
--- a/lib/active_relation/relations.rb
+++ b/lib/active_relation/relations.rb
@@ -1,4 +1,4 @@
-require 'active_relation/relations/base'
+require 'active_relation/relations/relation'
require 'active_relation/relations/compound'
require 'active_relation/relations/table'
require 'active_relation/relations/join'
diff --git a/lib/active_relation/relations/alias.rb b/lib/active_relation/relations/alias.rb
index 2d1b9c1476..63a92ccba1 100644
--- a/lib/active_relation/relations/alias.rb
+++ b/lib/active_relation/relations/alias.rb
@@ -1,36 +1,34 @@
module ActiveRelation
- module Relations
- class Alias < Compound
- attr_reader :alias
- alias_method :name, :alias
-
- def initialize(relation, aliaz)
- @relation, @alias = relation, aliaz
- end
-
- def attributes
- relation.attributes.collect(&method(:substitute))
- end
+ class Alias < Compound
+ attr_reader :alias
+ alias_method :name, :alias
- def ==(other)
- relation == other.relation and self.alias == other.alias
- end
-
- protected
- def table_sql
- "#{quote_table_name(relation.name)} AS #{quote_table_name(@alias)}"
- end
-
- def attribute(name)
- if unaliased_attribute = relation[name]
- substitute(unaliased_attribute)
- end
- end
+ def initialize(relation, aliaz)
+ @relation, @alias = relation, aliaz
+ end
- private
- def substitute(attribute)
- Primitives::Attribute.new(self, attribute.name, attribute.alias)
+ def attributes
+ relation.attributes.collect(&method(:substitute))
+ end
+
+ def ==(other)
+ relation == other.relation and self.alias == other.alias
+ end
+
+ protected
+ def table_sql
+ "#{quote_table_name(relation.name)} AS #{quote_table_name(@alias)}"
+ end
+
+ def attribute(name)
+ if unaliased_attribute = relation[name]
+ substitute(unaliased_attribute)
end
end
+
+ private
+ def substitute(attribute)
+ Attribute.new(self, attribute.name, attribute.alias)
+ end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/base.rb b/lib/active_relation/relations/base.rb
deleted file mode 100644
index d90d8ae3e6..0000000000
--- a/lib/active_relation/relations/base.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-module ActiveRelation
- module Relations
- class Base
- include Sql::Quoting
-
- 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 join(other)
- JoinOperation.new("INNER JOIN", self, other)
- end
-
- def outer_join(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(*predicates)
- Selection.new(self, *predicates)
- end
-
- def project(*attributes)
- Projection.new(self, *attributes)
- end
-
- def as(aliaz)
- Alias.new(self, aliaz)
- 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
-
- JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
- def on(*predicates)
- Join.new(join_sql, relation1, relation2, *predicates)
- end
- end
- end
- include Operations
-
- def to_sql(strategy = Sql::Select.new)
- strategy.select [
- "SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new) }.join(', ')}",
- "FROM #{table_sql}",
- (joins unless joins.blank?),
- ("WHERE #{selects.collect{|s| s.to_sql(Sql::Predicate.new)}.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 connection
- ActiveRecord::Base.connection
- end
-
- def attributes; [] end
- def selects; [] end
- def orders; [] end
- def inserts; [] end
- def joins; nil end
- def limit; nil end
- def offset; nil end
- def alias; nil end
- end
- end
-end \ No newline at end of file
diff --git a/lib/active_relation/relations/compound.rb b/lib/active_relation/relations/compound.rb
index 46454eb628..d6da8eb8fa 100644
--- a/lib/active_relation/relations/compound.rb
+++ b/lib/active_relation/relations/compound.rb
@@ -1,9 +1,7 @@
module ActiveRelation
- module Relations
- class Compound < Base
- attr_reader :relation
-
- delegate :attributes, :attribute, :joins, :selects, :orders, :table_sql, :inserts, :limit, :offset, :to => :relation
- end
+ class Compound < Relation
+ attr_reader :relation
+
+ delegate :attributes, :attribute, :joins, :selects, :orders, :table_sql, :inserts, :limit, :offset, :to => :relation
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/deletion.rb b/lib/active_relation/relations/deletion.rb
index add6440c2a..4ac40a146b 100644
--- a/lib/active_relation/relations/deletion.rb
+++ b/lib/active_relation/relations/deletion.rb
@@ -1,17 +1,15 @@
module ActiveRelation
- module Relations
- class Deletion < Compound
- def initialize(relation)
- @relation = relation
- end
-
- def to_sql(strategy = nil)
- [
- "DELETE",
- "FROM #{table_sql}",
- ("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?)
- ].compact.join("\n")
- end
+ class Deletion < Compound
+ def initialize(relation)
+ @relation = relation
end
+
+ def to_sql(strategy = nil)
+ [
+ "DELETE",
+ "FROM #{table_sql}",
+ ("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?)
+ ].compact.join("\n")
+ end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/insertion.rb b/lib/active_relation/relations/insertion.rb
index c82513ce0f..31e4339ee0 100644
--- a/lib/active_relation/relations/insertion.rb
+++ b/lib/active_relation/relations/insertion.rb
@@ -1,25 +1,23 @@
module ActiveRelation
- module Relations
- class Insertion < Compound
- attr_reader :record
-
- def initialize(relation, record)
- @relation, @record = relation, record
- end
+ class Insertion < Compound
+ attr_reader :record
- def to_sql(strategy = nil)
- [
- "INSERT",
- "INTO #{table_sql}",
- "(#{record.keys.collect(&:to_sql).join(', ')})",
- "VALUES #{inserts.collect(&:to_sql).join(', ')}"
- ].join("\n")
- end
+ def initialize(relation, record)
+ @relation, @record = relation, record
+ end
+
+ def to_sql(strategy = nil)
+ [
+ "INSERT",
+ "INTO #{table_sql}",
+ "(#{record.keys.collect(&:to_sql).join(', ')})",
+ "VALUES #{inserts.collect(&:to_sql).join(', ')}"
+ ].join("\n")
+ end
- protected
- def inserts
- relation.inserts + [record]
- end
+ protected
+ def inserts
+ relation.inserts + [record]
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/join.rb b/lib/active_relation/relations/join.rb
index 4e6c85979e..8ccd1e9c6c 100644
--- a/lib/active_relation/relations/join.rb
+++ b/lib/active_relation/relations/join.rb
@@ -1,45 +1,43 @@
module ActiveRelation
- module Relations
- class Join < Base
- attr_reader :join_sql, :relation1, :relation2, :predicates
-
- def initialize(join_sql, relation1, relation2, *predicates)
- @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates
- end
-
- def ==(other)
- predicates == other.predicates and
- ((relation1 == other.relation1 and relation2 == other.relation2) or
- (relation2 == other.relation1 and relation1 == other.relation2))
- end
-
- def qualify
- Join.new(join_sql, relation1.qualify, relation2.qualify, *predicates.collect(&:qualify))
- end
-
- protected
- def joins
- [relation1.joins, relation2.joins, join].compact.join(" ")
- end
-
- def selects
- relation1.send(:selects) + relation2.send(:selects)
- end
-
- def attributes
- relation1.attributes + relation2.attributes
- end
-
- def attribute(name)
- relation1[name] || relation2[name]
- end
-
- delegate :table_sql, :to => :relation1
-
- private
- def join
- "#{join_sql} #{relation2.send(:table_sql)} ON #{predicates.collect { |p| p.to_sql(Sql::Predicate.new) }.join(' AND ')}"
- end
+ class Join < Relation
+ attr_reader :join_sql, :relation1, :relation2, :predicates
+
+ def initialize(join_sql, relation1, relation2, *predicates)
+ @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates
+ end
+
+ def ==(other)
+ predicates == other.predicates and
+ ((relation1 == other.relation1 and relation2 == other.relation2) or
+ (relation2 == other.relation1 and relation1 == other.relation2))
+ end
+
+ def qualify
+ Join.new(join_sql, relation1.qualify, relation2.qualify, *predicates.collect(&:qualify))
+ end
+
+ protected
+ def joins
+ [relation1.joins, relation2.joins, join].compact.join(" ")
+ end
+
+ def selects
+ relation1.send(:selects) + relation2.send(:selects)
+ end
+
+ def attributes
+ relation1.attributes + relation2.attributes
+ end
+
+ def attribute(name)
+ relation1[name] || relation2[name]
+ end
+
+ delegate :table_sql, :to => :relation1
+
+ private
+ def join
+ "#{join_sql} #{relation2.send(:table_sql)} ON #{predicates.collect { |p| p.to_sql(Sql::Predicate.new) }.join(' AND ')}"
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/order.rb b/lib/active_relation/relations/order.rb
index bca81c1b6d..d5c2a54cd1 100644
--- a/lib/active_relation/relations/order.rb
+++ b/lib/active_relation/relations/order.rb
@@ -1,19 +1,17 @@
module ActiveRelation
- module Relations
- class Order < Compound
- attr_reader :orders
-
- def initialize(relation, *orders)
- @relation, @orders = relation, orders
- end
-
- def ==(other)
- relation == other.relation and orders == other.orders
- end
-
- def qualify
- Order.new(relation.qualify, *orders.collect { |o| o.qualify })
- end
+ class Order < Compound
+ attr_reader :orders
+
+ def initialize(relation, *orders)
+ @relation, @orders = relation, orders
+ end
+
+ def ==(other)
+ relation == other.relation and orders == other.orders
+ end
+
+ def qualify
+ Order.new(relation.qualify, *orders.collect { |o| o.qualify })
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/projection.rb b/lib/active_relation/relations/projection.rb
index 131db916f0..211e0607ac 100644
--- a/lib/active_relation/relations/projection.rb
+++ b/lib/active_relation/relations/projection.rb
@@ -1,19 +1,17 @@
module ActiveRelation
- module Relations
- class Projection < Compound
- attr_reader :attributes
-
- def initialize(relation, *attributes)
- @relation, @attributes = relation, attributes
- end
-
- def ==(other)
- self.class == other.class and relation == other.relation and attributes == other.attributes
- end
-
- def qualify
- Projection.new(relation.qualify, *attributes.collect(&:qualify))
- end
+ class Projection < Compound
+ attr_reader :attributes
+
+ def initialize(relation, *attributes)
+ @relation, @attributes = relation, attributes
+ end
+
+ def ==(other)
+ self.class == other.class and relation == other.relation and attributes == other.attributes
+ end
+
+ def qualify
+ Projection.new(relation.qualify, *attributes.collect(&:qualify))
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/range.rb b/lib/active_relation/relations/range.rb
index d7e08efa06..e8b7f4b69d 100644
--- a/lib/active_relation/relations/range.rb
+++ b/lib/active_relation/relations/range.rb
@@ -1,23 +1,21 @@
module ActiveRelation
- module Relations
- class Range < Compound
- attr_reader :range
-
- def initialize(relation, range)
- @relation, @range = relation, range
- end
-
- def ==(other)
- relation == other.relation and range == other.range
- end
-
- def limit
- range.end - range.begin + 1
- end
-
- def offset
- range.begin
- end
+ class Range < Compound
+ attr_reader :range
+
+ def initialize(relation, range)
+ @relation, @range = relation, range
+ end
+
+ def ==(other)
+ relation == other.relation and range == other.range
+ end
+
+ def limit
+ range.end - range.begin + 1
+ end
+
+ def offset
+ range.begin
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/relation.rb b/lib/active_relation/relations/relation.rb
new file mode 100644
index 0000000000..663450e69c
--- /dev/null
+++ b/lib/active_relation/relations/relation.rb
@@ -0,0 +1,103 @@
+module ActiveRelation
+ class Relation
+ include Sql::Quoting
+
+ 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 join(other)
+ JoinOperation.new("INNER JOIN", self, other)
+ end
+
+ def outer_join(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)
+ RelationInclusion.new(attribute, self)
+ end
+
+ def select(*predicates)
+ Selection.new(self, *predicates)
+ end
+
+ def project(*attributes)
+ Projection.new(self, *attributes)
+ end
+
+ def as(aliaz)
+ Alias.new(self, aliaz)
+ 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
+
+ JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
+ def on(*predicates)
+ Join.new(join_sql, relation1, relation2, *predicates)
+ end
+ end
+ end
+ include Operations
+
+ def to_sql(strategy = Sql::Select.new)
+ strategy.select [
+ "SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new) }.join(', ')}",
+ "FROM #{table_sql}",
+ (joins unless joins.blank?),
+ ("WHERE #{selects.collect{|s| s.to_sql(Sql::Predicate.new)}.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 connection
+ ActiveRecord::Base.connection
+ end
+
+ def attributes; [] end
+ def selects; [] end
+ def orders; [] end
+ def inserts; [] end
+ def joins; nil end
+ def limit; nil end
+ def offset; nil end
+ def alias; nil end
+ end
+end \ No newline at end of file
diff --git a/lib/active_relation/relations/rename.rb b/lib/active_relation/relations/rename.rb
index c4ba6ded88..2977804db1 100644
--- a/lib/active_relation/relations/rename.rb
+++ b/lib/active_relation/relations/rename.rb
@@ -1,38 +1,36 @@
module ActiveRelation
- module Relations
- class Rename < Compound
- attr_reader :schmattribute, :rename
-
- def initialize(relation, renames)
- @schmattribute, @rename = renames.shift
- @relation = renames.empty?? relation : Rename.new(relation, renames)
- end
-
- def ==(other)
- relation == other.relation and schmattribute == other.schmattribute and self.rename == other.rename
- end
-
- def attributes
- relation.attributes.collect(&method(:substitute))
- end
-
- def qualify
- Rename.new(relation.qualify, schmattribute.qualify => self.rename)
- end
-
- protected
- def attribute(name)
- case
- when name == self.rename then schmattribute.as(self.rename)
- when relation[name] == schmattribute then nil
- else relation[name]
- end
- end
-
- private
- def substitute(a)
- a == schmattribute ? a.as(self.rename) : a
+ class Rename < Compound
+ attr_reader :schmattribute, :rename
+
+ def initialize(relation, renames)
+ @schmattribute, @rename = renames.shift
+ @relation = renames.empty?? relation : Rename.new(relation, renames)
+ end
+
+ def ==(other)
+ relation == other.relation and schmattribute == other.schmattribute and self.rename == other.rename
+ end
+
+ def attributes
+ relation.attributes.collect(&method(:substitute))
+ end
+
+ def qualify
+ Rename.new(relation.qualify, schmattribute.qualify => self.rename)
+ end
+
+ protected
+ def attribute(name)
+ case
+ when name == self.rename then schmattribute.as(self.rename)
+ when relation[name] == schmattribute then nil
+ else relation[name]
end
end
+
+ private
+ def substitute(a)
+ a == schmattribute ? a.as(self.rename) : a
+ end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/selection.rb b/lib/active_relation/relations/selection.rb
index e86dc627db..3ecea059d5 100644
--- a/lib/active_relation/relations/selection.rb
+++ b/lib/active_relation/relations/selection.rb
@@ -1,25 +1,23 @@
module ActiveRelation
- module Relations
- class Selection < Compound
- attr_reader :predicate
-
- def initialize(relation, *predicates)
- @predicate = predicates.shift
- @relation = predicates.empty?? relation : Selection.new(relation, *predicates)
- end
-
- def ==(other)
- relation == other.relation and predicate == other.predicate
- end
-
- def qualify
- Selection.new(relation.qualify, predicate.qualify)
- end
-
- protected
- def selects
- relation.send(:selects) + [predicate]
- end
+ class Selection < Compound
+ attr_reader :predicate
+
+ def initialize(relation, *predicates)
+ @predicate = predicates.shift
+ @relation = predicates.empty?? relation : Selection.new(relation, *predicates)
+ end
+
+ def ==(other)
+ relation == other.relation and predicate == other.predicate
+ end
+
+ def qualify
+ Selection.new(relation.qualify, predicate.qualify)
+ end
+
+ protected
+ def selects
+ relation.send(:selects) + [predicate]
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/table.rb b/lib/active_relation/relations/table.rb
index a370b4266d..5220087318 100644
--- a/lib/active_relation/relations/table.rb
+++ b/lib/active_relation/relations/table.rb
@@ -1,39 +1,37 @@
module ActiveRelation
- module Relations
- class Table < Base
- attr_reader :name
-
- def initialize(name)
- @name = name
- end
-
- def attributes
- attributes_by_name.values
- end
+ class Table < Relation
+ attr_reader :name
+
+ def initialize(name)
+ @name = name
+ end
+
+ def attributes
+ attributes_by_name.values
+ end
+
+ def qualify
+ Rename.new self, qualifications
+ end
- def qualify
- Rename.new self, qualifications
- end
+ protected
+ def attribute(name)
+ attributes_by_name[name.to_s]
+ end
- protected
- def attribute(name)
- attributes_by_name[name.to_s]
- end
-
- def table_sql
- "#{quote_table_name(name)}"
- end
-
- private
- def attributes_by_name
- @attributes_by_name ||= connection.columns(name, "#{name} Columns").inject({}) do |attributes_by_name, column|
- attributes_by_name.merge(column.name => Primitives::Attribute.new(self, column.name.to_sym))
- end
- end
-
- def qualifications
- attributes.zip(attributes.collect(&:qualified_name)).to_hash
+ def table_sql
+ "#{quote_table_name(name)}"
+ end
+
+ private
+ def attributes_by_name
+ @attributes_by_name ||= connection.columns(name, "#{name} Columns").inject({}) do |attributes_by_name, column|
+ attributes_by_name.merge(column.name => Attribute.new(self, column.name.to_sym))
end
end
+
+ def qualifications
+ attributes.zip(attributes.collect(&:qualified_name)).to_hash
+ end
end
end \ No newline at end of file