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