From d01809a1a76a23ee2ff93993d9dc1f52e048db1c Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 25 Jun 2024 09:12:23 +0200 Subject: [PATCH] Sort only once for TOP clients Signed-off-by: DL6ER --- src/api/queries.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/api/queries.c b/src/api/queries.c index 1728048f..e7d71f68 100644 --- a/src/api/queries.c +++ b/src/api/queries.c @@ -22,7 +22,7 @@ // dbopen(false, ), dbclose() #include "database/common.h" -static int add_strings_to_array(struct ftl_conn *api, cJSON *array, const char *querystr, const int max_count) +static int add_strings_to_array(struct ftl_conn *api, cJSON *array1, cJSON *array2, const char *querystr, const int max_count) { sqlite3 *memdb = get_memdb(); @@ -48,7 +48,11 @@ static int add_strings_to_array(struct ftl_conn *api, cJSON *array, const char * int counter = 0; while((rc = sqlite3_step(stmt)) == SQLITE_ROW && (max_count < 0 || ++counter <= max_count)) - JSON_COPY_STR_TO_ARRAY(array, (const char*)sqlite3_column_text(stmt, 0)); + { + JSON_COPY_STR_TO_ARRAY(array1, (const char*)sqlite3_column_text(stmt, 0)); + if(array2 != NULL) + JSON_COPY_STR_TO_ARRAY(array2, (const char*)sqlite3_column_text(stmt, 1)); + } // Acceptable return codes are either // - SQLITE_DONE: We read all lines, or @@ -78,8 +82,8 @@ int api_queries_suggestions(struct ftl_conn *api) // Get domains cJSON *domain = JSON_NEW_ARRAY(); log_debug(DEBUG_API, "Reading top domains from database"); - rc = add_strings_to_array(api, domain, "WITH CTE AS (SELECT COUNT(*) cnt, domain FROM query_storage GROUP BY domain ORDER BY cnt DESC)"\ - "SELECT d.domain FROM CTE JOIN domain_by_id d ON CTE.domain = d.id", count); + rc = add_strings_to_array(api, domain, NULL, "WITH CTE AS (SELECT COUNT(*) cnt, domain FROM query_storage GROUP BY domain ORDER BY cnt DESC)"\ + "SELECT d.domain FROM CTE JOIN domain_by_id d ON CTE.domain = d.id", count); if(rc != 0) { log_err("Cannot read domains from database"); @@ -92,9 +96,10 @@ int api_queries_suggestions(struct ftl_conn *api) // We have to call DISTINCT() here as multiple IPs can map to and name and // vice versa cJSON *client_ip = JSON_NEW_ARRAY(); - log_debug(DEBUG_API, "Reading top client IPs from database"); - rc = add_strings_to_array(api, client_ip, "WITH CTE AS (SELECT COUNT(*) cnt, client FROM query_storage GROUP BY client ORDER BY cnt DESC)"\ - "SELECT c.ip FROM CTE JOIN client_by_id c ON CTE.client = c.id", count); + cJSON *client_name = JSON_NEW_ARRAY(); + log_debug(DEBUG_API, "Reading top client IPs and names from database"); + rc = add_strings_to_array(api, client_ip, client_name, "WITH CTE AS (SELECT COUNT(*) cnt, client FROM query_storage GROUP BY client ORDER BY cnt DESC)"\ + "SELECT c.ip,c.name FROM CTE JOIN client_by_id c ON CTE.client = c.id", count); if(rc != 0) { log_err("Cannot read client IPs from database"); @@ -102,27 +107,13 @@ int api_queries_suggestions(struct ftl_conn *api) cJSON_Delete(client_ip); return rc; } - log_debug(DEBUG_API, "Read %d client IPs from database", cJSON_GetArraySize(client_ip)); - - cJSON *client_name = JSON_NEW_ARRAY(); - log_debug(DEBUG_API, "Reading top client names from database"); - rc = add_strings_to_array(api, client_name, "WITH CTE AS (SELECT COUNT(*) cnt, client FROM query_storage GROUP BY client ORDER BY cnt DESC)"\ - "SELECT c.name FROM CTE JOIN client_by_id c ON CTE.client = c.id WHERE c.name IS NOT NULL", count); - if(rc != 0) - { - log_err("Cannot read client names from database"); - cJSON_Delete(domain); - cJSON_Delete(client_ip); - cJSON_Delete(client_name); - return rc; - } - log_debug(DEBUG_API, "Read %d client names from database", cJSON_GetArraySize(client_name)); + log_debug(DEBUG_API, "Read %d client IPs and %d client names from database", cJSON_GetArraySize(client_ip), cJSON_GetArraySize(client_name)); // Get upstreams cJSON *upstream = JSON_NEW_ARRAY(); log_debug(DEBUG_API, "Reading top upstreams from database"); - rc = add_strings_to_array(api, upstream, "WITH CTE AS (SELECT COUNT(*) cnt, forward FROM query_storage GROUP BY forward ORDER BY cnt DESC)"\ - "SELECT f.forward FROM CTE JOIN forward_by_id f ON CTE.forward = f.id", count); + rc = add_strings_to_array(api, upstream, NULL, "WITH CTE AS (SELECT COUNT(*) cnt, forward FROM query_storage GROUP BY forward ORDER BY cnt DESC)"\ + "SELECT f.forward FROM CTE JOIN forward_by_id f ON CTE.forward = f.id", count); if(rc != 0) { log_err("Cannot read forward from database");