diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h index 8741f6ef44dcd04945f5171c501c46c1dce48709..d533ec30a5d80d89885b27c6b8923edae02fea3f 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 50247177d2f3bdd9f10369a0a471b6beef431d6b..d1bce791f8824e3a9547e96888df225670deb8b8 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 5f08f3af8806e4b65a5a68c4964329fffe76b4cc..04ed376fa9d11134477d3bdc9f77fa2d4dee5d51 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 a0366d65482adc127bb0aa9af4d627205cb6be22..f76f556986fc660150160c44e76e350a72b82f9b 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 17bef1b5d2393b6fb1cc3cae2826c09d5945ca53..8781e704f0aa1193d3fcf0147b1a4f0983a31600 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 7b28879f2e567abd7782ce09b7f394e66d3568e5..dbb96795d8dd8e54580f4dbc82f0e87539d21590 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"))