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
7 under the terms of the GNU Affero General Public License as published
8 by the Free Software Foundation, either version 3 of the License,
9 or (at your option) any later version.
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Affero General Public License for more details.
16 You should have received a copy of the GNU Affero General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * @file sq/sq_result_helper.c
21 * @brief helper functions for queries
22 * @author Christian Grothoff
25 #include "gnunet_sq_lib.h"
29 * Extract variable-sized binary data from a Postgres database @a result at row @a row.
32 * @param result where to extract data from
33 * @param column column to extract data from
34 * @param[in,out] dst_size where to store size of result, may be NULL
35 * @param[out] dst where to store the result (actually a `void **`)
37 * #GNUNET_YES if all results could be extracted
38 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
41 extract_var_blob (void *cls,
49 void **rdst = (void **) dst;
52 sqlite3_column_type (result,
61 sqlite3_column_type (result,
67 /* sqlite manual says to invoke 'sqlite3_column_blob()'
68 before calling sqlite3_column_bytes() */
69 ret = sqlite3_column_blob (result,
71 have = sqlite3_column_bytes (result,
84 *rdst = GNUNET_malloc (have);
93 * Cleanup memory allocated by #extract_var_blob().
95 * @param cls pointer to pointer of allocation
98 clean_var_blob (void *cls)
100 void **dptr = (void **) cls;
111 * Variable-size result expected.
113 * @param[out] dst where to store the result, allocated
114 * @param[out] sptr where to store the size of @a dst
115 * @return array entry for the result specification to use
117 struct GNUNET_SQ_ResultSpec
118 GNUNET_SQ_result_spec_variable_size (void **dst,
121 struct GNUNET_SQ_ResultSpec rs = {
122 .conv = &extract_var_blob,
123 .cleaner = &clean_var_blob,
135 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
138 * @param result where to extract data from
139 * @param column column to extract data from
140 * @param[in,out] dst_size where to store size of result, may be NULL
141 * @param[out] dst where to store the result
143 * #GNUNET_YES if all results could be extracted
144 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
147 extract_fixed_blob (void *cls,
148 sqlite3_stmt *result,
156 if ( (0 == *dst_size) &&
158 sqlite3_column_type (result,
165 sqlite3_column_type (result,
169 return GNUNET_SYSERR;
171 /* sqlite manual says to invoke 'sqlite3_column_blob()'
172 before calling sqlite3_column_bytes() */
173 ret = sqlite3_column_blob (result,
175 have = sqlite3_column_bytes (result,
177 if (*dst_size != have)
180 return GNUNET_SYSERR;
190 * Fixed-size result expected.
192 * @param[out] dst where to store the result
193 * @param dst_size number of bytes in @a dst
194 * @return array entry for the result specification to use
196 struct GNUNET_SQ_ResultSpec
197 GNUNET_SQ_result_spec_fixed_size (void *dst,
200 struct GNUNET_SQ_ResultSpec rs = {
201 .conv = &extract_fixed_blob,
203 .dst_size = dst_size,
212 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
215 * @param result where to extract data from
216 * @param column column to extract data from
217 * @param[in,out] dst_size where to store size of result, may be NULL
218 * @param[out] dst where to store the result
220 * #GNUNET_YES if all results could be extracted
221 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
224 extract_utf8_string (void *cls,
225 sqlite3_stmt *result,
234 sqlite3_column_type (result,
241 sqlite3_column_type (result,
245 return GNUNET_SYSERR;
247 /* sqlite manual guarantees that 'sqlite3_column_text()'
249 text = (const char *) sqlite3_column_text (result,
254 return GNUNET_SYSERR;
256 *dst_size = strlen (text) + 1;
257 *rdst = GNUNET_strdup (text);
263 * Cleanup memory allocated by #extract_var_blob().
265 * @param cls pointer to pointer of allocation
268 clean_utf8_string (void *cls)
270 char **dptr = (char **) cls;
281 * 0-terminated string expected.
283 * @param[out] dst where to store the result, allocated
284 * @return array entry for the result specification to use
286 struct GNUNET_SQ_ResultSpec
287 GNUNET_SQ_result_spec_string (char **dst)
289 struct GNUNET_SQ_ResultSpec rs = {
290 .conv = &extract_utf8_string,
291 .cleaner = &clean_utf8_string,
302 * Extract data from a Postgres database @a result at row @a row.
305 * @param result where to extract data from
306 * @param column column to extract data from
307 * @param[in,out] dst_size where to store size of result, may be NULL
308 * @param[out] dst where to store the result
310 * #GNUNET_YES if all results could be extracted
311 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
314 extract_rsa_pub (void *cls,
315 sqlite3_stmt *result,
320 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
325 sqlite3_column_type (result,
329 return GNUNET_SYSERR;
331 /* sqlite manual says to invoke 'sqlite3_column_blob()'
332 before calling sqlite3_column_bytes() */
333 ret = sqlite3_column_blob (result,
335 have = sqlite3_column_bytes (result,
340 return GNUNET_SYSERR;
343 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
348 return GNUNET_SYSERR;
355 * Function called to clean up memory allocated
356 * by a #GNUNET_PQ_ResultConverter.
361 clean_rsa_pub (void *cls)
363 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
367 GNUNET_CRYPTO_rsa_public_key_free (*pk);
374 * RSA public key expected.
376 * @param[out] rsa where to store the result
377 * @return array entry for the result specification to use
379 struct GNUNET_SQ_ResultSpec
380 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
382 struct GNUNET_SQ_ResultSpec rs = {
383 .conv = &extract_rsa_pub,
384 .cleaner = &clean_rsa_pub,
395 * Extract data from a Postgres database @a result at row @a row.
398 * @param result where to extract data from
399 * @param column column to extract data from
400 * @param[in,out] dst_size where to store size of result, may be NULL
401 * @param[out] dst where to store the result
403 * #GNUNET_YES if all results could be extracted
404 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
407 extract_rsa_sig (void *cls,
408 sqlite3_stmt *result,
413 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
418 sqlite3_column_type (result,
422 return GNUNET_SYSERR;
424 /* sqlite manual says to invoke 'sqlite3_column_blob()'
425 before calling sqlite3_column_bytes() */
426 ret = sqlite3_column_blob (result,
428 have = sqlite3_column_bytes (result,
433 return GNUNET_SYSERR;
436 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
441 return GNUNET_SYSERR;
448 * Function called to clean up memory allocated
449 * by a #GNUNET_PQ_ResultConverter.
451 * @param cls result data to clean up
454 clean_rsa_sig (void *cls)
456 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
460 GNUNET_CRYPTO_rsa_signature_free (*sig);
467 * RSA signature expected.
469 * @param[out] sig where to store the result;
470 * @return array entry for the result specification to use
472 struct GNUNET_SQ_ResultSpec
473 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
475 struct GNUNET_SQ_ResultSpec rs = {
476 .conv = &extract_rsa_sig,
477 .cleaner = &clean_rsa_sig,
488 * Extract absolute time value from a Postgres database @a result at row @a row.
491 * @param result where to extract data from
492 * @param column column to extract data from
493 * @param[in,out] dst_size where to store size of result, may be NULL
494 * @param[out] dst where to store the result
496 * #GNUNET_YES if all results could be extracted
497 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
500 extract_abs_time (void *cls,
501 sqlite3_stmt *result,
506 struct GNUNET_TIME_Absolute *u = dst;
507 struct GNUNET_TIME_Absolute t;
509 GNUNET_assert (sizeof (uint64_t) == *dst_size);
510 if (SQLITE_INTEGER !=
511 sqlite3_column_type (result,
515 return GNUNET_SYSERR;
517 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
519 if (INT64_MAX == t.abs_value_us)
520 t = GNUNET_TIME_UNIT_FOREVER_ABS;
527 * Absolute time expected.
529 * @param[out] at where to store the result
530 * @return array entry for the result specification to use
532 struct GNUNET_SQ_ResultSpec
533 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
535 struct GNUNET_SQ_ResultSpec rs = {
536 .conv = &extract_abs_time,
538 .dst_size = sizeof (struct GNUNET_TIME_Absolute),
547 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
550 * @param result where to extract data from
551 * @param column column to extract data from
552 * @param[in,out] dst_size where to store size of result, may be NULL
553 * @param[out] dst where to store the result
555 * #GNUNET_YES if all results could be extracted
556 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
559 extract_abs_time_nbo (void *cls,
560 sqlite3_stmt *result,
565 struct GNUNET_TIME_AbsoluteNBO *u = dst;
566 struct GNUNET_TIME_Absolute t;
568 GNUNET_assert (sizeof (uint64_t) == *dst_size);
569 if (SQLITE_INTEGER !=
570 sqlite3_column_type (result,
574 return GNUNET_SYSERR;
576 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
578 if (INT64_MAX == t.abs_value_us)
579 t = GNUNET_TIME_UNIT_FOREVER_ABS;
580 *u = GNUNET_TIME_absolute_hton (t);
586 * Absolute time expected.
588 * @param[out] at where to store the result
589 * @return array entry for the result specification to use
591 struct GNUNET_SQ_ResultSpec
592 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
594 struct GNUNET_SQ_ResultSpec rs = {
595 .conv = &extract_abs_time_nbo,
597 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
606 * Extract 16-bit integer from a Postgres database @a result at row @a row.
609 * @param result where to extract data from
610 * @param column column to extract data from
611 * @param[in,out] dst_size where to store size of result, may be NULL
612 * @param[out] dst where to store the result
614 * #GNUNET_YES if all results could be extracted
615 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
618 extract_uint16 (void *cls,
619 sqlite3_stmt *result,
627 GNUNET_assert (sizeof (uint16_t) == *dst_size);
628 if (SQLITE_INTEGER !=
629 sqlite3_column_type (result,
633 return GNUNET_SYSERR;
635 v = (uint64_t) sqlite3_column_int64 (result,
640 return GNUNET_SYSERR;
650 * @param[out] u16 where to store the result
651 * @return array entry for the result specification to use
653 struct GNUNET_SQ_ResultSpec
654 GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
656 struct GNUNET_SQ_ResultSpec rs = {
657 .conv = &extract_uint16,
659 .dst_size = sizeof (uint16_t),
668 * Extract 32-bit integer from a Postgres database @a result at row @a row.
671 * @param result where to extract data from
672 * @param column column to extract data from
673 * @param[in,out] dst_size where to store size of result, may be NULL
674 * @param[out] dst where to store the result
676 * #GNUNET_YES if all results could be extracted
677 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
680 extract_uint32 (void *cls,
681 sqlite3_stmt *result,
689 GNUNET_assert (sizeof (uint32_t) == *dst_size);
690 if (SQLITE_INTEGER !=
691 sqlite3_column_type (result,
695 return GNUNET_SYSERR;
697 v = (uint64_t) sqlite3_column_int64 (result,
702 return GNUNET_SYSERR;
712 * @param[out] u32 where to store the result
713 * @return array entry for the result specification to use
715 struct GNUNET_SQ_ResultSpec
716 GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
718 struct GNUNET_SQ_ResultSpec rs = {
719 .conv = &extract_uint32,
721 .dst_size = sizeof (uint32_t),
730 * Extract 64-bit integer from a Postgres database @a result at row @a row.
733 * @param result where to extract data from
734 * @param column column to extract data from
735 * @param[in,out] dst_size where to store size of result, may be NULL
736 * @param[out] dst where to store the result
738 * #GNUNET_YES if all results could be extracted
739 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
742 extract_uint64 (void *cls,
743 sqlite3_stmt *result,
750 GNUNET_assert (sizeof (uint64_t) == *dst_size);
751 if (SQLITE_INTEGER !=
752 sqlite3_column_type (result,
756 return GNUNET_SYSERR;
758 *u = (uint64_t) sqlite3_column_int64 (result,
767 * @param[out] u64 where to store the result
768 * @return array entry for the result specification to use
770 struct GNUNET_SQ_ResultSpec
771 GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
773 struct GNUNET_SQ_ResultSpec rs = {
774 .conv = &extract_uint64,
776 .dst_size = sizeof (uint64_t),
784 /* end of sq_result_helper.c */