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_above_serial_id.c
18 : * @brief Implementation of the iterate_pending_webhooks_above_serial_id 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_above_serial_id.h"
24 : #include "helper.h"
25 :
26 : /**
27 : * Context used for lookup_all_webhooks_cb().
28 : */
29 : struct LookupAllWebhookContext
30 : {
31 : /**
32 : * Function to call with the results.
33 : */
34 : TALER_MERCHANTDB_AllWebhooksCallback 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 LookupAllWebhookContext *`
53 : * @param result the postgres result
54 : * @param num_results the number of results in @a result
55 : */
56 : static void
57 4 : lookup_all_webhooks_cb (void *cls,
58 : PGresult *result,
59 : unsigned int num_results)
60 : {
61 4 : struct LookupAllWebhookContext *pwlc = cls;
62 :
63 10 : 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 6 : char *header = NULL;
71 6 : char *body = NULL;
72 6 : struct GNUNET_PQ_ResultSpec rs[] = {
73 6 : GNUNET_PQ_result_spec_uint64 ("out_webhook_pending_serial",
74 : &webhook_pending_serial),
75 6 : GNUNET_PQ_result_spec_absolute_time ("out_next_attempt",
76 : &next_attempt),
77 6 : GNUNET_PQ_result_spec_uint32 ("out_retries",
78 : &retries),
79 6 : GNUNET_PQ_result_spec_string ("out_url",
80 : &url),
81 6 : GNUNET_PQ_result_spec_string ("out_http_method",
82 : &http_method),
83 6 : GNUNET_PQ_result_spec_allow_null (
84 : GNUNET_PQ_result_spec_string ("out_header",
85 : &header),
86 : NULL),
87 6 : GNUNET_PQ_result_spec_allow_null (
88 : GNUNET_PQ_result_spec_string ("out_body",
89 : &body),
90 : NULL),
91 : GNUNET_PQ_result_spec_end
92 : };
93 :
94 6 : if (GNUNET_OK !=
95 6 : 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 6 : pwlc->cb (pwlc->cb_cls,
104 : webhook_pending_serial,
105 : next_attempt,
106 : retries,
107 : url,
108 : http_method,
109 : header,
110 : body);
111 6 : GNUNET_PQ_cleanup_result (rs);
112 : }
113 : }
114 :
115 :
116 : enum GNUNET_DB_QueryStatus
117 4 : TALER_MERCHANTDB_iterate_pending_webhooks_above_serial_id (
118 : struct TALER_MERCHANTDB_PostgresContext *pg,
119 : const char *instance_id,
120 : uint64_t min_row,
121 : uint32_t max_results,
122 : TALER_MERCHANTDB_AllWebhooksCallback cb,
123 : void *cb_cls)
124 : {
125 4 : struct LookupAllWebhookContext pwlc = {
126 : .cb = cb,
127 : .cb_cls = cb_cls,
128 : .extract_failed = false,
129 : };
130 4 : uint64_t max_results64 = max_results;
131 4 : struct GNUNET_PQ_QueryParam params[] = {
132 4 : GNUNET_PQ_query_param_uint64 (&pg->current_merchant_serial),
133 4 : GNUNET_PQ_query_param_uint64 (&min_row),
134 4 : GNUNET_PQ_query_param_uint64 (&max_results64),
135 : GNUNET_PQ_query_param_end
136 : };
137 : enum GNUNET_DB_QueryStatus qs;
138 :
139 4 : GNUNET_assert (NULL != pg->current_merchant_id);
140 4 : GNUNET_assert (0 == strcmp (instance_id,
141 : pg->current_merchant_id));
142 4 : PREPARE (pg,
143 : "iterate_pending_webhooks_above_serial_id",
144 : " SELECT"
145 : " webhook_pending_serial AS out_webhook_pending_serial"
146 : " ,next_attempt AS out_next_attempt"
147 : " ,retries AS out_retries"
148 : " ,url AS out_url"
149 : " ,http_method AS out_http_method"
150 : " ,header AS out_header"
151 : " ,body AS out_body"
152 : " FROM merchant.merchant_pending_webhooks"
153 : " WHERE merchant_serial = $1"
154 : " AND webhook_pending_serial > $2"
155 : " ORDER BY webhook_pending_serial ASC"
156 : " LIMIT $3");
157 4 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
158 : "iterate_pending_webhooks_above_serial_id",
159 : params,
160 : &lookup_all_webhooks_cb,
161 : &pwlc);
162 4 : if (pwlc.extract_failed)
163 0 : return GNUNET_DB_STATUS_HARD_ERROR;
164 4 : return qs;
165 : }
|