diff --git a/lib/rebel/sql.rb b/lib/rebel/sql.rb index 40cf33e..0aa81e2 100644 --- a/lib/rebel/sql.rb +++ b/lib/rebel/sql.rb @@ -13,14 +13,14 @@ module Rebel::SQL exec(Rebel::SQL.drop_table(table_name)) end - def select(*fields, from: nil, where: nil, inner: nil, left: nil, right: nil, order_by: nil, limit: nil) + def select(*fields, from: nil, where: nil, inner: nil, left: nil, right: nil, order: nil, limit: nil) exec(Rebel::SQL.select(*fields, from: from, where: where, inner: inner, left: left, right: right, - order_by: order_by, + order: order, limit: limit)) end @@ -52,6 +52,10 @@ module Rebel::SQL Rebel::SQL.outer_join(table, on: on) end + def by(*clause) + Rebel::SQL.by(clause) + end + class Raw < String def wants_parens! @wants_parens = true @@ -143,6 +147,18 @@ module Rebel::SQL def like(n) Raw.new("#{self} LIKE #{Rebel::SQL.value(n)}") end + + def asc + Raw.new("#{self} ASC") + end + + def desc + Raw.new("#{self} DESC") + end + + def by(*clause) + Raw.new(Rebel::SQL.list(self, Rebel::SQL.names(*clause))) + end end @identifier_quote = '"' @@ -180,14 +196,14 @@ module Rebel::SQL SQL end - def select(*fields, from: nil, where: nil, inner: nil, left: nil, right: nil, order_by: nil, limit: nil) + def select(*fields, from: nil, where: nil, inner: nil, left: nil, right: nil, order: nil, limit: nil) <<-SQL SELECT #{names(*fields)} FROM #{name(from)} #{inner?(inner)} #{left?(left)} #{right?(right)} #{where?(where)} - #{order_by?(order_by)} + #{order?(order)} #{limit?(limit)}; SQL end @@ -259,6 +275,11 @@ module Rebel::SQL raw(right? outer_join(table, on: on)) end + def by(clause) + raw("BY #{names(*clause)}") + end + + ## Support def name(name) @@ -308,26 +329,10 @@ module Rebel::SQL "#{name_or_value(l)} = #{name_or_value(r)}" end - def order(l, r) - "#{name(l)} #{value(raw(r.to_s))}" - end - def assign_clause(clause) list(clause.map { |k, v| equal(k, v) }) end - def order_by_clause(clause) - case clause - when Symbol, String - order_by_clause(name(clause) => nil) - when Hash - list(clause.map { |k, v| order(k, v) }) - when Array - list(clause.map { |c| order_by_clause(c) }) - else raise NotImplementedError, clause.class - end - end - def clause_term(left, right) case right when Array @@ -365,8 +370,8 @@ module Rebel::SQL join ? "RIGHT #{join}" : nil end - def order_by?(*clause) - clause.any? ? "ORDER BY #{order_by_clause(*clause)}" : nil + def order?(clause) + clause ? "ORDER #{clause}" : nil end def limit?(count) diff --git a/test/test_exec.rb b/test/test_exec.rb index 66fb0f1..1b95d06 100644 --- a/test/test_exec.rb +++ b/test/test_exec.rb @@ -59,8 +59,8 @@ class TestExec < Minitest::Test insert_into :foo, id: 1, value: '2', col: 'whatevs' insert_into :foo, id: 2, value: '2', col: 'something' insert_into :foo, id: 3, value: '1', col: 'else' - assert_equal(select(:id, from: :foo, order_by: :col), [[3], [2], [1]]) - assert_equal(select(:id, from: :foo, order_by: {id: :desc}), [[3], [2], [1]]) - assert_equal(select(:id, from: :foo, order_by: [value: :asc, id: :asc]), [[3], [1], [2]]) + assert_equal(select(:id, from: :foo, order: by(:id).desc), [[3], [2], [1]]) + assert_equal(select(:id, from: :foo, order: by(:value, :id).asc), [[3], [1], [2]]) + assert_equal(select(:id, from: :foo, order: by(:value).asc.by(:id).desc), [[3], [2], [1]]) end end diff --git a/test/test_raw.rb b/test/test_raw.rb index d28f7a9..6ad1a1d 100644 --- a/test/test_raw.rb +++ b/test/test_raw.rb @@ -96,4 +96,18 @@ class TestRaw < Minitest::Test assert_str_equal(Rebel::SQL.value(DateTime.new(2016, 12, 31, 23, 59, 59)), "'2016-12-31T23:59:59+00:00'") assert_str_equal(Rebel::SQL.value(nil), 'NULL') end + + def test_asc + assert_str_equal(Rebel::SQL.raw("'FOO'").asc, "'FOO' ASC") + end + + def test_desc + assert_str_equal(Rebel::SQL.raw("'FOO'").desc, "'FOO' DESC") + end + + def test_by + assert_str_equal(Rebel::SQL.by(:foo), 'BY "foo"') + assert_str_equal(Rebel::SQL.by(:foo).desc, 'BY "foo" DESC') + assert_str_equal(Rebel::SQL.by(:foo).desc.by(:bar).asc, 'BY "foo" DESC, "bar" ASC') + end end