2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4 GNUnet is free software; you can redistribute it and/or modify it under the
5 terms of the GNU General Public License as published by the Free Software
6 Foundation; either version 3, or (at your option) any later version.
7 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
8 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
9 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10 You should have received a copy of the GNU General Public License along with
11 GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
14 * @file my/my_result_helper.c
15 * @brief functions to extract result values
16 * @author Christophe Genevey
20 #include "gnunet_util_lib.h"
21 #include "gnunet_my_lib.h"
24 * extract data from a Mysql database @a result at row @a row
27 * @param qp data about the query
28 * @param result mysql result
30 * #GNUNET_OK if all results could be extracted
31 * #GNUNET_SYSERR if a result was invalid
34 pre_extract_varsize_blob (void *cls,
35 struct GNUNET_MY_ResultSpec *rs,
40 results[0].buffer = 0;
41 results[0].buffer_length = 0;
42 results[0].length = &rs->mysql_bind_output_length;
49 * extract data from a Mysql database @a result at row @a row
53 * @param stmt the mysql statement that is being run
54 * @param column the column that is being processed
57 * #GNUNET_OK if all results could be extracted
58 * #GNUNET_SYSERR if a result was invalid
61 post_extract_varsize_blob (void *cls,
62 struct GNUNET_MY_ResultSpec *rs,
70 size = (size_t) rs->mysql_bind_output_length;
71 if (rs->mysql_bind_output_length != size)
72 return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
73 buf = GNUNET_malloc (size);
74 results[0].buffer = buf;
75 results[0].buffer_length = size;
77 mysql_stmt_fetch_column (stmt,
85 *(void **) rs->dst = buf;
86 *rs->result_size = size;
92 * extract data from a Mysql database @a result at row @a row
98 cleanup_varsize_blob (void *cls,
99 struct GNUNET_MY_ResultSpec *rs)
103 ptr = * (void **) rs->dst;
107 *(void **) rs->dst = NULL;
108 *rs->result_size = 0;
113 * Variable-size result expected
115 * @param[out] dst where to store the result, allocated
116 * @param[out] sptr where to store the size of @a dst
117 * @return array entru for the result specification to use
119 struct GNUNET_MY_ResultSpec
120 GNUNET_MY_result_spec_variable_size (void **dst,
123 struct GNUNET_MY_ResultSpec res =
125 .pre_conv = &pre_extract_varsize_blob,
126 .post_conv = &post_extract_varsize_blob,
127 .cleaner = &cleanup_varsize_blob,
128 .dst = (void *)(dst),
129 .result_size = ptr_size,
138 * Extract data from a Mysql database @a result at row @a row
141 * @param result where to extract data from
142 * @param int row to extract data from
143 * @param fname name (or prefix) of the fields to extract from
144 * @param[in] dst_size desired size, never NULL
145 * @param[out] dst where to store the result
147 * #GNUNET_OK if all results could be extracted
148 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
151 pre_extract_fixed_blob (void *cls,
152 struct GNUNET_MY_ResultSpec *rs,
157 results[0].buffer = rs->dst;
158 results[0].buffer_length = rs->dst_size;
159 results[0].length = &rs->mysql_bind_output_length;
160 results[0].buffer_type = MYSQL_TYPE_BLOB;
167 * Check size of extracted fixed size data from a Mysql database @a
168 * result at row @a row
171 * @param result where to extract data from
172 * @param int row to extract data from
173 * @param fname name (or prefix) of the fields to extract from
174 * @param[in] dst_size desired size, never NULL
175 * @param[out] dst where to store the result
177 * #GNUNET_OK if all results could be extracted
178 * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
181 post_extract_fixed_blob (void *cls,
182 struct GNUNET_MY_ResultSpec *rs,
187 if (rs->dst_size != rs->mysql_bind_output_length)
188 return GNUNET_SYSERR;
194 * Fixed-size result expected.
196 * @param name name of the field in the table
197 * @param[out] dst where to store the result
198 * @param dst_size number of bytes in @a dst
199 * @return array entry for the result specification to use
201 struct GNUNET_MY_ResultSpec
202 GNUNET_MY_result_spec_fixed_size (void *ptr,
205 struct GNUNET_MY_ResultSpec res =
207 .pre_conv = &pre_extract_fixed_blob,
208 .post_conv = &post_extract_fixed_blob,
209 .dst = (void *)(ptr),
210 .dst_size = ptr_size,
218 * Extract data from a Mysql database @a result at row @a row
221 * @param result where to extract data from
222 * @param int row to extract data from
223 * @param fname name (or prefix) of the fields to extract from
224 * @param[in, out] dst_size where to store size of result, may be NULL
225 * @param[out] dst where to store the result
227 * #GNUNET_OK if all results could be extracted
228 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
231 pre_extract_rsa_public_key (void *cls,
232 struct GNUNET_MY_ResultSpec *rs,
238 results[0].buffer = 0;
239 results[0].buffer_length = 0;
240 results[0].length = rs->mysql_bind_output_length;
241 results[0].buffer_type = MYSQL_TYPE_LONG;
248 * Check size of extracted fixed size data from a Mysql database @a
249 * result at row @a row
252 * @param result where to extract data from
253 * @param int row to extract data from
254 * @param fname name (or prefix) of the fields to extract from
255 * @param[in, out] dst_size where to store size of result, may be NULL
256 * @param[out] dst where to store the result
258 * #GNUNET_OK if all results could be extracted
259 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
262 post_extract_rsa_public_key (void *cls,
263 struct GNUNET_MY_ResultSpec *rs,
269 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
274 results[0].buffer = res;
275 results[0].buffer_length = size;
278 mysql_stmt_fetch_column (stmt,
283 return GNUNET_SYSERR;
286 *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
290 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
291 "Results contains bogus value (fail to decode)\n");
292 return GNUNET_SYSERR;
295 if (rs->dst_size != rs->mysql_bind_output_length)
296 return GNUNET_SYSERR;
303 * Function called to clean up memory allocated
304 * by a #GNUNET_MY_ResultConverter.
307 * @param rd result data to clean up
310 clean_rsa_public_key (void *cls,
311 struct GNUNET_MY_ResultSpec *rs)
313 struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
317 GNUNET_CRYPTO_rsa_public_key_free (*pk);
319 *rs->result_size = 0;
325 * RSA public key expected
327 * @param name name of the field in the table
328 * @param[out] rsa where to store the result
329 * @return array entry for the result specification to use
331 struct GNUNET_MY_ResultSpec
332 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
334 struct GNUNET_MY_ResultSpec res = {
335 .pre_conv = &pre_extract_rsa_public_key,
336 .post_conv = &post_extract_rsa_public_key,
337 .cleaner = &clean_rsa_public_key,
347 * Extract data from a Mysql database @a result at row @a row.
350 * @param result where to extract data from
351 * @param int row to extract data from
352 * @param fname name (or prefix) of the fields to extract from
353 * @param[in,out] dst_size where to store size of result, may be NULL
354 * @param[out] dst where to store the result
356 * #GNUNET_OK if all results could be extracted
357 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
360 pre_extract_rsa_signature (void *cls,
361 struct GNUNET_MY_ResultSpec *rs,
366 results[0].buffer = 0;
367 results[0].buffer_length = 0;
368 results[0].length = &rs->mysql_bind_output_length;
369 results[0].buffer_type = MYSQL_TYPE_LONG;
374 * Extract data from a Mysql database @a result at row @a row.
377 * @param result where to extract data from
378 * @param int row to extract data from
379 * @param fname name (or prefix) of the fields to extract from
380 * @param[in,out] dst_size where to store size of result, may be NULL
381 * @param[out] dst where to store the result
383 * #GNUNET_OK if all results could be extracted
384 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
387 post_extract_rsa_signature (void *cls,
388 struct GNUNET_MY_ResultSpec *rs,
393 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
397 results[0].buffer = res;
398 results[0].buffer_length = size;
401 mysql_stmt_fetch_column (stmt,
406 return GNUNET_SYSERR;
409 *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
414 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
415 "Resuls contains bogus value (fails to decode)\n");
416 return GNUNET_SYSERR;
424 * Function called to clean up memory allocated
425 * by a #GNUNET_MY_ResultConverter.
428 * @param rd result data to clean up
431 clean_rsa_signature (void *cls,
432 struct GNUNET_MY_ResultSpec *rs)
434 struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
438 GNUNET_CRYPTO_rsa_signature_free (*sig);
446 * RSA signature expected.
448 * @param[out] sig where to store the result;
449 * @return array entry for the result specification to use
451 struct GNUNET_MY_ResultSpec
452 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
454 struct GNUNET_MY_ResultSpec res =
456 .pre_conv = &pre_extract_rsa_signature,
457 .post_conv = &post_extract_rsa_signature,
458 .cleaner = &clean_rsa_signature,
467 * Extract data from a Mysql database @a result at row @a row
470 * @param result where to extract data from
471 * @param int row to extract data from
472 * @param fname name (or prefix) of the fields to extract from
473 * @param[in, out] dst_size where to store size of result, may be NULL
474 * @param[out] dst where to store the result
476 * #GNUNET_OK if all results could be extracted
477 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
480 pre_extract_string (void * cls,
481 struct GNUNET_MY_ResultSpec *rs,
486 results[0].buffer = (char *)rs->dst;
487 results[0].buffer_length = rs->dst_size;
488 results[0].length = &rs->mysql_bind_output_length;
490 char **str = rs->dst;
496 if (results->is_null)
498 return GNUNET_SYSERR;
501 len = results->buffer_length;
502 res = results->buffer;
504 *str = GNUNET_strndup (res,
509 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
510 "Results contains bogus value (fail to decode)\n");
511 return GNUNET_SYSERR;
518 * Check size of extracted fixed size data from a Mysql database @a
521 * @param result where to extract data from
522 * @param int row to extract data from
523 * @param fname name (or prefix) of the fields to extract from
524 * @param[in, out] dst_size where to store size of result, may be NULL
525 * @param[out] dst where to store the result
527 * #GNUNET_OK if all results could be extracted
528 * #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
531 post_extract_string (void * cls,
532 struct GNUNET_MY_ResultSpec *rs,
537 if (rs->dst_size != rs->mysql_bind_output_length)
538 return GNUNET_SYSERR;
541 char **str = rs->dst;
547 if (results->is_null)
549 return GNUNET_SYSERR;
552 len = results->buffer_length;
553 res = results->buffer;
555 *str = GNUNET_strndup (res,
560 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
561 "Results contains bogus value (fail to decode)\n");
562 return GNUNET_SYSERR;
570 * 0- terminated string exprected.
572 * @param[out] dst where to store the result, allocated
573 * @return array entry for the result specification to use
575 struct GNUNET_MY_ResultSpec
576 GNUNET_MY_result_spec_string (char **dst)
578 struct GNUNET_MY_ResultSpec res = {
579 .pre_conv = &pre_extract_string,
580 .post_conv = &post_extract_string,
590 * Absolute time expected
592 * @param name name of the field in the table
593 * @param[out] at where to store the result
594 * @return array entry for the result specification to use
596 struct GNUNET_MY_ResultSpec
597 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
599 return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
604 * Absolute time in network byte order expected
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_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
612 struct GNUNET_MY_ResultSpec res =
613 GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__);
619 * Extract data from a Postgres database @a result at row @a row.
622 * @param result where to extract data from
623 * @param int row to extract data from
624 * @param fname name (or prefix) of the fields to extract from
625 * @param[in,out] dst_size where to store size of result, may be NULL
626 * @param[out] dst where to store the result
628 * #GNUNET_YES if all results could be extracted
629 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
632 pre_extract_uint16 (void *cls,
633 struct GNUNET_MY_ResultSpec *rs,
638 results[0].buffer = (char *)rs->dst;
639 results[0].buffer_length = rs->dst_size;
640 results[0].length = &rs->mysql_bind_output_length;
641 results[0].buffer_type = MYSQL_TYPE_SHORT;
648 * Check size of extracted fixed size data from a Mysql datbase.
651 * @param result where to extract data from
652 * @param int row to extract data from
653 * @param fname name (or prefix) of the fields to extract from
654 * @param[in,out] dst_size where to store size of result, may be NULL
655 * @param[out] dst where to store the result
657 * #GNUNET_YES if all results could be extracted
658 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
661 post_extract_uint16 (void *cls,
662 struct GNUNET_MY_ResultSpec *rs,
667 if (rs->dst_size != rs->mysql_bind_output_length)
668 return GNUNET_SYSERR;
676 * @param[out] u16 where to store the result
677 * @return array entry for the result specification to use
679 struct GNUNET_MY_ResultSpec
680 GNUNET_MY_result_spec_uint16 (uint16_t *u16)
682 struct GNUNET_MY_ResultSpec res = {
683 .pre_conv = &pre_extract_uint16,
684 .post_conv = &post_extract_uint16,
686 .dst_size = sizeof (*u16),
693 * Extrac data from a MYSQL database @a result at row @a row
696 * @param result where to extract data from
697 * @param int row to extract data from
698 * @param fname name (or prefix) of the fields to extract from
699 * @param[in, out] dst_size where to store size of result, may be NULL
700 * @param[out] dst where to store the result
702 * #GNUNET_OK if all results could be extracted
703 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
706 pre_extract_uint32 (void *cls,
707 struct GNUNET_MY_ResultSpec *rs,
712 results[0].buffer = (int *)rs->dst;
713 results[0].buffer_length = rs->dst_size;
714 results[0].length = &rs->mysql_bind_output_length;
715 results[0].buffer_type = MYSQL_TYPE_LONG;
722 * Extrac data from a MYSQL database @a result at row @a row
725 * @param result where to extract data from
726 * @param int row to extract data from
727 * @param fname name (or prefix) of the fields to extract from
728 * @param[in, out] dst_size where to store size of result, may be NULL
729 * @param[out] dst where to store the result
731 * #GNUNET_OK if all results could be extracted
732 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
735 post_extract_uint32 (void *cls,
736 struct GNUNET_MY_ResultSpec *rs,
741 if (rs->dst_size != rs->mysql_bind_output_length)
742 return GNUNET_SYSERR;
750 * @param[out] u32 where to store the result
751 * @return array entry for the result specification to use
753 struct GNUNET_MY_ResultSpec
754 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
756 struct GNUNET_MY_ResultSpec res = {
757 .pre_conv = &pre_extract_uint32,
758 .post_conv = &post_extract_uint32,
760 .dst_size = sizeof (*u32),
768 * Extract data from a MYSQL database @a result at row @a row
771 * @param result where to extract data from
772 * @param int row to extract data from
773 * @param fname name (or prefix) of the fields to extract from
774 * @param[in, out] dst_size where to store size of result, may be null
775 * @param[out] dst where to store the result
777 * #GNUNET_OK if all results could be extracted
778 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
781 pre_extract_uint64 (void *cls,
782 struct GNUNET_MY_ResultSpec *rs,
787 results[0].buffer = rs->dst;
788 results[0].buffer_length = rs->dst_size;
789 results[0].length = &rs->mysql_bind_output_length;
790 results[0].buffer_type = MYSQL_TYPE_LONGLONG;
798 * Check size of extracted fixe size data from a Mysql database
801 * @param result where to extract data from
802 * @param int row to extract data from
803 * @param fname name (or prefix) of the fields to extract from
804 * @param[in, out] dst_size where to store size of result, may be null
805 * @param[out] dst where to store the result
807 * #GNUNET_OK if all results could be extracted
808 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
811 post_extract_uint64 (void *cls,
812 struct GNUNET_MY_ResultSpec *rs,
817 if (rs->dst_size != rs->mysql_bind_output_length)
818 return GNUNET_SYSERR;
826 * @param[out] u64 where to store the result
827 * @return array entry for the result specification to use
829 struct GNUNET_MY_ResultSpec
830 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
832 struct GNUNET_MY_ResultSpec res = {
833 .pre_conv = &pre_extract_uint64,
834 .post_conv = &post_extract_uint64,
836 .dst_size = sizeof (*u64),
842 /* end of pq_result_helper.c */