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 =
145 .pre_conv = &pre_extract_varsize_blob,
146 .post_conv = &post_extract_varsize_blob,
147 .cleaner = &cleanup_varsize_blob,
148 .dst = (void *)(dst),
149 .result_size = ptr_size,
158 * Extract data from a Mysql database @a result at row @a row
162 * @param stmt the mysql statement that is being run
163 * @param column the column that is being processed
164 * @param[out] results
166 * #GNUNET_OK if all results could be extracted
167 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
170 pre_extract_fixed_blob (void *cls,
171 struct GNUNET_MY_ResultSpec *rs,
176 results[0].buffer = rs->dst;
177 results[0].buffer_length = rs->dst_size;
178 results[0].length = &rs->mysql_bind_output_length;
179 results[0].buffer_type = MYSQL_TYPE_BLOB;
180 results[0].is_null = &rs->is_null;
188 * Check size of extracted fixed size data from a Mysql database @a
189 * result at row @a row
193 * @param stmt the mysql statement that is being run
194 * @param column the column that is being processed
195 * @param[out] results
197 * #GNUNET_OK if all results could be extracted
198 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
201 post_extract_fixed_blob (void *cls,
202 struct GNUNET_MY_ResultSpec *rs,
207 if (*results->is_null)
208 return GNUNET_SYSERR;
209 if (rs->dst_size != rs->mysql_bind_output_length)
210 return GNUNET_SYSERR;
216 * Fixed-size result expected.
218 * @param name name of the field in the table
219 * @param[out] dst where to store the result
220 * @param ptr_size number of bytes in @a dst
221 * @return array entry for the result specification to use
223 struct GNUNET_MY_ResultSpec
224 GNUNET_MY_result_spec_fixed_size (void *ptr,
227 struct GNUNET_MY_ResultSpec res =
229 .pre_conv = &pre_extract_fixed_blob,
230 .post_conv = &post_extract_fixed_blob,
232 .dst = (void *)(ptr),
233 .dst_size = ptr_size,
242 * Extract data from a Mysql database @a result at row @a row
246 * @param stmt the mysql statement that is being run
247 * @param column the column that is being processed
248 * @param[out] results
250 * #GNUNET_OK if all results could be extracted
251 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
254 pre_extract_rsa_public_key (void *cls,
255 struct GNUNET_MY_ResultSpec *rs,
260 results[0].buffer = NULL;
261 results[0].buffer_length = 0;
262 results[0].length = &rs->mysql_bind_output_length;
263 results[0].buffer_type = MYSQL_TYPE_BLOB;
264 results[0].is_null = &rs->is_null;
272 * Check size of extracted fixed size data from a Mysql database @a
273 * result at row @a row
277 * @param stmt the mysql statement that is being run
278 * @param column the column that is being processed
279 * @param[out] results
281 * #GNUNET_OK if all results could be extracted
282 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
285 post_extract_rsa_public_key (void *cls,
286 struct GNUNET_MY_ResultSpec *rs,
292 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
296 if (*results->is_null)
297 return GNUNET_SYSERR;
298 size = (size_t) rs->mysql_bind_output_length;
300 if (rs->mysql_bind_output_length != size)
301 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
302 buf = GNUNET_malloc (size);
304 results[0].buffer = buf;
305 results[0].buffer_length = size;
306 results[0].buffer_type = MYSQL_TYPE_BLOB;
308 mysql_stmt_fetch_column (stmt,
314 return GNUNET_SYSERR;
317 *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
322 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
323 "Results contains bogus public key value (fail to decode)\n");
324 return GNUNET_SYSERR;
332 * Function called to clean up memory allocated
333 * by a #GNUNET_MY_ResultConverter.
336 * @param rs result data to clean up
339 clean_rsa_public_key (void *cls,
340 struct GNUNET_MY_ResultSpec *rs)
342 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
346 GNUNET_CRYPTO_rsa_public_key_free (*pk);
353 * RSA public key expected
355 * @param name name of the field in the table
356 * @param[out] rsa where to store the result
357 * @return array entry for the result specification to use
359 struct GNUNET_MY_ResultSpec
360 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
362 struct GNUNET_MY_ResultSpec res = {
363 .pre_conv = &pre_extract_rsa_public_key,
364 .post_conv = &post_extract_rsa_public_key,
365 .cleaner = &clean_rsa_public_key,
376 * Extract data from a Mysql database @a result at row @a row.
380 * @param stmt the mysql statement that is being run
381 * @param column the column that is being processed
382 * @param[out] results
384 * #GNUNET_OK if all results could be extracted
385 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
388 pre_extract_rsa_signature (void *cls,
389 struct GNUNET_MY_ResultSpec *rs,
394 results[0].buffer = 0;
395 results[0].buffer_length = 0;
396 results[0].length = &rs->mysql_bind_output_length;
397 results[0].buffer_type = MYSQL_TYPE_BLOB;
398 results[0].is_null = &rs->is_null;
406 * Extract data from a Mysql database @a result at row @a row.
410 * @param stmt the mysql statement that is being run
411 * @param column the column that is being processed
412 * @param[out] results
414 * #GNUNET_OK if all results could be extracted
415 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
418 post_extract_rsa_signature (void *cls,
419 struct GNUNET_MY_ResultSpec *rs,
424 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
428 if (*results->is_null)
429 return GNUNET_SYSERR;
430 size = (size_t) rs->mysql_bind_output_length;
432 if (rs->mysql_bind_output_length != size)
433 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
434 buf = GNUNET_malloc (size);
436 results[0].buffer = buf;
437 results[0].buffer_length = size;
438 results[0].buffer_type = MYSQL_TYPE_BLOB;
440 mysql_stmt_fetch_column (stmt,
446 return GNUNET_SYSERR;
449 *sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
454 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
455 "Resuls contains bogus signature value (fails to decode)\n");
456 return GNUNET_SYSERR;
463 * Function called to clean up memory allocated
464 * by a #GNUNET_MY_ResultConverter.
467 * @param rd result data to clean up
470 clean_rsa_signature (void *cls,
471 struct GNUNET_MY_ResultSpec *rs)
473 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
477 GNUNET_CRYPTO_rsa_signature_free (*sig);
484 * RSA signature expected.
486 * @param[out] sig where to store the result;
487 * @return array entry for the result specification to use
489 struct GNUNET_MY_ResultSpec
490 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
492 struct GNUNET_MY_ResultSpec res =
494 .pre_conv = &pre_extract_rsa_signature,
495 .post_conv = &post_extract_rsa_signature,
496 .cleaner = &clean_rsa_signature,
506 * Extract data from a Mysql database @a result at row @a row
510 * @param stmt the mysql statement that is being run
511 * @param column the column that is being processed
512 * @param[out] results
514 * #GNUNET_OK if all results could be extracted
515 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
518 pre_extract_string (void * cls,
519 struct GNUNET_MY_ResultSpec *rs,
524 results[0].buffer = NULL;
525 results[0].buffer_length = 0;
526 results[0].length = &rs->mysql_bind_output_length;
527 results[0].buffer_type = MYSQL_TYPE_BLOB;
528 results[0].is_null = &rs->is_null;
536 * Check size of extracted fixed size data from a Mysql database @a
540 * @param stmt the mysql statement that is being run
541 * @param column the column that is being processed
542 * @param[out] results
544 * #GNUNET_OK if all results could be extracted
545 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
548 post_extract_string (void * cls,
549 struct GNUNET_MY_ResultSpec *rs,
554 size_t size = (size_t) rs->mysql_bind_output_length;
557 if (rs->mysql_bind_output_length != size)
558 return GNUNET_SYSERR;
559 if (*results->is_null)
561 *(void **) rs->dst = NULL;
565 buf = GNUNET_malloc (size);
566 results[0].buffer = buf;
567 results[0].buffer_length = size;
568 results[0].buffer_type = MYSQL_TYPE_BLOB;
571 mysql_stmt_fetch_column (stmt,
577 return GNUNET_SYSERR;
580 *(void **) rs->dst = buf;
586 * 0- terminated string exprected.
588 * @param[out] dst where to store the result, allocated
589 * @return array entry for the result specification to use
591 struct GNUNET_MY_ResultSpec
592 GNUNET_MY_result_spec_string (char **dst)
594 struct GNUNET_MY_ResultSpec res = {
595 .pre_conv = &pre_extract_string,
596 .post_conv = &post_extract_string,
607 * Absolute time expected
609 * @param name name of the field in the table
610 * @param[out] at where to store the result
611 * @return array entry for the result specification to use
613 struct GNUNET_MY_ResultSpec
614 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
616 return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
621 * Absolute time in network byte order expected
623 * @param[out] at where to store the result
624 * @return array entry for the result specification to use
626 struct GNUNET_MY_ResultSpec
627 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
629 struct GNUNET_MY_ResultSpec res =
630 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),
714 * Extrac data from a MYSQL database @a result at row @a row
719 * @param stmt the mysql statement that is being run
720 * @param column the column that is being processed
721 * @param[out] results
723 * #GNUNET_OK if all results could be extracted
724 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
727 pre_extract_uint32 (void *cls,
728 struct GNUNET_MY_ResultSpec *rs,
733 results[0].buffer = rs->dst;
734 results[0].buffer_length = rs->dst_size;
735 results[0].length = &rs->mysql_bind_output_length;
736 results[0].buffer_type = MYSQL_TYPE_LONG;
737 results[0].is_null = &rs->is_null;
745 * Extrac data from a MYSQL database @a result at row @a row
750 * @param stmt the mysql statement that is being run
751 * @param column the column that is being processed
752 * @param[out] results
754 * #GNUNET_OK if all results could be extracted
755 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
758 post_extract_uint32 (void *cls,
759 struct GNUNET_MY_ResultSpec *rs,
764 if (rs->dst_size != rs->mysql_bind_output_length)
765 return GNUNET_SYSERR;
766 if (*results->is_null)
767 return GNUNET_SYSERR;
775 * @param[out] u32 where to store the result
776 * @return array entry for the result specification to use
778 struct GNUNET_MY_ResultSpec
779 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
781 struct GNUNET_MY_ResultSpec res = {
782 .pre_conv = &pre_extract_uint32,
783 .post_conv = &post_extract_uint32,
786 .dst_size = sizeof (*u32),
794 * Extract data from a MYSQL database @a result at row @a row
798 * @param stmt the mysql statement that is being run
799 * @param column the column that is being processed
800 * @param[out] results
802 * #GNUNET_OK if all results could be extracted
803 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
806 pre_extract_uint64 (void *cls,
807 struct GNUNET_MY_ResultSpec *rs,
812 if (sizeof (uint64_t) != rs->dst_size)
813 return GNUNET_SYSERR;
814 results[0].buffer = rs->dst;
815 results[0].buffer_length = rs->dst_size;
816 results[0].length = &rs->mysql_bind_output_length;
817 results[0].buffer_type = MYSQL_TYPE_LONGLONG;
818 results[0].is_null = &rs->is_null;
826 * Check size of extracted fixe size data from a Mysql database
830 * @param stmt the mysql statement that is being run
831 * @param column the column that is being processed
832 * @param[out] results
834 * #GNUNET_OK if all results could be extracted
835 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
838 post_extract_uint64 (void *cls,
839 struct GNUNET_MY_ResultSpec *rs,
844 if (sizeof (uint64_t) != rs->dst_size)
845 return GNUNET_SYSERR;
846 if (*results->is_null)
847 return GNUNET_SYSERR;
855 * @param[out] u64 where to store the result
856 * @return array entry for the result specification to use
858 struct GNUNET_MY_ResultSpec
859 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
861 struct GNUNET_MY_ResultSpec res = {
862 .pre_conv = &pre_extract_uint64,
863 .post_conv = &post_extract_uint64,
866 .dst_size = sizeof (*u64),
873 /* end of my_result_helper.c */