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