Skip to content

Commit 8244775

Browse files
committed
add + operator overloading to clause to OR join two clauses
1 parent 4b95331 commit 8244775

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

lapis/db/base.lua

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ do
33
local _obj_0 = _G
44
setmetatable, getmetatable, tostring = _obj_0.setmetatable, _obj_0.getmetatable, _obj_0.tostring
55
end
6+
local clause, is_clause
67
local DBRaw
78
do
89
local _class_0
@@ -73,6 +74,15 @@ do
7374
return opts.operator
7475
end
7576
return "AND"
77+
end,
78+
__add = function(self, other)
79+
assert(is_clause(other), "db.clause.__add: right operand must be a clause object")
80+
return clause({
81+
self,
82+
other
83+
}, {
84+
operator = "OR"
85+
})
7686
end
7787
}
7888
_base_0.__index = _base_0
@@ -91,15 +101,13 @@ do
91101
_base_0.__class = _class_0
92102
DBClause = _class_0
93103
end
94-
local clause
95104
clause = function(clause, opts)
96105
assert(not getmetatable(clause), "db.clause: attempted to create clause from object that has metatable")
97106
return setmetatable({
98107
clause,
99108
opts
100109
}, DBClause.__base)
101110
end
102-
local is_clause
103111
is_clause = function(val)
104112
return getmetatable(val) == DBClause.__base
105113
end

lapis/db/base.moon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
import setmetatable, getmetatable, tostring from _G
33

4+
local clause, is_clause
5+
46
class DBRaw
57
raw = (val) -> setmetatable {tostring val}, DBRaw.__base
68
is_raw = (val) -> getmetatable(val) == DBRaw.__base
@@ -18,6 +20,10 @@ class DBClause
1820

1921
"AND"
2022

23+
__add: (other) =>
24+
assert is_clause(other), "db.clause.__add: right operand must be a clause object"
25+
clause { @, other }, operator: "OR"
26+
2127
clause = (clause, opts) ->
2228
assert not getmetatable(clause), "db.clause: attempted to create clause from object that has metatable"
2329
setmetatable {clause, opts}, DBClause.__base

spec/postgres_spec.moon

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,60 @@ describe "lapis.db.postgres", ->
920920
"db.encode_clause: passed an empty clause (use allow_empty: true to permit empty clause)"
921921
)
922922

923+
describe "+ operator", ->
924+
it "combines two clauses with OR", ->
925+
a = db.clause hello: "world"
926+
b = db.clause { "not deleted" }
927+
combined = a + b
928+
assert.same '("hello" = \'world\') OR ((not deleted))', db.encode_clause combined
929+
930+
it "chains multiple clauses", ->
931+
a = db.clause { "a" }
932+
b = db.clause { "b" }
933+
c = db.clause { "c" }
934+
combined = a + b + c
935+
assert.same '((a)) OR ((b)) OR ((c))', db.encode_clause combined
936+
937+
it "works with db.raw and db.NULL in clauses", ->
938+
a = db.clause { status: db.raw "active" }
939+
b = db.clause { deleted: db.NULL }
940+
combined = a + b
941+
assert.same '("status" = active) OR ("deleted" IS NULL)', db.encode_clause combined
942+
943+
it "works with db.list in clauses", ->
944+
a = db.clause { id: db.list {1, 2, 3} }
945+
b = db.clause { "archived" }
946+
combined = a + b
947+
assert.same '("id" IN (1, 2, 3)) OR ((archived))', db.encode_clause combined
948+
949+
it "errors when right operand is a plain table", ->
950+
a = db.clause hello: "world"
951+
assert.has_error(
952+
-> a + { hello: "world" }
953+
"db.clause.__add: right operand must be a clause object"
954+
)
955+
956+
it "errors when right operand is a string", ->
957+
a = db.clause hello: "world"
958+
assert.has_error(
959+
-> a + "not a clause"
960+
"db.clause.__add: right operand must be a clause object"
961+
)
962+
963+
it "errors when right operand is a number", ->
964+
a = db.clause hello: "world"
965+
assert.has_error(
966+
-> a + 123
967+
"db.clause.__add: right operand must be a clause object"
968+
)
969+
970+
it "errors when right operand is nil", ->
971+
a = db.clause hello: "world"
972+
assert.has_error(
973+
-> a + nil
974+
"db.clause.__add: right operand must be a clause object"
975+
)
976+
923977
describe "encode_assigns", ->
924978
it "writes output to buffer", ->
925979
buffer = {"hello"}

0 commit comments

Comments
 (0)