diff options
author | David Barksdale <amatus@amat.us> | 2017-04-16 12:39:43 -0500 |
---|---|---|
committer | David Barksdale <amatus@amat.us> | 2017-04-16 12:42:34 -0500 |
commit | 4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch) | |
tree | a2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore/plugin_datastore_postgres.c | |
parent | cacd64d8635201459e59bf2cd8a2ea8fd0699b84 (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.c | 129 |
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; |