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