Skip to content

Commit

Permalink
Delete marker => Only use on within JOINS instead of appending to the…
Browse files Browse the repository at this point in the history
… global WHERE. This ensures we dont transform the LEFT into an INNER and the full query can run.
  • Loading branch information
ThomasTJdev committed Jan 5, 2025
1 parent 955eb2e commit c76ad6d
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 62 deletions.
2 changes: 1 addition & 1 deletion sqlbuilder.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "1.0.6"
version = "1.1.0"
author = "ThomasTJdev"
description = "SQL builder"
license = "MIT"
Expand Down
65 changes: 47 additions & 18 deletions src/sqlbuilderpkg/select.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ import
from ./utils import SQLJoinType, ArgsContainer


# when defined(sqlDeletemarker):
# const sqlDeletemarkerSeq {.strdefine}: string = "sqlDeletemarkerSeq"
# const tablesWithDeleteMarkerInit = sqlDeletemarkerSeq.split(",")
# else:
# const tablesWithDeleteMarkerInit = [""]


##
## Constant generator utilities
##
Expand All @@ -27,7 +34,9 @@ proc sqlSelectConstSelect(select: varargs[string]): string =

proc sqlSelectConstJoin(
joinargs: varargs[tuple[table: string, tableAs: string, on: seq[string]]],
jointype: NimNode
jointype: NimNode,
deleteMarkersFields: seq[string],
deleteMarker: NimNode
): string =
var lef = ""

Expand All @@ -51,6 +60,12 @@ proc sqlSelectConstJoin(
lef.add(" AND ")
lef.add($join)

if d.table in deleteMarkersFields:
if d.tableAs != "" and (d.tableAs & $deleteMarker) notin lef:
lef.add(" AND " & d.tableAs & $deleteMarker)
elif (d.table & $deleteMarker) notin lef:
lef.add(" AND " & d.table & $deleteMarker)

lef.add(")")

return lef
Expand Down Expand Up @@ -207,28 +222,29 @@ proc sqlSelectConstWhereIn(

proc sqlSelectConstSoft(
wes, acc: string,
tablesInQuery: seq[tuple[table: string, tableAs: string]],
# tablesInQuery: seq[tuple[table: string, tableAs: string]],
table, tableAs: string,
tablesWithDeleteMarker: varargs[string],
useDeleteMarker: NimNode,
deleteMarker: NimNode
): (string, string) =
if $useDeleteMarker == "true" and tablesWithDeleteMarker.len() > 0:
var wesTo, accTo: string

for t in tablesInQuery:
if t.table notin tablesWithDeleteMarker:
continue
# for t in tablesInQuery:
if table notin tablesWithDeleteMarker:
return (wesTo, accTo)

let toUse = if t.tableAs != "": t.tableAs else: t.table
let toUse = if tableAs != "": tableAs else: table

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

elif acc != "":
accTo.add(" AND " & toUse & $deleteMarker)
elif acc != "":
accTo.add(" AND " & toUse & $deleteMarker)

else:
wesTo.add(" AND " & toUse & $deleteMarker)
else:
wesTo.add(" AND " & toUse & $deleteMarker)

return (wesTo, accTo)

Expand Down Expand Up @@ -342,7 +358,7 @@ macro sqlSelectConst*(
#
var lef = ""
if joinargs.len != 0:
lef = sqlSelectConstJoin(joinargs, jointype)
lef = sqlSelectConstJoin(joinargs, jointype, deleteMarkersFields, deleteMarker)


#
Expand All @@ -364,7 +380,8 @@ macro sqlSelectConst*(
#
var (toWes, toAcc) = sqlSelectConstSoft(
wes, acc,
tablesInQuery,
# tablesInQuery,
$table, $tableAs,
deleteMarkersFields,
useDeleteMarker, deleteMarker
)
Expand Down Expand Up @@ -522,6 +539,12 @@ proc sqlSelect*(
lef.add(" AND ")
lef.add(join)

if d.table in deleteMarkersFields:
if d.tableAs != "":# and (d.tableAs & $deleteMarker) notin lef:
lef.add(" AND " & d.tableAs & $deleteMarker)
else:#if (d.table & $deleteMarker) notin lef:
lef.add(" AND " & d.table & $deleteMarker)

lef.add(")")

if joinoverride.len() > 0:
Expand Down Expand Up @@ -611,6 +634,12 @@ proc sqlSelect*(
else:
wes.add("? " & d)

# => x != y
elif d.len() >= 5 and d.contains(" != ") and d.split(" != ").len() == 2:
wes.add(d)

# !! Waring = pfl.action IN (2,3,4) <== not supported

# => x = y
elif d.len() >= 5 and d.contains(" = "):
let eSplit = d.split(" = ")
Expand Down Expand Up @@ -696,11 +725,11 @@ proc sqlSelect*(
# Soft delete
#
if useDeleteMarker and deleteMarkersFields.len() > 0:
for t in tablesInQuery:
if t.table notin deleteMarkersFields:
continue
# for t in tablesInQuery:
if table in deleteMarkersFields:
# continue

let toUse = if t.tableAs != "": t.tableAs else: t.table
let toUse = if tableAs != "": tableAs else: table

if wes == "" and acc == "":
wes.add(" WHERE " & toUse & $deleteMarker)
Expand Down
4 changes: 2 additions & 2 deletions src/sqlbuilderpkg/utils_private.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ proc querycompare*(a, b: SqlQuery): bool =
var
a1: seq[string]
b1: seq[string]
for c in splitWhitespace(string(a)):
for c in splitWhitespace(string(a).toLowerAscii()):
a1.add($c)
for c in splitWhitespace(string(b)):
for c in splitWhitespace(string(b).toLowerAscii()):
b1.add($c)

if a1 != b1:
Expand Down
5 changes: 4 additions & 1 deletion tests/config.nims
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
switch("path", "..")
switch("d", "test")
switch("d", "dev")
switch("d", "dev")

# switch("d", "sqlDeletemarker")
# switch("d", "sqlDeletemarkerSeq=tasks")
8 changes: 8 additions & 0 deletions tests/insert/test_insert.nim
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ suite "insert - default":
check querycompare(test, sql("INSERT INTO my-table (name, age, company, ident) VALUES (?, NULL, NULL, ?)"))



test "manual NULL":
var test: SqlQuery

test = sqlInsert("my-table", ["name", "age"], @["NULL", "30"])
check querycompare(test, sql("INSERT INTO my-table (name, age) VALUES (NULL, ?)"))


suite "insert - macro":

test "sqlInsert - default":
Expand Down
3 changes: 1 addition & 2 deletions tests/legacy_convert/test_legacy_with_softdelete.nim
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
FROM
tasksitems AS tasks
LEFT JOIN history AS his ON
(his.id = tasks.hid AND his.status = 1)
(his.id = tasks.hid AND his.status = 1 AND his.is_deleted IS NULL)
LEFT JOIN projects ON
(projects.id = tasks.project_id AND projects.status = 1)
LEFT JOIN person ON
Expand All @@ -200,7 +200,6 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
AND tasks.status > ?
AND tasks.id in (1,2,3)
AND tasks.is_deleted IS NULL
AND his.is_deleted IS NULL
ORDER BY
tasks.created DESC
""")))
9 changes: 3 additions & 6 deletions tests/legacy_convert/test_legacy_with_softdelete2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio

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

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")
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")

check querycompare(test, sql("""
SELECT
Expand All @@ -47,7 +47,6 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
t.id = ?
AND p.id in (2,4,6,7)
AND t.is_deleted IS NULL
AND persons.is_deleted IS NULL
ORDER BY
t.name
"""))
Expand All @@ -67,12 +66,11 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
LEFT JOIN invoice AS p ON
(p.id = t.invoice_id)
LEFT JOIN persons ON
(persons.id = tasks.person_id)
(persons.id = tasks.person_id AND persons.is_deleted IS NULL)
WHERE
t.id = ?
AND p.id in (2,4,6,7)
AND t.is_deleted IS NULL
AND persons.is_deleted IS NULL
ORDER BY
t.name
"""))
Expand All @@ -90,12 +88,11 @@ suite "legacy - sqlSelect(converter) - with new functionality to avoid regressio
FROM
tasks
LEFT JOIN persons ON
(persons.id = t.persons_id)
(persons.id = t.persons_id AND persons.is_deleted IS NULL)
WHERE
t.id = ?
AND invoice.id in (2,4,6,7)
AND tasks.is_deleted IS NULL
AND persons.is_deleted IS NULL
ORDER BY
t.name
"""))
Expand Down
Loading

0 comments on commit c76ad6d

Please sign in to comment.