aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/plugin_datastore_postgres.c
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amat.us>2017-04-16 12:39:43 -0500
committerDavid Barksdale <amatus@amat.us>2017-04-16 12:42:34 -0500
commit4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch)
treea2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore/plugin_datastore_postgres.c
parentcacd64d8635201459e59bf2cd8a2ea8fd0699b84 (diff)
[datastore] Combine put and update plugin APIs
This resolves issue #4965.
Diffstat (limited to 'src/datastore/plugin_datastore_postgres.c')
-rw-r--r--src/datastore/plugin_datastore_postgres.c129
1 files changed, 57 insertions, 72 deletions
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c
index 87a7acbdc9..349848ae67 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -195,8 +195,8 @@ init_connection (struct Plugin *plugin)
"UPDATE gn090 "
"SET prio = prio + $1, "
"repl = repl + $2, "
- "expire = CASE WHEN expire < $3 THEN $3 ELSE expire END "
- "WHERE oid = $4", 4)) ||
+ "expire = GREATEST(expire, $3) "
+ "WHERE hash = $4 AND vhash = $5", 5)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl",
"UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
@@ -288,6 +288,7 @@ postgres_plugin_estimate_size (void *cls, unsigned long long *estimate)
*
* @param cls closure with the `struct Plugin`
* @param key key for the item
+ * @param absent true if the key was not found in the bloom filter
* @param size number of bytes in data
* @param data content stored
* @param type type of the content
@@ -300,23 +301,70 @@ postgres_plugin_estimate_size (void *cls, unsigned long long *estimate)
*/
static void
postgres_plugin_put (void *cls,
- const struct GNUNET_HashCode *key,
- uint32_t size,
+ const struct GNUNET_HashCode *key,
+ bool absent,
+ uint32_t size,
const void *data,
- enum GNUNET_BLOCK_Type type,
+ enum GNUNET_BLOCK_Type type,
uint32_t priority,
- uint32_t anonymity,
+ uint32_t anonymity,
uint32_t replication,
struct GNUNET_TIME_Absolute expiration,
- PluginPutCont cont,
+ PluginPutCont cont,
void *cont_cls)
{
struct Plugin *plugin = cls;
- uint32_t utype = type;
struct GNUNET_HashCode vhash;
+ PGresult *ret;
+
+ GNUNET_CRYPTO_hash (data,
+ size,
+ &vhash);
+
+ if (!absent)
+ {
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint32 (&priority),
+ GNUNET_PQ_query_param_uint32 (&replication),
+ GNUNET_PQ_query_param_absolute_time (&expiration),
+ GNUNET_PQ_query_param_auto_from_type (key),
+ GNUNET_PQ_query_param_auto_from_type (&vhash),
+ GNUNET_PQ_query_param_end
+ };
+ ret = GNUNET_PQ_exec_prepared (plugin->dbh,
+ "update",
+ params);
+ if (GNUNET_OK !=
+ GNUNET_POSTGRES_check_result (plugin->dbh,
+ ret,
+ PGRES_COMMAND_OK,
+ "PQexecPrepared",
+ "update"))
+ {
+ cont (cont_cls,
+ key,
+ size,
+ GNUNET_SYSERR,
+ _("Postgress exec failure"));
+ return;
+ }
+ /* What an awful API, this function really does return a string */
+ bool affected = 0 != strcmp ("0", PQcmdTuples (ret));
+ PQclear (ret);
+ if (affected)
+ {
+ cont (cont_cls,
+ key,
+ size,
+ GNUNET_NO,
+ NULL);
+ return;
+ }
+ }
+
+ uint32_t utype = type;
uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
UINT64_MAX);
- PGresult *ret;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint32 (&replication),
GNUNET_PQ_query_param_uint32 (&utype),
@@ -330,7 +378,6 @@ postgres_plugin_put (void *cls,
GNUNET_PQ_query_param_end
};
- GNUNET_CRYPTO_hash (data, size, &vhash);
ret = GNUNET_PQ_exec_prepared (plugin->dbh,
"put",
params);
@@ -750,67 +797,6 @@ postgres_plugin_get_expiration (void *cls,
/**
- * Update the priority, replication and expiration for a particular
- * unique ID in the datastore. If the expiration time in value is
- * different than the time found in the datastore, the higher value
- * should be kept. The specified priority and replication is added
- * to the existing value.
- *
- * @param cls our `struct Plugin *`
- * @param uid unique identifier of the datum
- * @param priority by how much should the priority
- * change?
- * @param replication by how much should the replication
- * change?
- * @param expire new expiration time should be the
- * MAX of any existing expiration time and
- * this value
- * @param cont continuation called with success or failure status
- * @param cons_cls continuation closure
- */
-static void
-postgres_plugin_update (void *cls,
- uint64_t uid,
- uint32_t priority,
- uint32_t replication,
- struct GNUNET_TIME_Absolute expire,
- PluginUpdateCont cont,
- void *cont_cls)
-{
- struct Plugin *plugin = cls;
- uint32_t oid = (uint32_t) uid;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint32 (&priority),
- GNUNET_PQ_query_param_uint32 (&replication),
- GNUNET_PQ_query_param_absolute_time (&expire),
- GNUNET_PQ_query_param_uint32 (&oid),
- GNUNET_PQ_query_param_end
- };
- PGresult *ret;
-
- ret = GNUNET_PQ_exec_prepared (plugin->dbh,
- "update",
- params);
- if (GNUNET_OK !=
- GNUNET_POSTGRES_check_result (plugin->dbh,
- ret,
- PGRES_COMMAND_OK,
- "PQexecPrepared",
- "update"))
- {
- cont (cont_cls,
- GNUNET_SYSERR,
- NULL);
- return;
- }
- PQclear (ret);
- cont (cont_cls,
- GNUNET_OK,
- NULL);
-}
-
-
-/**
* Get all of the keys in the datastore.
*
* @param cls closure with the `struct Plugin *`
@@ -891,7 +877,6 @@ libgnunet_plugin_datastore_postgres_init (void *cls)
api->cls = plugin;
api->estimate_size = &postgres_plugin_estimate_size;
api->put = &postgres_plugin_put;
- api->update = &postgres_plugin_update;
api->get_key = &postgres_plugin_get_key;
api->get_replication = &postgres_plugin_get_replication;
api->get_expiration = &postgres_plugin_get_expiration;