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"
28 * extract data from a Mysql database @a result at row @a row
32 * @param stmt the mysql statement that is being run
33 * @param column the column that is being processed
34 * @param[out] result mysql result
36 * #GNUNET_OK if all results could be extracted
37 * #GNUNET_SYSERR if a result was invalid
40 pre_extract_varsize_blob (void *cls,
41 struct GNUNET_MY_ResultSpec *rs,
46 results[0].buffer = NULL;
47 results[0].buffer_length = 0;
48 results[0].length = &rs->mysql_bind_output_length;
49 results[0].is_null = &rs->is_null;
57 * extract data from a Mysql database @a result at row @a row
61 * @param stmt the mysql statement that is being run
62 * @param column the column that is being processed
65 * #GNUNET_OK if all results could be extracted
66 * #GNUNET_SYSERR if a result was invalid
69 post_extract_varsize_blob (void *cls,
70 struct GNUNET_MY_ResultSpec *rs,
78 if (*results->is_null)
80 size = (size_t) rs->mysql_bind_output_length;
82 if (rs->mysql_bind_output_length != size)
83 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
85 buf = GNUNET_malloc (size);
87 results[0].buffer = buf;
88 results[0].buffer_length = size;
89 results[0].buffer_type = MYSQL_TYPE_BLOB;
92 mysql_stmt_fetch_column (stmt,
101 *(void **) rs->dst = buf;
102 *rs->result_size = size;
109 * extract data from a Mysql database @a result at row @a row
115 cleanup_varsize_blob (void *cls,
116 struct GNUNET_MY_ResultSpec *rs)
118 void **ptr = (void **)rs->dst;
129 * Variable-size result expected
131 * @param[out] dst where to store the result, allocated
132 * @param[out] ptr_size where to store the size of @a dst
133 * @return array entru for the result specification to use
135 struct GNUNET_MY_ResultSpec
136 GNUNET_MY_result_spec_variable_size (void **dst,
139 struct GNUNET_MY_ResultSpec res =
141 .pre_conv = &pre_extract_varsize_blob,
142 .post_conv = &post_extract_varsize_blob,
143 .cleaner = &cleanup_varsize_blob,
144 .dst = (void *)(dst),
145 .result_size = ptr_size,
154 * Extract data from a Mysql database @a result at row @a row
158 * @param stmt the mysql statement that is being run
159 * @param column the column that is being processed
160 * @param[out] results
162 * #GNUNET_OK if all results could be extracted
163 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
166 pre_extract_fixed_blob (void *cls,
167 struct GNUNET_MY_ResultSpec *rs,
172 results[0].buffer = rs->dst;
173 results[0].buffer_length = rs->dst_size;
174 results[0].length = &rs->mysql_bind_output_length;
175 results[0].buffer_type = MYSQL_TYPE_BLOB;
176 results[0].is_null = &rs->is_null;
184 * Check size of extracted fixed size data from a Mysql database @a
185 * result at row @a row
189 * @param stmt the mysql statement that is being run
190 * @param column the column that is being processed
191 * @param[out] results
193 * #GNUNET_OK if all results could be extracted
194 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
197 post_extract_fixed_blob (void *cls,
198 struct GNUNET_MY_ResultSpec *rs,
203 if (*results->is_null)
204 return GNUNET_SYSERR;
205 if (rs->dst_size != rs->mysql_bind_output_length)
206 return GNUNET_SYSERR;
212 * Fixed-size result expected.
214 * @param name name of the field in the table
215 * @param[out] dst where to store the result
216 * @param ptr_size number of bytes in @a dst
217 * @return array entry for the result specification to use
219 struct GNUNET_MY_ResultSpec
220 GNUNET_MY_result_spec_fixed_size (void *ptr,
223 struct GNUNET_MY_ResultSpec res =
225 .pre_conv = &pre_extract_fixed_blob,
226 .post_conv = &post_extract_fixed_blob,
228 .dst = (void *)(ptr),
229 .dst_size = ptr_size,
238 * Extract data from a Mysql database @a result at row @a row
242 * @param stmt the mysql statement that is being run
243 * @param column the column that is being processed
244 * @param[out] results
246 * #GNUNET_OK if all results could be extracted
247 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
250 pre_extract_rsa_public_key (void *cls,
251 struct GNUNET_MY_ResultSpec *rs,
256 results[0].buffer = NULL;
257 results[0].buffer_length = 0;
258 results[0].length = &rs->mysql_bind_output_length;
259 results[0].buffer_type = MYSQL_TYPE_BLOB;
260 results[0].is_null = &rs->is_null;
268 * Check size of extracted fixed size data from a Mysql database @a
269 * result at row @a row
273 * @param stmt the mysql statement that is being run
274 * @param column the column that is being processed
275 * @param[out] results
277 * #GNUNET_OK if all results could be extracted
278 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
281 post_extract_rsa_public_key (void *cls,
282 struct GNUNET_MY_ResultSpec *rs,
288 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
292 if (*results->is_null)
293 return GNUNET_SYSERR;
294 size = (size_t) rs->mysql_bind_output_length;
296 if (rs->mysql_bind_output_length != size)
297 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
298 buf = GNUNET_malloc (size);
300 results[0].buffer = buf;
301 results[0].buffer_length = size;
302 results[0].buffer_type = MYSQL_TYPE_BLOB;
304 mysql_stmt_fetch_column (stmt,
310 return GNUNET_SYSERR;
313 *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
318 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
319 "Results contains bogus public key value (fail to decode)\n");
320 return GNUNET_SYSERR;
328 * Function called to clean up memory allocated
329 * by a #GNUNET_MY_ResultConverter.
332 * @param rs result data to clean up
335 clean_rsa_public_key (void *cls,
336 struct GNUNET_MY_ResultSpec *rs)
338 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
342 GNUNET_CRYPTO_rsa_public_key_free (*pk);
349 * RSA public key expected
351 * @param name name of the field in the table
352 * @param[out] rsa where to store the result
353 * @return array entry for the result specification to use
355 struct GNUNET_MY_ResultSpec
356 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
358 struct GNUNET_MY_ResultSpec res = {
359 .pre_conv = &pre_extract_rsa_public_key,
360 .post_conv = &post_extract_rsa_public_key,
361 .cleaner = &clean_rsa_public_key,
372 * Extract data from a Mysql database @a result at row @a row.
376 * @param stmt the mysql statement that is being run
377 * @param column the column that is being processed
378 * @param[out] results
380 * #GNUNET_OK if all results could be extracted
381 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
384 pre_extract_rsa_signature (void *cls,
385 struct GNUNET_MY_ResultSpec *rs,
390 results[0].buffer = 0;
391 results[0].buffer_length = 0;
392 results[0].length = &rs->mysql_bind_output_length;
393 results[0].buffer_type = MYSQL_TYPE_BLOB;
394 results[0].is_null = &rs->is_null;
402 * Extract data from a Mysql database @a result at row @a row.
406 * @param stmt the mysql statement that is being run
407 * @param column the column that is being processed
408 * @param[out] results
410 * #GNUNET_OK if all results could be extracted
411 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
414 post_extract_rsa_signature (void *cls,
415 struct GNUNET_MY_ResultSpec *rs,
420 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
424 if (*results->is_null)
425 return GNUNET_SYSERR;
426 size = (size_t) rs->mysql_bind_output_length;
428 if (rs->mysql_bind_output_length != size)
429 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
430 buf = GNUNET_malloc (size);
432 results[0].buffer = buf;
433 results[0].buffer_length = size;
434 results[0].buffer_type = MYSQL_TYPE_BLOB;
436 mysql_stmt_fetch_column (stmt,
442 return GNUNET_SYSERR;
445 *sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
450 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
451 "Resuls contains bogus signature value (fails to decode)\n");
452 return GNUNET_SYSERR;
459 * Function called to clean up memory allocated
460 * by a #GNUNET_MY_ResultConverter.
463 * @param rd result data to clean up
466 clean_rsa_signature (void *cls,
467 struct GNUNET_MY_ResultSpec *rs)
469 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
473 GNUNET_CRYPTO_rsa_signature_free (*sig);
480 * RSA signature expected.
482 * @param[out] sig where to store the result;
483 * @return array entry for the result specification to use
485 struct GNUNET_MY_ResultSpec
486 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
488 struct GNUNET_MY_ResultSpec res =
490 .pre_conv = &pre_extract_rsa_signature,
491 .post_conv = &post_extract_rsa_signature,
492 .cleaner = &clean_rsa_signature,
502 * Extract data from a Mysql database @a result at row @a row
506 * @param stmt the mysql statement that is being run
507 * @param column the column that is being processed
508 * @param[out] results
510 * #GNUNET_OK if all results could be extracted
511 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
514 pre_extract_string (void * cls,
515 struct GNUNET_MY_ResultSpec *rs,
520 results[0].buffer = NULL;
521 results[0].buffer_length = 0;
522 results[0].length = &rs->mysql_bind_output_length;
523 results[0].buffer_type = MYSQL_TYPE_BLOB;
524 results[0].is_null = &rs->is_null;
532 * Check size of extracted fixed size data from a Mysql database @a
536 * @param stmt the mysql statement that is being run
537 * @param column the column that is being processed
538 * @param[out] results
540 * #GNUNET_OK if all results could be extracted
541 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
544 post_extract_string (void * cls,
545 struct GNUNET_MY_ResultSpec *rs,
550 size_t size = (size_t) rs->mysql_bind_output_length;
553 if (rs->mysql_bind_output_length != size)
554 return GNUNET_SYSERR;
555 if (*results->is_null)
557 *(void **) rs->dst = NULL;
561 buf = GNUNET_malloc (size);
562 results[0].buffer = buf;
563 results[0].buffer_length = size;
564 results[0].buffer_type = MYSQL_TYPE_BLOB;
567 mysql_stmt_fetch_column (stmt,
573 return GNUNET_SYSERR;
576 *(void **) rs->dst = buf;
582 * 0- terminated string exprected.
584 * @param[out] dst where to store the result, allocated
585 * @return array entry for the result specification to use
587 struct GNUNET_MY_ResultSpec
588 GNUNET_MY_result_spec_string (char **dst)
590 struct GNUNET_MY_ResultSpec res = {
591 .pre_conv = &pre_extract_string,
592 .post_conv = &post_extract_string,
603 * Absolute time expected
605 * @param name name of the field in the table
606 * @param[out] at where to store the result
607 * @return array entry for the result specification to use
609 struct GNUNET_MY_ResultSpec
610 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
612 return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
617 * Absolute time in network byte order expected
619 * @param[out] at where to store the result
620 * @return array entry for the result specification to use
622 struct GNUNET_MY_ResultSpec
623 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
625 struct GNUNET_MY_ResultSpec res =
626 GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__);
632 * Extract data from a Postgres database @a result at row @a row.
636 * @param stmt the mysql statement that is being run
637 * @param column the column that is being processed
638 * @param[out] results
640 * #GNUNET_YES if all results could be extracted
641 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
644 pre_extract_uint16 (void *cls,
645 struct GNUNET_MY_ResultSpec *rs,
650 results[0].buffer = rs->dst;
651 results[0].buffer_length = rs->dst_size;
652 results[0].length = &rs->mysql_bind_output_length;
653 results[0].buffer_type = MYSQL_TYPE_SHORT;
654 results[0].is_null = &rs->is_null;
662 * Check size of extracted fixed size data from a Mysql datbase.
666 * @param stmt the mysql statement that is being run
667 * @param column the column that is being processed
668 * @param[out] results
670 * #GNUNET_YES if all results could be extracted
671 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
674 post_extract_uint16 (void *cls,
675 struct GNUNET_MY_ResultSpec *rs,
680 if (rs->dst_size != rs->mysql_bind_output_length)
681 return GNUNET_SYSERR;
682 if (*results->is_null)
683 return GNUNET_SYSERR;
691 * @param[out] u16 where to store the result
692 * @return array entry for the result specification to use
694 struct GNUNET_MY_ResultSpec
695 GNUNET_MY_result_spec_uint16 (uint16_t *u16)
697 struct GNUNET_MY_ResultSpec res = {
698 .pre_conv = &pre_extract_uint16,
699 .post_conv = &post_extract_uint16,
702 .dst_size = sizeof (*u16),
710 * Extrac data from a MYSQL database @a result at row @a row
715 * @param stmt the mysql statement that is being run
716 * @param column the column that is being processed
717 * @param[out] results
719 * #GNUNET_OK if all results could be extracted
720 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
723 pre_extract_uint32 (void *cls,
724 struct GNUNET_MY_ResultSpec *rs,
729 results[0].buffer = rs->dst;
730 results[0].buffer_length = rs->dst_size;
731 results[0].length = &rs->mysql_bind_output_length;
732 results[0].buffer_type = MYSQL_TYPE_LONG;
733 results[0].is_null = &rs->is_null;
741 * Extrac data from a MYSQL database @a result at row @a row
746 * @param stmt the mysql statement that is being run
747 * @param column the column that is being processed
748 * @param[out] results
750 * #GNUNET_OK if all results could be extracted
751 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
754 post_extract_uint32 (void *cls,
755 struct GNUNET_MY_ResultSpec *rs,
760 if (rs->dst_size != rs->mysql_bind_output_length)
761 return GNUNET_SYSERR;
762 if (*results->is_null)
763 return GNUNET_SYSERR;
771 * @param[out] u32 where to store the result
772 * @return array entry for the result specification to use
774 struct GNUNET_MY_ResultSpec
775 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
777 struct GNUNET_MY_ResultSpec res = {
778 .pre_conv = &pre_extract_uint32,
779 .post_conv = &post_extract_uint32,
782 .dst_size = sizeof (*u32),
790 * Extract data from a MYSQL database @a result at row @a row
794 * @param stmt the mysql statement that is being run
795 * @param column the column that is being processed
796 * @param[out] results
798 * #GNUNET_OK if all results could be extracted
799 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
802 pre_extract_uint64 (void *cls,
803 struct GNUNET_MY_ResultSpec *rs,
808 if (sizeof (uint64_t) != rs->dst_size)
809 return GNUNET_SYSERR;
810 results[0].buffer = rs->dst;
811 results[0].buffer_length = rs->dst_size;
812 results[0].length = &rs->mysql_bind_output_length;
813 results[0].buffer_type = MYSQL_TYPE_LONGLONG;
814 results[0].is_null = &rs->is_null;
822 * Check size of extracted fixe size data from a Mysql database
826 * @param stmt the mysql statement that is being run
827 * @param column the column that is being processed
828 * @param[out] results
830 * #GNUNET_OK if all results could be extracted
831 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
834 post_extract_uint64 (void *cls,
835 struct GNUNET_MY_ResultSpec *rs,
840 if (sizeof (uint64_t) != rs->dst_size)
841 return GNUNET_SYSERR;
842 if (*results->is_null)
843 return GNUNET_SYSERR;
851 * @param[out] u64 where to store the result
852 * @return array entry for the result specification to use
854 struct GNUNET_MY_ResultSpec
855 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
857 struct GNUNET_MY_ResultSpec res = {
858 .pre_conv = &pre_extract_uint64,
859 .post_conv = &post_extract_uint64,
862 .dst_size = sizeof (*u64),
869 /* end of my_result_helper.c */