aboutsummaryrefslogtreecommitdiff
path: root/src/sq/sq_result_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sq/sq_result_helper.c')
-rw-r--r--src/sq/sq_result_helper.c554
1 files changed, 545 insertions, 9 deletions
diff --git a/src/sq/sq_result_helper.c b/src/sq/sq_result_helper.c
index 36ce53317..eaf606aa4 100644
--- a/src/sq/sq_result_helper.c
+++ b/src/sq/sq_result_helper.c
@@ -24,26 +24,75 @@
24 24
25 25
26/** 26/**
27 * Extract fixed-sized binary data from a Postgres database @a result at row @a row. 27 * Extract variable-sized binary data from a Postgres database @a result at row @a row.
28 * 28 *
29 * @param cls closure 29 * @param cls closure
30 * @param result where to extract data from 30 * @param result where to extract data from
31 * @param row row to extract data from
32 * @param column column to extract data from 31 * @param column column to extract data from
33 * @param[in,out] dst_size where to store size of result, may be NULL 32 * @param[in,out] dst_size where to store size of result, may be NULL
34 * @param[out] dst where to store the result 33 * @param[out] dst where to store the result (actually a `void **`)
35 * @return 34 * @return
36 * #GNUNET_YES if all results could be extracted 35 * #GNUNET_YES if all results could be extracted
37 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 36 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
38 */ 37 */
39static int 38static int
40extract_fixed_blob (void *cls, 39extract_var_blob (void *cls,
41 sqlite3_stmt *result, 40 sqlite3_stmt *result,
42 int row, 41 unsigned int column,
43 unsigned int column, 42 size_t *dst_size,
44 size_t *dst_size, 43 void *dst)
45 void *dst)
46{ 44{
45 int have;
46 const void *ret;
47 void **rdst = (void **) dst;
48
49 if (SQLITE_BLOB !=
50 sqlite3_column_type (result,
51 column))
52 {
53 GNUNET_break (0);
54 return GNUNET_SYSERR;
55 }
56 /* sqlite manual says to invoke 'sqlite3_column_blob()'
57 before calling sqlite3_column_bytes() */
58 ret = sqlite3_column_blob (result,
59 column);
60 have = sqlite3_column_bytes (result,
61 column);
62 if (have < 0)
63 {
64 GNUNET_break (0);
65 return GNUNET_SYSERR;
66 }
67 *dst_size = have;
68 if (0 == have)
69 {
70 *rdst = NULL;
71 return GNUNET_OK;
72 }
73 *rdst = GNUNET_malloc (have);
74 GNUNET_memcpy (*rdst,
75 ret,
76 have);
77 return GNUNET_OK;
78}
79
80
81/**
82 * Cleanup memory allocated by #extract_var_blob().
83 *
84 * @param cls pointer to pointer of allocation
85 */
86static void
87clean_var_blob (void *cls)
88{
89 void **dptr = (void **) cls;
90
91 if (NULL != *dptr)
92 {
93 GNUNET_free (*dptr);
94 *dptr = NULL;
95 }
47} 96}
48 97
49 98
@@ -58,6 +107,63 @@ struct GNUNET_SQ_ResultSpec
58GNUNET_SQ_result_spec_variable_size (void **dst, 107GNUNET_SQ_result_spec_variable_size (void **dst,
59 size_t *sptr) 108 size_t *sptr)
60{ 109{
110 struct GNUNET_SQ_ResultSpec rs = {
111 .conv = &extract_var_blob,
112 .cleaner = &clean_var_blob,
113 .dst = dst,
114 .cls = dst,
115 .result_size = sptr,
116 .num_params = 1
117 };
118
119 return rs;
120}
121
122
123/**
124 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
125 *
126 * @param cls closure
127 * @param result where to extract data from
128 * @param column column to extract data from
129 * @param[in,out] dst_size where to store size of result, may be NULL
130 * @param[out] dst where to store the result
131 * @return
132 * #GNUNET_YES if all results could be extracted
133 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
134 */
135static int
136extract_fixed_blob (void *cls,
137 sqlite3_stmt *result,
138 unsigned int column,
139 size_t *dst_size,
140 void *dst)
141{
142 int have;
143 const void *ret;
144
145 if (SQLITE_BLOB !=
146 sqlite3_column_type (result,
147 column))
148 {
149 GNUNET_break (0);
150 return GNUNET_SYSERR;
151 }
152 /* sqlite manual says to invoke 'sqlite3_column_blob()'
153 before calling sqlite3_column_bytes() */
154 ret = sqlite3_column_blob (result,
155 column);
156 have = sqlite3_column_bytes (result,
157 column);
158 if (*dst_size != have)
159 {
160 GNUNET_break (0);
161 return GNUNET_SYSERR;
162 }
163 GNUNET_memcpy (dst,
164 ret,
165 have);
166 return GNUNET_OK;
61} 167}
62 168
63 169
@@ -72,6 +178,76 @@ struct GNUNET_SQ_ResultSpec
72GNUNET_SQ_result_spec_fixed_size (void *dst, 178GNUNET_SQ_result_spec_fixed_size (void *dst,
73 size_t dst_size) 179 size_t dst_size)
74{ 180{
181 struct GNUNET_SQ_ResultSpec rs = {
182 .conv = &extract_fixed_blob,
183 .dst = dst,
184 .dst_size = dst_size,
185 .num_params = 1
186 };
187
188 return rs;
189}
190
191
192/**
193 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
194 *
195 * @param cls closure
196 * @param result where to extract data from
197 * @param column column to extract data from
198 * @param[in,out] dst_size where to store size of result, may be NULL
199 * @param[out] dst where to store the result
200 * @return
201 * #GNUNET_YES if all results could be extracted
202 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
203 */
204static int
205extract_utf8_string (void *cls,
206 sqlite3_stmt *result,
207 unsigned int column,
208 size_t *dst_size,
209 void *dst)
210{
211 const char *text;
212 char **rdst = dst;
213
214 if (SQLITE_TEXT !=
215 sqlite3_column_type (result,
216 column))
217 {
218 GNUNET_break (0);
219 return GNUNET_SYSERR;
220 }
221 /* sqlite manual guarantees that 'sqlite3_column_text()'
222 is 0-terminated */
223 text = (const char *) sqlite3_column_text (result,
224 column);
225 if (NULL == text)
226 {
227 GNUNET_break (0);
228 return GNUNET_SYSERR;
229 }
230 *dst_size = strlen (text) + 1;
231 *rdst = GNUNET_strdup (text);
232 return GNUNET_OK;
233}
234
235
236/**
237 * Cleanup memory allocated by #extract_var_blob().
238 *
239 * @param cls pointer to pointer of allocation
240 */
241static void
242clean_utf8_string (void *cls)
243{
244 char **dptr = (char **) cls;
245
246 if (NULL != *dptr)
247 {
248 GNUNET_free (*dptr);
249 *dptr = NULL;
250 }
75} 251}
76 252
77 253
@@ -84,6 +260,87 @@ GNUNET_SQ_result_spec_fixed_size (void *dst,
84struct GNUNET_SQ_ResultSpec 260struct GNUNET_SQ_ResultSpec
85GNUNET_SQ_result_spec_string (char **dst) 261GNUNET_SQ_result_spec_string (char **dst)
86{ 262{
263 struct GNUNET_SQ_ResultSpec rs = {
264 .conv = &extract_utf8_string,
265 .cleaner = &clean_utf8_string,
266 .cls = dst,
267 .dst = dst,
268 .num_params = 1
269 };
270
271 return rs;
272}
273
274
275/**
276 * Extract data from a Postgres database @a result at row @a row.
277 *
278 * @param cls closure
279 * @param result where to extract data from
280 * @param column column to extract data from
281 * @param[in,out] dst_size where to store size of result, may be NULL
282 * @param[out] dst where to store the result
283 * @return
284 * #GNUNET_YES if all results could be extracted
285 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
286 */
287static int
288extract_rsa_pub (void *cls,
289 sqlite3_stmt *result,
290 unsigned int column,
291 size_t *dst_size,
292 void *dst)
293{
294 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
295 int have;
296 const void *ret;
297
298 if (SQLITE_BLOB !=
299 sqlite3_column_type (result,
300 column))
301 {
302 GNUNET_break (0);
303 return GNUNET_SYSERR;
304 }
305 /* sqlite manual says to invoke 'sqlite3_column_blob()'
306 before calling sqlite3_column_bytes() */
307 ret = sqlite3_column_blob (result,
308 column);
309 have = sqlite3_column_bytes (result,
310 column);
311 if (have < 0)
312 {
313 GNUNET_break (0);
314 return GNUNET_SYSERR;
315 }
316
317 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
318 have);
319 if (NULL == *pk)
320 {
321 GNUNET_break (0);
322 return GNUNET_SYSERR;
323 }
324 return GNUNET_OK;
325}
326
327
328/**
329 * Function called to clean up memory allocated
330 * by a #GNUNET_PQ_ResultConverter.
331 *
332 * @param cls closure
333 */
334static void
335clean_rsa_pub (void *cls)
336{
337 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
338
339 if (NULL != *pk)
340 {
341 GNUNET_CRYPTO_rsa_public_key_free (*pk);
342 *pk = NULL;
343 }
87} 344}
88 345
89 346
@@ -96,6 +353,87 @@ GNUNET_SQ_result_spec_string (char **dst)
96struct GNUNET_SQ_ResultSpec 353struct GNUNET_SQ_ResultSpec
97GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa) 354GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
98{ 355{
356 struct GNUNET_SQ_ResultSpec rs = {
357 .conv = &extract_rsa_pub,
358 .cleaner = &clean_rsa_pub,
359 .dst = rsa,
360 .cls = rsa,
361 .num_params = 1
362 };
363
364 return rs;
365}
366
367
368/**
369 * Extract data from a Postgres database @a result at row @a row.
370 *
371 * @param cls closure
372 * @param result where to extract data from
373 * @param column column to extract data from
374 * @param[in,out] dst_size where to store size of result, may be NULL
375 * @param[out] dst where to store the result
376 * @return
377 * #GNUNET_YES if all results could be extracted
378 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
379 */
380static int
381extract_rsa_sig (void *cls,
382 sqlite3_stmt *result,
383 unsigned int column,
384 size_t *dst_size,
385 void *dst)
386{
387 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
388 int have;
389 const void *ret;
390
391 if (SQLITE_BLOB !=
392 sqlite3_column_type (result,
393 column))
394 {
395 GNUNET_break (0);
396 return GNUNET_SYSERR;
397 }
398 /* sqlite manual says to invoke 'sqlite3_column_blob()'
399 before calling sqlite3_column_bytes() */
400 ret = sqlite3_column_blob (result,
401 column);
402 have = sqlite3_column_bytes (result,
403 column);
404 if (have < 0)
405 {
406 GNUNET_break (0);
407 return GNUNET_SYSERR;
408 }
409
410 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
411 have);
412 if (NULL == *sig)
413 {
414 GNUNET_break (0);
415 return GNUNET_SYSERR;
416 }
417 return GNUNET_OK;
418}
419
420
421/**
422 * Function called to clean up memory allocated
423 * by a #GNUNET_PQ_ResultConverter.
424 *
425 * @param cls result data to clean up
426 */
427static void
428clean_rsa_sig (void *cls)
429{
430 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
431
432 if (NULL != *sig)
433 {
434 GNUNET_CRYPTO_rsa_signature_free (*sig);
435 *sig = NULL;
436 }
99} 437}
100 438
101 439
@@ -108,6 +446,15 @@ GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
108struct GNUNET_SQ_ResultSpec 446struct GNUNET_SQ_ResultSpec
109GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig) 447GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
110{ 448{
449 struct GNUNET_SQ_ResultSpec rs = {
450 .conv = &extract_rsa_sig,
451 .cleaner = &clean_rsa_sig,
452 .dst = sig,
453 .cls = sig,
454 .num_params = 1
455 };
456
457 return rs;
111} 458}
112 459
113 460
@@ -120,6 +467,44 @@ GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
120struct GNUNET_SQ_ResultSpec 467struct GNUNET_SQ_ResultSpec
121GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at) 468GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
122{ 469{
470 return GNUNET_SQ_result_spec_uint64 (&at->abs_value_us);
471}
472
473
474/**
475 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
476 *
477 * @param cls closure
478 * @param result where to extract data from
479 * @param column column to extract data from
480 * @param[in,out] dst_size where to store size of result, may be NULL
481 * @param[out] dst where to store the result
482 * @return
483 * #GNUNET_YES if all results could be extracted
484 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
485 */
486static int
487extract_abs_time_nbo (void *cls,
488 sqlite3_stmt *result,
489 unsigned int column,
490 size_t *dst_size,
491 void *dst)
492{
493 struct GNUNET_TIME_AbsoluteNBO *u = dst;
494 struct GNUNET_TIME_Absolute t;
495
496 GNUNET_assert (sizeof (uint64_t) == *dst_size);
497 if (SQLITE_INTEGER !=
498 sqlite3_column_type (result,
499 column))
500 {
501 GNUNET_break (0);
502 return GNUNET_SYSERR;
503 }
504 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
505 column);
506 *u = GNUNET_TIME_absolute_hton (t);
507 return GNUNET_OK;
123} 508}
124 509
125 510
@@ -132,6 +517,56 @@ GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
132struct GNUNET_SQ_ResultSpec 517struct GNUNET_SQ_ResultSpec
133GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at) 518GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
134{ 519{
520 struct GNUNET_SQ_ResultSpec rs = {
521 .conv = &extract_abs_time_nbo,
522 .dst = at,
523 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
524 .num_params = 1
525 };
526
527 return rs;
528}
529
530
531/**
532 * Extract 16-bit integer from a Postgres database @a result at row @a row.
533 *
534 * @param cls closure
535 * @param result where to extract data from
536 * @param column column to extract data from
537 * @param[in,out] dst_size where to store size of result, may be NULL
538 * @param[out] dst where to store the result
539 * @return
540 * #GNUNET_YES if all results could be extracted
541 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
542 */
543static int
544extract_uint16 (void *cls,
545 sqlite3_stmt *result,
546 unsigned int column,
547 size_t *dst_size,
548 void *dst)
549{
550 uint64_t v;
551 uint32_t *u = dst;
552
553 GNUNET_assert (sizeof (uint16_t) == *dst_size);
554 if (SQLITE_INTEGER !=
555 sqlite3_column_type (result,
556 column))
557 {
558 GNUNET_break (0);
559 return GNUNET_SYSERR;
560 }
561 v = (uint64_t) sqlite3_column_int64 (result,
562 column);
563 if (v > UINT16_MAX)
564 {
565 GNUNET_break (0);
566 return GNUNET_SYSERR;
567 }
568 *u = (uint16_t) v;
569 return GNUNET_OK;
135} 570}
136 571
137 572
@@ -144,6 +579,56 @@ GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
144struct GNUNET_SQ_ResultSpec 579struct GNUNET_SQ_ResultSpec
145GNUNET_SQ_result_spec_uint16 (uint16_t *u16) 580GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
146{ 581{
582 struct GNUNET_SQ_ResultSpec rs = {
583 .conv = &extract_uint16,
584 .dst = u16,
585 .dst_size = sizeof (uint16_t),
586 .num_params = 1
587 };
588
589 return rs;
590}
591
592
593/**
594 * Extract 32-bit integer from a Postgres database @a result at row @a row.
595 *
596 * @param cls closure
597 * @param result where to extract data from
598 * @param column column to extract data from
599 * @param[in,out] dst_size where to store size of result, may be NULL
600 * @param[out] dst where to store the result
601 * @return
602 * #GNUNET_YES if all results could be extracted
603 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
604 */
605static int
606extract_uint32 (void *cls,
607 sqlite3_stmt *result,
608 unsigned int column,
609 size_t *dst_size,
610 void *dst)
611{
612 uint64_t v;
613 uint32_t *u = dst;
614
615 GNUNET_assert (sizeof (uint32_t) == *dst_size);
616 if (SQLITE_INTEGER !=
617 sqlite3_column_type (result,
618 column))
619 {
620 GNUNET_break (0);
621 return GNUNET_SYSERR;
622 }
623 v = (uint64_t) sqlite3_column_int64 (result,
624 column);
625 if (v > UINT32_MAX)
626 {
627 GNUNET_break (0);
628 return GNUNET_SYSERR;
629 }
630 *u = (uint32_t) v;
631 return GNUNET_OK;
147} 632}
148 633
149 634
@@ -156,6 +641,49 @@ GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
156struct GNUNET_SQ_ResultSpec 641struct GNUNET_SQ_ResultSpec
157GNUNET_SQ_result_spec_uint32 (uint32_t *u32) 642GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
158{ 643{
644 struct GNUNET_SQ_ResultSpec rs = {
645 .conv = &extract_uint32,
646 .dst = u32,
647 .dst_size = sizeof (uint32_t),
648 .num_params = 1
649 };
650
651 return rs;
652}
653
654
655/**
656 * Extract 64-bit integer from a Postgres database @a result at row @a row.
657 *
658 * @param cls closure
659 * @param result where to extract data from
660 * @param column column to extract data from
661 * @param[in,out] dst_size where to store size of result, may be NULL
662 * @param[out] dst where to store the result
663 * @return
664 * #GNUNET_YES if all results could be extracted
665 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
666 */
667static int
668extract_uint64 (void *cls,
669 sqlite3_stmt *result,
670 unsigned int column,
671 size_t *dst_size,
672 void *dst)
673{
674 uint64_t *u = dst;
675
676 GNUNET_assert (sizeof (uint64_t) == *dst_size);
677 if (SQLITE_INTEGER !=
678 sqlite3_column_type (result,
679 column))
680 {
681 GNUNET_break (0);
682 return GNUNET_SYSERR;
683 }
684 *u = (uint64_t) sqlite3_column_int64 (result,
685 column);
686 return GNUNET_OK;
159} 687}
160 688
161 689
@@ -168,6 +696,14 @@ GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
168struct GNUNET_SQ_ResultSpec 696struct GNUNET_SQ_ResultSpec
169GNUNET_SQ_result_spec_uint64 (uint64_t *u64) 697GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
170{ 698{
699 struct GNUNET_SQ_ResultSpec rs = {
700 .conv = &extract_uint64,
701 .dst = u64,
702 .dst_size = sizeof (uint64_t),
703 .num_params = 1
704 };
705
706 return rs;
171} 707}
172 708
173 709