From a83efc5d5d94d50589a80bdd27ddf5b83ed39810 Mon Sep 17 00:00:00 2001 From: Nick Kallen Date: Sat, 12 Jan 2008 20:18:52 -0800 Subject: added aggregations --- lib/active_relation.rb | 3 +- lib/active_relation/primitives.rb | 3 + lib/active_relation/primitives/aggregation.rb | 21 ++++++ lib/active_relation/primitives/attribute.rb | 85 ++++++++++++++++++++++++ lib/active_relation/relations.rb | 1 - lib/active_relation/relations/attribute.rb | 60 ----------------- lib/active_relation/relations/table.rb | 2 +- spec/active_relation/relations/attribute_spec.rb | 40 ++++++++++- 8 files changed, 151 insertions(+), 64 deletions(-) create mode 100644 lib/active_relation/primitives.rb create mode 100644 lib/active_relation/primitives/aggregation.rb create mode 100644 lib/active_relation/primitives/attribute.rb delete mode 100644 lib/active_relation/relations/attribute.rb diff --git a/lib/active_relation.rb b/lib/active_relation.rb index cdac17facb..0b55ed74d0 100644 --- a/lib/active_relation.rb +++ b/lib/active_relation.rb @@ -6,5 +6,6 @@ require 'activerecord' require 'active_relation/sql_builder' require 'active_relation/extensions' +require 'active_relation/predicates' require 'active_relation/relations' -require 'active_relation/predicates' \ No newline at end of file +require 'active_relation/primitives' \ No newline at end of file diff --git a/lib/active_relation/primitives.rb b/lib/active_relation/primitives.rb new file mode 100644 index 0000000000..5d35f42564 --- /dev/null +++ b/lib/active_relation/primitives.rb @@ -0,0 +1,3 @@ +require 'active_relation/primitives/attribute' +require 'active_relation/primitives/aggregation' + diff --git a/lib/active_relation/primitives/aggregation.rb b/lib/active_relation/primitives/aggregation.rb new file mode 100644 index 0000000000..20fdcf46c5 --- /dev/null +++ b/lib/active_relation/primitives/aggregation.rb @@ -0,0 +1,21 @@ +module ActiveRelation + module Primitives + class Aggregation + include SqlBuilder + + attr_reader :attribute, :function_sql + + def initialize(attribute, function_sql) + @attribute, @function_sql = attribute, function_sql + end + + def to_sql(options = {}) + "#{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 +end \ No newline at end of file diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb new file mode 100644 index 0000000000..65ae12cf36 --- /dev/null +++ b/lib/active_relation/primitives/attribute.rb @@ -0,0 +1,85 @@ +module ActiveRelation + module Primitives + class Attribute + include SqlBuilder + + attr_reader :relation, :name, :alias + + def initialize(relation, name, aliaz = nil) + @relation, @name, @alias = relation, name, aliaz + end + + def alias(aliaz = nil) + aliaz ? Attribute.new(relation, name, aliaz) : @alias + end + + def qualified_name + "#{relation.table}.#{name}" + end + + def qualify + self.alias(qualified_name) + end + + def ==(other) + relation == other.relation and name == other.name and @alias == other.alias + 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 + 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 + end + include Aggregations + + def to_sql(options = {}) + "#{quote_table_name(relation.table)}.#{quote_column_name(name)}" + (options[:use_alias] && self.alias ? " AS #{self.alias.to_s.to_sql}" : "") + end + end + end +end \ No newline at end of file diff --git a/lib/active_relation/relations.rb b/lib/active_relation/relations.rb index f7d1bc207a..a25e82f607 100644 --- a/lib/active_relation/relations.rb +++ b/lib/active_relation/relations.rb @@ -2,7 +2,6 @@ require 'active_relation/relations/base' require 'active_relation/relations/compound' require 'active_relation/relations/table' require 'active_relation/relations/join' -require 'active_relation/relations/attribute' require 'active_relation/relations/projection' require 'active_relation/relations/selection' require 'active_relation/relations/order' diff --git a/lib/active_relation/relations/attribute.rb b/lib/active_relation/relations/attribute.rb deleted file mode 100644 index 2fe702cb14..0000000000 --- a/lib/active_relation/relations/attribute.rb +++ /dev/null @@ -1,60 +0,0 @@ -module ActiveRelation - module Primitives - class Attribute - include ::ActiveRelation::SqlBuilder - - attr_reader :relation, :name, :alias - - def initialize(relation, name, aliaz = nil) - @relation, @name, @alias = relation, name, aliaz - end - - def alias(aliaz = nil) - aliaz ? ActiveRelation::Primitives::Attribute.new(relation, name, aliaz) : @alias - end - - def qualified_name - "#{relation.table}.#{name}" - end - - def qualify - self.alias(qualified_name) - end - - def ==(other) - relation == other.relation and name == other.name and @alias == other.alias - end - - module Predications - def equals(other) - Predicates::Equality.new(self, other) - end - - def less_than(other) - Predicates::LessThan.new(self, other) - end - - def less_than_or_equal_to(other) - Predicates::LessThanOrEqualTo.new(self, other) - end - - def greater_than(other) - Predicates::GreaterThan.new(self, other) - end - - def greater_than_or_equal_to(other) - Predicates::GreaterThanOrEqualTo.new(self, other) - end - - def matches(regexp) - Predicates::Match.new(self, regexp) - end - end - include Predications - - def to_sql(options = {}) - "#{quote_table_name(relation.table)}.#{quote_column_name(name)}" + (options[:use_alias] && self.alias ? " AS #{self.alias.to_s.to_sql}" : "") - end - 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 38f540cc52..d642851687 100644 --- a/lib/active_relation/relations/table.rb +++ b/lib/active_relation/relations/table.rb @@ -23,7 +23,7 @@ module ActiveRelation private def attributes_by_name @attributes_by_name ||= connection.columns(table, "#{table} Columns").inject({}) do |attributes_by_name, column| - attributes_by_name.merge(column.name => ActiveRelation::Primitives::Attribute.new(self, column.name.to_sym)) + attributes_by_name.merge(column.name => Primitives::Attribute.new(self, column.name.to_sym)) end end diff --git a/spec/active_relation/relations/attribute_spec.rb b/spec/active_relation/relations/attribute_spec.rb index 28fb0c3754..2a6deca22a 100644 --- a/spec/active_relation/relations/attribute_spec.rb +++ b/spec/active_relation/relations/attribute_spec.rb @@ -56,7 +56,7 @@ describe ActiveRelation::Primitives::Attribute do end end - describe 'greater_than' do + describe '#greater_than' do it "manufactures a greater-than predicate" do @attribute1.greater_than(@attribute2).should == ActiveRelation::Predicates::GreaterThan.new(@attribute1, @attribute2) end @@ -74,4 +74,42 @@ describe ActiveRelation::Primitives::Attribute do 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") + end + end + + describe '#sum' do + it "manufactures a sum aggregation" do + @attribute1.sum.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "SUM") + end + end + + describe '#maximum' do + it "manufactures a maximum aggregation" do + @attribute1.maximum.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "MAX") + end + end + + describe '#minimum' do + it "manufactures a minimum aggregation" do + @attribute1.minimum.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "MIN") + end + end + + describe '#average' do + it "manufactures an average aggregation" do + @attribute1.average.should == ActiveRelation::Primitives::Aggregation.new(@attribute1, "AVG") + end + end + + + end end -- cgit v1.2.3