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:
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)
{