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,
56 /* sqlite manual says to invoke 'sqlite3_column_blob()'
57 before calling sqlite3_column_bytes() */
58 ret = sqlite3_column_blob (result,
60 have = sqlite3_column_bytes (result,
73 *rdst = GNUNET_malloc (have);
82 * Cleanup memory allocated by #extract_var_blob().
84 * @param cls pointer to pointer of allocation
87 clean_var_blob (void *cls)
89 void **dptr = (void **) cls;
100 * Variable-size result expected.
102 * @param[out] dst where to store the result, allocated
103 * @param[out] sptr where to store the size of @a dst
104 * @return array entry for the result specification to use
106 struct GNUNET_SQ_ResultSpec
107 GNUNET_SQ_result_spec_variable_size (void **dst,
110 struct GNUNET_SQ_ResultSpec rs = {
111 .conv = &extract_var_blob,
112 .cleaner = &clean_var_blob,
124 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
127 * @param result where to extract data from
128 * @param column column to extract data from
129 * @param[in,out] dst_size where to store size of result, may be NULL
130 * @param[out] dst where to store the result
132 * #GNUNET_YES if all results could be extracted
133 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
136 extract_fixed_blob (void *cls,
137 sqlite3_stmt *result,
146 sqlite3_column_type (result,
150 return GNUNET_SYSERR;
152 /* sqlite manual says to invoke 'sqlite3_column_blob()'
153 before calling sqlite3_column_bytes() */
154 ret = sqlite3_column_blob (result,
156 have = sqlite3_column_bytes (result,
158 if (*dst_size != have)
161 return GNUNET_SYSERR;
171 * Fixed-size result expected.
173 * @param[out] dst where to store the result
174 * @param dst_size number of bytes in @a dst
175 * @return array entry for the result specification to use
177 struct GNUNET_SQ_ResultSpec
178 GNUNET_SQ_result_spec_fixed_size (void *dst,
181 struct GNUNET_SQ_ResultSpec rs = {
182 .conv = &extract_fixed_blob,
184 .dst_size = dst_size,
193 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
196 * @param result where to extract data from
197 * @param column column to extract data from
198 * @param[in,out] dst_size where to store size of result, may be NULL
199 * @param[out] dst where to store the result
201 * #GNUNET_YES if all results could be extracted
202 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
205 extract_utf8_string (void *cls,
206 sqlite3_stmt *result,
215 sqlite3_column_type (result,
219 return GNUNET_SYSERR;
221 /* sqlite manual guarantees that 'sqlite3_column_text()'
223 text = (const char *) sqlite3_column_text (result,
228 return GNUNET_SYSERR;
230 *dst_size = strlen (text) + 1;
231 *rdst = GNUNET_strdup (text);
237 * Cleanup memory allocated by #extract_var_blob().
239 * @param cls pointer to pointer of allocation
242 clean_utf8_string (void *cls)
244 char **dptr = (char **) cls;
255 * 0-terminated string expected.
257 * @param[out] dst where to store the result, allocated
258 * @return array entry for the result specification to use
260 struct GNUNET_SQ_ResultSpec
261 GNUNET_SQ_result_spec_string (char **dst)
263 struct GNUNET_SQ_ResultSpec rs = {
264 .conv = &extract_utf8_string,
265 .cleaner = &clean_utf8_string,
276 * Extract data from a Postgres database @a result at row @a row.
279 * @param result where to extract data from
280 * @param column column to extract data from
281 * @param[in,out] dst_size where to store size of result, may be NULL
282 * @param[out] dst where to store the result
284 * #GNUNET_YES if all results could be extracted
285 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
288 extract_rsa_pub (void *cls,
289 sqlite3_stmt *result,
294 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
299 sqlite3_column_type (result,
303 return GNUNET_SYSERR;
305 /* sqlite manual says to invoke 'sqlite3_column_blob()'
306 before calling sqlite3_column_bytes() */
307 ret = sqlite3_column_blob (result,
309 have = sqlite3_column_bytes (result,
314 return GNUNET_SYSERR;
317 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
322 return GNUNET_SYSERR;
329 * Function called to clean up memory allocated
330 * by a #GNUNET_PQ_ResultConverter.
335 clean_rsa_pub (void *cls)
337 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
341 GNUNET_CRYPTO_rsa_public_key_free (*pk);
348 * RSA public key expected.
350 * @param[out] rsa where to store the result
351 * @return array entry for the result specification to use
353 struct GNUNET_SQ_ResultSpec
354 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
356 struct GNUNET_SQ_ResultSpec rs = {
357 .conv = &extract_rsa_pub,
358 .cleaner = &clean_rsa_pub,
369 * Extract data from a Postgres database @a result at row @a row.
372 * @param result where to extract data from
373 * @param column column to extract data from
374 * @param[in,out] dst_size where to store size of result, may be NULL
375 * @param[out] dst where to store the result
377 * #GNUNET_YES if all results could be extracted
378 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
381 extract_rsa_sig (void *cls,
382 sqlite3_stmt *result,
387 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
392 sqlite3_column_type (result,
396 return GNUNET_SYSERR;
398 /* sqlite manual says to invoke 'sqlite3_column_blob()'
399 before calling sqlite3_column_bytes() */
400 ret = sqlite3_column_blob (result,
402 have = sqlite3_column_bytes (result,
407 return GNUNET_SYSERR;
410 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
415 return GNUNET_SYSERR;
422 * Function called to clean up memory allocated
423 * by a #GNUNET_PQ_ResultConverter.
425 * @param cls result data to clean up
428 clean_rsa_sig (void *cls)
430 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
434 GNUNET_CRYPTO_rsa_signature_free (*sig);
441 * RSA signature expected.
443 * @param[out] sig where to store the result;
444 * @return array entry for the result specification to use
446 struct GNUNET_SQ_ResultSpec
447 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
449 struct GNUNET_SQ_ResultSpec rs = {
450 .conv = &extract_rsa_sig,
451 .cleaner = &clean_rsa_sig,
462 * Absolute time expected.
464 * @param[out] at where to store the result
465 * @return array entry for the result specification to use
467 struct GNUNET_SQ_ResultSpec
468 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
470 return GNUNET_SQ_result_spec_uint64 (&at->abs_value_us);
475 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
478 * @param result where to extract data from
479 * @param column column to extract data from
480 * @param[in,out] dst_size where to store size of result, may be NULL
481 * @param[out] dst where to store the result
483 * #GNUNET_YES if all results could be extracted
484 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
487 extract_abs_time_nbo (void *cls,
488 sqlite3_stmt *result,
493 struct GNUNET_TIME_AbsoluteNBO *u = dst;
494 struct GNUNET_TIME_Absolute t;
496 GNUNET_assert (sizeof (uint64_t) == *dst_size);
497 if (SQLITE_INTEGER !=
498 sqlite3_column_type (result,
502 return GNUNET_SYSERR;
504 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
506 *u = GNUNET_TIME_absolute_hton (t);
512 * Absolute time expected.
514 * @param[out] at where to store the result
515 * @return array entry for the result specification to use
517 struct GNUNET_SQ_ResultSpec
518 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
520 struct GNUNET_SQ_ResultSpec rs = {
521 .conv = &extract_abs_time_nbo,
523 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
532 * Extract 16-bit integer from a Postgres database @a result at row @a row.
535 * @param result where to extract data from
536 * @param column column to extract data from
537 * @param[in,out] dst_size where to store size of result, may be NULL
538 * @param[out] dst where to store the result
540 * #GNUNET_YES if all results could be extracted
541 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
544 extract_uint16 (void *cls,
545 sqlite3_stmt *result,
553 GNUNET_assert (sizeof (uint16_t) == *dst_size);
554 if (SQLITE_INTEGER !=
555 sqlite3_column_type (result,
559 return GNUNET_SYSERR;
561 v = (uint64_t) sqlite3_column_int64 (result,
566 return GNUNET_SYSERR;
576 * @param[out] u16 where to store the result
577 * @return array entry for the result specification to use
579 struct GNUNET_SQ_ResultSpec
580 GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
582 struct GNUNET_SQ_ResultSpec rs = {
583 .conv = &extract_uint16,
585 .dst_size = sizeof (uint16_t),
594 * Extract 32-bit integer from a Postgres database @a result at row @a row.
597 * @param result where to extract data from
598 * @param column column to extract data from
599 * @param[in,out] dst_size where to store size of result, may be NULL
600 * @param[out] dst where to store the result
602 * #GNUNET_YES if all results could be extracted
603 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
606 extract_uint32 (void *cls,
607 sqlite3_stmt *result,
615 GNUNET_assert (sizeof (uint32_t) == *dst_size);
616 if (SQLITE_INTEGER !=
617 sqlite3_column_type (result,
621 return GNUNET_SYSERR;
623 v = (uint64_t) sqlite3_column_int64 (result,
628 return GNUNET_SYSERR;
638 * @param[out] u32 where to store the result
639 * @return array entry for the result specification to use
641 struct GNUNET_SQ_ResultSpec
642 GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
644 struct GNUNET_SQ_ResultSpec rs = {
645 .conv = &extract_uint32,
647 .dst_size = sizeof (uint32_t),
656 * Extract 64-bit integer from a Postgres database @a result at row @a row.
659 * @param result where to extract data from
660 * @param column column to extract data from
661 * @param[in,out] dst_size where to store size of result, may be NULL
662 * @param[out] dst where to store the result
664 * #GNUNET_YES if all results could be extracted
665 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
668 extract_uint64 (void *cls,
669 sqlite3_stmt *result,
676 GNUNET_assert (sizeof (uint64_t) == *dst_size);
677 if (SQLITE_INTEGER !=
678 sqlite3_column_type (result,
682 return GNUNET_SYSERR;
684 *u = (uint64_t) sqlite3_column_int64 (result,
693 * @param[out] u64 where to store the result
694 * @return array entry for the result specification to use
696 struct GNUNET_SQ_ResultSpec
697 GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
699 struct GNUNET_SQ_ResultSpec rs = {
700 .conv = &extract_uint64,
702 .dst_size = sizeof (uint64_t),
710 /* end of sq_result_helper.c */