select_exchanges.c (4351B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2026 Taler Systems SA 4 5 TALER 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 TALER 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 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file src/backenddb/select_exchanges.c 18 * @brief Implementation of the select_exchanges function for Postgres 19 * @author Christian Grothoff 20 */ 21 #include "platform.h" 22 #include <taler/taler_pq_lib.h> 23 #include "merchant-database/select_exchanges.h" 24 #include "helper.h" 25 26 /** 27 * Context used for TALER_MERCHANTDB_lookup_exchanges(). 28 */ 29 struct LookupExchangesContext 30 { 31 /** 32 * Function to call with the results. 33 */ 34 TALER_MERCHANTDB_ExchangesCallback cb; 35 36 /** 37 * Closure for @a cb. 38 */ 39 void *cb_cls; 40 41 /** 42 * Did database result extraction fail? 43 */ 44 bool extract_failed; 45 }; 46 47 48 /** 49 * Function to be called with the results of a SELECT statement 50 * that has returned @a num_results results about product exchanges. 51 * 52 * @param[in,out] cls of type `struct LookupExchangesContext *` 53 * @param result the postgres result 54 * @param num_results the number of results in @a result 55 */ 56 static void 57 lookup_exchanges_cb (void *cls, 58 PGresult *result, 59 unsigned int num_results) 60 { 61 struct LookupExchangesContext *plc = cls; 62 63 for (unsigned int i = 0; i < num_results; i++) 64 { 65 char *exchange_url; 66 json_t *keys = NULL; 67 struct GNUNET_TIME_Absolute next_download; 68 struct GNUNET_TIME_Absolute keys_expiration; 69 uint32_t hc; 70 uint32_t ec; 71 struct GNUNET_PQ_ResultSpec rs[] = { 72 GNUNET_PQ_result_spec_absolute_time ("first_retry", 73 &next_download), 74 GNUNET_PQ_result_spec_absolute_time ("expiration_time", 75 &keys_expiration), 76 GNUNET_PQ_result_spec_string ("exchange_url", 77 &exchange_url), 78 GNUNET_PQ_result_spec_allow_null ( 79 TALER_PQ_result_spec_json ("keys_json", 80 &keys), 81 NULL), 82 GNUNET_PQ_result_spec_uint32 ("exchange_http_status", 83 &hc), 84 GNUNET_PQ_result_spec_uint32 ("exchange_ec_code", 85 &ec), 86 GNUNET_PQ_result_spec_end 87 }; 88 89 if (GNUNET_OK != 90 GNUNET_PQ_extract_result (result, 91 rs, 92 i)) 93 { 94 GNUNET_break (0); 95 plc->extract_failed = true; 96 return; 97 } 98 plc->cb (plc->cb_cls, 99 exchange_url, 100 keys, 101 next_download, 102 keys_expiration, 103 (unsigned int) hc, 104 (enum TALER_ErrorCode) ec); 105 GNUNET_PQ_cleanup_result (rs); 106 } 107 } 108 109 110 enum GNUNET_DB_QueryStatus 111 TALER_MERCHANTDB_select_exchanges ( 112 struct TALER_MERCHANTDB_PostgresContext *pg, 113 TALER_MERCHANTDB_ExchangesCallback cb, 114 void *cb_cls) 115 { 116 struct LookupExchangesContext plc = { 117 .cb = cb, 118 .cb_cls = cb_cls, 119 /* Can be overwritten by the lookup_exchanges_cb */ 120 .extract_failed = false, 121 }; 122 struct GNUNET_PQ_QueryParam params[] = { 123 GNUNET_PQ_query_param_end 124 }; 125 enum GNUNET_DB_QueryStatus qs; 126 127 check_connection (pg); 128 PREPARE (pg, 129 "select_exchanges", 130 "SELECT" 131 " exchange_url" 132 " ,first_retry" 133 " ,expiration_time" 134 " ,keys_json::TEXT" 135 " ,exchange_http_status" 136 " ,exchange_ec_code" 137 " FROM merchant.merchant_exchange_keys"); 138 qs = GNUNET_PQ_eval_prepared_multi_select ( 139 pg->conn, 140 "select_exchanges", 141 params, 142 &lookup_exchanges_cb, 143 &plc); 144 /* If there was an error inside lookup_exchanges_cb, return a hard error. */ 145 if (plc.extract_failed) 146 { 147 GNUNET_break (0); 148 return GNUNET_DB_STATUS_HARD_ERROR; 149 } 150 return qs; 151 }