diff options
-rw-r--r-- | src/include/gnunet_pq_lib.h | 55 | ||||
-rw-r--r-- | src/pq/pq.c | 45 | ||||
-rw-r--r-- | src/pq/pq_query_helper.c | 126 | ||||
-rw-r--r-- | src/pq/pq_result_helper.c | 101 | ||||
-rw-r--r-- | src/pq/test_pq.c | 17 |
5 files changed, 163 insertions, 181 deletions
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index ca549f77c..de717526c 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2016, 2017 GNUnet e.V. | 3 | Copyright (C) 2016, 2017, 2020 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -87,6 +87,7 @@ struct GNUNET_PQ_QueryParam | |||
87 | * Number of parameters eaten by this operation. | 87 | * Number of parameters eaten by this operation. |
88 | */ | 88 | */ |
89 | unsigned int num_params; | 89 | unsigned int num_params; |
90 | |||
90 | }; | 91 | }; |
91 | 92 | ||
92 | 93 | ||
@@ -100,20 +101,32 @@ struct GNUNET_PQ_QueryParam | |||
100 | 101 | ||
101 | 102 | ||
102 | /** | 103 | /** |
104 | * Generate query parameter to create a NULL value. | ||
105 | * | ||
106 | * @return query parameter to use to insert NULL into DB | ||
107 | */ | ||
108 | struct GNUNET_PQ_QueryParam | ||
109 | GNUNET_PQ_query_param_null (void); | ||
110 | |||
111 | |||
112 | /** | ||
103 | * Generate query parameter for a buffer @a ptr of | 113 | * Generate query parameter for a buffer @a ptr of |
104 | * @a ptr_size bytes. | 114 | * @a ptr_size bytes. |
105 | * | 115 | * |
106 | * @param ptr pointer to the query parameter to pass | 116 | * @param ptr pointer to the query parameter to pass |
107 | * @oaran ptr_size number of bytes in @a ptr | 117 | * @oaran ptr_size number of bytes in @a ptr |
118 | * @return query parameter to use | ||
108 | */ | 119 | */ |
109 | struct GNUNET_PQ_QueryParam | 120 | struct GNUNET_PQ_QueryParam |
110 | GNUNET_PQ_query_param_fixed_size (const void *ptr, size_t ptr_size); | 121 | GNUNET_PQ_query_param_fixed_size (const void *ptr, |
122 | size_t ptr_size); | ||
111 | 123 | ||
112 | 124 | ||
113 | /** | 125 | /** |
114 | * Generate query parameter for a string. | 126 | * Generate query parameter for a string. |
115 | * | 127 | * |
116 | * @param ptr pointer to the string query parameter to pass | 128 | * @param ptr pointer to the string query parameter to pass |
129 | * @return query parameter to use | ||
117 | */ | 130 | */ |
118 | struct GNUNET_PQ_QueryParam | 131 | struct GNUNET_PQ_QueryParam |
119 | GNUNET_PQ_query_param_string (const char *ptr); | 132 | GNUNET_PQ_query_param_string (const char *ptr); |
@@ -124,6 +137,7 @@ GNUNET_PQ_query_param_string (const char *ptr); | |||
124 | * by variable type. | 137 | * by variable type. |
125 | * | 138 | * |
126 | * @param x pointer to the query parameter to pass. | 139 | * @param x pointer to the query parameter to pass. |
140 | * @return query parameter to use | ||
127 | */ | 141 | */ |
128 | #define GNUNET_PQ_query_param_auto_from_type(x) \ | 142 | #define GNUNET_PQ_query_param_auto_from_type(x) \ |
129 | GNUNET_PQ_query_param_fixed_size ((x), sizeof(*(x))) | 143 | GNUNET_PQ_query_param_fixed_size ((x), sizeof(*(x))) |
@@ -134,6 +148,7 @@ GNUNET_PQ_query_param_string (const char *ptr); | |||
134 | * database must contain a BLOB type in the respective position. | 148 | * database must contain a BLOB type in the respective position. |
135 | * | 149 | * |
136 | * @param x the query parameter to pass. | 150 | * @param x the query parameter to pass. |
151 | * @return query parameter to use | ||
137 | */ | 152 | */ |
138 | struct GNUNET_PQ_QueryParam | 153 | struct GNUNET_PQ_QueryParam |
139 | GNUNET_PQ_query_param_rsa_public_key ( | 154 | GNUNET_PQ_query_param_rsa_public_key ( |
@@ -145,6 +160,7 @@ GNUNET_PQ_query_param_rsa_public_key ( | |||
145 | * database must contain a BLOB type in the respective position. | 160 | * database must contain a BLOB type in the respective position. |
146 | * | 161 | * |
147 | * @param x the query parameter to pass | 162 | * @param x the query parameter to pass |
163 | * @return query parameter to use | ||
148 | */ | 164 | */ |
149 | struct GNUNET_PQ_QueryParam | 165 | struct GNUNET_PQ_QueryParam |
150 | GNUNET_PQ_query_param_rsa_signature ( | 166 | GNUNET_PQ_query_param_rsa_signature ( |
@@ -156,6 +172,7 @@ GNUNET_PQ_query_param_rsa_signature ( | |||
156 | * The database must store a 64-bit integer. | 172 | * The database must store a 64-bit integer. |
157 | * | 173 | * |
158 | * @param x pointer to the query parameter to pass | 174 | * @param x pointer to the query parameter to pass |
175 | * @return query parameter to use | ||
159 | */ | 176 | */ |
160 | struct GNUNET_PQ_QueryParam | 177 | struct GNUNET_PQ_QueryParam |
161 | GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x); | 178 | GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x); |
@@ -166,6 +183,7 @@ GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x); | |||
166 | * The database must store a 64-bit integer. | 183 | * The database must store a 64-bit integer. |
167 | * | 184 | * |
168 | * @param x pointer to the query parameter to pass | 185 | * @param x pointer to the query parameter to pass |
186 | * @return query parameter to use | ||
169 | */ | 187 | */ |
170 | struct GNUNET_PQ_QueryParam | 188 | struct GNUNET_PQ_QueryParam |
171 | GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | 189 | GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); |
@@ -176,6 +194,7 @@ GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | |||
176 | * The database must store a 64-bit integer. | 194 | * The database must store a 64-bit integer. |
177 | * | 195 | * |
178 | * @param x pointer to the query parameter to pass | 196 | * @param x pointer to the query parameter to pass |
197 | * @return query parameter to use | ||
179 | */ | 198 | */ |
180 | struct GNUNET_PQ_QueryParam | 199 | struct GNUNET_PQ_QueryParam |
181 | GNUNET_PQ_query_param_absolute_time_nbo ( | 200 | GNUNET_PQ_query_param_absolute_time_nbo ( |
@@ -186,6 +205,7 @@ GNUNET_PQ_query_param_absolute_time_nbo ( | |||
186 | * Generate query parameter for an uint16_t in host byte order. | 205 | * Generate query parameter for an uint16_t in host byte order. |
187 | * | 206 | * |
188 | * @param x pointer to the query parameter to pass | 207 | * @param x pointer to the query parameter to pass |
208 | * @return query parameter to use | ||
189 | */ | 209 | */ |
190 | struct GNUNET_PQ_QueryParam | 210 | struct GNUNET_PQ_QueryParam |
191 | GNUNET_PQ_query_param_uint16 (const uint16_t *x); | 211 | GNUNET_PQ_query_param_uint16 (const uint16_t *x); |
@@ -195,6 +215,7 @@ GNUNET_PQ_query_param_uint16 (const uint16_t *x); | |||
195 | * Generate query parameter for an uint32_t in host byte order. | 215 | * Generate query parameter for an uint32_t in host byte order. |
196 | * | 216 | * |
197 | * @param x pointer to the query parameter to pass | 217 | * @param x pointer to the query parameter to pass |
218 | * @return query parameter to use | ||
198 | */ | 219 | */ |
199 | struct GNUNET_PQ_QueryParam | 220 | struct GNUNET_PQ_QueryParam |
200 | GNUNET_PQ_query_param_uint32 (const uint32_t *x); | 221 | GNUNET_PQ_query_param_uint32 (const uint32_t *x); |
@@ -204,6 +225,7 @@ GNUNET_PQ_query_param_uint32 (const uint32_t *x); | |||
204 | * Generate query parameter for an uint16_t in host byte order. | 225 | * Generate query parameter for an uint16_t in host byte order. |
205 | * | 226 | * |
206 | * @param x pointer to the query parameter to pass | 227 | * @param x pointer to the query parameter to pass |
228 | * @return query parameter to use | ||
207 | */ | 229 | */ |
208 | struct GNUNET_PQ_QueryParam | 230 | struct GNUNET_PQ_QueryParam |
209 | GNUNET_PQ_query_param_uint64 (const uint64_t *x); | 231 | GNUNET_PQ_query_param_uint64 (const uint64_t *x); |
@@ -288,6 +310,20 @@ struct GNUNET_PQ_ResultSpec | |||
288 | * Where to store actual size of the result. | 310 | * Where to store actual size of the result. |
289 | */ | 311 | */ |
290 | size_t *result_size; | 312 | size_t *result_size; |
313 | |||
314 | /** | ||
315 | * True if NULL is allowed for a value in the database. | ||
316 | */ | ||
317 | bool is_nullable; | ||
318 | |||
319 | /** | ||
320 | * Points to a location where we should store | ||
321 | * "true" if the result found is NULL, and | ||
322 | * otherwise "false". Only used if @e is_nullable | ||
323 | * is true. | ||
324 | */ | ||
325 | bool *is_null; | ||
326 | |||
291 | }; | 327 | }; |
292 | 328 | ||
293 | 329 | ||
@@ -303,6 +339,21 @@ struct GNUNET_PQ_ResultSpec | |||
303 | 339 | ||
304 | 340 | ||
305 | /** | 341 | /** |
342 | * Allow NULL value to be found in the database | ||
343 | * for the given value. | ||
344 | * | ||
345 | * @param rs result spec entry to modify | ||
346 | * @param[out] is_null location set to 'true' if the | ||
347 | * value was indeed NULL, set to 'false' if the | ||
348 | * value was non-NULL | ||
349 | * @return array entry for the result specification to use | ||
350 | */ | ||
351 | struct GNUNET_PQ_ResultSpec | ||
352 | GNUNET_PQ_result_spec_allow_null (struct GNUNET_PQ_ResultSpec rs, | ||
353 | bool *is_null); | ||
354 | |||
355 | |||
356 | /** | ||
306 | * Variable-size result expected. | 357 | * Variable-size result expected. |
307 | * | 358 | * |
308 | * @param name name of the field in the table | 359 | * @param name name of the field in the table |
diff --git a/src/pq/pq.c b/src/pq/pq.c index eca097e58..e9c960e33 100644 --- a/src/pq/pq.c +++ b/src/pq/pq.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2014, 2015, 2016, 2017, 2019 GNUnet e.V. | 3 | Copyright (C) 2014, 2015, 2016, 2017, 2019, 2020 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -27,14 +27,7 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "pq.h" | 28 | #include "pq.h" |
29 | 29 | ||
30 | /** | 30 | |
31 | * Execute a prepared statement. | ||
32 | * | ||
33 | * @param db database handle | ||
34 | * @param name name of the prepared statement | ||
35 | * @param params parameters to the statement | ||
36 | * @return postgres result | ||
37 | */ | ||
38 | PGresult * | 31 | PGresult * |
39 | GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db, | 32 | GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db, |
40 | const char *name, | 33 | const char *name, |
@@ -120,12 +113,6 @@ GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db, | |||
120 | } | 113 | } |
121 | 114 | ||
122 | 115 | ||
123 | /** | ||
124 | * Free all memory that was allocated in @a rs during | ||
125 | * #GNUNET_PQ_extract_result(). | ||
126 | * | ||
127 | * @param rs reult specification to clean up | ||
128 | */ | ||
129 | void | 116 | void |
130 | GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) | 117 | GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) |
131 | { | 118 | { |
@@ -136,17 +123,6 @@ GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) | |||
136 | } | 123 | } |
137 | 124 | ||
138 | 125 | ||
139 | /** | ||
140 | * Extract results from a query result according to the given | ||
141 | * specification. | ||
142 | * | ||
143 | * @param result result to process | ||
144 | * @param[in,out] rs result specification to extract for | ||
145 | * @param row row from the result to extract | ||
146 | * @return | ||
147 | * #GNUNET_YES if all results could be extracted | ||
148 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | ||
149 | */ | ||
150 | int | 126 | int |
151 | GNUNET_PQ_extract_result (PGresult *result, | 127 | GNUNET_PQ_extract_result (PGresult *result, |
152 | struct GNUNET_PQ_ResultSpec *rs, | 128 | struct GNUNET_PQ_ResultSpec *rs, |
@@ -160,6 +136,23 @@ GNUNET_PQ_extract_result (PGresult *result, | |||
160 | int ret; | 136 | int ret; |
161 | 137 | ||
162 | spec = &rs[i]; | 138 | spec = &rs[i]; |
139 | if (spec->is_nullable) | ||
140 | { | ||
141 | int fnum; | ||
142 | |||
143 | fnum = PQfnumber (result, | ||
144 | spec->fname); | ||
145 | if (PQgetisnull (result, | ||
146 | row, | ||
147 | fnum)) | ||
148 | { | ||
149 | if (NULL != spec->is_null) | ||
150 | *spec->is_null = true; | ||
151 | continue; | ||
152 | } | ||
153 | if (NULL != spec->is_null) | ||
154 | *spec->is_null = false; | ||
155 | } | ||
163 | ret = spec->conv (spec->cls, | 156 | ret = spec->conv (spec->cls, |
164 | result, | 157 | result, |
165 | row, | 158 | row, |
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index a36848f3a..cee84d203 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2014, 2015, 2016 GNUnet e.V. | 3 | Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -42,6 +42,56 @@ | |||
42 | * @return -1 on error, number of offsets used in @a scratch otherwise | 42 | * @return -1 on error, number of offsets used in @a scratch otherwise |
43 | */ | 43 | */ |
44 | static int | 44 | static int |
45 | qconv_null (void *cls, | ||
46 | const void *data, | ||
47 | size_t data_len, | ||
48 | void *param_values[], | ||
49 | int param_lengths[], | ||
50 | int param_formats[], | ||
51 | unsigned int param_length, | ||
52 | void *scratch[], | ||
53 | unsigned int scratch_length) | ||
54 | { | ||
55 | (void) scratch; | ||
56 | (void) scratch_length; | ||
57 | (void) data; | ||
58 | (void) data_len; | ||
59 | GNUNET_break (NULL == cls); | ||
60 | if (1 != param_length) | ||
61 | return -1; | ||
62 | param_values[0] = NULL; | ||
63 | param_lengths[0] = 0; | ||
64 | param_formats[0] = 1; | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | |||
69 | struct GNUNET_PQ_QueryParam | ||
70 | GNUNET_PQ_query_param_null (void) | ||
71 | { | ||
72 | struct GNUNET_PQ_QueryParam res = { | ||
73 | &qconv_null, NULL, NULL, 0, 1 | ||
74 | }; | ||
75 | |||
76 | return res; | ||
77 | } | ||
78 | |||
79 | |||
80 | /** | ||
81 | * Function called to convert input argument into SQL parameters. | ||
82 | * | ||
83 | * @param cls closure | ||
84 | * @param data pointer to input argument | ||
85 | * @param data_len number of bytes in @a data (if applicable) | ||
86 | * @param[out] param_values SQL data to set | ||
87 | * @param[out] param_lengths SQL length data to set | ||
88 | * @param[out] param_formats SQL format data to set | ||
89 | * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays | ||
90 | * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() | ||
91 | * @param scratch_length number of entries left in @a scratch | ||
92 | * @return -1 on error, number of offsets used in @a scratch otherwise | ||
93 | */ | ||
94 | static int | ||
45 | qconv_fixed (void *cls, | 95 | qconv_fixed (void *cls, |
46 | const void *data, | 96 | const void *data, |
47 | size_t data_len, | 97 | size_t data_len, |
@@ -64,33 +114,23 @@ qconv_fixed (void *cls, | |||
64 | } | 114 | } |
65 | 115 | ||
66 | 116 | ||
67 | /** | ||
68 | * Generate query parameter for a buffer @a ptr of | ||
69 | * @a ptr_size bytes. | ||
70 | * | ||
71 | * @param ptr pointer to the query parameter to pass | ||
72 | * @oaran ptr_size number of bytes in @a ptr | ||
73 | */ | ||
74 | struct GNUNET_PQ_QueryParam | 117 | struct GNUNET_PQ_QueryParam |
75 | GNUNET_PQ_query_param_fixed_size (const void *ptr, | 118 | GNUNET_PQ_query_param_fixed_size (const void *ptr, |
76 | size_t ptr_size) | 119 | size_t ptr_size) |
77 | { | 120 | { |
78 | struct GNUNET_PQ_QueryParam res = | 121 | struct GNUNET_PQ_QueryParam res = { |
79 | { &qconv_fixed, NULL, ptr, ptr_size, 1 }; | 122 | &qconv_fixed, NULL, ptr, ptr_size, 1 |
123 | }; | ||
80 | 124 | ||
81 | return res; | 125 | return res; |
82 | } | 126 | } |
83 | 127 | ||
84 | 128 | ||
85 | /** | ||
86 | * Generate query parameter for a string. | ||
87 | * | ||
88 | * @param ptr pointer to the string query parameter to pass | ||
89 | */ | ||
90 | struct GNUNET_PQ_QueryParam | 129 | struct GNUNET_PQ_QueryParam |
91 | GNUNET_PQ_query_param_string (const char *ptr) | 130 | GNUNET_PQ_query_param_string (const char *ptr) |
92 | { | 131 | { |
93 | return GNUNET_PQ_query_param_fixed_size (ptr, strlen (ptr)); | 132 | return GNUNET_PQ_query_param_fixed_size (ptr, |
133 | strlen (ptr)); | ||
94 | } | 134 | } |
95 | 135 | ||
96 | 136 | ||
@@ -137,11 +177,6 @@ qconv_uint16 (void *cls, | |||
137 | } | 177 | } |
138 | 178 | ||
139 | 179 | ||
140 | /** | ||
141 | * Generate query parameter for an uint16_t in host byte order. | ||
142 | * | ||
143 | * @param x pointer to the query parameter to pass | ||
144 | */ | ||
145 | struct GNUNET_PQ_QueryParam | 180 | struct GNUNET_PQ_QueryParam |
146 | GNUNET_PQ_query_param_uint16 (const uint16_t *x) | 181 | GNUNET_PQ_query_param_uint16 (const uint16_t *x) |
147 | { | 182 | { |
@@ -195,11 +230,6 @@ qconv_uint32 (void *cls, | |||
195 | } | 230 | } |
196 | 231 | ||
197 | 232 | ||
198 | /** | ||
199 | * Generate query parameter for an uint32_t in host byte order. | ||
200 | * | ||
201 | * @param x pointer to the query parameter to pass | ||
202 | */ | ||
203 | struct GNUNET_PQ_QueryParam | 233 | struct GNUNET_PQ_QueryParam |
204 | GNUNET_PQ_query_param_uint32 (const uint32_t *x) | 234 | GNUNET_PQ_query_param_uint32 (const uint32_t *x) |
205 | { | 235 | { |
@@ -253,11 +283,6 @@ qconv_uint64 (void *cls, | |||
253 | } | 283 | } |
254 | 284 | ||
255 | 285 | ||
256 | /** | ||
257 | * Generate query parameter for an uint64_t in host byte order. | ||
258 | * | ||
259 | * @param x pointer to the query parameter to pass | ||
260 | */ | ||
261 | struct GNUNET_PQ_QueryParam | 286 | struct GNUNET_PQ_QueryParam |
262 | GNUNET_PQ_query_param_uint64 (const uint64_t *x) | 287 | GNUNET_PQ_query_param_uint64 (const uint64_t *x) |
263 | { | 288 | { |
@@ -310,13 +335,6 @@ qconv_rsa_public_key (void *cls, | |||
310 | } | 335 | } |
311 | 336 | ||
312 | 337 | ||
313 | /** | ||
314 | * Generate query parameter for an RSA public key. The | ||
315 | * database must contain a BLOB type in the respective position. | ||
316 | * | ||
317 | * @param x the query parameter to pass | ||
318 | * @return array entry for the query parameters to use | ||
319 | */ | ||
320 | struct GNUNET_PQ_QueryParam | 338 | struct GNUNET_PQ_QueryParam |
321 | GNUNET_PQ_query_param_rsa_public_key (const struct | 339 | GNUNET_PQ_query_param_rsa_public_key (const struct |
322 | GNUNET_CRYPTO_RsaPublicKey *x) | 340 | GNUNET_CRYPTO_RsaPublicKey *x) |
@@ -370,13 +388,6 @@ qconv_rsa_signature (void *cls, | |||
370 | } | 388 | } |
371 | 389 | ||
372 | 390 | ||
373 | /** | ||
374 | * Generate query parameter for an RSA signature. The | ||
375 | * database must contain a BLOB type in the respective position. | ||
376 | * | ||
377 | * @param x the query parameter to pass | ||
378 | * @return array entry for the query parameters to use | ||
379 | */ | ||
380 | struct GNUNET_PQ_QueryParam | 391 | struct GNUNET_PQ_QueryParam |
381 | GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) | 392 | GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) |
382 | { | 393 | { |
@@ -432,13 +443,6 @@ qconv_rel_time (void *cls, | |||
432 | } | 443 | } |
433 | 444 | ||
434 | 445 | ||
435 | /** | ||
436 | * Generate query parameter for a relative time value. | ||
437 | * The database must store a 64-bit integer. | ||
438 | * | ||
439 | * @param x pointer to the query parameter to pass | ||
440 | * @return array entry for the query parameters to use | ||
441 | */ | ||
442 | struct GNUNET_PQ_QueryParam | 446 | struct GNUNET_PQ_QueryParam |
443 | GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x) | 447 | GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x) |
444 | { | 448 | { |
@@ -494,29 +498,17 @@ qconv_abs_time (void *cls, | |||
494 | } | 498 | } |
495 | 499 | ||
496 | 500 | ||
497 | /** | ||
498 | * Generate query parameter for an absolute time value. | ||
499 | * The database must store a 64-bit integer. | ||
500 | * | ||
501 | * @param x pointer to the query parameter to pass | ||
502 | * @return array entry for the query parameters to use | ||
503 | */ | ||
504 | struct GNUNET_PQ_QueryParam | 501 | struct GNUNET_PQ_QueryParam |
505 | GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) | 502 | GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) |
506 | { | 503 | { |
507 | struct GNUNET_PQ_QueryParam res = | 504 | struct GNUNET_PQ_QueryParam res = { |
508 | { &qconv_abs_time, NULL, x, sizeof(*x), 1 }; | 505 | &qconv_abs_time, NULL, x, sizeof(*x), 1 |
506 | }; | ||
509 | 507 | ||
510 | return res; | 508 | return res; |
511 | } | 509 | } |
512 | 510 | ||
513 | 511 | ||
514 | /** | ||
515 | * Generate query parameter for an absolute time value. | ||
516 | * The database must store a 64-bit integer. | ||
517 | * | ||
518 | * @param x pointer to the query parameter to pass | ||
519 | */ | ||
520 | struct GNUNET_PQ_QueryParam | 512 | struct GNUNET_PQ_QueryParam |
521 | GNUNET_PQ_query_param_absolute_time_nbo (const struct | 513 | GNUNET_PQ_query_param_absolute_time_nbo (const struct |
522 | GNUNET_TIME_AbsoluteNBO *x) | 514 | GNUNET_TIME_AbsoluteNBO *x) |
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index f764593b0..546822e45 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2014, 2015, 2016 GNUnet e.V. | 3 | Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -27,6 +27,19 @@ | |||
27 | #include "gnunet_pq_lib.h" | 27 | #include "gnunet_pq_lib.h" |
28 | 28 | ||
29 | 29 | ||
30 | struct GNUNET_PQ_ResultSpec | ||
31 | GNUNET_PQ_result_spec_allow_null (struct GNUNET_PQ_ResultSpec rs, | ||
32 | bool *is_null) | ||
33 | { | ||
34 | struct GNUNET_PQ_ResultSpec rsr; | ||
35 | |||
36 | rsr = rs; | ||
37 | rsr.is_nullable = true; | ||
38 | rsr.is_null = is_null; | ||
39 | return rsr; | ||
40 | } | ||
41 | |||
42 | |||
30 | /** | 43 | /** |
31 | * Function called to clean up memory allocated | 44 | * Function called to clean up memory allocated |
32 | * by a #GNUNET_PQ_ResultConverter. | 45 | * by a #GNUNET_PQ_ResultConverter. |
@@ -112,14 +125,6 @@ extract_varsize_blob (void *cls, | |||
112 | } | 125 | } |
113 | 126 | ||
114 | 127 | ||
115 | /** | ||
116 | * Variable-size result expected. | ||
117 | * | ||
118 | * @param name name of the field in the table | ||
119 | * @param[out] dst where to store the result, allocated | ||
120 | * @param[out] sptr where to store the size of @a dst | ||
121 | * @return array entry for the result specification to use | ||
122 | */ | ||
123 | struct GNUNET_PQ_ResultSpec | 128 | struct GNUNET_PQ_ResultSpec |
124 | GNUNET_PQ_result_spec_variable_size (const char *name, | 129 | GNUNET_PQ_result_spec_variable_size (const char *name, |
125 | void **dst, | 130 | void **dst, |
@@ -196,14 +201,6 @@ extract_fixed_blob (void *cls, | |||
196 | } | 201 | } |
197 | 202 | ||
198 | 203 | ||
199 | /** | ||
200 | * Fixed-size result expected. | ||
201 | * | ||
202 | * @param name name of the field in the table | ||
203 | * @param[out] dst where to store the result | ||
204 | * @param dst_size number of bytes in @a dst | ||
205 | * @return array entry for the result specification to use | ||
206 | */ | ||
207 | struct GNUNET_PQ_ResultSpec | 204 | struct GNUNET_PQ_ResultSpec |
208 | GNUNET_PQ_result_spec_fixed_size (const char *name, | 205 | GNUNET_PQ_result_spec_fixed_size (const char *name, |
209 | void *dst, | 206 | void *dst, |
@@ -301,13 +298,6 @@ clean_rsa_public_key (void *cls, | |||
301 | } | 298 | } |
302 | 299 | ||
303 | 300 | ||
304 | /** | ||
305 | * RSA public key expected. | ||
306 | * | ||
307 | * @param name name of the field in the table | ||
308 | * @param[out] rsa where to store the result | ||
309 | * @return array entry for the result specification to use | ||
310 | */ | ||
311 | struct GNUNET_PQ_ResultSpec | 301 | struct GNUNET_PQ_ResultSpec |
312 | GNUNET_PQ_result_spec_rsa_public_key (const char *name, | 302 | GNUNET_PQ_result_spec_rsa_public_key (const char *name, |
313 | struct GNUNET_CRYPTO_RsaPublicKey **rsa) | 303 | struct GNUNET_CRYPTO_RsaPublicKey **rsa) |
@@ -405,13 +395,6 @@ clean_rsa_signature (void *cls, | |||
405 | } | 395 | } |
406 | 396 | ||
407 | 397 | ||
408 | /** | ||
409 | * RSA signature expected. | ||
410 | * | ||
411 | * @param name name of the field in the table | ||
412 | * @param[out] sig where to store the result; | ||
413 | * @return array entry for the result specification to use | ||
414 | */ | ||
415 | struct GNUNET_PQ_ResultSpec | 398 | struct GNUNET_PQ_ResultSpec |
416 | GNUNET_PQ_result_spec_rsa_signature (const char *name, | 399 | GNUNET_PQ_result_spec_rsa_signature (const char *name, |
417 | struct GNUNET_CRYPTO_RsaSignature **sig) | 400 | struct GNUNET_CRYPTO_RsaSignature **sig) |
@@ -509,13 +492,6 @@ clean_string (void *cls, | |||
509 | } | 492 | } |
510 | 493 | ||
511 | 494 | ||
512 | /** | ||
513 | * 0-terminated string expected. | ||
514 | * | ||
515 | * @param name name of the field in the table | ||
516 | * @param[out] dst where to store the result, allocated | ||
517 | * @return array entry for the result specification to use | ||
518 | */ | ||
519 | struct GNUNET_PQ_ResultSpec | 495 | struct GNUNET_PQ_ResultSpec |
520 | GNUNET_PQ_result_spec_string (const char *name, | 496 | GNUNET_PQ_result_spec_string (const char *name, |
521 | char **dst) | 497 | char **dst) |
@@ -595,13 +571,6 @@ extract_rel_time (void *cls, | |||
595 | } | 571 | } |
596 | 572 | ||
597 | 573 | ||
598 | /** | ||
599 | * Relative time expected. | ||
600 | * | ||
601 | * @param name name of the field in the table | ||
602 | * @param[out] at where to store the result | ||
603 | * @return array entry for the result specification to use | ||
604 | */ | ||
605 | struct GNUNET_PQ_ResultSpec | 574 | struct GNUNET_PQ_ResultSpec |
606 | GNUNET_PQ_result_spec_relative_time (const char *name, | 575 | GNUNET_PQ_result_spec_relative_time (const char *name, |
607 | struct GNUNET_TIME_Relative *rt) | 576 | struct GNUNET_TIME_Relative *rt) |
@@ -685,13 +654,6 @@ extract_abs_time (void *cls, | |||
685 | } | 654 | } |
686 | 655 | ||
687 | 656 | ||
688 | /** | ||
689 | * Absolute time expected. | ||
690 | * | ||
691 | * @param name name of the field in the table | ||
692 | * @param[out] at where to store the result | ||
693 | * @return array entry for the result specification to use | ||
694 | */ | ||
695 | struct GNUNET_PQ_ResultSpec | 657 | struct GNUNET_PQ_ResultSpec |
696 | GNUNET_PQ_result_spec_absolute_time (const char *name, | 658 | GNUNET_PQ_result_spec_absolute_time (const char *name, |
697 | struct GNUNET_TIME_Absolute *at) | 659 | struct GNUNET_TIME_Absolute *at) |
@@ -706,13 +668,6 @@ GNUNET_PQ_result_spec_absolute_time (const char *name, | |||
706 | } | 668 | } |
707 | 669 | ||
708 | 670 | ||
709 | /** | ||
710 | * Absolute time in network byte order expected. | ||
711 | * | ||
712 | * @param name name of the field in the table | ||
713 | * @param[out] at where to store the result | ||
714 | * @return array entry for the result specification to use | ||
715 | */ | ||
716 | struct GNUNET_PQ_ResultSpec | 671 | struct GNUNET_PQ_ResultSpec |
717 | GNUNET_PQ_result_spec_absolute_time_nbo (const char *name, | 672 | GNUNET_PQ_result_spec_absolute_time_nbo (const char *name, |
718 | struct GNUNET_TIME_AbsoluteNBO *at) | 673 | struct GNUNET_TIME_AbsoluteNBO *at) |
@@ -786,13 +741,6 @@ extract_uint16 (void *cls, | |||
786 | } | 741 | } |
787 | 742 | ||
788 | 743 | ||
789 | /** | ||
790 | * uint16_t expected. | ||
791 | * | ||
792 | * @param name name of the field in the table | ||
793 | * @param[out] u16 where to store the result | ||
794 | * @return array entry for the result specification to use | ||
795 | */ | ||
796 | struct GNUNET_PQ_ResultSpec | 744 | struct GNUNET_PQ_ResultSpec |
797 | GNUNET_PQ_result_spec_uint16 (const char *name, | 745 | GNUNET_PQ_result_spec_uint16 (const char *name, |
798 | uint16_t *u16) | 746 | uint16_t *u16) |
@@ -869,13 +817,6 @@ extract_uint32 (void *cls, | |||
869 | } | 817 | } |
870 | 818 | ||
871 | 819 | ||
872 | /** | ||
873 | * uint32_t expected. | ||
874 | * | ||
875 | * @param name name of the field in the table | ||
876 | * @param[out] u32 where to store the result | ||
877 | * @return array entry for the result specification to use | ||
878 | */ | ||
879 | struct GNUNET_PQ_ResultSpec | 820 | struct GNUNET_PQ_ResultSpec |
880 | GNUNET_PQ_result_spec_uint32 (const char *name, | 821 | GNUNET_PQ_result_spec_uint32 (const char *name, |
881 | uint32_t *u32) | 822 | uint32_t *u32) |
@@ -952,22 +893,16 @@ extract_uint64 (void *cls, | |||
952 | } | 893 | } |
953 | 894 | ||
954 | 895 | ||
955 | /** | ||
956 | * uint64_t expected. | ||
957 | * | ||
958 | * @param name name of the field in the table | ||
959 | * @param[out] u64 where to store the result | ||
960 | * @return array entry for the result specification to use | ||
961 | */ | ||
962 | struct GNUNET_PQ_ResultSpec | 896 | struct GNUNET_PQ_ResultSpec |
963 | GNUNET_PQ_result_spec_uint64 (const char *name, | 897 | GNUNET_PQ_result_spec_uint64 (const char *name, |
964 | uint64_t *u64) | 898 | uint64_t *u64) |
965 | { | 899 | { |
966 | struct GNUNET_PQ_ResultSpec res = | 900 | struct GNUNET_PQ_ResultSpec res = { |
967 | { &extract_uint64, | 901 | &extract_uint64, |
968 | NULL, | 902 | NULL, |
969 | NULL, | 903 | NULL, |
970 | (void *) u64, sizeof(*u64), (name), NULL }; | 904 | (void *) u64, sizeof(*u64), (name), NULL |
905 | }; | ||
971 | 906 | ||
972 | return res; | 907 | return res; |
973 | } | 908 | } |
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index b09354af8..e588da45d 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c | |||
@@ -47,10 +47,11 @@ postgres_prepare (struct GNUNET_PQ_Context *db) | |||
47 | ",u16" | 47 | ",u16" |
48 | ",u32" | 48 | ",u32" |
49 | ",u64" | 49 | ",u64" |
50 | ",unn" | ||
50 | ") VALUES " | 51 | ") VALUES " |
51 | "($1, $2, $3, $4, $5, $6," | 52 | "($1, $2, $3, $4, $5, $6," |
52 | "$7, $8, $9);", | 53 | "$7, $8, $9, $10);", |
53 | 9), | 54 | 10), |
54 | GNUNET_PQ_make_prepare ("test_select", | 55 | GNUNET_PQ_make_prepare ("test_select", |
55 | "SELECT" | 56 | "SELECT" |
56 | " pub" | 57 | " pub" |
@@ -62,6 +63,7 @@ postgres_prepare (struct GNUNET_PQ_Context *db) | |||
62 | ",u16" | 63 | ",u16" |
63 | ",u32" | 64 | ",u32" |
64 | ",u64" | 65 | ",u64" |
66 | ",unn" | ||
65 | " FROM test_pq" | 67 | " FROM test_pq" |
66 | " ORDER BY abs_time DESC " | 68 | " ORDER BY abs_time DESC " |
67 | " LIMIT 1;", | 69 | " LIMIT 1;", |
@@ -106,7 +108,8 @@ run_queries (struct GNUNET_PQ_Context *db) | |||
106 | uint32_t u322; | 108 | uint32_t u322; |
107 | uint64_t u64; | 109 | uint64_t u64; |
108 | uint64_t u642; | 110 | uint64_t u642; |
109 | 111 | uint64_t uzzz = 42; | |
112 | |||
110 | priv = GNUNET_CRYPTO_rsa_private_key_create (1024); | 113 | priv = GNUNET_CRYPTO_rsa_private_key_create (1024); |
111 | pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv); | 114 | pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv); |
112 | memset (&hmsg, 42, sizeof(hmsg)); | 115 | memset (&hmsg, 42, sizeof(hmsg)); |
@@ -127,11 +130,13 @@ run_queries (struct GNUNET_PQ_Context *db) | |||
127 | GNUNET_PQ_query_param_uint16 (&u16), | 130 | GNUNET_PQ_query_param_uint16 (&u16), |
128 | GNUNET_PQ_query_param_uint32 (&u32), | 131 | GNUNET_PQ_query_param_uint32 (&u32), |
129 | GNUNET_PQ_query_param_uint64 (&u64), | 132 | GNUNET_PQ_query_param_uint64 (&u64), |
133 | GNUNET_PQ_query_param_null (), | ||
130 | GNUNET_PQ_query_param_end | 134 | GNUNET_PQ_query_param_end |
131 | }; | 135 | }; |
132 | struct GNUNET_PQ_QueryParam params_select[] = { | 136 | struct GNUNET_PQ_QueryParam params_select[] = { |
133 | GNUNET_PQ_query_param_end | 137 | GNUNET_PQ_query_param_end |
134 | }; | 138 | }; |
139 | bool got_null = false; | ||
135 | struct GNUNET_PQ_ResultSpec results_select[] = { | 140 | struct GNUNET_PQ_ResultSpec results_select[] = { |
136 | GNUNET_PQ_result_spec_rsa_public_key ("pub", &pub2), | 141 | GNUNET_PQ_result_spec_rsa_public_key ("pub", &pub2), |
137 | GNUNET_PQ_result_spec_rsa_signature ("sig", &sig2), | 142 | GNUNET_PQ_result_spec_rsa_signature ("sig", &sig2), |
@@ -142,6 +147,9 @@ run_queries (struct GNUNET_PQ_Context *db) | |||
142 | GNUNET_PQ_result_spec_uint16 ("u16", &u162), | 147 | GNUNET_PQ_result_spec_uint16 ("u16", &u162), |
143 | GNUNET_PQ_result_spec_uint32 ("u32", &u322), | 148 | GNUNET_PQ_result_spec_uint32 ("u32", &u322), |
144 | GNUNET_PQ_result_spec_uint64 ("u64", &u642), | 149 | GNUNET_PQ_result_spec_uint64 ("u64", &u642), |
150 | GNUNET_PQ_result_spec_allow_null ( | ||
151 | GNUNET_PQ_result_spec_uint64 ("unn", &uzzz), | ||
152 | &got_null), | ||
145 | GNUNET_PQ_result_spec_end | 153 | GNUNET_PQ_result_spec_end |
146 | }; | 154 | }; |
147 | 155 | ||
@@ -197,6 +205,8 @@ run_queries (struct GNUNET_PQ_Context *db) | |||
197 | GNUNET_break (16 == u162); | 205 | GNUNET_break (16 == u162); |
198 | GNUNET_break (32 == u322); | 206 | GNUNET_break (32 == u322); |
199 | GNUNET_break (64 == u642); | 207 | GNUNET_break (64 == u642); |
208 | GNUNET_break (42 == uzzz); | ||
209 | GNUNET_break (got_null); | ||
200 | GNUNET_PQ_cleanup_result (results_select); | 210 | GNUNET_PQ_cleanup_result (results_select); |
201 | PQclear (result); | 211 | PQclear (result); |
202 | } | 212 | } |
@@ -225,6 +235,7 @@ main (int argc, | |||
225 | ",u16 INT2 NOT NULL" | 235 | ",u16 INT2 NOT NULL" |
226 | ",u32 INT4 NOT NULL" | 236 | ",u32 INT4 NOT NULL" |
227 | ",u64 INT8 NOT NULL" | 237 | ",u64 INT8 NOT NULL" |
238 | ",unn INT8" | ||
228 | ")"), | 239 | ")"), |
229 | GNUNET_PQ_EXECUTE_STATEMENT_END | 240 | GNUNET_PQ_EXECUTE_STATEMENT_END |
230 | }; | 241 | }; |