diff --git a/lib/rebel/sql.rb b/lib/rebel/sql.rb index 0f59724..3deaccd 100644 --- a/lib/rebel/sql.rb +++ b/lib/rebel/sql.rb @@ -13,7 +13,7 @@ module Rebel::SQL exec(Rebel::SQL.drop_table(table_name)) end - def select(*fields, distinct: distinct, from: nil, where: nil, inner: nil, left: nil, right: nil, limit: nil, offset: nil) + def select(*fields, distinct: distinct, from: nil, where: nil, inner: nil, left: nil, right: nil, group: nil, order: nil, limit: nil, offset: nil) exec(Rebel::SQL.select(*fields, distinct: distinct, from: from, @@ -21,6 +21,8 @@ module Rebel::SQL inner: inner, left: left, right: right, + group: group, + order: order, limit: limit, offset: offset)) end @@ -88,6 +90,18 @@ module Rebel::SQL clause.any? ? on(*clause) : self end + def having(*clause) + Raw.new(self + " HAVING #{Rebel::SQL.and_clause(*clause)}") + end + + def asc + Raw.new(self + " ASC") + end + + def desc + Raw.new(self + " DESC") + end + def and(*clause) Raw.new("#{self.parens?} AND #{Rebel::SQL.and_clause(*clause)}") end @@ -181,7 +195,7 @@ module Rebel::SQL SQL end - def select(*fields, distinct: nil, from: nil, where: nil, inner: nil, left: nil, right: nil, limit: nil, offset: nil) + def select(*fields, distinct: nil, from: nil, where: nil, inner: nil, left: nil, right: nil, group: nil, order: nil, limit: nil, offset: nil) raw <<-SQL SELECT #{distinct ? "DISTINCT #{names(*distinct)}" : names(*fields)} #{from?(from)} @@ -189,6 +203,8 @@ module Rebel::SQL #{left?(left)} #{right?(right)} #{where?(where)} + #{group?(group)} + #{order?(order)} #{limit?(limit, offset)} SQL end @@ -236,6 +252,10 @@ module Rebel::SQL end alias fn function + def by(*n) + raw("BY #{names(*n)}") + end + def count(*n) raw("COUNT(#{names(*n)})") end @@ -354,6 +374,14 @@ module Rebel::SQL join ? "RIGHT #{join}" : nil end + def group?(group) + group ? "GROUP #{name(group)}" : nil + end + + def order?(order) + order ? "ORDER #{name(order)}" : nil + end + def limit?(limit, offset) limit ? "LIMIT #{value(limit)}" << (offset ? " OFFSET #{offset}" : "") : nil end diff --git a/test/test_raw.rb b/test/test_raw.rb index 2b9f3c9..b159468 100644 --- a/test/test_raw.rb +++ b/test/test_raw.rb @@ -117,6 +117,34 @@ class TestRaw < Minitest::Test assert_str_equal(Rebel::SQL.select(distinct: [:bar, :baz], from: :foo).gsub(/\s+/, ' ').strip, 'SELECT DISTINCT "bar", "baz" FROM "foo"') end + def test_select_group_by + assert_str_equal(Rebel::SQL.select(:bar, from: :foo, group: Rebel::SQL.by(:baz)).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" GROUP BY "baz"') + end + + def test_select_group_by_having + assert_str_equal(Rebel::SQL.select(:bar, from: :foo, group: Rebel::SQL.by(:baz).having(Rebel::SQL.count(:qux).gt(5))).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" GROUP BY "baz" HAVING COUNT("qux") > 5') + end + + def test_select_order_by + assert_str_equal(Rebel::SQL.select(:bar, from: :foo, order: Rebel::SQL.by(:baz)).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" ORDER BY "baz"') + end + + def test_select_order_by_asc + assert_str_equal(Rebel::SQL.select(:bar, from: :foo, order: Rebel::SQL.by(:baz).asc).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" ORDER BY "baz" ASC') + end + + def test_select_order_by_desc + assert_str_equal(Rebel::SQL.select(:bar, from: :foo, order: Rebel::SQL.by(:baz).desc).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" ORDER BY "baz" DESC') + end + + def test_select_multiple_order_by + assert_str_equal(Rebel::SQL.select(:bar, from: :foo, order: Rebel::SQL.by(:baz, :qux)).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" ORDER BY "baz", "qux"') + end + + def test_select_multiple_order_by_opposing + assert_str_equal(Rebel::SQL.select(:bar, from: :foo, order: Rebel::SQL.by(Rebel::SQL.name(:baz).asc, Rebel::SQL.name(:qux).desc)).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" ORDER BY "baz" ASC, "qux" DESC') + end + def test_select_limit assert_str_equal(Rebel::SQL.select(:bar, from: :foo, limit: 10).gsub(/\s+/, ' ').strip, 'SELECT "bar" FROM "foo" LIMIT 10') end