Skip to content

Commit c76ad6d

Browse files
committed
Delete marker => Only use on within JOINS instead of appending to the global WHERE. This ensures we dont transform the LEFT into an INNER and the full query can run.
1 parent 955eb2e commit c76ad6d

11 files changed

+318
-62
lines changed

sqlbuilder.nimble

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Package
22

3-
version = "1.0.6"
3+
version = "1.1.0"
44
author = "ThomasTJdev"
55
description = "SQL builder"
66
license = "MIT"

src/sqlbuilderpkg/select.nim

+47-18
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ import
1515
from ./utils import SQLJoinType, ArgsContainer
1616

1717

18+
# when defined(sqlDeletemarker):
19+
# const sqlDeletemarkerSeq {.strdefine}: string = "sqlDeletemarkerSeq"
20+
# const tablesWithDeleteMarkerInit = sqlDeletemarkerSeq.split(",")
21+
# else:
22+
# const tablesWithDeleteMarkerInit = [""]
23+
24+
1825
##
1926
## Constant generator utilities
2027
##
@@ -27,7 +34,9 @@ proc sqlSelectConstSelect(select: varargs[string]): string =
2734

2835
proc sqlSelectConstJoin(
2936
joinargs: varargs[tuple[table: string, tableAs: string, on: seq[string]]],
30-
jointype: NimNode
37+
jointype: NimNode,
38+
deleteMarkersFields: seq[string],
39+
deleteMarker: NimNode
3140
): string =
3241
var lef = ""
3342

@@ -51,6 +60,12 @@ proc sqlSelectConstJoin(
5160
lef.add(" AND ")
5261
lef.add($join)
5362

63+
if d.table in deleteMarkersFields:
64+
if d.tableAs != "" and (d.tableAs & $deleteMarker) notin lef:
65+
lef.add(" AND " & d.tableAs & $deleteMarker)
66+
elif (d.table & $deleteMarker) notin lef:
67+
lef.add(" AND " & d.table & $deleteMarker)
68+
5469
lef.add(")")
5570

5671
return lef
@@ -207,28 +222,29 @@ proc sqlSelectConstWhereIn(
207222

208223
proc sqlSelectConstSoft(
209224
wes, acc: string,
210-
tablesInQuery: seq[tuple[table: string, tableAs: string]],
225+
# tablesInQuery: seq[tuple[table: string, tableAs: string]],
226+
table, tableAs: string,
211227
tablesWithDeleteMarker: varargs[string],
212228
useDeleteMarker: NimNode,
213229
deleteMarker: NimNode
214230
): (string, string) =
215231
if $useDeleteMarker == "true" and tablesWithDeleteMarker.len() > 0:
216232
var wesTo, accTo: string
217233

218-
for t in tablesInQuery:
219-
if t.table notin tablesWithDeleteMarker:
220-
continue
234+
# for t in tablesInQuery:
235+
if table notin tablesWithDeleteMarker:
236+
return (wesTo, accTo)
221237

222-
let toUse = if t.tableAs != "": t.tableAs else: t.table
238+
let toUse = if tableAs != "": tableAs else: table
223239

224-
if wes == "" and acc == "":
225-
wesTo.add(" WHERE " & toUse & $deleteMarker)
240+
if wes == "" and acc == "":
241+
wesTo.add(" WHERE " & toUse & $deleteMarker)
226242

227-
elif acc != "":
228-
accTo.add(" AND " & toUse & $deleteMarker)
243+
elif acc != "":
244+
accTo.add(" AND " & toUse & $deleteMarker)
229245

230-
else:
231-
wesTo.add(" AND " & toUse & $deleteMarker)
246+
else:
247+
wesTo.add(" AND " & toUse & $deleteMarker)
232248

233249
return (wesTo, accTo)
234250

@@ -342,7 +358,7 @@ macro sqlSelectConst*(
342358
#
343359
var lef = ""
344360
if joinargs.len != 0:
345-
lef = sqlSelectConstJoin(joinargs, jointype)
361+
lef = sqlSelectConstJoin(joinargs, jointype, deleteMarkersFields, deleteMarker)
346362

347363

348364
#
@@ -364,7 +380,8 @@ macro sqlSelectConst*(
364380
#
365381
var (toWes, toAcc) = sqlSelectConstSoft(
366382
wes, acc,
367-
tablesInQuery,
383+
# tablesInQuery,
384+
$table, $tableAs,
368385
deleteMarkersFields,
369386
useDeleteMarker, deleteMarker
370387
)
@@ -522,6 +539,12 @@ proc sqlSelect*(
522539
lef.add(" AND ")
523540
lef.add(join)
524541

542+
if d.table in deleteMarkersFields:
543+
if d.tableAs != "":# and (d.tableAs & $deleteMarker) notin lef:
544+
lef.add(" AND " & d.tableAs & $deleteMarker)
545+
else:#if (d.table & $deleteMarker) notin lef:
546+
lef.add(" AND " & d.table & $deleteMarker)
547+
525548
lef.add(")")
526549

527550
if joinoverride.len() > 0:
@@ -611,6 +634,12 @@ proc sqlSelect*(
611634
else:
612635
wes.add("? " & d)
613636

637+
# => x != y
638+
elif d.len() >= 5 and d.contains(" != ") and d.split(" != ").len() == 2:
639+
wes.add(d)
640+
641+
# !! Waring = pfl.action IN (2,3,4) <== not supported
642+
614643
# => x = y
615644
elif d.len() >= 5 and d.contains(" = "):
616645
let eSplit = d.split(" = ")
@@ -696,11 +725,11 @@ proc sqlSelect*(
696725
# Soft delete
697726
#
698727
if useDeleteMarker and deleteMarkersFields.len() > 0:
699-
for t in tablesInQuery:
700-
if t.table notin deleteMarkersFields:
701-
continue
728+
# for t in tablesInQuery:
729+
if table in deleteMarkersFields:
730+
# continue
702731

703-
let toUse = if t.tableAs != "": t.tableAs else: t.table
732+
let toUse = if tableAs != "": tableAs else: table
704733

705734
if wes == "" and acc == "":
706735
wes.add(" WHERE " & toUse & $deleteMarker)

src/sqlbuilderpkg/utils_private.nim

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ proc querycompare*(a, b: SqlQuery): bool =
1515
var
1616
a1: seq[string]
1717
b1: seq[string]
18-
for c in splitWhitespace(string(a)):
18+
for c in splitWhitespace(string(a).toLowerAscii()):
1919
a1.add($c)
20-
for c in splitWhitespace(string(b)):
20+
for c in splitWhitespace(string(b).toLowerAscii()):
2121
b1.add($c)
2222

2323
if a1 != b1:

tests/config.nims

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
switch("path", "..")
22
switch("d", "test")
3-
switch("d", "dev")
3+
switch("d", "dev")
4+
5+
# switch("d", "sqlDeletemarker")
6+
# switch("d", "sqlDeletemarkerSeq=tasks")

tests/insert/test_insert.nim

+8
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ suite "insert - default":
100100
check querycompare(test, sql("INSERT INTO my-table (name, age, company, ident) VALUES (?, NULL, NULL, ?)"))
101101

102102

103+
104+
test "manual NULL":
105+
var test: SqlQuery
106+
107+
test = sqlInsert("my-table", ["name", "age"], @["NULL", "30"])
108+
check querycompare(test, sql("INSERT INTO my-table (name, age) VALUES (NULL, ?)"))
109+
110+
103111
suite "insert - macro":
104112

105113
test "sqlInsert - default":

tests/legacy_convert/test_legacy_with_softdelete.nim

+1-2
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
190190
FROM
191191
tasksitems AS tasks
192192
LEFT JOIN history AS his ON
193-
(his.id = tasks.hid AND his.status = 1)
193+
(his.id = tasks.hid AND his.status = 1 AND his.is_deleted IS NULL)
194194
LEFT JOIN projects ON
195195
(projects.id = tasks.project_id AND projects.status = 1)
196196
LEFT JOIN person ON
@@ -200,7 +200,6 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
200200
AND tasks.status > ?
201201
AND tasks.id in (1,2,3)
202202
AND tasks.is_deleted IS NULL
203-
AND his.is_deleted IS NULL
204203
ORDER BY
205204
tasks.created DESC
206205
""")))

tests/legacy_convert/test_legacy_with_softdelete2.nim

+3-6
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
3030

3131
test "existing delete in left join (double) - delete marker from left join":
3232

33-
let test = sqlSelect("tasks AS t", ["t.id", "t.name", "p.id"], ["invoice AS p ON p.id = t.invoice_id", "persons ON persons.id = tasks.person_id AND persons.is_deleted IS NULL"], ["t.id ="], "2,4,6,7", "p.id", "ORDER BY t.name")
33+
let test = sqlSelect("tasks AS t", ["t.id", "t.name", "p.id"], ["invoice AS p ON p.id = t.invoice_id", "persons ON persons.id = tasks.person_id"], ["t.id ="], "2,4,6,7", "p.id", "ORDER BY t.name")
3434

3535
check querycompare(test, sql("""
3636
SELECT
@@ -47,7 +47,6 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
4747
t.id = ?
4848
AND p.id in (2,4,6,7)
4949
AND t.is_deleted IS NULL
50-
AND persons.is_deleted IS NULL
5150
ORDER BY
5251
t.name
5352
"""))
@@ -67,12 +66,11 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
6766
LEFT JOIN invoice AS p ON
6867
(p.id = t.invoice_id)
6968
LEFT JOIN persons ON
70-
(persons.id = tasks.person_id)
69+
(persons.id = tasks.person_id AND persons.is_deleted IS NULL)
7170
WHERE
7271
t.id = ?
7372
AND p.id in (2,4,6,7)
7473
AND t.is_deleted IS NULL
75-
AND persons.is_deleted IS NULL
7674
ORDER BY
7775
t.name
7876
"""))
@@ -90,12 +88,11 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
9088
FROM
9189
tasks
9290
LEFT JOIN persons ON
93-
(persons.id = t.persons_id)
91+
(persons.id = t.persons_id AND persons.is_deleted IS NULL)
9492
WHERE
9593
t.id = ?
9694
AND invoice.id in (2,4,6,7)
9795
AND tasks.is_deleted IS NULL
98-
AND persons.is_deleted IS NULL
9996
ORDER BY
10097
t.name
10198
"""))

0 commit comments

Comments
 (0)