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/>.
19 * @file pq/pq_result_helper.c
20 * @brief functions to extract result values
21 * @author Christian Grothoff
24 #include "gnunet_util_lib.h"
25 #include "gnunet_pq_lib.h"
29 * Function called to clean up memory allocated
30 * by a #GNUNET_PQ_ResultConverter.
33 * @param rd result data to clean up
36 clean_varsize_blob (void *cls,
51 * Extract data from a Postgres database @a result at row @a row.
54 * @param result where to extract data from
55 * @param int row to extract data from
56 * @param fname name (or prefix) of the fields to extract from
57 * @param[in,out] dst_size where to store size of result, may be NULL
58 * @param[out] dst where to store the result
60 * #GNUNET_YES if all results could be extracted
61 * #GNUNET_SYSERR if a result was invalid (non-existing field)
64 extract_varsize_blob (void *cls,
78 *((void **) dst) = NULL;
80 fnum = PQfnumber (result,
87 if (PQgetisnull (result,
91 /* Let's allow this for varsize */
94 /* if a field is null, continue but
95 * remember that we now return a different result */
96 len = PQgetlength (result,
99 res = PQgetvalue (result,
102 GNUNET_assert (NULL != res);
104 idst = GNUNET_malloc (len);
105 *((void **) dst) = idst;
114 * Variable-size result expected.
116 * @param name name of the field in the table
117 * @param[out] dst where to store the result, allocated
118 * @param[out] sptr where to store the size of @a dst
119 * @return array entry for the result specification to use
121 struct GNUNET_PQ_ResultSpec
122 GNUNET_PQ_result_spec_variable_size (const char *name,
126 struct GNUNET_PQ_ResultSpec res =
127 { &extract_varsize_blob,
128 &clean_varsize_blob, NULL,
129 (void *) (dst), 0, name, sptr };
135 * Extract data from a Postgres database @a result at row @a row.
138 * @param result where to extract data from
139 * @param int row to extract data from
140 * @param fname name (or prefix) of the fields to extract from
141 * @param[in] dst_size desired size, never NULL
142 * @param[out] dst where to store the result
144 * #GNUNET_YES if all results could be extracted
145 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
148 extract_fixed_blob (void *cls,
160 fnum = PQfnumber (result,
165 return GNUNET_SYSERR;
167 if (PQgetisnull (result,
172 return GNUNET_SYSERR;
175 /* if a field is null, continue but
176 * remember that we now return a different result */
177 len = PQgetlength (result,
180 if (*dst_size != len)
183 return GNUNET_SYSERR;
185 res = PQgetvalue (result,
188 GNUNET_assert (NULL != res);
197 * Fixed-size result expected.
199 * @param name name of the field in the table
200 * @param[out] dst where to store the result
201 * @param dst_size number of bytes in @a dst
202 * @return array entry for the result specification to use
204 struct GNUNET_PQ_ResultSpec
205 GNUNET_PQ_result_spec_fixed_size (const char *name,
209 struct GNUNET_PQ_ResultSpec res =
210 { &extract_fixed_blob,
212 (dst), dst_size, name, NULL };
218 * Extract data from a Postgres database @a result at row @a row.
221 * @param result where to extract data from
222 * @param int row to extract data from
223 * @param fname name (or prefix) of the fields to extract from
224 * @param[in,out] dst_size where to store size of result, may be NULL
225 * @param[out] dst where to store the result
227 * #GNUNET_YES if all results could be extracted
228 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
231 extract_rsa_public_key (void *cls,
238 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
245 fnum = PQfnumber (result,
250 return GNUNET_SYSERR;
252 if (PQgetisnull (result,
257 return GNUNET_SYSERR;
259 /* if a field is null, continue but
260 * remember that we now return a different result */
261 len = PQgetlength (result,
264 res = PQgetvalue (result,
267 *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
272 return GNUNET_SYSERR;
279 * Function called to clean up memory allocated
280 * by a #GNUNET_PQ_ResultConverter.
283 * @param rd result data to clean up
286 clean_rsa_public_key (void *cls,
289 struct GNUNET_CRYPTO_RsaPublicKey **pk = rd;
294 GNUNET_CRYPTO_rsa_public_key_free (*pk);
301 * RSA public key expected.
303 * @param name name of the field in the table
304 * @param[out] rsa where to store the result
305 * @return array entry for the result specification to use
307 struct GNUNET_PQ_ResultSpec
308 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
309 struct GNUNET_CRYPTO_RsaPublicKey **rsa)
311 struct GNUNET_PQ_ResultSpec res =
312 { &extract_rsa_public_key,
313 &clean_rsa_public_key,
315 (void *) rsa, 0, name, NULL };
321 * Extract data from a Postgres database @a result at row @a row.
324 * @param result where to extract data from
325 * @param int row to extract data from
326 * @param fname name (or prefix) of the fields to extract from
327 * @param[in,out] dst_size where to store size of result, may be NULL
328 * @param[out] dst where to store the result
330 * #GNUNET_YES if all results could be extracted
331 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
334 extract_rsa_signature (void *cls,
341 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
348 fnum = PQfnumber (result,
353 return GNUNET_SYSERR;
355 if (PQgetisnull (result,
360 return GNUNET_SYSERR;
362 /* if a field is null, continue but
363 * remember that we now return a different result */
364 len = PQgetlength (result,
367 res = PQgetvalue (result,
370 *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
375 return GNUNET_SYSERR;
382 * Function called to clean up memory allocated
383 * by a #GNUNET_PQ_ResultConverter.
386 * @param rd result data to clean up
389 clean_rsa_signature (void *cls,
392 struct GNUNET_CRYPTO_RsaSignature **sig = rd;
397 GNUNET_CRYPTO_rsa_signature_free (*sig);
404 * RSA signature expected.
406 * @param name name of the field in the table
407 * @param[out] sig where to store the result;
408 * @return array entry for the result specification to use
410 struct GNUNET_PQ_ResultSpec
411 GNUNET_PQ_result_spec_rsa_signature (const char *name,
412 struct GNUNET_CRYPTO_RsaSignature **sig)
414 struct GNUNET_PQ_ResultSpec res =
415 { &extract_rsa_signature,
416 &clean_rsa_signature,
418 (void *) sig, 0, (name), NULL };
424 * Extract data from a Postgres database @a result at row @a row.
427 * @param result where to extract data from
428 * @param int row to extract data from
429 * @param fname name (or prefix) of the fields to extract from
430 * @param[in,out] dst_size where to store size of result, may be NULL
431 * @param[out] dst where to store the result
433 * #GNUNET_YES if all results could be extracted
434 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
437 extract_string (void *cls,
451 fnum = PQfnumber (result,
456 return GNUNET_SYSERR;
458 if (PQgetisnull (result,
463 return GNUNET_SYSERR;
465 /* if a field is null, continue but
466 * remember that we now return a different result */
467 len = PQgetlength (result,
470 res = PQgetvalue (result,
473 *str = GNUNET_strndup (res,
478 return GNUNET_SYSERR;
485 * Function called to clean up memory allocated
486 * by a #GNUNET_PQ_ResultConverter.
489 * @param rd result data to clean up
492 clean_string (void *cls,
507 * 0-terminated string expected.
509 * @param name name of the field in the table
510 * @param[out] dst where to store the result, allocated
511 * @return array entry for the result specification to use
513 struct GNUNET_PQ_ResultSpec
514 GNUNET_PQ_result_spec_string (const char *name,
517 struct GNUNET_PQ_ResultSpec res =
521 (void *) dst, 0, (name), NULL };
527 * Extract data from a Postgres database @a result at row @a row.
530 * @param result where to extract data from
531 * @param int row to extract data from
532 * @param fname name (or prefix) of the fields to extract from
533 * @param[in,out] dst_size where to store size of result, may be NULL
534 * @param[out] dst where to store the result
536 * #GNUNET_YES if all results could be extracted
537 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
540 extract_abs_time (void *cls,
547 struct GNUNET_TIME_Absolute *udst = dst;
552 fnum = PQfnumber (result,
557 return GNUNET_SYSERR;
559 if (PQgetisnull (result,
564 return GNUNET_SYSERR;
566 GNUNET_assert (NULL != dst);
567 if (sizeof (struct GNUNET_TIME_Absolute) != *dst_size)
570 return GNUNET_SYSERR;
572 if (sizeof (int64_t) !=
578 return GNUNET_SYSERR;
580 res = (int64_t *) PQgetvalue (result,
583 if (INT64_MAX == *res)
584 *udst = GNUNET_TIME_UNIT_FOREVER_ABS;
586 udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res);
592 * Absolute time expected.
594 * @param name name of the field in the table
595 * @param[out] at where to store the result
596 * @return array entry for the result specification to use
598 struct GNUNET_PQ_ResultSpec
599 GNUNET_PQ_result_spec_absolute_time (const char *name,
600 struct GNUNET_TIME_Absolute *at)
602 struct GNUNET_PQ_ResultSpec res =
606 (void *) at, sizeof (*at), (name), NULL };
612 * Absolute time in network byte order expected.
614 * @param name name of the field in the table
615 * @param[out] at where to store the result
616 * @return array entry for the result specification to use
618 struct GNUNET_PQ_ResultSpec
619 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
620 struct GNUNET_TIME_AbsoluteNBO *at)
622 struct GNUNET_PQ_ResultSpec res =
623 GNUNET_PQ_result_spec_auto_from_type(name, &at->abs_value_us__);
629 * Extract data from a Postgres database @a result at row @a row.
632 * @param result where to extract data from
633 * @param int row to extract data from
634 * @param fname name (or prefix) of the fields to extract from
635 * @param[in,out] dst_size where to store size of result, may be NULL
636 * @param[out] dst where to store the result
638 * #GNUNET_YES if all results could be extracted
639 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
642 extract_uint16 (void *cls,
649 uint16_t *udst = dst;
654 fnum = PQfnumber (result,
659 return GNUNET_SYSERR;
661 if (PQgetisnull (result,
666 return GNUNET_SYSERR;
668 GNUNET_assert (NULL != dst);
669 if (sizeof (uint16_t) != *dst_size)
672 return GNUNET_SYSERR;
674 if (sizeof (uint16_t) !=
680 return GNUNET_SYSERR;
682 res = (uint16_t *) PQgetvalue (result,
685 *udst = ntohs (*res);
693 * @param name name of the field in the table
694 * @param[out] u16 where to store the result
695 * @return array entry for the result specification to use
697 struct GNUNET_PQ_ResultSpec
698 GNUNET_PQ_result_spec_uint16 (const char *name,
701 struct GNUNET_PQ_ResultSpec res =
705 (void *) u16, sizeof (*u16), (name), NULL };
711 * Extract data from a Postgres database @a result at row @a row.
714 * @param result where to extract data from
715 * @param int row to extract data from
716 * @param fname name (or prefix) of the fields to extract from
717 * @param[in,out] dst_size where to store size of result, may be NULL
718 * @param[out] dst where to store the result
720 * #GNUNET_YES if all results could be extracted
721 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
724 extract_uint32 (void *cls,
731 uint32_t *udst = dst;
736 fnum = PQfnumber (result,
741 return GNUNET_SYSERR;
743 if (PQgetisnull (result,
748 return GNUNET_SYSERR;
750 GNUNET_assert (NULL != dst);
751 if (sizeof (uint32_t) != *dst_size)
754 return GNUNET_SYSERR;
756 if (sizeof (uint32_t) !=
762 return GNUNET_SYSERR;
764 res = (uint32_t *) PQgetvalue (result,
767 *udst = ntohl (*res);
775 * @param name name of the field in the table
776 * @param[out] u32 where to store the result
777 * @return array entry for the result specification to use
779 struct GNUNET_PQ_ResultSpec
780 GNUNET_PQ_result_spec_uint32 (const char *name,
783 struct GNUNET_PQ_ResultSpec res =
787 (void *) u32, sizeof (*u32), (name), NULL };
793 * Extract data from a Postgres database @a result at row @a row.
796 * @param result where to extract data from
797 * @param int row to extract data from
798 * @param fname name (or prefix) of the fields to extract from
799 * @param[in,out] dst_size where to store size of result, may be NULL
800 * @param[out] dst where to store the result
802 * #GNUNET_YES if all results could be extracted
803 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
806 extract_uint64 (void *cls,
813 uint64_t *udst = dst;
818 fnum = PQfnumber (result,
823 return GNUNET_SYSERR;
825 if (PQgetisnull (result,
830 return GNUNET_SYSERR;
832 GNUNET_assert (NULL != dst);
833 if (sizeof (uint64_t) != *dst_size)
836 return GNUNET_SYSERR;
838 if (sizeof (uint64_t) !=
844 return GNUNET_SYSERR;
846 res = (uint64_t *) PQgetvalue (result,
849 *udst = GNUNET_ntohll (*res);
857 * @param name name of the field in the table
858 * @param[out] u64 where to store the result
859 * @return array entry for the result specification to use
861 struct GNUNET_PQ_ResultSpec
862 GNUNET_PQ_result_spec_uint64 (const char *name,
865 struct GNUNET_PQ_ResultSpec res =
869 (void *) u64, sizeof (*u64), (name), NULL };
874 /* end of pq_result_helper.c */