Line data Source code
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 "platform.h"
22 : #include <sqlite3.h>
23 : #include <gnunet/gnunet_util_lib.h>
24 : #include <gnunet/gnunet_sq_lib.h>
25 : #include "taler_sq_lib.h"
26 : #include "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 2 : extract_amount (void *cls,
43 : sqlite3_stmt *result,
44 : unsigned int column,
45 : size_t *dst_size,
46 : void *dst)
47 : {
48 2 : struct TALER_Amount *amount = dst;
49 2 : const char *currency = cls;
50 : uint64_t frac;
51 :
52 4 : if ((sizeof (struct TALER_Amount) != *dst_size) ||
53 2 : (SQLITE_INTEGER != sqlite3_column_type (result,
54 2 : (int) column)) ||
55 2 : (SQLITE_INTEGER != sqlite3_column_type (result,
56 2 : (int) column + 1)))
57 : {
58 0 : GNUNET_break (0);
59 0 : return GNUNET_SYSERR;
60 : }
61 2 : GNUNET_strlcpy (amount->currency,
62 : currency,
63 : TALER_CURRENCY_LEN);
64 2 : amount->value = (uint64_t) sqlite3_column_int64 (result,
65 : (int) column);
66 4 : frac = (uint64_t) sqlite3_column_int64 (result,
67 2 : (int) column + 1);
68 2 : amount->fraction = (uint32_t) frac;
69 2 : return GNUNET_YES;
70 : }
71 :
72 :
73 : struct GNUNET_SQ_ResultSpec
74 1 : TALER_SQ_result_spec_amount (const char *currency,
75 : struct TALER_Amount *amount)
76 : {
77 1 : 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 1 : 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 1 : extract_amount_nbo (void *cls,
103 : sqlite3_stmt *result,
104 : unsigned int column,
105 : size_t *dst_size,
106 : void *dst)
107 : {
108 1 : struct TALER_AmountNBO *amount = dst;
109 : struct TALER_Amount amount_hbo;
110 1 : size_t amount_hbo_size = sizeof (struct TALER_Amount);
111 :
112 : (void) cls;
113 : (void) dst_size;
114 1 : if (GNUNET_YES !=
115 1 : extract_amount (cls,
116 : result,
117 : column,
118 : &amount_hbo_size,
119 : &amount_hbo))
120 : {
121 0 : GNUNET_break (0);
122 0 : return GNUNET_SYSERR;
123 : }
124 1 : TALER_amount_hton (amount,
125 : &amount_hbo);
126 1 : return GNUNET_YES;
127 : }
128 :
129 :
130 : struct GNUNET_SQ_ResultSpec
131 1 : TALER_SQ_result_spec_amount_nbo (const char *currency,
132 : struct TALER_AmountNBO *amount)
133 : {
134 1 : 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 1 : 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 1 : extract_json (void *cls,
160 : sqlite3_stmt *result,
161 : unsigned int column,
162 : size_t *dst_size,
163 : void *dst)
164 : {
165 1 : 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 1 : if (SQLITE_TEXT != sqlite3_column_type (result,
173 : column))
174 : {
175 0 : GNUNET_break (0);
176 0 : return GNUNET_SYSERR;
177 : }
178 1 : res = (const char *) sqlite3_column_text (result,
179 : column);
180 1 : slen = strlen (res);
181 1 : *j_dst = json_loadb (res,
182 : slen,
183 : JSON_REJECT_DUPLICATES,
184 : &json_error);
185 1 : if (NULL == *j_dst)
186 : {
187 0 : 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 0 : return GNUNET_SYSERR;
193 : }
194 1 : 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 1 : clean_json (void *cls)
206 : {
207 1 : json_t **dst = cls;
208 :
209 : (void) cls;
210 1 : if (NULL != *dst)
211 : {
212 1 : json_decref (*dst);
213 1 : *dst = NULL;
214 : }
215 1 : }
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 1 : TALER_SQ_result_spec_json (json_t **jp)
226 : {
227 1 : 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 1 : return res;
236 : }
237 :
238 :
239 : /* end of sq/sq_result_helper.c */
|