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,
236 return GNUNET_SYSERR;
238 /* sqlite manual guarantees that 'sqlite3_column_text()'
240 text = (const char *) sqlite3_column_text (result,
245 return GNUNET_SYSERR;
247 *dst_size = strlen (text) + 1;
248 *rdst = GNUNET_strdup (text);
254 * Cleanup memory allocated by #extract_var_blob().
256 * @param cls pointer to pointer of allocation
259 clean_utf8_string (void *cls)
261 char **dptr = (char **) cls;
272 * 0-terminated string expected.
274 * @param[out] dst where to store the result, allocated
275 * @return array entry for the result specification to use
277 struct GNUNET_SQ_ResultSpec
278 GNUNET_SQ_result_spec_string (char **dst)
280 struct GNUNET_SQ_ResultSpec rs = {
281 .conv = &extract_utf8_string,
282 .cleaner = &clean_utf8_string,
293 * Extract data from a Postgres database @a result at row @a row.
296 * @param result where to extract data from
297 * @param column column to extract data from
298 * @param[in,out] dst_size where to store size of result, may be NULL
299 * @param[out] dst where to store the result
301 * #GNUNET_YES if all results could be extracted
302 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
305 extract_rsa_pub (void *cls,
306 sqlite3_stmt *result,
311 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
316 sqlite3_column_type (result,
320 return GNUNET_SYSERR;
322 /* sqlite manual says to invoke 'sqlite3_column_blob()'
323 before calling sqlite3_column_bytes() */
324 ret = sqlite3_column_blob (result,
326 have = sqlite3_column_bytes (result,
331 return GNUNET_SYSERR;
334 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
339 return GNUNET_SYSERR;
346 * Function called to clean up memory allocated
347 * by a #GNUNET_PQ_ResultConverter.
352 clean_rsa_pub (void *cls)
354 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
358 GNUNET_CRYPTO_rsa_public_key_free (*pk);
365 * RSA public key expected.
367 * @param[out] rsa where to store the result
368 * @return array entry for the result specification to use
370 struct GNUNET_SQ_ResultSpec
371 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
373 struct GNUNET_SQ_ResultSpec rs = {
374 .conv = &extract_rsa_pub,
375 .cleaner = &clean_rsa_pub,
386 * Extract data from a Postgres database @a result at row @a row.
389 * @param result where to extract data from
390 * @param column column to extract data from
391 * @param[in,out] dst_size where to store size of result, may be NULL
392 * @param[out] dst where to store the result
394 * #GNUNET_YES if all results could be extracted
395 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
398 extract_rsa_sig (void *cls,
399 sqlite3_stmt *result,
404 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
409 sqlite3_column_type (result,
413 return GNUNET_SYSERR;
415 /* sqlite manual says to invoke 'sqlite3_column_blob()'
416 before calling sqlite3_column_bytes() */
417 ret = sqlite3_column_blob (result,
419 have = sqlite3_column_bytes (result,
424 return GNUNET_SYSERR;
427 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
432 return GNUNET_SYSERR;
439 * Function called to clean up memory allocated
440 * by a #GNUNET_PQ_ResultConverter.
442 * @param cls result data to clean up
445 clean_rsa_sig (void *cls)
447 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
451 GNUNET_CRYPTO_rsa_signature_free (*sig);
458 * RSA signature expected.
460 * @param[out] sig where to store the result;
461 * @return array entry for the result specification to use
463 struct GNUNET_SQ_ResultSpec
464 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
466 struct GNUNET_SQ_ResultSpec rs = {
467 .conv = &extract_rsa_sig,
468 .cleaner = &clean_rsa_sig,
479 * Extract absolute time value from a Postgres database @a result at row @a row.
482 * @param result where to extract data from
483 * @param column column to extract data from
484 * @param[in,out] dst_size where to store size of result, may be NULL
485 * @param[out] dst where to store the result
487 * #GNUNET_YES if all results could be extracted
488 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
491 extract_abs_time (void *cls,
492 sqlite3_stmt *result,
497 struct GNUNET_TIME_Absolute *u = dst;
498 struct GNUNET_TIME_Absolute t;
500 GNUNET_assert (sizeof (uint64_t) == *dst_size);
501 if (SQLITE_INTEGER !=
502 sqlite3_column_type (result,
506 return GNUNET_SYSERR;
508 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
510 if (INT64_MAX == t.abs_value_us)
511 t = GNUNET_TIME_UNIT_FOREVER_ABS;
518 * Absolute time expected.
520 * @param[out] at where to store the result
521 * @return array entry for the result specification to use
523 struct GNUNET_SQ_ResultSpec
524 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
526 struct GNUNET_SQ_ResultSpec rs = {
527 .conv = &extract_abs_time,
529 .dst_size = sizeof (struct GNUNET_TIME_Absolute),
538 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
541 * @param result where to extract data from
542 * @param column column to extract data from
543 * @param[in,out] dst_size where to store size of result, may be NULL
544 * @param[out] dst where to store the result
546 * #GNUNET_YES if all results could be extracted
547 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
550 extract_abs_time_nbo (void *cls,
551 sqlite3_stmt *result,
556 struct GNUNET_TIME_AbsoluteNBO *u = dst;
557 struct GNUNET_TIME_Absolute t;
559 GNUNET_assert (sizeof (uint64_t) == *dst_size);
560 if (SQLITE_INTEGER !=
561 sqlite3_column_type (result,
565 return GNUNET_SYSERR;
567 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
569 if (INT64_MAX == t.abs_value_us)
570 t = GNUNET_TIME_UNIT_FOREVER_ABS;
571 *u = GNUNET_TIME_absolute_hton (t);
577 * Absolute time expected.
579 * @param[out] at where to store the result
580 * @return array entry for the result specification to use
582 struct GNUNET_SQ_ResultSpec
583 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
585 struct GNUNET_SQ_ResultSpec rs = {
586 .conv = &extract_abs_time_nbo,
588 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
597 * Extract 16-bit integer from a Postgres database @a result at row @a row.
600 * @param result where to extract data from
601 * @param column column to extract data from
602 * @param[in,out] dst_size where to store size of result, may be NULL
603 * @param[out] dst where to store the result
605 * #GNUNET_YES if all results could be extracted
606 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
609 extract_uint16 (void *cls,
610 sqlite3_stmt *result,
618 GNUNET_assert (sizeof (uint16_t) == *dst_size);
619 if (SQLITE_INTEGER !=
620 sqlite3_column_type (result,
624 return GNUNET_SYSERR;
626 v = (uint64_t) sqlite3_column_int64 (result,
631 return GNUNET_SYSERR;
641 * @param[out] u16 where to store the result
642 * @return array entry for the result specification to use
644 struct GNUNET_SQ_ResultSpec
645 GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
647 struct GNUNET_SQ_ResultSpec rs = {
648 .conv = &extract_uint16,
650 .dst_size = sizeof (uint16_t),
659 * Extract 32-bit integer from a Postgres database @a result at row @a row.
662 * @param result where to extract data from
663 * @param column column to extract data from
664 * @param[in,out] dst_size where to store size of result, may be NULL
665 * @param[out] dst where to store the result
667 * #GNUNET_YES if all results could be extracted
668 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
671 extract_uint32 (void *cls,
672 sqlite3_stmt *result,
680 GNUNET_assert (sizeof (uint32_t) == *dst_size);
681 if (SQLITE_INTEGER !=
682 sqlite3_column_type (result,
686 return GNUNET_SYSERR;
688 v = (uint64_t) sqlite3_column_int64 (result,
693 return GNUNET_SYSERR;
703 * @param[out] u32 where to store the result
704 * @return array entry for the result specification to use
706 struct GNUNET_SQ_ResultSpec
707 GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
709 struct GNUNET_SQ_ResultSpec rs = {
710 .conv = &extract_uint32,
712 .dst_size = sizeof (uint32_t),
721 * Extract 64-bit integer from a Postgres database @a result at row @a row.
724 * @param result where to extract data from
725 * @param column column to extract data from
726 * @param[in,out] dst_size where to store size of result, may be NULL
727 * @param[out] dst where to store the result
729 * #GNUNET_YES if all results could be extracted
730 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
733 extract_uint64 (void *cls,
734 sqlite3_stmt *result,
741 GNUNET_assert (sizeof (uint64_t) == *dst_size);
742 if (SQLITE_INTEGER !=
743 sqlite3_column_type (result,
747 return GNUNET_SYSERR;
749 *u = (uint64_t) sqlite3_column_int64 (result,
758 * @param[out] u64 where to store the result
759 * @return array entry for the result specification to use
761 struct GNUNET_SQ_ResultSpec
762 GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
764 struct GNUNET_SQ_ResultSpec rs = {
765 .conv = &extract_uint64,
767 .dst_size = sizeof (uint64_t),
775 /* end of sq_result_helper.c */