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/>.
19 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file sq/sq_result_helper.c
23 * @brief helper functions for queries
24 * @author Christian Grothoff
27 #include "gnunet_sq_lib.h"
31 * Extract variable-sized binary data from a Postgres database @a result at row @a row.
34 * @param result where to extract data from
35 * @param column column to extract data from
36 * @param[in,out] dst_size where to store size of result, may be NULL
37 * @param[out] dst where to store the result (actually a `void **`)
39 * #GNUNET_YES if all results could be extracted
40 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
43 extract_var_blob (void *cls,
51 void **rdst = (void **) dst;
54 sqlite3_column_type (result,
63 sqlite3_column_type (result,
69 /* sqlite manual says to invoke 'sqlite3_column_blob()'
70 before calling sqlite3_column_bytes() */
71 ret = sqlite3_column_blob (result,
73 have = sqlite3_column_bytes (result,
86 *rdst = GNUNET_malloc (have);
95 * Cleanup memory allocated by #extract_var_blob().
97 * @param cls pointer to pointer of allocation
100 clean_var_blob (void *cls)
102 void **dptr = (void **) cls;
113 * Variable-size result expected.
115 * @param[out] dst where to store the result, allocated
116 * @param[out] sptr where to store the size of @a dst
117 * @return array entry for the result specification to use
119 struct GNUNET_SQ_ResultSpec
120 GNUNET_SQ_result_spec_variable_size (void **dst,
123 struct GNUNET_SQ_ResultSpec rs = {
124 .conv = &extract_var_blob,
125 .cleaner = &clean_var_blob,
137 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
140 * @param result where to extract data from
141 * @param column column to extract data from
142 * @param[in,out] dst_size where to store size of result, may be NULL
143 * @param[out] dst where to store the result
145 * #GNUNET_YES if all results could be extracted
146 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
149 extract_fixed_blob (void *cls,
150 sqlite3_stmt *result,
158 if ( (0 == *dst_size) &&
160 sqlite3_column_type (result,
167 sqlite3_column_type (result,
171 return GNUNET_SYSERR;
173 /* sqlite manual says to invoke 'sqlite3_column_blob()'
174 before calling sqlite3_column_bytes() */
175 ret = sqlite3_column_blob (result,
177 have = sqlite3_column_bytes (result,
179 if (*dst_size != have)
182 return GNUNET_SYSERR;
192 * Fixed-size result expected.
194 * @param[out] dst where to store the result
195 * @param dst_size number of bytes in @a dst
196 * @return array entry for the result specification to use
198 struct GNUNET_SQ_ResultSpec
199 GNUNET_SQ_result_spec_fixed_size (void *dst,
202 struct GNUNET_SQ_ResultSpec rs = {
203 .conv = &extract_fixed_blob,
205 .dst_size = dst_size,
214 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
217 * @param result where to extract data from
218 * @param column column to extract data from
219 * @param[in,out] dst_size where to store size of result, may be NULL
220 * @param[out] dst where to store the result
222 * #GNUNET_YES if all results could be extracted
223 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
226 extract_utf8_string (void *cls,
227 sqlite3_stmt *result,
236 sqlite3_column_type (result,
243 sqlite3_column_type (result,
247 return GNUNET_SYSERR;
249 /* sqlite manual guarantees that 'sqlite3_column_text()'
251 text = (const char *) sqlite3_column_text (result,
256 return GNUNET_SYSERR;
258 *dst_size = strlen (text) + 1;
259 *rdst = GNUNET_strdup (text);
265 * Cleanup memory allocated by #extract_var_blob().
267 * @param cls pointer to pointer of allocation
270 clean_utf8_string (void *cls)
272 char **dptr = (char **) cls;
283 * 0-terminated string expected.
285 * @param[out] dst where to store the result, allocated
286 * @return array entry for the result specification to use
288 struct GNUNET_SQ_ResultSpec
289 GNUNET_SQ_result_spec_string (char **dst)
291 struct GNUNET_SQ_ResultSpec rs = {
292 .conv = &extract_utf8_string,
293 .cleaner = &clean_utf8_string,
304 * Extract data from a Postgres database @a result at row @a row.
307 * @param result where to extract data from
308 * @param column column to extract data from
309 * @param[in,out] dst_size where to store size of result, may be NULL
310 * @param[out] dst where to store the result
312 * #GNUNET_YES if all results could be extracted
313 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
316 extract_rsa_pub (void *cls,
317 sqlite3_stmt *result,
322 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
327 sqlite3_column_type (result,
331 return GNUNET_SYSERR;
333 /* sqlite manual says to invoke 'sqlite3_column_blob()'
334 before calling sqlite3_column_bytes() */
335 ret = sqlite3_column_blob (result,
337 have = sqlite3_column_bytes (result,
342 return GNUNET_SYSERR;
345 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
350 return GNUNET_SYSERR;
357 * Function called to clean up memory allocated
358 * by a #GNUNET_PQ_ResultConverter.
363 clean_rsa_pub (void *cls)
365 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
369 GNUNET_CRYPTO_rsa_public_key_free (*pk);
376 * RSA public key expected.
378 * @param[out] rsa where to store the result
379 * @return array entry for the result specification to use
381 struct GNUNET_SQ_ResultSpec
382 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
384 struct GNUNET_SQ_ResultSpec rs = {
385 .conv = &extract_rsa_pub,
386 .cleaner = &clean_rsa_pub,
397 * Extract data from a Postgres database @a result at row @a row.
400 * @param result where to extract data from
401 * @param column column to extract data from
402 * @param[in,out] dst_size where to store size of result, may be NULL
403 * @param[out] dst where to store the result
405 * #GNUNET_YES if all results could be extracted
406 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
409 extract_rsa_sig (void *cls,
410 sqlite3_stmt *result,
415 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
420 sqlite3_column_type (result,
424 return GNUNET_SYSERR;
426 /* sqlite manual says to invoke 'sqlite3_column_blob()'
427 before calling sqlite3_column_bytes() */
428 ret = sqlite3_column_blob (result,
430 have = sqlite3_column_bytes (result,
435 return GNUNET_SYSERR;
438 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
443 return GNUNET_SYSERR;
450 * Function called to clean up memory allocated
451 * by a #GNUNET_PQ_ResultConverter.
453 * @param cls result data to clean up
456 clean_rsa_sig (void *cls)
458 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
462 GNUNET_CRYPTO_rsa_signature_free (*sig);
469 * RSA signature expected.
471 * @param[out] sig where to store the result;
472 * @return array entry for the result specification to use
474 struct GNUNET_SQ_ResultSpec
475 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
477 struct GNUNET_SQ_ResultSpec rs = {
478 .conv = &extract_rsa_sig,
479 .cleaner = &clean_rsa_sig,
490 * Extract absolute time value from a Postgres database @a result at row @a row.
493 * @param result where to extract data from
494 * @param column column to extract data from
495 * @param[in,out] dst_size where to store size of result, may be NULL
496 * @param[out] dst where to store the result
498 * #GNUNET_YES if all results could be extracted
499 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
502 extract_abs_time (void *cls,
503 sqlite3_stmt *result,
508 struct GNUNET_TIME_Absolute *u = dst;
509 struct GNUNET_TIME_Absolute t;
511 GNUNET_assert (sizeof (uint64_t) == *dst_size);
512 if (SQLITE_INTEGER !=
513 sqlite3_column_type (result,
517 return GNUNET_SYSERR;
519 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
521 if (INT64_MAX == t.abs_value_us)
522 t = GNUNET_TIME_UNIT_FOREVER_ABS;
529 * Absolute time expected.
531 * @param[out] at where to store the result
532 * @return array entry for the result specification to use
534 struct GNUNET_SQ_ResultSpec
535 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
537 struct GNUNET_SQ_ResultSpec rs = {
538 .conv = &extract_abs_time,
540 .dst_size = sizeof (struct GNUNET_TIME_Absolute),
549 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
552 * @param result where to extract data from
553 * @param column column to extract data from
554 * @param[in,out] dst_size where to store size of result, may be NULL
555 * @param[out] dst where to store the result
557 * #GNUNET_YES if all results could be extracted
558 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
561 extract_abs_time_nbo (void *cls,
562 sqlite3_stmt *result,
567 struct GNUNET_TIME_AbsoluteNBO *u = dst;
568 struct GNUNET_TIME_Absolute t;
570 GNUNET_assert (sizeof (uint64_t) == *dst_size);
571 if (SQLITE_INTEGER !=
572 sqlite3_column_type (result,
576 return GNUNET_SYSERR;
578 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
580 if (INT64_MAX == t.abs_value_us)
581 t = GNUNET_TIME_UNIT_FOREVER_ABS;
582 *u = GNUNET_TIME_absolute_hton (t);
588 * Absolute time expected.
590 * @param[out] at where to store the result
591 * @return array entry for the result specification to use
593 struct GNUNET_SQ_ResultSpec
594 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
596 struct GNUNET_SQ_ResultSpec rs = {
597 .conv = &extract_abs_time_nbo,
599 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
608 * Extract 16-bit integer from a Postgres database @a result at row @a row.
611 * @param result where to extract data from
612 * @param column column to extract data from
613 * @param[in,out] dst_size where to store size of result, may be NULL
614 * @param[out] dst where to store the result
616 * #GNUNET_YES if all results could be extracted
617 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
620 extract_uint16 (void *cls,
621 sqlite3_stmt *result,
629 GNUNET_assert (sizeof (uint16_t) == *dst_size);
630 if (SQLITE_INTEGER !=
631 sqlite3_column_type (result,
635 return GNUNET_SYSERR;
637 v = (uint64_t) sqlite3_column_int64 (result,
642 return GNUNET_SYSERR;
652 * @param[out] u16 where to store the result
653 * @return array entry for the result specification to use
655 struct GNUNET_SQ_ResultSpec
656 GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
658 struct GNUNET_SQ_ResultSpec rs = {
659 .conv = &extract_uint16,
661 .dst_size = sizeof (uint16_t),
670 * Extract 32-bit integer from a Postgres database @a result at row @a row.
673 * @param result where to extract data from
674 * @param column column to extract data from
675 * @param[in,out] dst_size where to store size of result, may be NULL
676 * @param[out] dst where to store the result
678 * #GNUNET_YES if all results could be extracted
679 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
682 extract_uint32 (void *cls,
683 sqlite3_stmt *result,
691 GNUNET_assert (sizeof (uint32_t) == *dst_size);
692 if (SQLITE_INTEGER !=
693 sqlite3_column_type (result,
697 return GNUNET_SYSERR;
699 v = (uint64_t) sqlite3_column_int64 (result,
704 return GNUNET_SYSERR;
714 * @param[out] u32 where to store the result
715 * @return array entry for the result specification to use
717 struct GNUNET_SQ_ResultSpec
718 GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
720 struct GNUNET_SQ_ResultSpec rs = {
721 .conv = &extract_uint32,
723 .dst_size = sizeof (uint32_t),
732 * Extract 64-bit integer from a Postgres database @a result at row @a row.
735 * @param result where to extract data from
736 * @param column column to extract data from
737 * @param[in,out] dst_size where to store size of result, may be NULL
738 * @param[out] dst where to store the result
740 * #GNUNET_YES if all results could be extracted
741 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
744 extract_uint64 (void *cls,
745 sqlite3_stmt *result,
752 GNUNET_assert (sizeof (uint64_t) == *dst_size);
753 if (SQLITE_INTEGER !=
754 sqlite3_column_type (result,
758 return GNUNET_SYSERR;
760 *u = (uint64_t) sqlite3_column_int64 (result,
769 * @param[out] u64 where to store the result
770 * @return array entry for the result specification to use
772 struct GNUNET_SQ_ResultSpec
773 GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
775 struct GNUNET_SQ_ResultSpec rs = {
776 .conv = &extract_uint64,
778 .dst_size = sizeof (uint64_t),
786 /* end of sq_result_helper.c */