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