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 pg_get_auditor_progress.c
18 : * @brief Implementation of get_auditor_progress function
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include "taler_error_codes.h"
23 : #include "taler_dbevents.h"
24 : #include "taler_pq_lib.h"
25 : #include "pg_get_auditor_progress.h"
26 : #include "pg_helper.h"
27 :
28 :
29 : /**
30 : * Closure for #auditor_progress_cb().
31 : */
32 : struct AuditorProgressContext
33 : {
34 :
35 : /**
36 : * Where to store results.
37 : */
38 : uint64_t **dst;
39 :
40 : /**
41 : * Offset in @e dst.
42 : */
43 : unsigned int off;
44 :
45 : /**
46 : * Length of array at @e dst.
47 : */
48 : unsigned int len;
49 :
50 : /**
51 : * Plugin context.
52 : */
53 : struct PostgresClosure *pg;
54 :
55 : /**
56 : * Set to true on failure.
57 : */
58 : bool failure;
59 : };
60 :
61 :
62 : /**
63 : * Helper function for #TAH_PG_get_auditor_progress().
64 : * To be called with the results of a SELECT statement
65 : * that has returned @a num_results results.
66 : *
67 : * @param cls closure of type `struct AuditorProgressContext *`
68 : * @param result the postgres result
69 : * @param num_results the number of results in @a result
70 : */
71 : static void
72 646 : auditor_progress_cb (void *cls,
73 : PGresult *result,
74 : unsigned int num_results)
75 : {
76 646 : struct AuditorProgressContext *ctx = cls;
77 :
78 646 : GNUNET_assert (num_results == ctx->len);
79 2978 : for (unsigned int i = 0; i < num_results; i++)
80 : {
81 2332 : bool is_missing = false;
82 2332 : struct GNUNET_PQ_ResultSpec rs[] = {
83 2332 : GNUNET_PQ_result_spec_allow_null (
84 : GNUNET_PQ_result_spec_uint64 ("progress_offset",
85 2332 : ctx->dst[i]),
86 : &is_missing),
87 : GNUNET_PQ_result_spec_end
88 : };
89 :
90 2332 : if (GNUNET_OK !=
91 2332 : GNUNET_PQ_extract_result (result,
92 : rs,
93 : i))
94 : {
95 0 : GNUNET_break (0);
96 0 : ctx->failure = true;
97 0 : return;
98 : }
99 2332 : if (is_missing)
100 1294 : *ctx->dst[i] = 0;
101 2332 : ctx->off++;
102 : }
103 : }
104 :
105 :
106 : enum GNUNET_DB_QueryStatus
107 646 : TAH_PG_get_auditor_progress (void *cls,
108 : const char *progress_key,
109 : uint64_t *progress_offset,
110 : ...)
111 : {
112 646 : struct PostgresClosure *pg = cls;
113 646 : unsigned int cnt = 1;
114 : va_list ap;
115 :
116 646 : va_start (ap,
117 : progress_offset);
118 2332 : while (NULL != va_arg (ap,
119 : const char *))
120 : {
121 1686 : cnt++;
122 1686 : (void) va_arg (ap,
123 : uint64_t *);
124 : }
125 646 : va_end (ap);
126 646 : {
127 646 : const char *keys[cnt];
128 646 : uint64_t *dsts[cnt];
129 646 : unsigned int off = 1;
130 646 : struct GNUNET_PQ_QueryParam params[] = {
131 646 : GNUNET_PQ_query_param_array_ptrs_string (cnt,
132 : keys,
133 : pg->conn),
134 : GNUNET_PQ_query_param_end
135 : };
136 646 : struct AuditorProgressContext ctx = {
137 : .dst = dsts,
138 : .len = cnt,
139 : .pg = pg
140 : };
141 : enum GNUNET_DB_QueryStatus qs;
142 :
143 646 : keys[0] = progress_key;
144 646 : dsts[0] = progress_offset;
145 646 : va_start (ap,
146 : progress_offset);
147 2332 : while (off < cnt)
148 : {
149 1686 : keys[off] = va_arg (ap,
150 : const char *);
151 1686 : dsts[off] = va_arg (ap,
152 : uint64_t *);
153 1686 : off++;
154 : }
155 646 : GNUNET_assert (NULL == va_arg (ap,
156 : const char *));
157 646 : va_end (ap);
158 :
159 646 : PREPARE (pg,
160 : "get_auditor_progress",
161 : "SELECT"
162 : " auditor_do_get_auditor_progress AS progress_offset"
163 : " FROM auditor_do_get_auditor_progress "
164 : "($1);");
165 646 : ctx.off = 0;
166 646 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
167 : "get_auditor_progress",
168 : params,
169 : &auditor_progress_cb,
170 : &ctx);
171 646 : GNUNET_PQ_cleanup_query_params_closures (params);
172 646 : if (ctx.failure)
173 0 : return GNUNET_DB_STATUS_HARD_ERROR;
174 646 : if (qs < 0)
175 0 : return qs;
176 646 : GNUNET_assert (ctx.off == cnt);
177 646 : return qs;
178 : }
179 : }
|