iterate_auditor_closure_lags.c (5151B)
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 #include "taler/taler_error_codes.h" 17 #include "taler/taler_dbevents.h" 18 #include "taler/taler_pq_lib.h" 19 #include "pg_helper.h" 20 #include "auditor-database/iterate_auditor_closure_lags.h" 21 22 23 /** 24 * Hard upper bound on the number of records returned by a single 25 * call, regardless of the limit requested by the client. 26 */ 27 #define MAX_RECORDS 50000 28 29 30 struct ClosureLagsContext 31 { 32 33 /** 34 * Function to call for each closure lag . 35 */ 36 TALER_AUDITORDB_ClosureLagsCallback cb; 37 38 /** 39 * Closure for @e cb 40 */ 41 void *cb_cls; 42 43 /** 44 * Plugin context. 45 */ 46 struct TALER_AUDITORDB_PostgresContext *pg; 47 48 /** 49 * Query status to return. 50 */ 51 enum GNUNET_DB_QueryStatus qs; 52 }; 53 54 55 /** 56 * Helper function for #TALER_AUDITORDB_iterate_auditor_closure_lags(). 57 * To be called with the results of a SELECT statement 58 * that has returned @a num_results results. 59 * 60 * @param cls closure of type `struct ClosureLagsContext *` 61 * @param result the postgres result 62 * @param num_results the number of results in @a result 63 */ 64 static void 65 closure_lags_cb (void *cls, 66 PGresult *result, 67 unsigned int num_results) 68 { 69 struct ClosureLagsContext *dcc = cls; 70 struct TALER_AUDITORDB_PostgresContext *pg = dcc->pg; 71 72 for (unsigned int i = 0; i < num_results; i++) 73 { 74 struct TALER_AUDITORDB_ClosureLags dc; 75 struct GNUNET_PQ_ResultSpec rs[] = { 76 GNUNET_PQ_result_spec_uint64 ("row_id", 77 &dc.row_id), 78 GNUNET_PQ_result_spec_uint64 ("problem_row_id", 79 &dc.problem_row_id), 80 TALER_PQ_RESULT_SPEC_AMOUNT ("amount", 81 &dc.amount), 82 GNUNET_PQ_result_spec_absolute_time ("deadline", 83 &dc.deadline), 84 GNUNET_PQ_result_spec_auto_from_type ("wtid", 85 &dc.wtid), 86 GNUNET_PQ_result_spec_string ("account", 87 &dc.account.full_payto), 88 GNUNET_PQ_result_spec_bool ("suppressed", 89 &dc.suppressed), 90 GNUNET_PQ_result_spec_end 91 }; 92 enum GNUNET_GenericReturnValue rval; 93 94 if (GNUNET_OK != 95 GNUNET_PQ_extract_result (result, 96 rs, 97 i)) 98 { 99 GNUNET_break (0); 100 dcc->qs = GNUNET_DB_STATUS_HARD_ERROR; 101 return; 102 } 103 dcc->qs = i + 1; 104 rval = dcc->cb (dcc->cb_cls, 105 &dc); 106 GNUNET_PQ_cleanup_result (rs); 107 if (GNUNET_OK != rval) 108 break; 109 } 110 } 111 112 113 enum GNUNET_DB_QueryStatus 114 TALER_AUDITORDB_iterate_auditor_closure_lags ( 115 struct TALER_AUDITORDB_PostgresContext *pg, 116 int64_t limit, 117 uint64_t offset, 118 bool return_suppressed, 119 TALER_AUDITORDB_ClosureLagsCallback cb, 120 void *cb_cls) 121 { 122 uint64_t plimit = GNUNET_MIN ((uint64_t) MAX_RECORDS, 123 TALER_AUDITORDB_abs_limit (limit)); 124 struct GNUNET_PQ_QueryParam params[] = { 125 GNUNET_PQ_query_param_uint64 (&offset), 126 GNUNET_PQ_query_param_bool (return_suppressed), 127 GNUNET_PQ_query_param_uint64 (&plimit), 128 GNUNET_PQ_query_param_end 129 }; 130 struct ClosureLagsContext dcc = { 131 .cb = cb, 132 .cb_cls = cb_cls, 133 .pg = pg 134 }; 135 enum GNUNET_DB_QueryStatus qs; 136 137 PREPARE (pg, 138 "iterate_auditor_closure_lags_desc", 139 "SELECT" 140 " row_id" 141 ",problem_row_id" 142 ",amount" 143 ",deadline" 144 ",wtid" 145 ",account" 146 ",suppressed" 147 " FROM auditor_closure_lags" 148 " WHERE (row_id < $1)" 149 " AND ($2 OR NOT suppressed)" 150 " ORDER BY row_id DESC" 151 " LIMIT $3" 152 ); 153 PREPARE (pg, 154 "iterate_auditor_closure_lags_asc", 155 "SELECT" 156 " row_id" 157 ",problem_row_id" 158 ",amount" 159 ",deadline" 160 ",wtid" 161 ",account" 162 ",suppressed" 163 " FROM auditor_closure_lags" 164 " WHERE (row_id > $1)" 165 " AND ($2 OR NOT suppressed)" 166 " ORDER BY row_id ASC" 167 " LIMIT $3" 168 ); 169 qs = GNUNET_PQ_eval_prepared_multi_select ( 170 pg->conn, 171 (limit > 0) 172 ? "iterate_auditor_closure_lags_asc" 173 : "iterate_auditor_closure_lags_desc", 174 params, 175 &closure_lags_cb, 176 &dcc); 177 if (qs > 0) 178 return dcc.qs; 179 GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); 180 return qs; 181 }