diff --git a/sqlbuilder.nimble b/sqlbuilder.nimble index 0a0e36a..8ecf70a 100644 --- a/sqlbuilder.nimble +++ b/sqlbuilder.nimble @@ -1,6 +1,6 @@ # Package -version = "1.0.6" +version = "1.1.0" author = "ThomasTJdev" description = "SQL builder" license = "MIT" diff --git a/src/sqlbuilderpkg/select.nim b/src/sqlbuilderpkg/select.nim index 521d75e..6b2f282 100644 --- a/src/sqlbuilderpkg/select.nim +++ b/src/sqlbuilderpkg/select.nim @@ -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 ## @@ -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 = "" @@ -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 @@ -207,7 +222,8 @@ 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 @@ -215,20 +231,20 @@ proc sqlSelectConstSoft( 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) @@ -342,7 +358,7 @@ macro sqlSelectConst*( # var lef = "" if joinargs.len != 0: - lef = sqlSelectConstJoin(joinargs, jointype) + lef = sqlSelectConstJoin(joinargs, jointype, deleteMarkersFields, deleteMarker) # @@ -364,7 +380,8 @@ macro sqlSelectConst*( # var (toWes, toAcc) = sqlSelectConstSoft( wes, acc, - tablesInQuery, + # tablesInQuery, + $table, $tableAs, deleteMarkersFields, useDeleteMarker, deleteMarker ) @@ -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: @@ -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(" = ") @@ -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) diff --git a/src/sqlbuilderpkg/utils_private.nim b/src/sqlbuilderpkg/utils_private.nim index 8cd9cc3..b8c81f7 100644 --- a/src/sqlbuilderpkg/utils_private.nim +++ b/src/sqlbuilderpkg/utils_private.nim @@ -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: diff --git a/tests/config.nims b/tests/config.nims index d665900..49e5a14 100644 --- a/tests/config.nims +++ b/tests/config.nims @@ -1,3 +1,6 @@ switch("path", "..") switch("d", "test") -switch("d", "dev") \ No newline at end of file +switch("d", "dev") + +# switch("d", "sqlDeletemarker") +# switch("d", "sqlDeletemarkerSeq=tasks") \ No newline at end of file diff --git a/tests/insert/test_insert.nim b/tests/insert/test_insert.nim index 64e4521..04591e9 100644 --- a/tests/insert/test_insert.nim +++ b/tests/insert/test_insert.nim @@ -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": diff --git a/tests/legacy_convert/test_legacy_with_softdelete.nim b/tests/legacy_convert/test_legacy_with_softdelete.nim index 048d775..bb0f335 100644 --- a/tests/legacy_convert/test_legacy_with_softdelete.nim +++ b/tests/legacy_convert/test_legacy_with_softdelete.nim @@ -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 @@ -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 """))) diff --git a/tests/legacy_convert/test_legacy_with_softdelete2.nim b/tests/legacy_convert/test_legacy_with_softdelete2.nim index 2fa1f9f..39e9482 100644 --- a/tests/legacy_convert/test_legacy_with_softdelete2.nim +++ b/tests/legacy_convert/test_legacy_with_softdelete2.nim @@ -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 @@ -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 """)) @@ -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 """)) @@ -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 """)) diff --git a/tests/select/test_select.nim b/tests/select/test_select.nim index 2f3509a..2370c3c 100644 --- a/tests/select/test_select.nim +++ b/tests/select/test_select.nim @@ -160,6 +160,54 @@ suite "test sqlSelect": check string(test).count("?") == 2 + test "SELECT with SUM and COUNT": + var test: SqlQuery + + test = sqlSelect( + table = "checklist_table", + tableAs = "cht", + select = [ + "cht.c_id", + "SUM(CASE WHEN cht.status IS NULL THEN 1 ELSE 0 END) as null", + "SUM(CASE WHEN cht.status = 0 THEN 1 ELSE 0 END) as zero", + "SUM(CASE WHEN cht.status = 1 THEN 1 ELSE 0 END) as one", + "SUM(CASE WHEN cht.status = 2 THEN 1 ELSE 0 END) as two", + "COUNT(cht.id) as total", + "SUM(CASE WHEN cht.extra_check IS TRUE AND cht.extra_approve IS TRUE THEN 1 ELSE 0 END) as extraApproved", + "SUM(CASE WHEN cht.extra_check IS TRUE AND cht.extra_approve IS False THEN 1 ELSE 0 END) as extraFailed", + "SUM(CASE WHEN cht.extra_check IS TRUE AND cht.extra_approve IS NULL AND cht.status = 1 THEN 1 ELSE 0 END) as extraAwaiting", + ], + where = [ + "cht.project_id =", + "cht.type =" + ], + joinargs = [ + (table: "checklist", tableAs: "c", on: @["c.id = cht.c_id"]) + ], + customSQL = "GROUP BY cht.c_id" + ) + check querycompare(test, sql(""" +select + cht.c_id, + SUM(case when cht.status is null then 1 else 0 end) as null, + SUM(case when cht.status = 0 then 1 else 0 end) as zero, + SUM(case when cht.status = 1 then 1 else 0 end) as one, + SUM(case when cht.status = 2 then 1 else 0 end) as two, + COUNT(cht.id) as total, + SUM(case when cht.extra_check is true and cht.extra_approve is true then 1 else 0 end) as extraApproved, + SUM(case when cht.extra_check is true and cht.extra_approve is false then 1 else 0 end) as extraFailed, + SUM(case when cht.extra_check is true and cht.extra_approve is null and cht.status = 1 then 1 else 0 end) as extraAwaiting +from + checklist_table as cht +left join checklist as c on + (c.id = cht.c_id) +where + cht.project_id = ? + and cht.type = ? +group by + cht.c_id + """)) + suite "test sqlSelect - joins": @@ -287,6 +335,10 @@ suite "test sqlSelect - deletemarkers / softdelete": + test "deletemarkers from seq - using full name for deletemarker table in LEFT JOIN": + var test: SqlQuery + let tableWithDeleteMarkerLet = @["tasks", "history", "tasksitems"] + test = sqlSelect( table = "tasks", select = @["id", "name"], @@ -294,9 +346,12 @@ suite "test sqlSelect - deletemarkers / softdelete": joinargs = @[(table: "history", tableAs: "", on: @["history.id = tasks.hid"])], tablesWithDeleteMarker = tableWithDeleteMarkerLet ) - check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid) WHERE id = ? AND tasks.is_deleted IS NULL AND history.is_deleted IS NULL ")) + check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid AND history.is_deleted IS NULL) WHERE id = ? AND tasks.is_deleted IS NULL ")) + test "deletemarkers from seq - using ALIAS for deletemarker table in LEFT JOIN": + var test: SqlQuery + let tableWithDeleteMarkerLet = @["tasks", "history", "tasksitems"] test = sqlSelect( table = "tasks", @@ -305,7 +360,7 @@ suite "test sqlSelect - deletemarkers / softdelete": joinargs = @[(table: "history", tableAs: "his", on: @["his.id = tasks.hid"])], tablesWithDeleteMarker = tableWithDeleteMarkerLet ) - check querycompare(test, sql("SELECT tasks.id, tasks.name FROM tasks LEFT JOIN history AS his ON (his.id = tasks.hid) WHERE tasks.id = ? AND tasks.is_deleted IS NULL AND his.is_deleted IS NULL ")) + check querycompare(test, sql("SELECT tasks.id, tasks.name FROM tasks LEFT JOIN history AS his ON (his.id = tasks.hid AND his.is_deleted IS NULL) WHERE tasks.id = ? AND tasks.is_deleted IS NULL ")) @@ -335,7 +390,7 @@ suite "test sqlSelect - deletemarkers / softdelete": tablesWithDeleteMarker = tableWithDeleteMarkerLet, deleteMarker = ".deleted_at = 543234563" ) - check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid) WHERE id = ? AND tasks.deleted_at = 543234563 AND history.deleted_at = 543234563 ")) + check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid AND history.deleted_at = 543234563) WHERE id = ? AND tasks.deleted_at = 543234563 ")) @@ -395,7 +450,7 @@ suite "test sqlSelect - deletemarkers / softdelete": 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 @@ -405,7 +460,6 @@ suite "test sqlSelect - deletemarkers / softdelete": 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 """))) @@ -669,6 +723,29 @@ suite "test where cases custom formatting": + test "where - using !=": + + let test = sqlSelect( + table = "history", + tableAs = "history", + select = [ + "person.name as user_id", + "history.creation" + ], + where = [ + "history.project_id =", + "history.creation != history.updated", + ], + joinargs = [ + (table: "person", tableAs: "", on: @["history.user_id = person.id"]) + ], + customSQL = "ORDER BY history.creation DESC, history.id DESC" + ) + + check querycompare(test, sql("SELECT person.name as user_id, history.creation FROM history LEFT JOIN person ON (history.user_id = person.id) WHERE history.project_id = ? AND history.creation != history.updated ORDER BY history.creation DESC, history.id DESC")) + + + suite "test using DB names for columns": test "info => in, nonull => null, anything => any": @@ -702,3 +779,57 @@ suite "catch bad formats": + test "kkk": + let a = sqlSelect( + table = "project", + tableAs = "p", + select = @[ + "p.id", # 0 + "pfl.folder_id", # 1 + "array_to_string(pfa.see, ',') AS pfaSee", + "array_to_string(pfa.write, ',') AS pfaWrite", + "p.name", # 4 + "p.author_id", # 5 + "pfa.folder_name", # 6 + "array_to_string(pfa.see_userIDs, ',')", # 7 + "array_to_string(pfa.write_userIDs, ',')", # 8 + "array_to_string(pugSee.userIDs, ',')", # 9 + "array_to_string(pugWrite.userIDs, ',')", # 10 + "array_to_string(p.priv_admin, ',')", # 11 + "array_to_string(p.priv_manager, ',')", # 12 + "array_to_string(p.priv_work, ',')", # 13 + "array_to_string(p.priv_designer, ',')", # 14 + "array_to_string(p.priv_contractor, ',')", # 15 + "array_to_string(p.priv_see, ',')" # 16 + ], + joinargs = @[ + (table: "project_files_log", tableAs: "pfl", on: @["pfl.project_id = p.id"]), + (table: "project_files_access", tableAs: "pfa", on: @["pfa.project_id = p.id", "pfa.key = pfl.folder_id"]), + (table: "project_users_groups", tableAs: "pugSee", on: @["pugSee.project_id = p.id", "pugSee.id = ANY(pfa.see_groupIDs)"]), + (table: "project_users_groups", tableAs: "pugWrite", on: @["pugWrite.project_id = p.id", "pugWrite.id = ANY(pfa.write_groupIDs)"]) + ], + where = @[ + "pfl.creation >", + "pfl.action IN (2, 3, 4, 5)", + "p.usetender IS NULL" # !! => Decides if tender + ], + customSQL = """ + GROUP BY + p.id, + pfl.folder_id, + pfa.see, + pfa.WRITE, + p.name, + p.author_id, + p.priv_admin, + p.priv_manager, + pfa.folder_name, + pfa.see_userIDs, + pfa.write_userIDs, + pugSee.userIDs, + pugWrite.userIDs + ORDER BY + p.name ASC + """ + ) + echo string(a) \ No newline at end of file diff --git a/tests/select/test_select_const.nim b/tests/select/test_select_const.nim index 41af683..c5d71b3 100644 --- a/tests/select/test_select_const.nim +++ b/tests/select/test_select_const.nim @@ -176,6 +176,55 @@ suite "test sqlSelectConst": check string(test).count("?") == 2 + test "SELECT with SUM and COUNT": + var test: SqlQuery + + test = sqlSelectConst( + table = "checklist_table", + tableAs = "cht", + select = [ + "cht.c_id", + "SUM(CASE WHEN cht.status IS NULL THEN 1 ELSE 0 END) as null", + "SUM(CASE WHEN cht.status = 0 THEN 1 ELSE 0 END) as zero", + "SUM(CASE WHEN cht.status = 1 THEN 1 ELSE 0 END) as one", + "SUM(CASE WHEN cht.status = 2 THEN 1 ELSE 0 END) as two", + "COUNT(cht.id) as total", + "SUM(CASE WHEN cht.extra_check IS TRUE AND cht.extra_approve IS TRUE THEN 1 ELSE 0 END) as extraApproved", + "SUM(CASE WHEN cht.extra_check IS TRUE AND cht.extra_approve IS False THEN 1 ELSE 0 END) as extraFailed", + "SUM(CASE WHEN cht.extra_check IS TRUE AND cht.extra_approve IS NULL AND cht.status = 1 THEN 1 ELSE 0 END) as extraAwaiting", + ], + where = [ + "cht.project_id =", + "cht.type =" + ], + joinargs = [ + (table: "checklist", tableAs: "c", on: @["c.id = cht.c_id"]) + ], + customSQL = "GROUP BY cht.c_id" + ) + check querycompare(test, sql(""" +select + cht.c_id, + SUM(case when cht.status is null then 1 else 0 end) as null, + SUM(case when cht.status = 0 then 1 else 0 end) as zero, + SUM(case when cht.status = 1 then 1 else 0 end) as one, + SUM(case when cht.status = 2 then 1 else 0 end) as two, + COUNT(cht.id) as total, + SUM(case when cht.extra_check is true and cht.extra_approve is true then 1 else 0 end) as extraApproved, + SUM(case when cht.extra_check is true and cht.extra_approve is false then 1 else 0 end) as extraFailed, + SUM(case when cht.extra_check is true and cht.extra_approve is null and cht.status = 1 then 1 else 0 end) as extraAwaiting +from + checklist_table as cht +left join checklist as c on + (c.id = cht.c_id) +where + cht.project_id = ? + and cht.type = ? +group by + cht.c_id + """)) + + suite "test sqlSelectConst - joins": @@ -426,7 +475,7 @@ suite "test sqlSelectConst - deletemarkers / softdelete": joinargs = [(table: "history", tableAs: "", on: @["history.id = tasks.hid"])], tablesWithDeleteMarker = ["tasks", "history", "tasksitems"] ) - check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid) WHERE id = ? AND tasks.is_deleted IS NULL AND history.is_deleted IS NULL ")) + check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid AND history.is_deleted IS NULL) WHERE id = ? AND tasks.is_deleted IS NULL ")) @@ -437,7 +486,7 @@ suite "test sqlSelectConst - deletemarkers / softdelete": joinargs = [(table: "history", tableAs: "his", on: @["his.id = tasks.hid"])], tablesWithDeleteMarker = ["tasks", "history", "tasksitems"] ) - check querycompare(test, sql("SELECT tasks.id, tasks.name FROM tasks LEFT JOIN history AS his ON (his.id = tasks.hid) WHERE tasks.id = ? AND tasks.is_deleted IS NULL AND his.is_deleted IS NULL ")) + check querycompare(test, sql("SELECT tasks.id, tasks.name FROM tasks LEFT JOIN history AS his ON (his.id = tasks.hid AND his.is_deleted IS NULL) WHERE tasks.id = ? AND tasks.is_deleted IS NULL ")) @@ -466,7 +515,7 @@ suite "test sqlSelectConst - deletemarkers / softdelete": tablesWithDeleteMarker = ["tasks", "history", "tasksitems"], deleteMarker = ".deleted_at = 543234563" ) - check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid) WHERE id = ? AND tasks.deleted_at = 543234563 AND history.deleted_at = 543234563 ")) + check querycompare(test, sql("SELECT id, name FROM tasks LEFT JOIN history ON (history.id = tasks.hid AND history.deleted_at = 543234563) WHERE id = ? AND tasks.deleted_at = 543234563 ")) @@ -523,7 +572,7 @@ suite "test sqlSelectConst - deletemarkers / softdelete": 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 @@ -533,7 +582,6 @@ suite "test sqlSelectConst - deletemarkers / softdelete": 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 """))) @@ -585,14 +633,13 @@ suite "sqlSelectConst": FROM 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) WHERE id = ? AND status > ? AND tasks.is_deleted IS NULL - AND his.is_deleted IS NULL """)) @@ -601,7 +648,7 @@ suite "sqlSelectConst": select = ["tasks.id"], where = ["status >"], joinargs = [ - (table: "history", tableAs: "", on: @["his.id = tasks.hid"]), + (table: "history", tableAs: "", on: @["history.id = tasks.hid"]), ], tablesWithDeleteMarker = ["tasks", "history", "tasksitems"] ) @@ -611,11 +658,10 @@ suite "sqlSelectConst": FROM tasks LEFT JOIN history ON - (his.id = tasks.hid) + (history.id = tasks.hid AND history.is_deleted IS NULL) WHERE status > ? AND tasks.is_deleted IS NULL - AND history.is_deleted IS NULL """)) @@ -625,11 +671,11 @@ suite "sqlSelectConst": select = ["tasks.id"], where = ["status >"], joinargs = [ - (table: "history", tableAs: "", on: @["his.id = tasks.hid"]), - (table: "history", tableAs: "", on: @["his.id = tasks.hid"]), - (table: "history", tableAs: "", on: @["his.id = tasks.hid"]), - (table: "history", tableAs: "", on: @["his.id = tasks.hid"]), - (table: "history", tableAs: "", on: @["his.id = tasks.hid"]), + (table: "history", tableAs: "his", on: @["his.id = tasks.hid"]), + # (table: "history", tableAs: "his", on: @["his.id = tasks.hid"]), + # (table: "history", tableAs: "his", on: @["his.id = tasks.hid"]), + # (table: "history", tableAs: "his", on: @["his.id = tasks.hid"]), + # (table: "history", tableAs: "his", on: @["his.id = tasks.hid"]), ], tablesWithDeleteMarker = ["tasks", "history", "tasksitems"] ) @@ -638,22 +684,20 @@ suite "sqlSelectConst": tasks.id FROM tasks - LEFT JOIN history ON - (his.id = tasks.hid) - LEFT JOIN history ON - (his.id = tasks.hid) - LEFT JOIN history ON - (his.id = tasks.hid) - LEFT JOIN history ON - (his.id = tasks.hid) - LEFT JOIN history ON - (his.id = tasks.hid) + LEFT JOIN history AS his ON + (his.id = tasks.hid AND his.is_deleted IS NULL) WHERE status > ? AND tasks.is_deleted IS NULL - AND history.is_deleted IS NULL """)) - + # LEFT JOIN history AS his ON + # (his.id = tasks.hid AND his.is_deleted IS NULL) + # LEFT JOIN history AS his ON + # (his.id = tasks.hid AND his.is_deleted IS NULL) + # LEFT JOIN history AS his ON + # (his.id = tasks.hid AND his.is_deleted IS NULL) + # LEFT JOIN history AS his ON + # (his.id = tasks.hid AND his.is_deleted IS NULL) test "where in values (preformatted)": let e = sqlSelectConst( diff --git a/tests/update/test_update.nim b/tests/update/test_update.nim index b563484..c23706e 100644 --- a/tests/update/test_update.nim +++ b/tests/update/test_update.nim @@ -124,6 +124,37 @@ suite "update - queries": + +suite "update - queries with specified NULL in data and ? in where": + + test "set NULL and where = ?": + let q = sqlUpdate( + "table", + ["name", "age", "info = NULL"], + ["id = ?"], + ) + check querycompare(q, sql("UPDATE table SET name = ?, age = ?, info = NULL WHERE id = ?")) + + + test "set NULL and where=?": + let q = sqlUpdate( + "table", + ["name", "age", "info = NULL"], + ["id=?"], + ) + check querycompare(q, sql("UPDATE table SET name = ?, age = ?, info = NULL WHERE id=?")) + + test "set =NULL and where=?": + let q = sqlUpdate( + "table", + ["name", "age", "info=NULL"], + ["id=?"], + ) + check querycompare(q, sql("UPDATE table SET name = ?, age = ?, info=NULL WHERE id=?")) + + + + suite "update macro": test "update value": diff --git a/tests/update/test_update_arrays.nim b/tests/update/test_update_arrays.nim index f8b6545..7ae31b2 100644 --- a/tests/update/test_update_arrays.nim +++ b/tests/update/test_update_arrays.nim @@ -38,6 +38,20 @@ suite "update - arrays": check querycompare(q, sql("UPDATE table SET project_ids = ARRAY_REMOVE(project_ids, ?) WHERE id = ?")) + test "update array with array_cat": + let q = sqlUpdate( + table = "projects", + data = [ + "sorting = ARRAY_CAT(sorting, ?::int[])" + ], + where = [ + "id = ANY(?::int[])" + ] + ) + + check querycompare(q, sql("UPDATE projects SET sorting = ARRAY_CAT(sorting, ?::int[]) WHERE id = ANY(?::int[])")) + + suite "update - arrays where cond ANY":