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