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.
16 * @file my/my_result_helper.c
17 * @brief functions to extract result values
18 * @author Christophe Genevey
22 #include "gnunet_util_lib.h"
23 #include "gnunet_my_lib.h"
27 * extract data from a Mysql database @a result at row @a row
31 * @param stmt the mysql statement that is being run
32 * @param column the column that is being processed
33 * @param[out] result mysql result
35 * #GNUNET_OK if all results could be extracted
36 * #GNUNET_SYSERR if a result was invalid
39 pre_extract_varsize_blob (void *cls,
40 struct GNUNET_MY_ResultSpec *rs,
45 results[0].buffer = NULL;
46 results[0].buffer_length = 0;
47 results[0].length = &rs->mysql_bind_output_length;
48 results[0].is_null = &rs->is_null;
56 * extract data from a Mysql database @a result at row @a row
60 * @param stmt the mysql statement that is being run
61 * @param column the column that is being processed
64 * #GNUNET_OK if all results could be extracted
65 * #GNUNET_SYSERR if a result was invalid
68 post_extract_varsize_blob (void *cls,
69 struct GNUNET_MY_ResultSpec *rs,
77 if (*results->is_null)
79 size = (size_t) rs->mysql_bind_output_length;
81 if (rs->mysql_bind_output_length != size)
82 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
84 buf = GNUNET_malloc (size);
86 results[0].buffer = buf;
87 results[0].buffer_length = size;
88 results[0].buffer_type = MYSQL_TYPE_BLOB;
91 mysql_stmt_fetch_column (stmt,
100 *(void **) rs->dst = buf;
101 *rs->result_size = size;
108 * extract data from a Mysql database @a result at row @a row
114 cleanup_varsize_blob (void *cls,
115 struct GNUNET_MY_ResultSpec *rs)
117 void **ptr = (void **)rs->dst;
128 * Variable-size result expected
130 * @param[out] dst where to store the result, allocated
131 * @param[out] ptr_size where to store the size of @a dst
132 * @return array entru for the result specification to use
134 struct GNUNET_MY_ResultSpec
135 GNUNET_MY_result_spec_variable_size (void **dst,
138 struct GNUNET_MY_ResultSpec res =
140 .pre_conv = &pre_extract_varsize_blob,
141 .post_conv = &post_extract_varsize_blob,
142 .cleaner = &cleanup_varsize_blob,
143 .dst = (void *)(dst),
144 .result_size = ptr_size,
153 * Extract data from a Mysql database @a result at row @a row
157 * @param stmt the mysql statement that is being run
158 * @param column the column that is being processed
159 * @param[out] results
161 * #GNUNET_OK if all results could be extracted
162 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
165 pre_extract_fixed_blob (void *cls,
166 struct GNUNET_MY_ResultSpec *rs,
171 results[0].buffer = rs->dst;
172 results[0].buffer_length = rs->dst_size;
173 results[0].length = &rs->mysql_bind_output_length;
174 results[0].buffer_type = MYSQL_TYPE_BLOB;
175 results[0].is_null = &rs->is_null;
183 * Check size of extracted fixed size data from a Mysql database @a
184 * result at row @a row
188 * @param stmt the mysql statement that is being run
189 * @param column the column that is being processed
190 * @param[out] results
192 * #GNUNET_OK if all results could be extracted
193 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
196 post_extract_fixed_blob (void *cls,
197 struct GNUNET_MY_ResultSpec *rs,
202 if (*results->is_null)
203 return GNUNET_SYSERR;
204 if (rs->dst_size != rs->mysql_bind_output_length)
205 return GNUNET_SYSERR;
211 * Fixed-size result expected.
213 * @param name name of the field in the table
214 * @param[out] dst where to store the result
215 * @param ptr_size number of bytes in @a dst
216 * @return array entry for the result specification to use
218 struct GNUNET_MY_ResultSpec
219 GNUNET_MY_result_spec_fixed_size (void *ptr,
222 struct GNUNET_MY_ResultSpec res =
224 .pre_conv = &pre_extract_fixed_blob,
225 .post_conv = &post_extract_fixed_blob,
227 .dst = (void *)(ptr),
228 .dst_size = ptr_size,
237 * Extract data from a Mysql database @a result at row @a row
241 * @param stmt the mysql statement that is being run
242 * @param column the column that is being processed
243 * @param[out] results
245 * #GNUNET_OK if all results could be extracted
246 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
249 pre_extract_rsa_public_key (void *cls,
250 struct GNUNET_MY_ResultSpec *rs,
255 results[0].buffer = NULL;
256 results[0].buffer_length = 0;
257 results[0].length = &rs->mysql_bind_output_length;
258 results[0].buffer_type = MYSQL_TYPE_BLOB;
259 results[0].is_null = &rs->is_null;
267 * Check size of extracted fixed size data from a Mysql database @a
268 * result at row @a row
272 * @param stmt the mysql statement that is being run
273 * @param column the column that is being processed
274 * @param[out] results
276 * #GNUNET_OK if all results could be extracted
277 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
280 post_extract_rsa_public_key (void *cls,
281 struct GNUNET_MY_ResultSpec *rs,
287 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
291 if (*results->is_null)
292 return GNUNET_SYSERR;
293 size = (size_t) rs->mysql_bind_output_length;
295 if (rs->mysql_bind_output_length != size)
296 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
297 buf = GNUNET_malloc (size);
299 results[0].buffer = buf;
300 results[0].buffer_length = size;
301 results[0].buffer_type = MYSQL_TYPE_BLOB;
303 mysql_stmt_fetch_column (stmt,
309 return GNUNET_SYSERR;
312 *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
317 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
318 "Results contains bogus public key value (fail to decode)\n");
319 return GNUNET_SYSERR;
327 * Function called to clean up memory allocated
328 * by a #GNUNET_MY_ResultConverter.
331 * @param rs result data to clean up
334 clean_rsa_public_key (void *cls,
335 struct GNUNET_MY_ResultSpec *rs)
337 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
341 GNUNET_CRYPTO_rsa_public_key_free (*pk);
348 * RSA public key expected
350 * @param name name of the field in the table
351 * @param[out] rsa where to store the result
352 * @return array entry for the result specification to use
354 struct GNUNET_MY_ResultSpec
355 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
357 struct GNUNET_MY_ResultSpec res = {
358 .pre_conv = &pre_extract_rsa_public_key,
359 .post_conv = &post_extract_rsa_public_key,
360 .cleaner = &clean_rsa_public_key,
371 * Extract data from a Mysql database @a result at row @a row.
375 * @param stmt the mysql statement that is being run
376 * @param column the column that is being processed
377 * @param[out] results
379 * #GNUNET_OK if all results could be extracted
380 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
383 pre_extract_rsa_signature (void *cls,
384 struct GNUNET_MY_ResultSpec *rs,
389 results[0].buffer = 0;
390 results[0].buffer_length = 0;
391 results[0].length = &rs->mysql_bind_output_length;
392 results[0].buffer_type = MYSQL_TYPE_BLOB;
393 results[0].is_null = &rs->is_null;
401 * Extract data from a Mysql database @a result at row @a row.
405 * @param stmt the mysql statement that is being run
406 * @param column the column that is being processed
407 * @param[out] results
409 * #GNUNET_OK if all results could be extracted
410 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
413 post_extract_rsa_signature (void *cls,
414 struct GNUNET_MY_ResultSpec *rs,
419 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
423 if (*results->is_null)
424 return GNUNET_SYSERR;
425 size = (size_t) rs->mysql_bind_output_length;
427 if (rs->mysql_bind_output_length != size)
428 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
429 buf = GNUNET_malloc (size);
431 results[0].buffer = buf;
432 results[0].buffer_length = size;
433 results[0].buffer_type = MYSQL_TYPE_BLOB;
435 mysql_stmt_fetch_column (stmt,
441 return GNUNET_SYSERR;
444 *sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
450 "Resuls contains bogus signature value (fails to decode)\n");
451 return GNUNET_SYSERR;
458 * Function called to clean up memory allocated
459 * by a #GNUNET_MY_ResultConverter.
462 * @param rd result data to clean up
465 clean_rsa_signature (void *cls,
466 struct GNUNET_MY_ResultSpec *rs)
468 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
472 GNUNET_CRYPTO_rsa_signature_free (*sig);
479 * RSA signature expected.
481 * @param[out] sig where to store the result;
482 * @return array entry for the result specification to use
484 struct GNUNET_MY_ResultSpec
485 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
487 struct GNUNET_MY_ResultSpec res =
489 .pre_conv = &pre_extract_rsa_signature,
490 .post_conv = &post_extract_rsa_signature,
491 .cleaner = &clean_rsa_signature,
501 * Extract data from a Mysql database @a result at row @a row
505 * @param stmt the mysql statement that is being run
506 * @param column the column that is being processed
507 * @param[out] results
509 * #GNUNET_OK if all results could be extracted
510 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
513 pre_extract_string (void * cls,
514 struct GNUNET_MY_ResultSpec *rs,
519 results[0].buffer = NULL;
520 results[0].buffer_length = 0;
521 results[0].length = &rs->mysql_bind_output_length;
522 results[0].buffer_type = MYSQL_TYPE_BLOB;
523 results[0].is_null = &rs->is_null;
531 * Check size of extracted fixed size data from a Mysql database @a
535 * @param stmt the mysql statement that is being run
536 * @param column the column that is being processed
537 * @param[out] results
539 * #GNUNET_OK if all results could be extracted
540 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
543 post_extract_string (void * cls,
544 struct GNUNET_MY_ResultSpec *rs,
549 size_t size = (size_t) rs->mysql_bind_output_length;
552 if (rs->mysql_bind_output_length != size)
553 return GNUNET_SYSERR;
554 if (*results->is_null)
556 *(void **) rs->dst = NULL;
560 buf = GNUNET_malloc (size);
561 results[0].buffer = buf;
562 results[0].buffer_length = size;
563 results[0].buffer_type = MYSQL_TYPE_BLOB;
566 mysql_stmt_fetch_column (stmt,
572 return GNUNET_SYSERR;
575 *(void **) rs->dst = buf;
581 * 0- terminated string exprected.
583 * @param[out] dst where to store the result, allocated
584 * @return array entry for the result specification to use
586 struct GNUNET_MY_ResultSpec
587 GNUNET_MY_result_spec_string (char **dst)
589 struct GNUNET_MY_ResultSpec res = {
590 .pre_conv = &pre_extract_string,
591 .post_conv = &post_extract_string,
602 * Absolute time expected
604 * @param name name of the field in the table
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 (struct GNUNET_TIME_Absolute *at)
611 return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
616 * Absolute time in network byte order expected
618 * @param[out] at where to store the result
619 * @return array entry for the result specification to use
621 struct GNUNET_MY_ResultSpec
622 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
624 struct GNUNET_MY_ResultSpec res =
625 GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__);
631 * Extract data from a Postgres database @a result at row @a row.
635 * @param stmt the mysql statement that is being run
636 * @param column the column that is being processed
637 * @param[out] results
639 * #GNUNET_YES if all results could be extracted
640 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
643 pre_extract_uint16 (void *cls,
644 struct GNUNET_MY_ResultSpec *rs,
649 results[0].buffer = rs->dst;
650 results[0].buffer_length = rs->dst_size;
651 results[0].length = &rs->mysql_bind_output_length;
652 results[0].buffer_type = MYSQL_TYPE_SHORT;
653 results[0].is_null = &rs->is_null;
661 * Check size of extracted fixed size data from a Mysql datbase.
665 * @param stmt the mysql statement that is being run
666 * @param column the column that is being processed
667 * @param[out] results
669 * #GNUNET_YES if all results could be extracted
670 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
673 post_extract_uint16 (void *cls,
674 struct GNUNET_MY_ResultSpec *rs,
679 if (rs->dst_size != rs->mysql_bind_output_length)
680 return GNUNET_SYSERR;
681 if (*results->is_null)
682 return GNUNET_SYSERR;
690 * @param[out] u16 where to store the result
691 * @return array entry for the result specification to use
693 struct GNUNET_MY_ResultSpec
694 GNUNET_MY_result_spec_uint16 (uint16_t *u16)
696 struct GNUNET_MY_ResultSpec res = {
697 .pre_conv = &pre_extract_uint16,
698 .post_conv = &post_extract_uint16,
701 .dst_size = sizeof (*u16),
709 * Extrac data from a MYSQL database @a result at row @a row
714 * @param stmt the mysql statement that is being run
715 * @param column the column that is being processed
716 * @param[out] results
718 * #GNUNET_OK if all results could be extracted
719 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
722 pre_extract_uint32 (void *cls,
723 struct GNUNET_MY_ResultSpec *rs,
728 results[0].buffer = rs->dst;
729 results[0].buffer_length = rs->dst_size;
730 results[0].length = &rs->mysql_bind_output_length;
731 results[0].buffer_type = MYSQL_TYPE_LONG;
732 results[0].is_null = &rs->is_null;
740 * Extrac data from a MYSQL database @a result at row @a row
745 * @param stmt the mysql statement that is being run
746 * @param column the column that is being processed
747 * @param[out] results
749 * #GNUNET_OK if all results could be extracted
750 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
753 post_extract_uint32 (void *cls,
754 struct GNUNET_MY_ResultSpec *rs,
759 if (rs->dst_size != rs->mysql_bind_output_length)
760 return GNUNET_SYSERR;
761 if (*results->is_null)
762 return GNUNET_SYSERR;
770 * @param[out] u32 where to store the result
771 * @return array entry for the result specification to use
773 struct GNUNET_MY_ResultSpec
774 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
776 struct GNUNET_MY_ResultSpec res = {
777 .pre_conv = &pre_extract_uint32,
778 .post_conv = &post_extract_uint32,
781 .dst_size = sizeof (*u32),
789 * Extract data from a MYSQL database @a result at row @a row
793 * @param stmt the mysql statement that is being run
794 * @param column the column that is being processed
795 * @param[out] results
797 * #GNUNET_OK if all results could be extracted
798 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
801 pre_extract_uint64 (void *cls,
802 struct GNUNET_MY_ResultSpec *rs,
807 if (sizeof (uint64_t) != rs->dst_size)
808 return GNUNET_SYSERR;
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;
813 results[0].is_null = &rs->is_null;
821 * Check size of extracted fixe size data from a Mysql database
825 * @param stmt the mysql statement that is being run
826 * @param column the column that is being processed
827 * @param[out] results
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 (sizeof (uint64_t) != rs->dst_size)
840 return GNUNET_SYSERR;
841 if (*results->is_null)
842 return GNUNET_SYSERR;
850 * @param[out] u64 where to store the result
851 * @return array entry for the result specification to use
853 struct GNUNET_MY_ResultSpec
854 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
856 struct GNUNET_MY_ResultSpec res = {
857 .pre_conv = &pre_extract_uint64,
858 .post_conv = &post_extract_uint64,
861 .dst_size = sizeof (*u64),
868 /* end of my_result_helper.c */