diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 6938ee0ab..93ea09cd8 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -293,6 +293,15 @@ TEH_PG_internal_setup (struct PostgresClosure *pg) NULL); if (NULL == db_conn) return GNUNET_SYSERR; + + if (GNUNET_OK != TALER_PQ_load_oids_for_composite_types (db_conn)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to load OIDs for composite types\n"); + GNUNET_PQ_disconnect (db_conn); + return GNUNET_SYSERR; + } + pg->prep_gen++; pg->conn = db_conn; } diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h index 45889435a..17b01b0ad 100644 --- a/src/include/taler_exchangedb_lib.h +++ b/src/include/taler_exchangedb_lib.h @@ -46,7 +46,6 @@ TALER_EXCHANGEDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg); void TALER_EXCHANGEDB_plugin_unload (struct TALER_EXCHANGEDB_Plugin *plugin); - /** * Information about an account from the configuration. */ diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index 43561703b..051962b2b 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -19,15 +19,42 @@ * @author Sree Harsha Totakura * @author Florian Dold * @author Christian Grothoff + * @author Özgür Kesim */ #ifndef TALER_PQ_LIB_H_ #define TALER_PQ_LIB_H_ #include #include +#include #include #include "taler_util.h" +/** + * Enumerates the composite types that Taler defines in Postgres. + * The corresponding OIDs (which are assigned by postgres at time of + * declaration) are stored in TALER_PQ_CompositeOIDs. + */ +enum TALER_PQ_CompositeType +{ + TALER_PQ_CompositeAmount, + TALER_PQ_CompositeMAX /* MUST be last */ +}; + +/** + * The correspondence of the Composite types and their OID in Postgres + */ +extern Oid TALER_PQ_CompositeOIDs[TALER_PQ_CompositeMAX]; + +/** + * Initialize the list of OIDs in TALER_PQ_CompositeOIDs. MUST be called + * before any composite type is used in arrays-specs/-params. + * + * @return GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +TALER_PQ_load_oids_for_composite_types (struct GNUNET_PQ_Context *db); + /** * Generate query parameter for a currency, consisting of the three * components "value", "fraction" and "currency" in this order. The diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am index b0717dfc7..23fd34dbc 100644 --- a/src/pq/Makefile.am +++ b/src/pq/Makefile.am @@ -10,6 +10,8 @@ lib_LTLIBRARIES = \ libtalerpq.la libtalerpq_la_SOURCES = \ + pq_common.h \ + pq_composite_types.c \ pq_query_helper.c \ pq_result_helper.c libtalerpq_la_LIBADD = \ diff --git a/src/pq/pq_common.h b/src/pq/pq_common.h index 36ba62a40..79c9d83ca 100644 --- a/src/pq/pq_common.h +++ b/src/pq/pq_common.h @@ -47,20 +47,6 @@ enum TALER_PQ_ArrayType TALER_PQ_array_of_MAX, /* must be last */ }; -/** - * The header for a postgresql array in binary format. note that this a - * simplified special case of the general structure (which contains pointers), - * as we only support one-dimensional arrays. - */ -struct TALER_PQ_ArrayHeader_P -{ - uint32_t ndim; /* number of dimensions. we only support ndim = 1 */ - uint32_t has_null; - uint32_t oid; - uint32_t dim; /* size of the array */ - uint32_t lbound; /* index value of first element in the db (default: 1). */ -} __attribute__((packed)); - /** * Memory representation of an taler amount record for Postgres. * @@ -92,5 +78,6 @@ struct TALER_PQ_Amount_P .f = htonl ((amount)->fraction) \ } + #endif /* TALER_PQ_COMMON_H_ */ /* end of pg/pq_common.h */ diff --git a/src/pq/pq_composite_types.c b/src/pq/pq_composite_types.c new file mode 100644 index 000000000..ed51ef428 --- /dev/null +++ b/src/pq/pq_composite_types.c @@ -0,0 +1,57 @@ +/* + This file is part of TALER + Copyright (C) 2023 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file pq/pq_composite_types.c + * @brief helper functions for Taler-specific libpq (PostGres) interactions with composite types + * @author Özgür Kesim + */ +#include "platform.h" +#include +#include +#include +#include "taler_pq_lib.h" +#include "pq_common.h" + +Oid TALER_PQ_CompositeOIDs[TALER_PQ_CompositeMAX] = {0}; + +enum GNUNET_GenericReturnValue +TALER_PQ_load_oids_for_composite_types ( + struct GNUNET_PQ_Context *db) +{ + static char *names[] = { + [TALER_PQ_CompositeAmount] = "taler_amount" + }; + size_t num = sizeof(names) / sizeof(names[0]); + + GNUNET_static_assert (num == TALER_PQ_CompositeMAX); + + for (size_t i = 0; i < num; i++) + { + enum GNUNET_GenericReturnValue ret; + enum TALER_PQ_CompositeType typ = i; + ret = GNUNET_PQ_get_oid_by_name (db, + names[i], + &TALER_PQ_CompositeOIDs[typ]); + if (GNUNET_OK != ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to load OID for type %s\n", + names[i]); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 9ada23575..6d8318b41 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -872,7 +872,7 @@ qconv_array ( RETURN_UNLESS ((0 == num) || (y / num == x)); /* size of header */ - total_size = x = sizeof(struct TALER_PQ_ArrayHeader_P); + total_size = x = sizeof(struct GNUNET_PQ_ArrayHeader_P); total_size += y; RETURN_UNLESS (total_size >= x); @@ -941,7 +941,7 @@ qconv_array ( /* Write data */ { char *out = elements; - struct TALER_PQ_ArrayHeader_P h = { + struct GNUNET_PQ_ArrayHeader_P h = { .ndim = htonl (1), /* We only support one-dimensional arrays */ .has_null = htonl (0), /* We do not support NULL entries in arrays */ .lbound = htonl (1), /* Default start index value */ diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 3ef2e71fb..ac1642bae 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -1166,7 +1166,7 @@ extract_array_generic ( int data_sz; char *data; void *out = NULL; - struct TALER_PQ_ArrayHeader_P header; + struct GNUNET_PQ_ArrayHeader_P header; int col_num; GNUNET_assert (NULL != dst); @@ -1192,8 +1192,8 @@ extract_array_generic ( FAIL_IF (NULL == data); { - struct TALER_PQ_ArrayHeader_P *h = - (struct TALER_PQ_ArrayHeader_P *) data; + struct GNUNET_PQ_ArrayHeader_P *h = + (struct GNUNET_PQ_ArrayHeader_P *) data; header.ndim = ntohl (h->ndim); header.has_null = ntohl (h->has_null); diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index a944cb1e0..9f18e7675 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -194,6 +194,16 @@ main (int argc, GNUNET_PQ_disconnect (conn); return 1; } + + ret = TALER_PQ_load_oids_for_composite_types (conn); + if (GNUNET_OK != ret) + { + fprintf (stderr, + "Failed to load oids for composites\n"); + GNUNET_PQ_disconnect (conn); + return 1; + } + ret = run_queries (conn); { struct GNUNET_PQ_ExecuteStatement ds[] = {