From 931fd99a6a7bd9b84aaa7aa6fc2642f921d93d8a Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Tue, 14 Apr 2020 20:52:42 +0200
Subject: [PATCH] Don't use callback in the search database functions

---
 inc/lektor/database.h | 21 ++++++++++++++++-----
 src/database/find.c   | 41 +++++++++++++++++++++++------------------
 2 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index 9adae381..a706a570 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -73,15 +73,26 @@ bool database_queue_toggle_pause(sqlite3 *db);
 bool database_queue_play(sqlite3 *db, int pos);
 bool database_queue_stop(sqlite3 *db);
 
+typedef bool (*database_callback)(void *args, int id, int id_len, const char *sql_row);
+
 /* List the content of the queue */
-bool database_queue_list_from(sqlite3 *db, unsigned int count, void *args, struct database_callback callback);
-bool database_queue_list_abs(sqlite3 *db, unsigned int from, unsigned int to, void *args, struct database_callback callback);
+bool database_queue_list_from(sqlite3 *db, unsigned int count, void *args, database_callback callback);
+bool database_queue_list_abs(sqlite3 *db, unsigned int from, unsigned int to, void *args, database_callback callback);
 
 /* Search the database */
-bool database_search_database_init(sqlite3 *db, const char *col_name, const char *rgx, sqlite3_stmt **ret);
+struct lkt_search_iterator {
+    enum lkt_search_iterator_type {
+        lkt_search_iterator_database,
+        lkt_search_iterator_queue,
+        lkt_search_iterator_playlist,
+    } type;
+    sqlite3_stmt *iter;
+    sqlite3 *db;
+};
+bool database_search_database_init(sqlite3 *db, const char *col_name, const char *rgx, struct lkt_search_iterator *ret);
 bool database_search_plt_init(sqlite3 *db, const char *plt_name, char *col_name, char *rgx,
-                              sqlite3_stmt **ret);
-bool database_search_iter(sqlite3 *db, sqlite3_stmt *item, struct lkt_callback callback, bool *need_free);
+                              struct lkt_search_iterator *ret);
+bool database_search_iter(struct lkt_search_iterator *item, void **ret, size_t *len);
 
 /* Next and prev operation on the queue. */
 bool database_queue_next(sqlite3 *db, char filepath[PATH_MAX]);
diff --git a/src/database/find.c b/src/database/find.c
index 1b6dbbe9..7a64e076 100644
--- a/src/database/find.c
+++ b/src/database/find.c
@@ -8,7 +8,7 @@
 #include <string.h>
 
 bool
-database_search_database_init(sqlite3 *db, const char *col_name, const char *rgx, sqlite3_stmt **ret)
+database_search_database_init(sqlite3 *db, const char *col_name, const char *rgx, struct lkt_search_iterator *ret)
 {
     if (ret == NULL) {
         fprintf(stderr, " ! database_search_init: Exit because return pointer is NULL\n");
@@ -25,12 +25,11 @@ database_search_database_init(sqlite3 *db, const char *col_name, const char *rgx
 
     snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT_TEMPLATE, col_name);
     SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0;
-    SQLITE_PREPARE(db, *ret, SQL_STMT, error);
-    SQLITE_BIND_TEXT(db, *ret, 1, rgx, error);
+    SQLITE_PREPARE(db, ret->iter, SQL_STMT, error);
+    SQLITE_BIND_TEXT(db, ret->iter, 1, rgx, error);
     return true;
 error:
-    sqlite3_finalize(*ret);
-    *ret = NULL;
+    sqlite3_finalize(ret->iter);
     return false;
 }
 
@@ -40,13 +39,14 @@ error:
 //}
 
 bool
-database_search_iter(sqlite3 *db, sqlite3_stmt *item, struct lkt_callback callback, bool *need_free)
+database_search_iter(struct lkt_search_iterator *item, void **ret, size_t *len)
 {
-    const char *sql_row;
-    int id, code, id_len;
+    int code;
 
-    *need_free = true;
-    code = sqlite3_step(item);
+    if (*len < 3)
+        goto to_small;
+
+    code = sqlite3_step(item->iter);
 
     if (item == NULL) {
         fprintf(stderr, " * database_search_iter: Exit function because the sqlite3_stmt* is NULL\n");
@@ -59,21 +59,26 @@ database_search_iter(sqlite3 *db, sqlite3_stmt *item, struct lkt_callback callba
     if (code != SQLITE_ROW)
         goto error;
 
-    switch (callback.type) {
+    switch (item->type) {
     case callback_database:
-        id = sqlite3_column_int(item, 0);
-        sql_row = (const char *) sqlite3_column_text(item, 1);
-        id_len = sqlite3_column_int(item, 2);
-        return callback.call(callback.args, id, id_len, sql_row);
+        * (int *) ret[0] = sqlite3_column_int(item->iter, 0);
+        ret[1] = (char *) sqlite3_column_text(item->iter, 1);
+        * (int *) ret[2] = sqlite3_column_int(item->iter, 2);
+        return true;
 
     default:
         break;
     }
 
+to_small:
+    fprintf(stderr, " . database_search_iter: length of ret is to small, should be at least 3\n");
+    return false;
 error:
-    fprintf(stderr, " ! database_search_iter: sqlite3_step failed: %s\n", sqlite3_errmsg(db));
+    fprintf(stderr, " ! database_search_iter: sqlite3_step failed: %s\n", sqlite3_errmsg(item->db));
+    sqlite3_finalize(item->iter);
+    return false;
 done:
-    sqlite3_finalize(item);
-    *need_free = false;
+    sqlite3_finalize(item->iter);
+    *len = 0;
     return false;
 }
-- 
GitLab