aboutsummaryrefslogtreecommitdiff
path: root/src/sq
diff options
context:
space:
mode:
Diffstat (limited to 'src/sq')
-rw-r--r--src/sq/Makefile.am2
-rw-r--r--src/sq/sq.c34
-rw-r--r--src/sq/sq_query_helper.c52
-rw-r--r--src/sq/sq_result_helper.c74
-rw-r--r--src/sq/test_sq.c20
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
10endif 10endif
11 11
12if HAVE_POSTGRESQL 12if HAVE_SQLITE
13lib_LTLIBRARIES = libgnunetsq.la 13lib_LTLIBRARIES = libgnunetsq.la
14endif 14endif
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 */
127void
128GNUNET_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 */
256static int
257bind_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)
243struct GNUNET_SQ_QueryParam 285struct GNUNET_SQ_QueryParam
244GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) 286GNUNET_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 */
497static int
498extract_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)
467struct GNUNET_SQ_ResultSpec 530struct GNUNET_SQ_ResultSpec
468GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at) 531GNUNET_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