aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/plugin_datacache_sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datacache/plugin_datacache_sqlite.c')
-rw-r--r--src/datacache/plugin_datacache_sqlite.c504
1 files changed, 208 insertions, 296 deletions
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index 07a72957a..0cf77d6e6 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -29,16 +29,17 @@
29#include "gnunet_sq_lib.h" 29#include "gnunet_sq_lib.h"
30#include <sqlite3.h> 30#include <sqlite3.h>
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "datacache-sqlite", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "datacache-sqlite", __VA_ARGS__)
33 33
34#define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn) 34#define LOG_STRERROR_FILE(kind, op, fn) \
35 GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn)
35 36
36 37
37/** 38/**
38 * How much overhead do we assume per entry in the 39 * How much overhead do we assume per entry in the
39 * datacache? 40 * datacache?
40 */ 41 */
41#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36) 42#define OVERHEAD (sizeof (struct GNUNET_HashCode) + 36)
42 43
43/** 44/**
44 * Context for all functions in this plugin. 45 * Context for all functions in this plugin.
@@ -115,7 +116,16 @@ struct Plugin
115 * @param level log level 116 * @param level log level
116 * @param cmd failed command 117 * @param cmd failed command
117 */ 118 */
118#define LOG_SQLITE(db, level, cmd) do { LOG (level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db)); } while(0) 119#define LOG_SQLITE(db, level, cmd) \
120 do \
121 { \
122 LOG (level, \
123 _ ("`%s' failed at %s:%d with error: %s\n"), \
124 cmd, \
125 __FILE__, \
126 __LINE__, \
127 sqlite3_errmsg (db)); \
128 } while (0)
119 129
120 130
121/** 131/**
@@ -124,7 +134,21 @@ struct Plugin
124 * @param db database handle 134 * @param db database handle
125 * @param cmd SQL command to execute 135 * @param cmd SQL command to execute
126 */ 136 */
127#define SQLITE3_EXEC(db, cmd) do { emsg = NULL; if (SQLITE_OK != sqlite3_exec(db, cmd, NULL, NULL, &emsg)) { LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sqlite3_exec", __FILE__, __LINE__, emsg); sqlite3_free(emsg); } } while(0) 137#define SQLITE3_EXEC(db, cmd) \
138 do \
139 { \
140 emsg = NULL; \
141 if (SQLITE_OK != sqlite3_exec (db, cmd, NULL, NULL, &emsg)) \
142 { \
143 LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, \
144 _ ("`%s' failed at %s:%d with error: %s\n"), \
145 "sqlite3_exec", \
146 __FILE__, \
147 __LINE__, \
148 emsg); \
149 sqlite3_free (emsg); \
150 } \
151 } while (0)
128 152
129 153
130/** 154/**
@@ -137,9 +161,9 @@ struct Plugin
137 */ 161 */
138static int 162static int
139sq_prepare (sqlite3 *dbh, 163sq_prepare (sqlite3 *dbh,
140 const char *zSql, /* SQL statement, UTF-8 encoded */ 164 const char *zSql, /* SQL statement, UTF-8 encoded */
141 sqlite3_stmt **ppStmt) 165 sqlite3_stmt **ppStmt)
142{ /* OUT: Statement handle */ 166{ /* OUT: Statement handle */
143 char *dummy; 167 char *dummy;
144 168
145 return sqlite3_prepare (dbh, 169 return sqlite3_prepare (dbh,
@@ -166,58 +190,53 @@ sq_prepare (sqlite3 *dbh,
166 */ 190 */
167static ssize_t 191static ssize_t
168sqlite_plugin_put (void *cls, 192sqlite_plugin_put (void *cls,
169 const struct GNUNET_HashCode *key, 193 const struct GNUNET_HashCode *key,
170 uint32_t xor_distance, 194 uint32_t xor_distance,
171 size_t size, 195 size_t size,
172 const char *data, 196 const char *data,
173 enum GNUNET_BLOCK_Type type, 197 enum GNUNET_BLOCK_Type type,
174 struct GNUNET_TIME_Absolute discard_time, 198 struct GNUNET_TIME_Absolute discard_time,
175 unsigned int path_info_len, 199 unsigned int path_info_len,
176 const struct GNUNET_PeerIdentity *path_info) 200 const struct GNUNET_PeerIdentity *path_info)
177{ 201{
178 struct Plugin *plugin = cls; 202 struct Plugin *plugin = cls;
179 uint32_t type32 = type; 203 uint32_t type32 = type;
180 struct GNUNET_SQ_QueryParam params[] = { 204 struct GNUNET_SQ_QueryParam params[] =
181 GNUNET_SQ_query_param_uint32 (&type32), 205 {GNUNET_SQ_query_param_uint32 (&type32),
182 GNUNET_SQ_query_param_absolute_time (&discard_time), 206 GNUNET_SQ_query_param_absolute_time (&discard_time),
183 GNUNET_SQ_query_param_auto_from_type (key), 207 GNUNET_SQ_query_param_auto_from_type (key),
184 GNUNET_SQ_query_param_uint32 (&xor_distance), 208 GNUNET_SQ_query_param_uint32 (&xor_distance),
185 GNUNET_SQ_query_param_fixed_size (data, size), 209 GNUNET_SQ_query_param_fixed_size (data, size),
186 GNUNET_SQ_query_param_fixed_size (path_info, 210 GNUNET_SQ_query_param_fixed_size (path_info,
187 path_info_len * sizeof (struct GNUNET_PeerIdentity)), 211 path_info_len *
188 GNUNET_SQ_query_param_end 212 sizeof (struct GNUNET_PeerIdentity)),
189 }; 213 GNUNET_SQ_query_param_end};
190 214
191 LOG (GNUNET_ERROR_TYPE_DEBUG, 215 LOG (GNUNET_ERROR_TYPE_DEBUG,
192 "Processing PUT of %u bytes with key `%s' and expiration %s\n", 216 "Processing PUT of %u bytes with key `%s' and expiration %s\n",
193 (unsigned int) size, 217 (unsigned int) size,
194 GNUNET_h2s (key), 218 GNUNET_h2s (key),
195 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (discard_time), 219 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (
220 discard_time),
196 GNUNET_YES)); 221 GNUNET_YES));
197 if (GNUNET_OK != 222 if (GNUNET_OK != GNUNET_SQ_bind (plugin->insert_stmt, params))
198 GNUNET_SQ_bind (plugin->insert_stmt,
199 params))
200 { 223 {
201 LOG_SQLITE (plugin->dbh, 224 LOG_SQLITE (plugin->dbh,
202 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 225 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
203 "sqlite3_bind_xxx"); 226 "sqlite3_bind_xxx");
204 GNUNET_SQ_reset (plugin->dbh, 227 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
205 plugin->insert_stmt);
206 return -1; 228 return -1;
207 } 229 }
208 if (SQLITE_DONE != 230 if (SQLITE_DONE != sqlite3_step (plugin->insert_stmt))
209 sqlite3_step (plugin->insert_stmt))
210 { 231 {
211 LOG_SQLITE (plugin->dbh, 232 LOG_SQLITE (plugin->dbh,
212 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 233 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
213 "sqlite3_step"); 234 "sqlite3_step");
214 GNUNET_SQ_reset (plugin->dbh, 235 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
215 plugin->insert_stmt);
216 return -1; 236 return -1;
217 } 237 }
218 plugin->num_items++; 238 plugin->num_items++;
219 GNUNET_SQ_reset (plugin->dbh, 239 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
220 plugin->insert_stmt);
221 return size + OVERHEAD; 240 return size + OVERHEAD;
222} 241}
223 242
@@ -251,62 +270,50 @@ sqlite_plugin_get (void *cls,
251 unsigned int total; 270 unsigned int total;
252 size_t psize; 271 size_t psize;
253 struct GNUNET_PeerIdentity *path; 272 struct GNUNET_PeerIdentity *path;
254 struct GNUNET_SQ_QueryParam params_count[] = { 273 struct GNUNET_SQ_QueryParam params_count[] =
255 GNUNET_SQ_query_param_auto_from_type (key), 274 {GNUNET_SQ_query_param_auto_from_type (key),
256 GNUNET_SQ_query_param_uint32 (&type32), 275 GNUNET_SQ_query_param_uint32 (&type32),
257 GNUNET_SQ_query_param_absolute_time (&now), 276 GNUNET_SQ_query_param_absolute_time (&now),
258 GNUNET_SQ_query_param_end 277 GNUNET_SQ_query_param_end};
259 }; 278 struct GNUNET_SQ_QueryParam params_select[] =
260 struct GNUNET_SQ_QueryParam params_select[] = { 279 {GNUNET_SQ_query_param_auto_from_type (key),
261 GNUNET_SQ_query_param_auto_from_type (key), 280 GNUNET_SQ_query_param_uint32 (&type32),
262 GNUNET_SQ_query_param_uint32 (&type32), 281 GNUNET_SQ_query_param_absolute_time (&now),
263 GNUNET_SQ_query_param_absolute_time (&now), 282 GNUNET_SQ_query_param_uint32 (&off),
264 GNUNET_SQ_query_param_uint32 (&off), 283 GNUNET_SQ_query_param_end};
265 GNUNET_SQ_query_param_end 284 struct GNUNET_SQ_ResultSpec rs[] =
266 }; 285 {GNUNET_SQ_result_spec_variable_size (&dat, &size),
267 struct GNUNET_SQ_ResultSpec rs[] = { 286 GNUNET_SQ_result_spec_absolute_time (&exp),
268 GNUNET_SQ_result_spec_variable_size (&dat, 287 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
269 &size), 288 GNUNET_SQ_result_spec_end};
270 GNUNET_SQ_result_spec_absolute_time (&exp),
271 GNUNET_SQ_result_spec_variable_size ((void **) &path,
272 &psize),
273 GNUNET_SQ_result_spec_end
274 };
275 289
276 now = GNUNET_TIME_absolute_get (); 290 now = GNUNET_TIME_absolute_get ();
277 LOG (GNUNET_ERROR_TYPE_DEBUG, 291 LOG (GNUNET_ERROR_TYPE_DEBUG,
278 "Processing GET for key `%s'\n", 292 "Processing GET for key `%s'\n",
279 GNUNET_h2s (key)); 293 GNUNET_h2s (key));
280 294
281 if (GNUNET_OK != 295 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_count_stmt, params_count))
282 GNUNET_SQ_bind (plugin->get_count_stmt,
283 params_count))
284 { 296 {
285 LOG_SQLITE (plugin->dbh, 297 LOG_SQLITE (plugin->dbh,
286 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 298 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
287 "sqlite3_bind_xxx"); 299 "sqlite3_bind_xxx");
288 GNUNET_SQ_reset (plugin->dbh, 300 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
289 plugin->get_count_stmt);
290 return 0; 301 return 0;
291 } 302 }
292 if (SQLITE_ROW != 303 if (SQLITE_ROW != sqlite3_step (plugin->get_count_stmt))
293 sqlite3_step (plugin->get_count_stmt))
294 { 304 {
295 LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 305 LOG_SQLITE (plugin->dbh,
306 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
296 "sqlite_step"); 307 "sqlite_step");
297 GNUNET_SQ_reset (plugin->dbh, 308 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
298 plugin->get_count_stmt);
299 LOG (GNUNET_ERROR_TYPE_DEBUG, 309 LOG (GNUNET_ERROR_TYPE_DEBUG,
300 "No content found when processing GET for key `%s'\n", 310 "No content found when processing GET for key `%s'\n",
301 GNUNET_h2s (key)); 311 GNUNET_h2s (key));
302 return 0; 312 return 0;
303 } 313 }
304 total = sqlite3_column_int (plugin->get_count_stmt, 314 total = sqlite3_column_int (plugin->get_count_stmt, 0);
305 0); 315 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
306 GNUNET_SQ_reset (plugin->dbh, 316 if ((0 == total) || (NULL == iter))
307 plugin->get_count_stmt);
308 if ( (0 == total) ||
309 (NULL == iter) )
310 { 317 {
311 if (0 == total) 318 if (0 == total)
312 LOG (GNUNET_ERROR_TYPE_DEBUG, 319 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -316,32 +323,24 @@ sqlite_plugin_get (void *cls,
316 } 323 }
317 324
318 cnt = 0; 325 cnt = 0;
319 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 326 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
320 total);
321 while (cnt < total) 327 while (cnt < total)
322 { 328 {
323 off = (off + 1) % total; 329 off = (off + 1) % total;
324 if (GNUNET_OK != 330 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_stmt, params_select))
325 GNUNET_SQ_bind (plugin->get_stmt,
326 params_select))
327 { 331 {
328 LOG_SQLITE (plugin->dbh, 332 LOG_SQLITE (plugin->dbh,
329 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 333 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
330 "sqlite3_bind_xxx"); 334 "sqlite3_bind_xxx");
331 GNUNET_SQ_reset (plugin->dbh, 335 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
332 plugin->get_stmt);
333 return cnt; 336 return cnt;
334 } 337 }
335 if (SQLITE_ROW != 338 if (SQLITE_ROW != sqlite3_step (plugin->get_stmt))
336 sqlite3_step (plugin->get_stmt))
337 break; 339 break;
338 if (GNUNET_OK != 340 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_stmt, rs))
339 GNUNET_SQ_extract_result (plugin->get_stmt,
340 rs))
341 { 341 {
342 GNUNET_break (0); 342 GNUNET_break (0);
343 GNUNET_SQ_reset (plugin->dbh, 343 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
344 plugin->get_stmt);
345 break; 344 break;
346 } 345 }
347 if (0 != psize % sizeof (struct GNUNET_PeerIdentity)) 346 if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
@@ -356,26 +355,16 @@ sqlite_plugin_get (void *cls,
356 "Found %u-byte result when processing GET for key `%s'\n", 355 "Found %u-byte result when processing GET for key `%s'\n",
357 (unsigned int) size, 356 (unsigned int) size,
358 GNUNET_h2s (key)); 357 GNUNET_h2s (key));
359 if (GNUNET_OK != iter (iter_cls, 358 if (GNUNET_OK != iter (iter_cls, key, size, dat, type, exp, psize, path))
360 key,
361 size,
362 dat,
363 type,
364 exp,
365 psize,
366 path))
367 { 359 {
368 GNUNET_SQ_cleanup_result (rs); 360 GNUNET_SQ_cleanup_result (rs);
369 GNUNET_SQ_reset (plugin->dbh, 361 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
370 plugin->get_stmt);
371 break; 362 break;
372 } 363 }
373 GNUNET_SQ_cleanup_result (rs); 364 GNUNET_SQ_cleanup_result (rs);
374 GNUNET_SQ_reset (plugin->dbh, 365 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
375 plugin->get_stmt);
376 } 366 }
377 GNUNET_SQ_reset (plugin->dbh, 367 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
378 plugin->get_stmt);
379 return cnt; 368 return cnt;
380} 369}
381 370
@@ -396,94 +385,66 @@ sqlite_plugin_del (void *cls)
396 size_t dsize; 385 size_t dsize;
397 struct GNUNET_HashCode hc; 386 struct GNUNET_HashCode hc;
398 struct GNUNET_TIME_Absolute now; 387 struct GNUNET_TIME_Absolute now;
399 struct GNUNET_SQ_ResultSpec rs[] = { 388 struct GNUNET_SQ_ResultSpec rs[] =
400 GNUNET_SQ_result_spec_uint64 (&rowid), 389 {GNUNET_SQ_result_spec_uint64 (&rowid),
401 GNUNET_SQ_result_spec_auto_from_type (&hc), 390 GNUNET_SQ_result_spec_auto_from_type (&hc),
402 GNUNET_SQ_result_spec_variable_size ((void **) &data, 391 GNUNET_SQ_result_spec_variable_size ((void **) &data, &dsize),
403 &dsize), 392 GNUNET_SQ_result_spec_end};
404 GNUNET_SQ_result_spec_end 393 struct GNUNET_SQ_QueryParam params[] = {GNUNET_SQ_query_param_uint64 (&rowid),
405 }; 394 GNUNET_SQ_query_param_end};
406 struct GNUNET_SQ_QueryParam params[] = { 395 struct GNUNET_SQ_QueryParam time_params[] =
407 GNUNET_SQ_query_param_uint64 (&rowid), 396 {GNUNET_SQ_query_param_absolute_time (&now), GNUNET_SQ_query_param_end};
408 GNUNET_SQ_query_param_end 397
409 }; 398 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing DEL\n");
410 struct GNUNET_SQ_QueryParam time_params[] = {
411 GNUNET_SQ_query_param_absolute_time (&now),
412 GNUNET_SQ_query_param_end
413 };
414
415 LOG (GNUNET_ERROR_TYPE_DEBUG,
416 "Processing DEL\n");
417 now = GNUNET_TIME_absolute_get (); 399 now = GNUNET_TIME_absolute_get ();
418 if (GNUNET_OK != 400 if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_expired_stmt, time_params))
419 GNUNET_SQ_bind (plugin->del_expired_stmt,
420 time_params))
421 { 401 {
422 LOG_SQLITE (plugin->dbh, 402 LOG_SQLITE (plugin->dbh,
423 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 403 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
424 "sqlite3_bind"); 404 "sqlite3_bind");
425 GNUNET_SQ_reset (plugin->dbh, 405 GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt);
426 plugin->del_expired_stmt);
427 return GNUNET_SYSERR; 406 return GNUNET_SYSERR;
428 } 407 }
429 if ( (SQLITE_ROW != 408 if ((SQLITE_ROW != sqlite3_step (plugin->del_expired_stmt)) ||
430 sqlite3_step (plugin->del_expired_stmt)) || 409 (GNUNET_OK != GNUNET_SQ_extract_result (plugin->del_expired_stmt, rs)))
431 (GNUNET_OK !=
432 GNUNET_SQ_extract_result (plugin->del_expired_stmt,
433 rs)) )
434 { 410 {
435 GNUNET_SQ_reset (plugin->dbh, 411 GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt);
436 plugin->del_expired_stmt); 412 if (SQLITE_ROW != sqlite3_step (plugin->del_select_stmt))
437 if (SQLITE_ROW !=
438 sqlite3_step (plugin->del_select_stmt))
439 { 413 {
440 LOG_SQLITE (plugin->dbh, 414 LOG_SQLITE (plugin->dbh,
441 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 415 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
442 "sqlite3_step"); 416 "sqlite3_step");
443 GNUNET_SQ_reset (plugin->dbh, 417 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
444 plugin->del_select_stmt);
445 return GNUNET_SYSERR; 418 return GNUNET_SYSERR;
446 } 419 }
447 if (GNUNET_OK != 420 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->del_select_stmt, rs))
448 GNUNET_SQ_extract_result (plugin->del_select_stmt,
449 rs))
450 { 421 {
451 GNUNET_SQ_reset (plugin->dbh, 422 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
452 plugin->del_select_stmt);
453 GNUNET_break (0); 423 GNUNET_break (0);
454 return GNUNET_SYSERR; 424 return GNUNET_SYSERR;
455 } 425 }
456 } 426 }
457 GNUNET_SQ_cleanup_result (rs); 427 GNUNET_SQ_cleanup_result (rs);
458 GNUNET_SQ_reset (plugin->dbh, 428 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
459 plugin->del_select_stmt); 429 if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_stmt, params))
460 if (GNUNET_OK !=
461 GNUNET_SQ_bind (plugin->del_stmt,
462 params))
463 { 430 {
464 LOG_SQLITE (plugin->dbh, 431 LOG_SQLITE (plugin->dbh,
465 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 432 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
466 "sqlite3_bind"); 433 "sqlite3_bind");
467 GNUNET_SQ_reset (plugin->dbh, 434 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
468 plugin->del_stmt);
469 return GNUNET_SYSERR; 435 return GNUNET_SYSERR;
470 } 436 }
471 if (SQLITE_DONE != 437 if (SQLITE_DONE != sqlite3_step (plugin->del_stmt))
472 sqlite3_step (plugin->del_stmt))
473 { 438 {
474 LOG_SQLITE (plugin->dbh, 439 LOG_SQLITE (plugin->dbh,
475 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 440 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
476 "sqlite3_step"); 441 "sqlite3_step");
477 GNUNET_SQ_reset (plugin->dbh, 442 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
478 plugin->del_stmt);
479 return GNUNET_SYSERR; 443 return GNUNET_SYSERR;
480 } 444 }
481 plugin->num_items--; 445 plugin->num_items--;
482 plugin->env->delete_notify (plugin->env->cls, 446 plugin->env->delete_notify (plugin->env->cls, &hc, dsize + OVERHEAD);
483 &hc, 447 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
484 dsize + OVERHEAD);
485 GNUNET_SQ_reset (plugin->dbh,
486 plugin->del_stmt);
487 return GNUNET_OK; 448 return GNUNET_OK;
488} 449}
489 450
@@ -510,48 +471,36 @@ sqlite_plugin_get_random (void *cls,
510 uint32_t type; 471 uint32_t type;
511 struct GNUNET_PeerIdentity *path; 472 struct GNUNET_PeerIdentity *path;
512 struct GNUNET_HashCode key; 473 struct GNUNET_HashCode key;
513 struct GNUNET_SQ_QueryParam params[] = { 474 struct GNUNET_SQ_QueryParam params[] = {GNUNET_SQ_query_param_uint32 (&off),
514 GNUNET_SQ_query_param_uint32 (&off), 475 GNUNET_SQ_query_param_end};
515 GNUNET_SQ_query_param_end 476 struct GNUNET_SQ_ResultSpec rs[] =
516 }; 477 {GNUNET_SQ_result_spec_variable_size (&dat, &size),
517 struct GNUNET_SQ_ResultSpec rs[] = { 478 GNUNET_SQ_result_spec_absolute_time (&exp),
518 GNUNET_SQ_result_spec_variable_size (&dat, 479 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
519 &size), 480 GNUNET_SQ_result_spec_auto_from_type (&key),
520 GNUNET_SQ_result_spec_absolute_time (&exp), 481 GNUNET_SQ_result_spec_uint32 (&type),
521 GNUNET_SQ_result_spec_variable_size ((void **) &path, 482 GNUNET_SQ_result_spec_end};
522 &psize),
523 GNUNET_SQ_result_spec_auto_from_type (&key),
524 GNUNET_SQ_result_spec_uint32 (&type),
525 GNUNET_SQ_result_spec_end
526 };
527 483
528 if (0 == plugin->num_items) 484 if (0 == plugin->num_items)
529 return 0; 485 return 0;
530 if (NULL == iter) 486 if (NULL == iter)
531 return 1; 487 return 1;
532 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 488 off =
533 plugin->num_items); 489 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, plugin->num_items);
534 if (GNUNET_OK != 490 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_random_stmt, params))
535 GNUNET_SQ_bind (plugin->get_random_stmt,
536 params))
537 { 491 {
538 return 0; 492 return 0;
539 } 493 }
540 if (SQLITE_ROW != 494 if (SQLITE_ROW != sqlite3_step (plugin->get_random_stmt))
541 sqlite3_step (plugin->get_random_stmt))
542 { 495 {
543 GNUNET_break (0); 496 GNUNET_break (0);
544 GNUNET_SQ_reset (plugin->dbh, 497 GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
545 plugin->get_random_stmt);
546 return 0; 498 return 0;
547 } 499 }
548 if (GNUNET_OK != 500 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_random_stmt, rs))
549 GNUNET_SQ_extract_result (plugin->get_random_stmt,
550 rs))
551 { 501 {
552 GNUNET_break (0); 502 GNUNET_break (0);
553 GNUNET_SQ_reset (plugin->dbh, 503 GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
554 plugin->get_random_stmt);
555 return 0; 504 return 0;
556 } 505 }
557 if (0 != psize % sizeof (struct GNUNET_PeerIdentity)) 506 if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
@@ -574,8 +523,7 @@ sqlite_plugin_get_random (void *cls,
574 psize, 523 psize,
575 path); 524 path);
576 GNUNET_SQ_cleanup_result (rs); 525 GNUNET_SQ_cleanup_result (rs);
577 GNUNET_SQ_reset (plugin->dbh, 526 GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
578 plugin->get_random_stmt);
579 return 1; 527 return 1;
580} 528}
581 529
@@ -611,45 +559,35 @@ sqlite_plugin_get_closest (void *cls,
611 uint32_t type; 559 uint32_t type;
612 struct GNUNET_HashCode hc; 560 struct GNUNET_HashCode hc;
613 struct GNUNET_PeerIdentity *path; 561 struct GNUNET_PeerIdentity *path;
614 struct GNUNET_SQ_QueryParam params[] = { 562 struct GNUNET_SQ_QueryParam params[] =
615 GNUNET_SQ_query_param_auto_from_type (key), 563 {GNUNET_SQ_query_param_auto_from_type (key),
616 GNUNET_SQ_query_param_absolute_time (&now), 564 GNUNET_SQ_query_param_absolute_time (&now),
617 GNUNET_SQ_query_param_uint32 (&num_results32), 565 GNUNET_SQ_query_param_uint32 (&num_results32),
618 GNUNET_SQ_query_param_end 566 GNUNET_SQ_query_param_end};
619 }; 567 struct GNUNET_SQ_ResultSpec rs[] =
620 struct GNUNET_SQ_ResultSpec rs[] = { 568 {GNUNET_SQ_result_spec_variable_size (&dat, &size),
621 GNUNET_SQ_result_spec_variable_size (&dat, 569 GNUNET_SQ_result_spec_absolute_time (&exp),
622 &size), 570 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
623 GNUNET_SQ_result_spec_absolute_time (&exp), 571 GNUNET_SQ_result_spec_uint32 (&type),
624 GNUNET_SQ_result_spec_variable_size ((void **) &path, 572 GNUNET_SQ_result_spec_auto_from_type (&hc),
625 &psize), 573 GNUNET_SQ_result_spec_end};
626 GNUNET_SQ_result_spec_uint32 (&type),
627 GNUNET_SQ_result_spec_auto_from_type (&hc),
628 GNUNET_SQ_result_spec_end
629 };
630 574
631 now = GNUNET_TIME_absolute_get (); 575 now = GNUNET_TIME_absolute_get ();
632 LOG (GNUNET_ERROR_TYPE_DEBUG, 576 LOG (GNUNET_ERROR_TYPE_DEBUG,
633 "Processing GET_CLOSEST for key `%s'\n", 577 "Processing GET_CLOSEST for key `%s'\n",
634 GNUNET_h2s (key)); 578 GNUNET_h2s (key));
635 if (GNUNET_OK != 579 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_closest_stmt, params))
636 GNUNET_SQ_bind (plugin->get_closest_stmt,
637 params))
638 { 580 {
639 LOG_SQLITE (plugin->dbh, 581 LOG_SQLITE (plugin->dbh,
640 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 582 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
641 "sqlite3_bind_xxx"); 583 "sqlite3_bind_xxx");
642 GNUNET_SQ_reset (plugin->dbh, 584 GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt);
643 plugin->get_closest_stmt);
644 return 0; 585 return 0;
645 } 586 }
646 cnt = 0; 587 cnt = 0;
647 while (SQLITE_ROW == 588 while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt))
648 sqlite3_step (plugin->get_closest_stmt))
649 { 589 {
650 if (GNUNET_OK != 590 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_closest_stmt, rs))
651 GNUNET_SQ_extract_result (plugin->get_closest_stmt,
652 rs))
653 { 591 {
654 GNUNET_break (0); 592 GNUNET_break (0);
655 break; 593 break;
@@ -666,22 +604,14 @@ sqlite_plugin_get_closest (void *cls,
666 "Found %u-byte result at %s when processing GET_CLOSE\n", 604 "Found %u-byte result at %s when processing GET_CLOSE\n",
667 (unsigned int) size, 605 (unsigned int) size,
668 GNUNET_h2s (&hc)); 606 GNUNET_h2s (&hc));
669 if (GNUNET_OK != iter (iter_cls, 607 if (GNUNET_OK != iter (iter_cls, &hc, size, dat, type, exp, psize, path))
670 &hc,
671 size,
672 dat,
673 type,
674 exp,
675 psize,
676 path))
677 { 608 {
678 GNUNET_SQ_cleanup_result (rs); 609 GNUNET_SQ_cleanup_result (rs);
679 break; 610 break;
680 } 611 }
681 GNUNET_SQ_cleanup_result (rs); 612 GNUNET_SQ_cleanup_result (rs);
682 } 613 }
683 GNUNET_SQ_reset (plugin->dbh, 614 GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt);
684 plugin->get_closest_stmt);
685 return cnt; 615 return cnt;
686} 616}
687 617
@@ -703,10 +633,9 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
703 sqlite3 *dbh; 633 sqlite3 *dbh;
704 char *emsg; 634 char *emsg;
705 635
706 if (GNUNET_YES == 636 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
707 GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 637 "datacache-sqlite",
708 "datacache-sqlite", 638 "IN_MEMORY"))
709 "IN_MEMORY"))
710 { 639 {
711 if (SQLITE_OK != sqlite3_open (":memory:", &dbh)) 640 if (SQLITE_OK != sqlite3_open (":memory:", &dbh))
712 return NULL; 641 return NULL;
@@ -716,10 +645,10 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
716 { 645 {
717 fn = GNUNET_DISK_mktemp ("gnunet-datacache"); 646 fn = GNUNET_DISK_mktemp ("gnunet-datacache");
718 if (fn == NULL) 647 if (fn == NULL)
719 { 648 {
720 GNUNET_break (0); 649 GNUNET_break (0);
721 return NULL; 650 return NULL;
722 } 651 }
723 /* fn should be UTF-8-encoded. If it isn't, it's a bug. */ 652 /* fn should be UTF-8-encoded. If it isn't, it's a bug. */
724 fn_utf8 = GNUNET_strdup (fn); 653 fn_utf8 = GNUNET_strdup (fn);
725 if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh)) 654 if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh))
@@ -736,10 +665,9 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
736 SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF"); 665 SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF");
737 SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF"); 666 SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF");
738 SQLITE3_EXEC (dbh, "PRAGMA page_size=4092"); 667 SQLITE3_EXEC (dbh, "PRAGMA page_size=4092");
739 if (GNUNET_YES == 668 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
740 GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 669 "datacache-sqlite",
741 "datacache-sqlite", 670 "IN_MEMORY"))
742 "IN_MEMORY"))
743 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3"); 671 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
744 672
745 SQLITE3_EXEC (dbh, 673 SQLITE3_EXEC (dbh,
@@ -749,7 +677,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
749 " key BLOB NOT NULL DEFAULT ''," 677 " key BLOB NOT NULL DEFAULT '',"
750 " prox INTEGER NOT NULL," 678 " prox INTEGER NOT NULL,"
751 " value BLOB NOT NULL," 679 " value BLOB NOT NULL,"
752 " path BLOB DEFAULT '')"); 680 " path BLOB DEFAULT '')");
753 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)"); 681 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)");
754 SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)"); 682 SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)");
755 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)"); 683 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)");
@@ -758,53 +686,46 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
758 plugin->dbh = dbh; 686 plugin->dbh = dbh;
759 plugin->fn = fn_utf8; 687 plugin->fn = fn_utf8;
760 688
761 if ( (SQLITE_OK != 689 if ((SQLITE_OK !=
762 sq_prepare (plugin->dbh, 690 sq_prepare (plugin->dbh,
763 "INSERT INTO ds091 (type, expire, key, prox, value, path) " 691 "INSERT INTO ds091 (type, expire, key, prox, value, path) "
764 "VALUES (?, ?, ?, ?, ?, ?)", 692 "VALUES (?, ?, ?, ?, ?, ?)",
765 &plugin->insert_stmt)) || 693 &plugin->insert_stmt)) ||
766 (SQLITE_OK != 694 (SQLITE_OK != sq_prepare (plugin->dbh,
767 sq_prepare (plugin->dbh, 695 "SELECT count(*) FROM ds091 "
768 "SELECT count(*) FROM ds091 " 696 "WHERE key=? AND type=? AND expire >= ?",
769 "WHERE key=? AND type=? AND expire >= ?", 697 &plugin->get_count_stmt)) ||
770 &plugin->get_count_stmt)) || 698 (SQLITE_OK !=
771 (SQLITE_OK != 699 sq_prepare (plugin->dbh,
772 sq_prepare (plugin->dbh, 700 "SELECT value,expire,path FROM ds091"
773 "SELECT value,expire,path FROM ds091" 701 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
774 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?", 702 &plugin->get_stmt)) ||
775 &plugin->get_stmt)) || 703 (SQLITE_OK != sq_prepare (plugin->dbh,
776 (SQLITE_OK != 704 "SELECT _ROWID_,key,value FROM ds091"
777 sq_prepare (plugin->dbh, 705 " WHERE expire < ?"
778 "SELECT _ROWID_,key,value FROM ds091" 706 " ORDER BY expire ASC LIMIT 1",
779 " WHERE expire < ?" 707 &plugin->del_expired_stmt)) ||
780 " ORDER BY expire ASC LIMIT 1", 708 (SQLITE_OK != sq_prepare (plugin->dbh,
781 &plugin->del_expired_stmt)) || 709 "SELECT _ROWID_,key,value FROM ds091"
782 (SQLITE_OK != 710 " ORDER BY prox ASC, expire ASC LIMIT 1",
783 sq_prepare (plugin->dbh, 711 &plugin->del_select_stmt)) ||
784 "SELECT _ROWID_,key,value FROM ds091" 712 (SQLITE_OK != sq_prepare (plugin->dbh,
785 " ORDER BY prox ASC, expire ASC LIMIT 1", 713 "DELETE FROM ds091 WHERE _ROWID_=?",
786 &plugin->del_select_stmt)) || 714 &plugin->del_stmt)) ||
787 (SQLITE_OK != 715 (SQLITE_OK != sq_prepare (plugin->dbh,
788 sq_prepare (plugin->dbh, 716 "SELECT value,expire,path,key,type FROM ds091 "
789 "DELETE FROM ds091 WHERE _ROWID_=?", 717 "ORDER BY key LIMIT 1 OFFSET ?",
790 &plugin->del_stmt)) || 718 &plugin->get_random_stmt)) ||
791 (SQLITE_OK != 719 (SQLITE_OK !=
792 sq_prepare (plugin->dbh, 720 sq_prepare (plugin->dbh,
793 "SELECT value,expire,path,key,type FROM ds091 " 721 "SELECT value,expire,path,type,key FROM ds091 "
794 "ORDER BY key LIMIT 1 OFFSET ?", 722 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
795 &plugin->get_random_stmt)) || 723 &plugin->get_closest_stmt)))
796 (SQLITE_OK !=
797 sq_prepare (plugin->dbh,
798 "SELECT value,expire,path,type,key FROM ds091 "
799 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
800 &plugin->get_closest_stmt))
801 )
802 { 724 {
803 LOG_SQLITE (plugin->dbh, 725 LOG_SQLITE (plugin->dbh,
804 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 726 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
805 "sq_prepare"); 727 "sq_prepare");
806 GNUNET_break (SQLITE_OK == 728 GNUNET_break (SQLITE_OK == sqlite3_close (plugin->dbh));
807 sqlite3_close (plugin->dbh));
808 GNUNET_free (plugin); 729 GNUNET_free (plugin);
809 return NULL; 730 return NULL;
810 } 731 }
@@ -816,8 +737,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
816 api->del = &sqlite_plugin_del; 737 api->del = &sqlite_plugin_del;
817 api->get_random = &sqlite_plugin_get_random; 738 api->get_random = &sqlite_plugin_get_random;
818 api->get_closest = &sqlite_plugin_get_closest; 739 api->get_closest = &sqlite_plugin_get_closest;
819 LOG (GNUNET_ERROR_TYPE_INFO, 740 LOG (GNUNET_ERROR_TYPE_INFO, "Sqlite datacache running\n");
820 "Sqlite datacache running\n");
821 return api; 741 return api;
822} 742}
823 743
@@ -839,12 +759,9 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
839 sqlite3_stmt *stmt; 759 sqlite3_stmt *stmt;
840#endif 760#endif
841 761
842#if !WINDOWS || defined(__CYGWIN__) 762#if ! WINDOWS || defined(__CYGWIN__)
843 if ( (NULL != plugin->fn) && 763 if ((NULL != plugin->fn) && (0 != unlink (plugin->fn)))
844 (0 != UNLINK (plugin->fn)) ) 764 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
845 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
846 "unlink",
847 plugin->fn);
848 GNUNET_free_non_null (plugin->fn); 765 GNUNET_free_non_null (plugin->fn);
849#endif 766#endif
850 sqlite3_finalize (plugin->insert_stmt); 767 sqlite3_finalize (plugin->insert_stmt);
@@ -860,7 +777,8 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
860 if (SQLITE_BUSY == result) 777 if (SQLITE_BUSY == result)
861 { 778 {
862 LOG (GNUNET_ERROR_TYPE_WARNING, 779 LOG (GNUNET_ERROR_TYPE_WARNING,
863 _("Tried to close sqlite without finalizing all prepared statements.\n")); 780 _ (
781 "Tried to close sqlite without finalizing all prepared statements.\n"));
864 stmt = sqlite3_next_stmt (plugin->dbh, NULL); 782 stmt = sqlite3_next_stmt (plugin->dbh, NULL);
865 while (NULL != stmt) 783 while (NULL != stmt)
866 { 784 {
@@ -876,16 +794,11 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
876 } 794 }
877#endif 795#endif
878 if (SQLITE_OK != result) 796 if (SQLITE_OK != result)
879 LOG_SQLITE (plugin->dbh, 797 LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
880 GNUNET_ERROR_TYPE_ERROR, 798
881 "sqlite3_close"); 799#if WINDOWS && ! defined(__CYGWIN__)
882 800 if ((NULL != plugin->fn) && (0 != unlink (plugin->fn)))
883#if WINDOWS && !defined(__CYGWIN__) 801 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
884 if ( (NULL != plugin->fn) &&
885 (0 != UNLINK (plugin->fn)) )
886 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
887 "unlink",
888 plugin->fn);
889 GNUNET_free_non_null (plugin->fn); 802 GNUNET_free_non_null (plugin->fn);
890#endif 803#endif
891 GNUNET_free (plugin); 804 GNUNET_free (plugin);
@@ -894,5 +807,4 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
894} 807}
895 808
896 809
897
898/* end of plugin_datacache_sqlite.c */ 810/* end of plugin_datacache_sqlite.c */