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