diff options
Diffstat (limited to 'src/include/gnunet_pq_lib.h')
-rw-r--r-- | src/include/gnunet_pq_lib.h | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h new file mode 100644 index 000000000..dd41406d3 --- /dev/null +++ b/src/include/gnunet_pq_lib.h | |||
@@ -0,0 +1,454 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2016 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_pq_lib.h | ||
18 | * @brief helper functions for DB interactions | ||
19 | * @author Christian Grothoff | ||
20 | */ | ||
21 | #ifndef GNUNET_PQ_LIB_H_ | ||
22 | #define GNUNET_PQ_LIB_H_ | ||
23 | |||
24 | #include <libpq-fe.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[out] param_values SQL data to set | ||
35 | * @param[out] param_lengths SQL length data to set | ||
36 | * @param[out] param_formats SQL format data to set | ||
37 | * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays | ||
38 | * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() | ||
39 | * @param scratch_length number of entries left in @a scratch | ||
40 | * @return -1 on error, number of offsets used in @a scratch otherwise | ||
41 | */ | ||
42 | typedef int | ||
43 | (*GNUNET_PQ_QueryConverter)(void *cls, | ||
44 | const void *data, | ||
45 | size_t data_len, | ||
46 | void *param_values[], | ||
47 | int param_lengths[], | ||
48 | int param_formats[], | ||
49 | unsigned int param_length, | ||
50 | void *scratch[], | ||
51 | unsigned int scratch_length); | ||
52 | |||
53 | |||
54 | /** | ||
55 | * @brief Description of a DB query parameter. | ||
56 | */ | ||
57 | struct GNUNET_PQ_QueryParam | ||
58 | { | ||
59 | |||
60 | /** | ||
61 | * Format of the rest of the entry, determines the data | ||
62 | * type that is being added to the query. | ||
63 | */ | ||
64 | GNUNET_PQ_QueryConverter conv; | ||
65 | |||
66 | /** | ||
67 | * Closure for @e conv. | ||
68 | */ | ||
69 | void *conv_cls; | ||
70 | |||
71 | /** | ||
72 | * Data or NULL. | ||
73 | */ | ||
74 | const void *data; | ||
75 | |||
76 | /** | ||
77 | * Size of @e data | ||
78 | */ | ||
79 | size_t size; | ||
80 | |||
81 | /** | ||
82 | * Number of parameters eaten by this operation. | ||
83 | */ | ||
84 | unsigned int num_params; | ||
85 | }; | ||
86 | |||
87 | |||
88 | /** | ||
89 | * End of query parameter specification. | ||
90 | */ | ||
91 | #define GNUNET_PQ_query_param_end { NULL, NULL, NULL, 0, 0 } | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Generate query parameter for a buffer @a ptr of | ||
96 | * @a ptr_size bytes. | ||
97 | * | ||
98 | * @param ptr pointer to the query parameter to pass | ||
99 | * @oaran ptr_size number of bytes in @a ptr | ||
100 | */ | ||
101 | struct GNUNET_PQ_QueryParam | ||
102 | GNUNET_PQ_query_param_fixed_size (const void *ptr, | ||
103 | size_t ptr_size); | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Generate fixed-size query parameter with size determined | ||
108 | * by variable type. | ||
109 | * | ||
110 | * @param x pointer to the query parameter to pass. | ||
111 | */ | ||
112 | #define GNUNET_PQ_query_param_auto_from_type(x) GNUNET_PQ_query_param_fixed_size ((x), sizeof (*(x))) | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Generate query parameter for an RSA public key. The | ||
117 | * database must contain a BLOB type in the respective position. | ||
118 | * | ||
119 | * @param x the query parameter to pass. | ||
120 | */ | ||
121 | struct GNUNET_PQ_QueryParam | ||
122 | GNUNET_PQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_rsa_PublicKey *x); | ||
123 | |||
124 | |||
125 | /** | ||
126 | * Generate query parameter for an RSA signature. The | ||
127 | * database must contain a BLOB type in the respective position. | ||
128 | * | ||
129 | * @param x the query parameter to pass | ||
130 | */ | ||
131 | struct GNUNET_PQ_QueryParam | ||
132 | GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_rsa_Signature *x); | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Generate query parameter for an absolute time value. | ||
137 | * The database must store a 64-bit integer. | ||
138 | * | ||
139 | * @param x pointer to the query parameter to pass | ||
140 | */ | ||
141 | struct GNUNET_PQ_QueryParam | ||
142 | GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Generate query parameter for an absolute time value. | ||
147 | * The database must store a 64-bit integer. | ||
148 | * | ||
149 | * @param x pointer to the query parameter to pass | ||
150 | */ | ||
151 | struct GNUNET_PQ_QueryParam | ||
152 | GNUNET_PQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x); | ||
153 | |||
154 | |||
155 | /** | ||
156 | * Generate query parameter for an uint16_t in host byte order. | ||
157 | * | ||
158 | * @param x pointer to the query parameter to pass | ||
159 | */ | ||
160 | struct GNUNET_PQ_QueryParam | ||
161 | GNUNET_PQ_query_param_uint16 (const uint16_t *x); | ||
162 | |||
163 | |||
164 | /** | ||
165 | * Generate query parameter for an uint32_t in host byte order. | ||
166 | * | ||
167 | * @param x pointer to the query parameter to pass | ||
168 | */ | ||
169 | struct GNUNET_PQ_QueryParam | ||
170 | GNUNET_PQ_query_param_uint32 (const uint32_t *x); | ||
171 | |||
172 | |||
173 | /** | ||
174 | * Generate query parameter for an uint16_t in host byte order. | ||
175 | * | ||
176 | * @param x pointer to the query parameter to pass | ||
177 | */ | ||
178 | struct GNUNET_PQ_QueryParam | ||
179 | GNUNET_PQ_query_param_uint64 (const uint64_t *x); | ||
180 | |||
181 | |||
182 | /** | ||
183 | * Extract data from a Postgres database @a result at row @a row. | ||
184 | * | ||
185 | * @param cls closure | ||
186 | * @param result where to extract data from | ||
187 | * @param int row to extract data from | ||
188 | * @param fname name (or prefix) of the fields to extract from | ||
189 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
190 | * @param[out] dst where to store the result | ||
191 | * @return | ||
192 | * #GNUNET_YES if all results could be extracted | ||
193 | * #GNUNET_NO if at least one result was NULL | ||
194 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | ||
195 | */ | ||
196 | typedef int | ||
197 | (*GNUNET_PQ_ResultConverter)(void *cls, | ||
198 | PGresult *result, | ||
199 | int row, | ||
200 | const char *fname, | ||
201 | size_t *dst_size, | ||
202 | void *dst); | ||
203 | |||
204 | |||
205 | /** | ||
206 | * Function called to clean up memory allocated | ||
207 | * by a #GNUNET_PQ_ResultConverter. | ||
208 | * | ||
209 | * @param cls closure | ||
210 | * @param rd result data to clean up | ||
211 | */ | ||
212 | typedef void | ||
213 | (*GNUNET_PQ_ResultCleanup)(void *cls, | ||
214 | void *rd); | ||
215 | |||
216 | |||
217 | /** | ||
218 | * @brief Description of a DB result cell. | ||
219 | */ | ||
220 | struct GNUNET_PQ_ResultSpec | ||
221 | { | ||
222 | |||
223 | /** | ||
224 | * What is the format of the result? | ||
225 | */ | ||
226 | GNUNET_PQ_ResultConverter conv; | ||
227 | |||
228 | /** | ||
229 | * Function to clean up result data, NULL if cleanup is | ||
230 | * not necessary. | ||
231 | */ | ||
232 | GNUNET_PQ_ResultCleanup cleaner; | ||
233 | |||
234 | /** | ||
235 | * Closure for @e conv and @e cleaner. | ||
236 | */ | ||
237 | void *cls; | ||
238 | |||
239 | /** | ||
240 | * Destination for the data. | ||
241 | */ | ||
242 | void *dst; | ||
243 | |||
244 | /** | ||
245 | * Allowed size for the data, 0 for variable-size | ||
246 | * (in this case, the type of @e dst is a `void **` | ||
247 | * and we need to allocate a buffer of the right size). | ||
248 | */ | ||
249 | size_t dst_size; | ||
250 | |||
251 | /** | ||
252 | * Field name of the desired result. | ||
253 | */ | ||
254 | const char *fname; | ||
255 | |||
256 | /** | ||
257 | * Where to store actual size of the result. | ||
258 | */ | ||
259 | size_t *result_size; | ||
260 | |||
261 | }; | ||
262 | |||
263 | |||
264 | /** | ||
265 | * End of result parameter specification. | ||
266 | * | ||
267 | * @return array last entry for the result specification to use | ||
268 | */ | ||
269 | #define GNUNET_PQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, NULL } | ||
270 | |||
271 | |||
272 | /** | ||
273 | * Variable-size result expected. | ||
274 | * | ||
275 | * @param name name of the field in the table | ||
276 | * @param[out] dst where to store the result, allocated | ||
277 | * @param[out] sptr where to store the size of @a dst | ||
278 | * @return array entry for the result specification to use | ||
279 | */ | ||
280 | struct GNUNET_PQ_ResultSpec | ||
281 | GNUNET_PQ_result_spec_variable_size (const char *name, | ||
282 | void **dst, | ||
283 | size_t *sptr); | ||
284 | |||
285 | |||
286 | /** | ||
287 | * Fixed-size result expected. | ||
288 | * | ||
289 | * @param name name of the field in the table | ||
290 | * @param[out] dst where to store the result | ||
291 | * @param dst_size number of bytes in @a dst | ||
292 | * @return array entry for the result specification to use | ||
293 | */ | ||
294 | struct GNUNET_PQ_ResultSpec | ||
295 | GNUNET_PQ_result_spec_fixed_size (const char *name, | ||
296 | void *dst, | ||
297 | size_t dst_size); | ||
298 | |||
299 | |||
300 | |||
301 | /** | ||
302 | * We expect a fixed-size result, with size determined by the type of `* dst` | ||
303 | * | ||
304 | * @param name name of the field in the table | ||
305 | * @param dst point to where to store the result, type fits expected result size | ||
306 | * @return array entry for the result specification to use | ||
307 | */ | ||
308 | #define GNUNET_PQ_result_spec_auto_from_type(name, dst) GNUNET_PQ_result_spec_fixed_size (name, (dst), sizeof (*(dst))) | ||
309 | |||
310 | |||
311 | /** | ||
312 | * Variable-size result expected. | ||
313 | * | ||
314 | * @param name name of the field in the table | ||
315 | * @param[out] dst where to store the result, allocated | ||
316 | * @param[out] sptr where to store the size of @a dst | ||
317 | * @return array entry for the result specification to use | ||
318 | */ | ||
319 | struct GNUNET_PQ_ResultSpec | ||
320 | GNUNET_PQ_result_spec_variable_size (const char *name, | ||
321 | void **dst, | ||
322 | size_t *sptr); | ||
323 | |||
324 | |||
325 | /** | ||
326 | * RSA public key expected. | ||
327 | * | ||
328 | * @param name name of the field in the table | ||
329 | * @param[out] rsa where to store the result | ||
330 | * @return array entry for the result specification to use | ||
331 | */ | ||
332 | struct GNUNET_PQ_ResultSpec | ||
333 | GNUNET_PQ_result_spec_rsa_public_key (const char *name, | ||
334 | struct GNUNET_CRYPTO_rsa_PublicKey **rsa); | ||
335 | |||
336 | |||
337 | /** | ||
338 | * RSA signature expected. | ||
339 | * | ||
340 | * @param name name of the field in the table | ||
341 | * @param[out] sig where to store the result; | ||
342 | * @return array entry for the result specification to use | ||
343 | */ | ||
344 | struct GNUNET_PQ_ResultSpec | ||
345 | GNUNET_PQ_result_spec_rsa_signature (const char *name, | ||
346 | struct GNUNET_CRYPTO_rsa_Signature **sig); | ||
347 | |||
348 | |||
349 | /** | ||
350 | * Absolute time expected. | ||
351 | * | ||
352 | * @param name name of the field in the table | ||
353 | * @param[out] at where to store the result | ||
354 | * @return array entry for the result specification to use | ||
355 | */ | ||
356 | struct GNUNET_PQ_ResultSpec | ||
357 | GNUNET_PQ_result_spec_absolute_time (const char *name, | ||
358 | struct GNUNET_TIME_Absolute *at); | ||
359 | |||
360 | |||
361 | /** | ||
362 | * Absolute time expected. | ||
363 | * | ||
364 | * @param name name of the field in the table | ||
365 | * @param[out] at where to store the result | ||
366 | * @return array entry for the result specification to use | ||
367 | */ | ||
368 | struct GNUNET_PQ_ResultSpec | ||
369 | GNUNET_PQ_result_spec_absolute_time_nbo (const char *name, | ||
370 | struct GNUNET_TIME_AbsoluteNBO *at); | ||
371 | |||
372 | |||
373 | /** | ||
374 | * uint16_t expected. | ||
375 | * | ||
376 | * @param name name of the field in the table | ||
377 | * @param[out] u16 where to store the result | ||
378 | * @return array entry for the result specification to use | ||
379 | */ | ||
380 | struct GNUNET_PQ_ResultSpec | ||
381 | GNUNET_PQ_result_spec_uint16 (const char *name, | ||
382 | uint16_t *u16); | ||
383 | |||
384 | |||
385 | /** | ||
386 | * uint32_t expected. | ||
387 | * | ||
388 | * @param name name of the field in the table | ||
389 | * @param[out] u32 where to store the result | ||
390 | * @return array entry for the result specification to use | ||
391 | */ | ||
392 | struct GNUNET_PQ_ResultSpec | ||
393 | GNUNET_PQ_result_spec_uint32 (const char *name, | ||
394 | uint32_t *u32); | ||
395 | |||
396 | |||
397 | /** | ||
398 | * uint64_t expected. | ||
399 | * | ||
400 | * @param name name of the field in the table | ||
401 | * @param[out] u64 where to store the result | ||
402 | * @return array entry for the result specification to use | ||
403 | */ | ||
404 | struct GNUNET_PQ_ResultSpec | ||
405 | GNUNET_PQ_result_spec_uint64 (const char *name, | ||
406 | uint64_t *u64); | ||
407 | |||
408 | |||
409 | /** | ||
410 | * Execute a prepared statement. | ||
411 | * | ||
412 | * @param db_conn database connection | ||
413 | * @param name name of the prepared statement | ||
414 | * @param params parameters to the statement | ||
415 | * @return postgres result | ||
416 | */ | ||
417 | PGresult * | ||
418 | GNUNET_PQ_exec_prepared (PGconn *db_conn, | ||
419 | const char *name, | ||
420 | const struct GNUNET_PQ_QueryParam *params); | ||
421 | |||
422 | |||
423 | /** | ||
424 | * Extract results from a query result according to the given specification. | ||
425 | * If colums are NULL, the destination is not modified, and #GNUNET_NO | ||
426 | * is returned. | ||
427 | * | ||
428 | * @param result result to process | ||
429 | * @param[in,out] rs result specification to extract for | ||
430 | * @param row row from the result to extract | ||
431 | * @return | ||
432 | * #GNUNET_YES if all results could be extracted | ||
433 | * #GNUNET_NO if at least one result was NULL | ||
434 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | ||
435 | */ | ||
436 | int | ||
437 | GNUNET_PQ_extract_result (PGresult *result, | ||
438 | struct GNUNET_PQ_ResultSpec *rs, | ||
439 | int row); | ||
440 | |||
441 | |||
442 | /** | ||
443 | * Free all memory that was allocated in @a rs during | ||
444 | * #GNUNET_PQ_extract_result(). | ||
445 | * | ||
446 | * @param rs reult specification to clean up | ||
447 | */ | ||
448 | void | ||
449 | GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs); | ||
450 | |||
451 | |||
452 | #endif /* GNUNET_PQ_LIB_H_ */ | ||
453 | |||
454 | /* end of include/gnunet_pq_lib.h */ | ||