aboutsummaryrefslogtreecommitdiff
path: root/src/pq/pq_query_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pq/pq_query_helper.c')
-rw-r--r--src/pq/pq_query_helper.c1328
1 files changed, 0 insertions, 1328 deletions
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
deleted file mode 100644
index 0350ad336..000000000
--- a/src/pq/pq_query_helper.c
+++ /dev/null
@@ -1,1328 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file pq/pq_query_helper.c
22 * @brief functions to initialize parameter arrays
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_common.h"
27#include "gnunet_pq_lib.h"
28#include "gnunet_time_lib.h"
29#include "pq.h"
30
31
32/**
33 * Function called to convert input argument into SQL parameters.
34 *
35 * @param cls closure
36 * @param data pointer to input argument
37 * @param data_len number of bytes in @a data (if applicable)
38 * @param[out] param_values SQL data to set
39 * @param[out] param_lengths SQL length data to set
40 * @param[out] param_formats SQL format data to set
41 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
42 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
43 * @param scratch_length number of entries left in @a scratch
44 * @return -1 on error, number of offsets used in @a scratch otherwise
45 */
46static int
47qconv_null (void *cls,
48 const void *data,
49 size_t data_len,
50 void *param_values[],
51 int param_lengths[],
52 int param_formats[],
53 unsigned int param_length,
54 void *scratch[],
55 unsigned int scratch_length)
56{
57 (void) scratch;
58 (void) scratch_length;
59 (void) data;
60 (void) data_len;
61 GNUNET_break (NULL == cls);
62 if (1 != param_length)
63 return -1;
64 param_values[0] = NULL;
65 param_lengths[0] = 0;
66 param_formats[0] = 1;
67 return 0;
68}
69
70
71struct GNUNET_PQ_QueryParam
72GNUNET_PQ_query_param_null (void)
73{
74 struct GNUNET_PQ_QueryParam res = {
75 .conv = &qconv_null,
76 .num_params = 1
77 };
78
79 return res;
80}
81
82
83/**
84 * Function called to convert input argument into SQL parameters.
85 *
86 * @param cls closure
87 * @param data pointer to input argument
88 * @param data_len number of bytes in @a data (if applicable)
89 * @param[out] param_values SQL data to set
90 * @param[out] param_lengths SQL length data to set
91 * @param[out] param_formats SQL format data to set
92 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
93 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
94 * @param scratch_length number of entries left in @a scratch
95 * @return -1 on error, number of offsets used in @a scratch otherwise
96 */
97static int
98qconv_fixed (void *cls,
99 const void *data,
100 size_t data_len,
101 void *param_values[],
102 int param_lengths[],
103 int param_formats[],
104 unsigned int param_length,
105 void *scratch[],
106 unsigned int scratch_length)
107{
108 (void) scratch;
109 (void) scratch_length;
110 GNUNET_break (NULL == cls);
111 if (1 != param_length)
112 return -1;
113 param_values[0] = (void *) data;
114 param_lengths[0] = data_len;
115 param_formats[0] = 1;
116 return 0;
117}
118
119
120struct GNUNET_PQ_QueryParam
121GNUNET_PQ_query_param_fixed_size (const void *ptr,
122 size_t ptr_size)
123{
124 struct GNUNET_PQ_QueryParam res = {
125 .conv = &qconv_fixed,
126 .conv_cls = NULL,
127 .data = ptr,
128 .size = ptr_size,
129 .num_params = 1
130 };
131
132 return res;
133}
134
135
136struct GNUNET_PQ_QueryParam
137GNUNET_PQ_query_param_string (const char *ptr)
138{
139 return GNUNET_PQ_query_param_fixed_size (ptr,
140 strlen (ptr));
141}
142
143
144struct GNUNET_PQ_QueryParam
145GNUNET_PQ_query_param_bool (bool b)
146{
147 static uint8_t bt = 1;
148 static uint8_t bf = 0;
149
150 return GNUNET_PQ_query_param_fixed_size (b ? &bt : &bf,
151 sizeof (uint8_t));
152}
153
154
155/**
156 * Function called to convert input argument into SQL parameters.
157 *
158 * @param cls closure
159 * @param data pointer to input argument
160 * @param data_len number of bytes in @a data (if applicable)
161 * @param[out] param_values SQL data to set
162 * @param[out] param_lengths SQL length data to set
163 * @param[out] param_formats SQL format data to set
164 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
165 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
166 * @param scratch_length number of entries left in @a scratch
167 * @return -1 on error, number of offsets used in @a scratch otherwise
168 */
169static int
170qconv_uint16 (void *cls,
171 const void *data,
172 size_t data_len,
173 void *param_values[],
174 int param_lengths[],
175 int param_formats[],
176 unsigned int param_length,
177 void *scratch[],
178 unsigned int scratch_length)
179{
180 const uint16_t *u_hbo = data;
181 uint16_t *u_nbo;
182
183 (void) scratch;
184 (void) scratch_length;
185 GNUNET_break (NULL == cls);
186 if (1 != param_length)
187 return -1;
188 u_nbo = GNUNET_new (uint16_t);
189 scratch[0] = u_nbo;
190 *u_nbo = htons (*u_hbo);
191 param_values[0] = (void *) u_nbo;
192 param_lengths[0] = sizeof(uint16_t);
193 param_formats[0] = 1;
194 return 1;
195}
196
197
198struct GNUNET_PQ_QueryParam
199GNUNET_PQ_query_param_uint16 (const uint16_t *x)
200{
201 struct GNUNET_PQ_QueryParam res = {
202 .conv = &qconv_uint16,
203 .data = x,
204 .size = sizeof(*x),
205 .num_params = 1
206 };
207
208 return res;
209}
210
211
212/**
213 * Function called to convert input argument into SQL parameters.
214 *
215 * @param cls closure
216 * @param data pointer to input argument
217 * @param data_len number of bytes in @a data (if applicable)
218 * @param[out] param_values SQL data to set
219 * @param[out] param_lengths SQL length data to set
220 * @param[out] param_formats SQL format data to set
221 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
222 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
223 * @param scratch_length number of entries left in @a scratch
224 * @return -1 on error, number of offsets used in @a scratch otherwise
225 */
226static int
227qconv_uint32 (void *cls,
228 const void *data,
229 size_t data_len,
230 void *param_values[],
231 int param_lengths[],
232 int param_formats[],
233 unsigned int param_length,
234 void *scratch[],
235 unsigned int scratch_length)
236{
237 const uint32_t *u_hbo = data;
238 uint32_t *u_nbo;
239
240 (void) scratch;
241 (void) scratch_length;
242 GNUNET_break (NULL == cls);
243 if (1 != param_length)
244 return -1;
245 u_nbo = GNUNET_new (uint32_t);
246 scratch[0] = u_nbo;
247 *u_nbo = htonl (*u_hbo);
248 param_values[0] = (void *) u_nbo;
249 param_lengths[0] = sizeof(uint32_t);
250 param_formats[0] = 1;
251 return 1;
252}
253
254
255struct GNUNET_PQ_QueryParam
256GNUNET_PQ_query_param_uint32 (const uint32_t *x)
257{
258 struct GNUNET_PQ_QueryParam res = {
259 .conv = &qconv_uint32,
260 .data = x,
261 .size = sizeof(*x),
262 .num_params = 1
263 };
264
265 return res;
266}
267
268
269/**
270 * Function called to convert input argument into SQL parameters.
271 *
272 * @param cls closure
273 * @param data pointer to input argument
274 * @param data_len number of bytes in @a data (if applicable)
275 * @param[out] param_values SQL data to set
276 * @param[out] param_lengths SQL length data to set
277 * @param[out] param_formats SQL format data to set
278 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
279 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
280 * @param scratch_length number of entries left in @a scratch
281 * @return -1 on error, number of offsets used in @a scratch otherwise
282 */
283static int
284qconv_uint64 (void *cls,
285 const void *data,
286 size_t data_len,
287 void *param_values[],
288 int param_lengths[],
289 int param_formats[],
290 unsigned int param_length,
291 void *scratch[],
292 unsigned int scratch_length)
293{
294 const uint64_t *u_hbo = data;
295 uint64_t *u_nbo;
296
297 (void) scratch;
298 (void) scratch_length;
299 GNUNET_break (NULL == cls);
300 if (1 != param_length)
301 return -1;
302 u_nbo = GNUNET_new (uint64_t);
303 scratch[0] = u_nbo;
304 *u_nbo = GNUNET_htonll (*u_hbo);
305 param_values[0] = (void *) u_nbo;
306 param_lengths[0] = sizeof(uint64_t);
307 param_formats[0] = 1;
308 return 1;
309}
310
311
312struct GNUNET_PQ_QueryParam
313GNUNET_PQ_query_param_uint64 (const uint64_t *x)
314{
315 struct GNUNET_PQ_QueryParam res = {
316 .conv = &qconv_uint64,
317 .data = x,
318 .size = sizeof(*x),
319 .num_params = 1
320 };
321
322 return res;
323}
324
325
326/**
327 * Function called to convert input argument into SQL parameters.
328 *
329 * @param cls closure
330 * @param data pointer to input argument
331 * @param data_len number of bytes in @a data (if applicable)
332 * @param[out] param_values SQL data to set
333 * @param[out] param_lengths SQL length data to set
334 * @param[out] param_formats SQL format data to set
335 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
336 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
337 * @param scratch_length number of entries left in @a scratch
338 * @return -1 on error, number of offsets used in @a scratch otherwise
339 */
340static int
341qconv_rsa_public_key (void *cls,
342 const void *data,
343 size_t data_len,
344 void *param_values[],
345 int param_lengths[],
346 int param_formats[],
347 unsigned int param_length,
348 void *scratch[],
349 unsigned int scratch_length)
350{
351 const struct GNUNET_CRYPTO_RsaPublicKey *rsa = data;
352 void *buf;
353 size_t buf_size;
354
355 GNUNET_break (NULL == cls);
356 if (1 != param_length)
357 return -1;
358 buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa,
359 &buf);
360 scratch[0] = buf;
361 param_values[0] = (void *) buf;
362 param_lengths[0] = buf_size;
363 param_formats[0] = 1;
364 return 1;
365}
366
367
368struct GNUNET_PQ_QueryParam
369GNUNET_PQ_query_param_rsa_public_key (
370 const struct GNUNET_CRYPTO_RsaPublicKey *x)
371{
372 struct GNUNET_PQ_QueryParam res = {
373 .conv = &qconv_rsa_public_key,
374 .data = x,
375 .num_params = 1
376 };
377
378 return res;
379}
380
381
382/**
383 * Function called to convert input argument into SQL parameters.
384 *
385 * @param cls closure
386 * @param data pointer to input argument
387 * @param data_len number of bytes in @a data (if applicable)
388 * @param[out] param_values SQL data to set
389 * @param[out] param_lengths SQL length data to set
390 * @param[out] param_formats SQL format data to set
391 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
392 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
393 * @param scratch_length number of entries left in @a scratch
394 * @return -1 on error, number of offsets used in @a scratch otherwise
395 */
396static int
397qconv_rsa_signature (void *cls,
398 const void *data,
399 size_t data_len,
400 void *param_values[],
401 int param_lengths[],
402 int param_formats[],
403 unsigned int param_length,
404 void *scratch[],
405 unsigned int scratch_length)
406{
407 const struct GNUNET_CRYPTO_RsaSignature *sig = data;
408 void *buf;
409 size_t buf_size;
410
411 GNUNET_break (NULL == cls);
412 if (1 != param_length)
413 return -1;
414 buf_size = GNUNET_CRYPTO_rsa_signature_encode (sig,
415 &buf);
416 scratch[0] = buf;
417 param_values[0] = (void *) buf;
418 param_lengths[0] = buf_size;
419 param_formats[0] = 1;
420 return 1;
421}
422
423
424struct GNUNET_PQ_QueryParam
425GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
426{
427 struct GNUNET_PQ_QueryParam res = {
428 .conv = &qconv_rsa_signature,
429 .data = x,
430 .num_params = 1
431 };
432
433 return res;
434}
435
436
437/**
438 * Function called to convert input argument into SQL parameters.
439 *
440 * @param cls closure
441 * @param data pointer to input argument
442 * @param data_len number of bytes in @a data (if applicable)
443 * @param[out] param_values SQL data to set
444 * @param[out] param_lengths SQL length data to set
445 * @param[out] param_formats SQL format data to set
446 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
447 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
448 * @param scratch_length number of entries left in @a scratch
449 * @return -1 on error, number of offsets used in @a scratch otherwise
450 */
451static int
452qconv_rel_time (void *cls,
453 const void *data,
454 size_t data_len,
455 void *param_values[],
456 int param_lengths[],
457 int param_formats[],
458 unsigned int param_length,
459 void *scratch[],
460 unsigned int scratch_length)
461{
462 const struct GNUNET_TIME_Relative *u = data;
463 struct GNUNET_TIME_Relative rel;
464 uint64_t *u_nbo;
465
466 GNUNET_break (NULL == cls);
467 if (1 != param_length)
468 return -1;
469 rel = *u;
470 if (rel.rel_value_us > INT64_MAX)
471 rel.rel_value_us = INT64_MAX;
472 u_nbo = GNUNET_new (uint64_t);
473 scratch[0] = u_nbo;
474 *u_nbo = GNUNET_htonll (rel.rel_value_us);
475 param_values[0] = (void *) u_nbo;
476 param_lengths[0] = sizeof(uint64_t);
477 param_formats[0] = 1;
478 return 1;
479}
480
481
482struct GNUNET_PQ_QueryParam
483GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x)
484{
485 struct GNUNET_PQ_QueryParam res = {
486 .conv = &qconv_rel_time,
487 .data = x,
488 .size = sizeof(*x),
489 .num_params = 1
490 };
491
492 return res;
493}
494
495
496/**
497 * Function called to convert input argument into SQL parameters.
498 *
499 * @param cls closure
500 * @param data pointer to input argument
501 * @param data_len number of bytes in @a data (if applicable)
502 * @param[out] param_values SQL data to set
503 * @param[out] param_lengths SQL length data to set
504 * @param[out] param_formats SQL format data to set
505 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
506 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
507 * @param scratch_length number of entries left in @a scratch
508 * @return -1 on error, number of offsets used in @a scratch otherwise
509 */
510static int
511qconv_abs_time (void *cls,
512 const void *data,
513 size_t data_len,
514 void *param_values[],
515 int param_lengths[],
516 int param_formats[],
517 unsigned int param_length,
518 void *scratch[],
519 unsigned int scratch_length)
520{
521 const struct GNUNET_TIME_Absolute *u = data;
522 struct GNUNET_TIME_Absolute abs;
523 uint64_t *u_nbo;
524
525 GNUNET_break (NULL == cls);
526 if (1 != param_length)
527 return -1;
528 abs = *u;
529 if (abs.abs_value_us > INT64_MAX)
530 abs.abs_value_us = INT64_MAX;
531 u_nbo = GNUNET_new (uint64_t);
532 scratch[0] = u_nbo;
533 *u_nbo = GNUNET_htonll (abs.abs_value_us);
534 param_values[0] = (void *) u_nbo;
535 param_lengths[0] = sizeof(uint64_t);
536 param_formats[0] = 1;
537 return 1;
538}
539
540
541struct GNUNET_PQ_QueryParam
542GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
543{
544 struct GNUNET_PQ_QueryParam res = {
545 .conv = &qconv_abs_time,
546 .data = x,
547 .size = sizeof(*x),
548 .num_params = 1
549 };
550
551 return res;
552}
553
554
555struct GNUNET_PQ_QueryParam
556GNUNET_PQ_query_param_absolute_time_nbo (
557 const struct GNUNET_TIME_AbsoluteNBO *x)
558{
559 return GNUNET_PQ_query_param_auto_from_type (&x->abs_value_us__);
560}
561
562
563struct GNUNET_PQ_QueryParam
564GNUNET_PQ_query_param_timestamp (const struct GNUNET_TIME_Timestamp *x)
565{
566 return GNUNET_PQ_query_param_absolute_time (&x->abs_time);
567}
568
569
570struct GNUNET_PQ_QueryParam
571GNUNET_PQ_query_param_timestamp_nbo (
572 const struct GNUNET_TIME_TimestampNBO *x)
573{
574 return GNUNET_PQ_query_param_absolute_time_nbo (&x->abs_time_nbo);
575}
576
577
578/**
579 * Closure for the array type handlers.
580 *
581 * May contain sizes information for the data, given (and handled) by the
582 * caller.
583 */
584struct qconv_array_cls
585{
586 /**
587 * If not null, contains the array of sizes (the size of the array is the
588 * .size field in the ambient GNUNET_PQ_QueryParam struct). We do not free
589 * this memory.
590 *
591 * If not null, this value has precedence over @a sizes, which MUST be NULL */
592 const size_t *sizes;
593
594 /**
595 * If @a size and @a c_sizes are NULL, this field defines the same size
596 * for each element in the array.
597 */
598 size_t same_size;
599
600 /**
601 * If true, the array parameter to the data pointer to the qconv_array is a
602 * continuous byte array of data, either with @a same_size each or sizes
603 * provided bytes by @a sizes;
604 */
605 bool continuous;
606
607 /**
608 * Type of the array elements
609 */
610 enum array_types typ;
611
612 /**
613 * Oid of the array elements
614 */
615 Oid oid;
616};
617
618/**
619 * Callback to cleanup a qconv_array_cls to be used during
620 * GNUNET_PQ_cleanup_query_params_closures
621 */
622static void
623qconv_array_cls_cleanup (void *cls)
624{
625 GNUNET_free (cls);
626}
627
628
629/**
630 * Function called to convert input argument into SQL parameters for arrays
631 *
632 * Note: the format for the encoding of arrays for libpq is not very well
633 * documented. We peeked into various sources (postgresql and libpqtypes) for
634 * guidance.
635 *
636 * @param cls Closure of type struct qconv_array_cls*
637 * @param data Pointer to first element in the array
638 * @param data_len Number of _elements_ in array @a data (if applicable)
639 * @param[out] param_values SQL data to set
640 * @param[out] param_lengths SQL length data to set
641 * @param[out] param_formats SQL format data to set
642 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
643 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
644 * @param scratch_length number of entries left in @a scratch
645 * @return -1 on error, number of offsets used in @a scratch otherwise
646 */
647static int
648qconv_array (
649 void *cls,
650 const void *data,
651 size_t data_len,
652 void *param_values[],
653 int param_lengths[],
654 int param_formats[],
655 unsigned int param_length,
656 void *scratch[],
657 unsigned int scratch_length)
658{
659 struct qconv_array_cls *meta = cls;
660 size_t num = data_len;
661 size_t total_size;
662 const size_t *sizes;
663 bool same_sized;
664 size_t *string_lengths = NULL;
665 void *elements = NULL;
666 bool noerror = true;
667
668 (void) (param_length);
669 (void) (scratch_length);
670
671 GNUNET_assert (NULL != meta);
672 GNUNET_assert (num < INT_MAX);
673
674 sizes = meta->sizes;
675 same_sized = (0 != meta->same_size);
676
677#define RETURN_UNLESS(cond) \
678 do { \
679 if (! (cond)) \
680 { \
681 GNUNET_break ((cond)); \
682 noerror = false; \
683 goto DONE; \
684 } \
685 } while (0)
686
687 /* Calculate sizes and check bounds */
688 {
689 /* num * length-field */
690 size_t x = sizeof(uint32_t);
691 size_t y = x * num;
692 RETURN_UNLESS ((0 == num) || (y / num == x));
693
694 /* size of header */
695 total_size = x = sizeof(struct pq_array_header);
696 total_size += y;
697 RETURN_UNLESS (total_size >= x);
698
699 /* sizes of elements */
700 if (same_sized)
701 {
702 x = num * meta->same_size;
703 RETURN_UNLESS ((0 == num) || (x / num == meta->same_size));
704
705 y = total_size;
706 total_size += x;
707 RETURN_UNLESS (total_size >= y);
708 }
709 else /* sizes are different per element */
710 {
711 /* for an array of strings we need to get their length's first */
712 if (array_of_string == meta->typ)
713 {
714 string_lengths = GNUNET_new_array (num, size_t);
715
716 if (meta->continuous)
717 {
718 const char *ptr = data;
719 for (unsigned int i = 0; i < num; i++)
720 {
721 size_t len = strlen (ptr);
722 string_lengths[i] = len;
723 ptr += len + 1;
724 }
725 }
726 else
727 {
728 const char **str = (const char **) data;
729 for (unsigned int i = 0; i < num; i++)
730 string_lengths[i] = strlen (str[i]);
731 }
732
733 sizes = string_lengths;
734 }
735
736 for (unsigned int i = 0; i < num; i++)
737 {
738 x = total_size;
739 total_size += sizes[i];
740 RETURN_UNLESS (total_size >= x);
741 }
742 }
743
744 RETURN_UNLESS (total_size < INT_MAX);
745
746 elements = GNUNET_malloc (total_size);
747 }
748
749 /* Write data */
750 {
751 char *in = (char *) data;
752 char *out = elements;
753 size_t nullbyte = (array_of_string == meta->typ) ? 1 : 0;
754 struct pq_array_header h = {
755 .ndim = htonl (1), /* We only support one-dimensional arrays */
756 .has_null = htonl (0), /* We do not support NULL entries in arrays */
757 .lbound = htonl (1), /* Default start index value */
758 .dim = htonl (num),
759 .oid = htonl (meta->oid),
760 };
761
762 /* Write header */
763 GNUNET_memcpy (out, &h, sizeof(h));
764 out += sizeof(h);
765
766
767 /* Write elements */
768 for (unsigned int i = 0; i < num; i++)
769 {
770 size_t sz = same_sized ? meta->same_size : sizes[i];
771 size_t hsz = htonl (sz);
772
773 GNUNET_memcpy (out,
774 &hsz,
775 sizeof(hsz));
776 out += sizeof(uint32_t);
777
778 switch (meta->typ)
779 {
780 case array_of_bool:
781 {
782 GNUNET_assert (sizeof(bool) == sz);
783 *(bool *) out = (*(bool *) in);
784 in += sz;
785 break;
786 }
787 case array_of_uint16:
788 {
789 GNUNET_assert (sizeof(uint16_t) == sz);
790 *(uint16_t *) out = htons (*(uint16_t *) in);
791 in += sz;
792 break;
793 }
794 case array_of_uint32:
795 {
796 uint32_t v;
797 GNUNET_assert (sizeof(uint32_t) == sz);
798
799 v = htonl (*(uint32_t *) in);
800 GNUNET_memcpy (out,
801 &v,
802 sizeof(v));
803 in += sz;
804 break;
805 }
806 case array_of_uint64:
807 {
808 uint64_t tmp;
809 GNUNET_assert (sizeof(uint64_t) == sz);
810
811 tmp = GNUNET_htonll (*(uint64_t *) in);
812 GNUNET_memcpy (out,
813 &tmp,
814 sizeof(tmp));
815 in += sz;
816 break;
817 }
818 case array_of_byte:
819 case array_of_string:
820 {
821 const void *ptr;
822
823 if (meta->continuous)
824 {
825 ptr = in;
826 in += sz + nullbyte;
827 }
828 else
829 ptr = ((const void **) data)[i];
830
831 GNUNET_memcpy (out,
832 ptr,
833 sz);
834 break;
835 }
836 case array_of_abs_time:
837 case array_of_rel_time:
838 case array_of_timestamp:
839 {
840 uint64_t val;
841
842 switch (meta->typ)
843 {
844 case array_of_abs_time:
845 {
846 const struct GNUNET_TIME_Absolute *abs =
847 (const struct GNUNET_TIME_Absolute *) in;
848
849 GNUNET_assert (sizeof(struct GNUNET_TIME_Absolute) == sz);
850
851 if (! meta->continuous)
852 abs = ((const struct GNUNET_TIME_Absolute **) data)[i];
853
854 val = abs->abs_value_us;
855 break;
856 }
857 case array_of_rel_time:
858 {
859 const struct GNUNET_TIME_Relative *rel =
860 (const struct GNUNET_TIME_Relative *) in;
861
862 GNUNET_assert (sizeof(struct GNUNET_TIME_Relative) == sz);
863
864 if (! meta->continuous)
865 rel = ((const struct GNUNET_TIME_Relative **) data)[i];
866
867 val = rel->rel_value_us;
868 break;
869 }
870 case array_of_timestamp:
871 {
872 const struct GNUNET_TIME_Timestamp *ts =
873 (const struct GNUNET_TIME_Timestamp *) in;
874
875 GNUNET_assert (sizeof(struct GNUNET_TIME_Timestamp) == sz);
876
877 if (! meta->continuous)
878 ts = ((const struct GNUNET_TIME_Timestamp **) data)[i];
879
880 val = ts->abs_time.abs_value_us;
881 break;
882 }
883 default:
884 {
885 GNUNET_assert (0);
886 }
887 }
888
889 if (val > INT64_MAX)
890 val = INT64_MAX;
891
892 val = GNUNET_htonll (val);
893 GNUNET_memcpy (out,
894 &val,
895 sizeof(val));
896
897 if (meta->continuous)
898 in += sz;
899
900 break;
901 }
902 default:
903 {
904 GNUNET_assert (0);
905 break;
906 }
907 }
908 out += sz;
909 }
910 }
911
912 param_values[0] = elements;
913 param_lengths[0] = total_size;
914 param_formats[0] = 1;
915 scratch[0] = elements;
916
917DONE:
918 GNUNET_free (string_lengths);
919
920 if (noerror)
921 return 1;
922
923 return -1;
924}
925
926
927/**
928 * Function to genreate a typ specific query parameter and corresponding closure
929 *
930 * @param num Number of elements in @a elements
931 * @param continuous If true, @a elements is an continuous array of data
932 * @param elements Array of @a num elements, either continuous or pointers
933 * @param sizes Array of @a num sizes, one per element, may be NULL
934 * @param same_size If not 0, all elements in @a elements have this size
935 * @param typ Supported internal type of each element in @a elements
936 * @param oid Oid of the type to be used in Postgres
937 * @return Query parameter
938 */
939static struct GNUNET_PQ_QueryParam
940query_param_array_generic (
941 unsigned int num,
942 bool continuous,
943 const void *elements,
944 const size_t *sizes,
945 size_t same_size,
946 enum array_types typ,
947 Oid oid)
948{
949 struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls);
950
951 meta->typ = typ;
952 meta->oid = oid;
953 meta->sizes = sizes;
954 meta->same_size = same_size;
955 meta->continuous = continuous;
956
957 {
958 struct GNUNET_PQ_QueryParam res = {
959 .conv = qconv_array,
960 .conv_cls = meta,
961 .conv_cls_cleanup = &qconv_array_cls_cleanup,
962 .data = elements,
963 .size = num,
964 .num_params = 1,
965 };
966
967 return res;
968 }
969}
970
971
972struct GNUNET_PQ_QueryParam
973GNUNET_PQ_query_param_array_bool (
974 unsigned int num,
975 const bool *elements,
976 struct GNUNET_PQ_Context *db)
977{
978 Oid oid;
979
980 GNUNET_assert (GNUNET_OK ==
981 GNUNET_PQ_get_oid_by_name (db,
982 "bool",
983 &oid));
984 return query_param_array_generic (num,
985 true,
986 elements,
987 NULL,
988 sizeof(bool),
989 array_of_bool,
990 oid);
991}
992
993
994struct GNUNET_PQ_QueryParam
995GNUNET_PQ_query_param_array_uint16 (
996 unsigned int num,
997 const uint16_t *elements,
998 struct GNUNET_PQ_Context *db)
999{
1000 Oid oid;
1001
1002 GNUNET_assert (GNUNET_OK ==
1003 GNUNET_PQ_get_oid_by_name (db,
1004 "int2",
1005 &oid));
1006 return query_param_array_generic (num,
1007 true,
1008 elements,
1009 NULL,
1010 sizeof(uint16_t),
1011 array_of_uint16,
1012 oid);
1013}
1014
1015
1016struct GNUNET_PQ_QueryParam
1017GNUNET_PQ_query_param_array_uint32 (
1018 unsigned int num,
1019 const uint32_t *elements,
1020 struct GNUNET_PQ_Context *db)
1021{
1022 Oid oid;
1023
1024 GNUNET_assert (GNUNET_OK ==
1025 GNUNET_PQ_get_oid_by_name (db,
1026 "int4",
1027 &oid));
1028 return query_param_array_generic (num,
1029 true,
1030 elements,
1031 NULL,
1032 sizeof(uint32_t),
1033 array_of_uint32,
1034 oid);
1035}
1036
1037
1038struct GNUNET_PQ_QueryParam
1039GNUNET_PQ_query_param_array_uint64 (
1040 unsigned int num,
1041 const uint64_t *elements,
1042 struct GNUNET_PQ_Context *db)
1043{
1044 Oid oid;
1045
1046 GNUNET_assert (GNUNET_OK ==
1047 GNUNET_PQ_get_oid_by_name (db,
1048 "int8",
1049 &oid));
1050 return query_param_array_generic (num,
1051 true,
1052 elements,
1053 NULL,
1054 sizeof(uint64_t),
1055 array_of_uint64,
1056 oid);
1057}
1058
1059
1060struct GNUNET_PQ_QueryParam
1061GNUNET_PQ_query_param_array_bytes (
1062 unsigned int num,
1063 const void *elements,
1064 const size_t *sizes,
1065 struct GNUNET_PQ_Context *db)
1066{
1067 Oid oid;
1068
1069 GNUNET_assert (GNUNET_OK ==
1070 GNUNET_PQ_get_oid_by_name (db,
1071 "bytea",
1072 &oid));
1073 return query_param_array_generic (num,
1074 true,
1075 elements,
1076 sizes,
1077 0,
1078 array_of_byte,
1079 oid);
1080}
1081
1082
1083struct GNUNET_PQ_QueryParam
1084GNUNET_PQ_query_param_array_ptrs_bytes (
1085 unsigned int num,
1086 const void *elements[static num],
1087 const size_t *sizes,
1088 struct GNUNET_PQ_Context *db)
1089{
1090 Oid oid;
1091
1092 GNUNET_assert (GNUNET_OK ==
1093 GNUNET_PQ_get_oid_by_name (db,
1094 "bytea",
1095 &oid));
1096 return query_param_array_generic (num,
1097 false,
1098 elements,
1099 sizes,
1100 0,
1101 array_of_byte,
1102 oid);
1103}
1104
1105
1106struct GNUNET_PQ_QueryParam
1107GNUNET_PQ_query_param_array_bytes_same_size (
1108 unsigned int num,
1109 const void *elements,
1110 size_t same_size,
1111 struct GNUNET_PQ_Context *db)
1112{
1113 Oid oid;
1114
1115 GNUNET_assert (GNUNET_OK ==
1116 GNUNET_PQ_get_oid_by_name (db,
1117 "bytea",
1118 &oid));
1119 return query_param_array_generic (num,
1120 true,
1121 elements,
1122 NULL,
1123 same_size,
1124 array_of_byte,
1125 oid);
1126}
1127
1128
1129struct GNUNET_PQ_QueryParam
1130GNUNET_PQ_query_param_array_ptrs_bytes_same_size (
1131 unsigned int num,
1132 const void *elements[static num],
1133 size_t same_size,
1134 struct GNUNET_PQ_Context *db)
1135{
1136 Oid oid;
1137
1138 GNUNET_assert (GNUNET_OK ==
1139 GNUNET_PQ_get_oid_by_name (db,
1140 "bytea",
1141 &oid));
1142 return query_param_array_generic (num,
1143 false,
1144 elements,
1145 NULL,
1146 same_size,
1147 array_of_byte,
1148 oid);
1149}
1150
1151
1152struct GNUNET_PQ_QueryParam
1153GNUNET_PQ_query_param_array_string (
1154 unsigned int num,
1155 const char *elements,
1156 struct GNUNET_PQ_Context *db)
1157{
1158 Oid oid;
1159
1160 GNUNET_assert (GNUNET_OK ==
1161 GNUNET_PQ_get_oid_by_name (db,
1162 "text",
1163 &oid));
1164 return query_param_array_generic (num,
1165 true,
1166 elements,
1167 NULL,
1168 0,
1169 array_of_string,
1170 oid);
1171}
1172
1173
1174struct GNUNET_PQ_QueryParam
1175GNUNET_PQ_query_param_array_ptrs_string (
1176 unsigned int num,
1177 const char *elements[],
1178 struct GNUNET_PQ_Context *db)
1179{
1180 Oid oid;
1181
1182 GNUNET_assert (GNUNET_OK ==
1183 GNUNET_PQ_get_oid_by_name (db,
1184 "text",
1185 &oid));
1186 return query_param_array_generic (num,
1187 false,
1188 elements,
1189 NULL,
1190 0,
1191 array_of_string,
1192 oid);
1193}
1194
1195
1196struct GNUNET_PQ_QueryParam
1197GNUNET_PQ_query_param_array_abs_time (
1198 unsigned int num,
1199 const struct GNUNET_TIME_Absolute *elements,
1200 struct GNUNET_PQ_Context *db)
1201{
1202 Oid oid;
1203
1204 GNUNET_assert (GNUNET_OK ==
1205 GNUNET_PQ_get_oid_by_name (db,
1206 "int8",
1207 &oid));
1208 return query_param_array_generic (num,
1209 true,
1210 elements,
1211 NULL,
1212 sizeof(struct GNUNET_TIME_Absolute),
1213 array_of_abs_time,
1214 oid);
1215}
1216
1217
1218struct GNUNET_PQ_QueryParam
1219GNUNET_PQ_query_param_array_ptrs_abs_time (
1220 unsigned int num,
1221 const struct GNUNET_TIME_Absolute *elements[],
1222 struct GNUNET_PQ_Context *db)
1223{
1224 Oid oid;
1225
1226 GNUNET_assert (GNUNET_OK ==
1227 GNUNET_PQ_get_oid_by_name (db,
1228 "int8",
1229 &oid));
1230 return query_param_array_generic (num,
1231 false,
1232 elements,
1233 NULL,
1234 sizeof(struct GNUNET_TIME_Absolute),
1235 array_of_abs_time,
1236 oid);
1237}
1238
1239
1240struct GNUNET_PQ_QueryParam
1241GNUNET_PQ_query_param_array_rel_time (
1242 unsigned int num,
1243 const struct GNUNET_TIME_Relative *elements,
1244 struct GNUNET_PQ_Context *db)
1245{
1246 Oid oid;
1247
1248 GNUNET_assert (GNUNET_OK ==
1249 GNUNET_PQ_get_oid_by_name (db,
1250 "int8",
1251 &oid));
1252 return query_param_array_generic (num,
1253 true,
1254 elements,
1255 NULL,
1256 sizeof(struct GNUNET_TIME_Relative),
1257 array_of_abs_time,
1258 oid);
1259}
1260
1261
1262struct GNUNET_PQ_QueryParam
1263GNUNET_PQ_query_param_array_ptrs_rel_time (
1264 unsigned int num,
1265 const struct GNUNET_TIME_Relative *elements[],
1266 struct GNUNET_PQ_Context *db)
1267{
1268 Oid oid;
1269
1270 GNUNET_assert (GNUNET_OK ==
1271 GNUNET_PQ_get_oid_by_name (db,
1272 "int8",
1273 &oid));
1274 return query_param_array_generic (num,
1275 false,
1276 elements,
1277 NULL,
1278 sizeof(struct GNUNET_TIME_Relative),
1279 array_of_abs_time,
1280 oid);
1281}
1282
1283
1284struct GNUNET_PQ_QueryParam
1285GNUNET_PQ_query_param_array_timestamp (
1286 unsigned int num,
1287 const struct GNUNET_TIME_Timestamp *elements,
1288 struct GNUNET_PQ_Context *db)
1289{
1290 Oid oid;
1291
1292 GNUNET_assert (GNUNET_OK ==
1293 GNUNET_PQ_get_oid_by_name (db,
1294 "int8",
1295 &oid));
1296 return query_param_array_generic (num,
1297 true,
1298 elements,
1299 NULL,
1300 sizeof(struct GNUNET_TIME_Timestamp),
1301 array_of_timestamp,
1302 oid);
1303}
1304
1305
1306struct GNUNET_PQ_QueryParam
1307GNUNET_PQ_query_param_array_ptrs_timestamp (
1308 unsigned int num,
1309 const struct GNUNET_TIME_Timestamp *elements[],
1310 struct GNUNET_PQ_Context *db)
1311{
1312 Oid oid;
1313
1314 GNUNET_assert (GNUNET_OK ==
1315 GNUNET_PQ_get_oid_by_name (db,
1316 "int8",
1317 &oid));
1318 return query_param_array_generic (num,
1319 false,
1320 elements,
1321 NULL,
1322 sizeof(struct GNUNET_TIME_Timestamp),
1323 array_of_timestamp,
1324 oid);
1325}
1326
1327
1328/* end of pq_query_helper.c */