2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file pq/pq_result_helper.c
22 * @brief functions to extract result values
23 * @author Christian Grothoff
26 #include "gnunet_util_lib.h"
27 #include "gnunet_pq_lib.h"
31 * Function called to clean up memory allocated
32 * by a #GNUNET_PQ_ResultConverter.
35 * @param rd result data to clean up
38 clean_varsize_blob (void *cls,
53 * Extract data from a Postgres database @a result at row @a row.
56 * @param result where to extract data from
57 * @param int row to extract data from
58 * @param fname name (or prefix) of the fields to extract from
59 * @param[in,out] dst_size where to store size of result, may be NULL
60 * @param[out] dst where to store the result
62 * #GNUNET_YES if all results could be extracted
63 * #GNUNET_SYSERR if a result was invalid (non-existing field)
66 extract_varsize_blob (void *cls,
80 *((void **) dst) = NULL;
82 fnum = PQfnumber (result,
89 if (PQgetisnull (result,
93 /* Let's allow this for varsize */
96 /* if a field is null, continue but
97 * remember that we now return a different result */
98 len = PQgetlength (result,
101 res = PQgetvalue (result,
104 GNUNET_assert (NULL != res);
106 idst = GNUNET_malloc (len);
107 *((void **) dst) = idst;
116 * Variable-size result expected.
118 * @param name name of the field in the table
119 * @param[out] dst where to store the result, allocated
120 * @param[out] sptr where to store the size of @a dst
121 * @return array entry for the result specification to use
123 struct GNUNET_PQ_ResultSpec
124 GNUNET_PQ_result_spec_variable_size (const char *name,
128 struct GNUNET_PQ_ResultSpec res =
129 { &extract_varsize_blob,
130 &clean_varsize_blob, NULL,
131 (void *) (dst), 0, name, sptr };
137 * Extract data from a Postgres database @a result at row @a row.
140 * @param result where to extract data from
141 * @param int row to extract data from
142 * @param fname name (or prefix) of the fields to extract from
143 * @param[in] dst_size desired size, never NULL
144 * @param[out] dst where to store the result
146 * #GNUNET_YES if all results could be extracted
147 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
150 extract_fixed_blob (void *cls,
162 fnum = PQfnumber (result,
167 return GNUNET_SYSERR;
169 if (PQgetisnull (result,
174 return GNUNET_SYSERR;
177 /* if a field is null, continue but
178 * remember that we now return a different result */
179 len = PQgetlength (result,
182 if (*dst_size != len)
185 return GNUNET_SYSERR;
187 res = PQgetvalue (result,
190 GNUNET_assert (NULL != res);
199 * Fixed-size result expected.
201 * @param name name of the field in the table
202 * @param[out] dst where to store the result
203 * @param dst_size number of bytes in @a dst
204 * @return array entry for the result specification to use
206 struct GNUNET_PQ_ResultSpec
207 GNUNET_PQ_result_spec_fixed_size (const char *name,
211 struct GNUNET_PQ_ResultSpec res =
212 { &extract_fixed_blob,
214 (dst), dst_size, name, NULL };
220 * Extract data from a Postgres database @a result at row @a row.
223 * @param result where to extract data from
224 * @param int row to extract data from
225 * @param fname name (or prefix) of the fields to extract from
226 * @param[in,out] dst_size where to store size of result, may be NULL
227 * @param[out] dst where to store the result
229 * #GNUNET_YES if all results could be extracted
230 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
233 extract_rsa_public_key (void *cls,
240 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
247 fnum = PQfnumber (result,
252 return GNUNET_SYSERR;
254 if (PQgetisnull (result,
259 return GNUNET_SYSERR;
261 /* if a field is null, continue but
262 * remember that we now return a different result */
263 len = PQgetlength (result,
266 res = PQgetvalue (result,
269 *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
274 return GNUNET_SYSERR;
281 * Function called to clean up memory allocated
282 * by a #GNUNET_PQ_ResultConverter.
285 * @param rd result data to clean up
288 clean_rsa_public_key (void *cls,
291 struct GNUNET_CRYPTO_RsaPublicKey **pk = rd;
296 GNUNET_CRYPTO_rsa_public_key_free (*pk);
303 * RSA public key expected.
305 * @param name name of the field in the table
306 * @param[out] rsa where to store the result
307 * @return array entry for the result specification to use
309 struct GNUNET_PQ_ResultSpec
310 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
311 struct GNUNET_CRYPTO_RsaPublicKey **rsa)
313 struct GNUNET_PQ_ResultSpec res =
314 { &extract_rsa_public_key,
315 &clean_rsa_public_key,
317 (void *) rsa, 0, name, NULL };
323 * Extract data from a Postgres database @a result at row @a row.
326 * @param result where to extract data from
327 * @param int row to extract data from
328 * @param fname name (or prefix) of the fields to extract from
329 * @param[in,out] dst_size where to store size of result, may be NULL
330 * @param[out] dst where to store the result
332 * #GNUNET_YES if all results could be extracted
333 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
336 extract_rsa_signature (void *cls,
343 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
350 fnum = PQfnumber (result,
355 return GNUNET_SYSERR;
357 if (PQgetisnull (result,
362 return GNUNET_SYSERR;
364 /* if a field is null, continue but
365 * remember that we now return a different result */
366 len = PQgetlength (result,
369 res = PQgetvalue (result,
372 *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
377 return GNUNET_SYSERR;
384 * Function called to clean up memory allocated
385 * by a #GNUNET_PQ_ResultConverter.
388 * @param rd result data to clean up
391 clean_rsa_signature (void *cls,
394 struct GNUNET_CRYPTO_RsaSignature **sig = rd;
399 GNUNET_CRYPTO_rsa_signature_free (*sig);
406 * RSA signature expected.
408 * @param name name of the field in the table
409 * @param[out] sig where to store the result;
410 * @return array entry for the result specification to use
412 struct GNUNET_PQ_ResultSpec
413 GNUNET_PQ_result_spec_rsa_signature (const char *name,
414 struct GNUNET_CRYPTO_RsaSignature **sig)
416 struct GNUNET_PQ_ResultSpec res =
417 { &extract_rsa_signature,
418 &clean_rsa_signature,
420 (void *) sig, 0, (name), NULL };
426 * Extract data from a Postgres database @a result at row @a row.
429 * @param result where to extract data from
430 * @param int row to extract data from
431 * @param fname name (or prefix) of the fields to extract from
432 * @param[in,out] dst_size where to store size of result, may be NULL
433 * @param[out] dst where to store the result
435 * #GNUNET_YES if all results could be extracted
436 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
439 extract_string (void *cls,
453 fnum = PQfnumber (result,
458 return GNUNET_SYSERR;
460 if (PQgetisnull (result,
465 return GNUNET_SYSERR;
467 /* if a field is null, continue but
468 * remember that we now return a different result */
469 len = PQgetlength (result,
472 res = PQgetvalue (result,
475 *str = GNUNET_strndup (res,
480 return GNUNET_SYSERR;
487 * Function called to clean up memory allocated
488 * by a #GNUNET_PQ_ResultConverter.
491 * @param rd result data to clean up
494 clean_string (void *cls,
509 * 0-terminated string expected.
511 * @param name name of the field in the table
512 * @param[out] dst where to store the result, allocated
513 * @return array entry for the result specification to use
515 struct GNUNET_PQ_ResultSpec
516 GNUNET_PQ_result_spec_string (const char *name,
519 struct GNUNET_PQ_ResultSpec res =
523 (void *) dst, 0, (name), NULL };
529 * Extract data from a Postgres database @a result at row @a row.
532 * @param result where to extract data from
533 * @param int row to extract data from
534 * @param fname name (or prefix) of the fields to extract from
535 * @param[in,out] dst_size where to store size of result, may be NULL
536 * @param[out] dst where to store the result
538 * #GNUNET_YES if all results could be extracted
539 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
542 extract_abs_time (void *cls,
549 struct GNUNET_TIME_Absolute *udst = dst;
554 fnum = PQfnumber (result,
559 return GNUNET_SYSERR;
561 if (PQgetisnull (result,
566 return GNUNET_SYSERR;
568 GNUNET_assert (NULL != dst);
569 if (sizeof (struct GNUNET_TIME_Absolute) != *dst_size)
572 return GNUNET_SYSERR;
574 if (sizeof (int64_t) !=
580 return GNUNET_SYSERR;
582 res = (int64_t *) PQgetvalue (result,
585 if (INT64_MAX == *res)
586 *udst = GNUNET_TIME_UNIT_FOREVER_ABS;
588 udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res);
594 * Absolute time expected.
596 * @param name name of the field in the table
597 * @param[out] at where to store the result
598 * @return array entry for the result specification to use
600 struct GNUNET_PQ_ResultSpec
601 GNUNET_PQ_result_spec_absolute_time (const char *name,
602 struct GNUNET_TIME_Absolute *at)
604 struct GNUNET_PQ_ResultSpec res =
608 (void *) at, sizeof (*at), (name), NULL };
614 * Absolute time in network byte order expected.
616 * @param name name of the field in the table
617 * @param[out] at where to store the result
618 * @return array entry for the result specification to use
620 struct GNUNET_PQ_ResultSpec
621 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
622 struct GNUNET_TIME_AbsoluteNBO *at)
624 struct GNUNET_PQ_ResultSpec res =
625 GNUNET_PQ_result_spec_auto_from_type(name, &at->abs_value_us__);
631 * Extract data from a Postgres database @a result at row @a row.
634 * @param result where to extract data from
635 * @param int row to extract data from
636 * @param fname name (or prefix) of the fields to extract from
637 * @param[in,out] dst_size where to store size of result, may be NULL
638 * @param[out] dst where to store the result
640 * #GNUNET_YES if all results could be extracted
641 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
644 extract_uint16 (void *cls,
651 uint16_t *udst = dst;
656 fnum = PQfnumber (result,
661 return GNUNET_SYSERR;
663 if (PQgetisnull (result,
668 return GNUNET_SYSERR;
670 GNUNET_assert (NULL != dst);
671 if (sizeof (uint16_t) != *dst_size)
674 return GNUNET_SYSERR;
676 if (sizeof (uint16_t) !=
682 return GNUNET_SYSERR;
684 res = (uint16_t *) PQgetvalue (result,
687 *udst = ntohs (*res);
695 * @param name name of the field in the table
696 * @param[out] u16 where to store the result
697 * @return array entry for the result specification to use
699 struct GNUNET_PQ_ResultSpec
700 GNUNET_PQ_result_spec_uint16 (const char *name,
703 struct GNUNET_PQ_ResultSpec res =
707 (void *) u16, sizeof (*u16), (name), NULL };
713 * Extract data from a Postgres database @a result at row @a row.
716 * @param result where to extract data from
717 * @param int row to extract data from
718 * @param fname name (or prefix) of the fields to extract from
719 * @param[in,out] dst_size where to store size of result, may be NULL
720 * @param[out] dst where to store the result
722 * #GNUNET_YES if all results could be extracted
723 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
726 extract_uint32 (void *cls,
733 uint32_t *udst = dst;
738 fnum = PQfnumber (result,
743 return GNUNET_SYSERR;
745 if (PQgetisnull (result,
750 return GNUNET_SYSERR;
752 GNUNET_assert (NULL != dst);
753 if (sizeof (uint32_t) != *dst_size)
756 return GNUNET_SYSERR;
758 if (sizeof (uint32_t) !=
764 return GNUNET_SYSERR;
766 res = (uint32_t *) PQgetvalue (result,
769 *udst = ntohl (*res);
777 * @param name name of the field in the table
778 * @param[out] u32 where to store the result
779 * @return array entry for the result specification to use
781 struct GNUNET_PQ_ResultSpec
782 GNUNET_PQ_result_spec_uint32 (const char *name,
785 struct GNUNET_PQ_ResultSpec res =
789 (void *) u32, sizeof (*u32), (name), NULL };
795 * Extract data from a Postgres database @a result at row @a row.
798 * @param result where to extract data from
799 * @param int row to extract data from
800 * @param fname name (or prefix) of the fields to extract from
801 * @param[in,out] dst_size where to store size of result, may be NULL
802 * @param[out] dst where to store the result
804 * #GNUNET_YES if all results could be extracted
805 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
808 extract_uint64 (void *cls,
815 uint64_t *udst = dst;
820 fnum = PQfnumber (result,
825 return GNUNET_SYSERR;
827 if (PQgetisnull (result,
832 return GNUNET_SYSERR;
834 GNUNET_assert (NULL != dst);
835 if (sizeof (uint64_t) != *dst_size)
838 return GNUNET_SYSERR;
840 if (sizeof (uint64_t) !=
846 return GNUNET_SYSERR;
848 res = (uint64_t *) PQgetvalue (result,
851 *udst = GNUNET_ntohll (*res);
859 * @param name name of the field in the table
860 * @param[out] u64 where to store the result
861 * @return array entry for the result specification to use
863 struct GNUNET_PQ_ResultSpec
864 GNUNET_PQ_result_spec_uint64 (const char *name,
867 struct GNUNET_PQ_ResultSpec res =
871 (void *) u64, sizeof (*u64), (name), NULL };
876 /* end of pq_result_helper.c */