aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--spec/active_relation/predicates/binary_spec.rb60
-rw-r--r--spec/active_relation/predicates/equality_spec.rb40
-rw-r--r--spec/active_relation/predicates/match_spec.rb22
-rw-r--r--spec/active_relation/predicates/relation_inclusion_spec.rb36
-rw-r--r--spec/active_relation/primitives/aggregation_spec.rb38
-rw-r--r--spec/active_relation/primitives/attribute_spec.rb164
-rw-r--r--spec/active_relation/relations/alias_spec.rb50
-rw-r--r--spec/active_relation/relations/base_spec.rb102
-rw-r--r--spec/active_relation/relations/compound_spec.rb14
-rw-r--r--spec/active_relation/relations/deletion_spec.rb36
-rw-r--r--spec/active_relation/relations/insertion_spec.rb40
-rw-r--r--spec/active_relation/relations/join_spec.rb64
-rw-r--r--spec/active_relation/relations/order_spec.rb44
-rw-r--r--spec/active_relation/relations/projection_spec.rb50
-rw-r--r--spec/active_relation/relations/range_spec.rb45
-rw-r--r--spec/active_relation/relations/relation_spec.rb104
-rw-r--r--spec/active_relation/relations/rename_spec.rb86
-rw-r--r--spec/active_relation/relations/selection_spec.rb64
-rw-r--r--spec/active_relation/relations/table_spec.rb42
-rw-r--r--spec/spec_helper.rb5
38 files changed, 1039 insertions, 1041 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
diff --git a/spec/active_relation/predicates/binary_spec.rb b/spec/active_relation/predicates/binary_spec.rb
index be607efd95..a6878e4898 100644
--- a/spec/active_relation/predicates/binary_spec.rb
+++ b/spec/active_relation/predicates/binary_spec.rb
@@ -1,42 +1,44 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Predicates::Binary do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @attribute1 = ActiveRelation::Primitives::Attribute.new(@relation1, :name1)
- @attribute2 = ActiveRelation::Primitives::Attribute.new(@relation2, :name2)
- class ConcreteBinary < ActiveRelation::Predicates::Binary
- def predicate_sql
- "<=>"
+module ActiveRelation
+ describe Binary do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @attribute1 = Attribute.new(@relation1, :name1)
+ @attribute2 = Attribute.new(@relation2, :name2)
+ class ConcreteBinary < Binary
+ def predicate_sql
+ "<=>"
+ end
end
end
- end
- describe '==' do
- it "obtains if attribute1 and attribute2 are identical" do
- ActiveRelation::Predicates::Binary.new(@attribute1, @attribute2).should == ActiveRelation::Predicates::Binary.new(@attribute1, @attribute2)
- ActiveRelation::Predicates::Binary.new(@attribute1, @attribute2).should_not == ActiveRelation::Predicates::Binary.new(@attribute1, @attribute1)
- end
+ describe '==' do
+ it "obtains if attribute1 and attribute2 are identical" do
+ Binary.new(@attribute1, @attribute2).should == Binary.new(@attribute1, @attribute2)
+ Binary.new(@attribute1, @attribute2).should_not == Binary.new(@attribute1, @attribute1)
+ end
- it "obtains if the concrete type of the ActiveRelation::Predicates::Binarys are identical" do
- ActiveRelation::Predicates::Binary.new(@attribute1, @attribute2).should == ActiveRelation::Predicates::Binary.new(@attribute1, @attribute2)
- ActiveRelation::Predicates::Binary.new(@attribute1, @attribute2).should_not == ConcreteBinary.new(@attribute1, @attribute2)
+ it "obtains if the concrete type of the Predicates::Binarys are identical" do
+ Binary.new(@attribute1, @attribute2).should == Binary.new(@attribute1, @attribute2)
+ Binary.new(@attribute1, @attribute2).should_not == ConcreteBinary.new(@attribute1, @attribute2)
+ end
end
- end
- describe '#qualify' do
- it "distributes over the predicates and attributes" do
- ConcreteBinary.new(@attribute1, @attribute2).qualify. \
- should == ConcreteBinary.new(@attribute1.qualify, @attribute2.qualify)
+ describe '#qualify' do
+ it "distributes over the predicates and attributes" do
+ ConcreteBinary.new(@attribute1, @attribute2).qualify. \
+ should == ConcreteBinary.new(@attribute1.qualify, @attribute2.qualify)
+ end
end
- end
- describe '#to_sql' do
- it 'manufactures correct sql' do
- ConcreteBinary.new(@attribute1, @attribute2).to_sql.should be_like("""
- `foo`.`name1` <=> `bar`.`name2`
- """)
+ describe '#to_sql' do
+ it 'manufactures correct sql' do
+ ConcreteBinary.new(@attribute1, @attribute2).to_sql.should be_like("""
+ `foo`.`name1` <=> `bar`.`name2`
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/predicates/equality_spec.rb b/spec/active_relation/predicates/equality_spec.rb
index 9394e63835..d23893e438 100644
--- a/spec/active_relation/predicates/equality_spec.rb
+++ b/spec/active_relation/predicates/equality_spec.rb
@@ -1,28 +1,30 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Predicates::Equality do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @attribute1 = ActiveRelation::Primitives::Attribute.new(@relation1, :name)
- @attribute2 = ActiveRelation::Primitives::Attribute.new(@relation2, :name)
- end
-
- describe '==' do
- it "obtains if attribute1 and attribute2 are identical" do
- ActiveRelation::Predicates::Equality.new(@attribute1, @attribute2).should == ActiveRelation::Predicates::Equality.new(@attribute1, @attribute2)
- ActiveRelation::Predicates::Equality.new(@attribute1, @attribute2).should_not == ActiveRelation::Predicates::Equality.new(@attribute1, @attribute1)
+module ActiveRelation
+ describe Equality do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @attribute1 = Attribute.new(@relation1, :name)
+ @attribute2 = Attribute.new(@relation2, :name)
end
+
+ describe '==' do
+ it "obtains if attribute1 and attribute2 are identical" do
+ Equality.new(@attribute1, @attribute2).should == Equality.new(@attribute1, @attribute2)
+ Equality.new(@attribute1, @attribute2).should_not == Equality.new(@attribute1, @attribute1)
+ end
- it "obtains if the concrete type of the predicates are identical" do
- ActiveRelation::Predicates::Equality.new(@attribute1, @attribute2).should_not == ActiveRelation::Predicates::Binary.new(@attribute1, @attribute2)
- end
+ it "obtains if the concrete type of the predicates are identical" do
+ Equality.new(@attribute1, @attribute2).should_not == Binary.new(@attribute1, @attribute2)
+ end
- it "is commutative on the attributes" do
- ActiveRelation::Predicates::Equality.new(@attribute1, @attribute2).should == ActiveRelation::Predicates::Equality.new(@attribute2, @attribute1)
+ it "is commutative on the attributes" do
+ Equality.new(@attribute1, @attribute2).should == Equality.new(@attribute2, @attribute1)
+ end
end
- end
- describe '#to_sql' do
+ describe '#to_sql' do
+ end
end
end \ No newline at end of file
diff --git a/spec/active_relation/predicates/match_spec.rb b/spec/active_relation/predicates/match_spec.rb
index a01f4fb76b..3d01ce1055 100644
--- a/spec/active_relation/predicates/match_spec.rb
+++ b/spec/active_relation/predicates/match_spec.rb
@@ -1,16 +1,18 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Predicates::RelationInclusion do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @attribute = @relation1[:baz]
- end
+module ActiveRelation
+ describe RelationInclusion do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @attribute = @relation1[:baz]
+ end
- describe ActiveRelation::Predicates::RelationInclusion, '==' do
- it "obtains if attribute1 and attribute2 are identical" do
- ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation1).should == ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation1)
- ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation1).should_not == ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation2)
+ describe RelationInclusion, '==' do
+ it "obtains if attribute1 and attribute2 are identical" do
+ RelationInclusion.new(@attribute, @relation1).should == RelationInclusion.new(@attribute, @relation1)
+ RelationInclusion.new(@attribute, @relation1).should_not == RelationInclusion.new(@attribute, @relation2)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/predicates/relation_inclusion_spec.rb b/spec/active_relation/predicates/relation_inclusion_spec.rb
index de3dcf7747..05039028ee 100644
--- a/spec/active_relation/predicates/relation_inclusion_spec.rb
+++ b/spec/active_relation/predicates/relation_inclusion_spec.rb
@@ -1,25 +1,27 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Predicates::RelationInclusion do
- before do
- foo = ActiveRelation::Relations::Table.new(:foo)
- @relation1 = foo.project(foo[:id])
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @attribute = @relation1[:id]
- end
+module ActiveRelation
+ describe RelationInclusion do
+ before do
+ foo = Table.new(:foo)
+ @relation1 = foo.project(foo[:id])
+ @relation2 = Table.new(:bar)
+ @attribute = @relation1[:id]
+ end
- describe ActiveRelation::Predicates::RelationInclusion, '==' do
- it "obtains if attribute1 and attribute2 are identical" do
- ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation1).should == ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation1)
- ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation1).should_not == ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation2)
+ describe RelationInclusion, '==' do
+ it "obtains if attribute1 and attribute2 are identical" do
+ RelationInclusion.new(@attribute, @relation1).should == RelationInclusion.new(@attribute, @relation1)
+ RelationInclusion.new(@attribute, @relation1).should_not == RelationInclusion.new(@attribute, @relation2)
+ end
end
- end
- describe ActiveRelation::Predicates::RelationInclusion, '#to_sql' do
- it "manufactures subselect sql" do
- ActiveRelation::Predicates::RelationInclusion.new(@attribute, @relation1).to_sql.should be_like("""
- `foo`.`id` IN (SELECT `foo`.`id` FROM `foo`)
- """)
+ describe RelationInclusion, '#to_sql' do
+ it "manufactures subselect sql" do
+ RelationInclusion.new(@attribute, @relation1).to_sql.should be_like("""
+ `foo`.`id` IN (SELECT `foo`.`id` FROM `foo`)
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/primitives/aggregation_spec.rb b/spec/active_relation/primitives/aggregation_spec.rb
index 60bb4a6aa8..bdfa152bca 100644
--- a/spec/active_relation/primitives/aggregation_spec.rb
+++ b/spec/active_relation/primitives/aggregation_spec.rb
@@ -1,25 +1,27 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Primitives::Aggregation do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- end
+module ActiveRelation
+ describe Aggregation do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ end
- describe '==' do
- it 'obtains if the attribute and function sql are identical' do
- @relation1[:id].sum.should == @relation1[:id].sum
- @relation1[:id].sum.should_not == @relation1[:name].sum
- @relation1[:id].sum.should_not == @relation1[:name].average
- @relation1[:id].sum.should_not == @relation2[:id].sum
+ describe '==' do
+ it 'obtains if the attribute and function sql are identical' do
+ @relation1[:id].sum.should == @relation1[:id].sum
+ @relation1[:id].sum.should_not == @relation1[:name].sum
+ @relation1[:id].sum.should_not == @relation1[:name].average
+ @relation1[:id].sum.should_not == @relation2[:id].sum
+ end
end
- end
- describe '#to_sql' do
- it 'manufactures sql with an aggregation function' do
- @relation1[:id].maximum.to_sql.should be_like("""
- MAX(`foo`.`id`)
- """)
+ describe '#to_sql' do
+ it 'manufactures sql with an aggregation function' do
+ @relation1[:id].maximum.to_sql.should be_like("""
+ MAX(`foo`.`id`)
+ """)
+ end
end
end
-end
+end \ No newline at end of file
diff --git a/spec/active_relation/primitives/attribute_spec.rb b/spec/active_relation/primitives/attribute_spec.rb
index f1aa404a34..6078da08f3 100644
--- a/spec/active_relation/primitives/attribute_spec.rb
+++ b/spec/active_relation/primitives/attribute_spec.rb
@@ -1,119 +1,119 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Primitives::Attribute do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- end
-
- describe '#as' do
- it "manufactures an aliased attributed when provided a parameter" do
- @relation1[:id].as(:alias).should == ActiveRelation::Primitives::Attribute.new(@relation1, :id, :alias)
+module ActiveRelation
+ describe Attribute do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
end
- end
- describe '#qualified_name' do
- it "manufactures an attribute name prefixed with the relation's name" do
- @relation1[:id].qualified_name.should == 'foo.id'
+ describe '#as' do
+ it "manufactures an aliased attributed when provided a parameter" do
+ @relation1[:id].as(:alias).should == Attribute.new(@relation1, :id, :alias)
+ end
end
+
+ describe '#qualified_name' do
+ it "manufactures an attribute name prefixed with the relation's name" do
+ @relation1[:id].qualified_name.should == 'foo.id'
+ end
- it "manufactures an attribute name prefixed with the relation's aliased name" do
- @relation1.as(:bar)[:id].qualified_name.should == 'bar.id'
+ it "manufactures an attribute name prefixed with the relation's aliased name" do
+ @relation1.as(:bar)[:id].qualified_name.should == 'bar.id'
+ end
end
- end
- describe '#qualify' do
- it "manufactures an attribute aliased with that attributes qualified name" do
- @relation1[:id].qualify.should == @relation1[:id].qualify
+ describe '#qualify' do
+ it "manufactures an attribute aliased with that attributes qualified name" do
+ @relation1[:id].qualify.should == @relation1[:id].qualify
+ end
end
- end
- describe '==' do
- it "obtains if the relation and attribute name are identical" do
- ActiveRelation::Primitives::Attribute.new(@relation1, :name).should == ActiveRelation::Primitives::Attribute.new(@relation1, :name)
- ActiveRelation::Primitives::Attribute.new(@relation1, :name).should_not == ActiveRelation::Primitives::Attribute.new(@relation1, :another_name)
- ActiveRelation::Primitives::Attribute.new(@relation1, :name).should_not == ActiveRelation::Primitives::Attribute.new(@relation2, :name)
+ describe '==' do
+ it "obtains if the relation and attribute name are identical" do
+ Attribute.new(@relation1, :name).should == Attribute.new(@relation1, :name)
+ Attribute.new(@relation1, :name).should_not == Attribute.new(@relation1, :another_name)
+ Attribute.new(@relation1, :name).should_not == Attribute.new(@relation2, :name)
+ end
end
- end
- describe 'predications' do
- before do
- @attribute1 = ActiveRelation::Primitives::Attribute.new(@relation1, :name)
- @attribute2 = ActiveRelation::Primitives::Attribute.new(@relation2, :name)
- end
+ describe 'predications' do
+ before do
+ @attribute1 = Attribute.new(@relation1, :name)
+ @attribute2 = Attribute.new(@relation2, :name)
+ end
- describe '#equals' do
- it "manufactures an equality predicate" do
- @attribute1.equals(@attribute2).should == ActiveRelation::Predicates::Equality.new(@attribute1, @attribute2)
+ describe '#equals' do
+ it "manufactures an equality predicate" do
+ @attribute1.equals(@attribute2).should == Equality.new(@attribute1, @attribute2)
+ end
end
- end
- describe '#less_than' do
- it "manufactures a less-than predicate" do
- @attribute1.less_than(@attribute2).should == ActiveRelation::Predicates::LessThan.new(@attribute1, @attribute2)
+ describe '#less_than' do
+ it "manufactures a less-than predicate" do
+ @attribute1.less_than(@attribute2).should == LessThan.new(@attribute1, @attribute2)
+ end
end
- end
- describe '#less_than_or_equal_to' do
- it "manufactures a less-than or equal-to predicate" do
- @attribute1.less_than_or_equal_to(@attribute2).should == ActiveRelation::Predicates::LessThanOrEqualTo.new(@attribute1, @attribute2)
+ describe '#less_than_or_equal_to' do
+ it "manufactures a less-than or equal-to predicate" do
+ @attribute1.less_than_or_equal_to(@attribute2).should == LessThanOrEqualTo.new(@attribute1, @attribute2)
+ end
end
- end
- describe '#greater_than' do
- it "manufactures a greater-than predicate" do
- @attribute1.greater_than(@attribute2).should == ActiveRelation::Predicates::GreaterThan.new(@attribute1, @attribute2)
+ describe '#greater_than' do
+ it "manufactures a greater-than predicate" do
+ @attribute1.greater_than(@attribute2).should == GreaterThan.new(@attribute1, @attribute2)
+ end
end
- end
- describe '#greater_than_or_equal_to' do
- it "manufactures a greater-than or equal to predicate" do
- @attribute1.greater_than_or_equal_to(@attribute2).should == ActiveRelation::Predicates::GreaterThanOrEqualTo.new(@attribute1, @attribute2)
+ describe '#greater_than_or_equal_to' do
+ it "manufactures a greater-than or equal to predicate" do
+ @attribute1.greater_than_or_equal_to(@attribute2).should == GreaterThanOrEqualTo.new(@attribute1, @attribute2)
+ end
end
- end
- describe '#matches' do
- it "manufactures a match predicate" do
- @attribute1.matches(/.*/).should == ActiveRelation::Predicates::Match.new(@attribute1, @attribute2)
+ describe '#matches' do
+ it "manufactures a match predicate" do
+ @attribute1.matches(/.*/).should == Match.new(@attribute1, @attribute2)
+ end
end
end
- end
- describe 'aggregations' do
- before do
- @attribute1 = ActiveRelation::Primitives::Attribute.new(@relation1, :name)
- end
-
- describe '#count' do
- it "manufactures a count aggregation" do
- @attribute1.count.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "COUNT")
+ describe 'aggregations' do
+ before do
+ @attribute1 = Attribute.new(@relation1, :name)
end
- end
- describe '#sum' do
- it "manufactures a sum aggregation" do
- @attribute1.sum.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "SUM")
+ describe '#count' do
+ it "manufactures a count aggregation" do
+ @attribute1.count.should == Aggregation.new(@attribute1, "COUNT")
+ end
end
- end
- describe '#maximum' do
- it "manufactures a maximum aggregation" do
- @attribute1.maximum.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "MAX")
+ describe '#sum' do
+ it "manufactures a sum aggregation" do
+ @attribute1.sum.should == Aggregation.new(@attribute1, "SUM")
+ end
end
- end
- describe '#minimum' do
- it "manufactures a minimum aggregation" do
- @attribute1.minimum.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "MIN")
+ describe '#maximum' do
+ it "manufactures a maximum aggregation" do
+ @attribute1.maximum.should == Aggregation.new(@attribute1, "MAX")
+ end
end
- end
- describe '#average' do
- it "manufactures an average aggregation" do
- @attribute1.average.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "AVG")
+ describe '#minimum' do
+ it "manufactures a minimum aggregation" do
+ @attribute1.minimum.should == Aggregation.new(@attribute1, "MIN")
+ end
end
- end
-
+ describe '#average' do
+ it "manufactures an average aggregation" do
+ @attribute1.average.should == Aggregation.new(@attribute1, "AVG")
+ end
+ end
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/active_relation/relations/alias_spec.rb b/spec/active_relation/relations/alias_spec.rb
index 6f25df3ddb..418af7fe66 100644
--- a/spec/active_relation/relations/alias_spec.rb
+++ b/spec/active_relation/relations/alias_spec.rb
@@ -1,36 +1,38 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Alias do
- before do
- @relation = ActiveRelation::Relations::Table.new(:users)
- @alias_relation = @relation.as(:foo)
- end
+module ActiveRelation
+ describe Alias do
+ before do
+ @relation = Table.new(:users)
+ @alias_relation = @relation.as(:foo)
+ end
- describe '#name' do
- it 'returns the alias' do
- @alias_relation.name.should == :foo
+ describe '#name' do
+ it 'returns the alias' do
+ @alias_relation.name.should == :foo
+ end
end
- end
- describe '#attributes' do
- it 'manufactures sql deleting a table relation' do
- @alias_relation.attributes.should == @relation.attributes.collect { |a| ActiveRelation::Primitives::Attribute.new(@alias_relation, a.name) }
+ describe '#attributes' do
+ it 'manufactures sql deleting a table relation' do
+ @alias_relation.attributes.should == @relation.attributes.collect { |a| Attribute.new(@alias_relation, a.name) }
+ end
end
- end
- describe '[]' do
- it 'manufactures attributes associated with the aliased relation' do
- @alias_relation[:id].relation.should == @alias_relation
- @alias_relation[:does_not_exist].should be_nil
+ describe '[]' do
+ it 'manufactures attributes associated with the aliased relation' do
+ @alias_relation[:id].relation.should == @alias_relation
+ @alias_relation[:does_not_exist].should be_nil
+ end
end
- end
- describe '#to_sql' do
- it "manufactures an aliased select query" do
- @alias_relation.to_sql.should be_like("""
- SELECT `foo`.`name`, `foo`.`id`
- FROM `users` AS `foo`
- """)
+ describe '#to_sql' do
+ it "manufactures an aliased select query" do
+ @alias_relation.to_sql.should be_like("""
+ SELECT `foo`.`name`, `foo`.`id`
+ FROM `users` AS `foo`
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/relations/base_spec.rb b/spec/active_relation/relations/base_spec.rb
deleted file mode 100644
index 18063757df..0000000000
--- a/spec/active_relation/relations/base_spec.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-
-describe ActiveRelation::Relations::Base do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @attribute1 = ActiveRelation::Primitives::Attribute.new(@relation1, :id)
- @attribute2 = ActiveRelation::Primitives::Attribute.new(@relation1, :name)
- end
-
- describe '[]' do
- it "manufactures an attribute when given a symbol" do
- @relation1[:id].should == ActiveRelation::Primitives::Attribute.new(@relation1, :id)
- end
-
- it "manufactures a range relation when given a range" do
- @relation1[1..2].should == ActiveRelation::Relations::Range.new(@relation1, 1..2)
- end
- end
-
- describe '#include?' do
- it "manufactures an inclusion predicate" do
- @relation1.include?(@attribute1).should be_kind_of(ActiveRelation::Predicates::RelationInclusion)
- end
- end
-
- describe 'read operations' do
- describe 'joins' do
- before do
- @predicate = @relation1[:id].equals(@relation2[:id])
- end
-
- describe '#join' do
- it "manufactures an inner join operation between those two relations" do
- @relation1.join(@relation2).on(@predicate).should == ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation2, @predicate)
- end
- end
-
- describe '#outer_join' do
- it "manufactures a left outer join operation between those two relations" do
- @relation1.outer_join(@relation2).on(@predicate).should == ActiveRelation::Relations::Join.new("LEFT OUTER JOIN", @relation1, @relation2, @predicate)
- end
- end
- end
-
- describe '#project' do
- it "collapses identical projections" do
- pending
- end
-
- it "manufactures a projection relation" do
- @relation1.project(@attribute1, @attribute2).should == ActiveRelation::Relations::Projection.new(@relation1, @attribute1, @attribute2)
- end
- end
-
- describe '#as' do
- it "manufactures an alias relation" do
- @relation1.as(:thucydides).should == ActiveRelation::Relations::Alias.new(@relation1, :thucydides)
- end
- end
-
- describe '#rename' do
- it "manufactures a rename relation" do
- @relation1.rename(@attribute1, :foo).should == ActiveRelation::Relations::Rename.new(@relation1, @attribute1 => :foo)
- end
- end
-
- describe '#select' do
- before do
- @predicate = ActiveRelation::Predicates::Equality.new(@attribute1, @attribute2)
- end
-
- it "manufactures a selection relation" do
- @relation1.select(@predicate).should == ActiveRelation::Relations::Selection.new(@relation1, @predicate)
- end
-
- it "accepts arbitrary strings" do
- @relation1.select("arbitrary").should == ActiveRelation::Relations::Selection.new(@relation1, "arbitrary")
- end
- end
-
- describe '#order' do
- it "manufactures an order relation" do
- @relation1.order(@attribute1, @attribute2).should be_kind_of(ActiveRelation::Relations::Order)
- end
- end
- end
-
- describe 'write operations' do
- describe '#delete' do
- it 'manufactures a deletion relation' do
- @relation1.delete.should be_kind_of(ActiveRelation::Relations::Deletion)
- end
- end
-
- describe '#insert' do
- it 'manufactures an insertion relation' do
- @relation1.insert(record = {:id => 1}).should be_kind_of(ActiveRelation::Relations::Insertion)
- end
- end
- end
-end \ No newline at end of file
diff --git a/spec/active_relation/relations/compound_spec.rb b/spec/active_relation/relations/compound_spec.rb
index f383ff4dfd..6309547c7d 100644
--- a/spec/active_relation/relations/compound_spec.rb
+++ b/spec/active_relation/relations/compound_spec.rb
@@ -1,12 +1,14 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Compound do
- before do
- @relation = ActiveRelation::Relations::Table.new(:users)
+module ActiveRelation
+ describe Compound do
+ before do
+ @relation = Table.new(:users)
- class ConcreteCompound < ActiveRelation::Relations::Compound
- def initialize(relation)
- @relation = relation
+ class ConcreteCompound < Compound
+ def initialize(relation)
+ @relation = relation
+ end
end
end
end
diff --git a/spec/active_relation/relations/deletion_spec.rb b/spec/active_relation/relations/deletion_spec.rb
index ed201ac0d9..64b75d0600 100644
--- a/spec/active_relation/relations/deletion_spec.rb
+++ b/spec/active_relation/relations/deletion_spec.rb
@@ -1,24 +1,26 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Deletion do
- before do
- @relation = ActiveRelation::Relations::Table.new(:users)
- end
-
- describe '#to_sql' do
- it 'manufactures sql deleting a table relation' do
- ActiveRelation::Relations::Deletion.new(@relation).to_sql.should be_like("""
- DELETE
- FROM `users`
- """)
+module ActiveRelation
+ describe Deletion do
+ before do
+ @relation = Table.new(:users)
end
+
+ describe '#to_sql' do
+ it 'manufactures sql deleting a table relation' do
+ Deletion.new(@relation).to_sql.should be_like("""
+ DELETE
+ FROM `users`
+ """)
+ end
- it 'manufactures sql deleting a selection relation' do
- ActiveRelation::Relations::Deletion.new(@relation.select(@relation[:id].equals(1))).to_sql.should be_like("""
- DELETE
- FROM `users`
- WHERE `users`.`id` = 1
- """)
+ it 'manufactures sql deleting a selection relation' do
+ Deletion.new(@relation.select(@relation[:id].equals(1))).to_sql.should be_like("""
+ DELETE
+ FROM `users`
+ WHERE `users`.`id` = 1
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/relations/insertion_spec.rb b/spec/active_relation/relations/insertion_spec.rb
index da39edf773..f16ab8cc23 100644
--- a/spec/active_relation/relations/insertion_spec.rb
+++ b/spec/active_relation/relations/insertion_spec.rb
@@ -1,26 +1,28 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Insertion do
- before do
- @relation = ActiveRelation::Relations::Table.new(:users)
- end
-
- describe '#to_sql' do
- it 'manufactures sql inserting the data for one item' do
- ActiveRelation::Relations::Insertion.new(@relation, @relation[:name] => "nick").to_sql.should be_like("""
- INSERT
- INTO `users`
- (`users`.`name`) VALUES ('nick')
- """)
+module ActiveRelation
+ describe Insertion do
+ before do
+ @relation = Table.new(:users)
end
+
+ describe '#to_sql' do
+ it 'manufactures sql inserting the data for one item' do
+ Insertion.new(@relation, @relation[:name] => "nick").to_sql.should be_like("""
+ INSERT
+ INTO `users`
+ (`users`.`name`) VALUES ('nick')
+ """)
+ end
- it 'manufactures sql inserting the data for multiple items' do
- nested_insertion = ActiveRelation::Relations::Insertion.new(@relation, @relation[:name] => "cobra")
- ActiveRelation::Relations::Insertion.new(nested_insertion, nested_insertion[:name] => "commander").to_sql.should be_like("""
- INSERT
- INTO `users`
- (`users`.`name`) VALUES ('cobra'), ('commander')
- """)
+ it 'manufactures sql inserting the data for multiple items' do
+ nested_insertion = Insertion.new(@relation, @relation[:name] => "cobra")
+ Insertion.new(nested_insertion, nested_insertion[:name] => "commander").to_sql.should be_like("""
+ INSERT
+ INTO `users`
+ (`users`.`name`) VALUES ('cobra'), ('commander')
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/relations/join_spec.rb b/spec/active_relation/relations/join_spec.rb
index 2a84a92b70..25c505e371 100644
--- a/spec/active_relation/relations/join_spec.rb
+++ b/spec/active_relation/relations/join_spec.rb
@@ -1,43 +1,45 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Join do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @predicate = ActiveRelation::Predicates::Equality.new(@relation1[:id], @relation2[:id])
- end
-
- describe '==' do
- it 'obtains if the two relations and the predicate are identical' do
- ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation2, @predicate).should == ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation2, @predicate)
- ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation2, @predicate).should_not == ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation1, @predicate)
+module ActiveRelation
+ describe Join do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @predicate = Equality.new(@relation1[:id], @relation2[:id])
end
- it 'is commutative on the relations' do
- ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation2, @predicate).should == ActiveRelation::Relations::Join.new("INNER JOIN", @relation2, @relation1, @predicate)
- end
- end
+ describe '==' do
+ it 'obtains if the two relations and the predicate are identical' do
+ Join.new("INNER JOIN", @relation1, @relation2, @predicate).should == Join.new("INNER JOIN", @relation1, @relation2, @predicate)
+ Join.new("INNER JOIN", @relation1, @relation2, @predicate).should_not == Join.new("INNER JOIN", @relation1, @relation1, @predicate)
+ end
- describe '#qualify' do
- it 'distributes over the relations and predicates' do
- ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation2, @predicate).qualify. \
- should == ActiveRelation::Relations::Join.new("INNER JOIN", @relation1.qualify, @relation2.qualify, @predicate.qualify)
+ it 'is commutative on the relations' do
+ Join.new("INNER JOIN", @relation1, @relation2, @predicate).should == Join.new("INNER JOIN", @relation2, @relation1, @predicate)
+ end
end
- end
- describe '#to_sql' do
- before do
- @relation1 = @relation1.select(@relation1[:id].equals(1))
+ describe '#qualify' do
+ it 'distributes over the relations and predicates' do
+ Join.new("INNER JOIN", @relation1, @relation2, @predicate).qualify. \
+ should == Join.new("INNER JOIN", @relation1.qualify, @relation2.qualify, @predicate.qualify)
+ end
end
+
+ describe '#to_sql' do
+ before do
+ @relation1 = @relation1.select(@relation1[:id].equals(1))
+ end
- it 'manufactures sql joining the two tables on the predicate, merging the selects' do
- ActiveRelation::Relations::Join.new("INNER JOIN", @relation1, @relation2, @predicate).to_sql.should be_like("""
- SELECT `foo`.`name`, `foo`.`id`, `bar`.`name`, `bar`.`foo_id`, `bar`.`id`
- FROM `foo`
- INNER JOIN `bar` ON `foo`.`id` = `bar`.`id`
- WHERE
- `foo`.`id` = 1
- """)
+ it 'manufactures sql joining the two tables on the predicate, merging the selects' do
+ Join.new("INNER JOIN", @relation1, @relation2, @predicate).to_sql.should be_like("""
+ SELECT `foo`.`name`, `foo`.`id`, `bar`.`name`, `bar`.`foo_id`, `bar`.`id`
+ FROM `foo`
+ INNER JOIN `bar` ON `foo`.`id` = `bar`.`id`
+ WHERE
+ `foo`.`id` = 1
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/relations/order_spec.rb b/spec/active_relation/relations/order_spec.rb
index edf2faf455..204558daec 100644
--- a/spec/active_relation/relations/order_spec.rb
+++ b/spec/active_relation/relations/order_spec.rb
@@ -1,28 +1,30 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Order do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @attribute1 = @relation1[:id]
- @attribute2 = @relation2[:id]
- end
+module ActiveRelation
+ describe Order do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @attribute1 = @relation1[:id]
+ @attribute2 = @relation2[:id]
+ end
- describe '#qualify' do
- it "distributes over the relation and attributes" do
- ActiveRelation::Relations::Order.new(@relation1, @attribute1).qualify. \
- should == ActiveRelation::Relations::Order.new(@relation1.qualify, @attribute1.qualify)
+ describe '#qualify' do
+ it "distributes over the relation and attributes" do
+ Order.new(@relation1, @attribute1).qualify. \
+ should == Order.new(@relation1.qualify, @attribute1.qualify)
+ end
end
- end
- describe '#to_sql' do
- it "manufactures sql with an order clause" do
- ActiveRelation::Relations::Order.new(@relation1, @attribute1).to_sql.should be_like("""
- SELECT `foo`.`name`, `foo`.`id`
- FROM `foo`
- ORDER BY `foo`.`id`
- """)
+ describe '#to_sql' do
+ it "manufactures sql with an order clause" do
+ Order.new(@relation1, @attribute1).to_sql.should be_like("""
+ SELECT `foo`.`name`, `foo`.`id`
+ FROM `foo`
+ ORDER BY `foo`.`id`
+ """)
+ end
end
end
-
-end \ No newline at end of file
+end
+ \ No newline at end of file
diff --git a/spec/active_relation/relations/projection_spec.rb b/spec/active_relation/relations/projection_spec.rb
index 6ffdeb8e09..8d6a093af2 100644
--- a/spec/active_relation/relations/projection_spec.rb
+++ b/spec/active_relation/relations/projection_spec.rb
@@ -1,34 +1,36 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Projection do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @attribute1 = @relation1[:id]
- @attribute2 = @relation2[:id]
- end
+module ActiveRelation
+ describe Projection do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @attribute1 = @relation1[:id]
+ @attribute2 = @relation2[:id]
+ end
- describe '==' do
- it "obtains if the relations and attributes are identical" do
- ActiveRelation::Relations::Projection.new(@relation1, @attribute1, @attribute2).should == ActiveRelation::Relations::Projection.new(@relation1, @attribute1, @attribute2)
- ActiveRelation::Relations::Projection.new(@relation1, @attribute1).should_not == ActiveRelation::Relations::Projection.new(@relation2, @attribute1)
- ActiveRelation::Relations::Projection.new(@relation1, @attribute1).should_not == ActiveRelation::Relations::Projection.new(@relation1, @attribute2)
+ describe '==' do
+ it "obtains if the relations and attributes are identical" do
+ Projection.new(@relation1, @attribute1, @attribute2).should == Projection.new(@relation1, @attribute1, @attribute2)
+ Projection.new(@relation1, @attribute1).should_not == Projection.new(@relation2, @attribute1)
+ Projection.new(@relation1, @attribute1).should_not == Projection.new(@relation1, @attribute2)
+ end
end
- end
- describe '#qualify' do
- it "distributes over the relation and attributes" do
- ActiveRelation::Relations::Projection.new(@relation1, @attribute1).qualify. \
- should == ActiveRelation::Relations::Projection.new(@relation1.qualify, @attribute1.qualify)
+ describe '#qualify' do
+ it "distributes over the relation and attributes" do
+ Projection.new(@relation1, @attribute1).qualify. \
+ should == Projection.new(@relation1.qualify, @attribute1.qualify)
+ end
end
- end
- describe '#to_sql' do
- it "manufactures sql with a limited select clause" do
- ActiveRelation::Relations::Projection.new(@relation1, @attribute1).to_sql.should be_like("""
- SELECT `foo`.`id`
- FROM `foo`
- """)
+ describe '#to_sql' do
+ it "manufactures sql with a limited select clause" do
+ Projection.new(@relation1, @attribute1).to_sql.should be_like("""
+ SELECT `foo`.`id`
+ FROM `foo`
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/relations/range_spec.rb b/spec/active_relation/relations/range_spec.rb
index d4107259aa..f417626fed 100644
--- a/spec/active_relation/relations/range_spec.rb
+++ b/spec/active_relation/relations/range_spec.rb
@@ -1,30 +1,31 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Range do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @range1 = 1..2
- @range2 = 4..9
- end
+module ActiveRelation
+ describe Range do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @range1 = 1..2
+ @range2 = 4..9
+ end
- describe '#qualify' do
- it "distributes over the relation and attributes" do
- pending
+ describe '#qualify' do
+ it "distributes over the relation and attributes" do
+ pending
+ end
end
- end
- describe '#to_sql' do
- it "manufactures sql with limit and offset" do
- range_size = @range2.last - @range2.first + 1
- range_start = @range2.first
- ActiveRelation::Relations::Range.new(@relation1, @range2).to_s.should be_like("""
- SELECT `foo`.`name`, `foo`.`id`
- FROM `foo`
- LIMIT #{range_size}
- OFFSET #{range_start}
- """)
+ describe '#to_sql' do
+ it "manufactures sql with limit and offset" do
+ range_size = @range2.last - @range2.first + 1
+ range_start = @range2.first
+ Range.new(@relation1, @range2).to_s.should be_like("""
+ SELECT `foo`.`name`, `foo`.`id`
+ FROM `foo`
+ LIMIT #{range_size}
+ OFFSET #{range_start}
+ """)
+ end
end
end
-
end \ No newline at end of file
diff --git a/spec/active_relation/relations/relation_spec.rb b/spec/active_relation/relations/relation_spec.rb
new file mode 100644
index 0000000000..72b7d14389
--- /dev/null
+++ b/spec/active_relation/relations/relation_spec.rb
@@ -0,0 +1,104 @@
+require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
+
+module ActiveRelation
+ describe Relation do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @attribute1 = Attribute.new(@relation1, :id)
+ @attribute2 = Attribute.new(@relation1, :name)
+ end
+
+ describe '[]' do
+ it "manufactures an attribute when given a symbol" do
+ @relation1[:id].should == Attribute.new(@relation1, :id)
+ end
+
+ it "manufactures a range relation when given a range" do
+ @relation1[1..2].should == Range.new(@relation1, 1..2)
+ end
+ end
+
+ describe '#include?' do
+ it "manufactures an inclusion predicate" do
+ @relation1.include?(@attribute1).should be_kind_of(RelationInclusion)
+ end
+ end
+
+ describe 'read operations' do
+ describe 'joins' do
+ before do
+ @predicate = @relation1[:id].equals(@relation2[:id])
+ end
+
+ describe '#join' do
+ it "manufactures an inner join operation between those two relations" do
+ @relation1.join(@relation2).on(@predicate).should == Join.new("INNER JOIN", @relation1, @relation2, @predicate)
+ end
+ end
+
+ describe '#outer_join' do
+ it "manufactures a left outer join operation between those two relations" do
+ @relation1.outer_join(@relation2).on(@predicate).should == Join.new("LEFT OUTER JOIN", @relation1, @relation2, @predicate)
+ end
+ end
+ end
+
+ describe '#project' do
+ it "collapses identical projections" do
+ pending
+ end
+
+ it "manufactures a projection relation" do
+ @relation1.project(@attribute1, @attribute2).should == Projection.new(@relation1, @attribute1, @attribute2)
+ end
+ end
+
+ describe '#as' do
+ it "manufactures an alias relation" do
+ @relation1.as(:thucydides).should == Alias.new(@relation1, :thucydides)
+ end
+ end
+
+ describe '#rename' do
+ it "manufactures a rename relation" do
+ @relation1.rename(@attribute1, :foo).should == Rename.new(@relation1, @attribute1 => :foo)
+ end
+ end
+
+ describe '#select' do
+ before do
+ @predicate = Equality.new(@attribute1, @attribute2)
+ end
+
+ it "manufactures a selection relation" do
+ @relation1.select(@predicate).should == Selection.new(@relation1, @predicate)
+ end
+
+ it "accepts arbitrary strings" do
+ @relation1.select("arbitrary").should == Selection.new(@relation1, "arbitrary")
+ end
+ end
+
+ describe '#order' do
+ it "manufactures an order relation" do
+ @relation1.order(@attribute1, @attribute2).should be_kind_of(Order)
+ end
+ end
+ end
+
+ describe 'write operations' do
+ describe '#delete' do
+ it 'manufactures a deletion relation' do
+ @relation1.delete.should be_kind_of(Deletion)
+ end
+ end
+
+ describe '#insert' do
+ it 'manufactures an insertion relation' do
+ @relation1.insert(record = {:id => 1}).should be_kind_of(Insertion)
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/active_relation/relations/rename_spec.rb b/spec/active_relation/relations/rename_spec.rb
index bdc5c97492..3f8d5e3dbd 100644
--- a/spec/active_relation/relations/rename_spec.rb
+++ b/spec/active_relation/relations/rename_spec.rb
@@ -1,61 +1,63 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Rename do
- before do
- @relation = ActiveRelation::Relations::Table.new(:foo)
- @renamed_relation = ActiveRelation::Relations::Rename.new(@relation, @relation[:id] => :schmid)
- end
-
- describe '#initialize' do
- it "manufactures nested rename relations if multiple renames are provided" do
- ActiveRelation::Relations::Rename.new(@relation, @relation[:id] => :humpty, @relation[:name] => :dumpty). \
- should == ActiveRelation::Relations::Rename.new(ActiveRelation::Relations::Rename.new(@relation, @relation[:id] => :humpty), @relation[:name] => :dumpty)
+module ActiveRelation
+ describe Rename do
+ before do
+ @relation = Table.new(:foo)
+ @renamed_relation = Rename.new(@relation, @relation[:id] => :schmid)
end
- it "raises an exception if the rename provided is already used" do
- pending
+ describe '#initialize' do
+ it "manufactures nested rename relations if multiple renames are provided" do
+ Rename.new(@relation, @relation[:id] => :humpty, @relation[:name] => :dumpty). \
+ should == Rename.new(Rename.new(@relation, @relation[:id] => :humpty), @relation[:name] => :dumpty)
+ end
+
+ it "raises an exception if the rename provided is already used" do
+ pending
+ end
end
- end
- describe '==' do
- it "obtains if the relation, attribute, and rename are identical" do
- pending
+ describe '==' do
+ it "obtains if the relation, attribute, and rename are identical" do
+ pending
+ end
end
- end
- describe '#attributes' do
- it "manufactures a list of attributes with the renamed attribute renameed" do
- ActiveRelation::Relations::Rename.new(@relation, @relation[:id] => :schmid).attributes.should ==
- (@relation.attributes - [@relation[:id]]) + [@relation[:id].as(:schmid)]
+ describe '#attributes' do
+ it "manufactures a list of attributes with the renamed attribute renameed" do
+ Rename.new(@relation, @relation[:id] => :schmid).attributes.should ==
+ (@relation.attributes - [@relation[:id]]) + [@relation[:id].as(:schmid)]
+ end
end
- end
- describe '[]' do
- it 'indexes attributes by rename' do
- @renamed_relation[:id].should be_nil
- @renamed_relation[:schmid].should == @relation[:id].as(:schmid)
+ describe '[]' do
+ it 'indexes attributes by rename' do
+ @renamed_relation[:id].should be_nil
+ @renamed_relation[:schmid].should == @relation[:id].as(:schmid)
+ end
end
- end
- describe '#schmattribute' do
- it "should be renamed" do
- pending
+ describe '#schmattribute' do
+ it "should be renamed" do
+ pending
+ end
end
- end
- describe '#qualify' do
- it "distributes over the relation and renames" do
- ActiveRelation::Relations::Rename.new(@relation, @relation[:id] => :schmid).qualify. \
- should == ActiveRelation::Relations::Rename.new(@relation.qualify, @relation[:id].qualify => :schmid)
+ describe '#qualify' do
+ it "distributes over the relation and renames" do
+ Rename.new(@relation, @relation[:id] => :schmid).qualify. \
+ should == Rename.new(@relation.qualify, @relation[:id].qualify => :schmid)
+ end
end
- end
- describe '#to_sql' do
- it 'manufactures sql renameing the attribute' do
- @renamed_relation.to_sql.should be_like("""
- SELECT `foo`.`name`, `foo`.`id` AS 'schmid'
- FROM `foo`
- """)
+ describe '#to_sql' do
+ it 'manufactures sql renameing the attribute' do
+ @renamed_relation.to_sql.should be_like("""
+ SELECT `foo`.`name`, `foo`.`id` AS 'schmid'
+ FROM `foo`
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/relations/selection_spec.rb b/spec/active_relation/relations/selection_spec.rb
index 90dc3169b6..95d9e68625 100644
--- a/spec/active_relation/relations/selection_spec.rb
+++ b/spec/active_relation/relations/selection_spec.rb
@@ -1,42 +1,44 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Selection do
- before do
- @relation1 = ActiveRelation::Relations::Table.new(:foo)
- @relation2 = ActiveRelation::Relations::Table.new(:bar)
- @predicate1 = ActiveRelation::Predicates::Equality.new(@relation1[:id], @relation2[:foo_id])
- @predicate2 = ActiveRelation::Predicates::LessThan.new(@relation1[:age], 2)
- end
-
- describe '#initialize' do
- it "manufactures nested selection relations if multiple predicates are provided" do
- ActiveRelation::Relations::Selection.new(@relation1, @predicate1, @predicate2). \
- should == ActiveRelation::Relations::Selection.new(ActiveRelation::Relations::Selection.new(@relation1, @predicate2), @predicate1)
+module ActiveRelation
+ describe Selection do
+ before do
+ @relation1 = Table.new(:foo)
+ @relation2 = Table.new(:bar)
+ @predicate1 = Equality.new(@relation1[:id], @relation2[:foo_id])
+ @predicate2 = LessThan.new(@relation1[:age], 2)
end
- end
- describe '#qualify' do
- it "distributes over the relation and predicates" do
- ActiveRelation::Relations::Selection.new(@relation1, @predicate1).qualify. \
- should == ActiveRelation::Relations::Selection.new(@relation1.qualify, @predicate1.qualify)
+ describe '#initialize' do
+ it "manufactures nested selection relations if multiple predicates are provided" do
+ Selection.new(@relation1, @predicate1, @predicate2). \
+ should == Selection.new(Selection.new(@relation1, @predicate2), @predicate1)
+ end
end
- end
- describe '#to_sql' do
- it "manufactures sql with where clause conditions" do
- ActiveRelation::Relations::Selection.new(@relation1, @predicate1).to_sql.should be_like("""
- SELECT `foo`.`name`, `foo`.`id`
- FROM `foo`
- WHERE `foo`.`id` = `bar`.`foo_id`
- """)
+ describe '#qualify' do
+ it "distributes over the relation and predicates" do
+ Selection.new(@relation1, @predicate1).qualify. \
+ should == Selection.new(@relation1.qualify, @predicate1.qualify)
+ end
end
+
+ describe '#to_sql' do
+ it "manufactures sql with where clause conditions" do
+ Selection.new(@relation1, @predicate1).to_sql.should be_like("""
+ SELECT `foo`.`name`, `foo`.`id`
+ FROM `foo`
+ WHERE `foo`.`id` = `bar`.`foo_id`
+ """)
+ end
- it "allows arbitrary sql" do
- ActiveRelation::Relations::Selection.new(@relation1, "asdf").to_sql.should be_like("""
- SELECT `foo`.`name`, `foo`.`id`
- FROM `foo`
- WHERE asdf
- """)
+ it "allows arbitrary sql" do
+ Selection.new(@relation1, "asdf").to_sql.should be_like("""
+ SELECT `foo`.`name`, `foo`.`id`
+ FROM `foo`
+ WHERE asdf
+ """)
+ end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/relations/table_spec.rb b/spec/active_relation/relations/table_spec.rb
index 1418ac203f..ec6e6e10bd 100644
--- a/spec/active_relation/relations/table_spec.rb
+++ b/spec/active_relation/relations/table_spec.rb
@@ -1,30 +1,32 @@
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
-describe ActiveRelation::Relations::Table do
- before do
- @relation = ActiveRelation::Relations::Table.new(:users)
- end
+module ActiveRelation
+ describe Table do
+ before do
+ @relation = Table.new(:users)
+ end
- describe '#to_sql' do
- it "manufactures a simple select query" do
- @relation.to_sql.should be_like("""
- SELECT `users`.`name`, `users`.`id`
- FROM `users`
- """)
+ describe '#to_sql' do
+ it "manufactures a simple select query" do
+ @relation.to_sql.should be_like("""
+ SELECT `users`.`name`, `users`.`id`
+ FROM `users`
+ """)
+ end
end
- end
- describe '#attributes' do
- it 'manufactures attributes corresponding to columns in the table' do
- pending
+ describe '#attributes' do
+ it 'manufactures attributes corresponding to columns in the table' do
+ pending
+ end
end
- end
- describe '#qualify' do
- it 'manufactures a rename relation with all attribute names qualified' do
- @relation.qualify.should == ActiveRelation::Relations::Rename.new(
- ActiveRelation::Relations::Rename.new(@relation, @relation[:id] => 'users.id'), @relation[:name] => 'users.name'
- )
+ describe '#qualify' do
+ it 'manufactures a rename relation with all attribute names qualified' do
+ @relation.qualify.should == Rename.new(
+ Rename.new(@relation, @relation[:id] => 'users.id'), @relation[:name] => 'users.name'
+ )
+ end
end
end
end \ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e799aed339..ab9a14f3bd 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -9,7 +9,7 @@ ActiveRecord::Base.configurations = {
'sql_algebra_test' => {
:adapter => 'mysql',
:username => 'root',
- :password => 'password',
+ :password => '',
:encoding => 'utf8',
:database => 'sql_algebra_test',
},
@@ -26,8 +26,5 @@ end
Spec::Runner.configure do |config|
config.include(BeLikeMatcher)
- config.include(ActiveRelation::Relations)
- config.include(ActiveRelation::Primitives)
- config.include(ActiveRelation::Predicates)
config.mock_with :rr
end \ No newline at end of file