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,
50 * Extract data from a Postgres database @a result at row @a row.
53 * @param result where to extract data from
54 * @param int row to extract data from
55 * @param fname name (or prefix) of the fields to extract from
56 * @param[in,out] dst_size where to store size of result, may be NULL
57 * @param[out] dst where to store the result
59 * #GNUNET_YES if all results could be extracted
60 * #GNUNET_SYSERR if a result was invalid (non-existing field)
63 extract_varsize_blob (void *cls,
76 *((void **) dst) = NULL;
78 fnum = PQfnumber (result,
85 if (PQgetisnull (result,
89 /* Let's allow this for varsize */
92 /* if a field is null, continue but
93 * remember that we now return a different result */
94 len = PQgetlength (result,
97 res = PQgetvalue (result,
100 GNUNET_assert (NULL != res);
102 idst = GNUNET_malloc (len);
103 *((void **) dst) = idst;
112 * Variable-size result expected.
114 * @param name name of the field in the table
115 * @param[out] dst where to store the result, allocated
116 * @param[out] sptr where to store the size of @a dst
117 * @return array entry for the result specification to use
119 struct GNUNET_PQ_ResultSpec
120 GNUNET_PQ_result_spec_variable_size (const char *name,
124 struct GNUNET_PQ_ResultSpec res =
125 { &extract_varsize_blob,
126 &clean_varsize_blob, NULL,
127 (void *) (dst), 0, name, sptr };
133 * Extract data from a Postgres database @a result at row @a row.
136 * @param result where to extract data from
137 * @param int row to extract data from
138 * @param fname name (or prefix) of the fields to extract from
139 * @param[in] dst_size desired size, never NULL
140 * @param[out] dst where to store the result
142 * #GNUNET_YES if all results could be extracted
143 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
146 extract_fixed_blob (void *cls,
157 fnum = PQfnumber (result,
162 return GNUNET_SYSERR;
164 if (PQgetisnull (result,
169 return GNUNET_SYSERR;
172 /* if a field is null, continue but
173 * remember that we now return a different result */
174 len = PQgetlength (result,
177 if (*dst_size != len)
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_SYSERR if a result was invalid (non-existing field or NULL)
228 extract_rsa_public_key (void *cls,
235 struct GNUNET_CRYPTO_RsaPublicKey **pk = dst;
241 fnum = PQfnumber (result,
246 return GNUNET_SYSERR;
248 if (PQgetisnull (result,
253 return GNUNET_SYSERR;
255 /* if a field is null, continue but
256 * remember that we now return a different result */
257 len = PQgetlength (result,
260 res = PQgetvalue (result,
263 *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
268 return GNUNET_SYSERR;
275 * Function called to clean up memory allocated
276 * by a #GNUNET_PQ_ResultConverter.
279 * @param rd result data to clean up
282 clean_rsa_public_key (void *cls,
285 struct GNUNET_CRYPTO_RsaPublicKey **pk = rd;
289 GNUNET_CRYPTO_rsa_public_key_free (*pk);
296 * RSA public key expected.
298 * @param name name of the field in the table
299 * @param[out] rsa where to store the result
300 * @return array entry for the result specification to use
302 struct GNUNET_PQ_ResultSpec
303 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
304 struct GNUNET_CRYPTO_RsaPublicKey **rsa)
306 struct GNUNET_PQ_ResultSpec res =
307 { &extract_rsa_public_key,
308 &clean_rsa_public_key,
310 (void *) rsa, 0, name, NULL };
316 * Extract data from a Postgres database @a result at row @a row.
319 * @param result where to extract data from
320 * @param int row to extract data from
321 * @param fname name (or prefix) of the fields to extract from
322 * @param[in,out] dst_size where to store size of result, may be NULL
323 * @param[out] dst where to store the result
325 * #GNUNET_YES if all results could be extracted
326 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
329 extract_rsa_signature (void *cls,
336 struct GNUNET_CRYPTO_RsaSignature **sig = dst;
342 fnum = PQfnumber (result,
347 return GNUNET_SYSERR;
349 if (PQgetisnull (result,
354 return GNUNET_SYSERR;
356 /* if a field is null, continue but
357 * remember that we now return a different result */
358 len = PQgetlength (result,
361 res = PQgetvalue (result,
364 *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
369 return GNUNET_SYSERR;
376 * Function called to clean up memory allocated
377 * by a #GNUNET_PQ_ResultConverter.
380 * @param rd result data to clean up
383 clean_rsa_signature (void *cls,
386 struct GNUNET_CRYPTO_RsaSignature **sig = rd;
390 GNUNET_CRYPTO_rsa_signature_free (*sig);
397 * RSA signature expected.
399 * @param name name of the field in the table
400 * @param[out] sig where to store the result;
401 * @return array entry for the result specification to use
403 struct GNUNET_PQ_ResultSpec
404 GNUNET_PQ_result_spec_rsa_signature (const char *name,
405 struct GNUNET_CRYPTO_RsaSignature **sig)
407 struct GNUNET_PQ_ResultSpec res =
408 { &extract_rsa_signature,
409 &clean_rsa_signature,
411 (void *) sig, 0, (name), NULL };
417 * Extract data from a Postgres database @a result at row @a row.
420 * @param result where to extract data from
421 * @param int row to extract data from
422 * @param fname name (or prefix) of the fields to extract from
423 * @param[in,out] dst_size where to store size of result, may be NULL
424 * @param[out] dst where to store the result
426 * #GNUNET_YES if all results could be extracted
427 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
430 extract_string (void *cls,
443 fnum = PQfnumber (result,
448 return GNUNET_SYSERR;
450 if (PQgetisnull (result,
455 return GNUNET_SYSERR;
457 /* if a field is null, continue but
458 * remember that we now return a different result */
459 len = PQgetlength (result,
462 res = PQgetvalue (result,
465 *str = GNUNET_strndup (res,
470 return GNUNET_SYSERR;
477 * Function called to clean up memory allocated
478 * by a #GNUNET_PQ_ResultConverter.
481 * @param rd result data to clean up
484 clean_string (void *cls,
498 * 0-terminated string expected.
500 * @param name name of the field in the table
501 * @param[out] dst where to store the result, allocated
502 * @return array entry for the result specification to use
504 struct GNUNET_PQ_ResultSpec
505 GNUNET_PQ_result_spec_string (const char *name,
508 struct GNUNET_PQ_ResultSpec res =
512 (void *) dst, 0, (name), NULL };
518 * Absolute time expected.
520 * @param name name of the field in the table
521 * @param[out] at where to store the result
522 * @return array entry for the result specification to use
524 struct GNUNET_PQ_ResultSpec
525 GNUNET_PQ_result_spec_absolute_time (const char *name,
526 struct GNUNET_TIME_Absolute *at)
528 return GNUNET_PQ_result_spec_uint64 (name,
534 * Absolute time in network byte order expected.
536 * @param name name of the field in the table
537 * @param[out] at where to store the result
538 * @return array entry for the result specification to use
540 struct GNUNET_PQ_ResultSpec
541 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
542 struct GNUNET_TIME_AbsoluteNBO *at)
544 struct GNUNET_PQ_ResultSpec res =
545 GNUNET_PQ_result_spec_auto_from_type(name, &at->abs_value_us__);
551 * Extract data from a Postgres database @a result at row @a row.
554 * @param result where to extract data from
555 * @param int row to extract data from
556 * @param fname name (or prefix) of the fields to extract from
557 * @param[in,out] dst_size where to store size of result, may be NULL
558 * @param[out] dst where to store the result
560 * #GNUNET_YES if all results could be extracted
561 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
564 extract_uint16 (void *cls,
571 uint16_t *udst = dst;
575 fnum = PQfnumber (result,
580 return GNUNET_SYSERR;
582 if (PQgetisnull (result,
587 return GNUNET_SYSERR;
589 GNUNET_assert (NULL != dst);
590 if (sizeof (uint16_t) != *dst_size)
593 return GNUNET_SYSERR;
595 if (sizeof (uint16_t) !=
601 return GNUNET_SYSERR;
603 res = (uint16_t *) PQgetvalue (result,
606 *udst = ntohs (*res);
614 * @param name name of the field in the table
615 * @param[out] u16 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_uint16 (const char *name,
622 struct GNUNET_PQ_ResultSpec res =
626 (void *) u16, sizeof (*u16), (name), NULL };
632 * Extract data from a Postgres database @a result at row @a row.
635 * @param result where to extract data from
636 * @param int row to extract data from
637 * @param fname name (or prefix) of the fields to extract from
638 * @param[in,out] dst_size where to store size of result, may be NULL
639 * @param[out] dst where to store the result
641 * #GNUNET_YES if all results could be extracted
642 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
645 extract_uint32 (void *cls,
652 uint32_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 (uint32_t) != *dst_size)
674 return GNUNET_SYSERR;
676 if (sizeof (uint32_t) !=
682 return GNUNET_SYSERR;
684 res = (uint32_t *) PQgetvalue (result,
687 *udst = ntohl (*res);
695 * @param name name of the field in the table
696 * @param[out] u32 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_uint32 (const char *name,
703 struct GNUNET_PQ_ResultSpec res =
707 (void *) u32, sizeof (*u32), (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_uint64 (void *cls,
733 uint64_t *udst = dst;
737 fnum = PQfnumber (result,
742 return GNUNET_SYSERR;
744 if (PQgetisnull (result,
749 return GNUNET_SYSERR;
751 GNUNET_assert (NULL != dst);
752 if (sizeof (uint64_t) != *dst_size)
755 return GNUNET_SYSERR;
757 if (sizeof (uint64_t) !=
763 return GNUNET_SYSERR;
765 res = (uint64_t *) PQgetvalue (result,
768 *udst = GNUNET_ntohll (*res);
776 * @param name name of the field in the table
777 * @param[out] u64 where to store the result
778 * @return array entry for the result specification to use
780 struct GNUNET_PQ_ResultSpec
781 GNUNET_PQ_result_spec_uint64 (const char *name,
784 struct GNUNET_PQ_ResultSpec res =
788 (void *) u64, sizeof (*u64), (name), NULL };
793 /* end of pq_result_helper.c */