3 This file is part of GNUnet
4 Copyright (C) 2017 GNUnet e.V.
6 GNUnet is free software; you can redistribute it and/or modify it under the
7 terms of the GNU General Public License as published by the Free Software
8 Foundation; either version 3, or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along with
15 GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
18 * @file sq/sq_result_helper.c
19 * @brief helper functions for queries
20 * @author Christian Grothoff
23 #include "gnunet_sq_lib.h"
27 * Extract variable-sized binary data from a Postgres database @a result at row @a row.
30 * @param result where to extract data from
31 * @param column column to extract data from
32 * @param[in,out] dst_size where to store size of result, may be NULL
33 * @param[out] dst where to store the result (actually a `void **`)
35 * #GNUNET_YES if all results could be extracted
36 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
39 extract_var_blob (void *cls,
47 void **rdst = (void **) dst;
50 sqlite3_column_type (result,
59 sqlite3_column_type (result,
65 /* sqlite manual says to invoke 'sqlite3_column_blob()'
66 before calling sqlite3_column_bytes() */
67 ret = sqlite3_column_blob (result,
69 have = sqlite3_column_bytes (result,
82 *rdst = GNUNET_malloc (have);
91 * Cleanup memory allocated by #extract_var_blob().
93 * @param cls pointer to pointer of allocation
96 clean_var_blob (void *cls)
98 void **dptr = (void **) cls;
109 * Variable-size result expected.
111 * @param[out] dst where to store the result, allocated
112 * @param[out] sptr where to store the size of @a dst
113 * @return array entry for the result specification to use
115 struct GNUNET_SQ_ResultSpec
116 GNUNET_SQ_result_spec_variable_size (void **dst,
119 struct GNUNET_SQ_ResultSpec rs = {
120 .conv = &extract_var_blob,
121 .cleaner = &clean_var_blob,
133 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
136 * @param result where to extract data from
137 * @param column column to extract data from
138 * @param[in,out] dst_size where to store size of result, may be NULL
139 * @param[out] dst where to store the result
141 * #GNUNET_YES if all results could be extracted
142 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
145 extract_fixed_blob (void *cls,
146 sqlite3_stmt *result,
154 if ( (0 == *dst_size) &&
156 sqlite3_column_type (result,
163 sqlite3_column_type (result,
167 return GNUNET_SYSERR;
169 /* sqlite manual says to invoke 'sqlite3_column_blob()'
170 before calling sqlite3_column_bytes() */
171 ret = sqlite3_column_blob (result,
173 have = sqlite3_column_bytes (result,
175 if (*dst_size != have)
178 return GNUNET_SYSERR;
188 * Fixed-size result expected.
190 * @param[out] dst where to store the result
191 * @param dst_size number of bytes in @a dst
192 * @return array entry for the result specification to use
194 struct GNUNET_SQ_ResultSpec
195 GNUNET_SQ_result_spec_fixed_size (void *dst,
198 struct GNUNET_SQ_ResultSpec rs = {
199 .conv = &extract_fixed_blob,
201 .dst_size = dst_size,
210 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
213 * @param result where to extract data from
214 * @param column column to extract data from
215 * @param[in,out] dst_size where to store size of result, may be NULL
216 * @param[out] dst where to store the result
218 * #GNUNET_YES if all results could be extracted
219 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
222 extract_utf8_string (void *cls,
223 sqlite3_stmt *result,
232 sqlite3_column_type (result,
239 sqlite3_column_type (result,
243 return GNUNET_SYSERR;
245 /* sqlite manual guarantees that 'sqlite3_column_text()'
247 text = (const char *) sqlite3_column_text (result,
252 return GNUNET_SYSERR;
254 *dst_size = strlen (text) + 1;
255 *rdst = GNUNET_strdup (text);
261 * Cleanup memory allocated by #extract_var_blob().
263 * @param cls pointer to pointer of allocation
266 clean_utf8_string (void *cls)
268 char **dptr = (char **) cls;
279 * 0-terminated string expected.
281 * @param[out] dst where to store the result, allocated
282 * @return array entry for the result specification to use
284 struct GNUNET_SQ_ResultSpec
285 GNUNET_SQ_result_spec_string (char **dst)
287 struct GNUNET_SQ_ResultSpec rs = {
288 .conv = &extract_utf8_string,
289 .cleaner = &clean_utf8_string,
300 * Extract data from a Postgres database @a result at row @a row.
303 * @param result where to extract data from
304 * @param column column to extract data from
305 * @param[in,out] dst_size where to store size of result, may be NULL
306 * @param[out] dst where to store the result
308 * #GNUNET_YES if all results could be extracted
309 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
312 extract_rsa_pub (void *cls,
313 sqlite3_stmt *result,
318 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
323 sqlite3_column_type (result,
327 return GNUNET_SYSERR;
329 /* sqlite manual says to invoke 'sqlite3_column_blob()'
330 before calling sqlite3_column_bytes() */
331 ret = sqlite3_column_blob (result,
333 have = sqlite3_column_bytes (result,
338 return GNUNET_SYSERR;
341 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
346 return GNUNET_SYSERR;
353 * Function called to clean up memory allocated
354 * by a #GNUNET_PQ_ResultConverter.
359 clean_rsa_pub (void *cls)
361 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
365 GNUNET_CRYPTO_rsa_public_key_free (*pk);
372 * RSA public key expected.
374 * @param[out] rsa where to store the result
375 * @return array entry for the result specification to use
377 struct GNUNET_SQ_ResultSpec
378 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
380 struct GNUNET_SQ_ResultSpec rs = {
381 .conv = &extract_rsa_pub,
382 .cleaner = &clean_rsa_pub,
393 * Extract data from a Postgres database @a result at row @a row.
396 * @param result where to extract data from
397 * @param column column to extract data from
398 * @param[in,out] dst_size where to store size of result, may be NULL
399 * @param[out] dst where to store the result
401 * #GNUNET_YES if all results could be extracted
402 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
405 extract_rsa_sig (void *cls,
406 sqlite3_stmt *result,
411 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
416 sqlite3_column_type (result,
420 return GNUNET_SYSERR;
422 /* sqlite manual says to invoke 'sqlite3_column_blob()'
423 before calling sqlite3_column_bytes() */
424 ret = sqlite3_column_blob (result,
426 have = sqlite3_column_bytes (result,
431 return GNUNET_SYSERR;
434 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
439 return GNUNET_SYSERR;
446 * Function called to clean up memory allocated
447 * by a #GNUNET_PQ_ResultConverter.
449 * @param cls result data to clean up
452 clean_rsa_sig (void *cls)
454 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
458 GNUNET_CRYPTO_rsa_signature_free (*sig);
465 * RSA signature expected.
467 * @param[out] sig where to store the result;
468 * @return array entry for the result specification to use
470 struct GNUNET_SQ_ResultSpec
471 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
473 struct GNUNET_SQ_ResultSpec rs = {
474 .conv = &extract_rsa_sig,
475 .cleaner = &clean_rsa_sig,
486 * Extract absolute time value from a Postgres database @a result at row @a row.
489 * @param result where to extract data from
490 * @param column column to extract data from
491 * @param[in,out] dst_size where to store size of result, may be NULL
492 * @param[out] dst where to store the result
494 * #GNUNET_YES if all results could be extracted
495 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
498 extract_abs_time (void *cls,
499 sqlite3_stmt *result,
504 struct GNUNET_TIME_Absolute *u = dst;
505 struct GNUNET_TIME_Absolute t;
507 GNUNET_assert (sizeof (uint64_t) == *dst_size);
508 if (SQLITE_INTEGER !=
509 sqlite3_column_type (result,
513 return GNUNET_SYSERR;
515 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
517 if (INT64_MAX == t.abs_value_us)
518 t = GNUNET_TIME_UNIT_FOREVER_ABS;
525 * Absolute time expected.
527 * @param[out] at where to store the result
528 * @return array entry for the result specification to use
530 struct GNUNET_SQ_ResultSpec
531 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
533 struct GNUNET_SQ_ResultSpec rs = {
534 .conv = &extract_abs_time,
536 .dst_size = sizeof (struct GNUNET_TIME_Absolute),
545 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
548 * @param result where to extract data from
549 * @param column column to extract data from
550 * @param[in,out] dst_size where to store size of result, may be NULL
551 * @param[out] dst where to store the result
553 * #GNUNET_YES if all results could be extracted
554 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
557 extract_abs_time_nbo (void *cls,
558 sqlite3_stmt *result,
563 struct GNUNET_TIME_AbsoluteNBO *u = dst;
564 struct GNUNET_TIME_Absolute t;
566 GNUNET_assert (sizeof (uint64_t) == *dst_size);
567 if (SQLITE_INTEGER !=
568 sqlite3_column_type (result,
572 return GNUNET_SYSERR;
574 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
576 if (INT64_MAX == t.abs_value_us)
577 t = GNUNET_TIME_UNIT_FOREVER_ABS;
578 *u = GNUNET_TIME_absolute_hton (t);
584 * Absolute time expected.
586 * @param[out] at where to store the result
587 * @return array entry for the result specification to use
589 struct GNUNET_SQ_ResultSpec
590 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
592 struct GNUNET_SQ_ResultSpec rs = {
593 .conv = &extract_abs_time_nbo,
595 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
604 * Extract 16-bit integer from a Postgres database @a result at row @a row.
607 * @param result where to extract data from
608 * @param column column to extract data from
609 * @param[in,out] dst_size where to store size of result, may be NULL
610 * @param[out] dst where to store the result
612 * #GNUNET_YES if all results could be extracted
613 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
616 extract_uint16 (void *cls,
617 sqlite3_stmt *result,
625 GNUNET_assert (sizeof (uint16_t) == *dst_size);
626 if (SQLITE_INTEGER !=
627 sqlite3_column_type (result,
631 return GNUNET_SYSERR;
633 v = (uint64_t) sqlite3_column_int64 (result,
638 return GNUNET_SYSERR;
648 * @param[out] u16 where to store the result
649 * @return array entry for the result specification to use
651 struct GNUNET_SQ_ResultSpec
652 GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
654 struct GNUNET_SQ_ResultSpec rs = {
655 .conv = &extract_uint16,
657 .dst_size = sizeof (uint16_t),
666 * Extract 32-bit integer from a Postgres database @a result at row @a row.
669 * @param result where to extract data from
670 * @param column column to extract data from
671 * @param[in,out] dst_size where to store size of result, may be NULL
672 * @param[out] dst where to store the result
674 * #GNUNET_YES if all results could be extracted
675 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
678 extract_uint32 (void *cls,
679 sqlite3_stmt *result,
687 GNUNET_assert (sizeof (uint32_t) == *dst_size);
688 if (SQLITE_INTEGER !=
689 sqlite3_column_type (result,
693 return GNUNET_SYSERR;
695 v = (uint64_t) sqlite3_column_int64 (result,
700 return GNUNET_SYSERR;
710 * @param[out] u32 where to store the result
711 * @return array entry for the result specification to use
713 struct GNUNET_SQ_ResultSpec
714 GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
716 struct GNUNET_SQ_ResultSpec rs = {
717 .conv = &extract_uint32,
719 .dst_size = sizeof (uint32_t),
728 * Extract 64-bit integer from a Postgres database @a result at row @a row.
731 * @param result where to extract data from
732 * @param column column to extract data from
733 * @param[in,out] dst_size where to store size of result, may be NULL
734 * @param[out] dst where to store the result
736 * #GNUNET_YES if all results could be extracted
737 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
740 extract_uint64 (void *cls,
741 sqlite3_stmt *result,
748 GNUNET_assert (sizeof (uint64_t) == *dst_size);
749 if (SQLITE_INTEGER !=
750 sqlite3_column_type (result,
754 return GNUNET_SYSERR;
756 *u = (uint64_t) sqlite3_column_int64 (result,
765 * @param[out] u64 where to store the result
766 * @return array entry for the result specification to use
768 struct GNUNET_SQ_ResultSpec
769 GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
771 struct GNUNET_SQ_ResultSpec rs = {
772 .conv = &extract_uint64,
774 .dst_size = sizeof (uint64_t),
782 /* end of sq_result_helper.c */