diff options
Diffstat (limited to 'src/include/gnunet_sq_lib.h')
-rw-r--r-- | src/include/gnunet_sq_lib.h | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/src/include/gnunet_sq_lib.h b/src/include/gnunet_sq_lib.h new file mode 100644 index 000000000..c196d7767 --- /dev/null +++ b/src/include/gnunet_sq_lib.h | |||
@@ -0,0 +1,451 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | /** | ||
17 | * @file include/gnunet_sq_lib.h | ||
18 | * @brief helper functions for Sqlite3 DB interactions | ||
19 | * @author Christian Grothoff | ||
20 | */ | ||
21 | #ifndef GNUNET_SQ_LIB_H | ||
22 | #define GNUNET_SQ_LIB_H | ||
23 | |||
24 | #include <sqlite3.h> | ||
25 | #include "gnunet_util_lib.h" | ||
26 | |||
27 | |||
28 | /** | ||
29 | * Function called to convert input argument into SQL parameters. | ||
30 | * | ||
31 | * @param cls closure | ||
32 | * @param data pointer to input argument | ||
33 | * @param data_len number of bytes in @a data (if applicable) | ||
34 | * @param stmt sqlite statement to bind parameters for | ||
35 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
36 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
37 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
38 | */ | ||
39 | typedef int | ||
40 | (*GNUNET_SQ_QueryConverter)(void *cls, | ||
41 | const void *data, | ||
42 | size_t data_len, | ||
43 | sqlite3_stmt *stmt, | ||
44 | unsigned int off); | ||
45 | |||
46 | |||
47 | /** | ||
48 | * @brief Description of a DB query parameter. | ||
49 | */ | ||
50 | struct GNUNET_SQ_QueryParam | ||
51 | { | ||
52 | |||
53 | /** | ||
54 | * Function for how to handle this type of entry. | ||
55 | */ | ||
56 | GNUNET_SQ_QueryConverter conv; | ||
57 | |||
58 | /** | ||
59 | * Closure for @e conv. | ||
60 | */ | ||
61 | void *conv_cls; | ||
62 | |||
63 | /** | ||
64 | * Data or NULL. | ||
65 | */ | ||
66 | const void *data; | ||
67 | |||
68 | /** | ||
69 | * Size of @e data | ||
70 | */ | ||
71 | size_t size; | ||
72 | |||
73 | /** | ||
74 | * Number of parameters eaten by this operation. | ||
75 | */ | ||
76 | unsigned int num_params; | ||
77 | }; | ||
78 | |||
79 | |||
80 | /** | ||
81 | * End of query parameter specification. | ||
82 | */ | ||
83 | #define GNUNET_SQ_query_param_end { NULL, NULL, NULL, 0, 0 } | ||
84 | |||
85 | |||
86 | /** | ||
87 | * Generate query parameter for a buffer @a ptr of | ||
88 | * @a ptr_size bytes. | ||
89 | * | ||
90 | * @param ptr pointer to the query parameter to pass | ||
91 | * @oaran ptr_size number of bytes in @a ptr | ||
92 | */ | ||
93 | struct GNUNET_SQ_QueryParam | ||
94 | GNUNET_SQ_query_param_fixed_size (const void *ptr, | ||
95 | size_t ptr_size); | ||
96 | |||
97 | |||
98 | |||
99 | /** | ||
100 | * Generate query parameter for a string. | ||
101 | * | ||
102 | * @param ptr pointer to the string query parameter to pass | ||
103 | */ | ||
104 | struct GNUNET_SQ_QueryParam | ||
105 | GNUNET_SQ_query_param_string (const char *ptr); | ||
106 | |||
107 | |||
108 | /** | ||
109 | * Generate fixed-size query parameter with size determined | ||
110 | * by variable type. | ||
111 | * | ||
112 | * @param x pointer to the query parameter to pass. | ||
113 | */ | ||
114 | #define GNUNET_SQ_query_param_auto_from_type(x) GNUNET_SQ_query_param_fixed_size ((x), sizeof (*(x))) | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Generate query parameter for an RSA public key. The | ||
119 | * database must contain a BLOB type in the respective position. | ||
120 | * | ||
121 | * @param x the query parameter to pass. | ||
122 | */ | ||
123 | struct GNUNET_SQ_QueryParam | ||
124 | GNUNET_SQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x); | ||
125 | |||
126 | |||
127 | /** | ||
128 | * Generate query parameter for an RSA signature. The | ||
129 | * database must contain a BLOB type in the respective position. | ||
130 | * | ||
131 | * @param x the query parameter to pass | ||
132 | */ | ||
133 | struct GNUNET_SQ_QueryParam | ||
134 | GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x); | ||
135 | |||
136 | |||
137 | /** | ||
138 | * Generate query parameter for an absolute time value. | ||
139 | * The database must store a 64-bit integer. | ||
140 | * | ||
141 | * @param x pointer to the query parameter to pass | ||
142 | */ | ||
143 | struct GNUNET_SQ_QueryParam | ||
144 | GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | ||
145 | |||
146 | |||
147 | /** | ||
148 | * Generate query parameter for an absolute time value. | ||
149 | * The database must store a 64-bit integer. | ||
150 | * | ||
151 | * @param x pointer to the query parameter to pass | ||
152 | */ | ||
153 | struct GNUNET_SQ_QueryParam | ||
154 | GNUNET_SQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x); | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Generate query parameter for an uint16_t in host byte order. | ||
159 | * | ||
160 | * @param x pointer to the query parameter to pass | ||
161 | */ | ||
162 | struct GNUNET_SQ_QueryParam | ||
163 | GNUNET_SQ_query_param_uint16 (const uint16_t *x); | ||
164 | |||
165 | |||
166 | /** | ||
167 | * Generate query parameter for an uint32_t in host byte order. | ||
168 | * | ||
169 | * @param x pointer to the query parameter to pass | ||
170 | */ | ||
171 | struct GNUNET_SQ_QueryParam | ||
172 | GNUNET_SQ_query_param_uint32 (const uint32_t *x); | ||
173 | |||
174 | |||
175 | /** | ||
176 | * Generate query parameter for an uint16_t in host byte order. | ||
177 | * | ||
178 | * @param x pointer to the query parameter to pass | ||
179 | */ | ||
180 | struct GNUNET_SQ_QueryParam | ||
181 | GNUNET_SQ_query_param_uint64 (const uint64_t *x); | ||
182 | |||
183 | |||
184 | /** | ||
185 | * Execute binding operations for a prepared statement. | ||
186 | * | ||
187 | * @param db_conn database connection | ||
188 | * @param params parameters to the statement | ||
189 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
190 | */ | ||
191 | int | ||
192 | GNUNET_SQ_bind (sqlite3_stmt *stmt, | ||
193 | const struct GNUNET_SQ_QueryParam *params); | ||
194 | |||
195 | |||
196 | /** | ||
197 | * Reset @a stmt and log error. | ||
198 | * | ||
199 | * @param dbh database handle | ||
200 | * @param stmt statement to reset | ||
201 | */ | ||
202 | void | ||
203 | GNUNET_SQ_reset (sqlite3 *dbh, | ||
204 | sqlite3_stmt *stmt); | ||
205 | |||
206 | |||
207 | /** | ||
208 | * Extract data from a Postgres database @a result at row @a row. | ||
209 | * | ||
210 | * @param cls closure | ||
211 | * @param result where to extract data from | ||
212 | * @param column column to extract data from | ||
213 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
214 | * @param[out] dst where to store the result | ||
215 | * @return | ||
216 | * #GNUNET_YES if all results could be extracted | ||
217 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
218 | */ | ||
219 | typedef int | ||
220 | (*GNUNET_SQ_ResultConverter)(void *cls, | ||
221 | sqlite3_stmt *result, | ||
222 | unsigned int column, | ||
223 | size_t *dst_size, | ||
224 | void *dst); | ||
225 | |||
226 | |||
227 | /** | ||
228 | * @brief Description of a DB result cell. | ||
229 | */ | ||
230 | struct GNUNET_SQ_ResultSpec; | ||
231 | |||
232 | |||
233 | /** | ||
234 | * Function called to clean up memory allocated | ||
235 | * by a #GNUNET_SQ_ResultConverter. | ||
236 | * | ||
237 | * @param cls closure | ||
238 | */ | ||
239 | typedef void | ||
240 | (*GNUNET_SQ_ResultCleanup)(void *cls); | ||
241 | |||
242 | |||
243 | /** | ||
244 | * @brief Description of a DB result cell. | ||
245 | */ | ||
246 | struct GNUNET_SQ_ResultSpec | ||
247 | { | ||
248 | |||
249 | /** | ||
250 | * What is the format of the result? | ||
251 | */ | ||
252 | GNUNET_SQ_ResultConverter conv; | ||
253 | |||
254 | /** | ||
255 | * Function to clean up result data, NULL if cleanup is | ||
256 | * not necessary. | ||
257 | */ | ||
258 | GNUNET_SQ_ResultCleanup cleaner; | ||
259 | |||
260 | /** | ||
261 | * Closure for @e conv and @e cleaner. | ||
262 | */ | ||
263 | void *cls; | ||
264 | |||
265 | /** | ||
266 | * Destination for the data. | ||
267 | */ | ||
268 | void *dst; | ||
269 | |||
270 | /** | ||
271 | * Allowed size for the data, 0 for variable-size | ||
272 | * (in this case, the type of @e dst is a `void **` | ||
273 | * and we need to allocate a buffer of the right size). | ||
274 | */ | ||
275 | size_t dst_size; | ||
276 | |||
277 | /** | ||
278 | * Where to store actual size of the result. If left at | ||
279 | * NULL, will be made to point to @e dst_size before | ||
280 | * @a conv is called. | ||
281 | */ | ||
282 | size_t *result_size; | ||
283 | |||
284 | /** | ||
285 | * Number of parameters (columns) eaten by this operation. | ||
286 | */ | ||
287 | unsigned int num_params; | ||
288 | |||
289 | }; | ||
290 | |||
291 | |||
292 | /** | ||
293 | * End of result parameter specification. | ||
294 | * | ||
295 | * @return array last entry for the result specification to use | ||
296 | */ | ||
297 | #define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL } | ||
298 | |||
299 | |||
300 | /** | ||
301 | * Variable-size result expected. | ||
302 | * | ||
303 | * @param[out] dst where to store the result, allocated | ||
304 | * @param[out] sptr where to store the size of @a dst | ||
305 | * @return array entry for the result specification to use | ||
306 | */ | ||
307 | struct GNUNET_SQ_ResultSpec | ||
308 | GNUNET_SQ_result_spec_variable_size (void **dst, | ||
309 | size_t *sptr); | ||
310 | |||
311 | |||
312 | /** | ||
313 | * Fixed-size result expected. | ||
314 | * | ||
315 | * @param[out] dst where to store the result | ||
316 | * @param dst_size number of bytes in @a dst | ||
317 | * @return array entry for the result specification to use | ||
318 | */ | ||
319 | struct GNUNET_SQ_ResultSpec | ||
320 | GNUNET_SQ_result_spec_fixed_size (void *dst, | ||
321 | size_t dst_size); | ||
322 | |||
323 | |||
324 | /** | ||
325 | * We expect a fixed-size result, with size determined by the type of `* dst` | ||
326 | * | ||
327 | * @param dst point to where to store the result, type fits expected result size | ||
328 | * @return array entry for the result specification to use | ||
329 | */ | ||
330 | #define GNUNET_SQ_result_spec_auto_from_type(dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof (*(dst))) | ||
331 | |||
332 | |||
333 | /** | ||
334 | * Variable-size result expected. | ||
335 | * | ||
336 | * @param[out] dst where to store the result, allocated | ||
337 | * @param[out] sptr where to store the size of @a dst | ||
338 | * @return array entry for the result specification to use | ||
339 | */ | ||
340 | struct GNUNET_SQ_ResultSpec | ||
341 | GNUNET_SQ_result_spec_variable_size (void **dst, | ||
342 | size_t *sptr); | ||
343 | |||
344 | |||
345 | /** | ||
346 | * 0-terminated string expected. | ||
347 | * | ||
348 | * @param[out] dst where to store the result, allocated | ||
349 | * @return array entry for the result specification to use | ||
350 | */ | ||
351 | struct GNUNET_SQ_ResultSpec | ||
352 | GNUNET_SQ_result_spec_string (char **dst); | ||
353 | |||
354 | |||
355 | /** | ||
356 | * RSA public key expected. | ||
357 | * | ||
358 | * @param[out] rsa where to store the result | ||
359 | * @return array entry for the result specification to use | ||
360 | */ | ||
361 | struct GNUNET_SQ_ResultSpec | ||
362 | GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa); | ||
363 | |||
364 | |||
365 | /** | ||
366 | * RSA signature expected. | ||
367 | * | ||
368 | * @param[out] sig where to store the result; | ||
369 | * @return array entry for the result specification to use | ||
370 | */ | ||
371 | struct GNUNET_SQ_ResultSpec | ||
372 | GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig); | ||
373 | |||
374 | |||
375 | /** | ||
376 | * Absolute time expected. | ||
377 | * | ||
378 | * @param[out] at where to store the result | ||
379 | * @return array entry for the result specification to use | ||
380 | */ | ||
381 | struct GNUNET_SQ_ResultSpec | ||
382 | GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at); | ||
383 | |||
384 | |||
385 | /** | ||
386 | * Absolute time expected. | ||
387 | * | ||
388 | * @param[out] at where to store the result | ||
389 | * @return array entry for the result specification to use | ||
390 | */ | ||
391 | struct GNUNET_SQ_ResultSpec | ||
392 | GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at); | ||
393 | |||
394 | |||
395 | /** | ||
396 | * uint16_t expected. | ||
397 | * | ||
398 | * @param[out] u16 where to store the result | ||
399 | * @return array entry for the result specification to use | ||
400 | */ | ||
401 | struct GNUNET_SQ_ResultSpec | ||
402 | GNUNET_SQ_result_spec_uint16 (uint16_t *u16); | ||
403 | |||
404 | |||
405 | /** | ||
406 | * uint32_t expected. | ||
407 | * | ||
408 | * @param[out] u32 where to store the result | ||
409 | * @return array entry for the result specification to use | ||
410 | */ | ||
411 | struct GNUNET_SQ_ResultSpec | ||
412 | GNUNET_SQ_result_spec_uint32 (uint32_t *u32); | ||
413 | |||
414 | |||
415 | /** | ||
416 | * uint64_t expected. | ||
417 | * | ||
418 | * @param[out] u64 where to store the result | ||
419 | * @return array entry for the result specification to use | ||
420 | */ | ||
421 | struct GNUNET_SQ_ResultSpec | ||
422 | GNUNET_SQ_result_spec_uint64 (uint64_t *u64); | ||
423 | |||
424 | |||
425 | /** | ||
426 | * Extract results from a query result according to the given specification. | ||
427 | * | ||
428 | * @param result result to process | ||
429 | * @param[in,out] rs result specification to extract for | ||
430 | * @return | ||
431 | * #GNUNET_OK if all results could be extracted | ||
432 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | ||
433 | */ | ||
434 | int | ||
435 | GNUNET_SQ_extract_result (sqlite3_stmt *result, | ||
436 | struct GNUNET_SQ_ResultSpec *rs); | ||
437 | |||
438 | |||
439 | /** | ||
440 | * Free all memory that was allocated in @a rs during | ||
441 | * #GNUNET_SQ_extract_result(). | ||
442 | * | ||
443 | * @param rs reult specification to clean up | ||
444 | */ | ||
445 | void | ||
446 | GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs); | ||
447 | |||
448 | |||
449 | #endif /* GNUNET_SQ_LIB_H_ */ | ||
450 | |||
451 | /* end of include/gnunet_sq_lib.h */ | ||