diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-06-03 21:42:38 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-06-03 21:42:38 +0200 |
commit | b56cfa1127b0f4f376ad73c8ecd5622600b1da1c (patch) | |
tree | fa33633d6def8bb6a09a273ae881afda73af7efe /src/datacache/plugin_datacache_postgres.c | |
parent | a2ce8dba133e644e304bb41e4205435bebd6145c (diff) | |
download | gnunet-b56cfa1127b0f4f376ad73c8ecd5622600b1da1c.tar.gz gnunet-b56cfa1127b0f4f376ad73c8ecd5622600b1da1c.zip |
migrate another function to libgnunetpq
Diffstat (limited to 'src/datacache/plugin_datacache_postgres.c')
-rw-r--r-- | src/datacache/plugin_datacache_postgres.c | 196 |
1 files changed, 109 insertions, 87 deletions
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index c5bbb390c..ce469a9ed 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2006, 2009, 2010, 2012, 2015 GNUnet e.V. | 3 | Copyright (C) 2006, 2009, 2010, 2012, 2015, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -479,6 +479,97 @@ postgres_plugin_get_random (void *cls, | |||
479 | 479 | ||
480 | 480 | ||
481 | /** | 481 | /** |
482 | * Closure for #extract_result_cb. | ||
483 | */ | ||
484 | struct ExtractResultContext | ||
485 | { | ||
486 | /** | ||
487 | * Function to call for each result found. | ||
488 | */ | ||
489 | GNUNET_DATACACHE_Iterator iter; | ||
490 | |||
491 | /** | ||
492 | * Closure for @e iter. | ||
493 | */ | ||
494 | void *iter_cls; | ||
495 | |||
496 | }; | ||
497 | |||
498 | |||
499 | /** | ||
500 | * Function to be called with the results of a SELECT statement | ||
501 | * that has returned @a num_results results. Calls the `iter` | ||
502 | * from @a cls for each result. | ||
503 | * | ||
504 | * @param cls closure with the `struct ExtractResultContext` | ||
505 | * @param result the postgres result | ||
506 | * @param num_result the number of results in @a result | ||
507 | */ | ||
508 | static void | ||
509 | extract_result_cb (void *cls, | ||
510 | PGresult *result, | ||
511 | unsigned int num_results) | ||
512 | { | ||
513 | struct ExtractResultContext *erc = cls; | ||
514 | |||
515 | if (NULL == erc->iter) | ||
516 | return; | ||
517 | for (unsigned int i=0;i<num_results;i++) | ||
518 | { | ||
519 | struct GNUNET_TIME_Absolute expiration_time; | ||
520 | uint32_t type; | ||
521 | void *data; | ||
522 | size_t data_size; | ||
523 | struct GNUNET_PeerIdentity *path; | ||
524 | size_t path_len; | ||
525 | struct GNUNET_HashCode key; | ||
526 | struct GNUNET_PQ_ResultSpec rs[] = { | ||
527 | GNUNET_PQ_result_spec_absolute_time ("", | ||
528 | &expiration_time), | ||
529 | GNUNET_PQ_result_spec_uint32 ("type", | ||
530 | &type), | ||
531 | GNUNET_PQ_result_spec_variable_size ("value", | ||
532 | &data, | ||
533 | &data_size), | ||
534 | GNUNET_PQ_result_spec_variable_size ("path", | ||
535 | (void **) &path, | ||
536 | &path_len), | ||
537 | GNUNET_PQ_result_spec_auto_from_type ("key", | ||
538 | &key), | ||
539 | GNUNET_PQ_result_spec_end | ||
540 | }; | ||
541 | |||
542 | if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity))) | ||
543 | { | ||
544 | GNUNET_break (0); | ||
545 | path_len = 0; | ||
546 | } | ||
547 | path_len %= sizeof (struct GNUNET_PeerIdentity); | ||
548 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
549 | "Found result of size %u bytes and type %u in database\n", | ||
550 | (unsigned int) data_size, | ||
551 | (unsigned int) type); | ||
552 | if (GNUNET_SYSERR == | ||
553 | erc->iter (erc->iter_cls, | ||
554 | &key, | ||
555 | data_size, | ||
556 | data, | ||
557 | (enum GNUNET_BLOCK_Type) type, | ||
558 | expiration_time, | ||
559 | path_len, | ||
560 | path)) | ||
561 | { | ||
562 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
563 | "Ending iteration (client error)\n"); | ||
564 | GNUNET_PQ_cleanup_result (rs); | ||
565 | break; | ||
566 | } | ||
567 | GNUNET_PQ_cleanup_result (rs); | ||
568 | } | ||
569 | } | ||
570 | |||
571 | |||
572 | /** | ||
482 | * Iterate over the results that are "close" to a particular key in | 573 | * Iterate over the results that are "close" to a particular key in |
483 | * the datacache. "close" is defined as numerically larger than @a | 574 | * the datacache. "close" is defined as numerically larger than @a |
484 | * key (when interpreted as a circular address space), with small | 575 | * key (when interpreted as a circular address space), with small |
@@ -499,105 +590,36 @@ postgres_plugin_get_closest (void *cls, | |||
499 | void *iter_cls) | 590 | void *iter_cls) |
500 | { | 591 | { |
501 | struct Plugin *plugin = cls; | 592 | struct Plugin *plugin = cls; |
502 | uint32_t nbo_limit = htonl (num_results); | 593 | uint32_t num_results32 = (uint32_t) num_results; |
503 | const char *paramValues[] = { | 594 | struct GNUNET_PQ_QueryParam params[] = { |
504 | (const char *) key, | 595 | GNUNET_PQ_query_param_auto_from_type (key), |
505 | (const char *) &nbo_limit, | 596 | GNUNET_PQ_query_param_uint32 (&num_results32), |
597 | GNUNET_PQ_query_param_end | ||
506 | }; | 598 | }; |
507 | int paramLengths[] = { | 599 | enum GNUNET_PQ_QueryStatus res; |
508 | sizeof (struct GNUNET_HashCode), | 600 | struct ExtractResultContext erc; |
509 | sizeof (nbo_limit) | ||
510 | 601 | ||
511 | }; | 602 | erc.iter = iter; |
512 | const int paramFormats[] = { 1, 1 }; | 603 | erc.iter_cls = iter_cls; |
513 | struct GNUNET_TIME_Absolute expiration_time; | 604 | res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh, |
514 | uint32_t size; | 605 | "get_closest", |
515 | unsigned int type; | 606 | params, |
516 | unsigned int cnt; | 607 | &extract_result_cb, |
517 | unsigned int i; | 608 | &erc); |
518 | unsigned int path_len; | 609 | if (0 > res) |
519 | const struct GNUNET_PeerIdentity *path; | ||
520 | PGresult *res; | ||
521 | |||
522 | res = | ||
523 | PQexecPrepared (plugin->dbh, | ||
524 | "get_closest", | ||
525 | 2, | ||
526 | paramValues, | ||
527 | paramLengths, | ||
528 | paramFormats, | ||
529 | 1); | ||
530 | if (GNUNET_OK != | ||
531 | GNUNET_POSTGRES_check_result (plugin->dbh, | ||
532 | res, | ||
533 | PGRES_TUPLES_OK, | ||
534 | "PQexecPrepared", | ||
535 | "get_closest")) | ||
536 | { | 610 | { |
537 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 611 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
538 | "Ending iteration (postgres error)\n"); | 612 | "Ending iteration (postgres error)\n"); |
539 | return 0; | 613 | return 0; |
540 | } | 614 | } |
541 | 615 | if (GNUNET_PQ_STATUS_SUCCESS_NO_RESULTS == res) | |
542 | if (0 == (cnt = PQntuples (res))) | ||
543 | { | 616 | { |
544 | /* no result */ | 617 | /* no result */ |
545 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 618 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
546 | "Ending iteration (no more results)\n"); | 619 | "Ending iteration (no more results)\n"); |
547 | PQclear (res); | ||
548 | return 0; | 620 | return 0; |
549 | } | 621 | } |
550 | if (NULL == iter) | 622 | return res; |
551 | { | ||
552 | PQclear (res); | ||
553 | return cnt; | ||
554 | } | ||
555 | if ( (5 != PQnfields (res)) || | ||
556 | (sizeof (uint64_t) != PQfsize (res, 0)) || | ||
557 | (sizeof (uint32_t) != PQfsize (res, 1)) || | ||
558 | (sizeof (struct GNUNET_HashCode) != PQfsize (res, 4)) ) | ||
559 | { | ||
560 | GNUNET_break (0); | ||
561 | PQclear (res); | ||
562 | return 0; | ||
563 | } | ||
564 | for (i = 0; i < cnt; i++) | ||
565 | { | ||
566 | expiration_time.abs_value_us = | ||
567 | GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0)); | ||
568 | type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1)); | ||
569 | size = PQgetlength (res, i, 2); | ||
570 | path_len = PQgetlength (res, i, 3); | ||
571 | if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity))) | ||
572 | { | ||
573 | GNUNET_break (0); | ||
574 | path_len = 0; | ||
575 | } | ||
576 | path_len %= sizeof (struct GNUNET_PeerIdentity); | ||
577 | path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, i, 3); | ||
578 | key = (const struct GNUNET_HashCode *) PQgetvalue (res, i, 4); | ||
579 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
580 | "Found result of size %u bytes and type %u in database\n", | ||
581 | (unsigned int) size, | ||
582 | (unsigned int) type); | ||
583 | if (GNUNET_SYSERR == | ||
584 | iter (iter_cls, | ||
585 | key, | ||
586 | size, | ||
587 | PQgetvalue (res, i, 2), | ||
588 | (enum GNUNET_BLOCK_Type) type, | ||
589 | expiration_time, | ||
590 | path_len, | ||
591 | path)) | ||
592 | { | ||
593 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
594 | "Ending iteration (client error)\n"); | ||
595 | PQclear (res); | ||
596 | return cnt; | ||
597 | } | ||
598 | } | ||
599 | PQclear (res); | ||
600 | return cnt; | ||
601 | } | 623 | } |
602 | 624 | ||
603 | 625 | ||