aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorNick Kallen <nkallen@nick-kallens-computer-2.local>2008-01-16 22:55:06 -0800
committerNick Kallen <nkallen@nick-kallens-computer-2.local>2008-01-16 22:55:06 -0800
commitb47ac80a17d7a74e1b5deac0e63a72960a4da453 (patch)
treede13e27979148c8a39c396298cc789348d4acb2e /lib
parentb5a2057fcd5dfcac3682a565f2ba15281f5dcbb2 (diff)
downloadrails-b47ac80a17d7a74e1b5deac0e63a72960a4da453.tar.gz
rails-b47ac80a17d7a74e1b5deac0e63a72960a4da453.tar.bz2
rails-b47ac80a17d7a74e1b5deac0e63a72960a4da453.zip
adding grouping functionality; added some dummy code ("Schmoin") for experimenting with aggregate joins. need to resolve the ambiguity in the #as operator between (SELECT * FROM foo AS bar) vs. (SELECT * FROM foo) AS bar
Diffstat (limited to 'lib')
-rw-r--r--lib/active_relation/primitives/aggregation.rb4
-rw-r--r--lib/active_relation/primitives/attribute.rb21
-rw-r--r--lib/active_relation/relations.rb2
-rw-r--r--lib/active_relation/relations/alias.rb9
-rw-r--r--lib/active_relation/relations/compound.rb3
-rw-r--r--lib/active_relation/relations/group.rb17
-rw-r--r--lib/active_relation/relations/order.rb2
-rw-r--r--lib/active_relation/relations/relation.rb6
-rw-r--r--lib/active_relation/relations/schmoin.rb43
9 files changed, 91 insertions, 16 deletions
diff --git a/lib/active_relation/primitives/aggregation.rb b/lib/active_relation/primitives/aggregation.rb
index 48f8946835..26348fb35e 100644
--- a/lib/active_relation/primitives/aggregation.rb
+++ b/lib/active_relation/primitives/aggregation.rb
@@ -6,6 +6,10 @@ module ActiveRelation
@attribute, @function_sql = attribute, function_sql
end
+ def substitute(new_relation)
+ Aggregation.new(attribute.substitute(new_relation), function_sql)
+ end
+
def to_sql(strategy = nil)
"#{function_sql}(#{attribute.to_sql})"
end
diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb
index 90bbe8012b..eb167b1a66 100644
--- a/lib/active_relation/primitives/attribute.rb
+++ b/lib/active_relation/primitives/attribute.rb
@@ -6,18 +6,25 @@ module ActiveRelation
@relation, @name, @alias = relation, name, aliaz
end
- def as(aliaz = nil)
- Attribute.new(relation, name, aliaz)
- end
+ module Transformations
+ def as(aliaz = nil)
+ Attribute.new(relation, name, aliaz)
+ end
+
+ def substitute(new_relation)
+ Attribute.new(new_relation, name, @alias)
+ end
+ def qualify
+ self.as(qualified_name)
+ end
+ end
+ include Transformations
+
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
diff --git a/lib/active_relation/relations.rb b/lib/active_relation/relations.rb
index 9ae8f16524..c9b9de93b2 100644
--- a/lib/active_relation/relations.rb
+++ b/lib/active_relation/relations.rb
@@ -2,6 +2,8 @@ require 'active_relation/relations/relation'
require 'active_relation/relations/compound'
require 'active_relation/relations/table'
require 'active_relation/relations/join'
+require 'active_relation/relations/schmoin'
+require 'active_relation/relations/group'
require 'active_relation/relations/projection'
require 'active_relation/relations/selection'
require 'active_relation/relations/order'
diff --git a/lib/active_relation/relations/alias.rb b/lib/active_relation/relations/alias.rb
index 63a92ccba1..f40e51475e 100644
--- a/lib/active_relation/relations/alias.rb
+++ b/lib/active_relation/relations/alias.rb
@@ -8,7 +8,7 @@ module ActiveRelation
end
def attributes
- relation.attributes.collect(&method(:substitute))
+ relation.attributes.collect { |attribute| attribute.substitute(self) }
end
def ==(other)
@@ -22,13 +22,8 @@ module ActiveRelation
def attribute(name)
if unaliased_attribute = relation[name]
- substitute(unaliased_attribute)
+ unaliased_attribute.substitute(self)
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/compound.rb b/lib/active_relation/relations/compound.rb
index d6da8eb8fa..bbc7ff1bae 100644
--- a/lib/active_relation/relations/compound.rb
+++ b/lib/active_relation/relations/compound.rb
@@ -2,6 +2,7 @@ module ActiveRelation
class Compound < Relation
attr_reader :relation
- delegate :attributes, :attribute, :joins, :selects, :orders, :table_sql, :inserts, :limit, :offset, :to => :relation
+ delegate :attributes, :attribute, :joins, :selects, :orders, :groupings, :table_sql, :inserts, :limit, :offset,
+ :to => :relation
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/group.rb b/lib/active_relation/relations/group.rb
new file mode 100644
index 0000000000..bc363970c7
--- /dev/null
+++ b/lib/active_relation/relations/group.rb
@@ -0,0 +1,17 @@
+module ActiveRelation
+ class Group < Compound
+ attr_reader :groupings
+
+ def initialize(relation, *groupings)
+ @relation, @groupings = relation, groupings
+ end
+
+ def ==(other)
+ relation == other.relation and groupings == other.groupings
+ end
+
+ def qualify
+ Group.new(relation.qualify, *groupings.collect(&:qualify))
+ 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 d5c2a54cd1..688207f7a9 100644
--- a/lib/active_relation/relations/order.rb
+++ b/lib/active_relation/relations/order.rb
@@ -11,7 +11,7 @@ module ActiveRelation
end
def qualify
- Order.new(relation.qualify, *orders.collect { |o| o.qualify })
+ Order.new(relation.qualify, *orders.collect(&:qualify))
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
index 663450e69c..18ba5491b1 100644
--- a/lib/active_relation/relations/relation.rb
+++ b/lib/active_relation/relations/relation.rb
@@ -64,6 +64,10 @@ module ActiveRelation
def delete
Deletion.new(self)
end
+
+ def group(*attributes)
+ Group.new(self, *attributes)
+ end
JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
def on(*predicates)
@@ -80,6 +84,7 @@ module ActiveRelation
(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?),
+ ("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank?),
("LIMIT #{limit.to_sql}" unless limit.blank?),
("OFFSET #{offset.to_sql}" unless offset.blank?)
].compact.join("\n")
@@ -95,6 +100,7 @@ module ActiveRelation
def selects; [] end
def orders; [] end
def inserts; [] end
+ def groupings; [] end
def joins; nil end
def limit; nil end
def offset; nil end
diff --git a/lib/active_relation/relations/schmoin.rb b/lib/active_relation/relations/schmoin.rb
new file mode 100644
index 0000000000..398cfb7b28
--- /dev/null
+++ b/lib/active_relation/relations/schmoin.rb
@@ -0,0 +1,43 @@
+module ActiveRelation
+ class Schmoin < 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
+ Schmoin.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