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