diff options
Diffstat (limited to 'src/datastore')
-rw-r--r-- | src/datastore/Makefile.am | 2 | ||||
-rw-r--r-- | src/datastore/Makefile.in | 6 | ||||
-rw-r--r-- | src/datastore/datastore.h | 5 | ||||
-rw-r--r-- | src/datastore/datastore_api.c | 94 | ||||
-rw-r--r-- | src/datastore/gnunet-service-datastore.c | 56 | ||||
-rw-r--r-- | src/datastore/perf_datastore_api.c | 5 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_mysql.c | 689 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_postgres.c | 305 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_sqlite.c | 27 | ||||
-rw-r--r-- | src/datastore/test_datastore_api.c | 4 | ||||
-rw-r--r-- | src/datastore/test_datastore_api_management.c | 5 | ||||
-rw-r--r-- | src/datastore/test_defaults.conf | 3 |
12 files changed, 182 insertions, 1019 deletions
diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am index 44c5bbe..e7bccbc 100644 --- a/src/datastore/Makefile.am +++ b/src/datastore/Makefile.am @@ -100,6 +100,7 @@ libgnunet_plugin_datastore_sqlite_la_LDFLAGS = \ libgnunet_plugin_datastore_mysql_la_SOURCES = \ plugin_datastore_mysql.c libgnunet_plugin_datastore_mysql_la_LIBADD = \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lz -lmysqlclient libgnunet_plugin_datastore_mysql_la_LDFLAGS = \ @@ -111,6 +112,7 @@ libgnunet_plugin_datastore_postgres_la_SOURCES = \ plugin_datastore_postgres.c libgnunet_plugin_datastore_postgres_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq libgnunet_plugin_datastore_postgres_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) $(POSTGRES_LDFLAGS) -lpq diff --git a/src/datastore/Makefile.in b/src/datastore/Makefile.in index d85f1ea..2488d24 100644 --- a/src/datastore/Makefile.in +++ b/src/datastore/Makefile.in @@ -87,6 +87,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \ LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = libgnunet_plugin_datastore_mysql_la_DEPENDENCIES = \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) @@ -106,6 +107,7 @@ libgnunet_plugin_datastore_mysql_la_LINK = $(LIBTOOL) $(AM_V_lt) \ @HAVE_MYSQL_TRUE@ -rpath $(plugindir) libgnunet_plugin_datastore_postgres_la_DEPENDENCIES = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(am__DEPENDENCIES_1) am_libgnunet_plugin_datastore_postgres_la_OBJECTS = libgnunet_plugin_datastore_postgres_la-plugin_datastore_postgres.lo @@ -405,6 +407,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -438,6 +441,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -639,6 +643,7 @@ libgnunet_plugin_datastore_mysql_la_SOURCES = \ plugin_datastore_mysql.c libgnunet_plugin_datastore_mysql_la_LIBADD = \ + $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lz -lmysqlclient @@ -653,6 +658,7 @@ libgnunet_plugin_datastore_postgres_la_SOURCES = \ libgnunet_plugin_datastore_postgres_la_LIBADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/postgres/libgnunetpostgres.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq libgnunet_plugin_datastore_postgres_la_LDFLAGS = \ diff --git a/src/datastore/datastore.h b/src/datastore/datastore.h index 1126027..87ceb01 100644 --- a/src/datastore/datastore.h +++ b/src/datastore/datastore.h @@ -27,7 +27,6 @@ #ifndef DATASTORE_H #define DATASTORE_H -#define DEBUG_DATASTORE GNUNET_EXTRA_LOGGING #include "gnunet_util_lib.h" @@ -130,7 +129,7 @@ struct GetMessage * Desired key (optional). Check the "size" of the * header to see if the key is actually present. */ - GNUNET_HashCode key GNUNET_PACKED; + GNUNET_HashCode key; }; @@ -253,7 +252,7 @@ struct DataMessage /** * Key under which the item can be found. */ - GNUNET_HashCode key GNUNET_PACKED; + GNUNET_HashCode key; }; GNUNET_NETWORK_STRUCT_END diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c index 4f406a2..57663e9 100644 --- a/src/datastore/datastore_api.c +++ b/src/datastore/datastore_api.c @@ -270,6 +270,22 @@ GNUNET_DATASTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) /** + * Task used by 'transmit_drop' to disconnect the datastore. + * + * @param cls the datastore handle + * @param tc scheduler context + */ +static void +disconnect_after_drop (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_DATASTORE_Handle *h = cls; + + GNUNET_DATASTORE_disconnect (h, GNUNET_NO); +} + + +/** * Transmit DROP message to datastore service. * * @param cls the 'struct GNUNET_DATASTORE_Handle' @@ -287,14 +303,16 @@ transmit_drop (void *cls, size_t size, void *buf) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to transmit request to drop database.\n")); - GNUNET_DATASTORE_disconnect (h, GNUNET_NO); + GNUNET_SCHEDULER_add_continuation (&disconnect_after_drop, h, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); return 0; } GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); hdr = buf; hdr->size = htons (sizeof (struct GNUNET_MessageHeader)); hdr->type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_DROP); - GNUNET_DATASTORE_disconnect (h, GNUNET_NO); + GNUNET_SCHEDULER_add_continuation (&disconnect_after_drop, h, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); return sizeof (struct GNUNET_MessageHeader); } @@ -311,9 +329,7 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, int drop) { struct GNUNET_DATASTORE_QueueEntry *qe; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Datastore disconnect\n"); -#endif if (NULL != h->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); @@ -321,7 +337,7 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, int drop) } if (h->client != NULL) { - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } if (h->reconnect_task != GNUNET_SCHEDULER_NO_TASK) @@ -346,7 +362,7 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, int drop) GNUNET_TIME_UNIT_MINUTES, GNUNET_YES, &transmit_drop, h)) return; - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } GNUNET_break (0); @@ -373,9 +389,7 @@ timeout_queue_entry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_NO); qe->task = GNUNET_SCHEDULER_NO_TASK; GNUNET_assert (qe->was_transmitted == GNUNET_NO); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Timeout of request in datastore queue\n"); -#endif qe->response_proc (qe->h, NULL); } @@ -455,9 +469,7 @@ make_queue_entry (struct GNUNET_DATASTORE_Handle *h, size_t msize, GNUNET_assert (pos->response_proc != NULL); /* move 'pos' element to head so that it will be * killed on 'NULL' call below */ -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Dropping request from datastore queue\n"); -#endif GNUNET_CONTAINER_DLL_remove (h->queue_head, h->queue_tail, pos); GNUNET_CONTAINER_DLL_insert (h->queue_head, h->queue_tail, pos); GNUNET_STATISTICS_update (h->stats, @@ -512,9 +524,7 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) gettext_noop ("# datastore connections (re)created"), 1, GNUNET_NO); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnected to DATASTORE\n"); -#endif process_queue (h); } @@ -530,17 +540,15 @@ do_disconnect (struct GNUNET_DATASTORE_Handle *h) { if (h->client == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "client NULL in disconnect, will not try to reconnect\n"); -#endif return; } #if 0 GNUNET_STATISTICS_update (stats, gettext_noop ("# reconnected to DATASTORE"), 1, GNUNET_NO); #endif - GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (h->client); h->skip_next_messages = 0; h->client = NULL; h->reconnect_task = @@ -562,9 +570,7 @@ receive_cb (void *cls, const struct GNUNET_MessageHeader *msg) struct GNUNET_DATASTORE_QueueEntry *qe; h->in_receive = GNUNET_NO; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving reply from datastore\n"); -#endif if (h->skip_next_messages > 0) { h->skip_next_messages--; @@ -601,9 +607,7 @@ transmit_request (void *cls, size_t size, void *buf) return 0; /* no entry in queue */ if (buf == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to transmit request to DATASTORE.\n"); -#endif GNUNET_STATISTICS_update (h->stats, gettext_noop ("# transmission request failures"), 1, GNUNET_NO); @@ -615,10 +619,8 @@ transmit_request (void *cls, size_t size, void *buf) process_queue (h); return 0; } -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u byte request to DATASTORE\n", msize); -#endif memcpy (buf, &qe[1], msize); qe->was_transmitted = GNUNET_YES; GNUNET_SCHEDULER_cancel (qe->task); @@ -647,30 +649,22 @@ process_queue (struct GNUNET_DATASTORE_Handle *h) if (NULL == (qe = h->queue_head)) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queue empty\n"); -#endif return; /* no entry in queue */ } if (qe->was_transmitted == GNUNET_YES) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Head request already transmitted\n"); -#endif return; /* waiting for replies */ } if (h->th != NULL) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Pending transmission request\n"); -#endif return; /* request pending */ } if (h->client == NULL) { -#if DEBUG_DATASTORE > 1 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not connected\n"); -#endif return; /* waiting for reconnect */ } if (GNUNET_YES == h->in_receive) @@ -678,10 +672,8 @@ process_queue (struct GNUNET_DATASTORE_Handle *h) /* wait for response to previous query */ return; } -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing %u byte request to DATASTORE\n", qe->message_size); -#endif h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, qe->message_size, GNUNET_TIME_absolute_get_remaining @@ -803,9 +795,7 @@ process_status_message (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); emsg = _("Invalid error message received from datastore service"); } -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received status %d/%s\n", (int) status, emsg); -#endif GNUNET_STATISTICS_update (h->stats, gettext_noop ("# status messages received"), 1, GNUNET_NO); @@ -861,12 +851,10 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, uint32_t rid, size_t msize; union QueueContext qc; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to put %u bytes of data under key `%s' for %llu ms\n", size, GNUNET_h2s (key), GNUNET_TIME_absolute_get_remaining (expiration).rel_value); -#endif msize = sizeof (struct DataMessage) + size; GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); qc.sc.cont = cont; @@ -875,9 +863,7 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, uint32_t rid, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for PUT\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, gettext_noop ("# PUT requests executed"), @@ -934,20 +920,16 @@ GNUNET_DATASTORE_reserve (struct GNUNET_DATASTORE_Handle *h, uint64_t amount, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to reserve %llu bytes of data and %u entries\n", (unsigned long long) amount, (unsigned int) entries); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; qe = make_queue_entry (h, sizeof (struct ReserveMessage), queue_priority, max_queue_size, timeout, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry to reserve\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -998,9 +980,7 @@ GNUNET_DATASTORE_release_reserve (struct GNUNET_DATASTORE_Handle *h, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to release reserve %d\n", rid); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; qe = make_queue_entry (h, sizeof (struct ReleaseReserveMessage), @@ -1008,10 +988,8 @@ GNUNET_DATASTORE_release_reserve (struct GNUNET_DATASTORE_Handle *h, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry to release reserve\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1060,20 +1038,16 @@ GNUNET_DATASTORE_update (struct GNUNET_DATASTORE_Handle *h, uint64_t uid, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to update entry %llu raising priority by %u and expiration to %llu\n", uid, (unsigned int) priority, (unsigned long long) expiration.abs_value); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; qe = make_queue_entry (h, sizeof (struct UpdateMessage), queue_priority, max_queue_size, timeout, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for UPDATE\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1127,10 +1101,8 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h, if (cont == NULL) cont = &drop_status_cont; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to remove %u bytes under key `%s'\n", size, GNUNET_h2s (key)); -#endif qc.sc.cont = cont; qc.sc.cont_cls = cont_cls; msize = sizeof (struct DataMessage) + size; @@ -1139,9 +1111,7 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h, &process_status_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for REMOVE\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1209,10 +1179,8 @@ process_result_message (void *cls, const struct GNUNET_MessageHeader *msg) rc = qe->qc.rc; GNUNET_assert (GNUNET_YES == qe->was_transmitted); free_queue_entry (qe); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received end of result set, new queue size is %u\n", h->queue_size); -#endif h->retry_time.rel_value = 0; h->result_count = 0; process_queue (h); @@ -1253,12 +1221,10 @@ process_result_message (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_STATISTICS_update (h->stats, gettext_noop ("# Results received"), 1, GNUNET_NO); dm = (const struct DataMessage *) msg; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Received result %llu with type %u and size %u with key %s\n", (unsigned long long) GNUNET_ntohll (dm->uid), ntohl (dm->type), ntohl (dm->size), GNUNET_h2s (&dm->key)); -#endif free_queue_entry (qe); h->retry_time.rel_value = 0; process_queue (h); @@ -1302,10 +1268,8 @@ GNUNET_DATASTORE_get_for_replication (struct GNUNET_DATASTORE_Handle *h, union QueueContext qc; GNUNET_assert (NULL != proc); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to get replication entry in %llu ms\n", (unsigned long long) timeout.rel_value); -#endif qc.rc.proc = proc; qc.rc.proc_cls = proc_cls; qe = make_queue_entry (h, sizeof (struct GNUNET_MessageHeader), @@ -1313,10 +1277,8 @@ GNUNET_DATASTORE_get_for_replication (struct GNUNET_DATASTORE_Handle *h, &process_result_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for GET REPLICATION\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1367,12 +1329,10 @@ GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h, GNUNET_assert (NULL != proc); GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to get %llu-th zero-anonymity entry of type %d in %llu ms\n", (unsigned long long) offset, type, (unsigned long long) timeout.rel_value); -#endif qc.rc.proc = proc; qc.rc.proc_cls = proc_cls; qe = make_queue_entry (h, sizeof (struct GetZeroAnonymityMessage), @@ -1380,10 +1340,8 @@ GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h, &process_result_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for zero-anonymity procation\n"); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, @@ -1435,21 +1393,17 @@ GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h, uint64_t offset, union QueueContext qc; GNUNET_assert (NULL != proc); -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to look for data of type %u under key `%s'\n", (unsigned int) type, GNUNET_h2s (key)); -#endif qc.rc.proc = proc; qc.rc.proc_cls = proc_cls; qe = make_queue_entry (h, sizeof (struct GetMessage), queue_priority, max_queue_size, timeout, &process_result_message, &qc); if (qe == NULL) { -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not queue request for `%s'\n", GNUNET_h2s (key)); -#endif return NULL; } GNUNET_STATISTICS_update (h->stats, gettext_noop ("# GET requests executed"), @@ -1486,11 +1440,9 @@ GNUNET_DATASTORE_cancel (struct GNUNET_DATASTORE_QueueEntry *qe) GNUNET_assert (GNUNET_SYSERR != qe->was_transmitted); h = qe->h; -#if DEBUG_DATASTORE LOG (GNUNET_ERROR_TYPE_DEBUG, "Pending DATASTORE request %p cancelled (%d, %d)\n", qe, qe->was_transmitted, h->queue_head == qe); -#endif if (GNUNET_YES == qe->was_transmitted) { free_queue_entry (qe); diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 1d7e8cd..49b9db8 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c @@ -250,7 +250,7 @@ struct TransmitCallbackContext /** * Handle for the transmission request. */ - struct GNUNET_CONNECTION_TransmitHandle *th; + struct GNUNET_SERVER_TransmitHandle *th; /** * Client that we are transmitting to. @@ -341,12 +341,10 @@ expired_processor (void *cls, const GNUNET_HashCode * key, uint32_t size, &delete_expired, NULL); return GNUNET_SYSERR; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting content `%s' of type %u that expired %llu ms ago\n", GNUNET_h2s (key), type, (unsigned long long) (now.abs_value - expiration.abs_value)); -#endif min_expiration = now; GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes expired"), size, GNUNET_YES); @@ -405,7 +403,6 @@ quota_processor (void *cls, const GNUNET_HashCode * key, uint32_t size, if (NULL == key) return GNUNET_SYSERR; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting %llu bytes of low-priority (%u) content `%s' of type %u at %llu ms prior to expiration (still trying to free another %llu bytes)\n", (unsigned long long) (size + GNUNET_DATASTORE_ENTRY_OVERHEAD), @@ -413,7 +410,6 @@ quota_processor (void *cls, const GNUNET_HashCode * key, uint32_t size, GNUNET_h2s (key), type, (unsigned long long) GNUNET_TIME_absolute_get_remaining (expiration).rel_value, *need); -#endif if (size + GNUNET_DATASTORE_ENTRY_OVERHEAD > *need) *need = 0; else @@ -447,10 +443,8 @@ manage_space (unsigned long long need) { unsigned long long last; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asked to free up %llu bytes of cache space\n", need); -#endif last = 0; while ((need > 0) && (last != need)) { @@ -513,10 +507,8 @@ transmit (struct GNUNET_SERVER_Client *client, struct GNUNET_MessageHeader *msg) if (GNUNET_YES == cleaning_done) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Shutdown in progress, aborting transmission.\n"); -#endif + _("Shutdown in progress, aborting transmission.\n")); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); GNUNET_free (msg); return; @@ -554,11 +546,9 @@ transmit_status (struct GNUNET_SERVER_Client *client, int code, const char *msg) struct StatusMessage *sm; size_t slen; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' message with value %d and message `%s'\n", "STATUS", code, msg != NULL ? msg : "(none)"); -#endif slen = (msg == NULL) ? 0 : strlen (msg) + 1; sm = GNUNET_malloc (sizeof (struct StatusMessage) + slen); sm->header.size = htons (sizeof (struct StatusMessage) + slen); @@ -603,10 +593,8 @@ transmit_item (void *cls, const GNUNET_HashCode * key, uint32_t size, if (key == NULL) { /* transmit 'DATA_END' */ -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' message\n", "DATA_END"); -#endif end = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader)); end->size = htons (sizeof (struct GNUNET_MessageHeader)); end->type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END); @@ -630,13 +618,11 @@ transmit_item (void *cls, const GNUNET_HashCode * key, uint32_t size, dm->uid = GNUNET_htonll (uid); dm->key = *key; memcpy (&dm[1], data, size); -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' message for `%s' of type %u with expiration %llu (now: %llu)\n", "DATA", GNUNET_h2s (key), type, (unsigned long long) expiration.abs_value, (unsigned long long) GNUNET_TIME_absolute_get ().abs_value); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# results found"), 1, GNUNET_NO); transmit (client, &dm->header); @@ -668,9 +654,7 @@ handle_reserve (void *cls, struct GNUNET_SERVER_Client *client, uint64_t amount; uint32_t entries; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "RESERVE"); -#endif amount = GNUNET_ntohll (msg->amount); entries = ntohl (msg->entries); used = payload + reserved; @@ -742,10 +726,8 @@ handle_release_reserve (void *cls, struct GNUNET_SERVER_Client *client, int rid = ntohl (msg->rid); unsigned long long rem; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "RELEASE_RESERVE"); -#endif next = reservations; prev = NULL; while (NULL != (pos = next)) @@ -764,11 +746,9 @@ handle_release_reserve (void *cls, struct GNUNET_SERVER_Client *client, reserved -= rem; GNUNET_STATISTICS_set (stats, gettext_noop ("# reserved"), reserved, GNUNET_NO); -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Returning %llu remaining reserved bytes to storage pool\n", rem); -#endif GNUNET_free (pos); transmit_status (client, GNUNET_OK, NULL); return; @@ -854,11 +834,9 @@ execute_put (struct GNUNET_SERVER_Client *client, const struct DataMessage *dm) GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes stored"), size, GNUNET_YES); GNUNET_CONTAINER_bloomfilter_add (filter, &dm->key); -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully stored %u bytes of type %u under key `%s'\n", size, ntohl (dm->type), GNUNET_h2s (&dm->key)); -#endif } transmit_status (client, ret, msg); GNUNET_free_non_null (msg); @@ -914,10 +892,8 @@ check_present (void *cls, const GNUNET_HashCode * key, uint32_t size, (0 == memcmp (&dm[1], data, size)))) { -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result already present in datastore\n"); -#endif /* FIXME: change API to allow increasing 'replication' counter */ if ((ntohl (dm->priority) > 0) || (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value > @@ -963,11 +939,9 @@ handle_put (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for `%s' of type %u\n", "PUT", GNUNET_h2s (&dm->key), ntohl (dm->type)); -#endif rid = ntohl (dm->rid); size = ntohl (dm->size); if (rid > 0) @@ -1026,11 +1000,9 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, return; } msg = (const struct GetMessage *) message; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for `%s' of type %u\n", "GET", GNUNET_h2s (&msg->key), ntohl (msg->type)); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# GET requests received"), 1, GNUNET_NO); GNUNET_SERVER_client_keep (client); @@ -1038,11 +1010,9 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, (GNUNET_YES != GNUNET_CONTAINER_bloomfilter_test (filter, &msg->key))) { /* don't bother database... */ -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Empty result set for `%s' request for `%s' (bloomfilter).\n", "GET", GNUNET_h2s (&msg->key)); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# requests filtered by bloomfilter"), 1, @@ -1077,10 +1047,8 @@ handle_update (void *cls, struct GNUNET_SERVER_Client *client, 1, GNUNET_NO); msg = (const struct UpdateMessage *) message; emsg = NULL; -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for %llu\n", "UPDATE", (unsigned long long) GNUNET_ntohll (msg->uid)); -#endif ret = plugin->api->update (plugin->api->cls, GNUNET_ntohll (msg->uid), (int32_t) ntohl (msg->priority), @@ -1101,10 +1069,8 @@ static void handle_get_replication (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "GET_REPLICATION"); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# GET REPLICATION requests received"), 1, @@ -1136,10 +1102,8 @@ handle_get_zero_anonymity (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "GET_ZERO_ANONYMITY"); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# GET ZERO ANONYMITY requests received"), 1, @@ -1165,19 +1129,15 @@ remove_callback (void *cls, const GNUNET_HashCode * key, uint32_t size, if (key == NULL) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No further matches for `%s' request.\n", "REMOVE"); -#endif transmit_status (client, GNUNET_NO, _("Content not found")); GNUNET_SERVER_client_drop (client); return GNUNET_OK; /* last item */ } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Item %llu matches `%s' request for key `%s' and type %u.\n", (unsigned long long) uid, "REMOVE", GNUNET_h2s (key), type); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes removed (explicit request)"), size, GNUNET_YES); @@ -1208,11 +1168,9 @@ handle_remove (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request for `%s' of type %u\n", "REMOVE", GNUNET_h2s (&dm->key), ntohl (dm->type)); -#endif GNUNET_STATISTICS_update (stats, gettext_noop ("# REMOVE requests received"), 1, GNUNET_NO); GNUNET_SERVER_client_keep (client); @@ -1234,9 +1192,7 @@ static void handle_drop (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "DROP"); -#endif do_drop = GNUNET_YES; GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -1287,11 +1243,9 @@ process_stat_in (void *cls, const char *subsystem, const char *name, GNUNET_assert (stats_worked == GNUNET_NO); stats_worked = GNUNET_YES; payload += value; -#if DEBUG_SQLITE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notification from statistics about existing payload (%llu), new payload is %llu\n", - abs_value, payload); -#endif + value, payload); return GNUNET_OK; } @@ -1348,10 +1302,8 @@ load_plugin () static void unload_plugin (struct DatastorePlugin *plug) { -#if DEBUG_DATASTORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Datastore service is unloading plugin...\n"); -#endif GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api)); GNUNET_free (plug->lib_name); GNUNET_free (plug->short_name); @@ -1409,7 +1361,7 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc); if (tcc->th != NULL) { - GNUNET_CONNECTION_notify_transmit_ready_cancel (tcc->th); + GNUNET_SERVER_notify_transmit_ready_cancel (tcc->th); GNUNET_SERVER_client_drop (tcc->client); } GNUNET_free (tcc->msg); diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c index aae152d..cdbd6ae 100644 --- a/src/datastore/perf_datastore_api.c +++ b/src/datastore/perf_datastore_api.c @@ -285,8 +285,9 @@ run_tests (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, c if (success != GNUNET_YES) { FPRINTF (stderr, - "Test 'put' operation failed with error `%s' database likely not setup, skipping test.", + "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", msg); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; } @@ -359,7 +360,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; return ok; } diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c index 76d6ad7..ed7741c 100644 --- a/src/datastore/plugin_datastore_mysql.c +++ b/src/datastore/plugin_datastore_mysql.c @@ -119,47 +119,11 @@ #include "platform.h" #include "gnunet_datastore_plugin.h" #include "gnunet_util_lib.h" -#include <mysql/mysql.h> +#include "gnunet_mysql_lib.h" -#define DEBUG_MYSQL GNUNET_EXTRA_LOGGING #define MAX_DATUM_SIZE 65536 -/** - * Maximum number of supported parameters for a prepared - * statement. Increase if needed. - */ -#define MAX_PARAM 16 - -/** - * Die with an error message that indicates - * a failure of the command 'cmd' with the message given - * by strerror(errno). - */ -#define DIE_MYSQL(cmd, dbh) do { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); GNUNET_abort(); } while(0); - -/** - * Log an error message at log-level 'level' that indicates - * a failure of the command 'cmd' on file 'filename' - * with the message given by strerror(errno). - */ -#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0); - - -struct GNUNET_MysqlStatementHandle -{ - struct GNUNET_MysqlStatementHandle *next; - - struct GNUNET_MysqlStatementHandle *prev; - - char *query; - - MYSQL_STMT *statement; - - int valid; - -}; - /** * Context for all functions in this plugin. @@ -174,64 +138,49 @@ struct Plugin /** * Handle to talk to MySQL. */ - MYSQL *dbf; - - /** - * We keep all prepared statements in a DLL. This is the head. - */ - struct GNUNET_MysqlStatementHandle *shead; - - /** - * We keep all prepared statements in a DLL. This is the tail. - */ - struct GNUNET_MysqlStatementHandle *stail; - - /** - * Filename of "my.cnf" (msyql configuration). - */ - char *cnffile; + struct GNUNET_MYSQL_Context *mc; /** * Prepared statements. */ #define INSERT_ENTRY "INSERT INTO gn090 (repl,type,prio,anonLevel,expire,rvalue,hash,vhash,value) VALUES (?,?,?,?,?,?,?,?,?)" - struct GNUNET_MysqlStatementHandle *insert_entry; + struct GNUNET_MYSQL_StatementHandle *insert_entry; #define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?" - struct GNUNET_MysqlStatementHandle *delete_entry_by_uid; + struct GNUNET_MYSQL_StatementHandle *delete_entry_by_uid; #define COUNT_ENTRY_BY_HASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash) WHERE hash=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash; #define SELECT_ENTRY_BY_HASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash) WHERE hash=? ORDER BY uid LIMIT 1 OFFSET ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash; #define COUNT_ENTRY_BY_HASH_AND_VHASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_vhash; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_and_vhash; #define SELECT_ENTRY_BY_HASH_AND_VHASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? ORDER BY uid LIMIT 1 OFFSET ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_vhash; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_vhash; #define COUNT_ENTRY_BY_HASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_type; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_and_type; #define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=? ORDER BY uid LIMIT 1 OFFSET ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_type; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_type; #define COUNT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=?" - struct GNUNET_MysqlStatementHandle *count_entry_by_hash_vhash_and_type; + struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_vhash_and_type; #define SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=? ORDER BY uid ASC LIMIT 1 OFFSET ?" - struct GNUNET_MysqlStatementHandle *select_entry_by_hash_vhash_and_type; + struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_vhash_and_type; #define UPDATE_ENTRY "UPDATE gn090 SET prio=prio+?,expire=IF(expire>=?,expire,?) WHERE uid=?" - struct GNUNET_MysqlStatementHandle *update_entry; + struct GNUNET_MYSQL_StatementHandle *update_entry; #define DEC_REPL "UPDATE gn090 SET repl=GREATEST (0, repl - 1) WHERE uid=?" - struct GNUNET_MysqlStatementHandle *dec_repl; + struct GNUNET_MYSQL_StatementHandle *dec_repl; #define SELECT_SIZE "SELECT SUM(BIT_LENGTH(value) DIV 8) FROM gn090" - struct GNUNET_MysqlStatementHandle *get_size; + struct GNUNET_MYSQL_StatementHandle *get_size; #define SELECT_IT_NON_ANONYMOUS "SELECT type,prio,anonLevel,expire,hash,value,uid "\ "FROM gn090 FORCE INDEX (idx_anonLevel_type_rvalue) "\ @@ -239,13 +188,13 @@ struct Plugin "(rvalue >= ? OR"\ " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_anonLevel_type_rvalue) WHERE anonLevel=0 AND type=? AND rvalue>=?)) "\ "ORDER BY rvalue ASC LIMIT 1" - struct GNUNET_MysqlStatementHandle *zero_iter; + struct GNUNET_MYSQL_StatementHandle *zero_iter; #define SELECT_IT_EXPIRATION "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_expire) WHERE expire < ? ORDER BY expire ASC LIMIT 1" - struct GNUNET_MysqlStatementHandle *select_expiration; + struct GNUNET_MYSQL_StatementHandle *select_expiration; #define SELECT_IT_PRIORITY "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_prio) ORDER BY prio ASC LIMIT 1" - struct GNUNET_MysqlStatementHandle *select_priority; + struct GNUNET_MYSQL_StatementHandle *select_priority; #define SELECT_IT_REPLICATION "SELECT type,prio,anonLevel,expire,hash,value,uid "\ "FROM gn090 FORCE INDEX (idx_repl_rvalue) "\ @@ -254,510 +203,15 @@ struct Plugin " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) "\ "ORDER BY rvalue ASC "\ "LIMIT 1" - struct GNUNET_MysqlStatementHandle *select_replication; + struct GNUNET_MYSQL_StatementHandle *select_replication; #define SELECT_MAX_REPL "SELECT MAX(repl) FROM gn090" - struct GNUNET_MysqlStatementHandle *max_repl; - -}; - - -/** - * Obtain the location of ".my.cnf". - * - * @param cfg our configuration - * @return NULL on error - */ -static char * -get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - char *cnffile; - char *home_dir; - struct stat st; - -#ifndef WINDOWS - struct passwd *pw; -#endif - int configured; - -#ifndef WINDOWS - pw = getpwuid (getuid ()); - if (!pw) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getpwuid"); - return NULL; - } - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (cfg, "datastore-mysql", "CONFIG")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_filename (cfg, - "datastore-mysql", - "CONFIG", - &cnffile)); - configured = GNUNET_YES; - } - else - { - home_dir = GNUNET_strdup (pw->pw_dir); - GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); - GNUNET_free (home_dir); - configured = GNUNET_NO; - } -#else - home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); - plibc_conv_to_win_path ("~/", home_dir); - GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); - GNUNET_free (home_dir); - configured = GNUNET_NO; -#endif - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Trying to use file `%s' for MySQL configuration.\n"), cnffile); - if ((0 != STAT (cnffile, &st)) || (0 != ACCESS (cnffile, R_OK)) || - (!S_ISREG (st.st_mode))) - { - if (configured == GNUNET_YES) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not access file `%s': %s\n"), cnffile, - STRERROR (errno)); - GNUNET_free (cnffile); - return NULL; - } - return cnffile; -} - - -/** - * Close database connection and all prepared statements (we got a DB - * disconnect error). - * - * @param plugin plugin context - */ -static int -iclose (struct Plugin *plugin) -{ - struct GNUNET_MysqlStatementHandle *s; - - for (s = plugin->shead; s != NULL; s = s->next) - { - if (s->valid) - { - mysql_stmt_close (s->statement); - s->valid = GNUNET_NO; - } - } - if (plugin->dbf != NULL) - { - mysql_close (plugin->dbf); - plugin->dbf = NULL; - } - return GNUNET_OK; -} - - -/** - * Open the connection with the database (and initialize - * our default options). - * - * @param plugin plugin context - * @return GNUNET_OK on success - */ -static int -iopen (struct Plugin *plugin) -{ - char *mysql_dbname; - char *mysql_server; - char *mysql_user; - char *mysql_password; - unsigned long long mysql_port; - my_bool reconnect; - unsigned int timeout; - - plugin->dbf = mysql_init (NULL); - if (plugin->dbf == NULL) - return GNUNET_SYSERR; - if (plugin->cnffile != NULL) - mysql_options (plugin->dbf, MYSQL_READ_DEFAULT_FILE, plugin->cnffile); - mysql_options (plugin->dbf, MYSQL_READ_DEFAULT_GROUP, "client"); - reconnect = 0; - mysql_options (plugin->dbf, MYSQL_OPT_RECONNECT, &reconnect); - timeout = 120; /* in seconds */ - mysql_options (plugin->dbf, MYSQL_OPT_CONNECT_TIMEOUT, - (const void *) &timeout); - mysql_options (plugin->dbf, MYSQL_SET_CHARSET_NAME, "UTF8"); - timeout = 60; /* in seconds */ - mysql_options (plugin->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout); - mysql_options (plugin->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout); - mysql_dbname = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "DATABASE")) - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "DATABASE", - &mysql_dbname)); - else - mysql_dbname = GNUNET_strdup ("gnunet"); - mysql_user = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "USER")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "USER", &mysql_user)); - } - mysql_password = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "PASSWORD")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "PASSWORD", - &mysql_password)); - } - mysql_server = NULL; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "HOST")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-mysql", - "HOST", - &mysql_server)); - } - mysql_port = 0; - if (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (plugin->env->cfg, "datastore-mysql", - "PORT")) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, - "datastore-mysql", - "PORT", &mysql_port)); - } + struct GNUNET_MYSQL_StatementHandle *max_repl; - GNUNET_assert (mysql_dbname != NULL); - mysql_real_connect (plugin->dbf, mysql_server, mysql_user, mysql_password, - mysql_dbname, (unsigned int) mysql_port, NULL, - CLIENT_IGNORE_SIGPIPE); - GNUNET_free_non_null (mysql_server); - GNUNET_free_non_null (mysql_user); - GNUNET_free_non_null (mysql_password); - GNUNET_free (mysql_dbname); - if (mysql_error (plugin->dbf)[0]) - { - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_real_connect", plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} +#define GET_ALL_KEYS "SELECT hash from gn090" + struct GNUNET_MYSQL_StatementHandle *get_all_keys; - -/** - * Run the given MySQL statement. - * - * @param plugin plugin context - * @param statement SQL statement to run - * @return GNUNET_OK on success, GNUNET_SYSERR on error - */ -static int -run_statement (struct Plugin *plugin, const char *statement) -{ - if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) - return GNUNET_SYSERR; - mysql_query (plugin->dbf, statement); - if (mysql_error (plugin->dbf)[0]) - { - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", plugin); - iclose (plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Create a prepared statement. - * - * @param plugin plugin context - * @param statement SQL statement text to prepare - * @return NULL on error - */ -static struct GNUNET_MysqlStatementHandle * -prepared_statement_create (struct Plugin *plugin, const char *statement) -{ - struct GNUNET_MysqlStatementHandle *ret; - - ret = GNUNET_malloc (sizeof (struct GNUNET_MysqlStatementHandle)); - ret->query = GNUNET_strdup (statement); - GNUNET_CONTAINER_DLL_insert (plugin->shead, plugin->stail, ret); - return ret; -} - - -/** - * Prepare a statement for running. - * - * @param plugin plugin context - * @param ret handle to prepared statement - * @return GNUNET_OK on success - */ -static int -prepare_statement (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *ret) -{ - if (GNUNET_YES == ret->valid) - return GNUNET_OK; - if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) - return GNUNET_SYSERR; - ret->statement = mysql_stmt_init (plugin->dbf); - if (ret->statement == NULL) - { - iclose (plugin); - return GNUNET_SYSERR; - } - if (mysql_stmt_prepare (ret->statement, ret->query, strlen (ret->query))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", - _("Failed to prepare statement `%s'\n"), ret->query); - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", plugin); - mysql_stmt_close (ret->statement); - ret->statement = NULL; - iclose (plugin); - return GNUNET_SYSERR; - } - ret->valid = GNUNET_YES; - return GNUNET_OK; - -} - - -/** - * Bind the parameters for the given MySQL statement - * and run it. - * - * @param plugin plugin context - * @param s statement to bind and run - * @param ap arguments for the binding - * @return GNUNET_SYSERR on error, GNUNET_OK on success - */ -static int -init_params (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *s, - va_list ap) -{ - MYSQL_BIND qbind[MAX_PARAM]; - unsigned int pc; - unsigned int off; - enum enum_field_types ft; - - pc = mysql_stmt_param_count (s->statement); - if (pc > MAX_PARAM) - { - /* increase internal constant! */ - GNUNET_break (0); - return GNUNET_SYSERR; - } - memset (qbind, 0, sizeof (qbind)); - off = 0; - ft = 0; - while ((pc > 0) && (-1 != (int) (ft = va_arg (ap, enum enum_field_types)))) - { - qbind[off].buffer_type = ft; - switch (ft) - { - case MYSQL_TYPE_FLOAT: - qbind[off].buffer = va_arg (ap, float *); - - break; - case MYSQL_TYPE_LONGLONG: - qbind[off].buffer = va_arg (ap, unsigned long long *); - qbind[off].is_unsigned = va_arg (ap, int); - - break; - case MYSQL_TYPE_LONG: - qbind[off].buffer = va_arg (ap, unsigned int *); - qbind[off].is_unsigned = va_arg (ap, int); - - break; - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_BLOB: - qbind[off].buffer = va_arg (ap, void *); - qbind[off].buffer_length = va_arg (ap, unsigned long); - qbind[off].length = va_arg (ap, unsigned long *); - - break; - default: - /* unsupported type */ - GNUNET_break (0); - return GNUNET_SYSERR; - } - pc--; - off++; - } - if (!((pc == 0) && (-1 != (int) ft) && (va_arg (ap, int) == -1))) - { - GNUNET_assert (0); - return GNUNET_SYSERR; - } - if (mysql_stmt_bind_param (s->statement, qbind)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_param", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - if (mysql_stmt_execute (s->statement)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' for `%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_execute", s->query, __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Run a prepared SELECT statement. - * - * @param plugin plugin context - * @param s statement to run - * @param result_size number of elements in results array - * @param results pointer to already initialized MYSQL_BIND - * array (of sufficient size) for passing results - * @param ap pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @return GNUNET_SYSERR on error, otherwise GNUNET_OK or GNUNET_NO (no result) - */ -static int -prepared_statement_run_select_va (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned int result_size, - MYSQL_BIND * results, va_list ap) -{ - int ret; - unsigned int rsize; - - if (GNUNET_OK != prepare_statement (plugin, s)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != init_params (plugin, s, ap)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - rsize = mysql_stmt_field_count (s->statement); - if (rsize > result_size) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (mysql_stmt_bind_result (s->statement, results)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_result", __FILE__, __LINE__, - mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - ret = mysql_stmt_fetch (s->statement); - if (ret == MYSQL_NO_DATA) - return GNUNET_NO; - if (ret != 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_fetch", - __FILE__, __LINE__, mysql_stmt_error (s->statement)); - iclose (plugin); - return GNUNET_SYSERR; - } - mysql_stmt_reset (s->statement); - return GNUNET_OK; -} - - -/** - * Run a prepared SELECT statement. - * - * @param plugin plugin context - * @param s statement to run - * @param result_size number of elements in results array - * @param results pointer to already initialized MYSQL_BIND - * array (of sufficient size) for passing results - * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @return GNUNET_SYSERR on error, otherwise - * the number of successfully affected (or queried) rows - */ -static int -prepared_statement_run_select (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned int result_size, MYSQL_BIND * results, - ...) -{ - va_list ap; - int ret; - - va_start (ap, results); - ret = prepared_statement_run_select_va (plugin, s, result_size, results, ap); - va_end (ap); - return ret; -} - - -/** - * Run a prepared statement that does NOT produce results. - * - * @param plugin plugin context - * @param s statement to run - * @param insert_id NULL or address where to store the row ID of whatever - * was inserted (only for INSERT statements!) - * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective - * values (size + buffer-reference for pointers); terminated - * with "-1" - * @return GNUNET_SYSERR on error, otherwise - * the number of successfully affected rows - */ -static int -prepared_statement_run (struct Plugin *plugin, - struct GNUNET_MysqlStatementHandle *s, - unsigned long long *insert_id, ...) -{ - va_list ap; - int affected; - - if (GNUNET_OK != prepare_statement (plugin, s)) - return GNUNET_SYSERR; - va_start (ap, insert_id); - if (GNUNET_OK != init_params (plugin, s, ap)) - { - va_end (ap); - return GNUNET_SYSERR; - } - va_end (ap); - affected = mysql_stmt_affected_rows (s->statement); - if (NULL != insert_id) - *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement); - mysql_stmt_reset (s->statement); - return affected; -} +}; /** @@ -772,13 +226,11 @@ do_delete_entry (struct Plugin *plugin, unsigned long long uid) { int ret; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting value %llu from gn090 table\n", uid); -#endif - ret = - prepared_statement_run (plugin, plugin->delete_entry_by_uid, NULL, - MYSQL_TYPE_LONGLONG, &uid, GNUNET_YES, -1); + ret = GNUNET_MYSQL_statement_run_prepared (plugin->mc, + plugin->delete_entry_by_uid, NULL, + MYSQL_TYPE_LONGLONG, &uid, GNUNET_YES, -1); if (ret >= 0) return GNUNET_OK; GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -807,7 +259,7 @@ mysql_plugin_estimate_size (void *cls) cbind[0].buffer = &total; cbind[0].is_unsigned = GNUNET_NO; if (GNUNET_OK != - prepared_statement_run_select (plugin, plugin->get_size, 1, cbind, -1)) + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->get_size, 1, cbind, NULL, NULL, -1)) return 0; return total; } @@ -857,7 +309,7 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, lsize = size; GNUNET_CRYPTO_hash (data, size, &vhash); if (GNUNET_OK != - prepared_statement_run (plugin, plugin->insert_entry, NULL, + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_entry, NULL, MYSQL_TYPE_LONG, &irepl, GNUNET_YES, MYSQL_TYPE_LONG, &type, GNUNET_YES, MYSQL_TYPE_LONG, &ipriority, GNUNET_YES, @@ -868,11 +320,9 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, MYSQL_TYPE_BLOB, &vhash, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, data, lsize, &lsize, -1)) return GNUNET_SYSERR; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Inserted value `%s' with size %u into gn090 table\n", GNUNET_h2s (key), (unsigned int) size); -#endif if (size > 0) plugin->env->duc (plugin->env->cls, size); return GNUNET_OK; @@ -911,14 +361,12 @@ mysql_plugin_update (void *cls, uint64_t uid, int delta, unsigned long long lexpire = expire.abs_value; int ret; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating value %llu adding %d to priority and maxing exp at %llu\n", vkey, delta, lexpire); -#endif ret = - prepared_statement_run (plugin, plugin->update_entry, NULL, - MYSQL_TYPE_LONG, &delta, GNUNET_NO, + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->update_entry, NULL, + MYSQL_TYPE_LONG, &delta, GNUNET_NO, MYSQL_TYPE_LONGLONG, &lexpire, GNUNET_YES, MYSQL_TYPE_LONGLONG, &lexpire, GNUNET_YES, MYSQL_TYPE_LONGLONG, &vkey, GNUNET_YES, -1); @@ -942,7 +390,7 @@ mysql_plugin_update (void *cls, uint64_t uid, int delta, * @param ... arguments to initialize stmt */ static void -execute_select (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *stmt, +execute_select (struct Plugin *plugin, struct GNUNET_MYSQL_StatementHandle *stmt, PluginDatumProcessor proc, void *proc_cls, ...) { va_list ap; @@ -986,7 +434,7 @@ execute_select (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *stmt, rbind[6].is_unsigned = 1; va_start (ap, proc_cls); - ret = prepared_statement_run_select_va (plugin, stmt, 7, rbind, ap); + ret = GNUNET_MYSQL_statement_run_prepared_select_va (plugin->mc, stmt, 7, rbind, NULL, NULL, ap); va_end (ap); if (ret <= 0) { @@ -1001,11 +449,9 @@ execute_select (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *stmt, proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u-byte value under key `%s' with prio %u, anon %u, expire %llu selecting from gn090 table\n", (unsigned int) size, GNUNET_h2s (&key), priority, anonymity, exp); -#endif GNUNET_assert (size < MAX_DATUM_SIZE); expiration.abs_value = exp; ret = @@ -1067,10 +513,10 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, if (vhash != NULL) { ret = - prepared_statement_run_select (plugin, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin-> count_entry_by_hash_vhash_and_type, 1, - cbind, MYSQL_TYPE_BLOB, key, hashSize, + cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONG, &type, GNUNET_YES, -1); @@ -1078,9 +524,9 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, else { ret = - prepared_statement_run_select (plugin, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_entry_by_hash_and_type, - 1, cbind, MYSQL_TYPE_BLOB, key, + 1, cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_LONG, &type, GNUNET_YES, -1); } @@ -1090,9 +536,9 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, if (vhash != NULL) { ret = - prepared_statement_run_select (plugin, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_entry_by_hash_and_vhash, - 1, cbind, MYSQL_TYPE_BLOB, key, + 1, cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, vhash, hashSize2, &hashSize2, -1); @@ -1100,8 +546,8 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, else { ret = - prepared_statement_run_select (plugin, plugin->count_entry_by_hash, 1, - cbind, MYSQL_TYPE_BLOB, key, hashSize, + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_entry_by_hash, 1, + cbind, NULL, NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, -1); } } @@ -1112,12 +558,9 @@ mysql_plugin_get_key (void *cls, uint64_t offset, const GNUNET_HashCode * key, } offset = offset % total; off = (unsigned long long) offset; -#if DEBUG_MYSQL GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Obtaining %llu/%lld result for GET `%s'\n", off, total, GNUNET_h2s (key)); -#endif - if (type != GNUNET_BLOCK_TYPE_ANY) { if (NULL != vhash) @@ -1244,8 +687,8 @@ repl_proc (void *cls, const GNUNET_HashCode * key, uint32_t size, { oid = (unsigned long long) uid; iret = - prepared_statement_run (plugin, plugin->dec_repl, NULL, - MYSQL_TYPE_LONGLONG, &oid, GNUNET_YES, -1); + GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->dec_repl, NULL, + MYSQL_TYPE_LONGLONG, &oid, GNUNET_YES, -1); if (iret == GNUNET_SYSERR) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -1287,7 +730,7 @@ mysql_plugin_get_replication (void *cls, PluginDatumProcessor proc, results.is_unsigned = GNUNET_YES; if (1 != - prepared_statement_run_select (plugin, plugin->max_repl, 1, &results, -1)) + GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->max_repl, 1, &results, NULL, NULL, -1)) { proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; @@ -1324,19 +767,18 @@ mysql_plugin_get_keys (void *cls, MYSQL_BIND cbind[1]; unsigned long length; - statement = mysql_stmt_init (plugin->dbf); + statement = GNUNET_MYSQL_statement_get_stmt (plugin->mc, + plugin->get_all_keys); if (statement == NULL) { - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } if (mysql_stmt_prepare (statement, query, strlen (query))) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", _("Failed to prepare statement `%s'\n"), query); - LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", plugin); - mysql_stmt_close (statement); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } GNUNET_assert (proc != NULL); @@ -1346,8 +788,7 @@ mysql_plugin_get_keys (void *cls, _("`%s' for `%s' failed at %s:%d with error: %s\n"), "mysql_stmt_execute", query, __FILE__, __LINE__, mysql_stmt_error (statement)); - mysql_stmt_close (statement); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } memset (cbind, 0, sizeof (cbind)); @@ -1362,7 +803,7 @@ mysql_plugin_get_keys (void *cls, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_bind_result", __FILE__, __LINE__, mysql_stmt_error (statement)); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } while (0 == (ret = mysql_stmt_fetch (statement))) @@ -1376,11 +817,10 @@ mysql_plugin_get_keys (void *cls, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_fetch", __FILE__, __LINE__, mysql_stmt_error (statement)); - mysql_stmt_close (statement); - iclose (plugin); + GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } - mysql_stmt_close (statement); + mysql_stmt_reset (statement); } @@ -1484,7 +924,7 @@ mysql_plugin_drop (void *cls) { struct Plugin *plugin = cls; - if (GNUNET_OK != run_statement (plugin, "DROP TABLE gn090")) + if (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, "DROP TABLE gn090")) return; /* error */ plugin->env->duc (plugin->env->cls, 0); } @@ -1505,16 +945,14 @@ libgnunet_plugin_datastore_mysql_init (void *cls) plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; - plugin->cnffile = get_my_cnf_path (env->cfg); - if (GNUNET_OK != iopen (plugin)) + plugin->mc = GNUNET_MYSQL_context_create (env->cfg, "datastore-mysql"); + if (NULL == plugin->mc) { - iclose (plugin); - GNUNET_free_non_null (plugin->cnffile); GNUNET_free (plugin); return NULL; } -#define MRUNS(a) (GNUNET_OK != run_statement (plugin, a) ) -#define PINIT(a,b) (NULL == (a = prepared_statement_create(plugin, b))) +#define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, a) ) +#define PINIT(a,b) (NULL == (a = GNUNET_MYSQL_statement_prepare (plugin->mc, b))) if (MRUNS ("CREATE TABLE IF NOT EXISTS gn090 (" " repl INT(11) UNSIGNED NOT NULL DEFAULT 0," @@ -1556,10 +994,10 @@ libgnunet_plugin_datastore_mysql_init (void *cls) PINIT (plugin->select_expiration, SELECT_IT_EXPIRATION) || PINIT (plugin->select_priority, SELECT_IT_PRIORITY) || PINIT (plugin->max_repl, SELECT_MAX_REPL) || + PINIT (plugin->get_all_keys, GET_ALL_KEYS) || PINIT (plugin->select_replication, SELECT_IT_REPLICATION)) { - iclose (plugin); - GNUNET_free_non_null (plugin->cnffile); + GNUNET_MYSQL_context_destroy (plugin->mc); GNUNET_free (plugin); return NULL; } @@ -1593,19 +1031,10 @@ libgnunet_plugin_datastore_mysql_done (void *cls) { struct GNUNET_DATASTORE_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; - struct GNUNET_MysqlStatementHandle *s; - iclose (plugin); - while (NULL != (s = plugin->shead)) - { - GNUNET_CONTAINER_DLL_remove (plugin->shead, plugin->stail, s); - GNUNET_free (s->query); - GNUNET_free (s); - } - GNUNET_free_non_null (plugin->cnffile); + GNUNET_MYSQL_context_destroy (plugin->mc); GNUNET_free (plugin); GNUNET_free (api); - mysql_library_end (); return NULL; } diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c index 16393c2..6dec314 100644 --- a/src/datastore/plugin_datastore_postgres.c +++ b/src/datastore/plugin_datastore_postgres.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -26,9 +26,9 @@ #include "platform.h" #include "gnunet_datastore_plugin.h" +#include "gnunet_postgres_lib.h" #include <postgresql/libpq-fe.h> -#define DEBUG_POSTGRES GNUNET_EXTRA_LOGGING /** * After how many ms "busy" should a DB operation fail for good? @@ -62,87 +62,6 @@ struct Plugin /** - * Check if the result obtained from Postgres has - * the desired status code. If not, log an error, clear the - * result and return GNUNET_SYSERR. - * - * @param plugin global context - * @param ret result to check - * @param expected_status expected return value - * @param command name of SQL command that was run - * @param args arguments to SQL command - * @param line line number for error reporting - * @return GNUNET_OK if the result is acceptable - */ -static int -check_result (struct Plugin *plugin, PGresult * ret, int expected_status, - const char *command, const char *args, int line) -{ - if (ret == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "datastore-postgres", - "Postgres failed to allocate result for `%s:%s' at %d\n", - command, args, line); - return GNUNET_SYSERR; - } - if (PQresultStatus (ret) != expected_status) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - "datastore-postgres", - _("`%s:%s' failed at %s:%d with error: %s"), command, args, - __FILE__, line, PQerrorMessage (plugin->dbh)); - PQclear (ret); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - -/** - * Run simple SQL statement (without results). - * - * @param plugin global context - * @param sql statement to run - * @param line code line for error reporting - */ -static int -pq_exec (struct Plugin *plugin, const char *sql, int line) -{ - PGresult *ret; - - ret = PQexec (plugin->dbh, sql); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexec", sql, line)) - return GNUNET_SYSERR; - PQclear (ret); - return GNUNET_OK; -} - -/** - * Prepare SQL statement. - * - * @param plugin global context - * @param name name for the prepared SQL statement - * @param sql SQL code to prepare - * @param nparams number of parameters in sql - * @param line code line for error reporting - * @return GNUNET_OK on success - */ -static int -pq_prepare (struct Plugin *plugin, const char *name, const char *sql, - int nparams, int line) -{ - PGresult *ret; - - ret = PQprepare (plugin->dbh, name, sql, nparams, NULL); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQprepare", sql, line)) - return GNUNET_SYSERR; - PQclear (ret); - return GNUNET_OK; -} - -/** * @brief Get a database handle * * @param plugin global context @@ -151,33 +70,11 @@ pq_prepare (struct Plugin *plugin, const char *name, const char *sql, static int init_connection (struct Plugin *plugin) { - char *conninfo; PGresult *ret; - /* Open database and precompile statements */ - conninfo = NULL; - (void) GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, - "datastore-postgres", "CONFIG", - &conninfo); - plugin->dbh = PQconnectdb (conninfo == NULL ? "" : conninfo); + plugin->dbh = GNUNET_POSTGRES_connect (plugin->env->cfg, "datastore-postgres"); if (NULL == plugin->dbh) - { - /* FIXME: warn about out-of-memory? */ - GNUNET_free_non_null (conninfo); - return GNUNET_SYSERR; - } - if (PQstatus (plugin->dbh) != CONNECTION_OK) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "datastore-postgres", - _ - ("Unable to initialize Postgres with configuration `%s': %s"), - conninfo, PQerrorMessage (plugin->dbh)); - PQfinish (plugin->dbh); - plugin->dbh = NULL; - GNUNET_free_non_null (conninfo); return GNUNET_SYSERR; - } - GNUNET_free_non_null (conninfo); ret = PQexec (plugin->dbh, "CREATE TABLE gn090 (" " repl INTEGER NOT NULL DEFAULT 0," @@ -194,8 +91,7 @@ init_connection (struct Plugin *plugin) (ret, PG_DIAG_SQLSTATE))))) { - (void) check_result (plugin, ret, PGRES_COMMAND_OK, "CREATE TABLE", "gn090", - __LINE__); + (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "CREATE TABLE", "gn090"); PQfinish (plugin->dbh); plugin->dbh = NULL; return GNUNET_SYSERR; @@ -203,29 +99,23 @@ init_connection (struct Plugin *plugin) if (PQresultStatus (ret) == PGRES_COMMAND_OK) { if ((GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_hash ON gn090 (hash)", __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_hash ON gn090 (hash)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_hash_vhash ON gn090 (hash,vhash)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_hash_vhash ON gn090 (hash,vhash)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_prio ON gn090 (prio)", __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_prio ON gn090 (prio)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_expire ON gn090 (expire)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_expire ON gn090 (expire)")) || (GNUNET_OK != - pq_exec (plugin, - "CREATE INDEX idx_prio_anon ON gn090 (prio,anonLevel)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, + "CREATE INDEX idx_prio_anon ON gn090 (prio,anonLevel)")) || (GNUNET_OK != - pq_exec (plugin, - "CREATE INDEX idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, + "CREATE INDEX idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_repl_rvalue ON gn090 (repl,rvalue)", - __LINE__)) || + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_repl_rvalue ON gn090 (repl,rvalue)")) || (GNUNET_OK != - pq_exec (plugin, "CREATE INDEX idx_expire_hash ON gn090 (expire,hash)", - __LINE__))) + GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_expire_hash ON gn090 (expire,hash)"))) { PQclear (ret); PQfinish (plugin->dbh); @@ -238,8 +128,7 @@ init_connection (struct Plugin *plugin) PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -248,8 +137,7 @@ init_connection (struct Plugin *plugin) PQclear (ret); ret = PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -258,8 +146,7 @@ init_connection (struct Plugin *plugin) PQclear (ret); ret = PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -267,60 +154,56 @@ init_connection (struct Plugin *plugin) } PQclear (ret); if ((GNUNET_OK != - pq_prepare (plugin, "getvt", + GNUNET_POSTGRES_prepare (plugin->dbh, "getvt", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE hash=$1 AND vhash=$2 AND type=$3 " - "ORDER BY oid ASC LIMIT 1 OFFSET $4", 4, __LINE__)) || + "ORDER BY oid ASC LIMIT 1 OFFSET $4", 4)) || (GNUNET_OK != - pq_prepare (plugin, "gett", + GNUNET_POSTGRES_prepare (plugin->dbh, "gett", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE hash=$1 AND type=$2 " - "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3, __LINE__)) || + "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3)) || (GNUNET_OK != - pq_prepare (plugin, "getv", + GNUNET_POSTGRES_prepare (plugin->dbh, "getv", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE hash=$1 AND vhash=$2 " - "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3, __LINE__)) || + "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3)) || (GNUNET_OK != - pq_prepare (plugin, "get", + GNUNET_POSTGRES_prepare (plugin->dbh, "get", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " - "WHERE hash=$1 " "ORDER BY oid ASC LIMIT 1 OFFSET $2", 2, - __LINE__)) || + "WHERE hash=$1 " "ORDER BY oid ASC LIMIT 1 OFFSET $2", 2)) || (GNUNET_OK != - pq_prepare (plugin, "put", + GNUNET_POSTGRES_prepare (plugin->dbh, "put", "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) " - "VALUES ($1, $2, $3, $4, $5, RANDOM(), $6, $7, $8)", 9, - __LINE__)) || + "VALUES ($1, $2, $3, $4, $5, RANDOM(), $6, $7, $8)", 9)) || (GNUNET_OK != - pq_prepare (plugin, "update", + GNUNET_POSTGRES_prepare (plugin->dbh, "update", "UPDATE gn090 SET prio = prio + $1, expire = CASE WHEN expire < $2 THEN $2 ELSE expire END " - "WHERE oid = $3", 3, __LINE__)) || + "WHERE oid = $3", 3)) || (GNUNET_OK != - pq_prepare (plugin, "decrepl", + GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl", "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " - "WHERE oid = $1", 1, __LINE__)) || + "WHERE oid = $1", 1)) || (GNUNET_OK != - pq_prepare (plugin, "select_non_anonymous", + GNUNET_POSTGRES_prepare (plugin->dbh, "select_non_anonymous", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE anonLevel = 0 AND type = $1 ORDER BY oid DESC LIMIT 1 OFFSET $2", - 1, __LINE__)) || + 1)) || (GNUNET_OK != - pq_prepare (plugin, "select_expiration_order", + GNUNET_POSTGRES_prepare (plugin->dbh, "select_expiration_order", "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) " "UNION " "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " "ORDER BY prio ASC LIMIT 1) " "ORDER BY expire ASC LIMIT 1", - 1, __LINE__)) || + 1)) || (GNUNET_OK != - pq_prepare (plugin, "select_replication_order", + GNUNET_POSTGRES_prepare (plugin->dbh, "select_replication_order", "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " - "ORDER BY repl DESC,RANDOM() LIMIT 1", 0, __LINE__)) || + "ORDER BY repl DESC,RANDOM() LIMIT 1", 0)) || (GNUNET_OK != - pq_prepare (plugin, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1, - __LINE__)) || + GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1)) || (GNUNET_OK != - pq_prepare (plugin, "get_keys", "SELECT hash FROM gn090", 0, - __LINE__))) + GNUNET_POSTGRES_prepare (plugin->dbh, "get_keys", "SELECT hash FROM gn090", 0))) { PQfinish (plugin->dbh); plugin->dbh = NULL; @@ -331,38 +214,6 @@ init_connection (struct Plugin *plugin) /** - * Delete the row identified by the given rowid (qid - * in postgres). - * - * @param plugin global context - * @param rowid which row to delete - * @return GNUNET_OK on success - */ -static int -delete_by_rowid (struct Plugin *plugin, unsigned int rowid) -{ - uint32_t browid; - const char *paramValues[] = { (const char *) &browid }; - int paramLengths[] = { sizeof (browid) }; - const int paramFormats[] = { 1 }; - PGresult *ret; - - browid = htonl (rowid); - ret = - PQexecPrepared (plugin->dbh, "delrow", 1, paramValues, paramLengths, - paramFormats, 1); - if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "delrow", - __LINE__)) - { - return GNUNET_SYSERR; - } - PQclear (ret); - return GNUNET_OK; -} - - -/** * Get an estimate of how much space the database is * currently using. * @@ -381,18 +232,22 @@ postgres_plugin_estimate_size (void *cls) "SELECT SUM(LENGTH(value))+256*COUNT(*) FROM gn090", 0, NULL, NULL, NULL, NULL, 1); if (GNUNET_OK != - check_result (plugin, ret, PGRES_TUPLES_OK, "PQexecParams", "get_size", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_TUPLES_OK, "PQexecParams", "get_size")) { return 0; } - if ((PQntuples (ret) != 1) || (PQnfields (ret) != 1) || - (PQgetlength (ret, 0, 0) != sizeof (unsigned long long))) + if ((PQntuples (ret) != 1) || (PQnfields (ret) != 1) ) { GNUNET_break (0); PQclear (ret); return 0; } + if (PQgetlength (ret, 0, 0) != sizeof (unsigned long long)) + { + GNUNET_break (0 == PQgetlength (ret, 0, 0)); + PQclear (ret); + return 0; + } total = GNUNET_ntohll (*(const unsigned long long *) PQgetvalue (ret, 0, 0)); PQclear (ret); return total; @@ -402,7 +257,7 @@ postgres_plugin_estimate_size (void *cls) /** * Store an item in the datastore. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param key key for the item * @param size number of bytes in data * @param data content stored @@ -457,15 +312,12 @@ postgres_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, PQexecPrepared (plugin->dbh, "put", 8, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put")) return GNUNET_SYSERR; PQclear (ret); plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD); -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Stored %u bytes in database\n", (unsigned int) size); -#endif return GNUNET_OK; } @@ -478,11 +330,13 @@ postgres_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, * @param proc function to call the value (once only). * @param proc_cls closure for proc * @param res result from exec + * @param filename filename for error messages * @param line line number for error messages */ static void process_result (struct Plugin *plugin, PluginDatumProcessor proc, - void *proc_cls, PGresult * res, int line) + void *proc_cls, PGresult * res, + const char *filename, int line) { int iret; enum GNUNET_BLOCK_Type type; @@ -494,13 +348,11 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, GNUNET_HashCode key; if (GNUNET_OK != - check_result (plugin, res, PGRES_TUPLES_OK, "PQexecPrepared", "select", - line)) + GNUNET_POSTGRES_check_result_ (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "select", + filename, line)) { -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Ending iteration (postgres error)\n"); -#endif proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } @@ -508,10 +360,8 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, if (0 == PQntuples (res)) { /* no result */ -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Ending iteration (no more results)\n"); -#endif proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); PQclear (res); return; @@ -534,7 +384,7 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, { GNUNET_break (0); PQclear (res); - delete_by_rowid (plugin, rowid); + GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", rowid); proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } @@ -546,11 +396,9 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, 0, 3)); memcpy (&key, PQgetvalue (res, 0, 4), sizeof (GNUNET_HashCode)); size = PQgetlength (res, 0, 5); -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Found result of size %u bytes and type %u in database\n", (unsigned int) size, (unsigned int) type); -#endif iret = proc (proc_cls, &key, size, PQgetvalue (res, 0, 5), (enum GNUNET_BLOCK_Type) type, priority, anonymity, expiration_time, @@ -558,23 +406,17 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, PQclear (res); if (iret == GNUNET_NO) { -#if DEBUG_POSTGRES GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processor asked for item %u to be removed.\n", rowid); -#endif - if (GNUNET_OK == delete_by_rowid (plugin, rowid)) + if (GNUNET_OK == GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", rowid)) { -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Deleting %u bytes from database\n", (unsigned int) size); -#endif plugin->env->duc (plugin->env->cls, -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); -#if DEBUG_POSTGRES GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datastore-postgres", "Deleted %u bytes from database\n", (unsigned int) size); -#endif } } } @@ -584,7 +426,7 @@ process_result (struct Plugin *plugin, PluginDatumProcessor proc, * Iterate over the results for a particular key * in the datastore. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param offset offset of the result (modulo num-results); * specific ordering does not matter for the offset * @param key maybe NULL (to match all entries) @@ -679,8 +521,7 @@ postgres_plugin_get_key (void *cls, uint64_t offset, } } if (GNUNET_OK != - check_result (plugin, ret, PGRES_TUPLES_OK, "PQexecParams", pname, - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_TUPLES_OK, "PQexecParams", pname)) { proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; @@ -704,7 +545,7 @@ postgres_plugin_get_key (void *cls, uint64_t offset, ret = PQexecPrepared (plugin->dbh, pname, nparams, paramValues, paramLengths, paramFormats, 1); - process_result (plugin, proc, proc_cls, ret, __LINE__); + process_result (plugin, proc, proc_cls, ret, __FILE__, __LINE__); } @@ -739,7 +580,7 @@ postgres_plugin_get_zero_anonymity (void *cls, uint64_t offset, ret = PQexecPrepared (plugin->dbh, "select_non_anonymous", 2, paramValues, paramLengths, paramFormats, 1); - process_result (plugin, proc, proc_cls, ret, __LINE__); + process_result (plugin, proc, proc_cls, ret, __FILE__, __LINE__); } @@ -771,7 +612,7 @@ struct ReplCtx * Decrements the replication counter and calls the original * iterator. * - * @param cls closure + * @param cls closure with the 'struct ReplCtx*' * @param key key for the content * @param size number of bytes in data * @param data content stored @@ -815,8 +656,8 @@ repl_proc (void *cls, const GNUNET_HashCode * key, uint32_t size, PQexecPrepared (plugin->dbh, "decrepl", 1, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, qret, PGRES_COMMAND_OK, "PQexecPrepared", - "decrepl", __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, qret, PGRES_COMMAND_OK, "PQexecPrepared", + "decrepl")) return GNUNET_SYSERR; PQclear (qret); } @@ -830,7 +671,7 @@ repl_proc (void *cls, const GNUNET_HashCode * key, uint32_t size, * replication counter is decremented by one IF it was positive before. * Call 'proc' with all values ZERO or NULL if the datastore is empty. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param proc function to call the value (once only). * @param proc_cls closure for proc */ @@ -848,7 +689,7 @@ postgres_plugin_get_replication (void *cls, PluginDatumProcessor proc, ret = PQexecPrepared (plugin->dbh, "select_replication_order", 0, NULL, NULL, NULL, 1); - process_result (plugin, &repl_proc, &rc, ret, __LINE__); + process_result (plugin, &repl_proc, &rc, ret, __FILE__, __LINE__); } @@ -856,7 +697,7 @@ postgres_plugin_get_replication (void *cls, PluginDatumProcessor proc, * Get a random item for expiration. * Call 'proc' with all values ZERO or NULL if the datastore is empty. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param proc function to call the value (once only). * @param proc_cls closure for proc */ @@ -875,7 +716,7 @@ postgres_plugin_get_expiration (void *cls, PluginDatumProcessor proc, ret = PQexecPrepared (plugin->dbh, "select_expiration_order", 1, paramValues, paramLengths, paramFormats, 1); - process_result (plugin, proc, proc_cls, ret, __LINE__); + process_result (plugin, proc, proc_cls, ret, __FILE__, __LINE__); } @@ -928,8 +769,7 @@ postgres_plugin_update (void *cls, uint64_t uid, int delta, PQexecPrepared (plugin->dbh, "update", 3, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != - check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "update", - __LINE__)) + GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "update")) return GNUNET_SYSERR; PQclear (ret); return GNUNET_OK; @@ -940,7 +780,7 @@ postgres_plugin_update (void *cls, uint64_t uid, int delta, /** * Get all of the keys in the datastore. * - * @param cls closure + * @param cls closure with the 'struct Plugin' * @param proc function to call on each key * @param proc_cls closure for proc */ @@ -972,13 +812,16 @@ postgres_plugin_get_keys (void *cls, /** * Drop database. + * + * @param cls closure with the 'struct Plugin' */ static void postgres_plugin_drop (void *cls) { struct Plugin *plugin = cls; - - pq_exec (plugin, "DROP TABLE gn090", __LINE__); + + if (GNUNET_OK != GNUNET_POSTGRES_exec (plugin->dbh, "DROP TABLE gn090")) + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "postgres", _("Failed to drop table from database.\n")); } diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c index cd5ae39..00195fb 100644 --- a/src/datastore/plugin_datastore_sqlite.c +++ b/src/datastore/plugin_datastore_sqlite.c @@ -28,10 +28,6 @@ #include "gnunet_datastore_plugin.h" #include <sqlite3.h> -/** - * Enable or disable logging debug messages. - */ -#define DEBUG_SQLITE GNUNET_EXTRA_LOGGING /** * We allocate items on the stack at times. To prevent a stack @@ -147,10 +143,8 @@ sq_prepare (sqlite3 * dbh, const char *zSql, sqlite3_stmt ** ppStmt) result = sqlite3_prepare_v2 (dbh, zSql, strlen (zSql), ppStmt, (const char **) &dummy); -#if DEBUG_SQLITE && 0 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Prepared `%s' / %p: %d\n", zSql, *ppStmt, result); -#endif return result; } @@ -415,10 +409,8 @@ database_shutdown (struct Plugin *plugin) stmt = sqlite3_next_stmt (plugin->dbh, NULL); while (stmt != NULL) { -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Closing statement %p\n", stmt); -#endif result = sqlite3_finalize (stmt); if (result != SQLITE_OK) GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite", @@ -502,14 +494,12 @@ sqlite_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, if (size > MAX_ITEM_SIZE) return GNUNET_SYSERR; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Storing in database block with type %u/key `%s'/priority %u/expiration in %llu ms (%lld).\n", type, GNUNET_h2s (key), priority, (unsigned long long) GNUNET_TIME_absolute_get_remaining (expiration).rel_value, (long long) expiration.abs_value); -#endif GNUNET_CRYPTO_hash (data, size, &vhash); stmt = plugin->insertContent; rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); @@ -540,11 +530,9 @@ sqlite_plugin_put (void *cls, const GNUNET_HashCode * key, uint32_t size, { case SQLITE_DONE: plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD); -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Stored new entry (%u bytes)\n", size + GNUNET_DATASTORE_ENTRY_OVERHEAD); -#endif ret = GNUNET_OK; break; case SQLITE_BUSY: @@ -621,9 +609,7 @@ sqlite_plugin_update (void *cls, uint64_t uid, int delta, switch (n) { case SQLITE_DONE: -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Block updated\n"); -#endif return GNUNET_OK; case SQLITE_BUSY: LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, @@ -677,11 +663,9 @@ execute_get (struct Plugin *plugin, sqlite3_stmt * stmt, break; } expiration.abs_value = sqlite3_column_int64 (stmt, 3); -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Found reply in database with expiration %llu\n", (unsigned long long) expiration.abs_value); -#endif ret = proc (proc_cls, sqlite3_column_blob (stmt, 4) /* key */ , size, sqlite3_column_blob (stmt, 5) /* data */ , sqlite3_column_int (stmt, 0) /* type */ , @@ -972,10 +956,8 @@ sqlite_plugin_get_replication (void *cls, PluginDatumProcessor proc, uint32_t repl; sqlite3_stmt *stmt; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Getting random block based on replication order.\n"); -#endif rc.have_uid = GNUNET_NO; rc.proc = proc; rc.proc_cls = proc_cls; @@ -1061,10 +1043,8 @@ sqlite_plugin_get_expiration (void *cls, PluginDatumProcessor proc, sqlite3_stmt *stmt; struct GNUNET_TIME_Absolute now; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Getting random block based on expiration and priority order.\n"); -#endif now = GNUNET_TIME_absolute_get (); stmt = plugin->selExpi; if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, now.abs_value)) @@ -1233,18 +1213,13 @@ libgnunet_plugin_datastore_sqlite_done (void *cls) struct GNUNET_DATASTORE_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "sqlite plugin is done\n"); -#endif - fn = NULL; if (plugin->drop_on_shutdown) fn = GNUNET_strdup (plugin->fn); -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Shutting down database\n"); -#endif database_shutdown (plugin); plugin->env = NULL; GNUNET_free (api); @@ -1254,10 +1229,8 @@ libgnunet_plugin_datastore_sqlite_done (void *cls) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); GNUNET_free (fn); } -#if DEBUG_SQLITE GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "sqlite plugin is finished\n"); -#endif return NULL; } diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c index 25836ca..4c07366 100644 --- a/src/datastore/test_datastore_api.c +++ b/src/datastore/test_datastore_api.c @@ -462,12 +462,14 @@ run_tests (void *cls, int32_t success, struct GNUNET_TIME_Absolute min_expiratio return; case GNUNET_NO: FPRINTF (stderr, "%s", "Test 'put' operation failed, key already exists (!?)\n"); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; case GNUNET_SYSERR: FPRINTF (stderr, "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", msg); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; default: @@ -544,7 +546,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; #endif if (ok != 0) diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c index 4015c2c..bb3898e 100644 --- a/src/datastore/test_datastore_api_management.c +++ b/src/datastore/test_datastore_api_management.c @@ -253,8 +253,9 @@ run_tests (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, c if (success != GNUNET_YES) { FPRINTF (stderr, - "Test 'put' operation failed with error `%s' database likely not setup, skipping test.", + "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", msg); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); return; } @@ -328,7 +329,7 @@ check () ok = 1; } GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); proc = NULL; if (ok != 0) FPRINTF (stderr, "Missed some testcases: %u\n", ok); diff --git a/src/datastore/test_defaults.conf b/src/datastore/test_defaults.conf index 113d6bb..ce27c01 100644 --- a/src/datastore/test_defaults.conf +++ b/src/datastore/test_defaults.conf @@ -28,3 +28,6 @@ AUTOSTART = NO [dv] AUTOSTART = NO + +[namestore] +AUTOSTART = NO |