@@ -2,158 +2,56 @@ local core = require "jester.core"
2
2
3
3
local _M = {}
4
4
5
- --[[
6
- Load data from a database into storage.
7
- ]]
8
- function _M .load_data (action )
9
- local fields = action .fields
10
- local filters = action .filters or {}
11
- local multiple = action .multiple
12
- local sort = action .sort
13
- local sort_order = action .sort_order
14
- local area = action .storage_area or " data"
15
- if fields then
16
- local dbh , conf = connect (action )
17
- local limit = multiple and " " or " LIMIT 1"
18
- -- Optional sort.
19
- local load_sort = sort and build_sort (sort , sort_order ) or " "
20
- -- Build the query.
21
- local sql = " SELECT " .. build_load_fields (fields ) .. " FROM " .. conf .table .. build_where (filters ) .. load_sort .. limit
22
- core .debug_log (" Executing query: %s" , sql )
23
- local count , suffix = 0 , " "
24
- -- Clean out storage area before loading in new data.
25
- core .clear_storage (area )
26
- -- Loop through the returned rows.
27
- assert (dbh :query (sql , function (row )
28
- count = count + 1
29
- for col , val in pairs (row ) do
30
- -- Multi-row results get a row suffix.
31
- if multiple then
32
- suffix = " _" .. count
33
- end
34
- core .set_storage (area , col .. suffix , val )
35
- end
36
- end ))
37
- dbh :release ()
38
- -- Multi-row results get a special count key.
39
- if multiple then
40
- core .debug_log (" Query rows returned: %d" , count )
41
- core .set_storage (area , " __count" , tonumber (count ))
42
- end
43
- end
44
- end
5
+ local escape
45
6
46
7
--[[
47
- Load data row counts from a database into storage .
8
+ Escapes special characters for the MySQL database.
48
9
]]
49
- function _M .load_data_count (action )
50
- local count_field = action .count_field
51
- local filters = action .filters or {}
52
- local area = action .storage_area or " data"
53
- local key = action .storage_key or " count"
54
- if count_field then
55
- local dbh , conf = connect (action )
56
- -- Build the query.
57
- local sql = " SELECT COUNT(" .. count_field .. " ) AS count FROM " .. conf .table .. build_where (filters )
58
- core .debug_log (" Executing query: %s" , sql )
59
- local count
60
- -- Loop through the returned rows.
61
- assert (dbh :query (sql , function (row ) count = tonumber (row .count ) end ))
62
- dbh :release ()
63
- core .set_storage (area , key , count )
64
- end
10
+ local function mysql_escape (string )
11
+ -- Single quote, double quote, backspace.
12
+ string = string.gsub (string , " (['\"\\ ])" , function (x ) return " \\ " .. x end )
13
+ -- Null byte.
14
+ string = string.gsub (string , " %z" , " \\ 0" )
15
+ return string
65
16
end
66
17
67
18
--[[
68
- Update data in a database.
19
+ Escapes special characters for the Postgres database.
69
20
]]
70
- function _M .update_data (action )
71
- local fields = action .fields
72
- local filters = action .filters or {}
73
- local update_type = action .update_type
74
- if fields then
75
- local dbh , conf = connect (action )
76
- local where = build_where (filters )
77
- local count = 0
78
- local message
79
- -- No type specified, or update forced, so try an update first.
80
- if not update_type or update_type == " update" then
81
- sql = " UPDATE " .. conf .table .. " SET " .. build_update_fields (fields ) .. where
82
- core .debug_log (" Executing query: %s" , sql )
83
- assert (dbh :query (sql ))
84
- message = " updated"
85
- count = dbh :affected_rows ()
86
- end
87
- -- Insert forced, or no rows updated and update is not forced, so insert.
88
- if update_type == " insert" or (count == 0 and update_type ~= " update" ) then
89
- local insert_fields , values = build_insert (filters , fields )
90
- sql = " INSERT INTO " .. conf .table .. " (" .. insert_fields .. " ) VALUES (" .. values .. " )"
91
- core .debug_log (" Executing query: %s" , sql )
92
- assert (dbh :query (sql ))
93
- message = " inserted"
94
- count = 1
95
- end
96
- dbh :release ()
97
- core .debug_log (" Rows %s: %d" , message , count )
98
- end
21
+ local function pgsql_escape (string )
22
+ -- Single quote.
23
+ string = string.gsub (string , " '" , " ''" )
24
+ -- Null byte.
25
+ string = string.gsub (string , " %z" , " " )
26
+ return string
99
27
end
100
28
101
29
--[[
102
- Delete data from a database.
30
+ Escapes special characters for the SQLite database.
103
31
]]
104
- function _M .delete_data (action )
105
- local filters = action .filters or {}
106
- local dbh , conf = connect (action )
107
- local sql = " DELETE FROM " .. conf .table .. build_where (filters )
108
- core .debug_log (" Executing query: %s" , sql )
109
- assert (dbh :query (sql ))
110
- dbh :release ()
32
+ local function sqlite_escape (string )
33
+ -- Single quote.
34
+ string = string.gsub (string , " '" , " ''" )
35
+ -- Null byte.
36
+ string = string.gsub (string , " %z" , " " )
37
+ return string
111
38
end
112
39
113
40
--[[
114
- Execute custom queries on a database, optionally returning data .
41
+ Sets the escape function based on the database type .
115
42
]]
116
- function _M .query_data (action )
117
- local query = action .query
118
- local return_fields = action .return_fields
119
- local area = action .storage_area or " data"
120
- local tokens = action .tokens
121
- local dbh , conf = connect (action )
122
- local sql
123
-
124
- -- Token replacements.
125
- if tokens then
126
- require " jester.support.string"
127
- for k ,v in pairs (tokens ) do
128
- tokens [k ] = escape (v )
129
- end
130
- sql = string .token_replace (query , tokens )
131
- else
132
- sql = query
133
- end
134
- core .debug_log (" Executing query: %s" , sql )
135
- if return_fields then
136
- local count = 0
137
- -- Clean out storage area before loading in new data.
138
- core .clear_storage (area )
139
- -- Loop through the returned rows.
140
- assert (dbh :query (sql , function (row )
141
- count = count + 1
142
- for col , val in pairs (row ) do
143
- core .set_storage (area , col .. " _" .. count , val )
144
- end
145
- end ))
146
- dbh :release ()
147
- core .debug_log (" Query rows returned: %d" , count )
148
- core .set_storage (area , " __count" , tonumber (count ))
43
+ local function set_escape (db_type )
44
+ if db_type == " mysql" then
45
+ escape = mysql_escape
46
+ elseif db_type == " pgsql" then
47
+ escape = pgsql_escape
48
+ elseif db_type == " sqlite" then
49
+ escape = sqlite_escape
149
50
else
150
- assert ( dbh : query ( sql ))
51
+ error ( string.format ( [[ Unsupported database type %s ]] , db_type ))
151
52
end
152
- dbh :release ()
153
53
end
154
54
155
- local escape
156
-
157
55
--[[
158
56
Connect to a database.
159
57
]]
@@ -283,51 +181,153 @@ local function build_sort(sort, sort_order)
283
181
end
284
182
285
183
--[[
286
- Sets the escape function based on the database type .
184
+ Load data from a database into storage .
287
185
]]
288
- local function set_escape (db_type )
289
- if db_type == " mysql" then
290
- escape = mysql_escape
291
- elseif db_type == " pgsql" then
292
- escape = pgsql_escape
293
- elseif db_type == " sqlite" then
294
- escape = sqlite_escape
295
- else
296
- error (string.format ([[ Unsupported database type %s]] , db_type ))
186
+ function _M .load_data (action )
187
+ local fields = action .fields
188
+ local filters = action .filters or {}
189
+ local multiple = action .multiple
190
+ local sort = action .sort
191
+ local sort_order = action .sort_order
192
+ local area = action .storage_area or " data"
193
+ if fields then
194
+ local dbh , conf = connect (action )
195
+ local limit = multiple and " " or " LIMIT 1"
196
+ -- Optional sort.
197
+ local load_sort = sort and build_sort (sort , sort_order ) or " "
198
+ -- Build the query.
199
+ local sql = " SELECT " .. build_load_fields (fields ) .. " FROM " .. conf .table .. build_where (filters ) .. load_sort .. limit
200
+ core .debug_log (" Executing query: %s" , sql )
201
+ local count , suffix = 0 , " "
202
+ -- Clean out storage area before loading in new data.
203
+ core .clear_storage (area )
204
+ -- Loop through the returned rows.
205
+ assert (dbh :query (sql , function (row )
206
+ count = count + 1
207
+ for col , val in pairs (row ) do
208
+ -- Multi-row results get a row suffix.
209
+ if multiple then
210
+ suffix = " _" .. count
211
+ end
212
+ core .set_storage (area , col .. suffix , val )
213
+ end
214
+ end ))
215
+ dbh :release ()
216
+ -- Multi-row results get a special count key.
217
+ if multiple then
218
+ core .debug_log (" Query rows returned: %d" , count )
219
+ core .set_storage (area , " __count" , tonumber (count ))
220
+ end
297
221
end
298
222
end
299
223
300
224
--[[
301
- Escapes special characters for the MySQL database.
225
+ Load data row counts from a database into storage .
302
226
]]
303
- local function mysql_escape (string )
304
- -- Single quote, double quote, backspace.
305
- string = string.gsub (string , " (['\"\\ ])" , function (x ) return " \\ " .. x end )
306
- -- Null byte.
307
- string = string.gsub (string , " %z" , " \\ 0" )
308
- return string
227
+ function _M .load_data_count (action )
228
+ local count_field = action .count_field
229
+ local filters = action .filters or {}
230
+ local area = action .storage_area or " data"
231
+ local key = action .storage_key or " count"
232
+ if count_field then
233
+ local dbh , conf = connect (action )
234
+ -- Build the query.
235
+ local sql = " SELECT COUNT(" .. count_field .. " ) AS count FROM " .. conf .table .. build_where (filters )
236
+ core .debug_log (" Executing query: %s" , sql )
237
+ local count
238
+ -- Loop through the returned rows.
239
+ assert (dbh :query (sql , function (row ) count = tonumber (row .count ) end ))
240
+ dbh :release ()
241
+ core .set_storage (area , key , count )
242
+ end
309
243
end
310
244
311
245
--[[
312
- Escapes special characters for the Postgres database.
246
+ Update data in a database.
313
247
]]
314
- local function pgsql_escape (string )
315
- -- Single quote.
316
- string = string.gsub (string , " '" , " ''" )
317
- -- Null byte.
318
- string = string.gsub (string , " %z" , " " )
319
- return string
248
+ function _M .update_data (action )
249
+ local fields = action .fields
250
+ local filters = action .filters or {}
251
+ local update_type = action .update_type
252
+ if fields then
253
+ local dbh , conf = connect (action )
254
+ local where = build_where (filters )
255
+ local count = 0
256
+ local message
257
+ -- No type specified, or update forced, so try an update first.
258
+ if not update_type or update_type == " update" then
259
+ sql = " UPDATE " .. conf .table .. " SET " .. build_update_fields (fields ) .. where
260
+ core .debug_log (" Executing query: %s" , sql )
261
+ assert (dbh :query (sql ))
262
+ message = " updated"
263
+ count = dbh :affected_rows ()
264
+ end
265
+ -- Insert forced, or no rows updated and update is not forced, so insert.
266
+ if update_type == " insert" or (count == 0 and update_type ~= " update" ) then
267
+ local insert_fields , values = build_insert (filters , fields )
268
+ sql = " INSERT INTO " .. conf .table .. " (" .. insert_fields .. " ) VALUES (" .. values .. " )"
269
+ core .debug_log (" Executing query: %s" , sql )
270
+ assert (dbh :query (sql ))
271
+ message = " inserted"
272
+ count = 1
273
+ end
274
+ dbh :release ()
275
+ core .debug_log (" Rows %s: %d" , message , count )
276
+ end
320
277
end
321
278
322
279
--[[
323
- Escapes special characters for the SQLite database.
280
+ Delete data from a database.
324
281
]]
325
- local function sqlite_escape (string )
326
- -- Single quote.
327
- string = string.gsub (string , " '" , " ''" )
328
- -- Null byte.
329
- string = string.gsub (string , " %z" , " " )
330
- return string
282
+ function _M .delete_data (action )
283
+ local filters = action .filters or {}
284
+ local dbh , conf = connect (action )
285
+ local sql = " DELETE FROM " .. conf .table .. build_where (filters )
286
+ core .debug_log (" Executing query: %s" , sql )
287
+ assert (dbh :query (sql ))
288
+ dbh :release ()
289
+ end
290
+
291
+ --[[
292
+ Execute custom queries on a database, optionally returning data.
293
+ ]]
294
+ function _M .query_data (action )
295
+ local query = action .query
296
+ local return_fields = action .return_fields
297
+ local area = action .storage_area or " data"
298
+ local tokens = action .tokens
299
+ local dbh , conf = connect (action )
300
+ local sql
301
+
302
+ -- Token replacements.
303
+ if tokens then
304
+ require " jester.support.string"
305
+ for k ,v in pairs (tokens ) do
306
+ tokens [k ] = escape (v )
307
+ end
308
+ sql = string .token_replace (query , tokens )
309
+ else
310
+ sql = query
311
+ end
312
+ core .debug_log (" Executing query: %s" , sql )
313
+ if return_fields then
314
+ local count = 0
315
+ -- Clean out storage area before loading in new data.
316
+ core .clear_storage (area )
317
+ -- Loop through the returned rows.
318
+ assert (dbh :query (sql , function (row )
319
+ count = count + 1
320
+ for col , val in pairs (row ) do
321
+ core .set_storage (area , col .. " _" .. count , val )
322
+ end
323
+ end ))
324
+ dbh :release ()
325
+ core .debug_log (" Query rows returned: %d" , count )
326
+ core .set_storage (area , " __count" , tonumber (count ))
327
+ else
328
+ assert (dbh :query (sql ))
329
+ end
330
+ dbh :release ()
331
331
end
332
332
333
333
return _M
0 commit comments