summaryrefslogtreecommitdiff
path: root/src/peerstore/plugin_peerstore_sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/peerstore/plugin_peerstore_sqlite.c')
-rw-r--r--src/peerstore/plugin_peerstore_sqlite.c699
1 files changed, 348 insertions, 351 deletions
diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c
index 898db2231..5f6617ebc 100644
--- a/src/peerstore/plugin_peerstore_sqlite.c
+++ b/src/peerstore/plugin_peerstore_sqlite.c
@@ -49,16 +49,14 @@
49 * a failure of the command 'cmd' on file 'filename' 49 * a failure of the command 'cmd' on file 'filename'
50 * with the message given by strerror(errno). 50 * with the message given by strerror(errno).
51 */ 51 */
52#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "peerstore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0) 52#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from(level, "peerstore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while (0)
53 53
54#define LOG(kind,...) GNUNET_log_from (kind, "peerstore-sqlite", __VA_ARGS__) 54#define LOG(kind, ...) GNUNET_log_from(kind, "peerstore-sqlite", __VA_ARGS__)
55 55
56/** 56/**
57 * Context for all functions in this plugin. 57 * Context for all functions in this plugin.
58 */ 58 */
59struct Plugin 59struct Plugin {
60{
61
62 /** 60 /**
63 * Configuration handle 61 * Configuration handle
64 */ 62 */
@@ -110,7 +108,6 @@ struct Plugin
110 * with given key 108 * with given key
111 */ 109 */
112 sqlite3_stmt *delete_peerstoredata; 110 sqlite3_stmt *delete_peerstoredata;
113
114}; 111};
115 112
116 113
@@ -124,46 +121,46 @@ struct Plugin
124 * @return number of deleted records, #GNUNE_SYSERR on error 121 * @return number of deleted records, #GNUNE_SYSERR on error
125 */ 122 */
126static int 123static int
127peerstore_sqlite_delete_records (void *cls, 124peerstore_sqlite_delete_records(void *cls,
128 const char *sub_system, 125 const char *sub_system,
129 const struct GNUNET_PeerIdentity *peer, 126 const struct GNUNET_PeerIdentity *peer,
130 const char *key) 127 const char *key)
131{ 128{
132 struct Plugin *plugin = cls; 129 struct Plugin *plugin = cls;
133 sqlite3_stmt *stmt = plugin->delete_peerstoredata; 130 sqlite3_stmt *stmt = plugin->delete_peerstoredata;
134 struct GNUNET_SQ_QueryParam params[] = { 131 struct GNUNET_SQ_QueryParam params[] = {
135 GNUNET_SQ_query_param_string (sub_system), 132 GNUNET_SQ_query_param_string(sub_system),
136 GNUNET_SQ_query_param_auto_from_type (peer), 133 GNUNET_SQ_query_param_auto_from_type(peer),
137 GNUNET_SQ_query_param_string (key), 134 GNUNET_SQ_query_param_string(key),
138 GNUNET_SQ_query_param_end 135 GNUNET_SQ_query_param_end
139 }; 136 };
140 int ret; 137 int ret;
141 138
142 if (GNUNET_OK != 139 if (GNUNET_OK !=
143 GNUNET_SQ_bind (stmt, 140 GNUNET_SQ_bind(stmt,
144 params)) 141 params))
145 { 142 {
146 LOG_SQLITE (plugin, 143 LOG_SQLITE(plugin,
147 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 144 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
148 "sqlite3_bind"); 145 "sqlite3_bind");
149 GNUNET_SQ_reset (plugin->dbh, 146 GNUNET_SQ_reset(plugin->dbh,
150 stmt); 147 stmt);
151 return GNUNET_SYSERR; 148 return GNUNET_SYSERR;
152 } 149 }
153 if (SQLITE_DONE != 150 if (SQLITE_DONE !=
154 sqlite3_step (stmt)) 151 sqlite3_step(stmt))
155 { 152 {
156 LOG_SQLITE (plugin, 153 LOG_SQLITE(plugin,
157 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 154 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
158 "sqlite3_step"); 155 "sqlite3_step");
159 ret = GNUNET_SYSERR; 156 ret = GNUNET_SYSERR;
160 } 157 }
161 else 158 else
162 { 159 {
163 ret = sqlite3_changes (plugin->dbh); 160 ret = sqlite3_changes(plugin->dbh);
164 } 161 }
165 GNUNET_SQ_reset (plugin->dbh, 162 GNUNET_SQ_reset(plugin->dbh,
166 stmt); 163 stmt);
167 return ret; 164 return ret;
168} 165}
169 166
@@ -179,42 +176,42 @@ peerstore_sqlite_delete_records (void *cls,
179 * called 176 * called
180 */ 177 */
181static int 178static int
182peerstore_sqlite_expire_records (void *cls, struct GNUNET_TIME_Absolute now, 179peerstore_sqlite_expire_records(void *cls, struct GNUNET_TIME_Absolute now,
183 GNUNET_PEERSTORE_Continuation cont, 180 GNUNET_PEERSTORE_Continuation cont,
184 void *cont_cls) 181 void *cont_cls)
185{ 182{
186 struct Plugin *plugin = cls; 183 struct Plugin *plugin = cls;
187 sqlite3_stmt *stmt = plugin->expire_peerstoredata; 184 sqlite3_stmt *stmt = plugin->expire_peerstoredata;
188 struct GNUNET_SQ_QueryParam params[] = { 185 struct GNUNET_SQ_QueryParam params[] = {
189 GNUNET_SQ_query_param_absolute_time (&now), 186 GNUNET_SQ_query_param_absolute_time(&now),
190 GNUNET_SQ_query_param_end 187 GNUNET_SQ_query_param_end
191 }; 188 };
192 189
193 if (GNUNET_OK != 190 if (GNUNET_OK !=
194 GNUNET_SQ_bind (stmt, 191 GNUNET_SQ_bind(stmt,
195 params)) 192 params))
196 { 193 {
197 LOG_SQLITE (plugin, 194 LOG_SQLITE(plugin,
198 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 195 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
199 "sqlite3_bind"); 196 "sqlite3_bind");
200 GNUNET_SQ_reset (plugin->dbh, 197 GNUNET_SQ_reset(plugin->dbh,
201 stmt); 198 stmt);
202 return GNUNET_SYSERR; 199 return GNUNET_SYSERR;
203 } 200 }
204 if (SQLITE_DONE != sqlite3_step (stmt)) 201 if (SQLITE_DONE != sqlite3_step(stmt))
205 { 202 {
206 LOG_SQLITE (plugin, 203 LOG_SQLITE(plugin,
207 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 204 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
208 "sqlite3_step"); 205 "sqlite3_step");
209 GNUNET_SQ_reset (plugin->dbh, 206 GNUNET_SQ_reset(plugin->dbh,
210 stmt); 207 stmt);
211 return GNUNET_SYSERR; 208 return GNUNET_SYSERR;
212 } 209 }
213 if (NULL != cont) 210 if (NULL != cont)
214 cont (cont_cls, 211 cont(cont_cls,
215 sqlite3_changes (plugin->dbh)); 212 sqlite3_changes(plugin->dbh));
216 GNUNET_SQ_reset (plugin->dbh, 213 GNUNET_SQ_reset(plugin->dbh,
217 stmt); 214 stmt);
218 return GNUNET_OK; 215 return GNUNET_OK;
219} 216}
220 217
@@ -234,12 +231,12 @@ peerstore_sqlite_expire_records (void *cls, struct GNUNET_TIME_Absolute now,
234 * called 231 * called
235 */ 232 */
236static int 233static int
237peerstore_sqlite_iterate_records (void *cls, 234peerstore_sqlite_iterate_records(void *cls,
238 const char *sub_system, 235 const char *sub_system,
239 const struct GNUNET_PeerIdentity *peer, 236 const struct GNUNET_PeerIdentity *peer,
240 const char *key, 237 const char *key,
241 GNUNET_PEERSTORE_Processor iter, 238 GNUNET_PEERSTORE_Processor iter,
242 void *iter_cls) 239 void *iter_cls)
243{ 240{
244 struct Plugin *plugin = cls; 241 struct Plugin *plugin = cls;
245 sqlite3_stmt *stmt; 242 sqlite3_stmt *stmt;
@@ -247,113 +244,113 @@ peerstore_sqlite_iterate_records (void *cls,
247 int sret; 244 int sret;
248 struct GNUNET_PEERSTORE_Record rec; 245 struct GNUNET_PEERSTORE_Record rec;
249 246
250 LOG (GNUNET_ERROR_TYPE_DEBUG, 247 LOG(GNUNET_ERROR_TYPE_DEBUG,
251 "Executing iterate request on sqlite db.\n"); 248 "Executing iterate request on sqlite db.\n");
252 if (NULL == peer) 249 if (NULL == peer)
253 {
254 if (NULL == key)
255 {
256 struct GNUNET_SQ_QueryParam params[] = {
257 GNUNET_SQ_query_param_string (sub_system),
258 GNUNET_SQ_query_param_end
259 };
260
261 stmt = plugin->select_peerstoredata;
262 err = GNUNET_SQ_bind (stmt,
263 params);
264 }
265 else
266 { 250 {
267 struct GNUNET_SQ_QueryParam params[] = { 251 if (NULL == key)
268 GNUNET_SQ_query_param_string (sub_system), 252 {
269 GNUNET_SQ_query_param_string (key), 253 struct GNUNET_SQ_QueryParam params[] = {
270 GNUNET_SQ_query_param_end 254 GNUNET_SQ_query_param_string(sub_system),
271 }; 255 GNUNET_SQ_query_param_end
272 256 };
273 stmt = plugin->select_peerstoredata_by_key; 257
274 err = GNUNET_SQ_bind (stmt, 258 stmt = plugin->select_peerstoredata;
275 params); 259 err = GNUNET_SQ_bind(stmt,
260 params);
261 }
262 else
263 {
264 struct GNUNET_SQ_QueryParam params[] = {
265 GNUNET_SQ_query_param_string(sub_system),
266 GNUNET_SQ_query_param_string(key),
267 GNUNET_SQ_query_param_end
268 };
269
270 stmt = plugin->select_peerstoredata_by_key;
271 err = GNUNET_SQ_bind(stmt,
272 params);
273 }
276 } 274 }
277 }
278 else 275 else
279 {
280 if (NULL == key)
281 { 276 {
282 struct GNUNET_SQ_QueryParam params[] = { 277 if (NULL == key)
283 GNUNET_SQ_query_param_string (sub_system), 278 {
284 GNUNET_SQ_query_param_auto_from_type (peer), 279 struct GNUNET_SQ_QueryParam params[] = {
285 GNUNET_SQ_query_param_end 280 GNUNET_SQ_query_param_string(sub_system),
286 }; 281 GNUNET_SQ_query_param_auto_from_type(peer),
287 282 GNUNET_SQ_query_param_end
288 stmt = plugin->select_peerstoredata_by_pid; 283 };
289 err = GNUNET_SQ_bind (stmt, 284
290 params); 285 stmt = plugin->select_peerstoredata_by_pid;
286 err = GNUNET_SQ_bind(stmt,
287 params);
288 }
289 else
290 {
291 struct GNUNET_SQ_QueryParam params[] = {
292 GNUNET_SQ_query_param_string(sub_system),
293 GNUNET_SQ_query_param_auto_from_type(peer),
294 GNUNET_SQ_query_param_string(key),
295 GNUNET_SQ_query_param_end
296 };
297
298 stmt = plugin->select_peerstoredata_by_all;
299 err = GNUNET_SQ_bind(stmt,
300 params);
301 }
291 } 302 }
292 else
293 {
294 struct GNUNET_SQ_QueryParam params[] = {
295 GNUNET_SQ_query_param_string (sub_system),
296 GNUNET_SQ_query_param_auto_from_type (peer),
297 GNUNET_SQ_query_param_string (key),
298 GNUNET_SQ_query_param_end
299 };
300
301 stmt = plugin->select_peerstoredata_by_all;
302 err = GNUNET_SQ_bind (stmt,
303 params);
304 }
305 }
306 303
307 if (GNUNET_OK != err) 304 if (GNUNET_OK != err)
308 { 305 {
309 LOG_SQLITE (plugin, 306 LOG_SQLITE(plugin,
310 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 307 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
311 "sqlite3_bind_XXXX"); 308 "sqlite3_bind_XXXX");
312 GNUNET_SQ_reset (plugin->dbh, 309 GNUNET_SQ_reset(plugin->dbh,
313 stmt); 310 stmt);
314 return GNUNET_SYSERR; 311 return GNUNET_SYSERR;
315 } 312 }
316 313
317 err = 0; 314 err = 0;
318 while (SQLITE_ROW == (sret = sqlite3_step (stmt))) 315 while (SQLITE_ROW == (sret = sqlite3_step(stmt)))
319 {
320 LOG (GNUNET_ERROR_TYPE_DEBUG,
321 "Returning a matched record.\n");
322 struct GNUNET_SQ_ResultSpec rs[] = {
323 GNUNET_SQ_result_spec_string (&rec.sub_system),
324 GNUNET_SQ_result_spec_auto_from_type (&rec.peer),
325 GNUNET_SQ_result_spec_string (&rec.key),
326 GNUNET_SQ_result_spec_variable_size (&rec.value, &rec.value_size),
327 GNUNET_SQ_result_spec_absolute_time (&rec.expiry),
328 GNUNET_SQ_result_spec_end
329 };
330
331 if (GNUNET_OK !=
332 GNUNET_SQ_extract_result (stmt,
333 rs))
334 { 316 {
335 GNUNET_break (0); 317 LOG(GNUNET_ERROR_TYPE_DEBUG,
336 break; 318 "Returning a matched record.\n");
319 struct GNUNET_SQ_ResultSpec rs[] = {
320 GNUNET_SQ_result_spec_string(&rec.sub_system),
321 GNUNET_SQ_result_spec_auto_from_type(&rec.peer),
322 GNUNET_SQ_result_spec_string(&rec.key),
323 GNUNET_SQ_result_spec_variable_size(&rec.value, &rec.value_size),
324 GNUNET_SQ_result_spec_absolute_time(&rec.expiry),
325 GNUNET_SQ_result_spec_end
326 };
327
328 if (GNUNET_OK !=
329 GNUNET_SQ_extract_result(stmt,
330 rs))
331 {
332 GNUNET_break(0);
333 break;
334 }
335 if (NULL != iter)
336 iter(iter_cls,
337 &rec,
338 NULL);
339 GNUNET_SQ_cleanup_result(rs);
337 } 340 }
338 if (NULL != iter)
339 iter (iter_cls,
340 &rec,
341 NULL);
342 GNUNET_SQ_cleanup_result (rs);
343 }
344 if (SQLITE_DONE != sret) 341 if (SQLITE_DONE != sret)
345 { 342 {
346 LOG_SQLITE (plugin, 343 LOG_SQLITE(plugin,
347 GNUNET_ERROR_TYPE_ERROR, 344 GNUNET_ERROR_TYPE_ERROR,
348 "sqlite_step"); 345 "sqlite_step");
349 err = 1; 346 err = 1;
350 } 347 }
351 GNUNET_SQ_reset (plugin->dbh, 348 GNUNET_SQ_reset(plugin->dbh,
352 stmt); 349 stmt);
353 if (NULL != iter) 350 if (NULL != iter)
354 iter (iter_cls, 351 iter(iter_cls,
355 NULL, 352 NULL,
356 err ? "sqlite error" : NULL); 353 err ? "sqlite error" : NULL);
357 return GNUNET_OK; 354 return GNUNET_OK;
358} 355}
359 356
@@ -376,52 +373,52 @@ peerstore_sqlite_iterate_records (void *cls,
376 * @return #GNUNET_OK on success, else #GNUNET_SYSERR and cont is not called 373 * @return #GNUNET_OK on success, else #GNUNET_SYSERR and cont is not called
377 */ 374 */
378static int 375static int
379peerstore_sqlite_store_record (void *cls, 376peerstore_sqlite_store_record(void *cls,
380 const char *sub_system, 377 const char *sub_system,
381 const struct GNUNET_PeerIdentity *peer, 378 const struct GNUNET_PeerIdentity *peer,
382 const char *key, 379 const char *key,
383 const void *value, 380 const void *value,
384 size_t size, 381 size_t size,
385 struct GNUNET_TIME_Absolute expiry, 382 struct GNUNET_TIME_Absolute expiry,
386 enum GNUNET_PEERSTORE_StoreOption options, 383 enum GNUNET_PEERSTORE_StoreOption options,
387 GNUNET_PEERSTORE_Continuation cont, 384 GNUNET_PEERSTORE_Continuation cont,
388 void *cont_cls) 385 void *cont_cls)
389{ 386{
390 struct Plugin *plugin = cls; 387 struct Plugin *plugin = cls;
391 sqlite3_stmt *stmt = plugin->insert_peerstoredata; 388 sqlite3_stmt *stmt = plugin->insert_peerstoredata;
392 struct GNUNET_SQ_QueryParam params[] = { 389 struct GNUNET_SQ_QueryParam params[] = {
393 GNUNET_SQ_query_param_string (sub_system), 390 GNUNET_SQ_query_param_string(sub_system),
394 GNUNET_SQ_query_param_auto_from_type (peer), 391 GNUNET_SQ_query_param_auto_from_type(peer),
395 GNUNET_SQ_query_param_string (key), 392 GNUNET_SQ_query_param_string(key),
396 GNUNET_SQ_query_param_fixed_size (value, size), 393 GNUNET_SQ_query_param_fixed_size(value, size),
397 GNUNET_SQ_query_param_absolute_time (&expiry), 394 GNUNET_SQ_query_param_absolute_time(&expiry),
398 GNUNET_SQ_query_param_end 395 GNUNET_SQ_query_param_end
399 }; 396 };
400 397
401 if (GNUNET_PEERSTORE_STOREOPTION_REPLACE == options) 398 if (GNUNET_PEERSTORE_STOREOPTION_REPLACE == options)
402 { 399 {
403 peerstore_sqlite_delete_records (cls, 400 peerstore_sqlite_delete_records(cls,
404 sub_system, 401 sub_system,
405 peer, 402 peer,
406 key); 403 key);
407 } 404 }
408 if (GNUNET_OK != 405 if (GNUNET_OK !=
409 GNUNET_SQ_bind (stmt, 406 GNUNET_SQ_bind(stmt,
410 params)) 407 params))
411 LOG_SQLITE (plugin, 408 LOG_SQLITE(plugin,
412 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 409 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
413 "sqlite3_bind"); 410 "sqlite3_bind");
414 else if (SQLITE_DONE != sqlite3_step (stmt)) 411 else if (SQLITE_DONE != sqlite3_step(stmt))
415 { 412 {
416 LOG_SQLITE (plugin, 413 LOG_SQLITE(plugin,
417 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 414 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
418 "sqlite3_step"); 415 "sqlite3_step");
419 } 416 }
420 GNUNET_SQ_reset (plugin->dbh, 417 GNUNET_SQ_reset(plugin->dbh,
421 stmt); 418 stmt);
422 if (NULL != cont) 419 if (NULL != cont)
423 cont (cont_cls, 420 cont(cont_cls,
424 GNUNET_OK); 421 GNUNET_OK);
425 return GNUNET_OK; 422 return GNUNET_OK;
426} 423}
427 424
@@ -434,25 +431,25 @@ peerstore_sqlite_store_record (void *cls,
434 * @return 0 on success 431 * @return 0 on success
435 */ 432 */
436static int 433static int
437sql_exec (sqlite3 *dbh, 434sql_exec(sqlite3 *dbh,
438 const char *sql) 435 const char *sql)
439{ 436{
440 int result; 437 int result;
441 438
442 result = sqlite3_exec (dbh, 439 result = sqlite3_exec(dbh,
443 sql, 440 sql,
444 NULL, 441 NULL,
445 NULL, 442 NULL,
446 NULL); 443 NULL);
447 LOG (GNUNET_ERROR_TYPE_DEBUG, 444 LOG(GNUNET_ERROR_TYPE_DEBUG,
448 "Executed `%s' / %d\n", 445 "Executed `%s' / %d\n",
449 sql, 446 sql,
450 result); 447 result);
451 if (SQLITE_OK != result) 448 if (SQLITE_OK != result)
452 LOG (GNUNET_ERROR_TYPE_ERROR, 449 LOG(GNUNET_ERROR_TYPE_ERROR,
453 _("Error executing SQL query: %s\n %s\n"), 450 _("Error executing SQL query: %s\n %s\n"),
454 sqlite3_errmsg (dbh), 451 sqlite3_errmsg(dbh),
455 sql); 452 sql);
456 return result; 453 return result;
457} 454}
458 455
@@ -466,28 +463,28 @@ sql_exec (sqlite3 *dbh,
466 * @return 0 on success 463 * @return 0 on success
467 */ 464 */
468static int 465static int
469sql_prepare (sqlite3 *dbh, 466sql_prepare(sqlite3 *dbh,
470 const char *sql, 467 const char *sql,
471 sqlite3_stmt ** stmt) 468 sqlite3_stmt ** stmt)
472{ 469{
473 char *tail; 470 char *tail;
474 int result; 471 int result;
475 472
476 result = sqlite3_prepare_v2 (dbh, 473 result = sqlite3_prepare_v2(dbh,
477 sql, 474 sql,
478 strlen (sql), 475 strlen(sql),
479 stmt, 476 stmt,
480 (const char **) &tail); 477 (const char **)&tail);
481 LOG (GNUNET_ERROR_TYPE_DEBUG, 478 LOG(GNUNET_ERROR_TYPE_DEBUG,
482 "Prepared `%s' / %p: %d\n", 479 "Prepared `%s' / %p: %d\n",
483 sql, 480 sql,
484 *stmt, 481 *stmt,
485 result); 482 result);
486 if (SQLITE_OK != result) 483 if (SQLITE_OK != result)
487 LOG (GNUNET_ERROR_TYPE_ERROR, 484 LOG(GNUNET_ERROR_TYPE_ERROR,
488 _("Error preparing SQL query: %s\n %s\n"), 485 _("Error preparing SQL query: %s\n %s\n"),
489 sqlite3_errmsg (dbh), 486 sqlite3_errmsg(dbh),
490 sql); 487 sql);
491 return result; 488 return result;
492} 489}
493 490
@@ -501,110 +498,110 @@ sql_prepare (sqlite3 *dbh,
501 * @return #GNUNET_OK on success 498 * @return #GNUNET_OK on success
502 */ 499 */
503static int 500static int
504database_setup (struct Plugin *plugin) 501database_setup(struct Plugin *plugin)
505{ 502{
506 char *filename; 503 char *filename;
507 504
508 if (GNUNET_OK != 505 if (GNUNET_OK !=
509 GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, 506 GNUNET_CONFIGURATION_get_value_filename(plugin->cfg,
510 "peerstore-sqlite", 507 "peerstore-sqlite",
511 "FILENAME", 508 "FILENAME",
512 &filename)) 509 &filename))
513 {
514 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
515 "peerstore-sqlite",
516 "FILENAME");
517 return GNUNET_SYSERR;
518 }
519 if (GNUNET_OK != GNUNET_DISK_file_test (filename))
520 {
521 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (filename))
522 { 510 {
523 GNUNET_break (0); 511 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR,
524 GNUNET_free (filename); 512 "peerstore-sqlite",
513 "FILENAME");
525 return GNUNET_SYSERR; 514 return GNUNET_SYSERR;
526 } 515 }
527 } 516 if (GNUNET_OK != GNUNET_DISK_file_test(filename))
517 {
518 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file(filename))
519 {
520 GNUNET_break(0);
521 GNUNET_free(filename);
522 return GNUNET_SYSERR;
523 }
524 }
528 /* filename should be UTF-8-encoded. If it isn't, it's a bug */ 525 /* filename should be UTF-8-encoded. If it isn't, it's a bug */
529 plugin->fn = filename; 526 plugin->fn = filename;
530 /* Open database and precompile statements */ 527 /* Open database and precompile statements */
531 if (SQLITE_OK != sqlite3_open (plugin->fn, 528 if (SQLITE_OK != sqlite3_open(plugin->fn,
532 &plugin->dbh)) 529 &plugin->dbh))
533 { 530 {
534 LOG (GNUNET_ERROR_TYPE_ERROR, 531 LOG(GNUNET_ERROR_TYPE_ERROR,
535 _("Unable to initialize SQLite: %s.\n"), 532 _("Unable to initialize SQLite: %s.\n"),
536 sqlite3_errmsg (plugin->dbh)); 533 sqlite3_errmsg(plugin->dbh));
537 return GNUNET_SYSERR; 534 return GNUNET_SYSERR;
538 } 535 }
539 sql_exec (plugin->dbh, 536 sql_exec(plugin->dbh,
540 "PRAGMA temp_store=MEMORY"); 537 "PRAGMA temp_store=MEMORY");
541 sql_exec (plugin->dbh, 538 sql_exec(plugin->dbh,
542 "PRAGMA synchronous=OFF"); 539 "PRAGMA synchronous=OFF");
543 sql_exec (plugin->dbh, 540 sql_exec(plugin->dbh,
544 "PRAGMA legacy_file_format=OFF"); 541 "PRAGMA legacy_file_format=OFF");
545 sql_exec (plugin->dbh, 542 sql_exec(plugin->dbh,
546 "PRAGMA auto_vacuum=INCREMENTAL"); 543 "PRAGMA auto_vacuum=INCREMENTAL");
547 sql_exec (plugin->dbh, 544 sql_exec(plugin->dbh,
548 "PRAGMA encoding=\"UTF-8\""); 545 "PRAGMA encoding=\"UTF-8\"");
549 sql_exec (plugin->dbh, 546 sql_exec(plugin->dbh,
550 "PRAGMA page_size=4096"); 547 "PRAGMA page_size=4096");
551 sqlite3_busy_timeout (plugin->dbh, 548 sqlite3_busy_timeout(plugin->dbh,
552 BUSY_TIMEOUT_MS); 549 BUSY_TIMEOUT_MS);
553 /* Create tables */ 550 /* Create tables */
554 sql_exec (plugin->dbh, 551 sql_exec(plugin->dbh,
555 "CREATE TABLE IF NOT EXISTS peerstoredata (\n" 552 "CREATE TABLE IF NOT EXISTS peerstoredata (\n"
556 " sub_system TEXT NOT NULL,\n" 553 " sub_system TEXT NOT NULL,\n"
557 " peer_id BLOB NOT NULL,\n" 554 " peer_id BLOB NOT NULL,\n"
558 " key TEXT NOT NULL,\n" 555 " key TEXT NOT NULL,\n"
559 " value BLOB NULL,\n" 556 " value BLOB NULL,\n"
560 " expiry INT8 NOT NULL" ");"); 557 " expiry INT8 NOT NULL" ");");
561 /* Create Indices */ 558 /* Create Indices */
562 if (SQLITE_OK != 559 if (SQLITE_OK !=
563 sqlite3_exec (plugin->dbh, 560 sqlite3_exec(plugin->dbh,
564 "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)", 561 "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)",
565 NULL, 562 NULL,
566 NULL, 563 NULL,
567 NULL)) 564 NULL))
568 { 565 {
569 LOG (GNUNET_ERROR_TYPE_ERROR, 566 LOG(GNUNET_ERROR_TYPE_ERROR,
570 _("Unable to create indices: %s.\n"), 567 _("Unable to create indices: %s.\n"),
571 sqlite3_errmsg (plugin->dbh)); 568 sqlite3_errmsg(plugin->dbh));
572 return GNUNET_SYSERR; 569 return GNUNET_SYSERR;
573 } 570 }
574 /* Prepare statements */ 571 /* Prepare statements */
575 572
576 sql_prepare (plugin->dbh, 573 sql_prepare(plugin->dbh,
577 "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry)" 574 "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry)"
578 " VALUES (?,?,?,?,?);", 575 " VALUES (?,?,?,?,?);",
579 &plugin->insert_peerstoredata); 576 &plugin->insert_peerstoredata);
580 sql_prepare (plugin->dbh, 577 sql_prepare(plugin->dbh,
581 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" 578 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
582 " WHERE sub_system = ?", 579 " WHERE sub_system = ?",
583 &plugin->select_peerstoredata); 580 &plugin->select_peerstoredata);
584 sql_prepare (plugin->dbh, 581 sql_prepare(plugin->dbh,
585 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" 582 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
586 " WHERE sub_system = ?" 583 " WHERE sub_system = ?"
587 " AND peer_id = ?", 584 " AND peer_id = ?",
588 &plugin->select_peerstoredata_by_pid); 585 &plugin->select_peerstoredata_by_pid);
589 sql_prepare (plugin->dbh, 586 sql_prepare(plugin->dbh,
590 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" 587 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
591 " WHERE sub_system = ?" 588 " WHERE sub_system = ?"
592 " AND key = ?", 589 " AND key = ?",
593 &plugin->select_peerstoredata_by_key); 590 &plugin->select_peerstoredata_by_key);
594 sql_prepare (plugin->dbh, 591 sql_prepare(plugin->dbh,
595 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" 592 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
596 " WHERE sub_system = ?" 593 " WHERE sub_system = ?"
597 " AND peer_id = ?" " AND key = ?", 594 " AND peer_id = ?" " AND key = ?",
598 &plugin->select_peerstoredata_by_all); 595 &plugin->select_peerstoredata_by_all);
599 sql_prepare (plugin->dbh, 596 sql_prepare(plugin->dbh,
600 "DELETE FROM peerstoredata" 597 "DELETE FROM peerstoredata"
601 " WHERE expiry < ?", 598 " WHERE expiry < ?",
602 &plugin->expire_peerstoredata); 599 &plugin->expire_peerstoredata);
603 sql_prepare (plugin->dbh, 600 sql_prepare(plugin->dbh,
604 "DELETE FROM peerstoredata" 601 "DELETE FROM peerstoredata"
605 " WHERE sub_system = ?" 602 " WHERE sub_system = ?"
606 " AND peer_id = ?" " AND key = ?", 603 " AND peer_id = ?" " AND key = ?",
607 &plugin->delete_peerstoredata); 604 &plugin->delete_peerstoredata);
608 return GNUNET_OK; 605 return GNUNET_OK;
609} 606}
610 607
@@ -615,26 +612,26 @@ database_setup (struct Plugin *plugin)
615 * @param plugin the plugin context (state for this module) 612 * @param plugin the plugin context (state for this module)
616 */ 613 */
617static void 614static void
618database_shutdown (struct Plugin *plugin) 615database_shutdown(struct Plugin *plugin)
619{ 616{
620 int result; 617 int result;
621 sqlite3_stmt *stmt; 618 sqlite3_stmt *stmt;
622 619
623 while (NULL != (stmt = sqlite3_next_stmt (plugin->dbh, 620 while (NULL != (stmt = sqlite3_next_stmt(plugin->dbh,
624 NULL))) 621 NULL)))
625 { 622 {
626 result = sqlite3_finalize (stmt); 623 result = sqlite3_finalize(stmt);
627 if (SQLITE_OK != result) 624 if (SQLITE_OK != result)
628 LOG (GNUNET_ERROR_TYPE_WARNING, 625 LOG(GNUNET_ERROR_TYPE_WARNING,
629 "Failed to close statement %p: %d\n", 626 "Failed to close statement %p: %d\n",
630 stmt, 627 stmt,
631 result); 628 result);
632 } 629 }
633 if (SQLITE_OK != sqlite3_close (plugin->dbh)) 630 if (SQLITE_OK != sqlite3_close(plugin->dbh))
634 LOG_SQLITE (plugin, 631 LOG_SQLITE(plugin,
635 GNUNET_ERROR_TYPE_ERROR, 632 GNUNET_ERROR_TYPE_ERROR,
636 "sqlite3_close"); 633 "sqlite3_close");
637 GNUNET_free_non_null (plugin->fn); 634 GNUNET_free_non_null(plugin->fn);
638} 635}
639 636
640 637
@@ -645,7 +642,7 @@ database_shutdown (struct Plugin *plugin)
645 * @return NULL on error, otherwise the plugin context 642 * @return NULL on error, otherwise the plugin context
646 */ 643 */
647void * 644void *
648libgnunet_plugin_peerstore_sqlite_init (void *cls) 645libgnunet_plugin_peerstore_sqlite_init(void *cls)
649{ 646{
650 static struct Plugin plugin; 647 static struct Plugin plugin;
651 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 648 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -653,22 +650,22 @@ libgnunet_plugin_peerstore_sqlite_init (void *cls)
653 650
654 if (NULL != plugin.cfg) 651 if (NULL != plugin.cfg)
655 return NULL; /* can only initialize once! */ 652 return NULL; /* can only initialize once! */
656 memset (&plugin, 653 memset(&plugin,
657 0, 654 0,
658 sizeof (struct Plugin)); 655 sizeof(struct Plugin));
659 plugin.cfg = cfg; 656 plugin.cfg = cfg;
660 if (GNUNET_OK != database_setup (&plugin)) 657 if (GNUNET_OK != database_setup(&plugin))
661 { 658 {
662 database_shutdown (&plugin); 659 database_shutdown(&plugin);
663 return NULL; 660 return NULL;
664 } 661 }
665 api = GNUNET_new (struct GNUNET_PEERSTORE_PluginFunctions); 662 api = GNUNET_new(struct GNUNET_PEERSTORE_PluginFunctions);
666 api->cls = &plugin; 663 api->cls = &plugin;
667 api->store_record = &peerstore_sqlite_store_record; 664 api->store_record = &peerstore_sqlite_store_record;
668 api->iterate_records = &peerstore_sqlite_iterate_records; 665 api->iterate_records = &peerstore_sqlite_iterate_records;
669 api->expire_records = &peerstore_sqlite_expire_records; 666 api->expire_records = &peerstore_sqlite_expire_records;
670 LOG (GNUNET_ERROR_TYPE_DEBUG, 667 LOG(GNUNET_ERROR_TYPE_DEBUG,
671 "Sqlite plugin is running\n"); 668 "Sqlite plugin is running\n");
672 return api; 669 return api;
673} 670}
674 671
@@ -680,16 +677,16 @@ libgnunet_plugin_peerstore_sqlite_init (void *cls)
680 * @return Always NULL 677 * @return Always NULL
681 */ 678 */
682void * 679void *
683libgnunet_plugin_peerstore_sqlite_done (void *cls) 680libgnunet_plugin_peerstore_sqlite_done(void *cls)
684{ 681{
685 struct GNUNET_PEERSTORE_PluginFunctions *api = cls; 682 struct GNUNET_PEERSTORE_PluginFunctions *api = cls;
686 struct Plugin *plugin = api->cls; 683 struct Plugin *plugin = api->cls;
687 684
688 database_shutdown (plugin); 685 database_shutdown(plugin);
689 plugin->cfg = NULL; 686 plugin->cfg = NULL;
690 GNUNET_free (api); 687 GNUNET_free(api);
691 LOG (GNUNET_ERROR_TYPE_DEBUG, 688 LOG(GNUNET_ERROR_TYPE_DEBUG,
692 "Sqlite plugin is finished\n"); 689 "Sqlite plugin is finished\n");
693 return NULL; 690 return NULL;
694} 691}
695 692