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 };
138 * Extract data from a Postgres database @a result at row @a row.
141 * @param result where to extract data from
142 * @param int row to extract data from
143 * @param fname name (or prefix) of the fields to extract from
144 * @param[in] dst_size desired size, never NULL
145 * @param[out] dst where to store the result
147 * #GNUNET_YES if all results could be extracted
148 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
151 extract_fixed_blob (void *cls,
163 fnum = PQfnumber (result,
168 return GNUNET_SYSERR;
170 if (PQgetisnull (result,
175 return GNUNET_SYSERR;
178 /* if a field is null, continue but
179 * remember that we now return a different result */
180 len = PQgetlength (result,
183 if (*dst_size != len)
186 return GNUNET_SYSERR;
188 res = PQgetvalue (result,
191 GNUNET_assert (NULL != res);
200 * Fixed-size result expected.
202 * @param name name of the field in the table
203 * @param[out] dst where to store the result
204 * @param dst_size number of bytes in @a dst
205 * @return array entry for the result specification to use
207 struct GNUNET_PQ_ResultSpec
208 GNUNET_PQ_result_spec_fixed_size (const char *name,
212 struct GNUNET_PQ_ResultSpec res =
213 { &extract_fixed_blob,
215 (dst), dst_size, name, NULL };
222 * Extract data from a Postgres database @a result at row @a row.
225 * @param result where to extract data from
226 * @param int row to extract data from
227 * @param fname name (or prefix) of the fields to extract from
228 * @param[in,out] dst_size where to store size of result, may be NULL
229 * @param[out] dst where to store the result
231 * #GNUNET_YES if all results could be extracted
232 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
235 extract_rsa_public_key (void *cls,
242 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
249 fnum = PQfnumber (result,
254 return GNUNET_SYSERR;
256 if (PQgetisnull (result,
261 return GNUNET_SYSERR;
263 /* if a field is null, continue but
264 * remember that we now return a different result */
265 len = PQgetlength (result,
268 res = PQgetvalue (result,
271 *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
276 return GNUNET_SYSERR;
283 * Function called to clean up memory allocated
284 * by a #GNUNET_PQ_ResultConverter.
287 * @param rd result data to clean up
290 clean_rsa_public_key (void *cls,
293 struct GNUNET_CRYPTO_RsaPublicKey **pk = rd;
298 GNUNET_CRYPTO_rsa_public_key_free (*pk);
305 * RSA public key expected.
307 * @param name name of the field in the table
308 * @param[out] rsa where to store the result
309 * @return array entry for the result specification to use
311 struct GNUNET_PQ_ResultSpec
312 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
313 struct GNUNET_CRYPTO_RsaPublicKey **rsa)
315 struct GNUNET_PQ_ResultSpec res =
316 { &extract_rsa_public_key,
317 &clean_rsa_public_key,
319 (void *) rsa, 0, name, NULL };
326 * Extract data from a Postgres database @a result at row @a row.
329 * @param result where to extract data from
330 * @param int row to extract data from
331 * @param fname name (or prefix) of the fields to extract from
332 * @param[in,out] dst_size where to store size of result, may be NULL
333 * @param[out] dst where to store the result
335 * #GNUNET_YES if all results could be extracted
336 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
339 extract_rsa_signature (void *cls,
346 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
353 fnum = PQfnumber (result,
358 return GNUNET_SYSERR;
360 if (PQgetisnull (result,
365 return GNUNET_SYSERR;
367 /* if a field is null, continue but
368 * remember that we now return a different result */
369 len = PQgetlength (result,
372 res = PQgetvalue (result,
375 *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
380 return GNUNET_SYSERR;
387 * Function called to clean up memory allocated
388 * by a #GNUNET_PQ_ResultConverter.
391 * @param rd result data to clean up
394 clean_rsa_signature (void *cls,
397 struct GNUNET_CRYPTO_RsaSignature **sig = rd;
402 GNUNET_CRYPTO_rsa_signature_free (*sig);
409 * RSA signature expected.
411 * @param name name of the field in the table
412 * @param[out] sig where to store the result;
413 * @return array entry for the result specification to use
415 struct GNUNET_PQ_ResultSpec
416 GNUNET_PQ_result_spec_rsa_signature (const char *name,
417 struct GNUNET_CRYPTO_RsaSignature **sig)
419 struct GNUNET_PQ_ResultSpec res =
420 { &extract_rsa_signature,
421 &clean_rsa_signature,
423 (void *) sig, 0, (name), NULL };
430 * Extract data from a Postgres database @a result at row @a row.
433 * @param result where to extract data from
434 * @param int row to extract data from
435 * @param fname name (or prefix) of the fields to extract from
436 * @param[in,out] dst_size where to store size of result, may be NULL
437 * @param[out] dst where to store the result
439 * #GNUNET_YES if all results could be extracted
440 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
443 extract_string (void *cls,
457 fnum = PQfnumber (result,
462 return GNUNET_SYSERR;
464 if (PQgetisnull (result,
469 return GNUNET_SYSERR;
471 /* if a field is null, continue but
472 * remember that we now return a different result */
473 len = PQgetlength (result,
476 res = PQgetvalue (result,
479 *str = GNUNET_strndup (res,
484 return GNUNET_SYSERR;
491 * Function called to clean up memory allocated
492 * by a #GNUNET_PQ_ResultConverter.
495 * @param rd result data to clean up
498 clean_string (void *cls,
513 * 0-terminated string expected.
515 * @param name name of the field in the table
516 * @param[out] dst where to store the result, allocated
517 * @return array entry for the result specification to use
519 struct GNUNET_PQ_ResultSpec
520 GNUNET_PQ_result_spec_string (const char *name,
523 struct GNUNET_PQ_ResultSpec res =
527 (void *) dst, 0, (name), NULL };
534 * Extract data from a Postgres database @a result at row @a row.
537 * @param result where to extract data from
538 * @param int row to extract data from
539 * @param fname name (or prefix) of the fields to extract from
540 * @param[in,out] dst_size where to store size of result, may be NULL
541 * @param[out] dst where to store the result
543 * #GNUNET_YES if all results could be extracted
544 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
547 extract_abs_time (void *cls,
554 struct GNUNET_TIME_Absolute *udst = dst;
559 fnum = PQfnumber (result,
564 return GNUNET_SYSERR;
566 if (PQgetisnull (result,
571 return GNUNET_SYSERR;
573 GNUNET_assert (NULL != dst);
574 if (sizeof(struct GNUNET_TIME_Absolute) != *dst_size)
577 return GNUNET_SYSERR;
579 if (sizeof(int64_t) !=
585 return GNUNET_SYSERR;
587 res = (int64_t *) PQgetvalue (result,
590 if (INT64_MAX == *res)
591 *udst = GNUNET_TIME_UNIT_FOREVER_ABS;
593 udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res);
599 * Absolute time expected.
601 * @param name name of the field in the table
602 * @param[out] at where to store the result
603 * @return array entry for the result specification to use
605 struct GNUNET_PQ_ResultSpec
606 GNUNET_PQ_result_spec_absolute_time (const char *name,
607 struct GNUNET_TIME_Absolute *at)
609 struct GNUNET_PQ_ResultSpec res =
613 (void *) at, sizeof(*at), (name), NULL };
620 * Absolute time in network byte order expected.
622 * @param name name of the field in the table
623 * @param[out] at where to store the result
624 * @return array entry for the result specification to use
626 struct GNUNET_PQ_ResultSpec
627 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
628 struct GNUNET_TIME_AbsoluteNBO *at)
630 struct GNUNET_PQ_ResultSpec res =
631 GNUNET_PQ_result_spec_auto_from_type (name, &at->abs_value_us__);
638 * Extract data from a Postgres database @a result at row @a row.
641 * @param result where to extract data from
642 * @param int row to extract data from
643 * @param fname name (or prefix) of the fields to extract from
644 * @param[in,out] dst_size where to store size of result, may be NULL
645 * @param[out] dst where to store the result
647 * #GNUNET_YES if all results could be extracted
648 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
651 extract_uint16 (void *cls,
658 uint16_t *udst = dst;
663 fnum = PQfnumber (result,
668 return GNUNET_SYSERR;
670 if (PQgetisnull (result,
675 return GNUNET_SYSERR;
677 GNUNET_assert (NULL != dst);
678 if (sizeof(uint16_t) != *dst_size)
681 return GNUNET_SYSERR;
683 if (sizeof(uint16_t) !=
689 return GNUNET_SYSERR;
691 res = (uint16_t *) PQgetvalue (result,
694 *udst = ntohs (*res);
702 * @param name name of the field in the table
703 * @param[out] u16 where to store the result
704 * @return array entry for the result specification to use
706 struct GNUNET_PQ_ResultSpec
707 GNUNET_PQ_result_spec_uint16 (const char *name,
710 struct GNUNET_PQ_ResultSpec res =
714 (void *) u16, sizeof(*u16), (name), NULL };
721 * Extract data from a Postgres database @a result at row @a row.
724 * @param result where to extract data from
725 * @param int row to extract data from
726 * @param fname name (or prefix) of the fields to extract from
727 * @param[in,out] dst_size where to store size of result, may be NULL
728 * @param[out] dst where to store the result
730 * #GNUNET_YES if all results could be extracted
731 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
734 extract_uint32 (void *cls,
741 uint32_t *udst = dst;
746 fnum = PQfnumber (result,
751 return GNUNET_SYSERR;
753 if (PQgetisnull (result,
758 return GNUNET_SYSERR;
760 GNUNET_assert (NULL != dst);
761 if (sizeof(uint32_t) != *dst_size)
764 return GNUNET_SYSERR;
766 if (sizeof(uint32_t) !=
772 return GNUNET_SYSERR;
774 res = (uint32_t *) PQgetvalue (result,
777 *udst = ntohl (*res);
785 * @param name name of the field in the table
786 * @param[out] u32 where to store the result
787 * @return array entry for the result specification to use
789 struct GNUNET_PQ_ResultSpec
790 GNUNET_PQ_result_spec_uint32 (const char *name,
793 struct GNUNET_PQ_ResultSpec res =
797 (void *) u32, sizeof(*u32), (name), NULL };
804 * Extract data from a Postgres database @a result at row @a row.
807 * @param result where to extract data from
808 * @param int row to extract data from
809 * @param fname name (or prefix) of the fields to extract from
810 * @param[in,out] dst_size where to store size of result, may be NULL
811 * @param[out] dst where to store the result
813 * #GNUNET_YES if all results could be extracted
814 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
817 extract_uint64 (void *cls,
824 uint64_t *udst = dst;
829 fnum = PQfnumber (result,
834 return GNUNET_SYSERR;
836 if (PQgetisnull (result,
841 return GNUNET_SYSERR;
843 GNUNET_assert (NULL != dst);
844 if (sizeof(uint64_t) != *dst_size)
847 return GNUNET_SYSERR;
849 if (sizeof(uint64_t) !=
855 return GNUNET_SYSERR;
857 res = (uint64_t *) PQgetvalue (result,
860 *udst = GNUNET_ntohll (*res);
868 * @param name name of the field in the table
869 * @param[out] u64 where to store the result
870 * @return array entry for the result specification to use
872 struct GNUNET_PQ_ResultSpec
873 GNUNET_PQ_result_spec_uint64 (const char *name,
876 struct GNUNET_PQ_ResultSpec res =
880 (void *) u64, sizeof(*u64), (name), NULL };
886 /* end of pq_result_helper.c */