commit 6c81dc288274027abcd8903764be401e3e43339c
parent 517cad11b8f63beb001ad0d3634fad88269e679f
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 8 Mar 2024 22:17:45 +0100
PQ: add int64 data type support
Diffstat:
4 files changed, 173 insertions(+), 10 deletions(-)
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h
@@ -577,7 +577,7 @@ GNUNET_PQ_query_param_uint32 (const uint32_t *x);
/**
- * Generate query parameter for an uint16_t in host byte order.
+ * Generate query parameter for an uint64_t in host byte order.
*
* @param x pointer to the query parameter to pass
* @return query parameter to use
@@ -586,6 +586,16 @@ struct GNUNET_PQ_QueryParam
GNUNET_PQ_query_param_uint64 (const uint64_t *x);
+/**
+ * Generate query parameter for an int64_t in host byte order.
+ *
+ * @param x pointer to the query parameter to pass
+ * @return query parameter to use
+ */
+struct GNUNET_PQ_QueryParam
+GNUNET_PQ_query_param_int64 (const int64_t *x);
+
+
/* ************************* pq_result_helper.c functions ************************ */
@@ -895,6 +905,19 @@ struct GNUNET_PQ_ResultSpec
GNUNET_PQ_result_spec_uint64 (const char *name,
uint64_t *u64);
+
+/**
+ * int64_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] i64 where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+GNUNET_PQ_result_spec_int64 (const char *name,
+ int64_t *i64);
+
+
/**
* array of bool expected.
*
diff --git a/src/lib/pq/pq_query_helper.c b/src/lib/pq/pq_query_helper.c
@@ -338,6 +338,63 @@ GNUNET_PQ_query_param_uint64 (const uint64_t *x)
* @return -1 on error, number of offsets used in @a scratch otherwise
*/
static int
+qconv_int64 (void *cls,
+ const void *data,
+ size_t data_len,
+ void *param_values[],
+ int param_lengths[],
+ int param_formats[],
+ unsigned int param_length,
+ void *scratch[],
+ unsigned int scratch_length)
+{
+ const int64_t *u_hbo = data;
+ int64_t *u_nbo;
+
+ (void) scratch;
+ (void) scratch_length;
+ GNUNET_break (NULL == cls);
+ if (1 != param_length)
+ return -1;
+ u_nbo = GNUNET_new (int64_t);
+ scratch[0] = u_nbo;
+ *u_nbo = GNUNET_htonll (*u_hbo);
+ param_values[0] = (void *) u_nbo;
+ param_lengths[0] = sizeof(int64_t);
+ param_formats[0] = 1;
+ return 1;
+}
+
+
+struct GNUNET_PQ_QueryParam
+GNUNET_PQ_query_param_int64 (const int64_t *x)
+{
+ struct GNUNET_PQ_QueryParam res = {
+ .conv = &qconv_int64,
+ .data = x,
+ .size = sizeof(*x),
+ .num_params = 1
+ };
+
+ return res;
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param[out] param_values SQL data to set
+ * @param[out] param_lengths SQL length data to set
+ * @param[out] param_formats SQL format data to set
+ * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
+ * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
+ * @param scratch_length number of entries left in @a scratch
+ * @return -1 on error, number of offsets used in @a scratch otherwise
+ */
+static int
qconv_rsa_public_key (void *cls,
const void *data,
size_t data_len,
diff --git a/src/lib/pq/pq_result_helper.c b/src/lib/pq/pq_result_helper.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V.
+ Copyright (C) 2014-2024 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -1122,6 +1122,90 @@ GNUNET_PQ_result_spec_uint64 (const char *name,
/**
+ * Extract data from a Postgres database @a result at row @a row.
+ *
+ * @param cls closure
+ * @param result where to extract data from
+ * @param row row to extract data from
+ * @param fname name (or prefix) of the fields to extract from
+ * @param[in,out] dst_size where to store size of result, may be NULL
+ * @param[out] dst where to store the result
+ * @return
+ * #GNUNET_YES if all results could be extracted
+ * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
+ */
+static enum GNUNET_GenericReturnValue
+extract_int64 (void *cls,
+ PGresult *result,
+ int row,
+ const char *fname,
+ size_t *dst_size,
+ void *dst)
+{
+ int64_t *udst = dst;
+ const int64_t *res;
+ int fnum;
+
+ (void) cls;
+ fnum = PQfnumber (result,
+ fname);
+ if (fnum < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Field %s missing in result\n",
+ fname);
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (PQgetisnull (result,
+ row,
+ fnum))
+ return GNUNET_NO;
+
+ GNUNET_assert (NULL != dst);
+ if (sizeof(int64_t) != *dst_size)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (sizeof(int64_t) !=
+ PQgetlength (result,
+ row,
+ fnum))
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Got length %u for field `%s'\n",
+ PQgetlength (result,
+ row,
+ fnum),
+ fname);
+ return GNUNET_SYSERR;
+ }
+ res = (int64_t *) PQgetvalue (result,
+ row,
+ fnum);
+ *udst = GNUNET_ntohll (*res);
+ return GNUNET_OK;
+}
+
+
+struct GNUNET_PQ_ResultSpec
+GNUNET_PQ_result_spec_int64 (const char *name,
+ int64_t *i64)
+{
+ struct GNUNET_PQ_ResultSpec res = {
+ .conv = &extract_int64,
+ .dst = (void *) i64,
+ .dst_size = sizeof(*i64),
+ .fname = name
+ };
+
+ return res;
+}
+
+
+/**
* Closure for the array result specifications. Contains type information
* for the generic parser extract_array_generic and out-pointers for the results.
*/
@@ -1180,13 +1264,13 @@ extract_array_generic (
*((void **) dst) = NULL;
#define FAIL_IF(cond) \
- do { \
- if ((cond)) \
- { \
- GNUNET_break (! (cond)); \
- goto FAIL; \
- } \
- } while (0)
+ do { \
+ if ((cond)) \
+ { \
+ GNUNET_break (! (cond)); \
+ goto FAIL; \
+ } \
+ } while (0)
col_num = PQfnumber (result, fname);
FAIL_IF (0 > col_num);
diff --git a/src/lib/util/gnunet_error_codes.c b/src/lib/util/gnunet_error_codes.c
@@ -17,7 +17,6 @@
SPDX-License-Identifier: AGPL3.0-or-later
*/
-#include "platform.h"
#include "gnunet_error_codes.h"
#include <stddef.h>
#include <microhttpd.h>