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.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file my/my_result_helper.c
22 * @brief functions to extract result values
23 * @author Christophe Genevey
27 #include "gnunet_util_lib.h"
28 #include "gnunet_my_lib.h"
32 * extract data from a Mysql database @a result at row @a row
36 * @param stmt the mysql statement that is being run
37 * @param column the column that is being processed
38 * @param[out] result mysql result
40 * #GNUNET_OK if all results could be extracted
41 * #GNUNET_SYSERR if a result was invalid
44 pre_extract_varsize_blob (void *cls,
45 struct GNUNET_MY_ResultSpec *rs,
50 results[0].buffer = NULL;
51 results[0].buffer_length = 0;
52 results[0].length = &rs->mysql_bind_output_length;
53 results[0].is_null = &rs->is_null;
61 * extract data from a Mysql database @a result at row @a row
65 * @param stmt the mysql statement that is being run
66 * @param column the column that is being processed
69 * #GNUNET_OK if all results could be extracted
70 * #GNUNET_SYSERR if a result was invalid
73 post_extract_varsize_blob (void *cls,
74 struct GNUNET_MY_ResultSpec *rs,
82 if (*results->is_null)
84 size = (size_t) rs->mysql_bind_output_length;
86 if (rs->mysql_bind_output_length != size)
87 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
89 buf = GNUNET_malloc (size);
91 results[0].buffer = buf;
92 results[0].buffer_length = size;
93 results[0].buffer_type = MYSQL_TYPE_BLOB;
96 mysql_stmt_fetch_column (stmt,
102 return GNUNET_SYSERR;
105 *(void **) rs->dst = buf;
106 *rs->result_size = size;
113 * extract data from a Mysql database @a result at row @a row
119 cleanup_varsize_blob (void *cls,
120 struct GNUNET_MY_ResultSpec *rs)
122 void **ptr = (void **) rs->dst;
133 * Variable-size result expected
135 * @param[out] dst where to store the result, allocated
136 * @param[out] ptr_size where to store the size of @a dst
137 * @return array entru for the result specification to use
139 struct GNUNET_MY_ResultSpec
140 GNUNET_MY_result_spec_variable_size (void **dst,
143 struct GNUNET_MY_ResultSpec res = {
144 .pre_conv = &pre_extract_varsize_blob,
145 .post_conv = &post_extract_varsize_blob,
146 .cleaner = &cleanup_varsize_blob,
147 .dst = (void *) (dst),
148 .result_size = ptr_size,
157 * Extract data from a Mysql database @a result at row @a row
161 * @param stmt the mysql statement that is being run
162 * @param column the column that is being processed
163 * @param[out] results
165 * #GNUNET_OK if all results could be extracted
166 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
169 pre_extract_fixed_blob (void *cls,
170 struct GNUNET_MY_ResultSpec *rs,
175 results[0].buffer = rs->dst;
176 results[0].buffer_length = rs->dst_size;
177 results[0].length = &rs->mysql_bind_output_length;
178 results[0].buffer_type = MYSQL_TYPE_BLOB;
179 results[0].is_null = &rs->is_null;
187 * Check size of extracted fixed size data from a Mysql database @a
188 * result at row @a row
192 * @param stmt the mysql statement that is being run
193 * @param column the column that is being processed
194 * @param[out] results
196 * #GNUNET_OK if all results could be extracted
197 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
200 post_extract_fixed_blob (void *cls,
201 struct GNUNET_MY_ResultSpec *rs,
206 if (*results->is_null)
207 return GNUNET_SYSERR;
208 if (rs->dst_size != rs->mysql_bind_output_length)
209 return GNUNET_SYSERR;
215 * Fixed-size result expected.
217 * @param name name of the field in the table
218 * @param[out] dst where to store the result
219 * @param ptr_size number of bytes in @a dst
220 * @return array entry for the result specification to use
222 struct GNUNET_MY_ResultSpec
223 GNUNET_MY_result_spec_fixed_size (void *ptr,
226 struct GNUNET_MY_ResultSpec res = {
227 .pre_conv = &pre_extract_fixed_blob,
228 .post_conv = &post_extract_fixed_blob,
230 .dst = (void *) (ptr),
231 .dst_size = ptr_size,
240 * Extract data from a Mysql database @a result at row @a row
244 * @param stmt the mysql statement that is being run
245 * @param column the column that is being processed
246 * @param[out] results
248 * #GNUNET_OK if all results could be extracted
249 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
252 pre_extract_rsa_public_key (void *cls,
253 struct GNUNET_MY_ResultSpec *rs,
258 results[0].buffer = NULL;
259 results[0].buffer_length = 0;
260 results[0].length = &rs->mysql_bind_output_length;
261 results[0].buffer_type = MYSQL_TYPE_BLOB;
262 results[0].is_null = &rs->is_null;
270 * Check size of extracted fixed size data from a Mysql database @a
271 * result at row @a row
275 * @param stmt the mysql statement that is being run
276 * @param column the column that is being processed
277 * @param[out] results
279 * #GNUNET_OK if all results could be extracted
280 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
283 post_extract_rsa_public_key (void *cls,
284 struct GNUNET_MY_ResultSpec *rs,
290 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
294 if (*results->is_null)
295 return GNUNET_SYSERR;
296 size = (size_t) rs->mysql_bind_output_length;
298 if (rs->mysql_bind_output_length != size)
299 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
300 buf = GNUNET_malloc (size);
302 results[0].buffer = buf;
303 results[0].buffer_length = size;
304 results[0].buffer_type = MYSQL_TYPE_BLOB;
306 mysql_stmt_fetch_column (stmt,
312 return GNUNET_SYSERR;
315 *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
320 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
321 "Results contains bogus public key value (fail to decode)\n");
322 return GNUNET_SYSERR;
330 * Function called to clean up memory allocated
331 * by a #GNUNET_MY_ResultConverter.
334 * @param rs result data to clean up
337 clean_rsa_public_key (void *cls,
338 struct GNUNET_MY_ResultSpec *rs)
340 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
344 GNUNET_CRYPTO_rsa_public_key_free (*pk);
351 * RSA public key expected
353 * @param name name of the field in the table
354 * @param[out] rsa where to store the result
355 * @return array entry for the result specification to use
357 struct GNUNET_MY_ResultSpec
358 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
360 struct GNUNET_MY_ResultSpec res = {
361 .pre_conv = &pre_extract_rsa_public_key,
362 .post_conv = &post_extract_rsa_public_key,
363 .cleaner = &clean_rsa_public_key,
374 * Extract data from a Mysql database @a result at row @a row.
378 * @param stmt the mysql statement that is being run
379 * @param column the column that is being processed
380 * @param[out] results
382 * #GNUNET_OK if all results could be extracted
383 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
386 pre_extract_rsa_signature (void *cls,
387 struct GNUNET_MY_ResultSpec *rs,
392 results[0].buffer = 0;
393 results[0].buffer_length = 0;
394 results[0].length = &rs->mysql_bind_output_length;
395 results[0].buffer_type = MYSQL_TYPE_BLOB;
396 results[0].is_null = &rs->is_null;
404 * Extract data from a Mysql database @a result at row @a row.
408 * @param stmt the mysql statement that is being run
409 * @param column the column that is being processed
410 * @param[out] results
412 * #GNUNET_OK if all results could be extracted
413 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
416 post_extract_rsa_signature (void *cls,
417 struct GNUNET_MY_ResultSpec *rs,
422 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
426 if (*results->is_null)
427 return GNUNET_SYSERR;
428 size = (size_t) rs->mysql_bind_output_length;
430 if (rs->mysql_bind_output_length != size)
431 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
432 buf = GNUNET_malloc (size);
434 results[0].buffer = buf;
435 results[0].buffer_length = size;
436 results[0].buffer_type = MYSQL_TYPE_BLOB;
438 mysql_stmt_fetch_column (stmt,
444 return GNUNET_SYSERR;
447 *sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
452 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
453 "Resuls contains bogus signature value (fails to decode)\n");
454 return GNUNET_SYSERR;
461 * Function called to clean up memory allocated
462 * by a #GNUNET_MY_ResultConverter.
465 * @param rd result data to clean up
468 clean_rsa_signature (void *cls,
469 struct GNUNET_MY_ResultSpec *rs)
471 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
475 GNUNET_CRYPTO_rsa_signature_free (*sig);
482 * RSA signature expected.
484 * @param[out] sig where to store the result;
485 * @return array entry for the result specification to use
487 struct GNUNET_MY_ResultSpec
488 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
490 struct GNUNET_MY_ResultSpec res = {
491 .pre_conv = &pre_extract_rsa_signature,
492 .post_conv = &post_extract_rsa_signature,
493 .cleaner = &clean_rsa_signature,
504 * Extract data from a Mysql database @a result at row @a row
508 * @param stmt the mysql statement that is being run
509 * @param column the column that is being processed
510 * @param[out] results
512 * #GNUNET_OK if all results could be extracted
513 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
516 pre_extract_string (void *cls,
517 struct GNUNET_MY_ResultSpec *rs,
522 results[0].buffer = NULL;
523 results[0].buffer_length = 0;
524 results[0].length = &rs->mysql_bind_output_length;
525 results[0].buffer_type = MYSQL_TYPE_BLOB;
526 results[0].is_null = &rs->is_null;
534 * Check size of extracted fixed size data from a Mysql database @a
538 * @param stmt the mysql statement that is being run
539 * @param column the column that is being processed
540 * @param[out] results
542 * #GNUNET_OK if all results could be extracted
543 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
546 post_extract_string (void *cls,
547 struct GNUNET_MY_ResultSpec *rs,
552 size_t size = (size_t) rs->mysql_bind_output_length;
555 if (rs->mysql_bind_output_length != size)
556 return GNUNET_SYSERR;
557 if (*results->is_null)
559 *(void **) rs->dst = NULL;
563 buf = GNUNET_malloc (size);
564 results[0].buffer = buf;
565 results[0].buffer_length = size;
566 results[0].buffer_type = MYSQL_TYPE_BLOB;
569 mysql_stmt_fetch_column (stmt,
575 return GNUNET_SYSERR;
578 *(void **) rs->dst = buf;
584 * 0- terminated string exprected.
586 * @param[out] dst where to store the result, allocated
587 * @return array entry for the result specification to use
589 struct GNUNET_MY_ResultSpec
590 GNUNET_MY_result_spec_string (char **dst)
592 struct GNUNET_MY_ResultSpec res = {
593 .pre_conv = &pre_extract_string,
594 .post_conv = &post_extract_string,
606 * Absolute time expected
608 * @param name name of the field in the table
609 * @param[out] at where to store the result
610 * @return array entry for the result specification to use
612 struct GNUNET_MY_ResultSpec
613 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
615 return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
620 * Absolute time in network byte order expected
622 * @param[out] at where to store the result
623 * @return array entry for the result specification to use
625 struct GNUNET_MY_ResultSpec
626 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
628 struct GNUNET_MY_ResultSpec res =
629 GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__);
636 * Extract data from a Postgres database @a result at row @a row.
640 * @param stmt the mysql statement that is being run
641 * @param column the column that is being processed
642 * @param[out] results
644 * #GNUNET_YES if all results could be extracted
645 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
648 pre_extract_uint16 (void *cls,
649 struct GNUNET_MY_ResultSpec *rs,
654 results[0].buffer = rs->dst;
655 results[0].buffer_length = rs->dst_size;
656 results[0].length = &rs->mysql_bind_output_length;
657 results[0].buffer_type = MYSQL_TYPE_SHORT;
658 results[0].is_null = &rs->is_null;
666 * Check size of extracted fixed size data from a Mysql datbase.
670 * @param stmt the mysql statement that is being run
671 * @param column the column that is being processed
672 * @param[out] results
674 * #GNUNET_YES if all results could be extracted
675 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
678 post_extract_uint16 (void *cls,
679 struct GNUNET_MY_ResultSpec *rs,
684 if (rs->dst_size != rs->mysql_bind_output_length)
685 return GNUNET_SYSERR;
686 if (*results->is_null)
687 return GNUNET_SYSERR;
695 * @param[out] u16 where to store the result
696 * @return array entry for the result specification to use
698 struct GNUNET_MY_ResultSpec
699 GNUNET_MY_result_spec_uint16 (uint16_t *u16)
701 struct GNUNET_MY_ResultSpec res = {
702 .pre_conv = &pre_extract_uint16,
703 .post_conv = &post_extract_uint16,
706 .dst_size = sizeof(*u16),
715 * Extrac data from a MYSQL database @a result at row @a row
720 * @param stmt the mysql statement that is being run
721 * @param column the column that is being processed
722 * @param[out] results
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 = 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;
738 results[0].is_null = &rs->is_null;
746 * Extrac data from a MYSQL database @a result at row @a row
751 * @param stmt the mysql statement that is being run
752 * @param column the column that is being processed
753 * @param[out] results
755 * #GNUNET_OK if all results could be extracted
756 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
759 post_extract_uint32 (void *cls,
760 struct GNUNET_MY_ResultSpec *rs,
765 if (rs->dst_size != rs->mysql_bind_output_length)
766 return GNUNET_SYSERR;
767 if (*results->is_null)
768 return GNUNET_SYSERR;
776 * @param[out] u32 where to store the result
777 * @return array entry for the result specification to use
779 struct GNUNET_MY_ResultSpec
780 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
782 struct GNUNET_MY_ResultSpec res = {
783 .pre_conv = &pre_extract_uint32,
784 .post_conv = &post_extract_uint32,
787 .dst_size = sizeof(*u32),
796 * Extract data from a MYSQL database @a result at row @a row
800 * @param stmt the mysql statement that is being run
801 * @param column the column that is being processed
802 * @param[out] results
804 * #GNUNET_OK if all results could be extracted
805 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
808 pre_extract_uint64 (void *cls,
809 struct GNUNET_MY_ResultSpec *rs,
814 if (sizeof(uint64_t) != rs->dst_size)
815 return GNUNET_SYSERR;
816 results[0].buffer = rs->dst;
817 results[0].buffer_length = rs->dst_size;
818 results[0].length = &rs->mysql_bind_output_length;
819 results[0].buffer_type = MYSQL_TYPE_LONGLONG;
820 results[0].is_null = &rs->is_null;
828 * Check size of extracted fixe size data from a Mysql database
832 * @param stmt the mysql statement that is being run
833 * @param column the column that is being processed
834 * @param[out] results
836 * #GNUNET_OK if all results could be extracted
837 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
840 post_extract_uint64 (void *cls,
841 struct GNUNET_MY_ResultSpec *rs,
846 if (sizeof(uint64_t) != rs->dst_size)
847 return GNUNET_SYSERR;
848 if (*results->is_null)
849 return GNUNET_SYSERR;
857 * @param[out] u64 where to store the result
858 * @return array entry for the result specification to use
860 struct GNUNET_MY_ResultSpec
861 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
863 struct GNUNET_MY_ResultSpec res = {
864 .pre_conv = &pre_extract_uint64,
865 .post_conv = &post_extract_uint64,
868 .dst_size = sizeof(*u64),
876 /* end of my_result_helper.c */