11# Copyright 2020 - Thomas T. Jarløv
22
33when NimMajor >= 2 :
4- import
5- db_connector/ db_common
4+ import db_connector/ db_common
65else :
7- import
8- std/ db_common
6+ import std/ db_common
97
108import
119 std/ macros,
1210 std/ strutils
1311
1412import
15- ./ utils
13+ ./ utils_private
14+
15+ from ./ utils import ArgsContainer
1616
1717
1818proc 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
4653proc 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
10775proc 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
153120proc 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+ #
179167proc 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+
192183proc 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