Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 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 src/backenddb/iterate_pending_webhooks.c
18 : * @brief Implementation of the iterate_pending_webhooks function for Postgres
19 : * @author Iván Ávalos
20 : */
21 : #include "platform.h"
22 : #include <taler/taler_pq_lib.h>
23 : #include "merchant-database/iterate_pending_webhooks.h"
24 : #include "helper.h"
25 :
26 : /**
27 : * Context used for lookup_pending_webhooks_cb().
28 : */
29 : struct LookupPendingWebhookContext
30 : {
31 : /**
32 : * Function to call with the results.
33 : */
34 : TALER_MERCHANTDB_PendingWebhooksCallback 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 webhook.
51 : *
52 : * @param[in,out] cls of type `struct LookupPendingWebhookContext *`
53 : * @param result the postgres result
54 : * @param num_results the number of results in @a result
55 : */
56 : static void
57 204 : lookup_pending_webhooks_cb (void *cls,
58 : PGresult *result,
59 : unsigned int num_results)
60 : {
61 204 : struct LookupPendingWebhookContext *pwlc = cls;
62 :
63 221 : for (unsigned int i = 0; i < num_results; i++)
64 : {
65 : uint64_t webhook_pending_serial;
66 : struct GNUNET_TIME_Absolute next_attempt;
67 : uint32_t retries;
68 : char *url;
69 : char *http_method;
70 17 : char *header = NULL;
71 17 : char *body = NULL;
72 17 : struct GNUNET_PQ_ResultSpec rs[] = {
73 17 : GNUNET_PQ_result_spec_uint64 ("webhook_pending_serial",
74 : &webhook_pending_serial),
75 17 : GNUNET_PQ_result_spec_absolute_time ("next_attempt",
76 : &next_attempt),
77 17 : GNUNET_PQ_result_spec_uint32 ("retries",
78 : &retries),
79 17 : GNUNET_PQ_result_spec_string ("url",
80 : &url),
81 17 : GNUNET_PQ_result_spec_string ("http_method",
82 : &http_method),
83 17 : GNUNET_PQ_result_spec_allow_null (
84 : GNUNET_PQ_result_spec_string ("header",
85 : &header),
86 : NULL),
87 17 : GNUNET_PQ_result_spec_allow_null (
88 : GNUNET_PQ_result_spec_string ("body",
89 : &body),
90 : NULL),
91 : GNUNET_PQ_result_spec_end
92 : };
93 :
94 17 : if (GNUNET_OK !=
95 17 : GNUNET_PQ_extract_result (result,
96 : rs,
97 : i))
98 : {
99 0 : GNUNET_break (0);
100 0 : pwlc->extract_failed = true;
101 0 : return;
102 : }
103 17 : pwlc->cb (pwlc->cb_cls,
104 : webhook_pending_serial,
105 : next_attempt,
106 : retries,
107 : url,
108 : http_method,
109 : header,
110 : body);
111 17 : GNUNET_PQ_cleanup_result (rs);
112 : }
113 : }
114 :
115 :
116 : enum GNUNET_DB_QueryStatus
117 114 : TALER_MERCHANTDB_iterate_pending_webhooks (
118 : struct TALER_MERCHANTDB_PostgresContext *pg,
119 : uint64_t limit,
120 : TALER_MERCHANTDB_PendingWebhooksCallback cb,
121 : void *cb_cls)
122 : {
123 114 : struct LookupPendingWebhookContext pwlc = {
124 : .cb = cb,
125 : .cb_cls = cb_cls,
126 : .extract_failed = false,
127 : };
128 114 : struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
129 114 : struct GNUNET_PQ_QueryParam params[] = {
130 114 : GNUNET_PQ_query_param_absolute_time (&now),
131 114 : GNUNET_PQ_query_param_uint64 (&limit),
132 : GNUNET_PQ_query_param_end
133 : };
134 : enum GNUNET_DB_QueryStatus qs;
135 :
136 114 : PREPARE (pg,
137 : "iterate_pending_webhooks",
138 : "SELECT"
139 : " webhook_pending_serial"
140 : " ,next_attempt"
141 : " ,retries"
142 : " ,url"
143 : " ,http_method"
144 : " ,header"
145 : " ,body"
146 : " FROM merchant.merchant_pending_webhooks"
147 : " WHERE next_attempt <= $1"
148 : " ORDER BY next_attempt ASC"
149 : " LIMIT $2");
150 114 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
151 : "iterate_pending_webhooks",
152 : params,
153 : &lookup_pending_webhooks_cb,
154 : &pwlc);
155 114 : if (pwlc.extract_failed)
156 0 : return GNUNET_DB_STATUS_HARD_ERROR;
157 114 : return qs;
158 : }
159 :
160 :
161 : enum GNUNET_DB_QueryStatus
162 90 : TALER_MERCHANTDB_iterate_pending_webhooks_next (
163 : struct TALER_MERCHANTDB_PostgresContext *pg,
164 : TALER_MERCHANTDB_PendingWebhooksCallback cb,
165 : void *cb_cls)
166 : {
167 90 : struct LookupPendingWebhookContext pwlc = {
168 : .cb = cb,
169 : .cb_cls = cb_cls,
170 : .extract_failed = false,
171 : };
172 90 : struct GNUNET_PQ_QueryParam params_null[] = {
173 : GNUNET_PQ_query_param_end
174 : };
175 : enum GNUNET_DB_QueryStatus qs;
176 :
177 90 : PREPARE (pg,
178 : "iterate_pending_webhooks_next",
179 : "SELECT"
180 : " webhook_pending_serial"
181 : " ,next_attempt"
182 : " ,retries"
183 : " ,url"
184 : " ,http_method"
185 : " ,header"
186 : " ,body"
187 : " FROM merchant.merchant_pending_webhooks"
188 : " ORDER BY next_attempt ASC"
189 : " LIMIT 1");
190 90 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
191 : "iterate_pending_webhooks_next",
192 : params_null,
193 : &lookup_pending_webhooks_cb,
194 : &pwlc);
195 90 : if (pwlc.extract_failed)
196 0 : return GNUNET_DB_STATUS_HARD_ERROR;
197 90 : return qs;
198 : }
|