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