aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/peerstore')
-rw-r--r--src/peerstore/Makefile.am4
-rw-r--r--src/peerstore/gnunet-service-peerstore.c28
-rw-r--r--src/peerstore/peerstore.h2
-rw-r--r--src/peerstore/peerstore_api.c27
-rw-r--r--src/peerstore/peerstore_common.c20
-rw-r--r--src/peerstore/peerstore_common.h2
-rw-r--r--src/peerstore/plugin_peerstore_flat.c49
-rw-r--r--src/peerstore/plugin_peerstore_sqlite.c464
-rw-r--r--src/peerstore/test_peerstore_api_iterate.c73
-rw-r--r--src/peerstore/test_peerstore_api_store.c55
-rw-r--r--src/peerstore/test_plugin_peerstore.c127
11 files changed, 538 insertions, 313 deletions
diff --git a/src/peerstore/Makefile.am b/src/peerstore/Makefile.am
index 21db6ad17..3aef05769 100644
--- a/src/peerstore/Makefile.am
+++ b/src/peerstore/Makefile.am
@@ -73,7 +73,9 @@ libgnunet_plugin_peerstore_sqlite_la_SOURCES = \
73 plugin_peerstore_sqlite.c 73 plugin_peerstore_sqlite.c
74libgnunet_plugin_peerstore_sqlite_la_LIBADD = \ 74libgnunet_plugin_peerstore_sqlite_la_LIBADD = \
75 libgnunetpeerstore.la \ 75 libgnunetpeerstore.la \
76 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 \ 76 $(top_builddir)/src/sq/libgnunetsq.la \
77 $(top_builddir)/src/util/libgnunetutil.la \
78 $(XLIBS) -lsqlite3 \
77 $(LTLIBINTL) 79 $(LTLIBINTL)
78libgnunet_plugin_peerstore_sqlite_la_LDFLAGS = \ 80libgnunet_plugin_peerstore_sqlite_la_LDFLAGS = \
79 $(GN_PLUGIN_LDFLAGS) 81 $(GN_PLUGIN_LDFLAGS)
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c
index 8200c2366..92d020799 100644
--- a/src/peerstore/gnunet-service-peerstore.c
+++ b/src/peerstore/gnunet-service-peerstore.c
@@ -260,15 +260,23 @@ record_iterator (void *cls,
260 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cls_record->client), 260 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cls_record->client),
261 env); 261 env);
262 if (NULL == emsg) 262 if (NULL == emsg)
263 {
263 GNUNET_SERVICE_client_continue (cls_record->client); 264 GNUNET_SERVICE_client_continue (cls_record->client);
265 }
264 else 266 else
267 {
268 GNUNET_break (0);
269 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
270 "Failed to iterate: %s\n",
271 emsg);
265 GNUNET_SERVICE_client_drop (cls_record->client); 272 GNUNET_SERVICE_client_drop (cls_record->client);
273 }
266 PEERSTORE_destroy_record (cls_record); 274 PEERSTORE_destroy_record (cls_record);
267 return; 275 return;
268 } 276 }
269 277
270 env = PEERSTORE_create_record_mq_envelope (record->sub_system, 278 env = PEERSTORE_create_record_mq_envelope (record->sub_system,
271 record->peer, 279 &record->peer,
272 record->key, 280 record->key,
273 record->value, 281 record->value,
274 record->value_size, 282 record->value_size,
@@ -301,7 +309,7 @@ watch_notifier_it (void *cls,
301 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 309 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
302 "Found a watcher to update.\n"); 310 "Found a watcher to update.\n");
303 env = PEERSTORE_create_record_mq_envelope (record->sub_system, 311 env = PEERSTORE_create_record_mq_envelope (record->sub_system,
304 record->peer, 312 &record->peer,
305 record->key, 313 record->key,
306 record->value, 314 record->value,
307 record->value_size, 315 record->value_size,
@@ -325,7 +333,7 @@ watch_notifier (struct GNUNET_PEERSTORE_Record *record)
325 struct GNUNET_HashCode keyhash; 333 struct GNUNET_HashCode keyhash;
326 334
327 PEERSTORE_hash_key (record->sub_system, 335 PEERSTORE_hash_key (record->sub_system,
328 record->peer, 336 &record->peer,
329 record->key, 337 record->key,
330 &keyhash); 338 &keyhash);
331 GNUNET_CONTAINER_multihashmap_get_multiple (watchers, 339 GNUNET_CONTAINER_multihashmap_get_multiple (watchers,
@@ -434,17 +442,18 @@ handle_iterate (void *cls,
434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
435 "Iterate request: ss `%s', peer `%s', key `%s'\n", 443 "Iterate request: ss `%s', peer `%s', key `%s'\n",
436 record->sub_system, 444 record->sub_system,
437 (NULL == record->peer) ? "NULL" : GNUNET_i2s (record->peer), 445 GNUNET_i2s (&record->peer),
438 (NULL == record->key) ? "NULL" : record->key); 446 (NULL == record->key) ? "NULL" : record->key);
439 record->client = client; 447 record->client = client;
440 if (GNUNET_OK != 448 if (GNUNET_OK !=
441 db->iterate_records (db->cls, 449 db->iterate_records (db->cls,
442 record->sub_system, 450 record->sub_system,
443 record->peer, 451 (ntohs (srm->peer_set)) ? &record->peer : NULL,
444 record->key, 452 record->key,
445 &record_iterator, 453 &record_iterator,
446 record)) 454 record))
447 { 455 {
456 GNUNET_break (0);
448 GNUNET_SERVICE_client_drop (client); 457 GNUNET_SERVICE_client_drop (client);
449 PEERSTORE_destroy_record (record); 458 PEERSTORE_destroy_record (record);
450 } 459 }
@@ -470,6 +479,7 @@ store_record_continuation (void *cls,
470 } 479 }
471 else 480 else
472 { 481 {
482 GNUNET_break (0);
473 GNUNET_SERVICE_client_drop (record->client); 483 GNUNET_SERVICE_client_drop (record->client);
474 } 484 }
475 PEERSTORE_destroy_record (record); 485 PEERSTORE_destroy_record (record);
@@ -496,7 +506,6 @@ check_store (void *cls,
496 return GNUNET_SYSERR; 506 return GNUNET_SYSERR;
497 } 507 }
498 if ( (NULL == record->sub_system) || 508 if ( (NULL == record->sub_system) ||
499 (NULL == record->peer) ||
500 (NULL == record->key) ) 509 (NULL == record->key) )
501 { 510 {
502 GNUNET_break (0); 511 GNUNET_break (0);
@@ -525,22 +534,23 @@ handle_store (void *cls,
525 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 534 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
526 "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %u.\n", 535 "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %u.\n",
527 record->sub_system, 536 record->sub_system,
528 GNUNET_i2s (record->peer), 537 GNUNET_i2s (&record->peer),
529 record->key, 538 record->key,
530 (uint32_t) ntohl (srm->options)); 539 (uint32_t) ntohl (srm->options));
531 record->client = client; 540 record->client = client;
532 if (GNUNET_OK != 541 if (GNUNET_OK !=
533 db->store_record (db->cls, 542 db->store_record (db->cls,
534 record->sub_system, 543 record->sub_system,
535 record->peer, 544 &record->peer,
536 record->key, 545 record->key,
537 record->value, 546 record->value,
538 record->value_size, 547 record->value_size,
539 *record->expiry, 548 record->expiry,
540 ntohl (srm->options), 549 ntohl (srm->options),
541 &store_record_continuation, 550 &store_record_continuation,
542 record)) 551 record))
543 { 552 {
553 GNUNET_break (0);
544 PEERSTORE_destroy_record (record); 554 PEERSTORE_destroy_record (record);
545 GNUNET_SERVICE_client_drop (client); 555 GNUNET_SERVICE_client_drop (client);
546 return; 556 return;
diff --git a/src/peerstore/peerstore.h b/src/peerstore/peerstore.h
index 8b3c4dd92..c6b954676 100644
--- a/src/peerstore/peerstore.h
+++ b/src/peerstore/peerstore.h
@@ -60,7 +60,7 @@ struct StoreRecordMessage
60 /** 60 /**
61 * Expiry time of entry 61 * Expiry time of entry
62 */ 62 */
63 struct GNUNET_TIME_Absolute expiry GNUNET_PACKED; 63 struct GNUNET_TIME_AbsoluteNBO expiry;
64 64
65 /** 65 /**
66 * Size of the key string 66 * Size of the key string
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index c9fcd17ab..df182fe10 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -286,6 +286,10 @@ store_request_sent (void *cls)
286/******************* CONNECTION FUNCTIONS *********************/ 286/******************* CONNECTION FUNCTIONS *********************/
287/******************************************************************************/ 287/******************************************************************************/
288 288
289
290/**
291 * Function called when we had trouble talking to the service.
292 */
289static void 293static void
290handle_client_error (void *cls, 294handle_client_error (void *cls,
291 enum GNUNET_MQ_Error error) 295 enum GNUNET_MQ_Error error)
@@ -293,7 +297,7 @@ handle_client_error (void *cls,
293 struct GNUNET_PEERSTORE_Handle *h = cls; 297 struct GNUNET_PEERSTORE_Handle *h = cls;
294 298
295 LOG (GNUNET_ERROR_TYPE_ERROR, 299 LOG (GNUNET_ERROR_TYPE_ERROR,
296 _("Received an error notification from MQ of type: %d\n"), 300 "Received an error notification from MQ of type: %d\n",
297 error); 301 error);
298 reconnect (h); 302 reconnect (h);
299} 303}
@@ -341,7 +345,9 @@ iterate_timeout (void *cls)
341 callback_cls = ic->callback_cls; 345 callback_cls = ic->callback_cls;
342 GNUNET_PEERSTORE_iterate_cancel (ic); 346 GNUNET_PEERSTORE_iterate_cancel (ic);
343 if (NULL != callback) 347 if (NULL != callback)
344 callback (callback_cls, NULL, _("timeout")); 348 callback (callback_cls,
349 NULL,
350 _("timeout"));
345} 351}
346 352
347 353
@@ -510,7 +516,7 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
510 "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n", 516 "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n",
511 size, sub_system, GNUNET_i2s (peer), key); 517 size, sub_system, GNUNET_i2s (peer), key);
512 ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, value, size, 518 ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, value, size,
513 &expiry, options, 519 expiry, options,
514 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); 520 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
515 sc = GNUNET_new (struct GNUNET_PEERSTORE_StoreContext); 521 sc = GNUNET_new (struct GNUNET_PEERSTORE_StoreContext);
516 522
@@ -684,8 +690,12 @@ GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
684 struct GNUNET_MQ_Envelope *ev; 690 struct GNUNET_MQ_Envelope *ev;
685 struct GNUNET_PEERSTORE_IterateContext *ic; 691 struct GNUNET_PEERSTORE_IterateContext *ic;
686 692
687 ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, NULL, 0, 693 ev = PEERSTORE_create_record_mq_envelope (sub_system,
694 peer,
695 key,
688 NULL, 0, 696 NULL, 0,
697 GNUNET_TIME_UNIT_FOREVER_ABS,
698 0,
689 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); 699 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE);
690 ic = GNUNET_new (struct GNUNET_PEERSTORE_IterateContext); 700 ic = GNUNET_new (struct GNUNET_PEERSTORE_IterateContext);
691 701
@@ -756,7 +766,7 @@ handle_watch_record (void *cls,
756 return; 766 return;
757 } 767 }
758 PEERSTORE_hash_key (record->sub_system, 768 PEERSTORE_hash_key (record->sub_system,
759 record->peer, 769 &record->peer,
760 record->key, 770 record->key,
761 &keyhash); 771 &keyhash);
762 // FIXME: what if there are multiple watches for the same key? 772 // FIXME: what if there are multiple watches for the same key?
@@ -848,9 +858,12 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
848 &ic->peer, 858 &ic->peer,
849 ic->key, 859 ic->key,
850 NULL, 0, 860 NULL, 0,
851 NULL, 0, 861 GNUNET_TIME_UNIT_FOREVER_ABS,
862 0,
852 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); 863 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE);
853 GNUNET_MQ_send (h->mq, ev); 864 GNUNET_MQ_send (h->mq, ev);
865 if (NULL != ic->timeout_task)
866 GNUNET_SCHEDULER_cancel (ic->timeout_task);
854 ic->timeout_task 867 ic->timeout_task
855 = GNUNET_SCHEDULER_add_delayed (ic->timeout, 868 = GNUNET_SCHEDULER_add_delayed (ic->timeout,
856 &iterate_timeout, 869 &iterate_timeout,
@@ -863,7 +876,7 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
863 sc->key, 876 sc->key,
864 sc->value, 877 sc->value,
865 sc->size, 878 sc->size,
866 &sc->expiry, 879 sc->expiry,
867 sc->options, 880 sc->options,
868 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); 881 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
869 GNUNET_MQ_notify_sent (ev, 882 GNUNET_MQ_notify_sent (ev,
diff --git a/src/peerstore/peerstore_common.c b/src/peerstore/peerstore_common.c
index d12c4e21e..e0ab778fa 100644
--- a/src/peerstore/peerstore_common.c
+++ b/src/peerstore/peerstore_common.c
@@ -77,7 +77,7 @@ PEERSTORE_create_record_mq_envelope (const char *sub_system,
77 const char *key, 77 const char *key,
78 const void *value, 78 const void *value,
79 size_t value_size, 79 size_t value_size,
80 struct GNUNET_TIME_Absolute *expiry, 80 struct GNUNET_TIME_Absolute expiry,
81 enum GNUNET_PEERSTORE_StoreOption options, 81 enum GNUNET_PEERSTORE_StoreOption options,
82 uint16_t msg_type) 82 uint16_t msg_type)
83{ 83{
@@ -97,8 +97,7 @@ PEERSTORE_create_record_mq_envelope (const char *sub_system,
97 msg_size = ss_size + key_size + value_size; 97 msg_size = ss_size + key_size + value_size;
98 ev = GNUNET_MQ_msg_extra (srm, msg_size, msg_type); 98 ev = GNUNET_MQ_msg_extra (srm, msg_size, msg_type);
99 srm->key_size = htons (key_size); 99 srm->key_size = htons (key_size);
100 if (NULL != expiry) 100 srm->expiry = GNUNET_TIME_absolute_hton (expiry);
101 srm->expiry = *expiry;
102 if (NULL == peer) 101 if (NULL == peer)
103 srm->peer_set = htons (GNUNET_NO); 102 srm->peer_set = htons (GNUNET_NO);
104 else 103 else
@@ -147,12 +146,9 @@ PEERSTORE_parse_record_message (const struct StoreRecordMessage *srm)
147 record = GNUNET_new (struct GNUNET_PEERSTORE_Record); 146 record = GNUNET_new (struct GNUNET_PEERSTORE_Record);
148 if (GNUNET_YES == ntohs (srm->peer_set)) 147 if (GNUNET_YES == ntohs (srm->peer_set))
149 { 148 {
150 record->peer = GNUNET_new (struct GNUNET_PeerIdentity); 149 record->peer = srm->peer;
151 *record->peer = srm->peer;
152 } 150 }
153 record->expiry = GNUNET_new (struct GNUNET_TIME_Absolute); 151 record->expiry = GNUNET_TIME_absolute_ntoh (srm->expiry);
154
155 *(record->expiry) = srm->expiry;
156 dummy = (char *) &srm[1]; 152 dummy = (char *) &srm[1];
157 if (ss_size > 0) 153 if (ss_size > 0)
158 { 154 {
@@ -167,7 +163,9 @@ PEERSTORE_parse_record_message (const struct StoreRecordMessage *srm)
167 if (value_size > 0) 163 if (value_size > 0)
168 { 164 {
169 record->value = GNUNET_malloc (value_size); 165 record->value = GNUNET_malloc (value_size);
170 GNUNET_memcpy (record->value, dummy, value_size); 166 GNUNET_memcpy (record->value,
167 dummy,
168 value_size);
171 } 169 }
172 record->value_size = value_size; 170 record->value_size = value_size;
173 return record; 171 return record;
@@ -184,8 +182,6 @@ PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record)
184{ 182{
185 if (NULL != record->sub_system) 183 if (NULL != record->sub_system)
186 GNUNET_free (record->sub_system); 184 GNUNET_free (record->sub_system);
187 if (NULL != record->peer)
188 GNUNET_free (record->peer);
189 if (NULL != record->key) 185 if (NULL != record->key)
190 GNUNET_free (record->key); 186 GNUNET_free (record->key);
191 if (NULL != record->value) 187 if (NULL != record->value)
@@ -193,7 +189,5 @@ PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record)
193 GNUNET_free (record->value); 189 GNUNET_free (record->value);
194 record->value = 0; 190 record->value = 0;
195 } 191 }
196 if (NULL != record->expiry)
197 GNUNET_free (record->expiry);
198 GNUNET_free (record); 192 GNUNET_free (record);
199} 193}
diff --git a/src/peerstore/peerstore_common.h b/src/peerstore/peerstore_common.h
index 3d938b5da..0fc14d9b4 100644
--- a/src/peerstore/peerstore_common.h
+++ b/src/peerstore/peerstore_common.h
@@ -56,7 +56,7 @@ PEERSTORE_create_record_mq_envelope (const char *sub_system,
56 const char *key, 56 const char *key,
57 const void *value, 57 const void *value,
58 size_t value_size, 58 size_t value_size,
59 struct GNUNET_TIME_Absolute *expiry, 59 struct GNUNET_TIME_Absolute expiry,
60 enum GNUNET_PEERSTORE_StoreOption options, 60 enum GNUNET_PEERSTORE_StoreOption options,
61 uint16_t msg_type); 61 uint16_t msg_type);
62 62
diff --git a/src/peerstore/plugin_peerstore_flat.c b/src/peerstore/plugin_peerstore_flat.c
index 2b90719d9..c75b2b1e4 100644
--- a/src/peerstore/plugin_peerstore_flat.c
+++ b/src/peerstore/plugin_peerstore_flat.c
@@ -107,7 +107,9 @@ delete_entries (void *cls,
107 struct GNUNET_PEERSTORE_Record *entry = value; 107 struct GNUNET_PEERSTORE_Record *entry = value;
108 if (0 != strcmp (plugin->iter_key, entry->key)) 108 if (0 != strcmp (plugin->iter_key, entry->key))
109 return GNUNET_YES; 109 return GNUNET_YES;
110 if (0 != memcmp (plugin->iter_peer, entry->peer, sizeof (struct GNUNET_PeerIdentity))) 110 if (0 != memcmp (plugin->iter_peer,
111 &entry->peer,
112 sizeof (struct GNUNET_PeerIdentity)))
111 return GNUNET_YES; 113 return GNUNET_YES;
112 if (0 != strcmp (plugin->iter_sub_system, entry->sub_system)) 114 if (0 != strcmp (plugin->iter_sub_system, entry->sub_system))
113 return GNUNET_YES; 115 return GNUNET_YES;
@@ -153,7 +155,7 @@ expire_entries (void *cls,
153 struct Plugin *plugin = cls; 155 struct Plugin *plugin = cls;
154 struct GNUNET_PEERSTORE_Record *entry = value; 156 struct GNUNET_PEERSTORE_Record *entry = value;
155 157
156 if (entry->expiry->abs_value_us < plugin->iter_now.abs_value_us) 158 if (entry->expiry.abs_value_us < plugin->iter_now.abs_value_us)
157 { 159 {
158 GNUNET_CONTAINER_multihashmap_remove (plugin->hm, key, value); 160 GNUNET_CONTAINER_multihashmap_remove (plugin->hm, key, value);
159 plugin->exp_changes++; 161 plugin->exp_changes++;
@@ -204,7 +206,7 @@ iterate_entries (void *cls,
204 206
205 if ((NULL != plugin->iter_peer) && 207 if ((NULL != plugin->iter_peer) &&
206 (0 != memcmp (plugin->iter_peer, 208 (0 != memcmp (plugin->iter_peer,
207 entry->peer, 209 &entry->peer,
208 sizeof (struct GNUNET_PeerIdentity)))) 210 sizeof (struct GNUNET_PeerIdentity))))
209 { 211 {
210 return GNUNET_YES; 212 return GNUNET_YES;
@@ -296,10 +298,8 @@ peerstore_flat_store_record (void *cls, const char *sub_system,
296 entry->value = GNUNET_malloc (size); 298 entry->value = GNUNET_malloc (size);
297 GNUNET_memcpy (entry->value, value, size); 299 GNUNET_memcpy (entry->value, value, size);
298 entry->value_size = size; 300 entry->value_size = size;
299 entry->peer = GNUNET_new (struct GNUNET_PeerIdentity); 301 entry->peer = *peer;
300 GNUNET_memcpy (entry->peer, peer, sizeof (struct GNUNET_PeerIdentity)); 302 entry->expiry = expiry;
301 entry->expiry = GNUNET_new (struct GNUNET_TIME_Absolute);
302 entry->expiry->abs_value_us = expiry.abs_value_us;
303 303
304 peer_id = GNUNET_i2s (peer); 304 peer_id = GNUNET_i2s (peer);
305 GNUNET_CRYPTO_hash (peer_id, 305 GNUNET_CRYPTO_hash (peer_id,
@@ -409,7 +409,7 @@ database_setup (struct Plugin *plugin)
409 GNUNET_free (buffer); 409 GNUNET_free (buffer);
410 return GNUNET_SYSERR; 410 return GNUNET_SYSERR;
411 } 411 }
412 412
413 buffer[size] = '\0'; 413 buffer[size] = '\0';
414 GNUNET_DISK_file_close (fh); 414 GNUNET_DISK_file_close (fh);
415 if (0 < size) { 415 if (0 < size) {
@@ -433,22 +433,35 @@ database_setup (struct Plugin *plugin)
433 entry = GNUNET_new (struct GNUNET_PEERSTORE_Record); 433 entry = GNUNET_new (struct GNUNET_PEERSTORE_Record);
434 entry->sub_system = GNUNET_strdup (sub_system); 434 entry->sub_system = GNUNET_strdup (sub_system);
435 entry->key = GNUNET_strdup (key); 435 entry->key = GNUNET_strdup (key);
436 GNUNET_STRINGS_base64_decode (peer, 436 {
437 strlen (peer), 437 size_t s;
438 (char**)&entry->peer); 438 char *o;
439
440 o = NULL;
441 s = GNUNET_STRINGS_base64_decode (peer,
442 strlen (peer),
443 &o);
444 if (sizeof (struct GNUNET_PeerIdentity) == s)
445 GNUNET_memcpy (&entry->peer,
446 o,
447 s);
448 else
449 GNUNET_break (0);
450 GNUNET_free_non_null (o);
451 }
439 entry->value_size = GNUNET_STRINGS_base64_decode (value, 452 entry->value_size = GNUNET_STRINGS_base64_decode (value,
440 strlen (value), 453 strlen (value),
441 (char**)&entry->value); 454 (char**)&entry->value);
442 if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_time_to_absolute (expiry, 455 if (GNUNET_SYSERR ==
443 entry->expiry)) 456 GNUNET_STRINGS_fancy_time_to_absolute (expiry,
457 &entry->expiry))
444 { 458 {
445 GNUNET_free (entry->sub_system); 459 GNUNET_free (entry->sub_system);
446 GNUNET_free (entry->key); 460 GNUNET_free (entry->key);
447 GNUNET_free (entry->peer);
448 GNUNET_free (entry); 461 GNUNET_free (entry);
449 break; 462 break;
450 } 463 }
451 peer_id = GNUNET_i2s (entry->peer); 464 peer_id = GNUNET_i2s (&entry->peer);
452 GNUNET_CRYPTO_hash (peer_id, 465 GNUNET_CRYPTO_hash (peer_id,
453 strlen (peer_id), 466 strlen (peer_id),
454 &hkey); 467 &hkey);
@@ -479,8 +492,8 @@ store_and_free_entries (void *cls,
479 GNUNET_STRINGS_base64_encode (entry->value, 492 GNUNET_STRINGS_base64_encode (entry->value,
480 entry->value_size, 493 entry->value_size,
481 &val); 494 &val);
482 expiry = GNUNET_STRINGS_absolute_time_to_string (*entry->expiry); 495 expiry = GNUNET_STRINGS_absolute_time_to_string (entry->expiry);
483 GNUNET_STRINGS_base64_encode ((char*)entry->peer, 496 GNUNET_STRINGS_base64_encode ((char*)&entry->peer,
484 sizeof (struct GNUNET_PeerIdentity), 497 sizeof (struct GNUNET_PeerIdentity),
485 &peer); 498 &peer);
486 GNUNET_asprintf (&line, 499 GNUNET_asprintf (&line,
@@ -496,10 +509,8 @@ store_and_free_entries (void *cls,
496 line, 509 line,
497 strlen (line)); 510 strlen (line));
498 GNUNET_free (entry->sub_system); 511 GNUNET_free (entry->sub_system);
499 GNUNET_free (entry->peer);
500 GNUNET_free (entry->key); 512 GNUNET_free (entry->key);
501 GNUNET_free (entry->value); 513 GNUNET_free (entry->value);
502 GNUNET_free (entry->expiry);
503 GNUNET_free (entry); 514 GNUNET_free (entry);
504 GNUNET_free (line); 515 GNUNET_free (line);
505 return GNUNET_YES; 516 return GNUNET_YES;
diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c
index 2cd7e22cf..440263d44 100644
--- a/src/peerstore/plugin_peerstore_sqlite.c
+++ b/src/peerstore/plugin_peerstore_sqlite.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * This file is part of GNUnet 2 * This file is part of GNUnet
3 * Copyright (C) 2013 GNUnet e.V. 3 * Copyright (C) 2013, 2017 GNUnet e.V.
4 * 4 *
5 * GNUnet is free software; you can redistribute it and/or modify 5 * GNUnet is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published 6 * it under the terms of the GNU General Public License as published
@@ -22,11 +22,13 @@
22 * @file peerstore/plugin_peerstore_sqlite.c 22 * @file peerstore/plugin_peerstore_sqlite.c
23 * @brief sqlite-based peerstore backend 23 * @brief sqlite-based peerstore backend
24 * @author Omar Tarabai 24 * @author Omar Tarabai
25 * @author Christian Grothoff
25 */ 26 */
26 27
27#include "platform.h" 28#include "platform.h"
28#include "gnunet_peerstore_plugin.h" 29#include "gnunet_peerstore_plugin.h"
29#include "gnunet_peerstore_service.h" 30#include "gnunet_peerstore_service.h"
31#include "gnunet_sq_lib.h"
30#include "peerstore.h" 32#include "peerstore.h"
31#include <sqlite3.h> 33#include <sqlite3.h>
32 34
@@ -111,6 +113,7 @@ struct Plugin
111 113
112}; 114};
113 115
116
114/** 117/**
115 * Delete records with the given key 118 * Delete records with the given key
116 * 119 *
@@ -118,40 +121,50 @@ struct Plugin
118 * @param sub_system name of sub system 121 * @param sub_system name of sub system
119 * @param peer Peer identity (can be NULL) 122 * @param peer Peer identity (can be NULL)
120 * @param key entry key string (can be NULL) 123 * @param key entry key string (can be NULL)
121 * @return number of deleted records 124 * @return number of deleted records, #GNUNE_SYSERR on error
122 */ 125 */
123static int 126static int
124peerstore_sqlite_delete_records (void *cls, const char *sub_system, 127peerstore_sqlite_delete_records (void *cls,
128 const char *sub_system,
125 const struct GNUNET_PeerIdentity *peer, 129 const struct GNUNET_PeerIdentity *peer,
126 const char *key) 130 const char *key)
127{ 131{
128 struct Plugin *plugin = cls; 132 struct Plugin *plugin = cls;
129 sqlite3_stmt *stmt = plugin->delete_peerstoredata; 133 sqlite3_stmt *stmt = plugin->delete_peerstoredata;
134 struct GNUNET_SQ_QueryParam params[] = {
135 GNUNET_SQ_query_param_string (sub_system),
136 GNUNET_SQ_query_param_auto_from_type (peer),
137 GNUNET_SQ_query_param_string (key),
138 GNUNET_SQ_query_param_end
139 };
140 int ret;
130 141
131 if ((SQLITE_OK != 142 if (GNUNET_OK !=
132 sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, 143 GNUNET_SQ_bind (stmt,
133 SQLITE_STATIC)) || 144 params))
134 (SQLITE_OK !=
135 sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity),
136 SQLITE_STATIC)) ||
137 (SQLITE_OK !=
138 sqlite3_bind_text (stmt, 3, key, strlen (key) + 1, SQLITE_STATIC)))
139 { 145 {
140 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 146 LOG_SQLITE (plugin,
147 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
141 "sqlite3_bind"); 148 "sqlite3_bind");
149 GNUNET_SQ_reset (plugin->dbh,
150 stmt);
151 return GNUNET_SYSERR;
142 } 152 }
143 else if (SQLITE_DONE != sqlite3_step (stmt)) 153 if (SQLITE_DONE !=
154 sqlite3_step (stmt))
144 { 155 {
145 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 156 LOG_SQLITE (plugin,
157 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
146 "sqlite3_step"); 158 "sqlite3_step");
159 ret = GNUNET_SYSERR;
147 } 160 }
148 if (SQLITE_OK != sqlite3_reset (stmt)) 161 else
149 { 162 {
150 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 163 ret = sqlite3_changes (plugin->dbh);
151 "sqlite3_reset");
152 return 0;
153 } 164 }
154 return sqlite3_changes (plugin->dbh); 165 GNUNET_SQ_reset (plugin->dbh,
166 stmt);
167 return ret;
155} 168}
156 169
157 170
@@ -172,28 +185,36 @@ peerstore_sqlite_expire_records (void *cls, struct GNUNET_TIME_Absolute now,
172{ 185{
173 struct Plugin *plugin = cls; 186 struct Plugin *plugin = cls;
174 sqlite3_stmt *stmt = plugin->expire_peerstoredata; 187 sqlite3_stmt *stmt = plugin->expire_peerstoredata;
188 struct GNUNET_SQ_QueryParam params[] = {
189 GNUNET_SQ_query_param_absolute_time (&now),
190 GNUNET_SQ_query_param_end
191 };
175 192
176 if (SQLITE_OK != 193 if (GNUNET_OK !=
177 sqlite3_bind_int64 (stmt, 1, (sqlite3_uint64) now.abs_value_us)) 194 GNUNET_SQ_bind (stmt,
195 params))
178 { 196 {
179 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 197 LOG_SQLITE (plugin,
198 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
180 "sqlite3_bind"); 199 "sqlite3_bind");
200 GNUNET_SQ_reset (plugin->dbh,
201 stmt);
202 return GNUNET_SYSERR;
181 } 203 }
182 else if (SQLITE_DONE != sqlite3_step (stmt)) 204 if (SQLITE_DONE != sqlite3_step (stmt))
183 { 205 {
184 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 206 LOG_SQLITE (plugin,
207 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
185 "sqlite3_step"); 208 "sqlite3_step");
186 } 209 GNUNET_SQ_reset (plugin->dbh,
187 if (SQLITE_OK != sqlite3_reset (stmt)) 210 stmt);
188 {
189 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
190 "sqlite3_reset");
191 return GNUNET_SYSERR; 211 return GNUNET_SYSERR;
192 } 212 }
193 if (NULL != cont) 213 if (NULL != cont)
194 { 214 cont (cont_cls,
195 cont (cont_cls, sqlite3_changes (plugin->dbh)); 215 sqlite3_changes (plugin->dbh));
196 } 216 GNUNET_SQ_reset (plugin->dbh,
217 stmt);
197 return GNUNET_OK; 218 return GNUNET_OK;
198} 219}
199 220
@@ -213,7 +234,8 @@ peerstore_sqlite_expire_records (void *cls, struct GNUNET_TIME_Absolute now,
213 * called 234 * called
214 */ 235 */
215static int 236static int
216peerstore_sqlite_iterate_records (void *cls, const char *sub_system, 237peerstore_sqlite_iterate_records (void *cls,
238 const char *sub_system,
217 const struct GNUNET_PeerIdentity *peer, 239 const struct GNUNET_PeerIdentity *peer,
218 const char *key, 240 const char *key,
219 GNUNET_PEERSTORE_Processor iter, 241 GNUNET_PEERSTORE_Processor iter,
@@ -223,94 +245,115 @@ peerstore_sqlite_iterate_records (void *cls, const char *sub_system,
223 sqlite3_stmt *stmt; 245 sqlite3_stmt *stmt;
224 int err = 0; 246 int err = 0;
225 int sret; 247 int sret;
226 struct GNUNET_PEERSTORE_Record *ret; 248 struct GNUNET_PEERSTORE_Record rec;
227 249
228 LOG (GNUNET_ERROR_TYPE_DEBUG, "Executing iterate request on sqlite db.\n"); 250 LOG (GNUNET_ERROR_TYPE_DEBUG,
229 if (NULL == peer && NULL == key) 251 "Executing iterate request on sqlite db.\n");
230 { 252 if (NULL == peer)
231 stmt = plugin->select_peerstoredata;
232 err =
233 (SQLITE_OK !=
234 sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1,
235 SQLITE_STATIC));
236 }
237 else if (NULL == key)
238 {
239 stmt = plugin->select_peerstoredata_by_pid;
240 err =
241 (SQLITE_OK !=
242 sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1,
243 SQLITE_STATIC)) ||
244 (SQLITE_OK !=
245 sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity),
246 SQLITE_STATIC));
247 }
248 else if (NULL == peer)
249 { 253 {
250 stmt = plugin->select_peerstoredata_by_key; 254 if (NULL == key)
251 err = 255 {
252 (SQLITE_OK != 256 struct GNUNET_SQ_QueryParam params[] = {
253 sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, 257 GNUNET_SQ_query_param_string (sub_system),
254 SQLITE_STATIC)) || 258 GNUNET_SQ_query_param_end
255 (SQLITE_OK != 259 };
256 sqlite3_bind_text (stmt, 2, key, strlen (key) + 1, SQLITE_STATIC)); 260
261 stmt = plugin->select_peerstoredata;
262 err = GNUNET_SQ_bind (stmt,
263 params);
264 }
265 else
266 {
267 struct GNUNET_SQ_QueryParam params[] = {
268 GNUNET_SQ_query_param_string (sub_system),
269 GNUNET_SQ_query_param_string (key),
270 GNUNET_SQ_query_param_end
271 };
272
273 stmt = plugin->select_peerstoredata_by_key;
274 err = GNUNET_SQ_bind (stmt,
275 params);
276 }
257 } 277 }
258 else 278 else
259 { 279 {
260 stmt = plugin->select_peerstoredata_by_all; 280 if (NULL == key)
261 err = 281 {
262 (SQLITE_OK != 282 struct GNUNET_SQ_QueryParam params[] = {
263 sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, 283 GNUNET_SQ_query_param_string (sub_system),
264 SQLITE_STATIC)) || 284 GNUNET_SQ_query_param_auto_from_type (peer),
265 (SQLITE_OK != 285 GNUNET_SQ_query_param_end
266 sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity), 286 };
267 SQLITE_STATIC)) || 287
268 (SQLITE_OK != 288 stmt = plugin->select_peerstoredata_by_pid;
269 sqlite3_bind_text (stmt, 3, key, strlen (key) + 1, SQLITE_STATIC)); 289 err = GNUNET_SQ_bind (stmt,
290 params);
291 }
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 }
270 } 305 }
271 306
272 if (err) 307 if (GNUNET_OK != err)
273 { 308 {
274 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 309 LOG_SQLITE (plugin,
310 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
275 "sqlite3_bind_XXXX"); 311 "sqlite3_bind_XXXX");
276 if (SQLITE_OK != sqlite3_reset (stmt)) 312 GNUNET_SQ_reset (plugin->dbh,
277 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 313 stmt);
278 "sqlite3_reset");
279 return GNUNET_SYSERR; 314 return GNUNET_SYSERR;
280 } 315 }
316
317 err = 0;
281 while (SQLITE_ROW == (sret = sqlite3_step (stmt))) 318 while (SQLITE_ROW == (sret = sqlite3_step (stmt)))
282 { 319 {
283 LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning a matched record.\n"); 320 LOG (GNUNET_ERROR_TYPE_DEBUG,
284 ret = GNUNET_new (struct GNUNET_PEERSTORE_Record); 321 "Returning a matched record.\n");
285 322 struct GNUNET_SQ_ResultSpec rs[] = {
286 ret->sub_system = (char *) sqlite3_column_text (stmt, 0); 323 GNUNET_SQ_result_spec_string (&rec.sub_system),
287 ret->peer = (struct GNUNET_PeerIdentity *) sqlite3_column_blob (stmt, 1); 324 GNUNET_SQ_result_spec_auto_from_type (&rec.peer),
288 ret->key = (char *) sqlite3_column_text (stmt, 2); 325 GNUNET_SQ_result_spec_string (&rec.key),
289 ret->value = (void *) sqlite3_column_blob (stmt, 3); 326 GNUNET_SQ_result_spec_variable_size (&rec.value, &rec.value_size),
290 ret->value_size = sqlite3_column_bytes (stmt, 3); 327 GNUNET_SQ_result_spec_absolute_time (&rec.expiry),
291 ret->expiry = GNUNET_new (struct GNUNET_TIME_Absolute); 328 GNUNET_SQ_result_spec_end
292 329 };
293 ret->expiry->abs_value_us = (uint64_t) sqlite3_column_int64 (stmt, 4); 330
331 if (GNUNET_OK !=
332 GNUNET_SQ_extract_result (stmt,
333 rs))
334 {
335 GNUNET_break (0);
336 break;
337 }
294 if (NULL != iter) 338 if (NULL != iter)
295 iter (iter_cls, ret, NULL); 339 iter (iter_cls,
296 GNUNET_free (ret->expiry); 340 &rec,
297 GNUNET_free (ret); 341 NULL);
342 GNUNET_SQ_cleanup_result (rs);
298 } 343 }
299 if (SQLITE_DONE != sret) 344 if (SQLITE_DONE != sret)
300 { 345 {
301 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); 346 LOG_SQLITE (plugin,
302 err = 1; 347 GNUNET_ERROR_TYPE_ERROR,
303 } 348 "sqlite_step");
304 if (SQLITE_OK != sqlite3_reset (stmt))
305 {
306 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
307 "sqlite3_reset");
308 err = 1; 349 err = 1;
309 } 350 }
351 GNUNET_SQ_reset (plugin->dbh,
352 stmt);
310 if (NULL != iter) 353 if (NULL != iter)
311 { 354 iter (iter_cls,
312 iter (iter_cls, NULL, err ? "sqlite error" : NULL); 355 NULL,
313 } 356 err ? "sqlite error" : NULL);
314 return GNUNET_OK; 357 return GNUNET_OK;
315} 358}
316 359
@@ -333,9 +376,12 @@ peerstore_sqlite_iterate_records (void *cls, const char *sub_system,
333 * @return #GNUNET_OK on success, else #GNUNET_SYSERR and cont is not called 376 * @return #GNUNET_OK on success, else #GNUNET_SYSERR and cont is not called
334 */ 377 */
335static int 378static int
336peerstore_sqlite_store_record (void *cls, const char *sub_system, 379peerstore_sqlite_store_record (void *cls,
380 const char *sub_system,
337 const struct GNUNET_PeerIdentity *peer, 381 const struct GNUNET_PeerIdentity *peer,
338 const char *key, const void *value, size_t size, 382 const char *key,
383 const void *value,
384 size_t size,
339 struct GNUNET_TIME_Absolute expiry, 385 struct GNUNET_TIME_Absolute expiry,
340 enum GNUNET_PEERSTORE_StoreOption options, 386 enum GNUNET_PEERSTORE_StoreOption options,
341 GNUNET_PEERSTORE_Continuation cont, 387 GNUNET_PEERSTORE_Continuation cont,
@@ -343,39 +389,39 @@ peerstore_sqlite_store_record (void *cls, const char *sub_system,
343{ 389{
344 struct Plugin *plugin = cls; 390 struct Plugin *plugin = cls;
345 sqlite3_stmt *stmt = plugin->insert_peerstoredata; 391 sqlite3_stmt *stmt = plugin->insert_peerstoredata;
392 struct GNUNET_SQ_QueryParam params[] = {
393 GNUNET_SQ_query_param_string (sub_system),
394 GNUNET_SQ_query_param_auto_from_type (peer),
395 GNUNET_SQ_query_param_string (key),
396 GNUNET_SQ_query_param_fixed_size (value, size),
397 GNUNET_SQ_query_param_absolute_time (&expiry),
398 GNUNET_SQ_query_param_end
399 };
346 400
347 if (GNUNET_PEERSTORE_STOREOPTION_REPLACE == options) 401 if (GNUNET_PEERSTORE_STOREOPTION_REPLACE == options)
348 { 402 {
349 peerstore_sqlite_delete_records (cls, sub_system, peer, key); 403 peerstore_sqlite_delete_records (cls,
404 sub_system,
405 peer,
406 key);
350 } 407 }
351 if (SQLITE_OK != 408 if (GNUNET_OK !=
352 sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, 409 GNUNET_SQ_bind (stmt,
353 SQLITE_STATIC) || 410 params))
354 SQLITE_OK != sqlite3_bind_blob (stmt, 2, peer, 411 LOG_SQLITE (plugin,
355 sizeof (struct GNUNET_PeerIdentity), 412 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
356 SQLITE_STATIC) ||
357 SQLITE_OK != sqlite3_bind_text (stmt, 3, key, strlen (key) + 1,
358 SQLITE_STATIC) ||
359 SQLITE_OK != sqlite3_bind_blob (stmt, 4, value, size, SQLITE_STATIC) ||
360 SQLITE_OK != sqlite3_bind_int64 (stmt, 5,
361 (sqlite3_uint64) expiry.abs_value_us))
362 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
363 "sqlite3_bind"); 413 "sqlite3_bind");
364 else if (SQLITE_DONE != sqlite3_step (stmt)) 414 else if (SQLITE_DONE != sqlite3_step (stmt))
365 { 415 {
366 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 416 LOG_SQLITE (plugin,
417 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
367 "sqlite3_step"); 418 "sqlite3_step");
368 } 419 }
369 if (SQLITE_OK != sqlite3_reset (stmt)) 420 GNUNET_SQ_reset (plugin->dbh,
370 { 421 stmt);
371 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
372 "sqlite3_reset");
373 return GNUNET_SYSERR;
374 }
375 if (NULL != cont) 422 if (NULL != cont)
376 { 423 cont (cont_cls,
377 cont (cont_cls, GNUNET_OK); 424 GNUNET_OK);
378 }
379 return GNUNET_OK; 425 return GNUNET_OK;
380} 426}
381 427
@@ -388,15 +434,25 @@ peerstore_sqlite_store_record (void *cls, const char *sub_system,
388 * @return 0 on success 434 * @return 0 on success
389 */ 435 */
390static int 436static int
391sql_exec (sqlite3 * dbh, const char *sql) 437sql_exec (sqlite3 *dbh,
438 const char *sql)
392{ 439{
393 int result; 440 int result;
394 441
395 result = sqlite3_exec (dbh, sql, NULL, NULL, NULL); 442 result = sqlite3_exec (dbh,
396 LOG (GNUNET_ERROR_TYPE_DEBUG, "Executed `%s' / %d\n", sql, result); 443 sql,
397 if (result != SQLITE_OK) 444 NULL,
398 LOG (GNUNET_ERROR_TYPE_ERROR, _("Error executing SQL query: %s\n %s\n"), 445 NULL,
399 sqlite3_errmsg (dbh), sql); 446 NULL);
447 LOG (GNUNET_ERROR_TYPE_DEBUG,
448 "Executed `%s' / %d\n",
449 sql,
450 result);
451 if (SQLITE_OK != result)
452 LOG (GNUNET_ERROR_TYPE_ERROR,
453 _("Error executing SQL query: %s\n %s\n"),
454 sqlite3_errmsg (dbh),
455 sql);
400 return result; 456 return result;
401} 457}
402 458
@@ -410,38 +466,33 @@ sql_exec (sqlite3 * dbh, const char *sql)
410 * @return 0 on success 466 * @return 0 on success
411 */ 467 */
412static int 468static int
413sql_prepare (sqlite3 * dbh, const char *sql, sqlite3_stmt ** stmt) 469sql_prepare (sqlite3 *dbh,
470 const char *sql,
471 sqlite3_stmt ** stmt)
414{ 472{
415 char *tail; 473 char *tail;
416 int result; 474 int result;
417 475
418 result = 476 result = sqlite3_prepare_v2 (dbh,
419 sqlite3_prepare_v2 (dbh, sql, strlen (sql), stmt, (const char **) &tail); 477 sql,
420 LOG (GNUNET_ERROR_TYPE_DEBUG, "Prepared `%s' / %p: %d\n", sql, *stmt, result); 478 strlen (sql),
421 if (result != SQLITE_OK) 479 stmt,
422 LOG (GNUNET_ERROR_TYPE_ERROR, _("Error preparing SQL query: %s\n %s\n"), 480 (const char **) &tail);
423 sqlite3_errmsg (dbh), sql); 481 LOG (GNUNET_ERROR_TYPE_DEBUG,
482 "Prepared `%s' / %p: %d\n",
483 sql,
484 *stmt,
485 result);
486 if (SQLITE_OK != result)
487 LOG (GNUNET_ERROR_TYPE_ERROR,
488 _("Error preparing SQL query: %s\n %s\n"),
489 sqlite3_errmsg (dbh),
490 sql);
424 return result; 491 return result;
425} 492}
426 493
427 494
428/** 495/**
429 * sqlite3 custom function for comparison of uint64_t values
430 * since it is not supported by default
431 */
432void
433sqlite3_lessthan (sqlite3_context * ctx, int dummy, sqlite3_value ** values)
434{
435 uint64_t v1;
436 uint64_t v2;
437
438 v1 = (uint64_t) sqlite3_value_int64 (values[0]);
439 v2 = (uint64_t) sqlite3_value_int64 (values[1]);
440 sqlite3_result_int (ctx, v1 < v2);
441}
442
443
444/**
445 * Initialize the database connections and associated 496 * Initialize the database connections and associated
446 * data structures (create tables and indices 497 * data structures (create tables and indices
447 * as needed as well). 498 * as needed as well).
@@ -455,10 +506,13 @@ database_setup (struct Plugin *plugin)
455 char *filename; 506 char *filename;
456 507
457 if (GNUNET_OK != 508 if (GNUNET_OK !=
458 GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-sqlite", 509 GNUNET_CONFIGURATION_get_value_filename (plugin->cfg,
459 "FILENAME", &filename)) 510 "peerstore-sqlite",
511 "FILENAME",
512 &filename))
460 { 513 {
461 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-sqlite", 514 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
515 "peerstore-sqlite",
462 "FILENAME"); 516 "FILENAME");
463 return GNUNET_SYSERR; 517 return GNUNET_SYSERR;
464 } 518 }
@@ -474,60 +528,81 @@ database_setup (struct Plugin *plugin)
474 /* filename should be UTF-8-encoded. If it isn't, it's a bug */ 528 /* filename should be UTF-8-encoded. If it isn't, it's a bug */
475 plugin->fn = filename; 529 plugin->fn = filename;
476 /* Open database and precompile statements */ 530 /* Open database and precompile statements */
477 if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh)) 531 if (SQLITE_OK != sqlite3_open (plugin->fn,
532 &plugin->dbh))
478 { 533 {
479 LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize SQLite: %s.\n"), 534 LOG (GNUNET_ERROR_TYPE_ERROR,
535 _("Unable to initialize SQLite: %s.\n"),
480 sqlite3_errmsg (plugin->dbh)); 536 sqlite3_errmsg (plugin->dbh));
481 return GNUNET_SYSERR; 537 return GNUNET_SYSERR;
482 } 538 }
483 sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); 539 sql_exec (plugin->dbh,
484 sql_exec (plugin->dbh, "PRAGMA synchronous=OFF"); 540 "PRAGMA temp_store=MEMORY");
485 sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); 541 sql_exec (plugin->dbh,
486 sql_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL"); 542 "PRAGMA synchronous=OFF");
487 sql_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\""); 543 sql_exec (plugin->dbh,
488 sql_exec (plugin->dbh, "PRAGMA page_size=4096"); 544 "PRAGMA legacy_file_format=OFF");
489 sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS); 545 sql_exec (plugin->dbh,
546 "PRAGMA auto_vacuum=INCREMENTAL");
547 sql_exec (plugin->dbh,
548 "PRAGMA encoding=\"UTF-8\"");
549 sql_exec (plugin->dbh,
550 "PRAGMA page_size=4096");
551 sqlite3_busy_timeout (plugin->dbh,
552 BUSY_TIMEOUT_MS);
490 /* Create tables */ 553 /* Create tables */
491 sql_exec (plugin->dbh, 554 sql_exec (plugin->dbh,
492 "CREATE TABLE IF NOT EXISTS peerstoredata (\n" 555 "CREATE TABLE IF NOT EXISTS peerstoredata (\n"
493 " sub_system TEXT NOT NULL,\n" " peer_id BLOB NOT NULL,\n" 556 " sub_system TEXT NOT NULL,\n"
494 " key TEXT NOT NULL,\n" " value BLOB NULL,\n" 557 " peer_id BLOB NOT NULL,\n"
495 " expiry sqlite3_uint64 NOT NULL" ");"); 558 " key TEXT NOT NULL,\n"
496 sqlite3_create_function (plugin->dbh, "UINT64_LT", 2, SQLITE_UTF8, NULL, 559 " value BLOB NULL,\n"
497 &sqlite3_lessthan, NULL, NULL); 560 " expiry INT8 NOT NULL" ");");
498 /* Create Indices */ 561 /* Create Indices */
499 if (SQLITE_OK != 562 if (SQLITE_OK !=
500 sqlite3_exec (plugin->dbh, 563 sqlite3_exec (plugin->dbh,
501 "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)", 564 "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)",
502 NULL, NULL, NULL)) 565 NULL,
566 NULL,
567 NULL))
503 { 568 {
504 LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to create indices: %s.\n"), 569 LOG (GNUNET_ERROR_TYPE_ERROR,
570 _("Unable to create indices: %s.\n"),
505 sqlite3_errmsg (plugin->dbh)); 571 sqlite3_errmsg (plugin->dbh));
506 return GNUNET_SYSERR; 572 return GNUNET_SYSERR;
507 } 573 }
508 /* Prepare statements */ 574 /* Prepare statements */
509 575
510 sql_prepare (plugin->dbh, 576 sql_prepare (plugin->dbh,
511 "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry) VALUES (?,?,?,?,?);", 577 "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry)"
578 " VALUES (?,?,?,?,?);",
512 &plugin->insert_peerstoredata); 579 &plugin->insert_peerstoredata);
513 sql_prepare (plugin->dbh, 580 sql_prepare (plugin->dbh,
514 "SELECT * FROM peerstoredata" " WHERE sub_system = ?", 581 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
582 " WHERE sub_system = ?",
515 &plugin->select_peerstoredata); 583 &plugin->select_peerstoredata);
516 sql_prepare (plugin->dbh, 584 sql_prepare (plugin->dbh,
517 "SELECT * FROM peerstoredata" " WHERE sub_system = ?" 585 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
518 " AND peer_id = ?", &plugin->select_peerstoredata_by_pid); 586 " WHERE sub_system = ?"
587 " AND peer_id = ?",
588 &plugin->select_peerstoredata_by_pid);
519 sql_prepare (plugin->dbh, 589 sql_prepare (plugin->dbh,
520 "SELECT * FROM peerstoredata" " WHERE sub_system = ?" 590 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
521 " AND key = ?", &plugin->select_peerstoredata_by_key); 591 " WHERE sub_system = ?"
592 " AND key = ?",
593 &plugin->select_peerstoredata_by_key);
522 sql_prepare (plugin->dbh, 594 sql_prepare (plugin->dbh,
523 "SELECT * FROM peerstoredata" " WHERE sub_system = ?" 595 "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata"
596 " WHERE sub_system = ?"
524 " AND peer_id = ?" " AND key = ?", 597 " AND peer_id = ?" " AND key = ?",
525 &plugin->select_peerstoredata_by_all); 598 &plugin->select_peerstoredata_by_all);
526 sql_prepare (plugin->dbh, 599 sql_prepare (plugin->dbh,
527 "DELETE FROM peerstoredata" " WHERE UINT64_LT(expiry, ?)", 600 "DELETE FROM peerstoredata"
601 " WHERE expiry < ?",
528 &plugin->expire_peerstoredata); 602 &plugin->expire_peerstoredata);
529 sql_prepare (plugin->dbh, 603 sql_prepare (plugin->dbh,
530 "DELETE FROM peerstoredata" " WHERE sub_system = ?" 604 "DELETE FROM peerstoredata"
605 " WHERE sub_system = ?"
531 " AND peer_id = ?" " AND key = ?", 606 " AND peer_id = ?" " AND key = ?",
532 &plugin->delete_peerstoredata); 607 &plugin->delete_peerstoredata);
533 return GNUNET_OK; 608 return GNUNET_OK;
@@ -545,15 +620,20 @@ database_shutdown (struct Plugin *plugin)
545 int result; 620 int result;
546 sqlite3_stmt *stmt; 621 sqlite3_stmt *stmt;
547 622
548 while (NULL != (stmt = sqlite3_next_stmt (plugin->dbh, NULL))) 623 while (NULL != (stmt = sqlite3_next_stmt (plugin->dbh,
624 NULL)))
549 { 625 {
550 result = sqlite3_finalize (stmt); 626 result = sqlite3_finalize (stmt);
551 if (SQLITE_OK != result) 627 if (SQLITE_OK != result)
552 LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to close statement %p: %d\n", 628 LOG (GNUNET_ERROR_TYPE_WARNING,
553 stmt, result); 629 "Failed to close statement %p: %d\n",
630 stmt,
631 result);
554 } 632 }
555 if (SQLITE_OK != sqlite3_close (plugin->dbh)) 633 if (SQLITE_OK != sqlite3_close (plugin->dbh))
556 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close"); 634 LOG_SQLITE (plugin,
635 GNUNET_ERROR_TYPE_ERROR,
636 "sqlite3_close");
557 GNUNET_free_non_null (plugin->fn); 637 GNUNET_free_non_null (plugin->fn);
558} 638}
559 639
@@ -573,7 +653,9 @@ libgnunet_plugin_peerstore_sqlite_init (void *cls)
573 653
574 if (NULL != plugin.cfg) 654 if (NULL != plugin.cfg)
575 return NULL; /* can only initialize once! */ 655 return NULL; /* can only initialize once! */
576 memset (&plugin, 0, sizeof (struct Plugin)); 656 memset (&plugin,
657 0,
658 sizeof (struct Plugin));
577 plugin.cfg = cfg; 659 plugin.cfg = cfg;
578 if (GNUNET_OK != database_setup (&plugin)) 660 if (GNUNET_OK != database_setup (&plugin))
579 { 661 {
@@ -585,7 +667,8 @@ libgnunet_plugin_peerstore_sqlite_init (void *cls)
585 api->store_record = &peerstore_sqlite_store_record; 667 api->store_record = &peerstore_sqlite_store_record;
586 api->iterate_records = &peerstore_sqlite_iterate_records; 668 api->iterate_records = &peerstore_sqlite_iterate_records;
587 api->expire_records = &peerstore_sqlite_expire_records; 669 api->expire_records = &peerstore_sqlite_expire_records;
588 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sqlite plugin is running\n"); 670 LOG (GNUNET_ERROR_TYPE_DEBUG,
671 "Sqlite plugin is running\n");
589 return api; 672 return api;
590} 673}
591 674
@@ -605,7 +688,8 @@ libgnunet_plugin_peerstore_sqlite_done (void *cls)
605 database_shutdown (plugin); 688 database_shutdown (plugin);
606 plugin->cfg = NULL; 689 plugin->cfg = NULL;
607 GNUNET_free (api); 690 GNUNET_free (api);
608 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sqlite plugin is finished\n"); 691 LOG (GNUNET_ERROR_TYPE_DEBUG,
692 "Sqlite plugin is finished\n");
609 return NULL; 693 return NULL;
610} 694}
611 695
diff --git a/src/peerstore/test_peerstore_api_iterate.c b/src/peerstore/test_peerstore_api_iterate.c
index 83a6bf7b7..c607d9fb3 100644
--- a/src/peerstore/test_peerstore_api_iterate.c
+++ b/src/peerstore/test_peerstore_api_iterate.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C) 2013-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -42,7 +42,8 @@ static int count = 0;
42 42
43 43
44static void 44static void
45iter3_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, 45iter3_cb (void *cls,
46 const struct GNUNET_PEERSTORE_Record *record,
46 const char *emsg) 47 const char *emsg)
47{ 48{
48 if (NULL != emsg) 49 if (NULL != emsg)
@@ -63,7 +64,8 @@ iter3_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record,
63 64
64 65
65static void 66static void
66iter2_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, 67iter2_cb (void *cls,
68 const struct GNUNET_PEERSTORE_Record *record,
67 const char *emsg) 69 const char *emsg)
68{ 70{
69 if (NULL != emsg) 71 if (NULL != emsg)
@@ -78,13 +80,19 @@ iter2_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record,
78 } 80 }
79 GNUNET_assert (count == 2); 81 GNUNET_assert (count == 2);
80 count = 0; 82 count = 0;
81 ic = GNUNET_PEERSTORE_iterate (h, ss, NULL, NULL, GNUNET_TIME_UNIT_FOREVER_REL, 83 ic = GNUNET_PEERSTORE_iterate (h,
82 iter3_cb, NULL); 84 ss,
85 NULL,
86 NULL,
87 GNUNET_TIME_UNIT_FOREVER_REL,
88 &iter3_cb,
89 NULL);
83} 90}
84 91
85 92
86static void 93static void
87iter1_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, 94iter1_cb (void *cls,
95 const struct GNUNET_PEERSTORE_Record *record,
88 const char *emsg) 96 const char *emsg)
89{ 97{
90 if (NULL != emsg) 98 if (NULL != emsg)
@@ -99,30 +107,61 @@ iter1_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record,
99 } 107 }
100 GNUNET_assert (count == 1); 108 GNUNET_assert (count == 1);
101 count = 0; 109 count = 0;
102 ic = GNUNET_PEERSTORE_iterate (h, ss, &p1, NULL, GNUNET_TIME_UNIT_FOREVER_REL, 110 ic = GNUNET_PEERSTORE_iterate (h,
103 iter2_cb, NULL); 111 ss,
112 &p1,
113 NULL,
114 GNUNET_TIME_UNIT_FOREVER_REL,
115 iter2_cb,
116 NULL);
104} 117}
105 118
106 119
107static void 120static void
108run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, 121run (void *cls,
122 const struct GNUNET_CONFIGURATION_Handle *cfg,
109 struct GNUNET_TESTING_Peer *peer) 123 struct GNUNET_TESTING_Peer *peer)
110{ 124{
111 h = GNUNET_PEERSTORE_connect (cfg); 125 h = GNUNET_PEERSTORE_connect (cfg);
112 GNUNET_assert (NULL != h); 126 GNUNET_assert (NULL != h);
113 memset (&p1, 1, sizeof (p1)); 127 memset (&p1, 1, sizeof (p1));
114 memset (&p2, 2, sizeof (p2)); 128 memset (&p2, 2, sizeof (p2));
115 GNUNET_PEERSTORE_store (h, ss, &p1, k1, val, strlen (val) + 1, 129 GNUNET_PEERSTORE_store (h,
130 ss,
131 &p1,
132 k1,
133 val,
134 strlen (val) + 1,
116 GNUNET_TIME_UNIT_FOREVER_ABS, 135 GNUNET_TIME_UNIT_FOREVER_ABS,
117 GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); 136 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
118 GNUNET_PEERSTORE_store (h, ss, &p1, k2, val, strlen (val) + 1, 137 NULL,
138 NULL);
139 GNUNET_PEERSTORE_store (h,
140 ss,
141 &p1,
142 k2,
143 val,
144 strlen (val) + 1,
119 GNUNET_TIME_UNIT_FOREVER_ABS, 145 GNUNET_TIME_UNIT_FOREVER_ABS,
120 GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); 146 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
121 GNUNET_PEERSTORE_store (h, ss, &p2, k3, val, strlen (val) + 1, 147 NULL,
148 NULL);
149 GNUNET_PEERSTORE_store (h,
150 ss,
151 &p2,
152 k3,
153 val,
154 strlen (val) + 1,
122 GNUNET_TIME_UNIT_FOREVER_ABS, 155 GNUNET_TIME_UNIT_FOREVER_ABS,
123 GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); 156 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
124 ic = GNUNET_PEERSTORE_iterate (h, ss, &p1, k1, GNUNET_TIME_UNIT_FOREVER_REL, 157 NULL,
125 iter1_cb, NULL); 158 NULL);
159 ic = GNUNET_PEERSTORE_iterate (h,
160 ss,
161 &p1,
162 k1,
163 GNUNET_TIME_UNIT_FOREVER_REL,
164 &iter1_cb, NULL);
126} 165}
127 166
128 167
diff --git a/src/peerstore/test_peerstore_api_store.c b/src/peerstore/test_peerstore_api_store.c
index bfe1b5b55..978009dbb 100644
--- a/src/peerstore/test_peerstore_api_store.c
+++ b/src/peerstore/test_peerstore_api_store.c
@@ -39,6 +39,7 @@ static char *val3 = "test_peerstore_api_store_val3--";
39 39
40static int count = 0; 40static int count = 0;
41 41
42
42static void 43static void
43test3_cont2 (void *cls, 44test3_cont2 (void *cls,
44 const struct GNUNET_PEERSTORE_Record *record, 45 const struct GNUNET_PEERSTORE_Record *record,
@@ -49,7 +50,8 @@ test3_cont2 (void *cls,
49 if (NULL != record) 50 if (NULL != record)
50 { 51 {
51 GNUNET_assert ((strlen (val3) + 1) == record->value_size); 52 GNUNET_assert ((strlen (val3) + 1) == record->value_size);
52 GNUNET_assert (0 == strcmp ((char *) val3, (char *) record->value)); 53 GNUNET_assert (0 == strcmp ((char *) val3,
54 (char *) record->value));
53 count++; 55 count++;
54 return; 56 return;
55 } 57 }
@@ -61,7 +63,8 @@ test3_cont2 (void *cls,
61 63
62 64
63static void 65static void
64test3_cont (void *cls, int success) 66test3_cont (void *cls,
67 int success)
65{ 68{
66 if (GNUNET_YES != success) 69 if (GNUNET_YES != success)
67 return; 70 return;
@@ -71,7 +74,8 @@ test3_cont (void *cls, int success)
71 &pid, 74 &pid,
72 key, 75 key,
73 GNUNET_TIME_UNIT_SECONDS, 76 GNUNET_TIME_UNIT_SECONDS,
74 &test3_cont2, NULL); 77 &test3_cont2,
78 NULL);
75} 79}
76 80
77 81
@@ -81,9 +85,15 @@ test3_cont (void *cls, int success)
81static void 85static void
82test3 () 86test3 ()
83{ 87{
84 GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val3, strlen (val3) + 1, 88 GNUNET_PEERSTORE_store (h,
89 subsystem,
90 &pid,
91 key,
92 val3,
93 strlen (val3) + 1,
85 GNUNET_TIME_UNIT_FOREVER_ABS, 94 GNUNET_TIME_UNIT_FOREVER_ABS,
86 GNUNET_PEERSTORE_STOREOPTION_REPLACE, &test3_cont, 95 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
96 &test3_cont,
87 NULL); 97 NULL);
88} 98}
89 99
@@ -130,9 +140,15 @@ test2_cont (void *cls, int success)
130void 140void
131test2 () 141test2 ()
132{ 142{
133 GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val2, strlen (val2) + 1, 143 GNUNET_PEERSTORE_store (h,
144 subsystem,
145 &pid,
146 key,
147 val2,
148 strlen (val2) + 1,
134 GNUNET_TIME_UNIT_FOREVER_ABS, 149 GNUNET_TIME_UNIT_FOREVER_ABS,
135 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, &test2_cont, 150 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
151 &test2_cont,
136 NULL); 152 NULL);
137} 153}
138 154
@@ -163,8 +179,13 @@ test1_cont (void *cls, int success)
163 if (GNUNET_YES != success) 179 if (GNUNET_YES != success)
164 return; 180 return;
165 count = 0; 181 count = 0;
166 GNUNET_PEERSTORE_iterate (h, subsystem, &pid, key, GNUNET_TIME_UNIT_SECONDS, 182 GNUNET_PEERSTORE_iterate (h,
167 &test1_cont2, NULL); 183 subsystem,
184 &pid,
185 key,
186 GNUNET_TIME_UNIT_SECONDS,
187 &test1_cont2,
188 NULL);
168} 189}
169 190
170 191
@@ -174,9 +195,15 @@ test1_cont (void *cls, int success)
174static void 195static void
175test1 () 196test1 ()
176{ 197{
177 GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val1, strlen (val1) + 1, 198 GNUNET_PEERSTORE_store (h,
199 subsystem,
200 &pid,
201 key,
202 val1,
203 strlen (val1) + 1,
178 GNUNET_TIME_UNIT_FOREVER_ABS, 204 GNUNET_TIME_UNIT_FOREVER_ABS,
179 GNUNET_PEERSTORE_STOREOPTION_REPLACE, &test1_cont, 205 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
206 &test1_cont,
180 NULL); 207 NULL);
181} 208}
182 209
@@ -196,8 +223,10 @@ int
196main (int argc, char *argv[]) 223main (int argc, char *argv[])
197{ 224{
198 if (0 != 225 if (0 !=
199 GNUNET_TESTING_service_run ("test-gnunet-peerstore", "peerstore", 226 GNUNET_TESTING_service_run ("test-gnunet-peerstore",
200 "test_peerstore_api_data.conf", &run, NULL)) 227 "peerstore",
228 "test_peerstore_api_data.conf",
229 &run, NULL))
201 return 1; 230 return 1;
202 return ok; 231 return ok;
203} 232}
diff --git a/src/peerstore/test_plugin_peerstore.c b/src/peerstore/test_plugin_peerstore.c
index 179e32b52..62c06be8e 100644
--- a/src/peerstore/test_plugin_peerstore.c
+++ b/src/peerstore/test_plugin_peerstore.c
@@ -36,6 +36,11 @@ static int ok;
36static const char *plugin_name; 36static const char *plugin_name;
37 37
38 38
39static struct GNUNET_PEERSTORE_PluginFunctions *psp;
40
41static struct GNUNET_PeerIdentity p1;
42
43
39/** 44/**
40 * Function called when the service shuts down. Unloads our namestore 45 * Function called when the service shuts down. Unloads our namestore
41 * plugin. 46 * plugin.
@@ -47,8 +52,12 @@ unload_plugin (struct GNUNET_PEERSTORE_PluginFunctions *api)
47{ 52{
48 char *libname; 53 char *libname;
49 54
50 GNUNET_asprintf (&libname, "libgnunet_plugin_peer_%s", plugin_name); 55 GNUNET_asprintf (&libname,
51 GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api)); 56 "libgnunet_plugin_peer_%s",
57 plugin_name);
58 GNUNET_break (NULL ==
59 GNUNET_PLUGIN_unload (libname,
60 api));
52 GNUNET_free (libname); 61 GNUNET_free (libname);
53} 62}
54 63
@@ -65,12 +74,18 @@ load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg)
65 struct GNUNET_PEERSTORE_PluginFunctions *ret; 74 struct GNUNET_PEERSTORE_PluginFunctions *ret;
66 char *libname; 75 char *libname;
67 76
68 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' peer plugin\n"), 77 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
78 _("Loading `%s' peer plugin\n"),
69 plugin_name); 79 plugin_name);
70 GNUNET_asprintf (&libname, "libgnunet_plugin_peerstore_%s", plugin_name); 80 GNUNET_asprintf (&libname,
71 if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg))) 81 "libgnunet_plugin_peerstore_%s",
82 plugin_name);
83 if (NULL == (ret = GNUNET_PLUGIN_load (libname,
84 (void*) cfg)))
72 { 85 {
73 FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name); 86 FPRINTF (stderr,
87 "Failed to load plugin `%s'!\n",
88 plugin_name);
74 GNUNET_free (libname); 89 GNUNET_free (libname);
75 return NULL; 90 return NULL;
76 } 91 }
@@ -81,19 +96,28 @@ load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg)
81 96
82static void 97static void
83test_record (void *cls, 98test_record (void *cls,
84 const struct GNUNET_PEERSTORE_Record *record, 99 const struct GNUNET_PEERSTORE_Record *record,
85 const char *error) 100 const char *error)
86{ 101{
87 struct GNUNET_PeerIdentity *id = cls; 102 const struct GNUNET_PeerIdentity *id = cls;
88 char* testval = "test_val"; 103 const char* testval = "test_val";
89 104
90 if (NULL == record) 105 if (NULL == record)
106 {
107 unload_plugin (psp);
91 return; 108 return;
92 109 }
93 GNUNET_assert (0 == memcmp (record->peer, id, sizeof (struct GNUNET_PeerIdentity))); 110 GNUNET_assert (0 == memcmp (&record->peer,
94 GNUNET_assert (0 == strcmp ("subsys", record->sub_system)); 111 id,
95 GNUNET_assert (0 == strcmp ("key", record->key)); 112 sizeof (struct GNUNET_PeerIdentity)));
96 GNUNET_assert (0 == memcmp (testval, record->value, strlen (testval))); 113 GNUNET_assert (0 == strcmp ("subsys",
114 record->sub_system));
115 GNUNET_assert (0 == strcmp ("key",
116 record->key));
117 GNUNET_assert (0 == memcmp (testval,
118 record->value,
119 strlen (testval)));
120 ok = 0;
97} 121}
98 122
99 123
@@ -101,38 +125,52 @@ static void
101get_record (struct GNUNET_PEERSTORE_PluginFunctions *psp, 125get_record (struct GNUNET_PEERSTORE_PluginFunctions *psp,
102 const struct GNUNET_PeerIdentity *identity) 126 const struct GNUNET_PeerIdentity *identity)
103{ 127{
104 GNUNET_assert (GNUNET_OK == psp->iterate_records (psp->cls, 128 GNUNET_assert (GNUNET_OK ==
105 "subsys", identity, "key", &test_record, (void*)identity)); 129 psp->iterate_records (psp->cls,
130 "subsys",
131 identity,
132 "key",
133 &test_record,
134 (void*)identity));
106} 135}
107 136
137
108static void 138static void
109store_cont (void *cls, int status) 139store_cont (void *cls,
140 int status)
110{ 141{
111 GNUNET_assert (GNUNET_OK == status); 142 GNUNET_assert (GNUNET_OK == status);
143 get_record (psp,
144 &p1);
112} 145}
113 146
147
114static void 148static void
115put_record (struct GNUNET_PEERSTORE_PluginFunctions *psp, struct GNUNET_PeerIdentity *identity) 149put_record (struct GNUNET_PEERSTORE_PluginFunctions *psp,
150 const struct GNUNET_PeerIdentity *identity)
116{ 151{
117 GNUNET_assert (GNUNET_OK == psp->store_record (psp->cls, 152 GNUNET_assert (GNUNET_OK ==
118 "subsys", 153 psp->store_record (psp->cls,
119 identity, 154 "subsys",
120 "key", "test_value", strlen ("test_value"), 155 identity,
121 GNUNET_TIME_absolute_get (), 156 "key",
122 GNUNET_PEERSTORE_STOREOPTION_REPLACE, 157 "test_value",
123 &store_cont, 158 strlen ("test_value"),
124 identity)); 159 GNUNET_TIME_absolute_get (),
160 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
161 &store_cont,
162 NULL));
125} 163}
126 164
127 165
128static void 166static void
129run (void *cls, char *const *args, const char *cfgfile, 167run (void *cls,
168 char *const *args,
169 const char *cfgfile,
130 const struct GNUNET_CONFIGURATION_Handle *cfg) 170 const struct GNUNET_CONFIGURATION_Handle *cfg)
131{ 171{
132 struct GNUNET_PEERSTORE_PluginFunctions *psp;
133 struct GNUNET_PeerIdentity p1;
134 172
135 ok = 0; 173 ok = 1;
136 psp = load_plugin (cfg); 174 psp = load_plugin (cfg);
137 if (NULL == psp) 175 if (NULL == psp)
138 { 176 {
@@ -142,10 +180,8 @@ run (void *cls, char *const *args, const char *cfgfile,
142 return; 180 return;
143 } 181 }
144 memset (&p1, 1, sizeof (p1)); 182 memset (&p1, 1, sizeof (p1));
145 put_record (psp, &p1); 183 put_record (psp,
146 get_record (psp, &p1); 184 &p1);
147
148 unload_plugin (psp);
149} 185}
150 186
151 187
@@ -163,19 +199,26 @@ main (int argc, char *argv[])
163 GNUNET_GETOPT_OPTION_END 199 GNUNET_GETOPT_OPTION_END
164 }; 200 };
165 201
166 //GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite");
167 GNUNET_log_setup ("test-plugin-peerstore", 202 GNUNET_log_setup ("test-plugin-peerstore",
168 "WARNING", 203 "WARNING",
169 NULL); 204 NULL);
170 plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); 205 plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
171 GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_peerstore_%s.conf", 206 GNUNET_snprintf (cfg_name,
207 sizeof (cfg_name),
208 "test_plugin_peerstore_%s.conf",
172 plugin_name); 209 plugin_name);
173 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, 210 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1,
174 "test-plugin-peerstore", "nohelp", options, &run, NULL); 211 xargv,
212 "test-plugin-peerstore",
213 "nohelp",
214 options,
215 &run,
216 NULL);
175 if (ok != 0) 217 if (ok != 0)
176 FPRINTF (stderr, "Missed some testcases: %d\n", ok); 218 FPRINTF (stderr,
177 //GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite"); 219 "Missed some testcases: %d\n",
220 ok);
178 return ok; 221 return ok;
179} 222}
180 223
181/* end of test_plugin_namestore.c */ 224/* end of test_plugin_peerstore.c */