From 8d71f909cb22fbf6774e4042309a8eb133af3bfc Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 14 Mar 2017 00:31:02 +0100 Subject: [PATCH] convert sqlite peerstore to using libgnunetsq --- src/datastore/plugin_datastore_sqlite.c | 12 +- src/include/gnunet_peerstore_service.h | 4 +- src/peerstore/gnunet-service-peerstore.c | 28 +- src/peerstore/peerstore.h | 2 +- src/peerstore/peerstore_api.c | 27 +- src/peerstore/peerstore_common.c | 20 +- src/peerstore/peerstore_common.h | 2 +- src/peerstore/plugin_peerstore_sqlite.c | 357 +++++++++++---------- src/peerstore/test_peerstore_api_iterate.c | 73 ++++- src/peerstore/test_peerstore_api_store.c | 55 +++- src/peerstore/test_plugin_peerstore.c | 127 +++++--- 11 files changed, 434 insertions(+), 273 deletions(-) diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c index 491f73ed5..9ca8f056a 100644 --- a/src/datastore/plugin_datastore_sqlite.c +++ b/src/datastore/plugin_datastore_sqlite.c @@ -361,11 +361,15 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, sqlite3_step (stmt)) && (SQLITE_OK != sqlite3_exec (plugin->dbh, - "CREATE TABLE gn090 (" " repl INT4 NOT NULL DEFAULT 0," - " type INT4 NOT NULL DEFAULT 0," " prio INT4 NOT NULL DEFAULT 0," + "CREATE TABLE gn090 (" + " repl INT4 NOT NULL DEFAULT 0," + " type INT4 NOT NULL DEFAULT 0," + " prio INT4 NOT NULL DEFAULT 0," " anonLevel INT4 NOT NULL DEFAULT 0," - " expire INT8 NOT NULL DEFAULT 0," " rvalue INT8 NOT NULL," - " hash TEXT NOT NULL DEFAULT ''," " vhash TEXT NOT NULL DEFAULT ''," + " expire INT8 NOT NULL DEFAULT 0," + " rvalue INT8 NOT NULL," + " hash TEXT NOT NULL DEFAULT ''," + " vhash TEXT NOT NULL DEFAULT ''," " value BLOB NOT NULL DEFAULT '')", NULL, NULL, diff --git a/src/include/gnunet_peerstore_service.h b/src/include/gnunet_peerstore_service.h index 3cafe70b8..c636447c2 100644 --- a/src/include/gnunet_peerstore_service.h +++ b/src/include/gnunet_peerstore_service.h @@ -86,7 +86,7 @@ struct GNUNET_PEERSTORE_Record /** * Peer Identity */ - struct GNUNET_PeerIdentity *peer; + struct GNUNET_PeerIdentity peer; /** * Record key string @@ -106,7 +106,7 @@ struct GNUNET_PEERSTORE_Record /** * Expiry time of entry */ - struct GNUNET_TIME_Absolute *expiry; + struct GNUNET_TIME_Absolute expiry; /** * Client from which this record originated. 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, GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cls_record->client), env); if (NULL == emsg) + { GNUNET_SERVICE_client_continue (cls_record->client); + } else + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to iterate: %s\n", + emsg); GNUNET_SERVICE_client_drop (cls_record->client); + } PEERSTORE_destroy_record (cls_record); return; } env = PEERSTORE_create_record_mq_envelope (record->sub_system, - record->peer, + &record->peer, record->key, record->value, record->value_size, @@ -301,7 +309,7 @@ watch_notifier_it (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found a watcher to update.\n"); env = PEERSTORE_create_record_mq_envelope (record->sub_system, - record->peer, + &record->peer, record->key, record->value, record->value_size, @@ -325,7 +333,7 @@ watch_notifier (struct GNUNET_PEERSTORE_Record *record) struct GNUNET_HashCode keyhash; PEERSTORE_hash_key (record->sub_system, - record->peer, + &record->peer, record->key, &keyhash); GNUNET_CONTAINER_multihashmap_get_multiple (watchers, @@ -434,17 +442,18 @@ handle_iterate (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iterate request: ss `%s', peer `%s', key `%s'\n", record->sub_system, - (NULL == record->peer) ? "NULL" : GNUNET_i2s (record->peer), + GNUNET_i2s (&record->peer), (NULL == record->key) ? "NULL" : record->key); record->client = client; if (GNUNET_OK != db->iterate_records (db->cls, record->sub_system, - record->peer, + (ntohs (srm->peer_set)) ? &record->peer : NULL, record->key, &record_iterator, record)) { + GNUNET_break (0); GNUNET_SERVICE_client_drop (client); PEERSTORE_destroy_record (record); } @@ -470,6 +479,7 @@ store_record_continuation (void *cls, } else { + GNUNET_break (0); GNUNET_SERVICE_client_drop (record->client); } PEERSTORE_destroy_record (record); @@ -496,7 +506,6 @@ check_store (void *cls, return GNUNET_SYSERR; } if ( (NULL == record->sub_system) || - (NULL == record->peer) || (NULL == record->key) ) { GNUNET_break (0); @@ -525,22 +534,23 @@ handle_store (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %u.\n", record->sub_system, - GNUNET_i2s (record->peer), + GNUNET_i2s (&record->peer), record->key, (uint32_t) ntohl (srm->options)); record->client = client; if (GNUNET_OK != db->store_record (db->cls, record->sub_system, - record->peer, + &record->peer, record->key, record->value, record->value_size, - *record->expiry, + record->expiry, ntohl (srm->options), &store_record_continuation, record)) { + GNUNET_break (0); PEERSTORE_destroy_record (record); GNUNET_SERVICE_client_drop (client); 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 /** * Expiry time of entry */ - struct GNUNET_TIME_Absolute expiry GNUNET_PACKED; + struct GNUNET_TIME_AbsoluteNBO expiry; /** * 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) /******************* CONNECTION FUNCTIONS *********************/ /******************************************************************************/ + +/** + * Function called when we had trouble talking to the service. + */ static void handle_client_error (void *cls, enum GNUNET_MQ_Error error) @@ -293,7 +297,7 @@ handle_client_error (void *cls, struct GNUNET_PEERSTORE_Handle *h = cls; LOG (GNUNET_ERROR_TYPE_ERROR, - _("Received an error notification from MQ of type: %d\n"), + "Received an error notification from MQ of type: %d\n", error); reconnect (h); } @@ -341,7 +345,9 @@ iterate_timeout (void *cls) callback_cls = ic->callback_cls; GNUNET_PEERSTORE_iterate_cancel (ic); if (NULL != callback) - callback (callback_cls, NULL, _("timeout")); + callback (callback_cls, + NULL, + _("timeout")); } @@ -510,7 +516,7 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h, "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n", size, sub_system, GNUNET_i2s (peer), key); ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, value, size, - &expiry, options, + expiry, options, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); sc = GNUNET_new (struct GNUNET_PEERSTORE_StoreContext); @@ -684,8 +690,12 @@ GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h, struct GNUNET_MQ_Envelope *ev; struct GNUNET_PEERSTORE_IterateContext *ic; - ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, NULL, 0, + ev = PEERSTORE_create_record_mq_envelope (sub_system, + peer, + key, NULL, 0, + GNUNET_TIME_UNIT_FOREVER_ABS, + 0, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); ic = GNUNET_new (struct GNUNET_PEERSTORE_IterateContext); @@ -756,7 +766,7 @@ handle_watch_record (void *cls, return; } PEERSTORE_hash_key (record->sub_system, - record->peer, + &record->peer, record->key, &keyhash); // FIXME: what if there are multiple watches for the same key? @@ -848,9 +858,12 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h) &ic->peer, ic->key, NULL, 0, - NULL, 0, + GNUNET_TIME_UNIT_FOREVER_ABS, + 0, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); GNUNET_MQ_send (h->mq, ev); + if (NULL != ic->timeout_task) + GNUNET_SCHEDULER_cancel (ic->timeout_task); ic->timeout_task = GNUNET_SCHEDULER_add_delayed (ic->timeout, &iterate_timeout, @@ -863,7 +876,7 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h) sc->key, sc->value, sc->size, - &sc->expiry, + sc->expiry, sc->options, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); 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, const char *key, const void *value, size_t value_size, - struct GNUNET_TIME_Absolute *expiry, + struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, uint16_t msg_type) { @@ -97,8 +97,7 @@ PEERSTORE_create_record_mq_envelope (const char *sub_system, msg_size = ss_size + key_size + value_size; ev = GNUNET_MQ_msg_extra (srm, msg_size, msg_type); srm->key_size = htons (key_size); - if (NULL != expiry) - srm->expiry = *expiry; + srm->expiry = GNUNET_TIME_absolute_hton (expiry); if (NULL == peer) srm->peer_set = htons (GNUNET_NO); else @@ -147,12 +146,9 @@ PEERSTORE_parse_record_message (const struct StoreRecordMessage *srm) record = GNUNET_new (struct GNUNET_PEERSTORE_Record); if (GNUNET_YES == ntohs (srm->peer_set)) { - record->peer = GNUNET_new (struct GNUNET_PeerIdentity); - *record->peer = srm->peer; + record->peer = srm->peer; } - record->expiry = GNUNET_new (struct GNUNET_TIME_Absolute); - - *(record->expiry) = srm->expiry; + record->expiry = GNUNET_TIME_absolute_ntoh (srm->expiry); dummy = (char *) &srm[1]; if (ss_size > 0) { @@ -167,7 +163,9 @@ PEERSTORE_parse_record_message (const struct StoreRecordMessage *srm) if (value_size > 0) { record->value = GNUNET_malloc (value_size); - GNUNET_memcpy (record->value, dummy, value_size); + GNUNET_memcpy (record->value, + dummy, + value_size); } record->value_size = value_size; return record; @@ -184,8 +182,6 @@ PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record) { if (NULL != record->sub_system) GNUNET_free (record->sub_system); - if (NULL != record->peer) - GNUNET_free (record->peer); if (NULL != record->key) GNUNET_free (record->key); if (NULL != record->value) @@ -193,7 +189,5 @@ PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record) GNUNET_free (record->value); record->value = 0; } - if (NULL != record->expiry) - GNUNET_free (record->expiry); GNUNET_free (record); } 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, const char *key, const void *value, size_t value_size, - struct GNUNET_TIME_Absolute *expiry, + struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, uint16_t msg_type); diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c index 236be129e..440263d44 100644 --- a/src/peerstore/plugin_peerstore_sqlite.c +++ b/src/peerstore/plugin_peerstore_sqlite.c @@ -1,6 +1,6 @@ /* * This file is part of GNUnet - * Copyright (C) 2013 GNUnet e.V. + * Copyright (C) 2013, 2017 GNUnet e.V. * * GNUnet is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published @@ -22,11 +22,13 @@ * @file peerstore/plugin_peerstore_sqlite.c * @brief sqlite-based peerstore backend * @author Omar Tarabai + * @author Christian Grothoff */ #include "platform.h" #include "gnunet_peerstore_plugin.h" #include "gnunet_peerstore_service.h" +#include "gnunet_sq_lib.h" #include "peerstore.h" #include @@ -111,6 +113,7 @@ struct Plugin }; + /** * Delete records with the given key * @@ -118,40 +121,50 @@ struct Plugin * @param sub_system name of sub system * @param peer Peer identity (can be NULL) * @param key entry key string (can be NULL) - * @return number of deleted records + * @return number of deleted records, #GNUNE_SYSERR on error */ static int -peerstore_sqlite_delete_records (void *cls, const char *sub_system, +peerstore_sqlite_delete_records (void *cls, + const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key) { struct Plugin *plugin = cls; sqlite3_stmt *stmt = plugin->delete_peerstoredata; + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_string (sub_system), + GNUNET_SQ_query_param_auto_from_type (peer), + GNUNET_SQ_query_param_string (key), + GNUNET_SQ_query_param_end + }; + int ret; - if ((SQLITE_OK != - sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, - SQLITE_STATIC)) || - (SQLITE_OK != - sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity), - SQLITE_STATIC)) || - (SQLITE_OK != - sqlite3_bind_text (stmt, 3, key, strlen (key) + 1, SQLITE_STATIC))) + if (GNUNET_OK != + GNUNET_SQ_bind (stmt, + params)) { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind"); + GNUNET_SQ_reset (plugin->dbh, + stmt); + return GNUNET_SYSERR; } - else if (SQLITE_DONE != sqlite3_step (stmt)) + if (SQLITE_DONE != + sqlite3_step (stmt)) { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_step"); + ret = GNUNET_SYSERR; } - if (SQLITE_OK != sqlite3_reset (stmt)) + else { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "sqlite3_reset"); - return 0; + ret = sqlite3_changes (plugin->dbh); } - return sqlite3_changes (plugin->dbh); + GNUNET_SQ_reset (plugin->dbh, + stmt); + return ret; } @@ -172,28 +185,36 @@ peerstore_sqlite_expire_records (void *cls, struct GNUNET_TIME_Absolute now, { struct Plugin *plugin = cls; sqlite3_stmt *stmt = plugin->expire_peerstoredata; + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_absolute_time (&now), + GNUNET_SQ_query_param_end + }; - if (SQLITE_OK != - sqlite3_bind_int64 (stmt, 1, (sqlite3_uint64) now.abs_value_us)) + if (GNUNET_OK != + GNUNET_SQ_bind (stmt, + params)) { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind"); + GNUNET_SQ_reset (plugin->dbh, + stmt); + return GNUNET_SYSERR; } - else if (SQLITE_DONE != sqlite3_step (stmt)) + if (SQLITE_DONE != sqlite3_step (stmt)) { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_step"); - } - if (SQLITE_OK != sqlite3_reset (stmt)) - { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "sqlite3_reset"); + GNUNET_SQ_reset (plugin->dbh, + stmt); return GNUNET_SYSERR; } if (NULL != cont) - { - cont (cont_cls, sqlite3_changes (plugin->dbh)); - } + cont (cont_cls, + sqlite3_changes (plugin->dbh)); + GNUNET_SQ_reset (plugin->dbh, + stmt); return GNUNET_OK; } @@ -224,94 +245,115 @@ peerstore_sqlite_iterate_records (void *cls, sqlite3_stmt *stmt; int err = 0; int sret; - struct GNUNET_PEERSTORE_Record *ret; + struct GNUNET_PEERSTORE_Record rec; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Executing iterate request on sqlite db.\n"); - if (NULL == peer && NULL == key) - { - stmt = plugin->select_peerstoredata; - err = - (SQLITE_OK != - sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, - SQLITE_STATIC)); - } - else if (NULL == key) - { - stmt = plugin->select_peerstoredata_by_pid; - err = - (SQLITE_OK != - sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, - SQLITE_STATIC)) || - (SQLITE_OK != - sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity), - SQLITE_STATIC)); - } - else if (NULL == peer) + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Executing iterate request on sqlite db.\n"); + if (NULL == peer) { - stmt = plugin->select_peerstoredata_by_key; - err = - (SQLITE_OK != - sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, - SQLITE_STATIC)) || - (SQLITE_OK != - sqlite3_bind_text (stmt, 2, key, strlen (key) + 1, SQLITE_STATIC)); + if (NULL == key) + { + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_string (sub_system), + GNUNET_SQ_query_param_end + }; + + stmt = plugin->select_peerstoredata; + err = GNUNET_SQ_bind (stmt, + params); + } + else + { + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_string (sub_system), + GNUNET_SQ_query_param_string (key), + GNUNET_SQ_query_param_end + }; + + stmt = plugin->select_peerstoredata_by_key; + err = GNUNET_SQ_bind (stmt, + params); + } } else { - stmt = plugin->select_peerstoredata_by_all; - err = - (SQLITE_OK != - sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, - SQLITE_STATIC)) || - (SQLITE_OK != - sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity), - SQLITE_STATIC)) || - (SQLITE_OK != - sqlite3_bind_text (stmt, 3, key, strlen (key) + 1, SQLITE_STATIC)); + if (NULL == key) + { + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_string (sub_system), + GNUNET_SQ_query_param_auto_from_type (peer), + GNUNET_SQ_query_param_end + }; + + stmt = plugin->select_peerstoredata_by_pid; + err = GNUNET_SQ_bind (stmt, + params); + } + else + { + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_string (sub_system), + GNUNET_SQ_query_param_auto_from_type (peer), + GNUNET_SQ_query_param_string (key), + GNUNET_SQ_query_param_end + }; + + stmt = plugin->select_peerstoredata_by_all; + err = GNUNET_SQ_bind (stmt, + params); + } } - if (err) + if (GNUNET_OK != err) { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind_XXXX"); - if (SQLITE_OK != sqlite3_reset (stmt)) - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "sqlite3_reset"); + GNUNET_SQ_reset (plugin->dbh, + stmt); return GNUNET_SYSERR; } + + err = 0; while (SQLITE_ROW == (sret = sqlite3_step (stmt))) { - LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning a matched record.\n"); - ret = GNUNET_new (struct GNUNET_PEERSTORE_Record); - - ret->sub_system = (char *) sqlite3_column_text (stmt, 0); - ret->peer = (struct GNUNET_PeerIdentity *) sqlite3_column_blob (stmt, 1); - ret->key = (char *) sqlite3_column_text (stmt, 2); - ret->value = (void *) sqlite3_column_blob (stmt, 3); - ret->value_size = sqlite3_column_bytes (stmt, 3); - ret->expiry = GNUNET_new (struct GNUNET_TIME_Absolute); - - ret->expiry->abs_value_us = (uint64_t) sqlite3_column_int64 (stmt, 4); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Returning a matched record.\n"); + struct GNUNET_SQ_ResultSpec rs[] = { + GNUNET_SQ_result_spec_string (&rec.sub_system), + GNUNET_SQ_result_spec_auto_from_type (&rec.peer), + GNUNET_SQ_result_spec_string (&rec.key), + GNUNET_SQ_result_spec_variable_size (&rec.value, &rec.value_size), + GNUNET_SQ_result_spec_absolute_time (&rec.expiry), + GNUNET_SQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_SQ_extract_result (stmt, + rs)) + { + GNUNET_break (0); + break; + } if (NULL != iter) - iter (iter_cls, ret, NULL); - GNUNET_free (ret->expiry); - GNUNET_free (ret); + iter (iter_cls, + &rec, + NULL); + GNUNET_SQ_cleanup_result (rs); } if (SQLITE_DONE != sret) { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); - err = 1; - } - if (SQLITE_OK != sqlite3_reset (stmt)) - { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "sqlite3_reset"); + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR, + "sqlite_step"); err = 1; } + GNUNET_SQ_reset (plugin->dbh, + stmt); if (NULL != iter) - { - iter (iter_cls, NULL, err ? "sqlite error" : NULL); - } + iter (iter_cls, + NULL, + err ? "sqlite error" : NULL); return GNUNET_OK; } @@ -347,6 +389,14 @@ peerstore_sqlite_store_record (void *cls, { struct Plugin *plugin = cls; sqlite3_stmt *stmt = plugin->insert_peerstoredata; + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_string (sub_system), + GNUNET_SQ_query_param_auto_from_type (peer), + GNUNET_SQ_query_param_string (key), + GNUNET_SQ_query_param_fixed_size (value, size), + GNUNET_SQ_query_param_absolute_time (&expiry), + GNUNET_SQ_query_param_end + }; if (GNUNET_PEERSTORE_STOREOPTION_REPLACE == options) { @@ -355,34 +405,23 @@ peerstore_sqlite_store_record (void *cls, peer, key); } - if (SQLITE_OK != - sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, - SQLITE_STATIC) || - SQLITE_OK != sqlite3_bind_blob (stmt, 2, peer, - sizeof (struct GNUNET_PeerIdentity), - SQLITE_STATIC) || - SQLITE_OK != sqlite3_bind_text (stmt, 3, key, strlen (key) + 1, - SQLITE_STATIC) || - SQLITE_OK != sqlite3_bind_blob (stmt, 4, value, size, SQLITE_STATIC) || - SQLITE_OK != sqlite3_bind_int64 (stmt, 5, - (sqlite3_uint64) expiry.abs_value_us)) - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + if (GNUNET_OK != + GNUNET_SQ_bind (stmt, + params)) + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind"); else if (SQLITE_DONE != sqlite3_step (stmt)) { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_step"); } - if (SQLITE_OK != sqlite3_reset (stmt)) - { - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "sqlite3_reset"); - return GNUNET_SYSERR; - } + GNUNET_SQ_reset (plugin->dbh, + stmt); if (NULL != cont) - { - cont (cont_cls, GNUNET_OK); - } + cont (cont_cls, + GNUNET_OK); return GNUNET_OK; } @@ -453,24 +492,6 @@ sql_prepare (sqlite3 *dbh, } -/** - * sqlite3 custom function for comparison of uint64_t values - * since it is not supported by default - */ -static void -sqlite3_lessthan (sqlite3_context *ctx, - int dummy, - sqlite3_value **values) -{ - uint64_t v1; - uint64_t v2; - - v1 = (uint64_t) sqlite3_value_int64 (values[0]); - v2 = (uint64_t) sqlite3_value_int64 (values[1]); - sqlite3_result_int (ctx, v1 < v2); -} - - /** * Initialize the database connections and associated * data structures (create tables and indices @@ -532,17 +553,11 @@ database_setup (struct Plugin *plugin) /* Create tables */ sql_exec (plugin->dbh, "CREATE TABLE IF NOT EXISTS peerstoredata (\n" - " sub_system TEXT NOT NULL,\n" " peer_id BLOB NOT NULL,\n" - " key TEXT NOT NULL,\n" " value BLOB NULL,\n" - " expiry sqlite3_uint64 NOT NULL" ");"); - sqlite3_create_function (plugin->dbh, - "UINT64_LT", - 2, - SQLITE_UTF8, - NULL, - &sqlite3_lessthan, - NULL, - NULL); + " sub_system TEXT NOT NULL,\n" + " peer_id BLOB NOT NULL,\n" + " key TEXT NOT NULL,\n" + " value BLOB NULL,\n" + " expiry INT8 NOT NULL" ");"); /* Create Indices */ if (SQLITE_OK != sqlite3_exec (plugin->dbh, @@ -559,26 +574,35 @@ database_setup (struct Plugin *plugin) /* Prepare statements */ sql_prepare (plugin->dbh, - "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry) VALUES (?,?,?,?,?);", + "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry)" + " VALUES (?,?,?,?,?);", &plugin->insert_peerstoredata); sql_prepare (plugin->dbh, - "SELECT * FROM peerstoredata" " WHERE sub_system = ?", + "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" + " WHERE sub_system = ?", &plugin->select_peerstoredata); sql_prepare (plugin->dbh, - "SELECT * FROM peerstoredata" " WHERE sub_system = ?" - " AND peer_id = ?", &plugin->select_peerstoredata_by_pid); + "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" + " WHERE sub_system = ?" + " AND peer_id = ?", + &plugin->select_peerstoredata_by_pid); sql_prepare (plugin->dbh, - "SELECT * FROM peerstoredata" " WHERE sub_system = ?" - " AND key = ?", &plugin->select_peerstoredata_by_key); + "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" + " WHERE sub_system = ?" + " AND key = ?", + &plugin->select_peerstoredata_by_key); sql_prepare (plugin->dbh, - "SELECT * FROM peerstoredata" " WHERE sub_system = ?" + "SELECT sub_system,peer_id,key,value,expiry FROM peerstoredata" + " WHERE sub_system = ?" " AND peer_id = ?" " AND key = ?", &plugin->select_peerstoredata_by_all); sql_prepare (plugin->dbh, - "DELETE FROM peerstoredata" " WHERE UINT64_LT(expiry, ?)", + "DELETE FROM peerstoredata" + " WHERE expiry < ?", &plugin->expire_peerstoredata); sql_prepare (plugin->dbh, - "DELETE FROM peerstoredata" " WHERE sub_system = ?" + "DELETE FROM peerstoredata" + " WHERE sub_system = ?" " AND peer_id = ?" " AND key = ?", &plugin->delete_peerstoredata); return GNUNET_OK; @@ -596,15 +620,20 @@ database_shutdown (struct Plugin *plugin) int result; sqlite3_stmt *stmt; - while (NULL != (stmt = sqlite3_next_stmt (plugin->dbh, NULL))) + while (NULL != (stmt = sqlite3_next_stmt (plugin->dbh, + NULL))) { result = sqlite3_finalize (stmt); if (SQLITE_OK != result) - LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to close statement %p: %d\n", - stmt, result); + LOG (GNUNET_ERROR_TYPE_WARNING, + "Failed to close statement %p: %d\n", + stmt, + result); } if (SQLITE_OK != sqlite3_close (plugin->dbh)) - LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close"); + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR, + "sqlite3_close"); GNUNET_free_non_null (plugin->fn); } 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 @@ /* This file is part of GNUnet. - Copyright (C) + Copyright (C) 2013-2017 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -42,7 +42,8 @@ static int count = 0; static void -iter3_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, +iter3_cb (void *cls, + const struct GNUNET_PEERSTORE_Record *record, const char *emsg) { if (NULL != emsg) @@ -63,7 +64,8 @@ iter3_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, static void -iter2_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, +iter2_cb (void *cls, + const struct GNUNET_PEERSTORE_Record *record, const char *emsg) { if (NULL != emsg) @@ -78,13 +80,19 @@ iter2_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, } GNUNET_assert (count == 2); count = 0; - ic = GNUNET_PEERSTORE_iterate (h, ss, NULL, NULL, GNUNET_TIME_UNIT_FOREVER_REL, - iter3_cb, NULL); + ic = GNUNET_PEERSTORE_iterate (h, + ss, + NULL, + NULL, + GNUNET_TIME_UNIT_FOREVER_REL, + &iter3_cb, + NULL); } static void -iter1_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, +iter1_cb (void *cls, + const struct GNUNET_PEERSTORE_Record *record, const char *emsg) { if (NULL != emsg) @@ -99,30 +107,61 @@ iter1_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, } GNUNET_assert (count == 1); count = 0; - ic = GNUNET_PEERSTORE_iterate (h, ss, &p1, NULL, GNUNET_TIME_UNIT_FOREVER_REL, - iter2_cb, NULL); + ic = GNUNET_PEERSTORE_iterate (h, + ss, + &p1, + NULL, + GNUNET_TIME_UNIT_FOREVER_REL, + iter2_cb, + NULL); } static void -run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { h = GNUNET_PEERSTORE_connect (cfg); GNUNET_assert (NULL != h); memset (&p1, 1, sizeof (p1)); memset (&p2, 2, sizeof (p2)); - GNUNET_PEERSTORE_store (h, ss, &p1, k1, val, strlen (val) + 1, + GNUNET_PEERSTORE_store (h, + ss, + &p1, + k1, + val, + strlen (val) + 1, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); - GNUNET_PEERSTORE_store (h, ss, &p1, k2, val, strlen (val) + 1, + GNUNET_PEERSTORE_STOREOPTION_REPLACE, + NULL, + NULL); + GNUNET_PEERSTORE_store (h, + ss, + &p1, + k2, + val, + strlen (val) + 1, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); - GNUNET_PEERSTORE_store (h, ss, &p2, k3, val, strlen (val) + 1, + GNUNET_PEERSTORE_STOREOPTION_REPLACE, + NULL, + NULL); + GNUNET_PEERSTORE_store (h, + ss, + &p2, + k3, + val, + strlen (val) + 1, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); - ic = GNUNET_PEERSTORE_iterate (h, ss, &p1, k1, GNUNET_TIME_UNIT_FOREVER_REL, - iter1_cb, NULL); + GNUNET_PEERSTORE_STOREOPTION_REPLACE, + NULL, + NULL); + ic = GNUNET_PEERSTORE_iterate (h, + ss, + &p1, + k1, + GNUNET_TIME_UNIT_FOREVER_REL, + &iter1_cb, NULL); } 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--"; static int count = 0; + static void test3_cont2 (void *cls, const struct GNUNET_PEERSTORE_Record *record, @@ -49,7 +50,8 @@ test3_cont2 (void *cls, if (NULL != record) { GNUNET_assert ((strlen (val3) + 1) == record->value_size); - GNUNET_assert (0 == strcmp ((char *) val3, (char *) record->value)); + GNUNET_assert (0 == strcmp ((char *) val3, + (char *) record->value)); count++; return; } @@ -61,7 +63,8 @@ test3_cont2 (void *cls, static void -test3_cont (void *cls, int success) +test3_cont (void *cls, + int success) { if (GNUNET_YES != success) return; @@ -71,7 +74,8 @@ test3_cont (void *cls, int success) &pid, key, GNUNET_TIME_UNIT_SECONDS, - &test3_cont2, NULL); + &test3_cont2, + NULL); } @@ -81,9 +85,15 @@ test3_cont (void *cls, int success) static void test3 () { - GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val3, strlen (val3) + 1, + GNUNET_PEERSTORE_store (h, + subsystem, + &pid, + key, + val3, + strlen (val3) + 1, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_PEERSTORE_STOREOPTION_REPLACE, &test3_cont, + GNUNET_PEERSTORE_STOREOPTION_REPLACE, + &test3_cont, NULL); } @@ -130,9 +140,15 @@ test2_cont (void *cls, int success) void test2 () { - GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val2, strlen (val2) + 1, + GNUNET_PEERSTORE_store (h, + subsystem, + &pid, + key, + val2, + strlen (val2) + 1, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, &test2_cont, + GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, + &test2_cont, NULL); } @@ -163,8 +179,13 @@ test1_cont (void *cls, int success) if (GNUNET_YES != success) return; count = 0; - GNUNET_PEERSTORE_iterate (h, subsystem, &pid, key, GNUNET_TIME_UNIT_SECONDS, - &test1_cont2, NULL); + GNUNET_PEERSTORE_iterate (h, + subsystem, + &pid, + key, + GNUNET_TIME_UNIT_SECONDS, + &test1_cont2, + NULL); } @@ -174,9 +195,15 @@ test1_cont (void *cls, int success) static void test1 () { - GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val1, strlen (val1) + 1, + GNUNET_PEERSTORE_store (h, + subsystem, + &pid, + key, + val1, + strlen (val1) + 1, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_PEERSTORE_STOREOPTION_REPLACE, &test1_cont, + GNUNET_PEERSTORE_STOREOPTION_REPLACE, + &test1_cont, NULL); } @@ -196,8 +223,10 @@ int main (int argc, char *argv[]) { if (0 != - GNUNET_TESTING_service_run ("test-gnunet-peerstore", "peerstore", - "test_peerstore_api_data.conf", &run, NULL)) + GNUNET_TESTING_service_run ("test-gnunet-peerstore", + "peerstore", + "test_peerstore_api_data.conf", + &run, NULL)) return 1; return ok; } 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; static const char *plugin_name; +static struct GNUNET_PEERSTORE_PluginFunctions *psp; + +static struct GNUNET_PeerIdentity p1; + + /** * Function called when the service shuts down. Unloads our namestore * plugin. @@ -47,8 +52,12 @@ unload_plugin (struct GNUNET_PEERSTORE_PluginFunctions *api) { char *libname; - GNUNET_asprintf (&libname, "libgnunet_plugin_peer_%s", plugin_name); - GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api)); + GNUNET_asprintf (&libname, + "libgnunet_plugin_peer_%s", + plugin_name); + GNUNET_break (NULL == + GNUNET_PLUGIN_unload (libname, + api)); GNUNET_free (libname); } @@ -65,12 +74,18 @@ load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg) struct GNUNET_PEERSTORE_PluginFunctions *ret; char *libname; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' peer plugin\n"), + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Loading `%s' peer plugin\n"), plugin_name); - GNUNET_asprintf (&libname, "libgnunet_plugin_peerstore_%s", plugin_name); - if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg))) + GNUNET_asprintf (&libname, + "libgnunet_plugin_peerstore_%s", + plugin_name); + if (NULL == (ret = GNUNET_PLUGIN_load (libname, + (void*) cfg))) { - FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name); + FPRINTF (stderr, + "Failed to load plugin `%s'!\n", + plugin_name); GNUNET_free (libname); return NULL; } @@ -81,19 +96,28 @@ load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg) static void test_record (void *cls, - const struct GNUNET_PEERSTORE_Record *record, - const char *error) + const struct GNUNET_PEERSTORE_Record *record, + const char *error) { - struct GNUNET_PeerIdentity *id = cls; - char* testval = "test_val"; + const struct GNUNET_PeerIdentity *id = cls; + const char* testval = "test_val"; if (NULL == record) + { + unload_plugin (psp); return; - - GNUNET_assert (0 == memcmp (record->peer, id, sizeof (struct GNUNET_PeerIdentity))); - GNUNET_assert (0 == strcmp ("subsys", record->sub_system)); - GNUNET_assert (0 == strcmp ("key", record->key)); - GNUNET_assert (0 == memcmp (testval, record->value, strlen (testval))); + } + GNUNET_assert (0 == memcmp (&record->peer, + id, + sizeof (struct GNUNET_PeerIdentity))); + GNUNET_assert (0 == strcmp ("subsys", + record->sub_system)); + GNUNET_assert (0 == strcmp ("key", + record->key)); + GNUNET_assert (0 == memcmp (testval, + record->value, + strlen (testval))); + ok = 0; } @@ -101,38 +125,52 @@ static void get_record (struct GNUNET_PEERSTORE_PluginFunctions *psp, const struct GNUNET_PeerIdentity *identity) { - GNUNET_assert (GNUNET_OK == psp->iterate_records (psp->cls, - "subsys", identity, "key", &test_record, (void*)identity)); + GNUNET_assert (GNUNET_OK == + psp->iterate_records (psp->cls, + "subsys", + identity, + "key", + &test_record, + (void*)identity)); } + static void -store_cont (void *cls, int status) +store_cont (void *cls, + int status) { GNUNET_assert (GNUNET_OK == status); + get_record (psp, + &p1); } + static void -put_record (struct GNUNET_PEERSTORE_PluginFunctions *psp, struct GNUNET_PeerIdentity *identity) +put_record (struct GNUNET_PEERSTORE_PluginFunctions *psp, + const struct GNUNET_PeerIdentity *identity) { - GNUNET_assert (GNUNET_OK == psp->store_record (psp->cls, - "subsys", - identity, - "key", "test_value", strlen ("test_value"), - GNUNET_TIME_absolute_get (), - GNUNET_PEERSTORE_STOREOPTION_REPLACE, - &store_cont, - identity)); + GNUNET_assert (GNUNET_OK == + psp->store_record (psp->cls, + "subsys", + identity, + "key", + "test_value", + strlen ("test_value"), + GNUNET_TIME_absolute_get (), + GNUNET_PEERSTORE_STOREOPTION_REPLACE, + &store_cont, + NULL)); } static void -run (void *cls, char *const *args, const char *cfgfile, +run (void *cls, + char *const *args, + const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_PEERSTORE_PluginFunctions *psp; - struct GNUNET_PeerIdentity p1; - ok = 0; + ok = 1; psp = load_plugin (cfg); if (NULL == psp) { @@ -142,10 +180,8 @@ run (void *cls, char *const *args, const char *cfgfile, return; } memset (&p1, 1, sizeof (p1)); - put_record (psp, &p1); - get_record (psp, &p1); - - unload_plugin (psp); + put_record (psp, + &p1); } @@ -163,19 +199,26 @@ main (int argc, char *argv[]) GNUNET_GETOPT_OPTION_END }; - //GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite"); GNUNET_log_setup ("test-plugin-peerstore", "WARNING", NULL); plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); - GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_peerstore_%s.conf", + GNUNET_snprintf (cfg_name, + sizeof (cfg_name), + "test_plugin_peerstore_%s.conf", plugin_name); - GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, - "test-plugin-peerstore", "nohelp", options, &run, NULL); + GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, + xargv, + "test-plugin-peerstore", + "nohelp", + options, + &run, + NULL); if (ok != 0) - FPRINTF (stderr, "Missed some testcases: %d\n", ok); - //GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite"); + FPRINTF (stderr, + "Missed some testcases: %d\n", + ok); return ok; } -/* end of test_plugin_namestore.c */ +/* end of test_plugin_peerstore.c */ -- 2.25.1