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,
123 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
126 * @param result where to extract data from
127 * @param column column to extract data from
128 * @param[in,out] dst_size where to store size of result, may be NULL
129 * @param[out] dst where to store the result
131 * #GNUNET_YES if all results could be extracted
132 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
135 extract_fixed_blob (void *cls,
136 sqlite3_stmt *result,
145 sqlite3_column_type (result,
149 return GNUNET_SYSERR;
151 /* sqlite manual says to invoke 'sqlite3_column_blob()'
152 before calling sqlite3_column_bytes() */
153 ret = sqlite3_column_blob (result,
155 have = sqlite3_column_bytes (result,
157 if (*dst_size != have)
160 return GNUNET_SYSERR;
170 * Fixed-size result expected.
172 * @param[out] dst where to store the result
173 * @param dst_size number of bytes in @a dst
174 * @return array entry for the result specification to use
176 struct GNUNET_SQ_ResultSpec
177 GNUNET_SQ_result_spec_fixed_size (void *dst,
180 struct GNUNET_SQ_ResultSpec rs = {
181 .conv = &extract_fixed_blob,
183 .dst_size = dst_size,
192 * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
195 * @param result where to extract data from
196 * @param column column to extract data from
197 * @param[in,out] dst_size where to store size of result, may be NULL
198 * @param[out] dst where to store the result
200 * #GNUNET_YES if all results could be extracted
201 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
204 extract_utf8_string (void *cls,
205 sqlite3_stmt *result,
214 sqlite3_column_type (result,
218 return GNUNET_SYSERR;
220 /* sqlite manual guarantees that 'sqlite3_column_text()'
222 text = (const char *) sqlite3_column_text (result,
227 return GNUNET_SYSERR;
229 *dst_size = strlen (text) + 1;
230 *rdst = GNUNET_strdup (text);
236 * Cleanup memory allocated by #extract_var_blob().
238 * @param cls pointer to pointer of allocation
241 clean_utf8_string (void *cls)
243 char **dptr = (char **) cls;
254 * 0-terminated string expected.
256 * @param[out] dst where to store the result, allocated
257 * @return array entry for the result specification to use
259 struct GNUNET_SQ_ResultSpec
260 GNUNET_SQ_result_spec_string (char **dst)
262 struct GNUNET_SQ_ResultSpec rs = {
263 .conv = &extract_utf8_string,
264 .cleaner = &clean_utf8_string,
275 * Extract data from a Postgres database @a result at row @a row.
278 * @param result where to extract data from
279 * @param column column to extract data from
280 * @param[in,out] dst_size where to store size of result, may be NULL
281 * @param[out] dst where to store the result
283 * #GNUNET_YES if all results could be extracted
284 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
287 extract_rsa_pub (void *cls,
288 sqlite3_stmt *result,
293 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
298 sqlite3_column_type (result,
302 return GNUNET_SYSERR;
304 /* sqlite manual says to invoke 'sqlite3_column_blob()'
305 before calling sqlite3_column_bytes() */
306 ret = sqlite3_column_blob (result,
308 have = sqlite3_column_bytes (result,
313 return GNUNET_SYSERR;
316 *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret,
321 return GNUNET_SYSERR;
328 * Function called to clean up memory allocated
329 * by a #GNUNET_PQ_ResultConverter.
334 clean_rsa_pub (void *cls)
336 struct GNUNET_CRYPTO_RsaPublicKey **pk = cls;
340 GNUNET_CRYPTO_rsa_public_key_free (*pk);
347 * RSA public key expected.
349 * @param[out] rsa where to store the result
350 * @return array entry for the result specification to use
352 struct GNUNET_SQ_ResultSpec
353 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
355 struct GNUNET_SQ_ResultSpec rs = {
356 .conv = &extract_rsa_pub,
357 .cleaner = &clean_rsa_pub,
368 * Extract data from a Postgres database @a result at row @a row.
371 * @param result where to extract data from
372 * @param column column to extract data from
373 * @param[in,out] dst_size where to store size of result, may be NULL
374 * @param[out] dst where to store the result
376 * #GNUNET_YES if all results could be extracted
377 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
380 extract_rsa_sig (void *cls,
381 sqlite3_stmt *result,
386 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
391 sqlite3_column_type (result,
395 return GNUNET_SYSERR;
397 /* sqlite manual says to invoke 'sqlite3_column_blob()'
398 before calling sqlite3_column_bytes() */
399 ret = sqlite3_column_blob (result,
401 have = sqlite3_column_bytes (result,
406 return GNUNET_SYSERR;
409 *sig = GNUNET_CRYPTO_rsa_signature_decode (ret,
414 return GNUNET_SYSERR;
421 * Function called to clean up memory allocated
422 * by a #GNUNET_PQ_ResultConverter.
424 * @param cls result data to clean up
427 clean_rsa_sig (void *cls)
429 struct GNUNET_CRYPTO_RsaSignature **sig = cls;
433 GNUNET_CRYPTO_rsa_signature_free (*sig);
440 * RSA signature expected.
442 * @param[out] sig where to store the result;
443 * @return array entry for the result specification to use
445 struct GNUNET_SQ_ResultSpec
446 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
448 struct GNUNET_SQ_ResultSpec rs = {
449 .conv = &extract_rsa_sig,
450 .cleaner = &clean_rsa_sig,
461 * Absolute time expected.
463 * @param[out] at where to store the result
464 * @return array entry for the result specification to use
466 struct GNUNET_SQ_ResultSpec
467 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
469 return GNUNET_SQ_result_spec_uint64 (&at->abs_value_us);
474 * Extract absolute time value in NBO from a Postgres database @a result at row @a row.
477 * @param result where to extract data from
478 * @param column column to extract data from
479 * @param[in,out] dst_size where to store size of result, may be NULL
480 * @param[out] dst where to store the result
482 * #GNUNET_YES if all results could be extracted
483 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
486 extract_abs_time_nbo (void *cls,
487 sqlite3_stmt *result,
492 struct GNUNET_TIME_AbsoluteNBO *u = dst;
493 struct GNUNET_TIME_Absolute t;
495 GNUNET_assert (sizeof (uint64_t) == *dst_size);
496 if (SQLITE_INTEGER !=
497 sqlite3_column_type (result,
501 return GNUNET_SYSERR;
503 t.abs_value_us = (uint64_t) sqlite3_column_int64 (result,
505 *u = GNUNET_TIME_absolute_hton (t);
511 * Absolute time expected.
513 * @param[out] at where to store the result
514 * @return array entry for the result specification to use
516 struct GNUNET_SQ_ResultSpec
517 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
519 struct GNUNET_SQ_ResultSpec rs = {
520 .conv = &extract_abs_time_nbo,
522 .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
531 * Extract 16-bit integer from a Postgres database @a result at row @a row.
534 * @param result where to extract data from
535 * @param column column to extract data from
536 * @param[in,out] dst_size where to store size of result, may be NULL
537 * @param[out] dst where to store the result
539 * #GNUNET_YES if all results could be extracted
540 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
543 extract_uint16 (void *cls,
544 sqlite3_stmt *result,
552 GNUNET_assert (sizeof (uint16_t) == *dst_size);
553 if (SQLITE_INTEGER !=
554 sqlite3_column_type (result,
558 return GNUNET_SYSERR;
560 v = (uint64_t) sqlite3_column_int64 (result,
565 return GNUNET_SYSERR;
575 * @param[out] u16 where to store the result
576 * @return array entry for the result specification to use
578 struct GNUNET_SQ_ResultSpec
579 GNUNET_SQ_result_spec_uint16 (uint16_t *u16)
581 struct GNUNET_SQ_ResultSpec rs = {
582 .conv = &extract_uint16,
584 .dst_size = sizeof (uint16_t),
593 * Extract 32-bit integer from a Postgres database @a result at row @a row.
596 * @param result where to extract data from
597 * @param column column to extract data from
598 * @param[in,out] dst_size where to store size of result, may be NULL
599 * @param[out] dst where to store the result
601 * #GNUNET_YES if all results could be extracted
602 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
605 extract_uint32 (void *cls,
606 sqlite3_stmt *result,
614 GNUNET_assert (sizeof (uint32_t) == *dst_size);
615 if (SQLITE_INTEGER !=
616 sqlite3_column_type (result,
620 return GNUNET_SYSERR;
622 v = (uint64_t) sqlite3_column_int64 (result,
627 return GNUNET_SYSERR;
637 * @param[out] u32 where to store the result
638 * @return array entry for the result specification to use
640 struct GNUNET_SQ_ResultSpec
641 GNUNET_SQ_result_spec_uint32 (uint32_t *u32)
643 struct GNUNET_SQ_ResultSpec rs = {
644 .conv = &extract_uint32,
646 .dst_size = sizeof (uint32_t),
655 * Extract 64-bit integer from a Postgres database @a result at row @a row.
658 * @param result where to extract data from
659 * @param column column to extract data from
660 * @param[in,out] dst_size where to store size of result, may be NULL
661 * @param[out] dst where to store the result
663 * #GNUNET_YES if all results could be extracted
664 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
667 extract_uint64 (void *cls,
668 sqlite3_stmt *result,
675 GNUNET_assert (sizeof (uint64_t) == *dst_size);
676 if (SQLITE_INTEGER !=
677 sqlite3_column_type (result,
681 return GNUNET_SYSERR;
683 *u = (uint64_t) sqlite3_column_int64 (result,
692 * @param[out] u64 where to store the result
693 * @return array entry for the result specification to use
695 struct GNUNET_SQ_ResultSpec
696 GNUNET_SQ_result_spec_uint64 (uint64_t *u64)
698 struct GNUNET_SQ_ResultSpec rs = {
699 .conv = &extract_uint64,
701 .dst_size = sizeof (uint64_t),
709 /* end of sq_result_helper.c */