From 96feccbcdedd9b969a5d548a185b2c5747f74826 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Fri, 17 Apr 2020 14:38:41 +0200
Subject: [PATCH] Search on queue and database with almost the same functions

---
 inc/lektor/commands.h |  1 +
 inc/lektor/database.h |  1 +
 src/commands.c        | 27 ++++++++++++++++++++-------
 src/database/find.c   | 34 +++++++++++++++++++++++++++++++++-
 src/main/lkt.c        |  2 +-
 src/net/listen.c      |  2 ++
 6 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h
index 8741f6ef..d533ec30 100644
--- a/inc/lektor/commands.h
+++ b/inc/lektor/commands.h
@@ -40,6 +40,7 @@ bool command_move(sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], enum mpd_idle_f
 bool command_shuffle(sqlite3 *db, enum mpd_idle_flag *watch_mask_ptr);
 bool command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
 bool command_playid(sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], enum mpd_idle_flag *watch_mask_ptr);
+bool command_queue_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MAX], long continuation);
 
 /* The playlists */
 bool command_plt_create(sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], enum mpd_idle_flag *watch_mask_ptr);
diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index 50247177..d1bce791 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -104,6 +104,7 @@ struct lkt_search {
 typedef bool (*lkt_search_database_func)(struct lkt_state *srv, size_t c, int id, int id_len,
         const char *row);
 
+bool database_search_database_init(sqlite3 *db, char *col_name, char *rgx, struct lkt_search *ret);
 bool database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, struct lkt_search *ret);
 bool database_search_iter(struct lkt_search *item);
 
diff --git a/src/commands.c b/src/commands.c
index 5f08f3af..04ed376f 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -182,7 +182,7 @@ command_previous(sqlite3 *db, struct lkt_win *win, enum mpd_idle_flag *watch_mas
     return res;
 }
 
-bool
+static inline bool
 __play_that_file(sqlite3 *db, struct lkt_win *win, int pos)
 {
     char filepath[PATH_MAX];
@@ -606,9 +606,9 @@ lkt_callback_insert_v1(struct lkt_state *srv, size_t c, int id, int id_len, cons
     return database_queue_add_id(srv->db, id, 5);
 }
 
-bool
-command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MAX], long continuation,
-             enum lkt_find_action action)
+static bool
+__find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MAX], long continuation,
+       enum lkt_find_action action, bool(*init)(sqlite3*, char*, char*, struct lkt_search*))
 {
     char rgx[PATH_MAX], *col_name, *mpd_tag;
     int count;
@@ -621,7 +621,7 @@ command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MA
 
     // Check args //
     if (cmd_args == NULL || cmd_args[0] == NULL) {
-        fprintf(stderr, " ! command_find: Argument invalid, empty cmd_args\n");
+        fprintf(stderr, " ! __find: Argument invalid, empty cmd_args\n");
         return false;
     }
 
@@ -677,8 +677,8 @@ command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MA
     }
 
     // Make the search langand do the right action //
-    if (!database_search_queue_init(srv->db, col_name, rgx, &search)) {
-        fprintf(stderr, " ! command_find: Failed to init the search\n");
+    if (!init(srv->db, col_name, rgx, &search)) {
+        fprintf(stderr, " ! __find: Failed to init the search\n");
         return false;
     }
 
@@ -692,6 +692,19 @@ no_rgx:
     return false;
 }
 
+bool
+command_queue_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MAX], long continuation)
+{
+    return __find(srv, c, cmd_args, continuation, LKT_FND_ACT_RESPOND, database_search_queue_init);
+}
+
+bool
+command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MAX], long continuation,
+             enum lkt_find_action action)
+{
+    return __find(srv, c, cmd_args, continuation, action, database_search_database_init);
+}
+
 bool
 command_set_playback_option(struct lkt_state *srv, size_t c,
                             enum lkt_playback_option opt, char *args[LKT_MESSAGE_MAX])
diff --git a/src/database/find.c b/src/database/find.c
index a0366d65..f76f5569 100644
--- a/src/database/find.c
+++ b/src/database/find.c
@@ -8,7 +8,7 @@
 #include <string.h>
 
 bool
-database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, struct lkt_search *ret)
+database_search_database_init(sqlite3 *db, char *col_name, char *rgx, struct lkt_search *ret)
 {
     if (ret == NULL) {
         fprintf(stderr, " ! database_search_init: Exit because return pointer is NULL\n");
@@ -36,6 +36,38 @@ error:
     return false;
 }
 
+
+bool
+database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, struct lkt_search *ret)
+{
+    if (ret == NULL) {
+        fprintf(stderr, " ! database_search_init: Exit because return pointer is NULL\n");
+        return false;
+    }
+
+    static const char *SQL_STMT_TEMPLATE =
+        "WITH content AS ("
+        " SELECT kara_id AS id, string AS any_col, LENGTH(CAST(kara_id AS TEXT)) AS len"
+        " FROM queue_ "
+        " JOIN kara "
+        " ON kara_id = kara.id AND %s LIKE ?)"
+        "SELECT id, any_col, (SELECT MAX(len) FROM content)"
+        "FROM content LIMIT %d OFFSET %d;";
+    char SQL_STMT[LKT_MAX_SQLITE_STATEMENT];
+
+    snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT_TEMPLATE, col_name,
+             ret->msg_count, ret->continuation);
+    SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0;
+    SQLITE_PREPARE(db, ret->stmt, SQL_STMT, error);
+    SQLITE_BIND_TEXT(db, ret->stmt, 1, rgx, error);
+    ret->db = db;
+    /* Assign the callback. */
+    return true;
+error:
+    sqlite3_finalize(ret->stmt);
+    return false;
+}
+
 bool
 database_search_iter(struct lkt_search *item)
 {
diff --git a/src/main/lkt.c b/src/main/lkt.c
index 17bef1b5..8781e704 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -934,7 +934,7 @@ search_count__(struct lkt_cmd_args *args)
 noreturn void
 search_queue__(struct lkt_cmd_args *args)
 {
-    search_with_cmd__(args, "playlistinfo");
+    search_with_cmd__(args, "playlistfind");
 }
 
 /* Parsing stuff. */
diff --git a/src/net/listen.c b/src/net/listen.c
index 7b28879f..dbb96795 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -216,6 +216,8 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
 
         else if (!strcmp(cmd.name, "playlist") || !strcmp(cmd.name, "playlistinfo"))
             err = !command_queue_list(srv, c, cmd.args);
+        else if (!strcmp(cmd.name, "playlistfind") || !strcmp(cmd.name, "playlistsearch"))
+            err = ! command_queue_find(srv, c, cmd.args, cmd.cont);
 
         else if (!strcmp(cmd.name, "sticker") && cmd.args[0]) {
             if (!strcmp(cmd.args[0], "get"))
-- 
GitLab