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