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 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.
17 * @file sq/sq_result_helper.c
18 * @brief helper functions for queries
19 * @author Christian Grothoff
22 #include "gnunet_sq_lib.h"
26 * Extract variable-sized binary data from a Postgres database @a result at row @a row.
29 * @param result where to extract data from
30 * @param column column to extract data from
31 * @param[in,out] dst_size where to store size of result, may be NULL
32 * @param[out] dst where to store the result (actually a `void **`)
34 * #GNUNET_YES if all results could be extracted
35 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
38 extract_var_blob (void *cls,
46 void **rdst = (void **) dst;
49 sqlite3_column_type (result,
58 sqlite3_column_type (result,
64 /* sqlite manual says to invoke 'sqlite3_column_blob()'
65 before calling sqlite3_column_bytes() */
66 ret = sqlite3_column_blob (result,
68 have = sqlite3_column_bytes (result,
81 *rdst = GNUNET_malloc (have);
90 * Cleanup memory allocated by #extract_var_blob().
92 * @param cls pointer to pointer of allocation
95 clean_var_blob (void *cls)
97 void **dptr = (void **) cls;
108 * Variable-size result expected.
110 * @param[out] dst where to store the result, allocated
111 * @param[out] sptr where to store the size of @a dst
112 * @return array entry for the result specification to use
114 struct GNUNET_SQ_ResultSpec
115 GNUNET_SQ_result_spec_variable_size (void **dst,
118 struct GNUNET_SQ_ResultSpec rs = {
119 .conv = &extract_var_blob,
120 .cleaner = &clean_var_blob,
132 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
135 * @param result where to extract data from
136 * @param column column to extract data from
137 * @param[in,out] dst_size where to store size of result, may be NULL
138 * @param[out] dst where to store the result
140 * #GNUNET_YES if all results could be extracted
141 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
144 extract_fixed_blob (void *cls,
145 sqlite3_stmt *result,
153 if ( (0 == *dst_size) &&
155 sqlite3_column_type (result,
162 sqlite3_column_type (result,
166 return GNUNET_SYSERR;
168 /* sqlite manual says to invoke 'sqlite3_column_blob()'
169 before calling sqlite3_column_bytes() */
170 ret = sqlite3_column_blob (result,
172 have = sqlite3_column_bytes (result,
174 if (*dst_size != have)
177 return GNUNET_SYSERR;
187 * Fixed-size result expected.
189 * @param[out] dst where to store the result
190 * @param dst_size number of bytes in @a dst
191 * @return array entry for the result specification to use
193 struct GNUNET_SQ_ResultSpec
194 GNUNET_SQ_result_spec_fixed_size (void *dst,
197 struct GNUNET_SQ_ResultSpec rs = {
198 .conv = &extract_fixed_blob,
200 .dst_size = dst_size,
209 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
212 * @param result where to extract data from
213 * @param column column to extract data from
214 * @param[in,out] dst_size where to store size of result, may be NULL
215 * @param[out] dst where to store the result
217 * #GNUNET_YES if all results could be extracted
218 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
221 extract_utf8_string (void *cls,
222 sqlite3_stmt *result,
231 sqlite3_column_type (result,
238 sqlite3_column_type (result,
242 return GNUNET_SYSERR;
244 /* sqlite manual guarantees that 'sqlite3_column_text()'
246 text = (const char *) sqlite3_column_text (result,
251 return GNUNET_SYSERR;
253 *dst_size = strlen (text) + 1;
254 *rdst = GNUNET_strdup (text);
260 * Cleanup memory allocated by #extract_var_blob().
262 * @param cls pointer to pointer of allocation
265 clean_utf8_string (void *cls)
267 char **dptr = (char **) cls;
278 * 0-terminated string expected.
280 * @param[out] dst where to store the result, allocated
281 * @return array entry for the result specification to use
283 struct GNUNET_SQ_ResultSpec
284 GNUNET_SQ_result_spec_string (char **dst)
286 struct GNUNET_SQ_ResultSpec rs = {
287 .conv = &extract_utf8_string,
288 .cleaner = &clean_utf8_string,
299 * Extract data from a Postgres database @a result at row @a row.
302 * @param result where to extract data from
303 * @param column column to extract data from
304 * @param[in,out] dst_size where to store size of result, may be NULL
305 * @param[out] dst where to store the result
307 * #GNUNET_YES if all results could be extracted
308 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
311 extract_rsa_pub (void *cls,
312 sqlite3_stmt *result,
317 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
322 sqlite3_column_type (result,
326 return GNUNET_SYSERR;
328 /* sqlite manual says to invoke 'sqlite3_column_blob()'
329 before calling sqlite3_column_bytes() */
330 ret = sqlite3_column_blob (result,
332 have = sqlite3_column_bytes (result,
337 return GNUNET_SYSERR;
340 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
345 return GNUNET_SYSERR;
352 * Function called to clean up memory allocated
353 * by a #GNUNET_PQ_ResultConverter.
358 clean_rsa_pub (void *cls)
360 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
364 GNUNET_CRYPTO_rsa_public_key_free (*pk);
371 * RSA public key expected.
373 * @param[out] rsa where to store the result
374 * @return array entry for the result specification to use
376 struct GNUNET_SQ_ResultSpec
377 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
379 struct GNUNET_SQ_ResultSpec rs = {
380 .conv = &extract_rsa_pub,
381 .cleaner = &clean_rsa_pub,
392 * Extract data from a Postgres database @a result at row @a row.
395 * @param result where to extract data from
396 * @param column column to extract data from
397 * @param[in,out] dst_size where to store size of result, may be NULL
398 * @param[out] dst where to store the result
400 * #GNUNET_YES if all results could be extracted
401 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
404 extract_rsa_sig (void *cls,
405 sqlite3_stmt *result,
410 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
415 sqlite3_column_type (result,
419 return GNUNET_SYSERR;
421 /* sqlite manual says to invoke 'sqlite3_column_blob()'
422 before calling sqlite3_column_bytes() */
423 ret = sqlite3_column_blob (result,
425 have = sqlite3_column_bytes (result,
430 return GNUNET_SYSERR;
433 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
438 return GNUNET_SYSERR;
445 * Function called to clean up memory allocated
446 * by a #GNUNET_PQ_ResultConverter.
448 * @param cls result data to clean up
451 clean_rsa_sig (void *cls)
453 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
457 GNUNET_CRYPTO_rsa_signature_free (*sig);
464 * RSA signature expected.
466 * @param[out] sig where to store the result;
467 * @return array entry for the result specification to use
469 struct GNUNET_SQ_ResultSpec
470 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
472 struct GNUNET_SQ_ResultSpec rs = {
473 .conv = &extract_rsa_sig,
474 .cleaner = &clean_rsa_sig,
485 * Extract absolute time value from a Postgres database @a result at row @a row.
488 * @param result where to extract data from
489 * @param column column to extract data from
490 * @param[in,out] dst_size where to store size of result, may be NULL
491 * @param[out] dst where to store the result
493 * #GNUNET_YES if all results could be extracted
494 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
497 extract_abs_time (void *cls,
498 sqlite3_stmt *result,
503 struct GNUNET_TIME_Absolute *u = dst;
504 struct GNUNET_TIME_Absolute t;
506 GNUNET_assert (sizeof (uint64_t) == *dst_size);
507 if (SQLITE_INTEGER !=
508 sqlite3_column_type (result,
512 return GNUNET_SYSERR;
514 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
516 if (INT64_MAX == t.abs_value_us)
517 t = GNUNET_TIME_UNIT_FOREVER_ABS;
524 * Absolute time expected.
526 * @param[out] at where to store the result
527 * @return array entry for the result specification to use
529 struct GNUNET_SQ_ResultSpec
530 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
532 struct GNUNET_SQ_ResultSpec rs = {
533 .conv = &extract_abs_time,
535 .dst_size = sizeof (struct GNUNET_TIME_Absolute),
544 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
547 * @param result where to extract data from
548 * @param column column to extract data from
549 * @param[in,out] dst_size where to store size of result, may be NULL
550 * @param[out] dst where to store the result
552 * #GNUNET_YES if all results could be extracted
553 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
556 extract_abs_time_nbo (void *cls,
557 sqlite3_stmt *result,
562 struct GNUNET_TIME_AbsoluteNBO *u = dst;
563 struct GNUNET_TIME_Absolute t;
565 GNUNET_assert (sizeof (uint64_t) == *dst_size);
566 if (SQLITE_INTEGER !=
567 sqlite3_column_type (result,
571 return GNUNET_SYSERR;
573 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
575 if (INT64_MAX == t.abs_value_us)
576 t = GNUNET_TIME_UNIT_FOREVER_ABS;
577 *u = GNUNET_TIME_absolute_hton (t);
583 * Absolute time expected.
585 * @param[out] at where to store the result
586 * @return array entry for the result specification to use
588 struct GNUNET_SQ_ResultSpec
589 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
591 struct GNUNET_SQ_ResultSpec rs = {
592 .conv = &extract_abs_time_nbo,
594 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
603 * Extract 16-bit integer from a Postgres database @a result at row @a row.
606 * @param result where to extract data from
607 * @param column column to extract data from
608 * @param[in,out] dst_size where to store size of result, may be NULL
609 * @param[out] dst where to store the result
611 * #GNUNET_YES if all results could be extracted
612 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
615 extract_uint16 (void *cls,
616 sqlite3_stmt *result,
624 GNUNET_assert (sizeof (uint16_t) == *dst_size);
625 if (SQLITE_INTEGER !=
626 sqlite3_column_type (result,
630 return GNUNET_SYSERR;
632 v = (uint64_t) sqlite3_column_int64 (result,
637 return GNUNET_SYSERR;
647 * @param[out] u16 where to store the result
648 * @return array entry for the result specification to use
650 struct GNUNET_SQ_ResultSpec
651 GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
653 struct GNUNET_SQ_ResultSpec rs = {
654 .conv = &extract_uint16,
656 .dst_size = sizeof (uint16_t),
665 * Extract 32-bit integer from a Postgres database @a result at row @a row.
668 * @param result where to extract data from
669 * @param column column to extract data from
670 * @param[in,out] dst_size where to store size of result, may be NULL
671 * @param[out] dst where to store the result
673 * #GNUNET_YES if all results could be extracted
674 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
677 extract_uint32 (void *cls,
678 sqlite3_stmt *result,
686 GNUNET_assert (sizeof (uint32_t) == *dst_size);
687 if (SQLITE_INTEGER !=
688 sqlite3_column_type (result,
692 return GNUNET_SYSERR;
694 v = (uint64_t) sqlite3_column_int64 (result,
699 return GNUNET_SYSERR;
709 * @param[out] u32 where to store the result
710 * @return array entry for the result specification to use
712 struct GNUNET_SQ_ResultSpec
713 GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
715 struct GNUNET_SQ_ResultSpec rs = {
716 .conv = &extract_uint32,
718 .dst_size = sizeof (uint32_t),
727 * Extract 64-bit integer from a Postgres database @a result at row @a row.
730 * @param result where to extract data from
731 * @param column column to extract data from
732 * @param[in,out] dst_size where to store size of result, may be NULL
733 * @param[out] dst where to store the result
735 * #GNUNET_YES if all results could be extracted
736 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
739 extract_uint64 (void *cls,
740 sqlite3_stmt *result,
747 GNUNET_assert (sizeof (uint64_t) == *dst_size);
748 if (SQLITE_INTEGER !=
749 sqlite3_column_type (result,
753 return GNUNET_SYSERR;
755 *u = (uint64_t) sqlite3_column_int64 (result,
764 * @param[out] u64 where to store the result
765 * @return array entry for the result specification to use
767 struct GNUNET_SQ_ResultSpec
768 GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
770 struct GNUNET_SQ_ResultSpec rs = {
771 .conv = &extract_uint64,
773 .dst_size = sizeof (uint64_t),
781 /* end of sq_result_helper.c */