aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/arel/relations/compound.rb2
-rw-r--r--lib/arel/relations/relation.rb158
-rw-r--r--spec/arel/unit/relations/projection_spec.rb21
-rw-r--r--spec/arel/unit/relations/relation_spec.rb14
4 files changed, 91 insertions, 104 deletions
diff --git a/lib/arel/relations/compound.rb b/lib/arel/relations/compound.rb
index 7367e60a2d..1658efd636 100644
--- a/lib/arel/relations/compound.rb
+++ b/lib/arel/relations/compound.rb
@@ -1,9 +1,7 @@
module Arel
class Compound < Relation
attr_reader :relation
-
hash_on :relation
-
delegate :joins, :selects, :orders, :groupings, :inserts, :taken,
:skipped, :name, :alias, :aggregation?, :column_for,
:engine, :name_for, :table, :relation_for,
diff --git a/lib/arel/relations/relation.rb b/lib/arel/relations/relation.rb
index 0b20985914..440e6c9db6 100644
--- a/lib/arel/relations/relation.rb
+++ b/lib/arel/relations/relation.rb
@@ -3,7 +3,58 @@ module Arel
def session
Session.new
end
+
+ def name_for(relation)
+ relation.name
+ end
+
+ def to_sql(formatter = Sql::SelectStatement.new(self))
+ formatter.select [
+ "SELECT #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }.join(', ')}",
+ "FROM #{table_sql(Sql::TableReference.new(self))}",
+ (joins(Sql::TableReference.new(self)) unless joins.blank? ),
+ ("WHERE #{selects.collect { |s| s.to_sql(Sql::WhereClause.new(self)) }.join("\n\tAND ")}" unless selects.blank? ),
+ ("ORDER BY #{orders.collect { |o| o.to_sql(Sql::OrderClause.new(self)) }.join(', ')}" unless orders.blank? ),
+ ("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank? ),
+ ("LIMIT #{taken}" unless taken.blank? ),
+ ("OFFSET #{skipped}" unless skipped.blank? )
+ ].compact.join("\n"), name
+ end
+ alias_method :to_s, :to_sql
+ def table_sql(formatter = Sql::TableReference.new(self))
+ if table.aggregation?
+ table.to_sql(Sql::TableReference.new(self))
+ else
+ table.table_sql(Sql::TableReference.new(self))
+ end
+ end
+
+ def inclusion_predicate_sql
+ "IN"
+ end
+
+ def call(connection = engine.connection)
+ results = connection.execute(to_sql)
+ rows = []
+ results.each do |row|
+ rows << attributes.zip(row).to_hash
+ end
+ rows
+ end
+
+ def bind(relation)
+ self
+ end
+
+ def christener
+ @christener ||= Sql::Christener.new
+ end
+
+ def aggregation?
+ false
+ end
+
module Enumerable
include ::Enumerable
@@ -17,7 +68,7 @@ module Arel
end
include Enumerable
- module Operations
+ module Operable
def join(other = nil, join_type = "INNER JOIN")
case other
when String
@@ -32,18 +83,7 @@ module Arel
def outer_join(other = nil)
join(other, "LEFT OUTER JOIN")
end
-
- def [](index)
- case index
- when Symbol, String
- attribute_for_name(index)
- when Attribute, Expression
- attribute_for_attribute(index)
- when Array
- index.collect { |i| self[i] }
- end
- end
-
+
def select(*predicates)
predicates.all?(&:blank?) ? self : Selection.new(self, *predicates)
end
@@ -72,7 +112,7 @@ module Arel
groupings.all?(&:blank?) ? self : Grouping.new(self, *groupings)
end
- module Writes
+ module Writable
def insert(record)
session.create Insertion.new(self, record); self
end
@@ -85,7 +125,7 @@ module Arel
session.delete Deletion.new(self); self
end
end
- include Writes
+ include Writable
JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
def on(*predicates)
@@ -93,82 +133,42 @@ module Arel
end
end
end
- include Operations
+ include Operable
- module Externalizable
- def aggregation?
- false
+ module AttributeAccessable
+ def [](index)
+ case index
+ when Symbol, String
+ attribute_for_name(index)
+ when Attribute, Expression
+ attribute_for_attribute(index)
+ when Array
+ index.collect { |i| self[i] }
+ end
end
- def name_for(relation)
- relation.name
- end
- end
- include Externalizable
-
- def to_sql(formatter = Sql::SelectStatement.new(self))
- formatter.select [
- "SELECT #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }.join(', ')}",
- "FROM #{table_sql(Sql::TableReference.new(self))}",
- (joins(Sql::TableReference.new(self)) unless joins.blank? ),
- ("WHERE #{selects.collect { |s| s.to_sql(Sql::WhereClause.new(self)) }.join("\n\tAND ")}" unless selects.blank? ),
- ("ORDER BY #{orders.collect { |o| o.to_sql(Sql::OrderClause.new(self)) }.join(', ')}" unless orders.blank? ),
- ("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank? ),
- ("LIMIT #{taken}" unless taken.blank? ),
- ("OFFSET #{skipped}" unless skipped.blank? )
- ].compact.join("\n"), name
- end
- alias_method :to_s, :to_sql
-
- def table_sql(formatter = Sql::TableReference.new(self))
- if table.aggregation?
- table.to_sql(Sql::TableReference.new(self))
- else
- table.table_sql(Sql::TableReference.new(self))
- end
- end
-
- def inclusion_predicate_sql
- "IN"
- end
-
- def call(connection = engine.connection)
- results = connection.execute(to_sql)
- rows = []
- results.each do |row|
- rows << attributes.zip(row).to_hash
- end
- rows
- end
-
- module AttributeAccessors
def attribute_for_name(name)
attributes.detect { |a| a.alias_or_name.to_s == name.to_s }
end
-
+
def attribute_for_attribute(attribute)
attributes.select { |a| a =~ attribute }.min do |a1, a2|
(attribute % a1).size <=> (attribute % a2).size
end
end
end
- include AttributeAccessors
-
- def bind(relation)
- self
- end
-
- def christener
- @christener ||= Sql::Christener.new
- end
+ include AttributeAccessable
- def attributes; [] end
- def selects; [] end
- def orders; [] end
- def inserts; [] end
- def groupings; [] end
- def joins(formatter = nil); nil end
- def taken; nil end
- def skipped; nil end
+ module DefaultOperations
+ def attributes; [] end
+ def selects; [] end
+ def orders; [] end
+ def inserts; [] end
+ def groupings; [] end
+ def joins(formatter = nil); nil end
+ def taken; nil end
+ def skipped; nil end
+ end
+ include DefaultOperations
end
end \ No newline at end of file
diff --git a/spec/arel/unit/relations/projection_spec.rb b/spec/arel/unit/relations/projection_spec.rb
index eedcf77952..0008858e08 100644
--- a/spec/arel/unit/relations/projection_spec.rb
+++ b/spec/arel/unit/relations/projection_spec.rb
@@ -70,21 +70,18 @@ module Arel
end
end
- describe Projection::Externalizable do
- describe '#aggregation?' do
- describe 'when the projections are attributes' do
- it 'returns false' do
- Projection.new(@relation, @attribute).should_not be_aggregation
- end
+ describe '#aggregation?' do
+ describe 'when the projections are attributes' do
+ it 'returns false' do
+ Projection.new(@relation, @attribute).should_not be_aggregation
end
-
- describe 'when the projections include an aggregation' do
- it "obtains" do
- Projection.new(@relation, @attribute.sum).should be_aggregation
- end
+ end
+
+ describe 'when the projections include an aggregation' do
+ it "obtains" do
+ Projection.new(@relation, @attribute.sum).should be_aggregation
end
end
-
end
end
end \ No newline at end of file
diff --git a/spec/arel/unit/relations/relation_spec.rb b/spec/arel/unit/relations/relation_spec.rb
index 3b8be55c7d..d9ae8e0742 100644
--- a/spec/arel/unit/relations/relation_spec.rb
+++ b/spec/arel/unit/relations/relation_spec.rb
@@ -23,16 +23,8 @@ module Arel
end
end
end
-
- describe Relation::Externalizable do
- describe '#aggregation?' do
- it "returns false" do
- @relation.should_not be_aggregation
- end
- end
- end
-
- describe Relation::Operations do
+
+ describe Relation::Operable do
describe 'joins' do
before do
@predicate = @relation[:id].eq(@relation[:id])
@@ -154,7 +146,7 @@ module Arel
end
end
- describe Relation::Operations::Writes do
+ describe Relation::Operable::Writable do
describe '#delete' do
it 'manufactures a deletion relation' do
Session.start do