Skip to content

Commit 634c519

Browse files
committed
query: update
1 parent 69b7813 commit 634c519

File tree

1 file changed

+132
-92
lines changed

1 file changed

+132
-92
lines changed

src/sqlbuilderpkg/update.nim

Lines changed: 132 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
# Copyright 2020 - Thomas T. Jarløv
22

33
when NimMajor >= 2:
4-
import
5-
db_connector/db_common
4+
import db_connector/db_common
65
else:
7-
import
8-
std/db_common
6+
import std/db_common
97

108
import
119
std/macros,
1210
std/strutils
1311

1412
import
15-
./utils
13+
./utils_private
14+
15+
from ./utils import ArgsContainer
1616

1717

1818
proc updateSetFormat(v: string): string =
19+
## The table columns that we want to update. Validate whether
20+
## the user has provided equal sign or not.
21+
1922
let
2023
field = v.strip()
2124
fieldSplit = field.split("=")
@@ -25,93 +28,63 @@ proc updateSetFormat(v: string): string =
2528
#
2629
if fieldSplit.len() == 2:
2730
#
28-
# If the data is only having equal but no value, insert a `?` sign
31+
# If the data is only having equal but no value, insert a `?` sign.
32+
# Eg. `field =`
2933
#
3034
if fieldSplit[1] == "":
3135
return (field & " ?")
36+
3237
#
3338
# Otherwise just add the data as is, eg. `field = value`
39+
# Eg. `field = value`
3440
#
3541
else:
3642
return (field)
3743

3844
#
3945
# Otherwise revert to default
46+
# Eg. `field = ?`
4047
#
4148
else:
4249
return (field & " = ?")
4350

4451

4552

4653
proc updateSet(data: varargs[string]): string =
54+
## Update the SET part of the query.
55+
##
56+
## => ["name", "age = "]
57+
## => `SET name = ?, age = ?`
58+
##
4759
for i, d in data:
4860
if i > 0:
4961
result.add(", ")
50-
5162
result.add(updateSetFormat(d))
52-
5363
return result
5464

5565

56-
proc updateWhereFormat(v: string): string =
57-
let
58-
field = v.strip()
59-
60-
var fieldSplit: seq[string]
61-
if field.contains(" "):
62-
if field.contains("="):
63-
fieldSplit = field.split("=")
64-
elif field.contains("IS NOT"):
65-
fieldSplit = field.split("IS NOT")
66-
elif field.contains("IS"):
67-
fieldSplit = field.split("IS")
68-
elif field.contains("NOT IN"):
69-
fieldSplit = field.split("NOT IN")
70-
elif field.contains("IN"):
71-
fieldSplit = field.split("IN")
72-
elif field.contains("!="):
73-
fieldSplit = field.split("!=")
74-
elif field.contains("<="):
75-
fieldSplit = field.split("<=")
76-
elif field.contains(">="):
77-
fieldSplit = field.split(">=")
78-
elif field.contains("<"):
79-
fieldSplit = field.split("<")
80-
elif field.contains(">"):
81-
fieldSplit = field.split(">")
82-
else:
83-
fieldSplit = field.split("=")
84-
85-
#
86-
# Does the data have a `=` sign?
87-
#
88-
if fieldSplit.len() == 2:
89-
#
90-
# If the data is only having equal but no value, insert a `?` sign
91-
#
92-
if fieldSplit[1] == "":
93-
return (field & " ?")
94-
#
95-
# Otherwise just add the data as is, eg. `field = value`
96-
#
97-
else:
98-
return (field)
99-
100-
#
101-
# Otherwise revert to default
102-
#
103-
else:
104-
return (field & " = ?")
66+
proc updateArray(arrayType: string, arrayAppend: varargs[string]): string =
67+
## Format the arrayAppend part of the query.
68+
for i, d in arrayAppend:
69+
if i > 0:
70+
result.add(", ")
71+
result.add(d & " = " & arrayType & "(" & d & ", ?)")
72+
return result
10573

10674

10775
proc updateWhere(where: varargs[string]): string =
76+
## Update the WHERE part of the query.
77+
##
78+
## => ["name", "age = "]
79+
## => `WHERE name = ?, age = ?`
80+
##
81+
## => ["name = ", "age >"]
82+
## => `WHERE name = ?, age > ?`
10883
var wes = " WHERE "
10984
for i, v in where:
11085
if i > 0:
11186
wes.add(" AND ")
112-
113-
wes.add(updateWhereFormat(v))
114-
87+
wes.add(formatWhereParams(v))
11588
return wes
11689

11790

@@ -141,79 +114,146 @@ proc sqlUpdate*(table: string, data: varargs[string], where: varargs[string], ar
141114
else:
142115
wes.add(d & " = ?")
143116

144-
when defined(testSqlquery):
145-
echo fields & wes
146-
147-
when defined(test):
148-
testout = fields & wes
149-
150117
result = sql(fields & wes)
151118

152119

153120
proc sqlUpdate*(
154121
table: string,
155122
data: varargs[string],
156-
where: varargs[string]
123+
where: varargs[string],
157124
): SqlQuery =
158125
## SQL builder for UPDATE queries
159-
## Does NOT check for NULL values
160-
161-
var fields = "UPDATE " & table & " SET "
162-
126+
##
127+
## Can utilize custom equal signs and can also check for NULL values
128+
##
129+
## data => ["name", "age = ", "email = NULL"]
130+
## where => ["id = ", "name IS NULL"]
131+
var fields: string
163132
fields.add(updateSet(data))
164-
165133
fields.add(updateWhere(where))
134+
result = sql("UPDATE " & table & " SET " & fields)
166135

167136

168-
when defined(testSqlquery):
169-
echo fields
170-
171-
when defined(test):
172-
testout = fields
137+
proc sqlUpdateArrayRemove*(
138+
table: string,
139+
arrayRemove: varargs[string],
140+
where: varargs[string],
141+
): SqlQuery =
142+
## ARRAY_REMOVE
143+
var fields: string
144+
fields.add(updateArray("ARRAY_REMOVE", arrayRemove))
145+
fields.add(updateWhere(where))
146+
result = sql("UPDATE " & table & " SET " & fields)
173147

174-
result = sql(fields)
175148

149+
proc sqlUpdateArrayAppend*(
150+
table: string,
151+
arrayAppend: varargs[string],
152+
where: varargs[string],
153+
): SqlQuery =
154+
## ARRAY_APPEND
155+
var fields: string
156+
fields.add(updateArray("ARRAY_APPEND", arrayAppend))
157+
fields.add(updateWhere(where))
158+
result = sql("UPDATE " & table & " SET " & fields)
176159

177160

178161

162+
#
163+
#
164+
# Macro based
165+
#
166+
#
179167
proc updateSet(data: NimNode): string =
168+
## Update the SET part of the query.
169+
##
170+
## => ["name", "age = "]
171+
## => `SET name = ?, age = ?`
172+
##
180173
for i, v in data:
181174
# Convert NimNode to string
182175
let d = $v
183-
184176
if i > 0:
185177
result.add(", ")
186-
187178
result.add(updateSetFormat(d))
188-
189179
return result
190180

191181

182+
192183
proc updateWhere(where: NimNode): string =
184+
## Update the WHERE part of the query.
185+
##
186+
## => ["name", "age = "]
187+
## => `WHERE name = ?, age = ?`
188+
##
189+
## => ["name = ", "age >"]
190+
## => `WHERE name = ?, age > ?`
193191
var wes = " WHERE "
194192
for i, v in where:
195193
# Convert NimNode to string
196194
let d = $v
197-
198195
if i > 0:
199196
wes.add(" AND ")
200-
201-
wes.add(updateWhereFormat(d))
202-
197+
wes.add(formatWhereParams(d))
203198
return wes
204199

205200

206-
macro sqlUpdateMacro*(table: string, data: varargs[string], where: varargs[string]): SqlQuery =
201+
202+
macro sqlUpdateMacro*(
203+
table: string,
204+
data: varargs[string],
205+
where: varargs[string]
206+
): SqlQuery =
207207
## SQL builder for UPDATE queries
208-
## Does NOT check for NULL values
208+
##
209+
## Can utilize custom equal signs and can also check for NULL values
210+
##
211+
## data => ["name", "age = ", "email = NULL"]
212+
## where => ["id = ", "name IS NULL"]
213+
var fields: string
214+
fields.add(updateSet(data))
215+
fields.add(updateWhere(where))
216+
result = parseStmt("sql(\"" & "UPDATE " & $table & " SET " & fields & "\")")
209217

210-
var fields = "UPDATE " & $table & " SET "
211218

212-
fields.add(updateSet(data))
219+
#
220+
# Macro arrays
221+
#
222+
proc updateArray(arrayType: string, arrayAppend: NimNode): string =
223+
# Format the arrayAppend part of the query.
224+
225+
for i, v in arrayAppend:
226+
let d = $v
227+
if d == "":
228+
continue
229+
230+
if i > 0:
231+
result.add(", ")
213232

233+
result.add(d & " = " & $arrayType & "(" & d & ", ?)")
234+
235+
return result
236+
237+
238+
macro sqlUpdateMacroArrayRemove*(
239+
table: string,
240+
arrayRemove: varargs[string],
241+
where: varargs[string],
242+
): SqlQuery =
243+
## ARRAY_REMOVE macro
244+
var fields: string
245+
fields.add(updateArray("ARRAY_REMOVE", arrayRemove))
214246
fields.add(updateWhere(where))
247+
result = parseStmt("sql(\"" & "UPDATE " & $table & " SET " & fields & "\")")
215248

216-
when defined(testSqlquery):
217-
echo fields
218249

219-
result = parseStmt("sql(\"" & fields & "\")")
250+
macro sqlUpdateMacroArrayAppend*(
251+
table: string,
252+
arrayAppend: varargs[string],
253+
where: varargs[string],
254+
): SqlQuery =
255+
## ARRAY_APPEND macro
256+
var fields: string
257+
fields.add(updateArray("ARRAY_APPEND", arrayAppend))
258+
fields.add(updateWhere(where))
259+
result = parseStmt("sql(\"" & "UPDATE " & $table & " SET " & fields & "\")")

0 commit comments

Comments
 (0)