From 4ce508862da1685c3afaf47314fd8a08a7c56c16 Mon Sep 17 00:00:00 2001 From: Thomas Kienlen Date: Wed, 31 May 2017 15:44:12 +0200 Subject: [PATCH] select: order_by limit --- lib/rebel/sql.rb | 36 ++++++++++++++++++++++++++++++++---- test/test_exec.rb | 17 +++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/rebel/sql.rb b/lib/rebel/sql.rb index d3d980e..40cf33e 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_by: nil, limit: nil) exec(Rebel::SQL.select(*fields, from: from, where: where, inner: inner, left: left, - right: right)) + right: right, + order_by: order_by, + limit: limit)) end def insert_into(table_name, *rows) @@ -178,13 +180,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_by: nil, limit: nil) <<-SQL SELECT #{names(*fields)} FROM #{name(from)} #{inner?(inner)} #{left?(left)} #{right?(right)} - #{where?(where)}; + #{where?(where)} + #{order_by?(order_by)} + #{limit?(limit)}; SQL end @@ -304,10 +308,26 @@ 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 @@ -344,5 +364,13 @@ module Rebel::SQL def right?(join) join ? "RIGHT #{join}" : nil end + + def order_by?(*clause) + clause.any? ? "ORDER BY #{order_by_clause(*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..66fb0f1 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: :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]]) + end end