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)
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;
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 */