diff --git a/lib/rebel/sql.rb b/lib/rebel/sql.rb index d3d980e..b425f6b 100644 --- a/lib/rebel/sql.rb +++ b/lib/rebel/sql.rb @@ -13,13 +13,15 @@ module Rebel::SQL exec(Rebel::SQL.drop_table(table_name)) end - def select(*fields, from: nil, where: nil, inner: nil, left: nil, right: 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)) + right: right, + order: order, + limit: limit)) end def insert_into(table_name, *rows) @@ -50,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 @@ -141,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 = '"' @@ -178,13 +196,15 @@ module Rebel::SQL SQL end - def select(*fields, from: nil, where: nil, inner: nil, left: nil, right: 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)}; + #{where?(where)} + #{order?(order)} + #{limit?(limit)}; SQL end @@ -255,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) @@ -344,5 +369,13 @@ module Rebel::SQL def right?(join) join ? "RIGHT #{join}" : nil end + + def order?(clause) + clause ? "ORDER #{clause}" : nil + end + + def limit?(count) + count ? "LIMIT #{count}" : nil + end end end diff --git a/test/test_exec.rb b/test/test_exec.rb index cf7c18c..bef1408 100644 --- a/test/test_exec.rb +++ b/test/test_exec.rb @@ -46,4 +46,21 @@ class TestExec < Minitest::Test insert_into :foo, id: 1, col: 'whatevs' assert_equal(select('*', from: :foo), [[1, 'whatevs']]) end + + def test_limit + create_table :foo, id: 'INT', col: 'VARCHAR(255)' + insert_into :foo, id: 1, col: 'whatevs' + insert_into :foo, id: 2, col: 'something else' + assert_equal(select('*', from: :foo, limit: 1), [[1, 'whatevs']]) + end + + def test_order_by + create_table :foo, id: 'INT', col: 'VARCHAR(255)', value: 'VARCHAR(255)' + 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(: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..575556f 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