*/
#include "platform.h"
#include "gnunet_util_lib.h"
-#include "plugin_datacache.h"
+#include "gnunet_datacache_plugin.h"
#include <postgresql/libpq-fe.h>
#define DEBUG_POSTGRES GNUNET_NO
-
+/**
+ * Per-entry overhead estimate
+ */
+#define OVERHEAD (sizeof(GNUNET_HashCode) + 24)
/**
* Context for all functions in this plugin.
PGresult *ret;
/* Open database and precompile statements */
- conninfo = NULL;
- GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg,
- "datacache-postgres",
- "CONFIG",
- &conninfo);
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg,
+ "datacache-postgres",
+ "CONFIG",
+ &conninfo))
+ conninfo = NULL;
plugin->dbh = PQconnectdb (conninfo == NULL ? "" : conninfo);
GNUNET_free_non_null (conninfo);
if (NULL == plugin->dbh)
(ret,
PG_DIAG_SQLSTATE)))))
{
- check_result (plugin,
- ret, PGRES_COMMAND_OK, "CREATE TABLE", "gn090dc", __LINE__);
+ (void) check_result (plugin,
+ ret, PGRES_COMMAND_OK, "CREATE TABLE", "gn090dc", __LINE__);
PQfinish (plugin->dbh);
plugin->dbh = NULL;
return GNUNET_SYSERR;
(GNUNET_OK !=
pq_prepare (plugin,
"getm",
- "SELECT length(value),oid FROM gn090dc "
+ "SELECT length(value),oid,key FROM gn090dc "
"ORDER BY discard_time ASC LIMIT 1",
0,
__LINE__)) ||
*/
static int
delete_by_rowid (struct Plugin *plugin,
- unsigned int rowid)
+ uint32_t rowid)
{
- const char *paramValues[] = { (const char *) &rowid };
- int paramLengths[] = { sizeof (rowid) };
+ uint32_t brow = htonl (rowid);
+ const char *paramValues[] = { (const char *) &brow };
+ int paramLengths[] = { sizeof (brow) };
const int paramFormats[] = { 1 };
PGresult *ret;
* @param discard_time when to discard the value in any case
* @return 0 on error, number of bytes used otherwise
*/
-static uint32_t
+static size_t
postgres_plugin_put (void *cls,
const GNUNET_HashCode * key,
- uint32_t size,
+ size_t size,
const char *data,
enum GNUNET_BLOCK_Type type,
struct GNUNET_TIME_Absolute discard_time)
struct Plugin *plugin = cls;
PGresult *ret;
uint32_t btype = htonl (type);
- uint64_t bexpi = GNUNET_TIME_absolute_hton (discard_time).value__;
+ uint64_t bexpi = GNUNET_TIME_absolute_hton (discard_time).abs_value__;
const char *paramValues[] = {
(const char *) &btype,
(const char *) &bexpi,
"PQexecPrepared", "put", __LINE__))
return GNUNET_SYSERR;
PQclear (ret);
- return size;
+ return size + OVERHEAD;
}
PQclear (res);
return 0;
}
+ if (iter == NULL)
+ {
+ PQclear (res);
+ return cnt;
+ }
if ( (3 != PQnfields (res)) ||
(sizeof (uint64_t) != PQfsize (res, 0)) ||
(sizeof (uint32_t) != PQfsize (res, 1)))
}
for (i=0;i<cnt;i++)
{
- expiration_time.value = GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0));
+ expiration_time.abs_value = GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0));
type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1));
size = PQgetlength (res, i, 2);
#if DEBUG_POSTGRES
static int
postgres_plugin_del (void *cls)
{
-
- GNUNET_break (0);
- return GNUNET_SYSERR;
+ struct Plugin *plugin = cls;
+ uint32_t size;
+ uint32_t oid;
+ GNUNET_HashCode key;
+ PGresult *res;
+
+ res = PQexecPrepared (plugin->dbh,
+ "getm",
+ 0, NULL, NULL, NULL,
+ 1);
+ if (GNUNET_OK != check_result (plugin,
+ res,
+ PGRES_TUPLES_OK,
+ "PQexecPrepared",
+ "getm",
+ __LINE__))
+ {
+#if DEBUG_POSTGRES
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+ "datacache-postgres",
+ "Ending iteration (postgres error)\n");
+#endif
+ return 0;
+ }
+ if (0 == PQntuples (res))
+ {
+ /* no result */
+#if DEBUG_POSTGRES
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+ "datacache-postgres",
+ "Ending iteration (no more results)\n");
+#endif
+ PQclear (res);
+ return GNUNET_SYSERR;
+ }
+ if ( (3 != PQnfields (res)) ||
+ (sizeof (size) != PQfsize (res, 0)) ||
+ (sizeof (oid) != PQfsize (res, 1)) ||
+ (sizeof (GNUNET_HashCode) != PQgetlength (res, 0, 2)) )
+ {
+ GNUNET_break (0);
+ PQclear (res);
+ return 0;
+ }
+ size = ntohl (*(uint32_t *) PQgetvalue (res, 0, 0));
+ oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1));
+ memcpy (&key,
+ PQgetvalue (res, 0, 2),
+ sizeof (GNUNET_HashCode));
+ PQclear (res);
+ if (GNUNET_OK != delete_by_rowid (plugin, oid))
+ return GNUNET_SYSERR;
+ plugin->env->delete_notify (plugin->env->cls,
+ &key,
+ size + OVERHEAD);
+ return GNUNET_OK;
}
struct GNUNET_DATACACHE_PluginFunctions *api = cls;
struct Plugin *plugin = api->cls;
+ PQfinish (plugin->dbh);
GNUNET_free (plugin);
GNUNET_free (api);
return NULL;