2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4 GNUnet is free software; you can redistribute it and/or modify it under the
5 terms of the GNU General Public License as published by the Free Software
6 Foundation; either version 3, or (at your option) any later version.
7 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
8 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
9 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10 You should have received a copy of the GNU General Public License along with
11 GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
14 * @file my/my_result_helper.c
15 * @brief functions to extract result values
16 * @author Christophe Genevey
20 #include "gnunet_util_lib.h"
21 #include "gnunet_my_lib.h"
24 * extract data from a Mysql database @a result at row @a row
27 * @param qp data about the query
28 * @param result mysql result
30 * #GNUNET_OK if all results could be extracted
31 * #GNUNET_SYSERR if a result was invalid
34 pre_extract_varsize_blob (void *cls,
35 struct GNUNET_MY_ResultSpec *rs,
40 results[0].buffer = NULL;
41 results[0].buffer_length = 0;
42 results[0].length = &rs->mysql_bind_output_length;
43 results[0].buffer_type = MYSQL_TYPE_BLOB;
50 * extract data from a Mysql database @a result at row @a row
54 * @param stmt the mysql statement that is being run
55 * @param column the column that is being processed
58 * #GNUNET_OK if all results could be extracted
59 * #GNUNET_SYSERR if a result was invalid
62 post_extract_varsize_blob (void *cls,
63 struct GNUNET_MY_ResultSpec *rs,
71 size = (size_t) rs->mysql_bind_output_length;
72 if (rs->mysql_bind_output_length != size)
73 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
74 buf = GNUNET_malloc (size);
75 results[0].buffer = buf;
76 results[0].buffer_length = size;
79 mysql_stmt_fetch_column (stmt,
87 *(void **) rs->dst = buf;
88 *rs->result_size = size;
94 * extract data from a Mysql database @a result at row @a row
100 cleanup_varsize_blob (void *cls,
101 struct GNUNET_MY_ResultSpec *rs)
105 ptr = * (void **) rs->dst;
109 *(void **) rs->dst = NULL;
110 *rs->result_size = 0;
115 * Variable-size result expected
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 entru for the result specification to use
121 struct GNUNET_MY_ResultSpec
122 GNUNET_MY_result_spec_variable_size (void **dst,
125 struct GNUNET_MY_ResultSpec res =
127 .pre_conv = &pre_extract_varsize_blob,
128 .post_conv = &post_extract_varsize_blob,
129 .cleaner = &cleanup_varsize_blob,
130 .dst = (void *)(dst),
131 .result_size = ptr_size,
140 * Extract data from a Mysql database @a result at row @a row
143 * @param result where to extract data from
144 * @param int row to extract data from
145 * @param fname name (or prefix) of the fields to extract from
146 * @param[in] dst_size desired size, never NULL
147 * @param[out] dst where to store the result
149 * #GNUNET_OK if all results could be extracted
150 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
153 pre_extract_fixed_blob (void *cls,
154 struct GNUNET_MY_ResultSpec *rs,
159 results[0].buffer = rs->dst;
160 results[0].buffer_length = rs->dst_size;
161 results[0].length = &rs->mysql_bind_output_length;
162 results[0].buffer_type = MYSQL_TYPE_BLOB;
169 * Check size of extracted fixed size data from a Mysql database @a
170 * result at row @a row
173 * @param result where to extract data from
174 * @param int row to extract data from
175 * @param fname name (or prefix) of the fields to extract from
176 * @param[in] dst_size desired size, never NULL
177 * @param[out] dst where to store the result
179 * #GNUNET_OK if all results could be extracted
180 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
183 post_extract_fixed_blob (void *cls,
184 struct GNUNET_MY_ResultSpec *rs,
189 if (rs->dst_size != rs->mysql_bind_output_length)
190 return GNUNET_SYSERR;
196 * Fixed-size result expected.
198 * @param name name of the field in the table
199 * @param[out] dst where to store the result
200 * @param dst_size number of bytes in @a dst
201 * @return array entry for the result specification to use
203 struct GNUNET_MY_ResultSpec
204 GNUNET_MY_result_spec_fixed_size (void *ptr,
207 struct GNUNET_MY_ResultSpec res =
209 .pre_conv = &pre_extract_fixed_blob,
210 .post_conv = &post_extract_fixed_blob,
211 .dst = (void *)(ptr),
212 .dst_size = ptr_size,
220 * Extract data from a Mysql 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_OK if all results could be extracted
230 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
233 pre_extract_rsa_public_key (void *cls,
234 struct GNUNET_MY_ResultSpec *rs,
240 results[0].buffer = NULL;
241 results[0].buffer_length = 0;
242 results[0].length = &rs->mysql_bind_output_length;
243 results[0].buffer_type = MYSQL_TYPE_BLOB;
250 * Check size of extracted fixed size data from a Mysql database @a
251 * result at row @a row
254 * @param result where to extract data from
255 * @param int row to extract data from
256 * @param fname name (or prefix) of the fields to extract from
257 * @param[in, out] dst_size where to store size of result, may be NULL
258 * @param[out] dst where to store the result
260 * #GNUNET_OK if all results could be extracted
261 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
264 post_extract_rsa_public_key (void *cls,
265 struct GNUNET_MY_ResultSpec *rs,
271 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
276 results[0].buffer = res;
277 results[0].buffer_length = size;
280 mysql_stmt_fetch_column (stmt,
285 return GNUNET_SYSERR;
288 *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
292 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
293 "Results contains bogus value (fail to decode)\n");
294 return GNUNET_SYSERR;
302 * Function called to clean up memory allocated
303 * by a #GNUNET_MY_ResultConverter.
306 * @param rd result data to clean up
309 clean_rsa_public_key (void *cls,
310 struct GNUNET_MY_ResultSpec *rs)
312 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
316 GNUNET_CRYPTO_rsa_public_key_free (*pk);
318 *rs->result_size = 0;
324 * RSA public key expected
326 * @param name name of the field in the table
327 * @param[out] rsa where to store the result
328 * @return array entry for the result specification to use
330 struct GNUNET_MY_ResultSpec
331 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
333 struct GNUNET_MY_ResultSpec res = {
334 .pre_conv = &pre_extract_rsa_public_key,
335 .post_conv = &post_extract_rsa_public_key,
336 .cleaner = &clean_rsa_public_key,
346 * Extract data from a Mysql database @a result at row @a row.
349 * @param result where to extract data from
350 * @param int row to extract data from
351 * @param fname name (or prefix) of the fields to extract from
352 * @param[in,out] dst_size where to store size of result, may be NULL
353 * @param[out] dst where to store the result
355 * #GNUNET_OK if all results could be extracted
356 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
359 pre_extract_rsa_signature (void *cls,
360 struct GNUNET_MY_ResultSpec *rs,
365 results[0].buffer = 0;
366 results[0].buffer_length = 0;
367 results[0].length = &rs->mysql_bind_output_length;
368 results[0].buffer_type = MYSQL_TYPE_BLOB;
373 * Extract data from a Mysql database @a result at row @a row.
376 * @param result where to extract data from
377 * @param int row to extract data from
378 * @param fname name (or prefix) of the fields to extract from
379 * @param[in,out] dst_size where to store size of result, may be NULL
380 * @param[out] dst where to store the result
382 * #GNUNET_OK if all results could be extracted
383 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
386 post_extract_rsa_signature (void *cls,
387 struct GNUNET_MY_ResultSpec *rs,
392 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
396 results[0].buffer = res;
397 results[0].buffer_length = size;
400 mysql_stmt_fetch_column (stmt,
405 return GNUNET_SYSERR;
408 *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
413 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
414 "Resuls contains bogus value (fails to decode)\n");
415 return GNUNET_SYSERR;
423 * Function called to clean up memory allocated
424 * by a #GNUNET_MY_ResultConverter.
427 * @param rd result data to clean up
430 clean_rsa_signature (void *cls,
431 struct GNUNET_MY_ResultSpec *rs)
433 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
437 GNUNET_CRYPTO_rsa_signature_free (*sig);
445 * RSA signature expected.
447 * @param[out] sig where to store the result;
448 * @return array entry for the result specification to use
450 struct GNUNET_MY_ResultSpec
451 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
453 struct GNUNET_MY_ResultSpec res =
455 .pre_conv = &pre_extract_rsa_signature,
456 .post_conv = &post_extract_rsa_signature,
457 .cleaner = &clean_rsa_signature,
466 * Extract data from a Mysql database @a result at row @a row
469 * @param result where to extract data from
470 * @param int row to extract data from
471 * @param fname name (or prefix) of the fields to extract from
472 * @param[in, out] dst_size where to store size of result, may be NULL
473 * @param[out] dst where to store the result
475 * #GNUNET_OK if all results could be extracted
476 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
479 pre_extract_string (void * cls,
480 struct GNUNET_MY_ResultSpec *rs,
485 results[0].buffer = (char *)rs->dst;
486 results[0].buffer_length = rs->dst_size;
487 results[0].length = &rs->mysql_bind_output_length;
489 char **str = rs->dst;
495 if (results->is_null)
497 return GNUNET_SYSERR;
500 len = results->buffer_length;
501 res = results->buffer;
503 *str = GNUNET_strndup (res,
508 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
509 "Results contains bogus value (fail to decode)\n");
510 return GNUNET_SYSERR;
517 * Check size of extracted fixed size data from a Mysql database @a
520 * @param result where to extract data from
521 * @param int row to extract data from
522 * @param fname name (or prefix) of the fields to extract from
523 * @param[in, out] dst_size where to store size of result, may be NULL
524 * @param[out] dst where to store the result
526 * #GNUNET_OK if all results could be extracted
527 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
530 post_extract_string (void * cls,
531 struct GNUNET_MY_ResultSpec *rs,
536 if (rs->dst_size != rs->mysql_bind_output_length)
537 return GNUNET_SYSERR;
540 char **str = rs->dst;
546 if (results->is_null)
548 return GNUNET_SYSERR;
551 len = results->buffer_length;
552 res = results->buffer;
554 *str = GNUNET_strndup (res,
559 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
560 "Results contains bogus value (fail to decode)\n");
561 return GNUNET_SYSERR;
569 * 0- terminated string exprected.
571 * @param[out] dst where to store the result, allocated
572 * @return array entry for the result specification to use
574 struct GNUNET_MY_ResultSpec
575 GNUNET_MY_result_spec_string (char **dst)
577 struct GNUNET_MY_ResultSpec res = {
578 .pre_conv = &pre_extract_string,
579 .post_conv = &post_extract_string,
589 * Absolute time expected
591 * @param name name of the field in the table
592 * @param[out] at where to store the result
593 * @return array entry for the result specification to use
595 struct GNUNET_MY_ResultSpec
596 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
598 return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
603 * Absolute time in network byte order expected
605 * @param[out] at where to store the result
606 * @return array entry for the result specification to use
608 struct GNUNET_MY_ResultSpec
609 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
611 struct GNUNET_MY_ResultSpec res =
612 GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__);
618 * Extract data from a Postgres database @a result at row @a row.
621 * @param result where to extract data from
622 * @param int row to extract data from
623 * @param fname name (or prefix) of the fields to extract from
624 * @param[in,out] dst_size where to store size of result, may be NULL
625 * @param[out] dst where to store the result
627 * #GNUNET_YES if all results could be extracted
628 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
631 pre_extract_uint16 (void *cls,
632 struct GNUNET_MY_ResultSpec *rs,
637 results[0].buffer = (char *)rs->dst;
638 results[0].buffer_length = rs->dst_size;
639 results[0].length = &rs->mysql_bind_output_length;
640 results[0].buffer_type = MYSQL_TYPE_SHORT;
647 * Check size of extracted fixed size data from a Mysql datbase.
650 * @param result where to extract data from
651 * @param int row to extract data from
652 * @param fname name (or prefix) of the fields to extract from
653 * @param[in,out] dst_size where to store size of result, may be NULL
654 * @param[out] dst where to store the result
656 * #GNUNET_YES if all results could be extracted
657 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
660 post_extract_uint16 (void *cls,
661 struct GNUNET_MY_ResultSpec *rs,
666 if (rs->dst_size != rs->mysql_bind_output_length)
667 return GNUNET_SYSERR;
675 * @param[out] u16 where to store the result
676 * @return array entry for the result specification to use
678 struct GNUNET_MY_ResultSpec
679 GNUNET_MY_result_spec_uint16 (uint16_t *u16)
681 struct GNUNET_MY_ResultSpec res = {
682 .pre_conv = &pre_extract_uint16,
683 .post_conv = &post_extract_uint16,
685 .dst_size = sizeof (*u16),
692 * Extrac data from a MYSQL database @a result at row @a row
695 * @param result where to extract data from
696 * @param int row to extract data from
697 * @param fname name (or prefix) of the fields to extract from
698 * @param[in, out] dst_size where to store size of result, may be NULL
699 * @param[out] dst where to store the result
701 * #GNUNET_OK if all results could be extracted
702 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
705 pre_extract_uint32 (void *cls,
706 struct GNUNET_MY_ResultSpec *rs,
711 results[0].buffer = (int *)rs->dst;
712 results[0].buffer_length = rs->dst_size;
713 results[0].length = &rs->mysql_bind_output_length;
714 results[0].buffer_type = MYSQL_TYPE_LONG;
721 * Extrac data from a MYSQL 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_OK if all results could be extracted
731 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
734 post_extract_uint32 (void *cls,
735 struct GNUNET_MY_ResultSpec *rs,
740 if (rs->dst_size != rs->mysql_bind_output_length)
741 return GNUNET_SYSERR;
749 * @param[out] u32 where to store the result
750 * @return array entry for the result specification to use
752 struct GNUNET_MY_ResultSpec
753 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
755 struct GNUNET_MY_ResultSpec res = {
756 .pre_conv = &pre_extract_uint32,
757 .post_conv = &post_extract_uint32,
759 .dst_size = sizeof (*u32),
767 * Extract data from a MYSQL database @a result at row @a row
770 * @param result where to extract data from
771 * @param int row to extract data from
772 * @param fname name (or prefix) of the fields to extract from
773 * @param[in, out] dst_size where to store size of result, may be null
774 * @param[out] dst where to store the result
776 * #GNUNET_OK if all results could be extracted
777 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
780 pre_extract_uint64 (void *cls,
781 struct GNUNET_MY_ResultSpec *rs,
786 results[0].buffer = rs->dst;
787 results[0].buffer_length = rs->dst_size;
788 results[0].length = &rs->mysql_bind_output_length;
789 results[0].buffer_type = MYSQL_TYPE_LONGLONG;
797 * Check size of extracted fixe size data from a Mysql database
800 * @param result where to extract data from
801 * @param int row to extract data from
802 * @param fname name (or prefix) of the fields to extract from
803 * @param[in, out] dst_size where to store size of result, may be null
804 * @param[out] dst where to store the result
806 * #GNUNET_OK if all results could be extracted
807 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
810 post_extract_uint64 (void *cls,
811 struct GNUNET_MY_ResultSpec *rs,
816 if (rs->dst_size != rs->mysql_bind_output_length)
817 return GNUNET_SYSERR;
825 * @param[out] u64 where to store the result
826 * @return array entry for the result specification to use
828 struct GNUNET_MY_ResultSpec
829 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
831 struct GNUNET_MY_ResultSpec res = {
832 .pre_conv = &pre_extract_uint64,
833 .post_conv = &post_extract_uint64,
835 .dst_size = sizeof (*u64),
841 /* end of pq_result_helper.c */