-fix misc issues
[oweals/gnunet.git] / src / my / my_result_helper.c
1  /*
2   This file is part of GNUnet
3   Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4
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.
8
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.
12
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/>
15 */
16 /**
17  * @file my/my_result_helper.c
18  * @brief functions to extract result values
19  * @author Christophe Genevey
20  */
21
22 #include "platform.h"
23 #include "gnunet_util_lib.h"
24 #include "gnunet_my_lib.h"
25
26 /**
27  * extract data from a Mysql database @a result at row @a row
28  *
29  * @param cls closure
30  * @param qp data about the query
31  * @param result mysql result
32  * @return
33  *   #GNUNET_OK if all results could be extracted
34  *   #GNUNET_SYSERR if a result was invalid
35  */
36 static int
37 pre_extract_varsize_blob (void *cls,
38                           struct GNUNET_MY_ResultSpec *rs,
39                           MYSQL_STMT *stmt,
40                           unsigned int column,
41                           MYSQL_BIND *results)
42 {
43   results[0].buffer = NULL;
44   results[0].buffer_length = 0;
45   results[0].length = &rs->mysql_bind_output_length;
46  // results[0].buffer_type = MYSQL_TYPE_BLOB;
47
48   return GNUNET_OK;
49 }
50
51
52 /**
53  * extract data from a Mysql database @a result at row @a row
54  *
55  * @param cls closure
56  * @param[in,out] rs
57  * @param stmt the mysql statement that is being run
58  * @param column the column that is being processed
59  * @param[out] results
60  * @return
61  *   #GNUNET_OK if all results could be extracted
62  *   #GNUNET_SYSERR if a result was invalid
63  */
64 static int
65 post_extract_varsize_blob (void *cls,
66                            struct GNUNET_MY_ResultSpec *rs,
67                            MYSQL_STMT *stmt,
68                            unsigned int column,
69                            MYSQL_BIND *results)
70 {
71   void *buf;
72   size_t size;
73
74   size = (size_t) rs->mysql_bind_output_length;
75
76   if (rs->mysql_bind_output_length != size)
77     return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
78   buf = GNUNET_malloc (size);
79
80   results[0].buffer = buf;
81   results[0].buffer_length = size;
82   results[0].buffer_type = MYSQL_TYPE_BLOB;
83
84   fprintf(stderr, "size : %d\n", size);
85
86   if (0 !=
87       mysql_stmt_fetch_column (stmt,
88                                results,
89                                column,
90                                0))
91   {
92     GNUNET_free (buf);
93     return GNUNET_SYSERR;
94   }
95
96   printf("buf : %s\n", (char*)buf);
97
98   *(void **) rs->dst = buf;
99   *rs->result_size = size;
100
101   return GNUNET_OK;
102 }
103
104
105 /**
106  * extract data from a Mysql database @a result at row @a row
107  *
108  * @param cls closure
109  * @param[in,out] rs
110  */
111 static void
112 cleanup_varsize_blob (void *cls,
113                       struct GNUNET_MY_ResultSpec *rs)
114 {
115   void *ptr;
116
117   ptr = * (void **) rs->dst;
118   if (NULL == ptr)
119     return;
120   GNUNET_free (ptr);
121   *(void **) rs->dst = NULL;
122   *rs->result_size = 0;
123 }
124
125
126 /**
127  * Variable-size result expected
128  *
129  * @param[out] dst where to store the result, allocated
130  * @param[out] sptr where to store the size of @a dst
131  * @return array entru for the result specification to use
132  */
133 struct GNUNET_MY_ResultSpec
134 GNUNET_MY_result_spec_variable_size (void **dst,
135                                     size_t *ptr_size)
136 {
137   struct GNUNET_MY_ResultSpec res =
138   {
139     .pre_conv = &pre_extract_varsize_blob,
140     .post_conv = &post_extract_varsize_blob,
141     .cleaner = &cleanup_varsize_blob,
142     .dst =  (void *)(dst),
143     .result_size = ptr_size,
144     .num_fields = 1
145   };
146
147   return res;
148 }
149
150
151 /**
152  * Extract data from a Mysql database @a result at row @a row
153  *
154  * @param cls closure
155  * @param result where to extract data from
156  * @param int row to extract data from
157  * @param fname name (or prefix) of the fields to extract from
158  * @param[in] dst_size desired size, never NULL
159  * @param[out] dst where to store the result
160  * @return
161  *  #GNUNET_OK if all results could be extracted
162  *  #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
163  */
164 static int
165 pre_extract_fixed_blob (void *cls,
166                         struct GNUNET_MY_ResultSpec *rs,
167                         MYSQL_STMT *stmt,
168                         unsigned int column,
169                         MYSQL_BIND *results)
170 {
171   results[0].buffer = rs->dst;
172   results[0].buffer_length = rs->dst_size;
173   results[0].length = &rs->mysql_bind_output_length;
174   results[0].buffer_type = MYSQL_TYPE_BLOB;
175
176   return GNUNET_OK;
177 }
178
179
180 /**
181  * Check size of extracted fixed size data from a Mysql database @a
182  * result at row @a row
183  *
184  * @param cls closure
185  * @param result where to extract data from
186  * @param int row to extract data from
187  * @param fname name (or prefix) of the fields to extract from
188  * @param[in] dst_size desired size, never NULL
189  * @param[out] dst where to store the result
190  * @return
191  *  #GNUNET_OK if all results could be extracted
192  *  #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
193  */
194 static int
195 post_extract_fixed_blob (void *cls,
196                          struct GNUNET_MY_ResultSpec *rs,
197                          MYSQL_STMT *stmt,
198                          unsigned int column,
199                          MYSQL_BIND *results)
200 {
201   if (rs->dst_size != rs->mysql_bind_output_length)
202     return GNUNET_SYSERR;
203   return GNUNET_OK;
204 }
205
206
207 /**
208  * Fixed-size result expected.
209  *
210  * @param name name of the field in the table
211  * @param[out] dst where to store the result
212  * @param dst_size number of bytes in @a dst
213  * @return array entry for the result specification to use
214  */
215 struct GNUNET_MY_ResultSpec
216 GNUNET_MY_result_spec_fixed_size (void *ptr,
217                                   size_t ptr_size)
218 {
219   struct GNUNET_MY_ResultSpec res =
220   {
221     .pre_conv = &pre_extract_fixed_blob,
222     .post_conv = &post_extract_fixed_blob,
223     .dst = (void *)(ptr),
224     .dst_size = ptr_size,
225     .num_fields = 1
226   };
227
228   return res;
229 }
230
231
232 /**
233   * Extract data from a Mysql database @a result at row @a row
234   *
235   * @param cls closure
236   * @param result where to extract data from
237   * @param int row to extract data from
238   * @param fname name (or prefix) of the fields to extract from
239   * @param[in, out] dst_size where to store size of result, may be NULL
240   * @param[out] dst where to store the result
241   * @return
242   *   #GNUNET_OK if all results could be extracted
243   *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
244   */
245 static int
246 pre_extract_rsa_public_key (void *cls,
247                             struct GNUNET_MY_ResultSpec *rs,
248                             MYSQL_STMT *stmt,
249                             unsigned int column,
250                             MYSQL_BIND *results)
251 {
252   results[0].buffer = NULL;
253   results[0].buffer_length = 0;
254   results[0].length = &rs->mysql_bind_output_length;
255   results[0].buffer_type = MYSQL_TYPE_BLOB;
256
257   return GNUNET_OK;
258 }
259
260
261 /**
262   * Check size of extracted fixed size data from a Mysql database @a
263   * result at row @a row
264   *
265   * @param cls closure
266   * @param result where to extract data from
267   * @param int row to extract data from
268   * @param fname name (or prefix) of the fields to extract from
269   * @param[in, out] dst_size where to store size of result, may be NULL
270   * @param[out] dst where to store the result
271   * @return
272   *   #GNUNET_OK if all results could be extracted
273   *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
274   */
275 static int
276 post_extract_rsa_public_key  (void *cls,
277                               struct GNUNET_MY_ResultSpec *rs,
278                               MYSQL_STMT *stmt,
279                               unsigned int column,
280                               MYSQL_BIND *results)
281
282 {
283   struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
284   void *buf;
285   size_t size;
286
287   size = (size_t) rs->mysql_bind_output_length;
288
289   if (rs->mysql_bind_output_length != size)
290     return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
291   buf = GNUNET_malloc (size);
292
293   results[0].buffer = buf;
294   results[0].buffer_length = size;
295   results[0].buffer_type = MYSQL_TYPE_BLOB;
296   if (0 !=
297       mysql_stmt_fetch_column (stmt,
298                                results,
299                                column,
300                                0))
301   {
302     GNUNET_free (buf);
303     return GNUNET_SYSERR;
304   }
305   *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
306                                              size);
307   GNUNET_free (buf);
308   if (NULL == *pk)
309   {
310     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
311                 "Results contains bogus public key value (fail to decode)\n");
312     return GNUNET_SYSERR;
313   }
314
315   return GNUNET_OK;
316 }
317
318
319 /**
320  * Function called to clean up memory allocated
321  * by a #GNUNET_MY_ResultConverter.
322  *
323  * @param cls closure
324  * @param rd result data to clean up
325  */
326 static void
327 clean_rsa_public_key (void *cls,
328                       struct GNUNET_MY_ResultSpec *rs)
329 {
330   struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst;
331
332   if (NULL != *pk)
333   {
334     GNUNET_CRYPTO_rsa_public_key_free (*pk);
335     *pk = NULL;
336   }
337 }
338
339
340 /**
341   * RSA public key expected
342   *
343   * @param name name of the field in the table
344   * @param[out] rsa where to store the result
345   * @return array entry for the result specification to use
346   */
347 struct GNUNET_MY_ResultSpec
348 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa)
349 {
350   struct GNUNET_MY_ResultSpec res = {
351     .pre_conv = &pre_extract_rsa_public_key,
352     .post_conv = &post_extract_rsa_public_key,
353     .cleaner = &clean_rsa_public_key,
354     .dst = (void *) rsa,
355     .dst_size = 0,
356     .num_fields = 1
357   };
358
359   return res;
360 }
361
362 /**
363   * Extract data from a Mysql database @a result at row @a row.
364   *
365   * @param cls closure
366   * @param result where to extract data from
367   * @param int row to extract data from
368   * @param fname name (or prefix) of the fields to extract from
369   * @param[in,out] dst_size where to store size of result, may be NULL
370   * @param[out] dst where to store the result
371   * @return
372   *    #GNUNET_OK if all results could be extracted
373   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
374   */
375 static int
376 pre_extract_rsa_signature (void *cls,
377                       struct GNUNET_MY_ResultSpec *rs,
378                       MYSQL_STMT *stmt,
379                       unsigned int column,
380                       MYSQL_BIND *results)
381 {
382   results[0].buffer = 0;
383   results[0].buffer_length = 0;
384   results[0].length = &rs->mysql_bind_output_length;
385   results[0].buffer_type = MYSQL_TYPE_BLOB;
386
387   return GNUNET_OK;
388 }
389
390
391 /**
392   * Extract data from a Mysql database @a result at row @a row.
393   *
394   * @param cls closure
395   * @param result where to extract data from
396   * @param int row to extract data from
397   * @param fname name (or prefix) of the fields to extract from
398   * @param[in,out] dst_size where to store size of result, may be NULL
399   * @param[out] dst where to store the result
400   * @return
401   *    #GNUNET_OK if all results could be extracted
402   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
403   */
404 static int
405 post_extract_rsa_signature (void *cls,
406                       struct GNUNET_MY_ResultSpec *rs,
407                       MYSQL_STMT *stmt,
408                       unsigned int column,
409                       MYSQL_BIND *results)
410 {
411   struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
412   void *buf;
413   size_t size;
414
415   size = (size_t) rs->mysql_bind_output_length;
416
417   if (rs->mysql_bind_output_length != size)
418     return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */
419   buf = GNUNET_malloc (size);
420
421   results[0].buffer = buf;
422   results[0].buffer_length = size;
423   results[0].buffer_type = MYSQL_TYPE_BLOB;
424   if (0 !=
425       mysql_stmt_fetch_column (stmt,
426                                results,
427                                column,
428                                0))
429   {
430     GNUNET_free (buf);
431     return GNUNET_SYSERR;
432   }
433
434   *sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
435                                              size);
436   GNUNET_free (buf);
437   if (NULL == *sig)
438   {
439     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
440                 "Resuls contains bogus signature value (fails to decode)\n");
441     return GNUNET_SYSERR;
442   }
443   return GNUNET_OK;
444 }
445
446
447 /**
448  * Function called to clean up memory allocated
449  * by a #GNUNET_MY_ResultConverter.
450  *
451  * @param cls closure
452  * @param rd result data to clean up
453  */
454 static void
455 clean_rsa_signature (void *cls,
456           struct GNUNET_MY_ResultSpec *rs)
457 {
458   struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst;
459
460   if (NULL != *sig)
461   {
462     GNUNET_CRYPTO_rsa_signature_free (*sig);
463     *sig = NULL;
464   }
465 }
466
467
468 /**
469   * RSA signature expected.
470   *
471   * @param[out] sig where to store the result;
472   * @return array entry for the result specification to use
473   */
474 struct GNUNET_MY_ResultSpec
475 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig)
476 {
477   struct GNUNET_MY_ResultSpec res =
478   {
479     .pre_conv = &pre_extract_rsa_signature,
480     .post_conv = &post_extract_rsa_signature,
481     .cleaner = &clean_rsa_signature,
482     .dst = (void *)sig,
483     .dst_size = 0,
484     .num_fields = 1
485   };
486   return res;
487 }
488
489 /**
490   * Extract data from a Mysql database @a result at row @a row
491   *
492   * @param cls closure
493   * @param result where to extract data from
494   * @param int row to extract data from
495   * @param fname name (or prefix) of the fields to extract from
496   * @param[in, out] dst_size where to store size of result, may be NULL
497   * @param[out] dst where to store the result
498   * @return
499   *    #GNUNET_OK if all results could be extracted
500   *    #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
501   */
502 static int
503 pre_extract_string (void * cls,
504                 struct GNUNET_MY_ResultSpec *rs,
505                 MYSQL_STMT *stmt,
506                 unsigned int column,
507                 MYSQL_BIND *results)
508 {
509   results[0].buffer = (char *)rs->dst;
510   results[0].buffer_length = rs->dst_size;
511   results[0].length = &rs->mysql_bind_output_length;
512 /*
513   char **str = rs->dst;
514   size_t len;
515   const char *res;
516
517   *str = NULL;
518
519   if (results->is_null)
520   {
521     return GNUNET_SYSERR;
522   }
523
524   len = results->buffer_length;
525   res = results->buffer;
526
527   *str = GNUNET_strndup (res,
528                         len);
529
530   if (NULL == *str)
531   {
532     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
533                 "Results contains bogus value (fail to decode)\n");
534     return GNUNET_SYSERR;
535   }
536 */  return GNUNET_OK;
537 }
538
539
540 /**
541   * Check size of extracted fixed size data from a Mysql database @a
542   *
543   * @param cls closure
544   * @param result where to extract data from
545   * @param int row to extract data from
546   * @param fname name (or prefix) of the fields to extract from
547   * @param[in, out] dst_size where to store size of result, may be NULL
548   * @param[out] dst where to store the result
549   * @return
550   *    #GNUNET_OK if all results could be extracted
551   *    #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
552   */
553 static int
554 post_extract_string (void * cls,
555                 struct GNUNET_MY_ResultSpec *rs,
556                 MYSQL_STMT *stmt,
557                 unsigned int column,
558                 MYSQL_BIND *results)
559 {
560   if (rs->dst_size != rs->mysql_bind_output_length)
561     return GNUNET_SYSERR;
562   return GNUNET_OK;
563 /*
564   char **str = rs->dst;
565   size_t len;
566   const char *res;
567
568   *str = NULL;
569
570   if (results->is_null)
571   {
572     return GNUNET_SYSERR;
573   }
574
575   len = results->buffer_length;
576   res = results->buffer;
577
578   *str = GNUNET_strndup (res,
579                         len);
580
581   if (NULL == *str)
582   {
583     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
584                 "Results contains bogus value (fail to decode)\n");
585     return GNUNET_SYSERR;
586   }
587   return GNUNET_OK;
588 */
589 }
590
591
592 /**
593  * 0- terminated string exprected.
594  *
595  * @param[out] dst where to store the result, allocated
596  * @return array entry for the result specification to use
597  */
598 struct GNUNET_MY_ResultSpec
599 GNUNET_MY_result_spec_string (char **dst)
600 {
601   struct GNUNET_MY_ResultSpec res = {
602     .pre_conv = &pre_extract_string,
603     .post_conv = &post_extract_string,
604     .dst = (void *) dst,
605     .dst_size = 0,
606     .num_fields = 1
607   };
608   return res;
609 }
610
611
612 /**
613  * Absolute time expected
614  *
615  * @param name name of the field in the table
616  * @param[out] at where to store the result
617  * @return array entry for the result specification to use
618   */
619 struct GNUNET_MY_ResultSpec
620 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at)
621 {
622   return GNUNET_MY_result_spec_uint64 (&at->abs_value_us);
623 }
624
625
626 /**
627   * Absolute time in network byte order expected
628   *
629   * @param[out] at where to store the result
630   * @return array entry for the result specification to use
631   */
632 struct GNUNET_MY_ResultSpec
633 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at)
634 {
635   struct GNUNET_MY_ResultSpec res =
636     GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__);
637   return res;
638 }
639
640
641 /**
642  * Extract data from a Postgres database @a result at row @a row.
643  *
644  * @param cls closure
645  * @param result where to extract data from
646  * @param int row to extract data from
647  * @param fname name (or prefix) of the fields to extract from
648  * @param[in,out] dst_size where to store size of result, may be NULL
649  * @param[out] dst where to store the result
650  * @return
651  *   #GNUNET_YES if all results could be extracted
652  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
653  */
654 static int
655 pre_extract_uint16 (void *cls,
656                 struct GNUNET_MY_ResultSpec *rs,
657                 MYSQL_STMT *stmt,
658                 unsigned int column,
659                 MYSQL_BIND *results)
660 {
661   results[0].buffer = (char *)rs->dst;
662   results[0].buffer_length = rs->dst_size;
663   results[0].length = &rs->mysql_bind_output_length;
664   results[0].buffer_type = MYSQL_TYPE_SHORT;
665
666   return GNUNET_OK;
667 }
668
669
670 /**
671  * Check size of extracted fixed size data from a Mysql datbase.
672  *
673  * @param cls closure
674  * @param result where to extract data from
675  * @param int row to extract data from
676  * @param fname name (or prefix) of the fields to extract from
677  * @param[in,out] dst_size where to store size of result, may be NULL
678  * @param[out] dst where to store the result
679  * @return
680  *   #GNUNET_YES if all results could be extracted
681  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
682  */
683 static int
684 post_extract_uint16 (void *cls,
685                 struct GNUNET_MY_ResultSpec *rs,
686                 MYSQL_STMT *stmt,
687                 unsigned int column,
688                 MYSQL_BIND *results)
689 {
690   if (rs->dst_size != rs->mysql_bind_output_length)
691     return GNUNET_SYSERR;
692   return GNUNET_OK;
693 }
694
695
696 /**
697  * uint16_t expected
698  *
699  * @param[out] u16 where to store the result
700  * @return array entry for the result specification to use
701  */
702 struct GNUNET_MY_ResultSpec
703 GNUNET_MY_result_spec_uint16 (uint16_t *u16)
704 {
705   struct GNUNET_MY_ResultSpec res = {
706     .pre_conv = &pre_extract_uint16,
707     .post_conv = &post_extract_uint16,
708     .dst = (void *) u16,
709     .dst_size = sizeof (*u16),
710     .num_fields = 1
711   };
712   return res;
713 }
714
715 /**
716   * Extrac data from a  MYSQL database @a result at row @a row
717   *
718   * @param cls closure
719   * @param result where to extract data from
720   * @param int row to extract data from
721   * @param fname name (or prefix) of the fields to extract from
722   * @param[in, out] dst_size where to store size of result, may be NULL
723   * @param[out] dst where to store the result
724   * @return
725   *      #GNUNET_OK if all results could be extracted
726   *      #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
727   */
728 static int
729 pre_extract_uint32 (void *cls,
730                 struct GNUNET_MY_ResultSpec *rs,
731                 MYSQL_STMT *stmt,
732                 unsigned int column,
733                 MYSQL_BIND *results)
734 {
735   results[0].buffer = (int *)rs->dst;
736   results[0].buffer_length = rs->dst_size;
737   results[0].length = &rs->mysql_bind_output_length;
738   results[0].buffer_type = MYSQL_TYPE_LONG;
739
740   return GNUNET_OK;
741 }
742
743
744 /**
745   * Extrac data from a  MYSQL database @a result at row @a row
746   *
747   * @param cls closure
748   * @param result where to extract data from
749   * @param int row to extract data from
750   * @param fname name (or prefix) of the fields to extract from
751   * @param[in, out] dst_size where to store size of result, may be NULL
752   * @param[out] dst where to store the result
753   * @return
754   *      #GNUNET_OK if all results could be extracted
755   *      #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
756   */
757 static int
758 post_extract_uint32 (void *cls,
759                 struct GNUNET_MY_ResultSpec *rs,
760                 MYSQL_STMT * stmt,
761                 unsigned int column,
762                 MYSQL_BIND *results)
763 {
764   if (rs->dst_size != rs->mysql_bind_output_length)
765       return GNUNET_SYSERR;
766   return GNUNET_OK;
767 }
768
769
770 /**
771   * uint32_t expected
772   *
773   * @param[out] u32 where to store the result
774   * @return array entry for the result specification to use
775   */
776 struct GNUNET_MY_ResultSpec
777 GNUNET_MY_result_spec_uint32 (uint32_t *u32)
778 {
779   struct GNUNET_MY_ResultSpec res = {
780     .pre_conv = &pre_extract_uint32,
781     .post_conv = &post_extract_uint32,
782     .dst = (void *) u32,
783     .dst_size = sizeof (*u32),
784     .num_fields = 1
785   };
786   return res;
787 }
788
789
790 /**
791   * Extract data from a MYSQL database @a result at row @a row
792   *
793   * @param cls closure
794   * @param result where to extract data from
795   * @param int row to extract data from
796   * @param fname name (or prefix) of the fields to extract from
797   * @param[in, out] dst_size where to store size of result, may be null
798   * @param[out] dst where to store the result
799   * @return
800   *    #GNUNET_OK if all results could be extracted
801   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
802   */
803 static int
804 pre_extract_uint64 (void *cls,
805                 struct GNUNET_MY_ResultSpec *rs,
806                 MYSQL_STMT *stmt,
807                 unsigned int column,
808                 MYSQL_BIND *results)
809 {
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
815   return GNUNET_OK;
816 }
817
818
819
820 /**
821   * Check size of extracted fixe size data from a Mysql database
822   *
823   * @param cls closure
824   * @param result where to extract data from
825   * @param int row to extract data from
826   * @param fname name (or prefix) of the fields to extract from
827   * @param[in, out] dst_size where to store size of result, may be null
828   * @param[out] dst where to store the result
829   * @return
830   *    #GNUNET_OK if all results could be extracted
831   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
832   */
833 static int
834 post_extract_uint64 (void *cls,
835                 struct GNUNET_MY_ResultSpec *rs,
836                 MYSQL_STMT *stmt,
837                 unsigned int column,
838                 MYSQL_BIND *results)
839 {
840   if (rs->dst_size != rs->mysql_bind_output_length)
841     return GNUNET_SYSERR;
842   return GNUNET_OK;
843 }
844
845
846 /**
847   * uint64_t expected.
848   *
849   * @param[out] u64 where to store the result
850   * @return array entry for the result specification to use
851   */
852 struct GNUNET_MY_ResultSpec
853 GNUNET_MY_result_spec_uint64 (uint64_t *u64)
854 {
855   struct GNUNET_MY_ResultSpec res = {
856     .pre_conv = &pre_extract_uint64,
857     .post_conv = &post_extract_uint64,
858     .dst = (void *) u64,
859     .dst_size = sizeof (*u64),
860     .num_fields = 1
861   };
862   return res;
863 }
864
865 /* end of pq_result_helper.c */