summaryrefslogtreecommitdiff
path: root/src/datastore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-06-04 00:52:25 +0200
committerChristian Grothoff <christian@grothoff.org>2017-06-04 00:52:25 +0200
commit61ef51d43a9069b5a2d680883b5d47c1fb237d82 (patch)
treeec8f0f49eef374d7e9e67959f28ba412a0d88aea /src/datastore
parent8f254866dc993d2e832ef12ea7b4179f87ab3bd9 (diff)
downloadgnunet-61ef51d43a9069b5a2d680883b5d47c1fb237d82.tar.gz
gnunet-61ef51d43a9069b5a2d680883b5d47c1fb237d82.zip
finish datastore pq refactoring
Diffstat (limited to 'src/datastore')
-rw-r--r--src/datastore/Makefile.am1
-rw-r--r--src/datastore/plugin_datastore_postgres.c483
2 files changed, 277 insertions, 207 deletions
diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am
index 9b8cf365f..240abbc67 100644
--- a/src/datastore/Makefile.am
+++ b/src/datastore/Makefile.am
@@ -148,7 +148,6 @@ libgnunet_plugin_datastore_postgres_la_SOURCES = \
148 plugin_datastore_postgres.c 148 plugin_datastore_postgres.c
149libgnunet_plugin_datastore_postgres_la_LIBADD = \ 149libgnunet_plugin_datastore_postgres_la_LIBADD = \
150 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 150 $(top_builddir)/src/statistics/libgnunetstatistics.la \
151 $(top_builddir)/src/postgres/libgnunetpostgres.la \
152 $(top_builddir)/src/pq/libgnunetpq.la \ 151 $(top_builddir)/src/pq/libgnunetpq.la \
153 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq 152 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq
154libgnunet_plugin_datastore_postgres_la_LDFLAGS = \ 153libgnunet_plugin_datastore_postgres_la_LDFLAGS = \
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c
index 7496aeacc..9380a56c0 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -23,10 +23,8 @@
23 * @brief postgres-based datastore backend 23 * @brief postgres-based datastore backend
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26
27#include "platform.h" 26#include "platform.h"
28#include "gnunet_datastore_plugin.h" 27#include "gnunet_datastore_plugin.h"
29#include "gnunet_postgres_lib.h"
30#include "gnunet_pq_lib.h" 28#include "gnunet_pq_lib.h"
31 29
32 30
@@ -152,6 +150,9 @@ init_connection (struct Plugin *plugin)
152 GNUNET_PQ_make_prepare ("get_keys", 150 GNUNET_PQ_make_prepare ("get_keys",
153 "SELECT hash FROM gn090", 151 "SELECT hash FROM gn090",
154 0), 152 0),
153 GNUNET_PQ_make_prepare ("estimate_size",
154 "SELECT SUM(LENGTH(value))+256*COUNT(*) AS total FROM gn090",
155 0),
155 GNUNET_PQ_PREPARED_STATEMENT_END 156 GNUNET_PQ_PREPARED_STATEMENT_END
156 }; 157 };
157#undef RESULT_COLUMNS 158#undef RESULT_COLUMNS
@@ -184,44 +185,32 @@ init_connection (struct Plugin *plugin)
184 * @return number of bytes used on disk 185 * @return number of bytes used on disk
185 */ 186 */
186static void 187static void
187postgres_plugin_estimate_size (void *cls, unsigned long long *estimate) 188postgres_plugin_estimate_size (void *cls,
189 unsigned long long *estimate)
188{ 190{
189 struct Plugin *plugin = cls; 191 struct Plugin *plugin = cls;
190 unsigned long long total; 192 uint64_t total;
191 PGresult *ret; 193 struct GNUNET_PQ_QueryParam params[] = {
194 GNUNET_PQ_query_param_end
195 };
196 struct GNUNET_PQ_ResultSpec rs[] = {
197 GNUNET_PQ_result_spec_uint64 ("total",
198 &total),
199 GNUNET_PQ_result_spec_end
200 };
201 enum GNUNET_PQ_QueryStatus ret;
192 202
193 if (NULL == estimate) 203 if (NULL == estimate)
194 return; 204 return;
195 ret = 205 ret = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
196 PQexecParams (plugin->dbh, 206 "estimate_size",
197 "SELECT SUM(LENGTH(value))+256*COUNT(*) FROM gn090", 0, 207 params,
198 NULL, NULL, NULL, NULL, 1); 208 rs);
199 if (GNUNET_OK != 209 if (GNUNET_PQ_STATUS_SUCCESS_ONE_RESULT != ret)
200 GNUNET_POSTGRES_check_result (plugin->dbh,
201 ret,
202 PGRES_TUPLES_OK,
203 "PQexecParams",
204 "get_size"))
205 { 210 {
206 *estimate = 0; 211 *estimate = 0LL;
207 return; 212 return;
208 } 213 }
209 if ((PQntuples (ret) != 1) || (PQnfields (ret) != 1) )
210 {
211 GNUNET_break (0);
212 PQclear (ret);
213 *estimate = 0;
214 return;
215 }
216 if (PQgetlength (ret, 0, 0) != sizeof (unsigned long long))
217 {
218 GNUNET_break (0 == PQgetlength (ret, 0, 0));
219 PQclear (ret);
220 *estimate = 0;
221 return;
222 }
223 total = GNUNET_ntohll (*(const unsigned long long *) PQgetvalue (ret, 0, 0));
224 PQclear (ret);
225 *estimate = total; 214 *estimate = total;
226} 215}
227 216
@@ -342,135 +331,150 @@ postgres_plugin_put (void *cls,
342 331
343 332
344/** 333/**
345 * Function invoked to process the result and call the processor. 334 * Closure for #process_result.
335 */
336struct ProcessResultContext
337{
338
339 /**
340 * The plugin handle.
341 */
342 struct Plugin *plugin;
343
344 /**
345 * Function to call on each result.
346 */
347 PluginDatumProcessor proc;
348
349 /**
350 * Closure for @e proc.
351 */
352 void *proc_cls;
353
354};
355
356
357/**
358 * Function invoked to process the result and call the processor of @a
359 * cls.
346 * 360 *
347 * @param plugin global plugin data 361 * @param cls our `struct ProcessResultContext`
348 * @param proc function to call the value (once only).
349 * @param proc_cls closure for proc
350 * @param res result from exec 362 * @param res result from exec
351 * @param filename filename for error messages 363 * @param num_results number of results in @a res
352 * @param line line number for error messages
353 */ 364 */
354static void 365static void
355process_result (struct Plugin *plugin, 366process_result (void *cls,
356 PluginDatumProcessor proc, 367 PGresult *res,
357 void *proc_cls, 368 unsigned int num_results)
358 PGresult * res,
359 const char *filename, int line)
360{ 369{
361 int iret; 370 struct ProcessResultContext *prc = cls;
362 uint32_t rowid; 371 struct Plugin *plugin = prc->plugin;
363 uint32_t utype;
364 uint32_t anonymity;
365 uint32_t replication;
366 uint32_t priority;
367 size_t size;
368 void *data;
369 struct GNUNET_TIME_Absolute expiration_time;
370 struct GNUNET_HashCode key;
371 struct GNUNET_PQ_ResultSpec rs[] = {
372 GNUNET_PQ_result_spec_uint32 ("repl", &replication),
373 GNUNET_PQ_result_spec_uint32 ("type", &utype),
374 GNUNET_PQ_result_spec_uint32 ("prio", &priority),
375 GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity),
376 GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
377 GNUNET_PQ_result_spec_auto_from_type ("hash", &key),
378 GNUNET_PQ_result_spec_variable_size ("value", &data, &size),
379 GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
380 GNUNET_PQ_result_spec_end
381 };
382 372
383 if (GNUNET_OK != 373 if (0 == num_results)
384 GNUNET_POSTGRES_check_result_ (plugin->dbh,
385 res,
386 PGRES_TUPLES_OK,
387 "PQexecPrepared",
388 "select",
389 filename, line))
390 {
391 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
392 "datastore-postgres",
393 "Ending iteration (postgres error)\n");
394 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
395 return;
396 }
397
398 if (0 == PQntuples (res))
399 { 374 {
400 /* no result */ 375 /* no result */
401 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 376 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
402 "datastore-postgres", 377 "datastore-postgres",
403 "Ending iteration (no more results)\n"); 378 "Ending iteration (no more results)\n");
404 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 379 prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
405 PQclear (res); 380 GNUNET_TIME_UNIT_ZERO_ABS, 0);
406 return; 381 return;
407 } 382 }
408 if (1 != PQntuples (res)) 383 if (1 != num_results)
409 { 384 {
410 GNUNET_break (0); 385 GNUNET_break (0);
411 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 386 prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
412 PQclear (res); 387 GNUNET_TIME_UNIT_ZERO_ABS, 0);
413 return; 388 return;
414 } 389 }
415 if (GNUNET_OK != 390 /* Technically we don't need the loop here, but nicer in case
416 GNUNET_PQ_extract_result (res, 391 we ever relax the condition above. */
417 rs, 392 for (unsigned int i=0;i<num_results;i++)
418 0))
419 { 393 {
420 GNUNET_break (0); 394 int iret;
421 PQclear (res); 395 uint32_t rowid;
422 GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, 396 uint32_t utype;
423 "delrow", 397 uint32_t anonymity;
424 rowid); 398 uint32_t replication;
425 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 399 uint32_t priority;
426 return; 400 size_t size;
427 } 401 void *data;
402 struct GNUNET_TIME_Absolute expiration_time;
403 struct GNUNET_HashCode key;
404 struct GNUNET_PQ_ResultSpec rs[] = {
405 GNUNET_PQ_result_spec_uint32 ("repl", &replication),
406 GNUNET_PQ_result_spec_uint32 ("type", &utype),
407 GNUNET_PQ_result_spec_uint32 ("prio", &priority),
408 GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity),
409 GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
410 GNUNET_PQ_result_spec_auto_from_type ("hash", &key),
411 GNUNET_PQ_result_spec_variable_size ("value", &data, &size),
412 GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
413 GNUNET_PQ_result_spec_end
414 };
428 415
429 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 416 if (GNUNET_OK !=
430 "datastore-postgres", 417 GNUNET_PQ_extract_result (res,
431 "Found result of size %u bytes and type %u in database\n", 418 rs,
432 (unsigned int) size, 419 i))
433 (unsigned int) utype);
434 iret = proc (proc_cls,
435 &key,
436 size,
437 data,
438 (enum GNUNET_BLOCK_Type) utype,
439 priority,
440 anonymity,
441 replication,
442 expiration_time,
443 rowid);
444 PQclear (res);
445 if (iret == GNUNET_NO)
446 {
447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
448 "Processor asked for item %u to be removed.\n",
449 (unsigned int) rowid);
450 if (GNUNET_OK ==
451 GNUNET_POSTGRES_delete_by_rowid (plugin->dbh,
452 "delrow",
453 rowid))
454 { 420 {
455 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 421 GNUNET_break (0);
456 "datastore-postgres", 422 prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
457 "Deleting %u bytes from database\n", 423 GNUNET_TIME_UNIT_ZERO_ABS, 0);
458 (unsigned int) size); 424 return;
459 plugin->env->duc (plugin->env->cls,
460 - (size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
461 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
462 "datastore-postgres",
463 "Deleted %u bytes from database\n",
464 (unsigned int) size);
465 } 425 }
466 } 426
427 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
428 "datastore-postgres",
429 "Found result of size %u bytes and type %u in database\n",
430 (unsigned int) size,
431 (unsigned int) utype);
432 iret = prc->proc (prc->proc_cls,
433 &key,
434 size,
435 data,
436 (enum GNUNET_BLOCK_Type) utype,
437 priority,
438 anonymity,
439 replication,
440 expiration_time,
441 rowid);
442 if (iret == GNUNET_NO)
443 {
444 struct GNUNET_PQ_QueryParam param[] = {
445 GNUNET_PQ_query_param_uint32 (&rowid),
446 GNUNET_PQ_query_param_end
447 };
448
449 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
450 "Processor asked for item %u to be removed.\n",
451 (unsigned int) rowid);
452 if (0 <
453 GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
454 "delrow",
455 param))
456 {
457 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
458 "datastore-postgres",
459 "Deleting %u bytes from database\n",
460 (unsigned int) size);
461 plugin->env->duc (plugin->env->cls,
462 - (size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
463 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
464 "datastore-postgres",
465 "Deleted %u bytes from database\n",
466 (unsigned int) size);
467 }
468 }
469 GNUNET_PQ_cleanup_result (rs);
470 } /* for (i) */
467} 471}
468 472
469 473
470/** 474/**
471 * Get one of the results for a particular key in the datastore. 475 * Get one of the results for a particular key in the datastore.
472 * 476 *
473 * @param cls closure with the 'struct Plugin' 477 * @param cls closure with the `struct Plugin`
474 * @param next_uid return the result with lowest uid >= next_uid 478 * @param next_uid return the result with lowest uid >= next_uid
475 * @param random if true, return a random result instead of using next_uid 479 * @param random if true, return a random result instead of using next_uid
476 * @param key maybe NULL (to match all entries) 480 * @param key maybe NULL (to match all entries)
@@ -505,7 +509,8 @@ postgres_plugin_get_key (void *cls,
505 GNUNET_PQ_query_param_uint16 (&use_type), 509 GNUNET_PQ_query_param_uint16 (&use_type),
506 GNUNET_PQ_query_param_end 510 GNUNET_PQ_query_param_end
507 }; 511 };
508 PGresult *ret; 512 struct ProcessResultContext prc;
513 enum GNUNET_PQ_QueryStatus res;
509 514
510 if (random) 515 if (random)
511 { 516 {
@@ -514,16 +519,21 @@ postgres_plugin_get_key (void *cls,
514 next_uid = 0; 519 next_uid = 0;
515 } 520 }
516 else 521 else
522 {
517 rvalue = 0; 523 rvalue = 0;
518 524 }
519 ret = GNUNET_PQ_exec_prepared (plugin->dbh, 525 prc.plugin = plugin;
520 "get", 526 prc.proc = proc;
521 params); 527 prc.proc_cls = proc_cls;
522 process_result (plugin, 528
523 proc, 529 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
524 proc_cls, 530 "get",
525 ret, 531 params,
526 __FILE__, __LINE__); 532 &process_result,
533 &prc);
534 if (0 > res)
535 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
536 GNUNET_TIME_UNIT_ZERO_ABS, 0);
527} 537}
528 538
529 539
@@ -553,16 +563,20 @@ postgres_plugin_get_zero_anonymity (void *cls,
553 GNUNET_PQ_query_param_uint64 (&next_uid), 563 GNUNET_PQ_query_param_uint64 (&next_uid),
554 GNUNET_PQ_query_param_end 564 GNUNET_PQ_query_param_end
555 }; 565 };
556 PGresult *ret; 566 struct ProcessResultContext prc;
557 567 enum GNUNET_PQ_QueryStatus res;
558 ret = GNUNET_PQ_exec_prepared (plugin->dbh, 568
559 "select_non_anonymous", 569 prc.plugin = plugin;
560 params); 570 prc.proc = proc;
561 571 prc.proc_cls = proc_cls;
562 process_result (plugin, 572 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
563 proc, proc_cls, 573 "select_non_anonymous",
564 ret, 574 params,
565 __FILE__, __LINE__); 575 &process_result,
576 &prc);
577 if (0 > res)
578 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
579 GNUNET_TIME_UNIT_ZERO_ABS, 0);
566} 580}
567 581
568 582
@@ -630,7 +644,7 @@ repl_proc (void *cls,
630 GNUNET_PQ_query_param_uint32 (&oid), 644 GNUNET_PQ_query_param_uint32 (&oid),
631 GNUNET_PQ_query_param_end 645 GNUNET_PQ_query_param_end
632 }; 646 };
633 PGresult *qret; 647 enum GNUNET_PQ_QueryStatus qret;
634 648
635 ret = rc->proc (rc->proc_cls, 649 ret = rc->proc (rc->proc_cls,
636 key, 650 key,
@@ -644,17 +658,11 @@ repl_proc (void *cls,
644 uid); 658 uid);
645 if (NULL == key) 659 if (NULL == key)
646 return ret; 660 return ret;
647 qret = GNUNET_PQ_exec_prepared (plugin->dbh, 661 qret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
648 "decrepl", 662 "decrepl",
649 params); 663 params);
650 if (GNUNET_OK != 664 if (0 > qret)
651 GNUNET_POSTGRES_check_result (plugin->dbh,
652 qret,
653 PGRES_COMMAND_OK,
654 "PQexecPrepared",
655 "decrepl"))
656 return GNUNET_SYSERR; 665 return GNUNET_SYSERR;
657 PQclear (qret);
658 return ret; 666 return ret;
659} 667}
660 668
@@ -676,20 +684,27 @@ postgres_plugin_get_replication (void *cls,
676 void *proc_cls) 684 void *proc_cls)
677{ 685{
678 struct Plugin *plugin = cls; 686 struct Plugin *plugin = cls;
687 struct GNUNET_PQ_QueryParam params[] = {
688 GNUNET_PQ_query_param_end
689 };
679 struct ReplCtx rc; 690 struct ReplCtx rc;
680 PGresult *ret; 691 struct ProcessResultContext prc;
692 enum GNUNET_PQ_QueryStatus res;
681 693
682 rc.plugin = plugin; 694 rc.plugin = plugin;
683 rc.proc = proc; 695 rc.proc = proc;
684 rc.proc_cls = proc_cls; 696 rc.proc_cls = proc_cls;
685 ret = PQexecPrepared (plugin->dbh, 697 prc.plugin = plugin;
686 "select_replication_order", 0, NULL, NULL, 698 prc.proc = &repl_proc;
687 NULL, 1); 699 prc.proc_cls = &rc;
688 process_result (plugin, 700 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
689 &repl_proc, 701 "select_replication_order",
690 &rc, 702 params,
691 ret, 703 &process_result,
692 __FILE__, __LINE__); 704 &prc);
705 if (0 > res)
706 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
707 GNUNET_TIME_UNIT_ZERO_ABS, 0);
693} 708}
694 709
695 710
@@ -712,16 +727,75 @@ postgres_plugin_get_expiration (void *cls,
712 GNUNET_PQ_query_param_absolute_time (&now), 727 GNUNET_PQ_query_param_absolute_time (&now),
713 GNUNET_PQ_query_param_end 728 GNUNET_PQ_query_param_end
714 }; 729 };
715 PGresult *ret; 730 struct ProcessResultContext prc;
716 731
717 now = GNUNET_TIME_absolute_get (); 732 now = GNUNET_TIME_absolute_get ();
718 ret = GNUNET_PQ_exec_prepared (plugin->dbh, 733 prc.plugin = plugin;
719 "select_expiration_order", 734 prc.proc = proc;
720 params); 735 prc.proc_cls = proc_cls;
721 process_result (plugin, 736 (void) GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
722 proc, proc_cls, 737 "select_expiration_order",
723 ret, 738 params,
724 __FILE__, __LINE__); 739 &process_result,
740 &prc);
741}
742
743
744/**
745 * Closure for #process_keys.
746 */
747struct ProcessKeysContext
748{
749
750 /**
751 * Function to call for each key.
752 */
753 PluginKeyProcessor proc;
754
755 /**
756 * Closure for @e proc.
757 */
758 void *proc_cls;
759};
760
761
762/**
763 * Function to be called with the results of a SELECT statement
764 * that has returned @a num_results results.
765 *
766 * @param cls closure with a `struct ProcessKeysContext`
767 * @param result the postgres result
768 * @param num_result the number of results in @a result
769 */
770static void
771process_keys (void *cls,
772 PGresult *result,
773 unsigned int num_results)
774{
775 struct ProcessKeysContext *pkc = cls;
776
777 for (unsigned i=0;i<num_results;i++)
778 {
779 struct GNUNET_HashCode key;
780 struct GNUNET_PQ_ResultSpec rs[] = {
781 GNUNET_PQ_result_spec_auto_from_type ("hash",
782 &key),
783 GNUNET_PQ_result_spec_end
784 };
785
786 if (GNUNET_OK !=
787 GNUNET_PQ_extract_result (result,
788 rs,
789 i))
790 {
791 GNUNET_break (0);
792 continue;
793 }
794 pkc->proc (pkc->proc_cls,
795 &key,
796 1);
797 GNUNET_PQ_cleanup_result (rs);
798 }
725} 799}
726 800
727 801
@@ -738,28 +812,21 @@ postgres_plugin_get_keys (void *cls,
738 void *proc_cls) 812 void *proc_cls)
739{ 813{
740 struct Plugin *plugin = cls; 814 struct Plugin *plugin = cls;
741 int ret; 815 struct GNUNET_PQ_QueryParam params[] = {
742 int i; 816 GNUNET_PQ_query_param_end
743 struct GNUNET_HashCode key; 817 };
744 PGresult * res; 818 struct ProcessKeysContext pkc;
745 819
746 res = PQexecPrepared (plugin->dbh, 820 pkc.proc = proc;
747 "get_keys", 821 pkc.proc_cls = proc_cls;
748 0, NULL, NULL, NULL, 1); 822 (void) GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
749 ret = PQntuples (res); 823 "get_keys",
750 for (i=0;i<ret;i++) 824 params,
751 { 825 &process_keys,
752 if (sizeof (struct GNUNET_HashCode) != 826 &pkc);
753 PQgetlength (res, i, 0)) 827 proc (proc_cls,
754 { 828 NULL,
755 GNUNET_memcpy (&key, 829 0);
756 PQgetvalue (res, i, 0),
757 sizeof (struct GNUNET_HashCode));
758 proc (proc_cls, &key, 1);
759 }
760 }
761 PQclear (res);
762 proc (proc_cls, NULL, 0);
763} 830}
764 831
765 832
@@ -772,10 +839,14 @@ static void
772postgres_plugin_drop (void *cls) 839postgres_plugin_drop (void *cls)
773{ 840{
774 struct Plugin *plugin = cls; 841 struct Plugin *plugin = cls;
842 struct GNUNET_PQ_ExecuteStatement es[] = {
843 GNUNET_PQ_make_execute ("DROP TABLE gn090"),
844 GNUNET_PQ_EXECUTE_STATEMENT_END
845 };
775 846
776 if (GNUNET_OK != 847 if (GNUNET_OK !=
777 GNUNET_POSTGRES_exec (plugin->dbh, 848 GNUNET_PQ_exec_statements (plugin->dbh,
778 "DROP TABLE gn090")) 849 es))
779 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 850 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
780 "postgres", 851 "postgres",
781 _("Failed to drop table from database.\n")); 852 _("Failed to drop table from database.\n"));