sq_result_helper.c (6510B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2020 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 sq/sq_result_helper.c 18 * @brief functions to initialize parameter arrays 19 * @author Jonathan Buchanan 20 */ 21 #include "taler/platform.h" 22 #include <sqlite3.h> 23 #include <gnunet/gnunet_util_lib.h> 24 #include <gnunet/gnunet_sq_lib.h> 25 #include "taler/taler_sq_lib.h" 26 #include "taler/taler_util.h" 27 28 29 /** 30 * Extract amount data from a SQLite database 31 * 32 * @param cls closure, a `const char *` giving the currency 33 * @param result where to extract data from 34 * @param column column to extract data from 35 * @param[in,out] dst_size where to store size of result, may be NULL 36 * @param[out] dst where to store the result 37 * @return 38 * #GNUNET_YES if all results could be extracted 39 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 40 */ 41 static enum GNUNET_GenericReturnValue 42 extract_amount (void *cls, 43 sqlite3_stmt *result, 44 unsigned int column, 45 size_t *dst_size, 46 void *dst) 47 { 48 struct TALER_Amount *amount = dst; 49 const char *currency = cls; 50 uint64_t frac; 51 52 if ((sizeof (struct TALER_Amount) != *dst_size) || 53 (SQLITE_INTEGER != sqlite3_column_type (result, 54 (int) column)) || 55 (SQLITE_INTEGER != sqlite3_column_type (result, 56 (int) column + 1))) 57 { 58 GNUNET_break (0); 59 return GNUNET_SYSERR; 60 } 61 GNUNET_strlcpy (amount->currency, 62 currency, 63 TALER_CURRENCY_LEN); 64 amount->value = (uint64_t) sqlite3_column_int64 (result, 65 (int) column); 66 frac = (uint64_t) sqlite3_column_int64 (result, 67 (int) column + 1); 68 amount->fraction = (uint32_t) frac; 69 return GNUNET_YES; 70 } 71 72 73 struct GNUNET_SQ_ResultSpec 74 TALER_SQ_result_spec_amount (const char *currency, 75 struct TALER_Amount *amount) 76 { 77 struct GNUNET_SQ_ResultSpec res = { 78 .conv = &extract_amount, 79 .cls = (void *) currency, 80 .dst = (void *) amount, 81 .dst_size = sizeof (struct TALER_Amount), 82 .num_params = 2 83 }; 84 85 return res; 86 } 87 88 89 /** 90 * Extract amount data from a SQLite database 91 * 92 * @param cls closure, a `const char *` giving the currency 93 * @param result where to extract data from 94 * @param column column to extract data from 95 * @param[in,out] dst_size where to store size of result, may be NULL 96 * @param[out] dst where to store the result 97 * @return 98 * #GNUNET_YES if all results could be extracted 99 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 100 */ 101 static enum GNUNET_GenericReturnValue 102 extract_amount_nbo (void *cls, 103 sqlite3_stmt *result, 104 unsigned int column, 105 size_t *dst_size, 106 void *dst) 107 { 108 struct TALER_AmountNBO *amount = dst; 109 struct TALER_Amount amount_hbo; 110 size_t amount_hbo_size = sizeof (struct TALER_Amount); 111 112 (void) cls; 113 (void) dst_size; 114 if (GNUNET_YES != 115 extract_amount (cls, 116 result, 117 column, 118 &amount_hbo_size, 119 &amount_hbo)) 120 { 121 GNUNET_break (0); 122 return GNUNET_SYSERR; 123 } 124 TALER_amount_hton (amount, 125 &amount_hbo); 126 return GNUNET_YES; 127 } 128 129 130 struct GNUNET_SQ_ResultSpec 131 TALER_SQ_result_spec_amount_nbo (const char *currency, 132 struct TALER_AmountNBO *amount) 133 { 134 struct GNUNET_SQ_ResultSpec res = { 135 .conv = &extract_amount_nbo, 136 .cls = (void *) currency, 137 .dst = (void *) amount, 138 .dst_size = sizeof (struct TALER_AmountNBO), 139 .num_params = 2 140 }; 141 142 return res; 143 } 144 145 146 /** 147 * Extract amount data from a SQLite database 148 * 149 * @param cls closure 150 * @param result where to extract data from 151 * @param column column to extract data from 152 * @param[in,out] dst_size where to store size of result, may be NULL 153 * @param[out] dst where to store the result 154 * @return 155 * #GNUNET_YES if all results could be extracted 156 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 157 */ 158 static enum GNUNET_GenericReturnValue 159 extract_json (void *cls, 160 sqlite3_stmt *result, 161 unsigned int column, 162 size_t *dst_size, 163 void *dst) 164 { 165 json_t **j_dst = dst; 166 const char *res; 167 json_error_t json_error; 168 size_t slen; 169 170 (void) cls; 171 (void) dst_size; 172 if (SQLITE_TEXT != sqlite3_column_type (result, 173 column)) 174 { 175 GNUNET_break (0); 176 return GNUNET_SYSERR; 177 } 178 res = (const char *) sqlite3_column_text (result, 179 column); 180 slen = strlen (res); 181 *j_dst = json_loadb (res, 182 slen, 183 JSON_REJECT_DUPLICATES, 184 &json_error); 185 if (NULL == *j_dst) 186 { 187 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 188 "Failed to parse JSON result for column %d: %s (%s)\n", 189 column, 190 json_error.text, 191 json_error.source); 192 return GNUNET_SYSERR; 193 } 194 return GNUNET_OK; 195 } 196 197 198 /** 199 * Function called to clean up memory allocated 200 * by a #GNUNET_SQ_ResultConverter. 201 * 202 * @param cls closure 203 */ 204 static void 205 clean_json (void *cls) 206 { 207 json_t **dst = cls; 208 209 (void) cls; 210 if (NULL != *dst) 211 { 212 json_decref (*dst); 213 *dst = NULL; 214 } 215 } 216 217 218 /** 219 * json_t expected. 220 * 221 * @param[out] jp where to store the result 222 * @return array entry for the result specification to use 223 */ 224 struct GNUNET_SQ_ResultSpec 225 TALER_SQ_result_spec_json (json_t **jp) 226 { 227 struct GNUNET_SQ_ResultSpec res = { 228 .conv = &extract_json, 229 .cleaner = &clean_json, 230 .dst = (void *) jp, 231 .cls = (void *) jp, 232 .num_params = 1 233 }; 234 235 return res; 236 } 237 238 239 /* end of sq/sq_result_helper.c */