diff options
Diffstat (limited to 'src/include/gnunet_sq_lib.h')
-rw-r--r-- | src/include/gnunet_sq_lib.h | 431 |
1 files changed, 431 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..a068650ac --- /dev/null +++ b/src/include/gnunet_sq_lib.h | |||
@@ -0,0 +1,431 @@ | |||
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 <sqlite/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 | * Extract data from a Postgres database @a result at row @a row. | ||
186 | * | ||
187 | * @param cls closure | ||
188 | * @param result where to extract data from | ||
189 | * @param int row to extract data from | ||
190 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
191 | * @param[out] dst where to store the result | ||
192 | * @return | ||
193 | * #GNUNET_YES if all results could be extracted | ||
194 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
195 | */ | ||
196 | typedef int | ||
197 | (*GNUNET_SQ_ResultConverter)(void *cls, | ||
198 | sqlite3_stmt *result, | ||
199 | int row, | ||
200 | size_t *dst_size, | ||
201 | void *dst); | ||
202 | |||
203 | |||
204 | /** | ||
205 | * Function called to clean up memory allocated | ||
206 | * by a #GNUNET_SQ_ResultConverter. | ||
207 | * | ||
208 | * @param cls closure | ||
209 | * @param rd result data to clean up | ||
210 | */ | ||
211 | typedef void | ||
212 | (*GNUNET_SQ_ResultCleanup)(void *cls, | ||
213 | void *rd); | ||
214 | |||
215 | |||
216 | /** | ||
217 | * @brief Description of a DB result cell. | ||
218 | */ | ||
219 | struct GNUNET_SQ_ResultSpec | ||
220 | { | ||
221 | |||
222 | /** | ||
223 | * What is the format of the result? | ||
224 | */ | ||
225 | GNUNET_SQ_ResultConverter conv; | ||
226 | |||
227 | /** | ||
228 | * Function to clean up result data, NULL if cleanup is | ||
229 | * not necessary. | ||
230 | */ | ||
231 | GNUNET_SQ_ResultCleanup cleaner; | ||
232 | |||
233 | /** | ||
234 | * Closure for @e conv and @e cleaner. | ||
235 | */ | ||
236 | void *cls; | ||
237 | |||
238 | /** | ||
239 | * Destination for the data. | ||
240 | */ | ||
241 | void *dst; | ||
242 | |||
243 | /** | ||
244 | * Allowed size for the data, 0 for variable-size | ||
245 | * (in this case, the type of @e dst is a `void **` | ||
246 | * and we need to allocate a buffer of the right size). | ||
247 | */ | ||
248 | size_t dst_size; | ||
249 | |||
250 | /** | ||
251 | * Where to store actual size of the result. | ||
252 | */ | ||
253 | size_t *result_size; | ||
254 | |||
255 | }; | ||
256 | |||
257 | |||
258 | /** | ||
259 | * End of result parameter specification. | ||
260 | * | ||
261 | * @return array last entry for the result specification to use | ||
262 | */ | ||
263 | #define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL } | ||
264 | |||
265 | |||
266 | /** | ||
267 | * Variable-size result expected. | ||
268 | * | ||
269 | * @param[out] dst where to store the result, allocated | ||
270 | * @param[out] sptr where to store the size of @a dst | ||
271 | * @return array entry for the result specification to use | ||
272 | */ | ||
273 | struct GNUNET_SQ_ResultSpec | ||
274 | GNUNET_SQ_result_spec_variable_size (void **dst, | ||
275 | size_t *sptr); | ||
276 | |||
277 | |||
278 | /** | ||
279 | * Fixed-size result expected. | ||
280 | * | ||
281 | * @param[out] dst where to store the result | ||
282 | * @param dst_size number of bytes in @a dst | ||
283 | * @return array entry for the result specification to use | ||
284 | */ | ||
285 | struct GNUNET_SQ_ResultSpec | ||
286 | GNUNET_SQ_result_spec_fixed_size (void *dst, | ||
287 | size_t dst_size); | ||
288 | |||
289 | |||
290 | /** | ||
291 | * We expect a fixed-size result, with size determined by the type of `* dst` | ||
292 | * | ||
293 | * @param dst point to where to store the result, type fits expected result size | ||
294 | * @return array entry for the result specification to use | ||
295 | */ | ||
296 | #define GNUNET_SQ_result_spec_auto_from_type(dst) GNUNET_SQ_result_spec_fixed_size (name, (dst), sizeof (*(dst))) | ||
297 | |||
298 | |||
299 | /** | ||
300 | * Variable-size result expected. | ||
301 | * | ||
302 | * @param[out] dst where to store the result, allocated | ||
303 | * @param[out] sptr where to store the size of @a dst | ||
304 | * @return array entry for the result specification to use | ||
305 | */ | ||
306 | struct GNUNET_SQ_ResultSpec | ||
307 | GNUNET_SQ_result_spec_variable_size (void **dst, | ||
308 | size_t *sptr); | ||
309 | |||
310 | |||
311 | /** | ||
312 | * 0-terminated string expected. | ||
313 | * | ||
314 | * @param[out] dst where to store the result, allocated | ||
315 | * @return array entry for the result specification to use | ||
316 | */ | ||
317 | struct GNUNET_SQ_ResultSpec | ||
318 | GNUNET_SQ_result_spec_string (char **dst); | ||
319 | |||
320 | |||
321 | /** | ||
322 | * RSA public key expected. | ||
323 | * | ||
324 | * @param[out] rsa where to store the result | ||
325 | * @return array entry for the result specification to use | ||
326 | */ | ||
327 | struct GNUNET_SQ_ResultSpec | ||
328 | GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa); | ||
329 | |||
330 | |||
331 | /** | ||
332 | * RSA signature expected. | ||
333 | * | ||
334 | * @param[out] sig where to store the result; | ||
335 | * @return array entry for the result specification to use | ||
336 | */ | ||
337 | struct GNUNET_SQ_ResultSpec | ||
338 | GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig); | ||
339 | |||
340 | |||
341 | /** | ||
342 | * Absolute time expected. | ||
343 | * | ||
344 | * @param[out] at where to store the result | ||
345 | * @return array entry for the result specification to use | ||
346 | */ | ||
347 | struct GNUNET_SQ_ResultSpec | ||
348 | GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at); | ||
349 | |||
350 | |||
351 | /** | ||
352 | * Absolute time expected. | ||
353 | * | ||
354 | * @param[out] at where to store the result | ||
355 | * @return array entry for the result specification to use | ||
356 | */ | ||
357 | struct GNUNET_SQ_ResultSpec | ||
358 | GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at); | ||
359 | |||
360 | |||
361 | /** | ||
362 | * uint16_t expected. | ||
363 | * | ||
364 | * @param[out] u16 where to store the result | ||
365 | * @return array entry for the result specification to use | ||
366 | */ | ||
367 | struct GNUNET_SQ_ResultSpec | ||
368 | GNUNET_SQ_result_spec_uint16 (uint16_t *u16); | ||
369 | |||
370 | |||
371 | /** | ||
372 | * uint32_t expected. | ||
373 | * | ||
374 | * @param[out] u32 where to store the result | ||
375 | * @return array entry for the result specification to use | ||
376 | */ | ||
377 | struct GNUNET_SQ_ResultSpec | ||
378 | GNUNET_SQ_result_spec_uint32 (uint32_t *u32); | ||
379 | |||
380 | |||
381 | /** | ||
382 | * uint64_t expected. | ||
383 | * | ||
384 | * @param[out] u64 where to store the result | ||
385 | * @return array entry for the result specification to use | ||
386 | */ | ||
387 | struct GNUNET_SQ_ResultSpec | ||
388 | GNUNET_SQ_result_spec_uint64 (uint64_t *u64); | ||
389 | |||
390 | |||
391 | /** | ||
392 | * Execute a prepared statement. | ||
393 | * | ||
394 | * @param db_conn database connection | ||
395 | * @param params parameters to the statement | ||
396 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
397 | */ | ||
398 | int | ||
399 | GNUNET_SQ_bind (sqlite3_stmt *stmt, | ||
400 | const struct GNUNET_SQ_QueryParam *params); | ||
401 | |||
402 | |||
403 | /** | ||
404 | * Extract results from a query result according to the given specification. | ||
405 | * | ||
406 | * @param result result to process | ||
407 | * @param[in,out] rs result specification to extract for | ||
408 | * @param row row from the result to extract | ||
409 | * @return | ||
410 | * #GNUNET_YES if all results could be extracted | ||
411 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | ||
412 | */ | ||
413 | int | ||
414 | GNUNET_SQ_extract_result (sqlite3_stmt *result, | ||
415 | struct GNUNET_SQ_ResultSpec *rs, | ||
416 | int row); | ||
417 | |||
418 | |||
419 | /** | ||
420 | * Free all memory that was allocated in @a rs during | ||
421 | * #GNUNET_SQ_extract_result(). | ||
422 | * | ||
423 | * @param rs reult specification to clean up | ||
424 | */ | ||
425 | void | ||
426 | GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs); | ||
427 | |||
428 | |||
429 | #endif /* GNUNET_SQ_LIB_H_ */ | ||
430 | |||
431 | /* end of include/gnunet_sq_lib.h */ | ||