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 under the
6 terms of the GNU General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
9 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License along with
14 GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
17 * @file pq/pq_result_helper.c
18 * @brief functions to extract result values
19 * @author Christian Grothoff
22 #include "gnunet_util_lib.h"
23 #include "gnunet_pq_lib.h"
27 * Function called to clean up memory allocated
28 * by a #GNUNET_PQ_ResultConverter.
31 * @param rd result data to clean up
34 clean_varsize_blob (void *cls,
48 * Extract data from a Postgres database @a result at row @a row.
51 * @param result where to extract data from
52 * @param int row to extract data from
53 * @param fname name (or prefix) of the fields to extract from
54 * @param[in,out] dst_size where to store size of result, may be NULL
55 * @param[out] dst where to store the result
57 * #GNUNET_YES if all results could be extracted
58 * #GNUNET_NO if at least one result was NULL
59 * #GNUNET_SYSERR if a result was invalid (non-existing field)
62 extract_varsize_blob (void *cls,
74 fnum = PQfnumber (result,
78 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
79 "Field `%s' does not exist in result\n",
83 if (PQgetisnull (result,
88 /* if a field is null, continue but
89 * remember that we now return a different result */
90 len = PQgetlength (result,
93 res = PQgetvalue (result,
96 GNUNET_assert (NULL != res);
98 idst = GNUNET_malloc (len);
99 *((void **) dst) = idst;
108 * Variable-size result expected.
110 * @param name name of the field in the table
111 * @param[out] dst where to store the result, allocated
112 * @param[out] sptr where to store the size of @a dst
113 * @return array entry for the result specification to use
115 struct GNUNET_PQ_ResultSpec
116 GNUNET_PQ_result_spec_variable_size (const char *name,
120 struct GNUNET_PQ_ResultSpec res =
121 { &extract_varsize_blob,
122 &clean_varsize_blob, NULL,
123 (void *) (dst), 0, name, sptr };
129 * Extract data from a Postgres database @a result at row @a row.
132 * @param result where to extract data from
133 * @param int row to extract data from
134 * @param fname name (or prefix) of the fields to extract from
135 * @param[in] dst_size desired size, never NULL
136 * @param[out] dst where to store the result
138 * #GNUNET_YES if all results could be extracted
139 * #GNUNET_NO if at least one result was NULL
140 * #GNUNET_SYSERR if a result was invalid (non-existing field)
143 extract_fixed_blob (void *cls,
154 fnum = PQfnumber (result,
158 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
159 "Field `%s' does not exist in result\n",
161 return GNUNET_SYSERR;
163 if (PQgetisnull (result,
168 /* if a field is null, continue but
169 * remember that we now return a different result */
170 len = PQgetlength (result,
173 if (*dst_size != len)
175 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
176 "Field `%s' has wrong size (got %u, expected %u)\n",
179 (unsigned int) *dst_size);
180 return GNUNET_SYSERR;
182 res = PQgetvalue (result,
185 GNUNET_assert (NULL != res);
194 * Fixed-size result expected.
196 * @param name name of the field in the table
197 * @param[out] dst where to store the result
198 * @param dst_size number of bytes in @a dst
199 * @return array entry for the result specification to use
201 struct GNUNET_PQ_ResultSpec
202 GNUNET_PQ_result_spec_fixed_size (const char *name,
206 struct GNUNET_PQ_ResultSpec res =
207 { &extract_fixed_blob,
209 (dst), dst_size, name, NULL };
215 * Extract data from a Postgres database @a result at row @a row.
218 * @param result where to extract data from
219 * @param int row to extract data from
220 * @param fname name (or prefix) of the fields to extract from
221 * @param[in,out] dst_size where to store size of result, may be NULL
222 * @param[out] dst where to store the result
224 * #GNUNET_YES if all results could be extracted
225 * #GNUNET_NO if at least one result was NULL
226 * #GNUNET_SYSERR if a result was invalid (non-existing field)
229 extract_rsa_public_key (void *cls,
236 struct GNUNET_CRYPTO_rsa_PublicKey **pk = dst;
242 fnum = PQfnumber (result,
246 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
247 "Field `%s' does not exist in result\n",
249 return GNUNET_SYSERR;
251 if (PQgetisnull (result,
256 /* if a field is null, continue but
257 * remember that we now return a different result */
258 len = PQgetlength (result,
261 res = PQgetvalue (result,
264 *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
268 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
269 "Field `%s' contains bogus value (fails to decode)\n",
271 return GNUNET_SYSERR;
278 * Function called to clean up memory allocated
279 * by a #GNUNET_PQ_ResultConverter.
282 * @param rd result data to clean up
285 clean_rsa_public_key (void *cls,
288 struct GNUNET_CRYPTO_rsa_PublicKey **pk = rd;
292 GNUNET_CRYPTO_rsa_public_key_free (*pk);
299 * RSA public key expected.
301 * @param name name of the field in the table
302 * @param[out] rsa where to store the result
303 * @return array entry for the result specification to use
305 struct GNUNET_PQ_ResultSpec
306 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
307 struct GNUNET_CRYPTO_rsa_PublicKey **rsa)
309 struct GNUNET_PQ_ResultSpec res =
310 { &extract_rsa_public_key,
311 &clean_rsa_public_key,
313 (void *) rsa, 0, name, NULL };
319 * Extract data from a Postgres database @a result at row @a row.
322 * @param result where to extract data from
323 * @param int row to extract data from
324 * @param fname name (or prefix) of the fields to extract from
325 * @param[in,out] dst_size where to store size of result, may be NULL
326 * @param[out] dst where to store the result
328 * #GNUNET_YES if all results could be extracted
329 * #GNUNET_NO if at least one result was NULL
330 * #GNUNET_SYSERR if a result was invalid (non-existing field)
333 extract_rsa_signature (void *cls,
340 struct GNUNET_CRYPTO_rsa_Signature **sig = dst;
346 fnum = PQfnumber (result,
350 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
351 "Field `%s' does not exist in result\n",
353 return GNUNET_SYSERR;
355 if (PQgetisnull (result,
360 /* if a field is null, continue but
361 * remember that we now return a different result */
362 len = PQgetlength (result,
365 res = PQgetvalue (result,
368 *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
372 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
373 "Field `%s' contains bogus value (fails to decode)\n",
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_rsa_Signature **sig = rd;
396 GNUNET_CRYPTO_rsa_signature_free (*sig);
403 * RSA signature expected.
405 * @param name name of the field in the table
406 * @param[out] sig where to store the result;
407 * @return array entry for the result specification to use
409 struct GNUNET_PQ_ResultSpec
410 GNUNET_PQ_result_spec_rsa_signature (const char *name,
411 struct GNUNET_CRYPTO_rsa_Signature **sig)
413 struct GNUNET_PQ_ResultSpec res =
414 { &extract_rsa_signature,
415 &clean_rsa_signature,
417 (void *) sig, 0, (name), NULL };
423 * Absolute time expected.
425 * @param name name of the field in the table
426 * @param[out] at where to store the result
427 * @return array entry for the result specification to use
429 struct GNUNET_PQ_ResultSpec
430 GNUNET_PQ_result_spec_absolute_time (const char *name,
431 struct GNUNET_TIME_Absolute *at)
433 return GNUNET_PQ_result_spec_uint64 (name,
439 * Absolute time in network byte order expected.
441 * @param name name of the field in the table
442 * @param[out] at where to store the result
443 * @return array entry for the result specification to use
445 struct GNUNET_PQ_ResultSpec
446 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
447 struct GNUNET_TIME_AbsoluteNBO *at)
449 struct GNUNET_PQ_ResultSpec res =
450 GNUNET_PQ_result_spec_auto_from_type(name, &at->abs_value_us__);
456 * Extract data from a Postgres database @a result at row @a row.
459 * @param result where to extract data from
460 * @param int row to extract data from
461 * @param fname name (or prefix) of the fields to extract from
462 * @param[in,out] dst_size where to store size of result, may be NULL
463 * @param[out] dst where to store the result
465 * #GNUNET_YES if all results could be extracted
466 * #GNUNET_NO if at least one result was NULL
467 * #GNUNET_SYSERR if a result was invalid (non-existing field)
470 extract_uint16 (void *cls,
477 uint16_t *udst = dst;
481 fnum = PQfnumber (result,
485 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
486 "Field `%s' does not exist in result\n",
488 return GNUNET_SYSERR;
490 if (PQgetisnull (result,
494 GNUNET_assert (NULL != dst);
495 if (sizeof (uint16_t) != *dst_size)
498 return GNUNET_SYSERR;
500 res = (uint16_t *) PQgetvalue (result,
503 *udst = ntohs (*res);
511 * @param name name of the field in the table
512 * @param[out] u16 where to store the result
513 * @return array entry for the result specification to use
515 struct GNUNET_PQ_ResultSpec
516 GNUNET_PQ_result_spec_uint16 (const char *name,
519 struct GNUNET_PQ_ResultSpec res =
523 (void *) u16, sizeof (*u16), (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_NO if at least one result was NULL
540 * #GNUNET_SYSERR if a result was invalid (non-existing field)
543 extract_uint32 (void *cls,
550 uint32_t *udst = dst;
554 fnum = PQfnumber (result,
558 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
559 "Field `%s' does not exist in result\n",
561 return GNUNET_SYSERR;
563 if (PQgetisnull (result,
567 GNUNET_assert (NULL != dst);
568 if (sizeof (uint32_t) != *dst_size)
571 return GNUNET_SYSERR;
573 res = (uint32_t *) PQgetvalue (result,
576 *udst = ntohl (*res);
584 * @param name name of the field in the table
585 * @param[out] u32 where to store the result
586 * @return array entry for the result specification to use
588 struct GNUNET_PQ_ResultSpec
589 GNUNET_PQ_result_spec_uint32 (const char *name,
592 struct GNUNET_PQ_ResultSpec res =
596 (void *) u32, sizeof (*u32), (name), NULL };
602 * Extract data from a Postgres database @a result at row @a row.
605 * @param result where to extract data from
606 * @param int row to extract data from
607 * @param fname name (or prefix) of the fields to extract from
608 * @param[in,out] dst_size where to store size of result, may be NULL
609 * @param[out] dst where to store the result
611 * #GNUNET_YES if all results could be extracted
612 * #GNUNET_NO if at least one result was NULL
613 * #GNUNET_SYSERR if a result was invalid (non-existing field)
616 extract_uint64 (void *cls,
623 uint64_t *udst = dst;
627 fnum = PQfnumber (result,
631 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
632 "Field `%s' does not exist in result\n",
634 return GNUNET_SYSERR;
636 if (PQgetisnull (result,
640 GNUNET_assert (NULL != dst);
641 if (sizeof (uint64_t) != *dst_size)
644 return GNUNET_SYSERR;
646 res = (uint64_t *) PQgetvalue (result,
649 *udst = GNUNET_ntohll (*res);
657 * @param name name of the field in the table
658 * @param[out] u64 where to store the result
659 * @return array entry for the result specification to use
661 struct GNUNET_PQ_ResultSpec
662 GNUNET_PQ_result_spec_uint64 (const char *name,
665 struct GNUNET_PQ_ResultSpec res =
669 (void *) u64, sizeof (*u64), (name), NULL };
674 /* end of pq_result_helper.c */