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