From 7b122f9a336c8c780dcc5a29074f17f3ec493dc6 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Sep 2010 15:08:00 -0700 Subject: [PATCH] adding maximum nodes --- lib/arel/attributes/attribute.rb | 4 ++++ lib/arel/nodes.rb | 1 + lib/arel/nodes/max.rb | 22 ++++++++++++++++++++++ lib/arel/visitors/to_sql.rb | 5 +++++ spec/arel/attributes/attribute_spec.rb | 17 +++++++++++++++++ spec/arel/nodes/sum_spec.rb | 12 ++++++++++++ 6 files changed, 61 insertions(+) create mode 100644 lib/arel/nodes/max.rb create mode 100644 spec/arel/nodes/sum_spec.rb diff --git a/lib/arel/attributes/attribute.rb b/lib/arel/attributes/attribute.rb index af9bbdd478..bb85af4634 100644 --- a/lib/arel/attributes/attribute.rb +++ b/lib/arel/attributes/attribute.rb @@ -16,6 +16,10 @@ def count distinct = false def sum Nodes::Sum.new [self], Nodes::SqlLiteral.new('sum_id') end + + def maximum + Nodes::Max.new [self], Nodes::SqlLiteral.new('max_id') + end end class String < Attribute; end diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 24a71c54a2..28b9e61fb6 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -6,6 +6,7 @@ require 'arel/nodes/in' require 'arel/nodes/count' require 'arel/nodes/sum' +require 'arel/nodes/max' require 'arel/nodes/sql_literal' require 'arel/nodes/select_core' require 'arel/nodes/select_statement' diff --git a/lib/arel/nodes/max.rb b/lib/arel/nodes/max.rb new file mode 100644 index 0000000000..1766c56058 --- /dev/null +++ b/lib/arel/nodes/max.rb @@ -0,0 +1,22 @@ +module Arel + module Nodes + class Max + attr_accessor :expressions, :alias + + def initialize expr, aliaz = nil + @expressions = expr + @alias = aliaz + end + + def as aliaz + self.alias = SqlLiteral.new(aliaz) + self + end + + def to_sql + viz = Visitors::ToSql.new Table.engine + viz.accept self + end + end + end +end diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 2a96444d59..e1cf0f3778 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -76,6 +76,11 @@ def visit_Arel_Nodes_Sum o visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}" end + def visit_Arel_Nodes_Max o + "MAX(#{o.expressions.map { |x| + visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}" + end + def visit_Arel_Nodes_TableAlias o "#{visit o.relation} #{quote_table_name o.name}" end diff --git a/spec/arel/attributes/attribute_spec.rb b/spec/arel/attributes/attribute_spec.rb index 018f23ea9f..449cc38dad 100644 --- a/spec/arel/attributes/attribute_spec.rb +++ b/spec/arel/attributes/attribute_spec.rb @@ -3,6 +3,23 @@ module Arel module Attributes describe 'attribute' do + describe '#maximum' do + it 'should create a MAX node' do + relation = Table.new(:users) + relation[:id].maximum.should be_kind_of Nodes::Max + end + + # FIXME: backwards compat. Is this really necessary? + it 'should set the alias to "max_id"' do + relation = Table.new(:users) + mgr = relation.project relation[:id].maximum + mgr.to_sql.should be_like %{ + SELECT MAX("users"."id") AS max_id + FROM "users" + } + end + end + describe '#sum' do it 'should create a SUM node' do relation = Table.new(:users) diff --git a/spec/arel/nodes/sum_spec.rb b/spec/arel/nodes/sum_spec.rb new file mode 100644 index 0000000000..7691b06590 --- /dev/null +++ b/spec/arel/nodes/sum_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe Arel::Nodes::Sum do + describe "as" do + it 'should alias the sum' do + table = Arel::Table.new :users + table[:id].sum.as('foo').to_sql.should be_like %{ + SUM("users"."id") AS foo + } + end + end +end -- GitLab