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 my/my_result_helper.c
18 * @brief functions to extract result values
19 * @author Christophe Genevey
23 #include "gnunet_util_lib.h"
24 #include "gnunet_my_lib.h"
27 * extract data from a Mysql database @a result at row @a row
30 * @param qp data about the query
31 * @param result mysql result
33 * #GNUNET_OK if all results could be extracted
34 * #GNUNET_SYSERR if a result was invalid
37 pre_extract_varsize_blob (void *cls,
38 struct GNUNET_MY_ResultSpec *rs,
43 results[0].buffer = NULL;
44 results[0].buffer_length = 0;
45 results[0].length = &rs->mysql_bind_output_length;
52 * extract data from a Mysql database @a result at row @a row
56 * @param stmt the mysql statement that is being run
57 * @param column the column that is being processed
60 * #GNUNET_OK if all results could be extracted
61 * #GNUNET_SYSERR if a result was invalid
64 post_extract_varsize_blob (void *cls,
65 struct GNUNET_MY_ResultSpec *rs,
73 size = (size_t) rs->mysql_bind_output_length;
75 if (rs->mysql_bind_output_length != size)
76 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
77 buf = GNUNET_malloc (size);
79 results[0].buffer = buf;
80 results[0].buffer_length = size;
81 results[0].buffer_type = MYSQL_TYPE_BLOB;
83 fprintf(stderr, "size : %d\n", size);
86 mysql_stmt_fetch_column (stmt,
95 printf("buf : %s\n", (char*)buf);
97 *(void **) rs->dst = buf;
98 *rs->result_size = size;
105 * extract data from a Mysql database @a result at row @a row
111 cleanup_varsize_blob (void *cls,
112 struct GNUNET_MY_ResultSpec *rs)
116 ptr = * (void **) rs->dst;
120 *(void **) rs->dst = NULL;
121 *rs->result_size = 0;
126 * Variable-size result expected
128 * @param[out] dst where to store the result, allocated
129 * @param[out] sptr where to store the size of @a dst
130 * @return array entru for the result specification to use
132 struct GNUNET_MY_ResultSpec
133 GNUNET_MY_result_spec_variable_size (void **dst,
136 struct GNUNET_MY_ResultSpec res =
138 .pre_conv = &pre_extract_varsize_blob,
139 .post_conv = &post_extract_varsize_blob,
140 .cleaner = &cleanup_varsize_blob,
141 .dst = (void *)(dst),
142 .result_size = ptr_size,
151 * Extract data from a Mysql database @a result at row @a row
154 * @param result where to extract data from
155 * @param int row to extract data from
156 * @param fname name (or prefix) of the fields to extract from
157 * @param[in] dst_size desired size, never NULL
158 * @param[out] dst where to store the result
160 * #GNUNET_OK if all results could be extracted
161 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
164 pre_extract_fixed_blob (void *cls,
165 struct GNUNET_MY_ResultSpec *rs,
170 results[0].buffer = rs->dst;
171 results[0].buffer_length = rs->dst_size;
172 results[0].length = &rs->mysql_bind_output_length;
173 results[0].buffer_type = MYSQL_TYPE_BLOB;
180 * Check size of extracted fixed size data from a Mysql database @a
181 * result at row @a row
184 * @param result where to extract data from
185 * @param int row to extract data from
186 * @param fname name (or prefix) of the fields to extract from
187 * @param[in] dst_size desired size, never NULL
188 * @param[out] dst where to store the result
190 * #GNUNET_OK if all results could be extracted
191 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
194 post_extract_fixed_blob (void *cls,
195 struct GNUNET_MY_ResultSpec *rs,
200 if (rs->dst_size != rs->mysql_bind_output_length)
201 return GNUNET_SYSERR;
207 * Fixed-size result expected.
209 * @param name name of the field in the table
210 * @param[out] dst where to store the result
211 * @param dst_size number of bytes in @a dst
212 * @return array entry for the result specification to use
214 struct GNUNET_MY_ResultSpec
215 GNUNET_MY_result_spec_fixed_size (void *ptr,
218 struct GNUNET_MY_ResultSpec res =
220 .pre_conv = &pre_extract_fixed_blob,
221 .post_conv = &post_extract_fixed_blob,
222 .dst = (void *)(ptr),
223 .dst_size = ptr_size,
232 * Extract data from a Mysql database @a result at row @a row
235 * @param result where to extract data from
236 * @param int row to extract data from
237 * @param fname name (or prefix) of the fields to extract from
238 * @param[in, out] dst_size where to store size of result, may be NULL
239 * @param[out] dst where to store the result
241 * #GNUNET_OK if all results could be extracted
242 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
245 pre_extract_rsa_public_key (void *cls,
246 struct GNUNET_MY_ResultSpec *rs,
251 results[0].buffer = NULL;
252 results[0].buffer_length = 0;
253 results[0].length = &rs->mysql_bind_output_length;
254 results[0].buffer_type = MYSQL_TYPE_BLOB;
261 * Check size of extracted fixed size data from a Mysql database @a
262 * result at row @a row
265 * @param result where to extract data from
266 * @param int row to extract data from
267 * @param fname name (or prefix) of the fields to extract from
268 * @param[in, out] dst_size where to store size of result, may be NULL
269 * @param[out] dst where to store the result
271 * #GNUNET_OK if all results could be extracted
272 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
275 post_extract_rsa_public_key (void *cls,
276 struct GNUNET_MY_ResultSpec *rs,
282 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
286 size = (size_t) rs->mysql_bind_output_length;
288 if (rs->mysql_bind_output_length != size)
289 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
290 buf = GNUNET_malloc (size);
292 results[0].buffer = buf;
293 results[0].buffer_length = size;
294 results[0].buffer_type = MYSQL_TYPE_BLOB;
296 mysql_stmt_fetch_column (stmt,
302 return GNUNET_SYSERR;
304 *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
309 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
310 "Results contains bogus public key value (fail to decode)\n");
311 return GNUNET_SYSERR;
319 * Function called to clean up memory allocated
320 * by a #GNUNET_MY_ResultConverter.
323 * @param rd result data to clean up
326 clean_rsa_public_key (void *cls,
327 struct GNUNET_MY_ResultSpec *rs)
329 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
333 GNUNET_CRYPTO_rsa_public_key_free (*pk);
340 * RSA public key expected
342 * @param name name of the field in the table
343 * @param[out] rsa where to store the result
344 * @return array entry for the result specification to use
346 struct GNUNET_MY_ResultSpec
347 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
349 struct GNUNET_MY_ResultSpec res = {
350 .pre_conv = &pre_extract_rsa_public_key,
351 .post_conv = &post_extract_rsa_public_key,
352 .cleaner = &clean_rsa_public_key,
362 * Extract data from a Mysql database @a result at row @a row.
365 * @param result where to extract data from
366 * @param int row to extract data from
367 * @param fname name (or prefix) of the fields to extract from
368 * @param[in,out] dst_size where to store size of result, may be NULL
369 * @param[out] dst where to store the result
371 * #GNUNET_OK if all results could be extracted
372 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
375 pre_extract_rsa_signature (void *cls,
376 struct GNUNET_MY_ResultSpec *rs,
381 results[0].buffer = 0;
382 results[0].buffer_length = 0;
383 results[0].length = &rs->mysql_bind_output_length;
384 results[0].buffer_type = MYSQL_TYPE_BLOB;
391 * Extract data from a Mysql database @a result at row @a row.
394 * @param result where to extract data from
395 * @param int row to extract data from
396 * @param fname name (or prefix) of the fields to extract from
397 * @param[in,out] dst_size where to store size of result, may be NULL
398 * @param[out] dst where to store the result
400 * #GNUNET_OK if all results could be extracted
401 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
404 post_extract_rsa_signature (void *cls,
405 struct GNUNET_MY_ResultSpec *rs,
410 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
414 size = (size_t) rs->mysql_bind_output_length;
416 if (rs->mysql_bind_output_length != size)
417 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
418 buf = GNUNET_malloc (size);
420 results[0].buffer = buf;
421 results[0].buffer_length = size;
422 results[0].buffer_type = MYSQL_TYPE_BLOB;
424 mysql_stmt_fetch_column (stmt,
430 return GNUNET_SYSERR;
433 *sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
438 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
439 "Resuls contains bogus signature value (fails to decode)\n");
440 return GNUNET_SYSERR;
447 * Function called to clean up memory allocated
448 * by a #GNUNET_MY_ResultConverter.
451 * @param rd result data to clean up
454 clean_rsa_signature (void *cls,
455 struct GNUNET_MY_ResultSpec *rs)
457 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
461 GNUNET_CRYPTO_rsa_signature_free (*sig);
468 * RSA signature expected.
470 * @param[out] sig where to store the result;
471 * @return array entry for the result specification to use
473 struct GNUNET_MY_ResultSpec
474 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
476 struct GNUNET_MY_ResultSpec res =
478 .pre_conv = &pre_extract_rsa_signature,
479 .post_conv = &post_extract_rsa_signature,
480 .cleaner = &clean_rsa_signature,
489 * Extract data from a Mysql database @a result at row @a row
492 * @param result where to extract data from
493 * @param int row to extract data from
494 * @param fname name (or prefix) of the fields to extract from
495 * @param[in, out] dst_size where to store size of result, may be NULL
496 * @param[out] dst where to store the result
498 * #GNUNET_OK if all results could be extracted
499 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
502 pre_extract_string (void * cls,
503 struct GNUNET_MY_ResultSpec *rs,
508 results[0].buffer = (char *)rs->dst;
509 results[0].buffer_length = rs->dst_size;
510 results[0].length = &rs->mysql_bind_output_length;
512 char **str = rs->dst;
518 if (results->is_null)
520 return GNUNET_SYSERR;
523 len = results->buffer_length;
524 res = results->buffer;
526 *str = GNUNET_strndup (res,
531 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
532 "Results contains bogus value (fail to decode)\n");
533 return GNUNET_SYSERR;
540 * Check size of extracted fixed size data from a Mysql database @a
543 * @param result where to extract data from
544 * @param int row to extract data from
545 * @param fname name (or prefix) of the fields to extract from
546 * @param[in, out] dst_size where to store size of result, may be NULL
547 * @param[out] dst where to store the result
549 * #GNUNET_OK if all results could be extracted
550 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
553 post_extract_string (void * cls,
554 struct GNUNET_MY_ResultSpec *rs,
559 if (rs->dst_size != rs->mysql_bind_output_length)
560 return GNUNET_SYSERR;
563 char **str = rs->dst;
569 if (results->is_null)
571 return GNUNET_SYSERR;
574 len = results->buffer_length;
575 res = results->buffer;
577 *str = GNUNET_strndup (res,
582 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
583 "Results contains bogus value (fail to decode)\n");
584 return GNUNET_SYSERR;
592 * 0- terminated string exprected.
594 * @param[out] dst where to store the result, allocated
595 * @return array entry for the result specification to use
597 struct GNUNET_MY_ResultSpec
598 GNUNET_MY_result_spec_string (char **dst)
600 struct GNUNET_MY_ResultSpec res = {
601 .pre_conv = &pre_extract_string,
602 .post_conv = &post_extract_string,
612 * Absolute time 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_MY_ResultSpec
619 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
621 return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
626 * Absolute time in network byte order expected
628 * @param[out] at where to store the result
629 * @return array entry for the result specification to use
631 struct GNUNET_MY_ResultSpec
632 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
634 struct GNUNET_MY_ResultSpec res =
635 GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__);
641 * Extract data from a Postgres database @a result at row @a row.
644 * @param result where to extract data from
645 * @param int row to extract data from
646 * @param fname name (or prefix) of the fields to extract from
647 * @param[in,out] dst_size where to store size of result, may be NULL
648 * @param[out] dst where to store the result
650 * #GNUNET_YES if all results could be extracted
651 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
654 pre_extract_uint16 (void *cls,
655 struct GNUNET_MY_ResultSpec *rs,
660 results[0].buffer = (char *)rs->dst;
661 results[0].buffer_length = rs->dst_size;
662 results[0].length = &rs->mysql_bind_output_length;
663 results[0].buffer_type = MYSQL_TYPE_SHORT;
670 * Check size of extracted fixed size data from a Mysql datbase.
673 * @param result where to extract data from
674 * @param int row to extract data from
675 * @param fname name (or prefix) of the fields to extract from
676 * @param[in,out] dst_size where to store size of result, may be NULL
677 * @param[out] dst where to store the result
679 * #GNUNET_YES if all results could be extracted
680 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
683 post_extract_uint16 (void *cls,
684 struct GNUNET_MY_ResultSpec *rs,
689 if (rs->dst_size != rs->mysql_bind_output_length)
690 return GNUNET_SYSERR;
698 * @param[out] u16 where to store the result
699 * @return array entry for the result specification to use
701 struct GNUNET_MY_ResultSpec
702 GNUNET_MY_result_spec_uint16 (uint16_t *u16)
704 struct GNUNET_MY_ResultSpec res = {
705 .pre_conv = &pre_extract_uint16,
706 .post_conv = &post_extract_uint16,
708 .dst_size = sizeof (*u16),
715 * Extrac data from a MYSQL database @a result at row @a row
718 * @param result where to extract data from
719 * @param int row to extract data from
720 * @param fname name (or prefix) of the fields to extract from
721 * @param[in, out] dst_size where to store size of result, may be NULL
722 * @param[out] dst where to store the result
724 * #GNUNET_OK if all results could be extracted
725 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
728 pre_extract_uint32 (void *cls,
729 struct GNUNET_MY_ResultSpec *rs,
734 results[0].buffer = (int *)rs->dst;
735 results[0].buffer_length = rs->dst_size;
736 results[0].length = &rs->mysql_bind_output_length;
737 results[0].buffer_type = MYSQL_TYPE_LONG;
744 * Extrac data from a MYSQL database @a result at row @a row
747 * @param result where to extract data from
748 * @param int row to extract data from
749 * @param fname name (or prefix) of the fields to extract from
750 * @param[in, out] dst_size where to store size of result, may be NULL
751 * @param[out] dst where to store the result
753 * #GNUNET_OK if all results could be extracted
754 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
757 post_extract_uint32 (void *cls,
758 struct GNUNET_MY_ResultSpec *rs,
763 if (rs->dst_size != rs->mysql_bind_output_length)
764 return GNUNET_SYSERR;
772 * @param[out] u32 where to store the result
773 * @return array entry for the result specification to use
775 struct GNUNET_MY_ResultSpec
776 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
778 struct GNUNET_MY_ResultSpec res = {
779 .pre_conv = &pre_extract_uint32,
780 .post_conv = &post_extract_uint32,
782 .dst_size = sizeof (*u32),
790 * Extract data from a MYSQL database @a result at row @a row
793 * @param result where to extract data from
794 * @param int row to extract data from
795 * @param fname name (or prefix) of the fields to extract from
796 * @param[in, out] dst_size where to store size of result, may be null
797 * @param[out] dst where to store the result
799 * #GNUNET_OK if all results could be extracted
800 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
803 pre_extract_uint64 (void *cls,
804 struct GNUNET_MY_ResultSpec *rs,
809 results[0].buffer = rs->dst;
810 results[0].buffer_length = rs->dst_size;
811 results[0].length = &rs->mysql_bind_output_length;
812 results[0].buffer_type = MYSQL_TYPE_LONGLONG;
820 * Check size of extracted fixe size data from a Mysql database
823 * @param result where to extract data from
824 * @param int row to extract data from
825 * @param fname name (or prefix) of the fields to extract from
826 * @param[in, out] dst_size where to store size of result, may be null
827 * @param[out] dst where to store the result
829 * #GNUNET_OK if all results could be extracted
830 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
833 post_extract_uint64 (void *cls,
834 struct GNUNET_MY_ResultSpec *rs,
839 if (rs->dst_size != rs->mysql_bind_output_length)
840 return GNUNET_SYSERR;
848 * @param[out] u64 where to store the result
849 * @return array entry for the result specification to use
851 struct GNUNET_MY_ResultSpec
852 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
854 struct GNUNET_MY_ResultSpec res = {
855 .pre_conv = &pre_extract_uint64,
856 .post_conv = &post_extract_uint64,
858 .dst_size = sizeof (*u64),
864 /* end of pq_result_helper.c */