From 075957be04aa4ec37abde19f2b6048c97a468879 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Fri, 3 Mar 2017 16:13:06 +0100 Subject: [PATCH] wrap AND first member w/ parens --- lib/rebel/sql.rb | 8 ++++++-- test/test_raw.rb | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/rebel/sql.rb b/lib/rebel/sql.rb index 7e1871a..2a09898 100644 --- a/lib/rebel/sql.rb +++ b/lib/rebel/sql.rb @@ -65,6 +65,10 @@ module Rebel::SQL Raw.new("(#{self})") end + def parens? + wants_parens? ? parens : self + end + def as(n) Raw.new(self + " AS #{Rebel::SQL.name(n)}") end @@ -82,7 +86,7 @@ module Rebel::SQL end def and(*clause) - Raw.new("#{self} AND #{Rebel::SQL.and_clause(*clause)}") + Raw.new("#{self.parens?} AND #{Rebel::SQL.and_clause(*clause)}") end def or(*clause) @@ -313,7 +317,7 @@ module Rebel::SQL case e when Hash then and_clause(*e.to_a) when Array then clause_term(e[0], e[1]) - when Raw then e.wants_parens? && clause.count > 1 ? "(#{e})" : e + when Raw then e.parens? when String then e else raise NotImplementedError, e.class end diff --git a/test/test_raw.rb b/test/test_raw.rb index cf84d20..3d2b930 100644 --- a/test/test_raw.rb +++ b/test/test_raw.rb @@ -15,6 +15,14 @@ class TestRaw < Minitest::Test assert_str_equal(Rebel::SQL.name(:foo).eq(1).or(Rebel::SQL.name(:bar).eq(2)), '"foo" = 1 OR "bar" = 2') end + def test_and_or + assert_str_equal(Rebel::SQL.name(:foo).eq(0).and(Rebel::SQL.name(:foo).eq(1).or(Rebel::SQL.name(:bar).eq(2))), '"foo" = 0 AND ("foo" = 1 OR "bar" = 2)') + end + + def test_or_and_or + assert_str_equal(Rebel::SQL.name(:foo).eq(1).or(Rebel::SQL.name(:bar).eq(2)).and(Rebel::SQL.name(:foo).eq(3).or(Rebel::SQL.name(:bar).eq(4))), '("foo" = 1 OR "bar" = 2) AND ("foo" = 3 OR "bar" = 4)') + end + def test_is assert_str_equal(Rebel::SQL.name(:foo).is(nil), '"foo" IS NULL') assert_str_equal(Rebel::SQL.name(:foo).is(42), '"foo" = 42') @@ -62,7 +70,7 @@ class TestRaw < Minitest::Test def test_where assert_str_equal(Rebel::SQL.where?(foo: 1, bar: 2, baz: 3), 'WHERE "foo" = 1 AND "bar" = 2 AND "baz" = 3') assert_str_equal(Rebel::SQL.where?(Rebel::SQL.name(:foo).eq(1).or(Rebel::SQL.name(:bar).eq(2)), Rebel::SQL.name(:baz).eq(3)), 'WHERE ("foo" = 1 OR "bar" = 2) AND "baz" = 3') - assert_str_equal(Rebel::SQL.where?(Rebel::SQL.name(:foo).eq(1).or(Rebel::SQL.name(:bar).eq(2))), 'WHERE "foo" = 1 OR "bar" = 2') + assert_str_equal(Rebel::SQL.where?(Rebel::SQL.name(:foo).eq(1).or(Rebel::SQL.name(:bar).eq(2))), 'WHERE ("foo" = 1 OR "bar" = 2)') end def test_join