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)
downloadgnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.tar.gz
gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.zip
[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 87a7acbdc..349848ae6 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -195,8 +195,8 @@ init_connection (struct Plugin *plugin)
195 "UPDATE gn090 " 195 "UPDATE gn090 "
196 "SET prio = prio + $1, " 196 "SET prio = prio + $1, "
197 "repl = repl + $2, " 197 "repl = repl + $2, "
198 "expire = CASE WHEN expire < $3 THEN $3 ELSE expire END " 198 "expire = GREATEST(expire, $3) "
199 "WHERE oid = $4", 4)) || 199 "WHERE hash = $4 AND vhash = $5", 5)) ||
200 (GNUNET_OK != 200 (GNUNET_OK !=
201 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl", 201 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl",
202 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " 202 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
@@ -288,6 +288,7 @@ postgres_plugin_estimate_size (void *cls, unsigned long long *estimate)
288 * 288 *
289 * @param cls closure with the `struct Plugin` 289 * @param cls closure with the `struct Plugin`
290 * @param key key for the item 290 * @param key key for the item
291 * @param absent true if the key was not found in the bloom filter
291 * @param size number of bytes in data 292 * @param size number of bytes in data
292 * @param data content stored 293 * @param data content stored
293 * @param type type of the content 294 * @param type type of the content
@@ -300,23 +301,70 @@ postgres_plugin_estimate_size (void *cls, unsigned long long *estimate)
300 */ 301 */
301static void 302static void
302postgres_plugin_put (void *cls, 303postgres_plugin_put (void *cls,
303 const struct GNUNET_HashCode *key, 304 const struct GNUNET_HashCode *key,
304 uint32_t size, 305 bool absent,
306 uint32_t size,
305 const void *data, 307 const void *data,
306 enum GNUNET_BLOCK_Type type, 308 enum GNUNET_BLOCK_Type type,
307 uint32_t priority, 309 uint32_t priority,
308 uint32_t anonymity, 310 uint32_t anonymity,
309 uint32_t replication, 311 uint32_t replication,
310 struct GNUNET_TIME_Absolute expiration, 312 struct GNUNET_TIME_Absolute expiration,
311 PluginPutCont cont, 313 PluginPutCont cont,
312 void *cont_cls) 314 void *cont_cls)
313{ 315{
314 struct Plugin *plugin = cls; 316 struct Plugin *plugin = cls;
315 uint32_t utype = type;
316 struct GNUNET_HashCode vhash; 317 struct GNUNET_HashCode vhash;
318 PGresult *ret;
319
320 GNUNET_CRYPTO_hash (data,
321 size,
322 &vhash);
323
324 if (!absent)
325 {
326 struct GNUNET_PQ_QueryParam params[] = {
327 GNUNET_PQ_query_param_uint32 (&priority),
328 GNUNET_PQ_query_param_uint32 (&replication),
329 GNUNET_PQ_query_param_absolute_time (&expiration),
330 GNUNET_PQ_query_param_auto_from_type (key),
331 GNUNET_PQ_query_param_auto_from_type (&vhash),
332 GNUNET_PQ_query_param_end
333 };
334 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
335 "update",
336 params);
337 if (GNUNET_OK !=
338 GNUNET_POSTGRES_check_result (plugin->dbh,
339 ret,
340 PGRES_COMMAND_OK,
341 "PQexecPrepared",
342 "update"))
343 {
344 cont (cont_cls,
345 key,
346 size,
347 GNUNET_SYSERR,
348 _("Postgress exec failure"));
349 return;
350 }
351 /* What an awful API, this function really does return a string */
352 bool affected = 0 != strcmp ("0", PQcmdTuples (ret));
353 PQclear (ret);
354 if (affected)
355 {
356 cont (cont_cls,
357 key,
358 size,
359 GNUNET_NO,
360 NULL);
361 return;
362 }
363 }
364
365 uint32_t utype = type;
317 uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 366 uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
318 UINT64_MAX); 367 UINT64_MAX);
319 PGresult *ret;
320 struct GNUNET_PQ_QueryParam params[] = { 368 struct GNUNET_PQ_QueryParam params[] = {
321 GNUNET_PQ_query_param_uint32 (&replication), 369 GNUNET_PQ_query_param_uint32 (&replication),
322 GNUNET_PQ_query_param_uint32 (&utype), 370 GNUNET_PQ_query_param_uint32 (&utype),
@@ -330,7 +378,6 @@ postgres_plugin_put (void *cls,
330 GNUNET_PQ_query_param_end 378 GNUNET_PQ_query_param_end
331 }; 379 };
332 380
333 GNUNET_CRYPTO_hash (data, size, &vhash);
334 ret = GNUNET_PQ_exec_prepared (plugin->dbh, 381 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
335 "put", 382 "put",
336 params); 383 params);
@@ -750,67 +797,6 @@ postgres_plugin_get_expiration (void *cls,
750 797
751 798
752/** 799/**
753 * Update the priority, replication and expiration for a particular
754 * unique ID in the datastore. If the expiration time in value is
755 * different than the time found in the datastore, the higher value
756 * should be kept. The specified priority and replication is added
757 * to the existing value.
758 *
759 * @param cls our `struct Plugin *`
760 * @param uid unique identifier of the datum
761 * @param priority by how much should the priority
762 * change?
763 * @param replication by how much should the replication
764 * change?
765 * @param expire new expiration time should be the
766 * MAX of any existing expiration time and
767 * this value
768 * @param cont continuation called with success or failure status
769 * @param cons_cls continuation closure
770 */
771static void
772postgres_plugin_update (void *cls,
773 uint64_t uid,
774 uint32_t priority,
775 uint32_t replication,
776 struct GNUNET_TIME_Absolute expire,
777 PluginUpdateCont cont,
778 void *cont_cls)
779{
780 struct Plugin *plugin = cls;
781 uint32_t oid = (uint32_t) uid;
782 struct GNUNET_PQ_QueryParam params[] = {
783 GNUNET_PQ_query_param_uint32 (&priority),
784 GNUNET_PQ_query_param_uint32 (&replication),
785 GNUNET_PQ_query_param_absolute_time (&expire),
786 GNUNET_PQ_query_param_uint32 (&oid),
787 GNUNET_PQ_query_param_end
788 };
789 PGresult *ret;
790
791 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
792 "update",
793 params);
794 if (GNUNET_OK !=
795 GNUNET_POSTGRES_check_result (plugin->dbh,
796 ret,
797 PGRES_COMMAND_OK,
798 "PQexecPrepared",
799 "update"))
800 {
801 cont (cont_cls,
802 GNUNET_SYSERR,
803 NULL);
804 return;
805 }
806 PQclear (ret);
807 cont (cont_cls,
808 GNUNET_OK,
809 NULL);
810}
811
812
813/**
814 * Get all of the keys in the datastore. 800 * Get all of the keys in the datastore.
815 * 801 *
816 * @param cls closure with the `struct Plugin *` 802 * @param cls closure with the `struct Plugin *`
@@ -891,7 +877,6 @@ libgnunet_plugin_datastore_postgres_init (void *cls)
891 api->cls = plugin; 877 api->cls = plugin;
892 api->estimate_size = &postgres_plugin_estimate_size; 878 api->estimate_size = &postgres_plugin_estimate_size;
893 api->put = &postgres_plugin_put; 879 api->put = &postgres_plugin_put;
894 api->update = &postgres_plugin_update;
895 api->get_key = &postgres_plugin_get_key; 880 api->get_key = &postgres_plugin_get_key;
896 api->get_replication = &postgres_plugin_get_replication; 881 api->get_replication = &postgres_plugin_get_replication;
897 api->get_expiration = &postgres_plugin_get_expiration; 882 api->get_expiration = &postgres_plugin_get_expiration;