diff options
-rw-r--r-- | lib/arel/attributes/attribute.rb | 8 | ||||
-rw-r--r-- | lib/arel/nodes.rb | 1 | ||||
-rw-r--r-- | lib/arel/nodes/ordering.rb | 19 | ||||
-rw-r--r-- | lib/arel/visitors/dot.rb | 5 | ||||
-rw-r--r-- | lib/arel/visitors/to_sql.rb | 4 | ||||
-rw-r--r-- | spec/attributes/attribute_spec.rb | 32 | ||||
-rw-r--r-- | spec/visitors/to_sql_spec.rb | 9 |
7 files changed, 78 insertions, 0 deletions
diff --git a/lib/arel/attributes/attribute.rb b/lib/arel/attributes/attribute.rb index 25ffe717b2..ba18533590 100644 --- a/lib/arel/attributes/attribute.rb +++ b/lib/arel/attributes/attribute.rb @@ -151,6 +151,14 @@ module Arel grouping_all :lteq, others end + def asc + Nodes::Ordering.new self, :asc + end + + def desc + Nodes::Ordering.new self, :desc + end + private def grouping_any method_id, others diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 0063ed1cd5..47cbd64eb5 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -15,6 +15,7 @@ require 'arel/nodes/does_not_match' require 'arel/nodes/in' require 'arel/nodes/not_in' +require 'arel/nodes/ordering' require 'arel/nodes/lock' require 'arel/nodes/function' require 'arel/nodes/count' diff --git a/lib/arel/nodes/ordering.rb b/lib/arel/nodes/ordering.rb new file mode 100644 index 0000000000..d395c8631d --- /dev/null +++ b/lib/arel/nodes/ordering.rb @@ -0,0 +1,19 @@ +module Arel + module Nodes + class Ordering < Arel::Nodes::Node + attr_accessor :expr, :direction + + def initialize expression, direction = :asc + @expr, @direction = expression, direction + end + + def ascending? + direction == :asc + end + + def descending? + direction == :desc + end + end + end +end diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb index 655c75aab9..5202c5127e 100644 --- a/lib/arel/visitors/dot.rb +++ b/lib/arel/visitors/dot.rb @@ -32,6 +32,11 @@ module Arel visit_edge o, "expr" end + def visit_Arel_Nodes_Ordering o + visit_edge o, "expr" + visit_edge o, "direction" + end + def visit_Arel_Nodes_TableAlias o visit_edge o, "name" visit_edge o, "relation" diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 405578f604..17779b4037 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -107,6 +107,10 @@ module Arel "(#{visit o.expr})" end + def visit_Arel_Nodes_Ordering o + "#{visit o.expr} #{o.descending? ? 'DESC' : 'ASC'}" + end + def visit_Arel_Nodes_Group o visit o.expr end diff --git a/spec/attributes/attribute_spec.rb b/spec/attributes/attribute_spec.rb index c6d4fcebd4..562781ade9 100644 --- a/spec/attributes/attribute_spec.rb +++ b/spec/attributes/attribute_spec.rb @@ -601,6 +601,38 @@ module Arel } end end + + describe '#asc' do + it 'should create an Ordering node' do + relation = Table.new(:users) + relation[:id].asc.should be_kind_of Nodes::Ordering + end + + it 'should generate ASC in sql' do + relation = Table.new(:users) + mgr = relation.project relation[:id] + mgr.order relation[:id].asc + mgr.to_sql.should be_like %{ + SELECT "users"."id" FROM "users" ORDER BY "users"."id" ASC + } + end + end + + describe '#desc' do + it 'should create an Ordering node' do + relation = Table.new(:users) + relation[:id].desc.should be_kind_of Nodes::Ordering + end + + it 'should generate DESC in sql' do + relation = Table.new(:users) + mgr = relation.project relation[:id] + mgr.order relation[:id].desc + mgr.to_sql.should be_like %{ + SELECT "users"."id" FROM "users" ORDER BY "users"."id" DESC + } + end + end end describe 'equality' do diff --git a/spec/visitors/to_sql_spec.rb b/spec/visitors/to_sql_spec.rb index 1302d73e1c..a2862e4c4f 100644 --- a/spec/visitors/to_sql_spec.rb +++ b/spec/visitors/to_sql_spec.rb @@ -66,6 +66,15 @@ module Arel @visitor.accept(test).should be_like %{ "users"."id" = 't' } end + describe "Nodes::Ordering" do + it "should know how to visit" do + node = @attr.desc + @visitor.accept(node).should be_like %{ + "users"."id" DESC + } + end + end + describe "Nodes::In" do it "should know how to visit" do node = @attr.in [1, 2, 3] |