Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2022-2023 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 exchangedb/select_coin_deposits_above_serial_id.c
18 : * @brief Implementation of the select_coin_deposits_above_serial_id function for Postgres
19 : * @author Christian Grothoff
20 : */
21 : #include "taler/taler_pq_lib.h"
22 : #include "exchange-database/select_coin_deposits_above_serial_id.h"
23 : #include "helper.h"
24 :
25 : /**
26 : * Closure for #deposit_serial_helper_cb().
27 : */
28 : struct CoinDepositSerialContext
29 : {
30 :
31 : /**
32 : * Callback to call.
33 : */
34 : TALER_EXCHANGEDB_DepositCallback cb;
35 :
36 : /**
37 : * Closure for @e cb.
38 : */
39 : void *cb_cls;
40 :
41 : /**
42 : * Plugin context.
43 : */
44 : struct TALER_EXCHANGEDB_PostgresContext *pg;
45 :
46 : /**
47 : * Status code, set to #GNUNET_SYSERR on hard errors.
48 : */
49 : enum GNUNET_GenericReturnValue status;
50 : };
51 :
52 :
53 : /**
54 : * Helper function to be called with the results of a SELECT statement
55 : * that has returned @a num_results results.
56 : *
57 : * @param cls closure of type `struct CoinDepositSerialContext`
58 : * @param result the postgres result
59 : * @param num_results the number of results in @a result
60 : */
61 : static void
62 4 : coin_deposit_serial_helper_cb (void *cls,
63 : PGresult *result,
64 : unsigned int num_results)
65 : {
66 4 : struct CoinDepositSerialContext *dsc = cls;
67 4 : struct TALER_EXCHANGEDB_PostgresContext *pg = dsc->pg;
68 :
69 4 : for (unsigned int i = 0; i<num_results; i++)
70 : {
71 : struct TALER_EXCHANGEDB_Deposit deposit;
72 : struct GNUNET_TIME_Timestamp exchange_timestamp;
73 : struct TALER_DenominationPublicKey denom_pub;
74 : bool done;
75 : uint64_t rowid;
76 0 : struct GNUNET_PQ_ResultSpec rs[] = {
77 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
78 : &deposit.amount_with_fee),
79 0 : GNUNET_PQ_result_spec_timestamp ("wallet_timestamp",
80 : &deposit.timestamp),
81 0 : GNUNET_PQ_result_spec_timestamp ("exchange_timestamp",
82 : &exchange_timestamp),
83 0 : GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
84 : &deposit.merchant_pub),
85 0 : TALER_PQ_result_spec_denom_pub ("denom_pub",
86 : &denom_pub),
87 0 : GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
88 : &deposit.coin.coin_pub),
89 0 : GNUNET_PQ_result_spec_allow_null (
90 : GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
91 : &deposit.coin.h_age_commitment),
92 : &deposit.coin.no_age_commitment),
93 0 : GNUNET_PQ_result_spec_allow_null (
94 : GNUNET_PQ_result_spec_auto_from_type ("wallet_data_hash",
95 : &deposit.wallet_data_hash),
96 : &deposit.no_wallet_data_hash),
97 0 : GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
98 : &deposit.csig),
99 0 : GNUNET_PQ_result_spec_timestamp ("refund_deadline",
100 : &deposit.refund_deadline),
101 0 : GNUNET_PQ_result_spec_timestamp ("wire_deadline",
102 : &deposit.wire_deadline),
103 0 : GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
104 : &deposit.h_contract_terms),
105 0 : GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
106 : &deposit.wire_salt),
107 0 : GNUNET_PQ_result_spec_string ("receiver_wire_account",
108 : &deposit.receiver_wire_account.full_payto),
109 0 : GNUNET_PQ_result_spec_bool ("done",
110 : &done),
111 0 : GNUNET_PQ_result_spec_uint64 ("coin_deposit_serial_id",
112 : &rowid),
113 : GNUNET_PQ_result_spec_end
114 : };
115 : enum GNUNET_GenericReturnValue ret;
116 :
117 0 : memset (&deposit,
118 : 0,
119 : sizeof (deposit));
120 0 : if (GNUNET_OK !=
121 0 : GNUNET_PQ_extract_result (result,
122 : rs,
123 : i))
124 : {
125 0 : GNUNET_break (0);
126 0 : dsc->status = GNUNET_SYSERR;
127 0 : return;
128 : }
129 0 : ret = dsc->cb (dsc->cb_cls,
130 : rowid,
131 : exchange_timestamp,
132 : &deposit,
133 : &denom_pub,
134 : done);
135 0 : GNUNET_PQ_cleanup_result (rs);
136 0 : if (GNUNET_OK != ret)
137 0 : break;
138 : }
139 : }
140 :
141 :
142 : enum GNUNET_DB_QueryStatus
143 4 : TALER_EXCHANGEDB_select_coin_deposits_above_serial_id (
144 : struct TALER_EXCHANGEDB_PostgresContext *pg,
145 : uint64_t serial_id,
146 : TALER_EXCHANGEDB_DepositCallback cb,
147 : void *cb_cls)
148 : {
149 4 : struct GNUNET_PQ_QueryParam params[] = {
150 4 : GNUNET_PQ_query_param_uint64 (&serial_id),
151 : GNUNET_PQ_query_param_end
152 : };
153 4 : struct CoinDepositSerialContext dsc = {
154 : .cb = cb,
155 : .cb_cls = cb_cls,
156 : .pg = pg,
157 : .status = GNUNET_OK
158 : };
159 : enum GNUNET_DB_QueryStatus qs;
160 :
161 : /* Fetch deposits with rowid '\geq' the given parameter */
162 4 : PREPARE (pg,
163 : "audit_get_coin_deposits_incr",
164 : "SELECT"
165 : " cdep.amount_with_fee"
166 : ",bdep.wallet_timestamp"
167 : ",bdep.exchange_timestamp"
168 : ",bdep.merchant_pub"
169 : ",bdep.wallet_data_hash"
170 : ",denom.denom_pub"
171 : ",kc.coin_pub"
172 : ",kc.age_commitment_hash"
173 : ",cdep.coin_sig"
174 : ",bdep.refund_deadline"
175 : ",bdep.wire_deadline"
176 : ",bdep.h_contract_terms"
177 : ",bdep.wire_salt"
178 : ",wt.payto_uri AS receiver_wire_account"
179 : ",bdep.done"
180 : ",cdep.coin_deposit_serial_id"
181 : " FROM coin_deposits cdep"
182 : " JOIN batch_deposits bdep"
183 : " USING (batch_deposit_serial_id)"
184 : " JOIN wire_targets wt"
185 : " USING (wire_target_h_payto)"
186 : " JOIN known_coins kc"
187 : " USING (coin_pub)"
188 : " JOIN denominations denom"
189 : " USING (denominations_serial)"
190 : " WHERE (coin_deposit_serial_id>=$1)"
191 : " ORDER BY coin_deposit_serial_id ASC;");
192 4 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
193 : "audit_get_coin_deposits_incr",
194 : params,
195 : &coin_deposit_serial_helper_cb,
196 : &dsc);
197 4 : if (GNUNET_OK != dsc.status)
198 0 : return GNUNET_DB_STATUS_HARD_ERROR;
199 4 : return qs;
200 : }
|