pq: fix errornous include
[oweals/gnunet.git] / src / pq / pq_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 pq/pq_result_helper.c
18  * @brief functions to extract result values
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_util_lib.h"
23 #include "gnunet_pq_lib.h"
24
25
26 /**
27  * Function called to clean up memory allocated
28  * by a #GNUNET_PQ_ResultConverter.
29  *
30  * @param cls closure
31  * @param rd result data to clean up
32  */
33 static void
34 clean_varsize_blob (void *cls,
35                     void *rd)
36 {
37   void **dst = rd;
38
39   if (NULL != *dst)
40   {
41     GNUNET_free (*dst);
42     *dst = NULL;
43   }
44 }
45
46
47 /**
48  * Extract data from a Postgres database @a result at row @a row.
49  *
50  * @param cls closure
51  * @param result where to extract data from
52  * @param int row to extract data from
53  * @param fname name (or prefix) of the fields to extract from
54  * @param[in,out] dst_size where to store size of result, may be NULL
55  * @param[out] dst where to store the result
56  * @return
57  *   #GNUNET_YES if all results could be extracted
58  *   #GNUNET_NO if at least one result was NULL
59  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
60  */ 
61 static int
62 extract_varsize_blob (void *cls,
63                       PGresult *result,
64                       int row,
65                       const char *fname,
66                       size_t *dst_size,
67                       void *dst)
68 {
69   size_t len;
70   const char *res;
71   void *idst;
72   int fnum;
73   
74   fnum = PQfnumber (result,
75                     fname);
76   if (fnum < 0)
77   {
78     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
79                 "Field `%s' does not exist in result\n",
80                 fname);
81     return GNUNET_SYSERR;
82   }
83   if (PQgetisnull (result,
84                    row,
85                    fnum))
86     return GNUNET_NO;
87   
88   /* if a field is null, continue but
89    * remember that we now return a different result */
90   len = PQgetlength (result,
91                      row,
92                      fnum);
93   res = PQgetvalue (result,
94                     row,
95                     fnum);
96   GNUNET_assert (NULL != res);
97   *dst_size = len;
98   idst = GNUNET_malloc (len);
99   *((void **) dst) = idst;
100   memcpy (idst,
101           res,
102           len);
103   return GNUNET_OK;
104 }
105
106
107 /**
108  * Variable-size result expected.
109  *
110  * @param name name of the field in the table
111  * @param[out] dst where to store the result, allocated
112  * @param[out] sptr where to store the size of @a dst
113  * @return array entry for the result specification to use
114  */
115 struct GNUNET_PQ_ResultSpec
116 GNUNET_PQ_result_spec_variable_size (const char *name,
117                                      void **dst,
118                                      size_t *sptr)
119 {
120   struct GNUNET_PQ_ResultSpec res =
121     { &extract_varsize_blob,
122       &clean_varsize_blob, NULL, 
123       (void *) (dst), 0, name, sptr };
124   return res;
125 }
126
127
128 /**
129  * Extract data from a Postgres database @a result at row @a row.
130  *
131  * @param cls closure
132  * @param result where to extract data from
133  * @param int row to extract data from
134  * @param fname name (or prefix) of the fields to extract from
135  * @param[in] dst_size desired size, never NULL
136  * @param[out] dst where to store the result
137  * @return
138  *   #GNUNET_YES if all results could be extracted
139  *   #GNUNET_NO if at least one result was NULL
140  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
141  */ 
142 static int
143 extract_fixed_blob (void *cls,
144                     PGresult *result,
145                     int row,
146                     const char *fname,
147                     size_t *dst_size,
148                     void *dst)
149 {
150   size_t len;
151   const char *res;
152   int fnum;
153   
154   fnum = PQfnumber (result,
155                     fname);
156   if (fnum < 0)
157   {
158     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
159                 "Field `%s' does not exist in result\n",
160                 fname);
161     return GNUNET_SYSERR;
162   }
163   if (PQgetisnull (result,
164                    row,
165                    fnum))
166     return GNUNET_NO;
167   
168   /* if a field is null, continue but
169    * remember that we now return a different result */
170   len = PQgetlength (result,
171                      row,
172                      fnum);
173   if (*dst_size != len) 
174   {
175     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
176                 "Field `%s' has wrong size (got %u, expected %u)\n",
177                 fname,
178                 (unsigned int) len,
179                 (unsigned int) *dst_size);
180     return GNUNET_SYSERR;
181   }
182   res = PQgetvalue (result,
183                     row,
184                     fnum);
185   GNUNET_assert (NULL != res);
186   memcpy (dst,
187           res,
188           len);
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_PQ_ResultSpec
202 GNUNET_PQ_result_spec_fixed_size (const char *name,
203                                   void *dst,
204                                   size_t dst_size)
205 {
206   struct GNUNET_PQ_ResultSpec res =
207     { &extract_fixed_blob,
208       NULL, NULL, 
209       (dst), dst_size, name, NULL };
210   return res;
211 }
212
213
214 /**
215  * Extract data from a Postgres database @a result at row @a row.
216  *
217  * @param cls closure
218  * @param result where to extract data from
219  * @param int row to extract data from
220  * @param fname name (or prefix) of the fields to extract from
221  * @param[in,out] dst_size where to store size of result, may be NULL
222  * @param[out] dst where to store the result
223  * @return
224  *   #GNUNET_YES if all results could be extracted
225  *   #GNUNET_NO if at least one result was NULL
226  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
227  */ 
228 static int
229 extract_rsa_public_key (void *cls,
230                         PGresult *result,
231                         int row,
232                         const char *fname,
233                         size_t *dst_size,
234                         void *dst)
235 {
236   struct GNUNET_CRYPTO_rsa_PublicKey **pk = dst;
237   size_t len;
238   const char *res;
239   int fnum;
240
241   *pk = NULL;
242   fnum = PQfnumber (result,
243                     fname);
244   if (fnum < 0)
245   {
246     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
247                 "Field `%s' does not exist in result\n",
248                 fname);
249     return GNUNET_SYSERR;
250   }
251   if (PQgetisnull (result,
252                    row,
253                    fnum))
254     return GNUNET_NO;
255
256   /* if a field is null, continue but
257    * remember that we now return a different result */
258   len = PQgetlength (result,
259                      row,
260                      fnum);
261   res = PQgetvalue (result,
262                     row,
263                     fnum);
264   *pk = GNUNET_CRYPTO_rsa_public_key_decode (res,
265                                              len);
266   if (NULL == *pk)
267   {
268     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
269                 "Field `%s' contains bogus value (fails to decode)\n",
270                 fname);
271     return GNUNET_SYSERR;
272   }
273   return GNUNET_OK;
274 }
275
276
277 /**
278  * Function called to clean up memory allocated
279  * by a #GNUNET_PQ_ResultConverter.
280  *
281  * @param cls closure
282  * @param rd result data to clean up
283  */
284 static void
285 clean_rsa_public_key (void *cls,
286                       void *rd)
287 {
288   struct GNUNET_CRYPTO_rsa_PublicKey **pk = rd;
289   
290   if (NULL != *pk)
291   {
292     GNUNET_CRYPTO_rsa_public_key_free (*pk);
293     *pk = NULL;
294   }
295 }
296
297
298 /**
299  * RSA public key expected.
300  *
301  * @param name name of the field in the table
302  * @param[out] rsa where to store the result
303  * @return array entry for the result specification to use
304  */
305 struct GNUNET_PQ_ResultSpec
306 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
307                                       struct GNUNET_CRYPTO_rsa_PublicKey **rsa)
308 {
309   struct GNUNET_PQ_ResultSpec res =
310     { &extract_rsa_public_key,
311       &clean_rsa_public_key,
312       NULL,
313       (void *) rsa, 0, name, NULL };
314   return res;
315 }
316
317
318 /**
319  * Extract data from a Postgres database @a result at row @a row.
320  *
321  * @param cls closure
322  * @param result where to extract data from
323  * @param int row to extract data from
324  * @param fname name (or prefix) of the fields to extract from
325  * @param[in,out] dst_size where to store size of result, may be NULL
326  * @param[out] dst where to store the result
327  * @return
328  *   #GNUNET_YES if all results could be extracted
329  *   #GNUNET_NO if at least one result was NULL
330  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
331  */ 
332 static int
333 extract_rsa_signature (void *cls,
334                        PGresult *result,
335                        int row,
336                        const char *fname,
337                        size_t *dst_size,
338                        void *dst)
339 {
340   struct GNUNET_CRYPTO_rsa_Signature **sig = dst;
341   size_t len;
342   const char *res;
343   int fnum;
344   
345   *sig = NULL;
346   fnum = PQfnumber (result,
347                     fname);
348   if (fnum < 0)
349   {
350     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
351                 "Field `%s' does not exist in result\n",
352                 fname);
353     return GNUNET_SYSERR;
354   }
355   if (PQgetisnull (result,
356                    row,
357                    fnum))
358     return GNUNET_NO;
359
360   /* if a field is null, continue but
361    * remember that we now return a different result */
362   len = PQgetlength (result,
363                      row,
364                      fnum);
365   res = PQgetvalue (result,
366                     row,
367                     fnum);
368   *sig = GNUNET_CRYPTO_rsa_signature_decode (res,
369                                              len);
370   if (NULL == *sig)
371   {
372     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
373                 "Field `%s' contains bogus value (fails to decode)\n",
374                 fname);
375     return GNUNET_SYSERR;
376   }
377   return GNUNET_OK;
378 }
379
380
381 /**
382  * Function called to clean up memory allocated
383  * by a #GNUNET_PQ_ResultConverter.
384  *
385  * @param cls closure
386  * @param rd result data to clean up
387  */
388 static void
389 clean_rsa_signature (void *cls,
390                      void *rd)
391 {
392   struct GNUNET_CRYPTO_rsa_Signature **sig = rd;
393
394   if (NULL != *sig)
395   {
396     GNUNET_CRYPTO_rsa_signature_free (*sig);
397     *sig = NULL;
398   }
399 }
400
401
402 /**
403  * RSA signature expected.
404  *
405  * @param name name of the field in the table
406  * @param[out] sig where to store the result;
407  * @return array entry for the result specification to use
408  */
409 struct GNUNET_PQ_ResultSpec
410 GNUNET_PQ_result_spec_rsa_signature (const char *name,
411                                     struct GNUNET_CRYPTO_rsa_Signature **sig)
412 {
413   struct GNUNET_PQ_ResultSpec res =
414     { &extract_rsa_signature,
415       &clean_rsa_signature,
416       NULL,
417       (void *) sig, 0, (name), NULL };
418   return res;
419 }
420
421
422 /**
423  * Absolute time expected.
424  *
425  * @param name name of the field in the table
426  * @param[out] at where to store the result
427  * @return array entry for the result specification to use
428  */
429 struct GNUNET_PQ_ResultSpec
430 GNUNET_PQ_result_spec_absolute_time (const char *name,
431                                      struct GNUNET_TIME_Absolute *at)
432 {
433   return GNUNET_PQ_result_spec_uint64 (name,
434                                        &at->abs_value_us);
435 }
436
437
438 /**
439  * Absolute time in network byte order expected.
440  *
441  * @param name name of the field in the table
442  * @param[out] at where to store the result
443  * @return array entry for the result specification to use
444  */
445 struct GNUNET_PQ_ResultSpec
446 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
447                                          struct GNUNET_TIME_AbsoluteNBO *at)
448 {
449   struct GNUNET_PQ_ResultSpec res =
450     GNUNET_PQ_result_spec_auto_from_type(name, &at->abs_value_us__);
451   return res;
452 }
453
454
455 /**
456  * Extract data from a Postgres database @a result at row @a row.
457  *
458  * @param cls closure
459  * @param result where to extract data from
460  * @param int row to extract data from
461  * @param fname name (or prefix) of the fields to extract from
462  * @param[in,out] dst_size where to store size of result, may be NULL
463  * @param[out] dst where to store the result
464  * @return
465  *   #GNUNET_YES if all results could be extracted
466  *   #GNUNET_NO if at least one result was NULL
467  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
468  */ 
469 static int
470 extract_uint16 (void *cls,
471                 PGresult *result,
472                 int row,
473                 const char *fname,
474                 size_t *dst_size,
475                 void *dst)
476 {
477   uint16_t *udst = dst;
478   const uint16_t *res;
479   int fnum;
480   
481   fnum = PQfnumber (result,
482                     fname);
483   if (fnum < 0)
484   {
485     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
486                 "Field `%s' does not exist in result\n",
487                 fname);
488     return GNUNET_SYSERR;
489   }
490   if (PQgetisnull (result,
491                    row,
492                    fnum))
493     return GNUNET_NO;
494   GNUNET_assert (NULL != dst);
495   if (sizeof (uint16_t) != *dst_size)
496   {
497     GNUNET_break (0);
498     return GNUNET_SYSERR;
499   }
500   res = (uint16_t *) PQgetvalue (result,
501                                  row,
502                                  fnum);
503   *udst = ntohs (*res);
504   return GNUNET_OK;
505 }
506
507
508 /**
509  * uint16_t expected.
510  *
511  * @param name name of the field in the table
512  * @param[out] u16 where to store the result
513  * @return array entry for the result specification to use
514  */
515 struct GNUNET_PQ_ResultSpec
516 GNUNET_PQ_result_spec_uint16 (const char *name,
517                               uint16_t *u16)
518 {
519   struct GNUNET_PQ_ResultSpec res =
520     { &extract_uint16,
521       NULL,
522       NULL,
523       (void *) u16, sizeof (*u16), (name), NULL };
524   return res;
525 }
526
527
528 /**
529  * Extract data from a Postgres database @a result at row @a row.
530  *
531  * @param cls closure
532  * @param result where to extract data from
533  * @param int row to extract data from
534  * @param fname name (or prefix) of the fields to extract from
535  * @param[in,out] dst_size where to store size of result, may be NULL
536  * @param[out] dst where to store the result
537  * @return
538  *   #GNUNET_YES if all results could be extracted
539  *   #GNUNET_NO if at least one result was NULL
540  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
541  */ 
542 static int
543 extract_uint32 (void *cls,
544                 PGresult *result,
545                 int row,
546                 const char *fname,
547                 size_t *dst_size,
548                 void *dst)
549 {
550   uint32_t *udst = dst;
551   const uint32_t *res;
552   int fnum;
553   
554   fnum = PQfnumber (result,
555                     fname);
556   if (fnum < 0)
557   {
558     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
559                 "Field `%s' does not exist in result\n",
560                 fname);
561     return GNUNET_SYSERR;
562   }
563   if (PQgetisnull (result,
564                    row,
565                    fnum))
566     return GNUNET_NO;
567   GNUNET_assert (NULL != dst);
568   if (sizeof (uint32_t) != *dst_size)
569   {
570     GNUNET_break (0);
571     return GNUNET_SYSERR;
572   }
573   res = (uint32_t *) PQgetvalue (result,
574                                  row,
575                                  fnum);
576   *udst = ntohl (*res);
577   return GNUNET_OK;
578 }
579
580
581 /**
582  * uint32_t expected.
583  *
584  * @param name name of the field in the table
585  * @param[out] u32 where to store the result
586  * @return array entry for the result specification to use
587  */
588 struct GNUNET_PQ_ResultSpec
589 GNUNET_PQ_result_spec_uint32 (const char *name,
590                               uint32_t *u32)
591 {
592   struct GNUNET_PQ_ResultSpec res =
593     { &extract_uint32, 
594       NULL,
595       NULL,
596       (void *) u32, sizeof (*u32), (name), NULL };
597   return res;
598 }
599
600
601 /**
602  * Extract data from a Postgres database @a result at row @a row.
603  *
604  * @param cls closure
605  * @param result where to extract data from
606  * @param int row to extract data from
607  * @param fname name (or prefix) of the fields to extract from
608  * @param[in,out] dst_size where to store size of result, may be NULL
609  * @param[out] dst where to store the result
610  * @return
611  *   #GNUNET_YES if all results could be extracted
612  *   #GNUNET_NO if at least one result was NULL
613  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
614  */ 
615 static int
616 extract_uint64 (void *cls,
617                 PGresult *result,
618                 int row,
619                 const char *fname,
620                 size_t *dst_size,
621                 void *dst)
622 {
623   uint64_t *udst = dst;
624   const uint64_t *res;
625   int fnum;
626   
627   fnum = PQfnumber (result,
628                     fname);
629   if (fnum < 0)
630   {
631     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
632                 "Field `%s' does not exist in result\n",
633                 fname);
634     return GNUNET_SYSERR;
635   }
636   if (PQgetisnull (result,
637                    row,
638                    fnum))
639     return GNUNET_NO;
640   GNUNET_assert (NULL != dst);
641   if (sizeof (uint64_t) != *dst_size)
642   {
643     GNUNET_break (0);
644     return GNUNET_SYSERR;
645   }
646   res = (uint64_t *) PQgetvalue (result,
647                                  row,
648                                  fnum);
649   *udst = GNUNET_ntohll (*res);
650   return GNUNET_OK;
651 }
652
653
654 /**
655  * uint64_t expected.
656  *
657  * @param name name of the field in the table
658  * @param[out] u64 where to store the result
659  * @return array entry for the result specification to use
660  */
661 struct GNUNET_PQ_ResultSpec
662 GNUNET_PQ_result_spec_uint64 (const char *name,
663                               uint64_t *u64)
664 {
665   struct GNUNET_PQ_ResultSpec res =
666     { &extract_uint64,
667       NULL,
668       NULL,
669       (void *) u64, sizeof (*u64), (name), NULL };
670   return res;
671 }
672
673
674 /* end of pq_result_helper.c */