pg_lookup_spent_tokens_by_order.c (5052B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024 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 backenddb/pg_lookup_spent_tokens_by_order.c 18 * @brief Implementation of the lookup_spent_tokens_by_order function for Postgres 19 * @author Christian Blättler 20 */ 21 #include "platform.h" 22 #include <taler/taler_error_codes.h> 23 #include <taler/taler_dbevents.h> 24 #include <taler/taler_pq_lib.h> 25 #include "pg_lookup_spent_tokens_by_order.h" 26 #include "pg_helper.h" 27 #include "taler_merchantdb_plugin.h" 28 29 /** 30 * Closure for lookup_spent_tokens_by_order_cb(). 31 */ 32 struct LookupSpentTokensByOrderContext 33 { 34 35 /** 36 * Plugin context. 37 */ 38 struct PostgresClosure *pg; 39 40 /** 41 * Function to call with all results. 42 */ 43 TALER_MERCHANTDB_UsedTokensCallback cb; 44 45 /** 46 * Closure for @e cb. 47 */ 48 void *cb_cls; 49 50 /** 51 * Set to the query result. 52 */ 53 enum GNUNET_DB_QueryStatus qs; 54 }; 55 56 57 /** 58 * Function to be called with the results of a SELECT statement 59 * that has returned @a num_results results. 60 * 61 * @param cls of type `struct LookupSpentTokensByOrderContext *` 62 * @param result the postgres result 63 * @param num_results the number of results in @a result 64 */ 65 static void 66 lookup_spent_tokens_by_order_cb (void *cls, 67 PGresult *result, 68 unsigned int num_results) 69 { 70 struct LookupSpentTokensByOrderContext *ctx = cls; 71 72 for (unsigned int i = 0; i<num_results; i++) 73 { 74 uint64_t spent_token_serial; 75 struct TALER_PrivateContractHashP h_contract_terms; 76 struct TALER_TokenIssuePublicKeyHashP h_issue_pub; 77 struct TALER_TokenUsePublicKeyP use_pub; 78 struct TALER_TokenUseSignatureP use_sig; 79 struct TALER_TokenIssueSignature issue_sig; 80 struct GNUNET_PQ_ResultSpec rs[] = { 81 GNUNET_PQ_result_spec_uint64 ("spent_token_serial", 82 &spent_token_serial), 83 GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", 84 &h_contract_terms), 85 GNUNET_PQ_result_spec_auto_from_type ("h_pub", 86 &h_issue_pub), 87 GNUNET_PQ_result_spec_auto_from_type ("token_pub", 88 &use_pub), 89 GNUNET_PQ_result_spec_auto_from_type ("token_sig", 90 &use_sig), 91 GNUNET_PQ_result_spec_unblinded_sig ("blind_sig", 92 &issue_sig.signature), 93 GNUNET_PQ_result_spec_end 94 }; 95 96 if (GNUNET_OK != 97 GNUNET_PQ_extract_result (result, 98 rs, 99 i)) 100 { 101 GNUNET_break (0); 102 ctx->qs = GNUNET_DB_STATUS_HARD_ERROR; 103 return; 104 } 105 ctx->cb (ctx->cb_cls, 106 spent_token_serial, 107 &h_contract_terms, 108 &h_issue_pub, 109 &use_pub, 110 &use_sig, 111 &issue_sig); 112 GNUNET_PQ_cleanup_result (rs); 113 } 114 ctx->qs = num_results; 115 } 116 117 118 enum GNUNET_DB_QueryStatus 119 TMH_PG_lookup_spent_tokens_by_order (void *cls, 120 uint64_t order_serial, 121 TALER_MERCHANTDB_UsedTokensCallback cb, 122 void *cb_cls) 123 { 124 struct PostgresClosure *pg = cls; 125 struct LookupSpentTokensByOrderContext ctx = { 126 .pg = pg, 127 .cb = cb, 128 .cb_cls = cb_cls 129 }; 130 struct GNUNET_PQ_QueryParam params[] = { 131 GNUNET_PQ_query_param_uint64 (&order_serial), 132 GNUNET_PQ_query_param_end 133 }; 134 enum GNUNET_DB_QueryStatus qs; 135 136 check_connection (pg); 137 PREPARE (pg, 138 "lookup_spent_tokens_by_order", 139 "SELECT" 140 " spent_token_serial" 141 ",h_contract_terms" 142 ",h_pub" 143 ",token_pub" 144 ",token_sig" 145 ",blind_sig" 146 " FROM merchant_used_tokens" 147 " JOIN merchant_contract_terms" 148 " USING (h_contract_terms)" 149 " JOIN merchant_token_family_keys" 150 " USING (token_family_key_serial)" 151 " WHERE order_serial=$1"); 152 153 qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, 154 "lookup_spent_tokens_by_order", 155 params, 156 &lookup_spent_tokens_by_order_cb, 157 &ctx); 158 159 if (qs < 0) 160 return qs; 161 return ctx.qs; 162 }