From 9cb170e4dbeea45349a204359640e6c875be992c Mon Sep 17 00:00:00 2001 From: ThomasTJdev Date: Sat, 24 Feb 2024 21:03:54 +0100 Subject: [PATCH] Support complext where with parenthesis --- sqlbuilder.nimble | 2 +- src/sqlbuilderpkg/select.nim | 32 ++++++++++++++- tests/select/test_select.nim | 48 +++++++++++++++++++++++ tests/select/test_select_const_where.nim | 50 ++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 3 deletions(-) diff --git a/sqlbuilder.nimble b/sqlbuilder.nimble index 45c670a..0a0e36a 100644 --- a/sqlbuilder.nimble +++ b/sqlbuilder.nimble @@ -1,6 +1,6 @@ # Package -version = "1.0.5" +version = "1.0.6" author = "ThomasTJdev" description = "SQL builder" license = "MIT" diff --git a/src/sqlbuilderpkg/select.nim b/src/sqlbuilderpkg/select.nim index 7b29c7c..521d75e 100644 --- a/src/sqlbuilderpkg/select.nim +++ b/src/sqlbuilderpkg/select.nim @@ -77,6 +77,15 @@ proc sqlSelectConstWhere(where: varargs[string], usePrepared: NimNode): string = if v.len() > 0: + # + # If this is self-contained where with parenthesis in front and back + # add it and continue + # + # => (xx = yy AND zz = qq) + if v[0] == '(' and v[v.high] == ')': + wes.add(v) + continue + if needParenthesis: wes.add("(") @@ -137,7 +146,12 @@ proc sqlSelectConstWhere(where: varargs[string], usePrepared: NimNode): string = # Value included already if eSplit.len() == 2 and eSplit[0].strip().len() > 0 and eSplit[1].strip().len() > 0: if boolVal(usePrepared): - prepareCount += 1 + wes.add(v) + else: + wes.add(v) + # If there's multiple elements + elif eSplit.len() > 2 and eSplit[eSplit.high].len() > 1: + if boolVal(usePrepared): wes.add(v) else: wes.add(v) @@ -528,6 +542,15 @@ proc sqlSelect*( wes.add(" AND ") if d != "": + # + # If this is self-contained where with parenthesis in front and back + # add it and continue + # + # => (xx = yy AND zz = qq) + if d[0] == '(' and d[d.high] == ')': + wes.add(d) + continue + let dataUpper = d.toUpperAscii() let needParenthesis = dataUpper.contains(" OR ") or dataUpper.contains(" AND ") @@ -594,7 +617,12 @@ proc sqlSelect*( # Value included already if eSplit.len() == 2 and eSplit[0].strip().len() > 0 and eSplit[1].strip().len() > 0: if usePrepared: - prepareCount += 1 + wes.add(d) + else: + wes.add(d) + # If there's multiple elements + elif eSplit.len() > 2 and eSplit[eSplit.high].len() > 1: + if usePrepared: wes.add(d) else: wes.add(d) diff --git a/tests/select/test_select.nim b/tests/select/test_select.nim index cc56175..2f3509a 100644 --- a/tests/select/test_select.nim +++ b/tests/select/test_select.nim @@ -619,6 +619,54 @@ suite "test where cases custom formatting": + test "where - complex where item - with parenthesis around": + + let test = sqlSelect( + table = "history", + tableAs = "history", + select = [ + "person.name as user_id", + "history.creation" + ], + where = [ + "history.project_id =", + "history.item_id =", + "history.is_deleted IS NULL", + "(history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create')" + ], + 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.item_id = ? AND history.is_deleted IS NULL AND (history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create') ORDER BY history.creation DESC, history.id DESC")) + + + + test "where - complex where item - without parenthesis around": + + let test = sqlSelect( + table = "history", + tableAs = "history", + select = [ + "person.name as user_id", + "history.creation" + ], + where = [ + "history.project_id =", + "history.item_id =", + "history.is_deleted IS NULL", + "history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create'" + ], + 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.item_id = ? AND history.is_deleted IS NULL AND (history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create') ORDER BY history.creation DESC, history.id DESC")) + suite "test using DB names for columns": diff --git a/tests/select/test_select_const_where.nim b/tests/select/test_select_const_where.nim index cee3799..665196e 100644 --- a/tests/select/test_select_const_where.nim +++ b/tests/select/test_select_const_where.nim @@ -202,3 +202,53 @@ suite "test where cases custom formatting": + test "where - complex where item - with parenthesis around": + + let test = sqlSelectConst( + table = "history", + tableAs = "history", + select = [ + "person.name as user_id", + "history.creation" + ], + where = [ + "history.project_id =", + "history.item_id =", + "history.is_deleted IS NULL", + "(history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create')" + ], + 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.item_id = ? AND history.is_deleted IS NULL AND (history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create') ORDER BY history.creation DESC, history.id DESC")) + + + + test "where - complex where item - without parenthesis around": + + let test = sqlSelectConst( + table = "history", + tableAs = "history", + select = [ + "person.name as user_id", + "history.creation" + ], + where = [ + "history.project_id =", + "history.item_id =", + "history.is_deleted IS NULL", + "history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create'" + ], + 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.item_id = ? AND history.is_deleted IS NULL AND (history.choice = 'Comment' OR history.choice = 'Picture' OR history.choice = 'File' OR history.choice = 'Design' OR history.choice = 'Update' OR history.choice = 'Create') ORDER BY history.creation DESC, history.id DESC")) + + +