merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit bebf18afa23d109fdde22ed73b376aa33cea1531
parent 93eeda058bfceac7af8c02943386fb14005cb95b
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Tue, 15 Jul 2025 12:56:21 +0200

Fix statistics by interval SQL statements.

Diffstat:
Msrc/backenddb/pg_lookup_statistics_amount_by_interval.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/backenddb/pg_lookup_statistics_counter_by_interval.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 147 insertions(+), 30 deletions(-)

diff --git a/src/backenddb/pg_lookup_statistics_amount_by_interval.c b/src/backenddb/pg_lookup_statistics_amount_by_interval.c @@ -46,12 +46,57 @@ struct LookupAmountStatisticsContext * Did database result extraction fail? */ bool extract_failed; + + /** + * Description of statistic + */ + char*description; }; +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results about statistics. + * + * @param[in,out] cls of type `struct LookupTokenFamiliesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lookup_statistics_amount_by_interval_desc_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct LookupAmountStatisticsContext *tflc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + char *description; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("description", + &description), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + tflc->extract_failed = true; + return; + } + + tflc->description = GNUNET_strdup (description); + + GNUNET_PQ_cleanup_result (rs); + } +} + /** * Function to be called with the results of a SELECT statement - * that has returned @a num_results results about token families. + * that has returned @a num_results results about statistics. * * @param[in,out] cls of type `struct LookupTokenFamiliesContext *` * @param result the postgres result @@ -66,20 +111,13 @@ lookup_statistics_amount_by_interval_cb (void *cls, struct TALER_Amount *amounts = NULL; char *resp_desc = NULL; uint64_t cur_interval_start_epoch; - uint64_t bmeta_id_current; unsigned int amounts_len = 0; for (unsigned int i = 0; i < num_results; i++) { - char *description; struct TALER_Amount cumulative_amount; uint64_t interval_start_epoch; - uint64_t bmeta_id; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_uint64 ("bmeta_serial_id", - &bmeta_id), - GNUNET_PQ_result_spec_string ("description", - &description), GNUNET_PQ_result_spec_uint64 ("range", &interval_start_epoch), TALER_PQ_result_spec_amount_with_currency ("rvalue", @@ -98,9 +136,7 @@ lookup_statistics_amount_by_interval_cb (void *cls, } /* Call callback if the bucket changed */ - if ( (NULL != resp_desc) && - ( (bmeta_id != bmeta_id_current) || - (interval_start_epoch != cur_interval_start_epoch)) ) + if (interval_start_epoch != cur_interval_start_epoch) { struct GNUNET_TIME_Timestamp interval_start; @@ -115,12 +151,7 @@ lookup_statistics_amount_by_interval_cb (void *cls, 0); GNUNET_free (resp_desc); } - if (NULL == resp_desc) - { - cur_interval_start_epoch = interval_start_epoch; - resp_desc = GNUNET_strdup (description); - bmeta_id_current = bmeta_id; - } + cur_interval_start_epoch = interval_start_epoch; GNUNET_array_append (amounts, amounts_len, cumulative_amount); @@ -158,6 +189,11 @@ TMH_PG_lookup_statistics_amount_by_interval ( .cb_cls = cb_cls, /* Can be overwritten by the lookup_statistics_amount_by_interval_cb */ .extract_failed = false, + .description = NULL + }; + struct GNUNET_PQ_QueryParam descParams[] = { + GNUNET_PQ_query_param_string (slug), + GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (instance_id), @@ -168,17 +204,34 @@ TMH_PG_lookup_statistics_amount_by_interval ( check_connection (pg); PREPARE (pg, + "lookup_statistics_amount_by_interval_description", + "SELECT description" + " FROM merchant_statistic_interval_meta" + " WHERE slug=$1 LIMIT 1"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + "lookup_statistics_amount_by_interval_description", + descParams, + &lookup_statistics_amount_by_interval_desc_cb, + &context); + /* If there was an error inside the cb, return a hard error. */ + if (context.extract_failed) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + PREPARE (pg, "lookup_statistics_amount_by_interval", "SELECT *" - " FROM merchant_statistic_interval_amount_get($1,$2)" - " JOIN merchant_statistic_bucket_meta" - " ON slug=$2"); + " FROM merchant_statistic_interval_amount_get($2,$1)"); qs = GNUNET_PQ_eval_prepared_multi_select ( pg->conn, "lookup_statistics_amount_by_interval", params, &lookup_statistics_amount_by_interval_cb, &context); + if (NULL != context.description) + GNUNET_free (context.description); /* If there was an error inside the cb, return a hard error. */ if (context.extract_failed) { diff --git a/src/backenddb/pg_lookup_statistics_counter_by_interval.c b/src/backenddb/pg_lookup_statistics_counter_by_interval.c @@ -46,12 +46,57 @@ struct LookupCounterStatisticsContext * Did database result extraction fail? */ bool extract_failed; + + /** + * Description of statistic + */ + char*description; }; +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results about statistics. + * + * @param[in,out] cls of type `struct LookupTokenFamiliesContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lookup_statistics_counter_by_interval_desc_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct LookupCounterStatisticsContext *tflc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + char *description; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("description", + &description), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + tflc->extract_failed = true; + return; + } + + tflc->description = GNUNET_strdup (description); + + GNUNET_PQ_cleanup_result (rs); + } +} + /** * Function to be called with the results of a SELECT statement - * that has returned @a num_results results about token families. + * that has returned @a num_results results about statistics. * * @param[in,out] cls of type `struct LookupTokenFamiliesContext *` * @param result the postgres result @@ -66,15 +111,12 @@ lookup_statistics_counter_by_interval_cb (void *cls, for (unsigned int i = 0; i < num_results; i++) { - char *description; uint64_t cumulative_number; uint64_t interval_start_epoch; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_string ("description", - &description), - GNUNET_PQ_result_spec_uint64 ("start_time", + GNUNET_PQ_result_spec_uint64 ("range", &interval_start_epoch), - GNUNET_PQ_result_spec_uint64 ("cumulative_number", + GNUNET_PQ_result_spec_uint64 ("rvalue", &cumulative_number), GNUNET_PQ_result_spec_end }; @@ -92,7 +134,7 @@ lookup_statistics_counter_by_interval_cb (void *cls, interval_start = GNUNET_TIME_timestamp_from_s (interval_start_epoch); tflc->cb (tflc->cb_cls, - description, + tflc->description, interval_start, cumulative_number); GNUNET_PQ_cleanup_result (rs); @@ -114,6 +156,11 @@ TMH_PG_lookup_statistics_counter_by_interval ( .cb_cls = cb_cls, /* Can be overwritten by the lookup_token_families_cb */ .extract_failed = false, + .description = NULL + }; + struct GNUNET_PQ_QueryParam descParams[] = { + GNUNET_PQ_query_param_string (slug), + GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (instance_id), @@ -124,17 +171,34 @@ TMH_PG_lookup_statistics_counter_by_interval ( check_connection (pg); PREPARE (pg, + "lookup_statistics_counter_by_interval_description", + "SELECT description" + " FROM merchant_statistic_interval_meta" + " WHERE slug=$1 LIMIT 1"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + "lookup_statistics_counter_by_interval_description", + descParams, + &lookup_statistics_counter_by_interval_desc_cb, + &context); + /* If there was an error inside the cb, return a hard error. */ + if (context.extract_failed) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + PREPARE (pg, "lookup_statistics_counter_by_interval", "SELECT *" - " FROM merchant_statistic_interval_number_get($1,$2)" - " JOIN merchant_statistic_bucket_meta" - " ON slug=$2"); + " FROM merchant_statistic_interval_number_get($2,$1)"); qs = GNUNET_PQ_eval_prepared_multi_select ( pg->conn, "lookup_statistics_counter_by_interval", params, &lookup_statistics_counter_by_interval_cb, &context); + if (NULL != context.description) + GNUNET_free (context.description); /* If there was an error inside the cb, return a hard error. */ if (context.extract_failed) {