select_purse_decisions_above_serial_id.c (4859B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2022 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 exchangedb/select_purse_decisions_above_serial_id.c 18 * @brief Implementation of the select_purse_decisions_above_serial_id function for Postgres 19 * @author Christian Grothoff 20 */ 21 #include "taler/taler_pq_lib.h" 22 #include "exchange-database/select_purse_decisions_above_serial_id.h" 23 #include "helper.h" 24 25 /** 26 * Closure for #purse_decision_serial_helper_cb(). 27 */ 28 struct PurseDecisionSerialContext 29 { 30 31 /** 32 * Callback to call. 33 */ 34 TALER_EXCHANGEDB_PurseDecisionCallback cb; 35 36 /** 37 * Closure for @e cb. 38 */ 39 void *cb_cls; 40 41 /** 42 * Plugin context. 43 */ 44 struct TALER_EXCHANGEDB_PostgresContext *pg; 45 46 /** 47 * Status code, set to #GNUNET_SYSERR on hard errors. 48 */ 49 enum GNUNET_GenericReturnValue status; 50 }; 51 52 53 /** 54 * Helper function to be called with the results of a SELECT statement 55 * that has returned @a num_results results. 56 * 57 * @param cls closure of type `struct PurseRefundSerialContext` 58 * @param result the postgres result 59 * @param num_results the number of results in @a result 60 */ 61 static void 62 purse_decision_serial_helper_cb (void *cls, 63 PGresult *result, 64 unsigned int num_results) 65 { 66 struct PurseDecisionSerialContext *dsc = cls; 67 struct TALER_EXCHANGEDB_PostgresContext *pg = dsc->pg; 68 69 for (unsigned int i = 0; i<num_results; i++) 70 { 71 struct TALER_PurseContractPublicKeyP purse_pub; 72 struct TALER_ReservePublicKeyP reserve_pub; 73 bool no_reserve = true; 74 uint64_t rowid; 75 struct TALER_Amount val; 76 struct GNUNET_PQ_ResultSpec rs[] = { 77 GNUNET_PQ_result_spec_auto_from_type ("purse_pub", 78 &purse_pub), 79 GNUNET_PQ_result_spec_allow_null ( 80 GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", 81 &reserve_pub), 82 &no_reserve), 83 TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", 84 &val), 85 GNUNET_PQ_result_spec_uint64 ("purse_decision_serial_id", 86 &rowid), 87 GNUNET_PQ_result_spec_end 88 }; 89 enum GNUNET_GenericReturnValue ret; 90 91 if (GNUNET_OK != 92 GNUNET_PQ_extract_result (result, 93 rs, 94 i)) 95 { 96 GNUNET_break (0); 97 dsc->status = GNUNET_SYSERR; 98 return; 99 } 100 ret = dsc->cb (dsc->cb_cls, 101 rowid, 102 &purse_pub, 103 no_reserve ? NULL : &reserve_pub, 104 &val); 105 GNUNET_PQ_cleanup_result (rs); 106 if (GNUNET_OK != ret) 107 break; 108 } 109 } 110 111 112 enum GNUNET_DB_QueryStatus 113 TALER_TALER_EXCHANGEDB_select_purse_decisions_above_serial_id ( 114 struct TALER_EXCHANGEDB_PostgresContext *pg, 115 uint64_t serial_id, 116 bool refunded, 117 TALER_EXCHANGEDB_PurseDecisionCallback cb, 118 void *cb_cls) 119 { 120 struct GNUNET_PQ_QueryParam params[] = { 121 GNUNET_PQ_query_param_uint64 (&serial_id), 122 GNUNET_PQ_query_param_bool (refunded), 123 GNUNET_PQ_query_param_end 124 }; 125 struct PurseDecisionSerialContext dsc = { 126 .cb = cb, 127 .cb_cls = cb_cls, 128 .pg = pg, 129 .status = GNUNET_OK 130 }; 131 enum GNUNET_DB_QueryStatus qs; 132 133 PREPARE (pg, 134 "audit_get_purse_decisions_incr", 135 "SELECT" 136 " pd.purse_pub" 137 ",pm.reserve_pub" 138 ",pd.purse_decision_serial_id" 139 ",pr.amount_with_fee" 140 " FROM purse_decision pd" 141 " JOIN purse_requests pr ON (pd.purse_pub = pr.purse_pub)" 142 " LEFT JOIN purse_merges pm ON (pm.purse_pub = pd.purse_pub)" 143 " WHERE (" 144 " (purse_decision_serial_id>=$1) AND " 145 " (refunded=$2)" 146 " )" 147 " ORDER BY purse_decision_serial_id ASC;"); 148 149 150 qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, 151 "audit_get_purse_decisions_incr", 152 params, 153 &purse_decision_serial_helper_cb, 154 &dsc); 155 if (GNUNET_OK != dsc.status) 156 return GNUNET_DB_STATUS_HARD_ERROR; 157 return qs; 158 }