merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit e7b7ede1bb63d2dd5563dba070830587b0330bca
parent a05edcc23ab32bdc85afe5baab4cae2b3d7b1b42
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat,  7 Feb 2026 21:43:29 +0100

implement pg_select_exchanges for #10988

Diffstat:
Msrc/backenddb/Makefile.am | 1+
Asrc/backenddb/pg_select_exchanges.c | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_select_exchanges.h | 42++++++++++++++++++++++++++++++++++++++++++
Msrc/backenddb/plugin_merchantdb_postgres.c | 3+++
Msrc/include/taler_merchantdb_plugin.h | 33+++++++++++++++++++++++++++++++++
5 files changed, 225 insertions(+), 0 deletions(-)

diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am @@ -235,6 +235,7 @@ libtaler_plugin_merchantdb_postgres_la_SOURCES = \ pg_select_category.h pg_select_category.c \ pg_select_category_by_name.h pg_select_category_by_name.c \ pg_select_exchange_keys.h pg_select_exchange_keys.c \ + pg_select_exchanges.h pg_select_exchanges.c \ pg_select_login_token.h pg_select_login_token.c \ pg_select_open_transfers.h pg_select_open_transfers.c \ pg_select_otp.h pg_select_otp.c \ diff --git a/src/backenddb/pg_select_exchanges.c b/src/backenddb/pg_select_exchanges.c @@ -0,0 +1,146 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 <http://www.gnu.org/licenses/> + */ +/** + * @file backenddb/pg_select_exchanges.c + * @brief Implementation of the select_exchanges function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include <taler/taler_error_codes.h> +#include <taler/taler_dbevents.h> +#include <taler/taler_pq_lib.h> +#include "pg_select_exchanges.h" +#include "pg_helper.h" + +/** + * Context used for TMH_PG_lookup_exchanges(). + */ +struct LookupExchangesContext +{ + /** + * Function to call with the results. + */ + TALER_MERCHANTDB_ExchangesCallback cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Did database result extraction fail? + */ + bool extract_failed; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results about product exchanges. + * + * @param[in,out] cls of type `struct LookupExchangesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lookup_exchanges_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct LookupExchangesContext *plc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + char *exchange_url; + struct GNUNET_TIME_Absolute next_download; + struct GNUNET_TIME_Absolute keys_expiration; + uint32_t hc; + uint32_t ec; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_absolute_time ("first_retry", + &next_download), + GNUNET_PQ_result_spec_absolute_time ("expiration_time", + &keys_expiration), + GNUNET_PQ_result_spec_string ("exchange_url", + &exchange_url), + GNUNET_PQ_result_spec_uint32 ("exchange_http_status", + &hc), + GNUNET_PQ_result_spec_uint32 ("exchange_ec_code", + &ec), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + plc->extract_failed = true; + return; + } + plc->cb (plc->cb_cls, + exchange_url, + next_download, + keys_expiration, + (unsigned int) hc, + (enum TALER_ErrorCode) ec); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +TMH_PG_select_exchanges (void *cls, + TALER_MERCHANTDB_ExchangesCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct LookupExchangesContext plc = { + .cb = cb, + .cb_cls = cb_cls, + /* Can be overwritten by the lookup_exchanges_cb */ + .extract_failed = false, + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + check_connection (pg); + PREPARE (pg, + "select_exchanges", + "SELECT" + " exchange_url" + " ,first_retry" + " ,expiration_time" + " ,exchange_http_status" + " ,exchange_ec_code" + " FROM merchant_exchange_keys"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + "select_exchanges", + params, + &lookup_exchanges_cb, + &plc); + /* If there was an error inside lookup_exchanges_cb, return a hard error. */ + if (plc.extract_failed) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} diff --git a/src/backenddb/pg_select_exchanges.h b/src/backenddb/pg_select_exchanges.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 <http://www.gnu.org/licenses/> + */ +/** + * @file backenddb/pg_select_exchanges.h + * @brief implementation of the select_exchanges function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_SELECT_EXCHANGES_H +#define PG_SELECT_EXCHANGES_H + +#include <taler/taler_util.h> +#include <taler/taler_json_lib.h> +#include "taler_merchantdb_plugin.h" + +/** + * Call @a cb on each exchange we have in the database. + * + * @param cls closure + * @param cb callback to invoke + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +TMH_PG_select_exchanges (void *cls, + TALER_MERCHANTDB_ExchangesCallback cb, + void *cb_cls); + + +#endif diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c @@ -87,6 +87,7 @@ #include "pg_select_wirewatch_accounts.h" #include "pg_select_open_transfers.h" #include "pg_delete_exchange_accounts.h" +#include "pg_select_exchanges.h" #include "pg_select_accounts_by_exchange.h" #include "pg_insert_exchange_account.h" #include "pg_lookup_instance_auth.h" @@ -741,6 +742,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) = &TMH_PG_insert_product_group; plugin->delete_product_group = &TMH_PG_delete_product_group; + plugin->select_exchanges + = &TMH_PG_select_exchanges; plugin->update_product_group = &TMH_PG_update_product_group; plugin->select_product_groups diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h @@ -1158,6 +1158,26 @@ typedef void /** + * Function called about the ``/keys`` status of every exchange + * we are working with. + * + * @param cls closure + * @param exchange_url base URL of the exchange + * @param next_download when will be the next download + * @param keys_expiration when does the current ``/keys`` response expire + * @param http_status last HTTP status from ``/keys`` + * @param ec last error code from fetching ``/keys`` + */ +typedef void +(*TALER_MERCHANTDB_ExchangesCallback)( + void *cls, + const char *exchange_url, + struct GNUNET_TIME_Absolute next_download, + struct GNUNET_TIME_Absolute keys_expiration, + unsigned int http_status, + enum TALER_ErrorCode ec); + +/** * Results from trying to increase a refund. */ enum TALER_MERCHANTDB_RefundStatus @@ -2658,6 +2678,19 @@ struct TALER_MERCHANTDB_Plugin void *cb_cls); /** + * Call @a cb on each exchange we have in the database. + * + * @param cls closure + * @param cb callback to invoke + * @param cb_cls closure for @a cb + * @return transaction status code + */ + enum GNUNET_DB_QueryStatus + (*select_exchanges) (void *cls, + TALER_MERCHANTDB_ExchangesCallback cb, + void *cb_cls); + + /** * Lookup details about a particular product. * * @param cls closure