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