diff options
Diffstat (limited to 'src/sq')
-rw-r--r-- | src/sq/Makefile.am | 2 | ||||
-rw-r--r-- | src/sq/sq.c | 34 | ||||
-rw-r--r-- | src/sq/sq_query_helper.c | 52 | ||||
-rw-r--r-- | src/sq/sq_result_helper.c | 74 | ||||
-rw-r--r-- | src/sq/test_sq.c | 20 |
5 files changed, 171 insertions, 11 deletions
diff --git a/src/sq/Makefile.am b/src/sq/Makefile.am index c5f80bcf6..cfccd89f6 100644 --- a/src/sq/Makefile.am +++ b/src/sq/Makefile.am | |||
@@ -9,7 +9,7 @@ if USE_COVERAGE | |||
9 | AM_CFLAGS = --coverage | 9 | AM_CFLAGS = --coverage |
10 | endif | 10 | endif |
11 | 11 | ||
12 | if HAVE_POSTGRESQL | 12 | if HAVE_SQLITE |
13 | lib_LTLIBRARIES = libgnunetsq.la | 13 | lib_LTLIBRARIES = libgnunetsq.la |
14 | endif | 14 | endif |
15 | 15 | ||
diff --git a/src/sq/sq.c b/src/sq/sq.c index dc4416761..089ebf0ff 100644 --- a/src/sq/sq.c +++ b/src/sq/sq.c | |||
@@ -49,7 +49,14 @@ GNUNET_SQ_bind (sqlite3_stmt *stmt, | |||
49 | "sq", | 49 | "sq", |
50 | _("Failure to bind %u-th SQL parameter\n"), | 50 | _("Failure to bind %u-th SQL parameter\n"), |
51 | i); | 51 | i); |
52 | return GNUNET_SYSERR; | 52 | if (SQLITE_OK != |
53 | sqlite3_reset (stmt)) | ||
54 | { | ||
55 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
56 | "sq", | ||
57 | _("Failure in sqlite3_reset (!)\n")); | ||
58 | return GNUNET_SYSERR; | ||
59 | } | ||
53 | } | 60 | } |
54 | GNUNET_assert (0 != params[i].num_params); | 61 | GNUNET_assert (0 != params[i].num_params); |
55 | j += params[i].num_params; | 62 | j += params[i].num_params; |
@@ -83,7 +90,12 @@ GNUNET_SQ_extract_result (sqlite3_stmt *result, | |||
83 | j, | 90 | j, |
84 | rs[i].result_size, | 91 | rs[i].result_size, |
85 | rs[i].dst)) | 92 | rs[i].dst)) |
93 | { | ||
94 | for (unsigned int k=0;k<i;k++) | ||
95 | if (NULL != rs[k].cleaner) | ||
96 | rs[k].cleaner (rs[k].cls); | ||
86 | return GNUNET_SYSERR; | 97 | return GNUNET_SYSERR; |
98 | } | ||
87 | GNUNET_assert (0 != rs[i].num_params); | 99 | GNUNET_assert (0 != rs[i].num_params); |
88 | j += rs[i].num_params; | 100 | j += rs[i].num_params; |
89 | } | 101 | } |
@@ -105,4 +117,24 @@ GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs) | |||
105 | rs[i].cleaner (rs[i].cls); | 117 | rs[i].cleaner (rs[i].cls); |
106 | } | 118 | } |
107 | 119 | ||
120 | |||
121 | /** | ||
122 | * Reset @a stmt and log error. | ||
123 | * | ||
124 | * @param dbh database handle | ||
125 | * @param stmt statement to reset | ||
126 | */ | ||
127 | void | ||
128 | GNUNET_SQ_reset (sqlite3 *dbh, | ||
129 | sqlite3_stmt *stmt) | ||
130 | { | ||
131 | if (SQLITE_OK != | ||
132 | sqlite3_reset (stmt)) | ||
133 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
134 | "sqlite", | ||
135 | _("Failed to reset sqlite statement with error: %s\n"), | ||
136 | sqlite3_errmsg (dbh)); | ||
137 | } | ||
138 | |||
139 | |||
108 | /* end of sq.c */ | 140 | /* end of sq.c */ |
diff --git a/src/sq/sq_query_helper.c b/src/sq/sq_query_helper.c index 5529c5e6c..94a3a3f1c 100644 --- a/src/sq/sq_query_helper.c +++ b/src/sq/sq_query_helper.c | |||
@@ -90,6 +90,14 @@ bind_string (void *cls, | |||
90 | sqlite3_stmt *stmt, | 90 | sqlite3_stmt *stmt, |
91 | unsigned int off) | 91 | unsigned int off) |
92 | { | 92 | { |
93 | if (NULL == data) | ||
94 | { | ||
95 | if (SQLITE_OK != | ||
96 | sqlite3_bind_null (stmt, | ||
97 | (int) off)) | ||
98 | return GNUNET_SYSERR; | ||
99 | return GNUNET_OK; | ||
100 | } | ||
93 | if (SQLITE_OK != | 101 | if (SQLITE_OK != |
94 | sqlite3_bind_text (stmt, | 102 | sqlite3_bind_text (stmt, |
95 | (int) off, | 103 | (int) off, |
@@ -235,6 +243,40 @@ GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) | |||
235 | 243 | ||
236 | 244 | ||
237 | /** | 245 | /** |
246 | * Function called to convert input argument into SQL parameters. | ||
247 | * | ||
248 | * @param cls closure | ||
249 | * @param data pointer to input argument | ||
250 | * @param data_len number of bytes in @a data (if applicable) | ||
251 | * @param stmt sqlite statement to bind parameters for | ||
252 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
253 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
254 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
255 | */ | ||
256 | static int | ||
257 | bind_abstime (void *cls, | ||
258 | const void *data, | ||
259 | size_t data_len, | ||
260 | sqlite3_stmt *stmt, | ||
261 | unsigned int off) | ||
262 | { | ||
263 | const struct GNUNET_TIME_Absolute *u = data; | ||
264 | struct GNUNET_TIME_Absolute abs; | ||
265 | |||
266 | abs = *u; | ||
267 | if (abs.abs_value_us > INT64_MAX) | ||
268 | abs.abs_value_us = INT64_MAX; | ||
269 | GNUNET_assert (sizeof (uint64_t) == data_len); | ||
270 | if (SQLITE_OK != | ||
271 | sqlite3_bind_int64 (stmt, | ||
272 | (int) off, | ||
273 | (sqlite3_int64) abs.abs_value_us)) | ||
274 | return GNUNET_SYSERR; | ||
275 | return GNUNET_OK; | ||
276 | } | ||
277 | |||
278 | |||
279 | /** | ||
238 | * Generate query parameter for an absolute time value. | 280 | * Generate query parameter for an absolute time value. |
239 | * The database must store a 64-bit integer. | 281 | * The database must store a 64-bit integer. |
240 | * | 282 | * |
@@ -243,7 +285,13 @@ GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) | |||
243 | struct GNUNET_SQ_QueryParam | 285 | struct GNUNET_SQ_QueryParam |
244 | GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) | 286 | GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) |
245 | { | 287 | { |
246 | return GNUNET_SQ_query_param_uint64 (&x->abs_value_us); | 288 | struct GNUNET_SQ_QueryParam qp = { |
289 | .conv = &bind_abstime, | ||
290 | .data = x, | ||
291 | .size = sizeof (struct GNUNET_TIME_Absolute), | ||
292 | .num_params = 1 | ||
293 | }; | ||
294 | return qp; | ||
247 | } | 295 | } |
248 | 296 | ||
249 | 297 | ||
@@ -269,6 +317,8 @@ bind_nbotime (void *cls, | |||
269 | struct GNUNET_TIME_Absolute abs; | 317 | struct GNUNET_TIME_Absolute abs; |
270 | 318 | ||
271 | abs = GNUNET_TIME_absolute_ntoh (*u); | 319 | abs = GNUNET_TIME_absolute_ntoh (*u); |
320 | if (abs.abs_value_us > INT64_MAX) | ||
321 | abs.abs_value_us = INT64_MAX; | ||
272 | GNUNET_assert (sizeof (uint64_t) == data_len); | 322 | GNUNET_assert (sizeof (uint64_t) == data_len); |
273 | if (SQLITE_OK != | 323 | if (SQLITE_OK != |
274 | sqlite3_bind_int64 (stmt, | 324 | sqlite3_bind_int64 (stmt, |
diff --git a/src/sq/sq_result_helper.c b/src/sq/sq_result_helper.c index eaf606aa4..9579863b2 100644 --- a/src/sq/sq_result_helper.c +++ b/src/sq/sq_result_helper.c | |||
@@ -46,6 +46,15 @@ extract_var_blob (void *cls, | |||
46 | const void *ret; | 46 | const void *ret; |
47 | void **rdst = (void **) dst; | 47 | void **rdst = (void **) dst; |
48 | 48 | ||
49 | if (SQLITE_NULL == | ||
50 | sqlite3_column_type (result, | ||
51 | column)) | ||
52 | { | ||
53 | *rdst = NULL; | ||
54 | *dst_size = 0; | ||
55 | return GNUNET_YES; | ||
56 | } | ||
57 | |||
49 | if (SQLITE_BLOB != | 58 | if (SQLITE_BLOB != |
50 | sqlite3_column_type (result, | 59 | sqlite3_column_type (result, |
51 | column)) | 60 | column)) |
@@ -142,6 +151,14 @@ extract_fixed_blob (void *cls, | |||
142 | int have; | 151 | int have; |
143 | const void *ret; | 152 | const void *ret; |
144 | 153 | ||
154 | if ( (0 == *dst_size) && | ||
155 | (SQLITE_NULL == | ||
156 | sqlite3_column_type (result, | ||
157 | column)) ) | ||
158 | { | ||
159 | return GNUNET_YES; | ||
160 | } | ||
161 | |||
145 | if (SQLITE_BLOB != | 162 | if (SQLITE_BLOB != |
146 | sqlite3_column_type (result, | 163 | sqlite3_column_type (result, |
147 | column)) | 164 | column)) |
@@ -211,6 +228,13 @@ extract_utf8_string (void *cls, | |||
211 | const char *text; | 228 | const char *text; |
212 | char **rdst = dst; | 229 | char **rdst = dst; |
213 | 230 | ||
231 | if (SQLITE_NULL == | ||
232 | sqlite3_column_type (result, | ||
233 | column)) | ||
234 | { | ||
235 | *rdst = NULL; | ||
236 | return GNUNET_OK; | ||
237 | } | ||
214 | if (SQLITE_TEXT != | 238 | if (SQLITE_TEXT != |
215 | sqlite3_column_type (result, | 239 | sqlite3_column_type (result, |
216 | column)) | 240 | column)) |
@@ -459,6 +483,45 @@ GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig) | |||
459 | 483 | ||
460 | 484 | ||
461 | /** | 485 | /** |
486 | * Extract absolute time value from a Postgres database @a result at row @a row. | ||
487 | * | ||
488 | * @param cls closure | ||
489 | * @param result where to extract data from | ||
490 | * @param column column to extract data from | ||
491 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
492 | * @param[out] dst where to store the result | ||
493 | * @return | ||
494 | * #GNUNET_YES if all results could be extracted | ||
495 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
496 | */ | ||
497 | static int | ||
498 | extract_abs_time (void *cls, | ||
499 | sqlite3_stmt *result, | ||
500 | unsigned int column, | ||
501 | size_t *dst_size, | ||
502 | void *dst) | ||
503 | { | ||
504 | struct GNUNET_TIME_Absolute *u = dst; | ||
505 | struct GNUNET_TIME_Absolute t; | ||
506 | |||
507 | GNUNET_assert (sizeof (uint64_t) == *dst_size); | ||
508 | if (SQLITE_INTEGER != | ||
509 | sqlite3_column_type (result, | ||
510 | column)) | ||
511 | { | ||
512 | GNUNET_break (0); | ||
513 | return GNUNET_SYSERR; | ||
514 | } | ||
515 | t.abs_value_us = (uint64_t) sqlite3_column_int64 (result, | ||
516 | column); | ||
517 | if (INT64_MAX == t.abs_value_us) | ||
518 | t = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
519 | *u = t; | ||
520 | return GNUNET_OK; | ||
521 | } | ||
522 | |||
523 | |||
524 | /** | ||
462 | * Absolute time expected. | 525 | * Absolute time expected. |
463 | * | 526 | * |
464 | * @param[out] at where to store the result | 527 | * @param[out] at where to store the result |
@@ -467,7 +530,14 @@ GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig) | |||
467 | struct GNUNET_SQ_ResultSpec | 530 | struct GNUNET_SQ_ResultSpec |
468 | GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at) | 531 | GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at) |
469 | { | 532 | { |
470 | return GNUNET_SQ_result_spec_uint64 (&at->abs_value_us); | 533 | struct GNUNET_SQ_ResultSpec rs = { |
534 | .conv = &extract_abs_time, | ||
535 | .dst = at, | ||
536 | .dst_size = sizeof (struct GNUNET_TIME_Absolute), | ||
537 | .num_params = 1 | ||
538 | }; | ||
539 | |||
540 | return rs; | ||
471 | } | 541 | } |
472 | 542 | ||
473 | 543 | ||
@@ -503,6 +573,8 @@ extract_abs_time_nbo (void *cls, | |||
503 | } | 573 | } |
504 | t.abs_value_us = (uint64_t) sqlite3_column_int64 (result, | 574 | t.abs_value_us = (uint64_t) sqlite3_column_int64 (result, |
505 | column); | 575 | column); |
576 | if (INT64_MAX == t.abs_value_us) | ||
577 | t = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
506 | *u = GNUNET_TIME_absolute_hton (t); | 578 | *u = GNUNET_TIME_absolute_hton (t); |
507 | return GNUNET_OK; | 579 | return GNUNET_OK; |
508 | } | 580 | } |
diff --git a/src/sq/test_sq.c b/src/sq/test_sq.c index e6896861e..713809030 100644 --- a/src/sq/test_sq.c +++ b/src/sq/test_sq.c | |||
@@ -253,8 +253,12 @@ main(int argc, | |||
253 | { | 253 | { |
254 | fprintf (stderr, | 254 | fprintf (stderr, |
255 | "Failed to create table\n"); | 255 | "Failed to create table\n"); |
256 | sqlite3_close (dbh); | 256 | GNUNET_break (SQLITE_OK == |
257 | unlink ("test.db"); | 257 | sqlite3_close (dbh)); |
258 | if (0 != unlink ("test.db")) | ||
259 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
260 | "unlink", | ||
261 | "test.db"); | ||
258 | return 1; | 262 | return 1; |
259 | } | 263 | } |
260 | 264 | ||
@@ -266,12 +270,14 @@ main(int argc, | |||
266 | { | 270 | { |
267 | fprintf (stderr, | 271 | fprintf (stderr, |
268 | "Failed to drop table\n"); | 272 | "Failed to drop table\n"); |
269 | sqlite3_close (dbh); | 273 | ret = 1; |
270 | unlink ("test.db"); | ||
271 | return 1; | ||
272 | } | 274 | } |
273 | sqlite3_close (dbh); | 275 | GNUNET_break (SQLITE_OK == |
274 | unlink ("test.db"); | 276 | sqlite3_close (dbh)); |
277 | if (0 != unlink ("test.db")) | ||
278 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
279 | "unlink", | ||
280 | "test.db"); | ||
275 | return ret; | 281 | return ret; |
276 | } | 282 | } |
277 | 283 | ||