pg_lookup_global_fee_by_time.c (5673B)
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/pg_lookup_global_fee_by_time.c 18 * @brief Implementation of the lookup_global_fee_by_time function for Postgres 19 * @author Christian Grothoff 20 */ 21 #include "taler/platform.h" 22 #include "taler/taler_error_codes.h" 23 #include "taler/taler_dbevents.h" 24 #include "taler/taler_pq_lib.h" 25 #include "pg_lookup_global_fee_by_time.h" 26 #include "pg_helper.h" 27 28 /** 29 * Closure for #global_fee_by_time_helper() 30 */ 31 struct GlobalFeeLookupContext 32 { 33 34 /** 35 * Set to the wire fees. Set to invalid if fees conflict over 36 * the given time period. 37 */ 38 struct TALER_GlobalFeeSet *fees; 39 40 /** 41 * Set to timeout of unmerged purses 42 */ 43 struct GNUNET_TIME_Relative *purse_timeout; 44 45 /** 46 * Set to history expiration for reserves. 47 */ 48 struct GNUNET_TIME_Relative *history_expiration; 49 50 /** 51 * Set to number of free purses per account. 52 */ 53 uint32_t *purse_account_limit; 54 55 /** 56 * Plugin context. 57 */ 58 struct PostgresClosure *pg; 59 }; 60 61 62 /** 63 * Helper function for #TEH_PG_lookup_global_fee_by_time(). 64 * Calls the callback with each denomination key. 65 * 66 * @param cls a `struct GlobalFeeLookupContext` 67 * @param result db results 68 * @param num_results number of results in @a result 69 */ 70 static void 71 global_fee_by_time_helper (void *cls, 72 PGresult *result, 73 unsigned int num_results) 74 { 75 struct GlobalFeeLookupContext *wlc = cls; 76 struct PostgresClosure *pg = wlc->pg; 77 78 for (unsigned int i = 0; i<num_results; i++) 79 { 80 struct TALER_GlobalFeeSet fs; 81 struct GNUNET_TIME_Relative purse_timeout; 82 struct GNUNET_TIME_Relative history_expiration; 83 uint32_t purse_account_limit; 84 struct GNUNET_PQ_ResultSpec rs[] = { 85 TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee", 86 &fs.history), 87 TALER_PQ_RESULT_SPEC_AMOUNT ("account_fee", 88 &fs.account), 89 TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee", 90 &fs.purse), 91 GNUNET_PQ_result_spec_relative_time ("purse_timeout", 92 &purse_timeout), 93 GNUNET_PQ_result_spec_relative_time ("history_expiration", 94 &history_expiration), 95 GNUNET_PQ_result_spec_uint32 ("purse_account_limit", 96 &purse_account_limit), 97 GNUNET_PQ_result_spec_end 98 }; 99 100 if (GNUNET_OK != 101 GNUNET_PQ_extract_result (result, 102 rs, 103 i)) 104 { 105 GNUNET_break (0); 106 /* invalidate */ 107 memset (wlc->fees, 108 0, 109 sizeof (struct TALER_GlobalFeeSet)); 110 return; 111 } 112 if (0 == i) 113 { 114 *wlc->fees = fs; 115 *wlc->purse_timeout = purse_timeout; 116 *wlc->history_expiration = history_expiration; 117 *wlc->purse_account_limit = purse_account_limit; 118 continue; 119 } 120 if ( (0 != 121 TALER_global_fee_set_cmp (&fs, 122 wlc->fees)) || 123 (purse_account_limit != *wlc->purse_account_limit) || 124 (GNUNET_TIME_relative_cmp (purse_timeout, 125 !=, 126 *wlc->purse_timeout)) || 127 (GNUNET_TIME_relative_cmp (history_expiration, 128 !=, 129 *wlc->history_expiration)) ) 130 { 131 /* invalidate */ 132 memset (wlc->fees, 133 0, 134 sizeof (struct TALER_GlobalFeeSet)); 135 return; 136 } 137 } 138 } 139 140 141 enum GNUNET_DB_QueryStatus 142 TEH_PG_lookup_global_fee_by_time ( 143 void *cls, 144 struct GNUNET_TIME_Timestamp start_time, 145 struct GNUNET_TIME_Timestamp end_time, 146 struct TALER_GlobalFeeSet *fees, 147 struct GNUNET_TIME_Relative *purse_timeout, 148 struct GNUNET_TIME_Relative *history_expiration, 149 uint32_t *purse_account_limit) 150 { 151 struct PostgresClosure *pg = cls; 152 struct GNUNET_PQ_QueryParam params[] = { 153 GNUNET_PQ_query_param_timestamp (&start_time), 154 GNUNET_PQ_query_param_timestamp (&end_time), 155 GNUNET_PQ_query_param_end 156 }; 157 struct GlobalFeeLookupContext wlc = { 158 .fees = fees, 159 .purse_timeout = purse_timeout, 160 .history_expiration = history_expiration, 161 .purse_account_limit = purse_account_limit, 162 .pg = pg 163 }; 164 165 PREPARE (pg, 166 "lookup_global_fee_by_time", 167 "SELECT" 168 " history_fee" 169 ",account_fee" 170 ",purse_fee" 171 ",purse_timeout" 172 ",history_expiration" 173 ",purse_account_limit" 174 " FROM global_fee" 175 " WHERE end_date > $1" 176 " AND start_date < $2;"); 177 return GNUNET_PQ_eval_prepared_multi_select (pg->conn, 178 "lookup_global_fee_by_time", 179 params, 180 &global_fee_by_time_helper, 181 &wlc); 182 }