From 2a44156d155737ae81a17de0b97f5370ee461279 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Wed, 15 Apr 2020 14:52:20 +0200 Subject: [PATCH] WIP: A first try of getting the continue working --- inc/lektor/database.h | 5 +++-- src/commands.c | 18 +++++++++++++++--- src/database/queue.c | 24 ++++++++++++++---------- src/main/lkt.c | 14 ++++++-------- src/net/listen.c | 13 +++++++++++-- 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/inc/lektor/database.h b/inc/lektor/database.h index 796398e9..03b451fa 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -82,8 +82,9 @@ struct lkt_callback { }; /* List the content of the queue */ -bool database_queue_list_from(sqlite3 *db, unsigned int count, struct lkt_callback *callback); -bool database_queue_list_abs(sqlite3 *db, unsigned int from, unsigned int to, struct lkt_callback *callback); +bool database_queue_list_from(sqlite3 *db, size_t count, size_t *continuation, struct lkt_callback *callback); +bool database_queue_list_abs(sqlite3 *db, size_t from, size_t to, size_t *continuation, + struct lkt_callback *callback); /* Search the database */ bool database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, sqlite3_stmt **ret); diff --git a/src/commands.c b/src/commands.c index 67314205..94381e9a 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1,5 +1,6 @@ #define _POSIX_C_SOURCE 200809L +#include <lektor/macro.h> #include <lektor/commands.h> #include <lektor/database.h> #include <lektor/net.h> @@ -884,8 +885,9 @@ bool command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]) { unsigned int count, from, to, tmp_switch; - long val; + long val, ret; char *endptr, *str; + size_t continuation = lkt_get_continuation(srv, c); struct lkt_callback callback = { .call = lkt_callback_send_row_v1, .srv = srv, @@ -954,11 +956,21 @@ command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_ /* The command is used in its relative forme, display elements from the current one. */ is_relative: - return database_queue_list_from(srv->db, count, &callback); + count -= continuation; + if (count < lkt_remaining_msg(srv, c) - 1) { + lkt_set_continuation(srv, c, 0); + return database_queue_list_from(srv->db, count, &continuation, &callback); + } else { + count = lkt_remaining_msg(srv, c) - 2; /* One for `continue: i` and one for OK/ACK. */ + ret = database_queue_list_from(srv->db, count, &continuation, &callback); + lkt_set_continuation(srv, c, continuation + count); + return ret; + } /* The command is used with a range specifier. */ is_absolute: - return database_queue_list_abs(srv->db, from, to, &callback); + ret = database_queue_list_abs(srv->db, from, to, &continuation, &callback); + return ret; } bool diff --git a/src/database/queue.c b/src/database/queue.c index ff7f174e..8419740d 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -673,25 +673,29 @@ error: } bool -database_queue_list_abs(sqlite3 *db, unsigned int from, unsigned int to, struct lkt_callback *callback) +database_queue_list_abs(sqlite3 *db, size_t from, size_t to, size_t *continuation, + struct lkt_callback *callback) { - const char *SQL_STMT = + const char *SQL_TEMPLATE = "WITH content AS (" " SELECT kara.id AS id, string, LENGTH(CAST(kara.id AS TEXT)) AS len" " FROM queue_" " JOIN kara ON kara_id = kara.id" " WHERE position >= ? AND position <= ?" - " GROUP BY position ORDER BY position)" + " GROUP BY position ORDER BY position LIMIT %d OFFSET %d)" "SELECT id, string, (SELECT MAX(len) FROM content)" " FROM content;"; int code, id, id_len; + char SQL_STMT[LKT_MAX_SQLITE_STATEMENT]; const char *row; bool ret = false; sqlite3_stmt *stmt; + snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_TEMPLATE, to - from + 1, *continuation); + SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0; SQLITE_PREPARE(db, stmt, SQL_STMT, error); - SQLITE_BIND_INT(db, stmt, 1, from, error); - SQLITE_BIND_INT(db, stmt, 2, to, error); + SQLITE_BIND_INT(db, stmt, 1, (int) from, error); + SQLITE_BIND_INT(db, stmt, 2, (int) to, error); for (;;) { code = sqlite3_step(stmt); @@ -723,7 +727,7 @@ error: } bool -database_queue_list_from(sqlite3 *db, unsigned int count, struct lkt_callback *callback) +database_queue_list_from(sqlite3 *db, size_t count, size_t *continuation, struct lkt_callback *callback) { const char *SQL_TEMPLATE = "WITH content AS (" @@ -733,17 +737,17 @@ database_queue_list_from(sqlite3 *db, unsigned int count, struct lkt_callback *c " WHEN queue_state.current IS NULL THEN 1" " ELSE queue_state.current END" " JOIN kara ON kara_id = kara.id" - " GROUP BY position ORDER BY position LIMIT %d)" + " GROUP BY position ORDER BY position LIMIT %d OFFSET %d)" "SELECT id, string, (SELECT MAX(len) FROM content)" " FROM content;"; - static const int stmt_len = 512; - char SQL_STMT[stmt_len]; + char SQL_STMT[LKT_MAX_SQLITE_STATEMENT]; int code, id, id_len; const char *row; bool ret = false; sqlite3_stmt *stmt; - snprintf(SQL_STMT, stmt_len, SQL_TEMPLATE, count); + snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_TEMPLATE, count, *continuation); + SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0; SQLITE_PREPARE(db, stmt, SQL_STMT, error); for (;;) { diff --git a/src/main/lkt.c b/src/main/lkt.c index 2356f744..da9ad84b 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -196,7 +196,7 @@ err: static inline int write_continue(FILE *sock, const int continuation) { - return write_socket(sock, "continue %d\n", continuation); + return write_socket_format(sock, "continue %d\n", continuation); } static FILE * @@ -585,13 +585,11 @@ list__(struct lkt_cmd_args *args) FILE *sock = NULL; redo: sock = lkt_connect(); - - if (continuation > 0) - write_continue(sock, continuation); - - write_socket(sock, "playlist ", strlen("playlist ")); - write_socket(sock, args->argv[0], strlen(args->argv[0])); - write_socket(sock, "\n", sizeof(char)); + write_socket_format(sock, "command_list_begin\n" + "continue %d\n" + "playlist %s\n" + "command_list_end\n", + continuation, args->argv[0]); for (;;) { memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); diff --git a/src/net/listen.c b/src/net/listen.c index 11418168..f4bbf152 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -160,7 +160,7 @@ command_list_begin(struct lkt_state *srv, size_t c, int list_ok) static int handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) { - int err; + int err, continuation = 0; switch (*lkt_client_get_mask(srv, c)) { case MPD_IDLE_NONE: @@ -193,8 +193,11 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) else if (!strcmp(cmd.name, "ping")) err = 0; else if (!strcmp(cmd.name, "continue")) { - srv->clients[c - 1].continuation = atoi(cmd.args[0]); + continuation = atoi(cmd.args[0]); + lkt_set_continuation(srv, c, continuation); + fprintf(stderr, " * Client is continuing from %d\n", continuation); err = 0; + goto skip_continue; } else if (!strcmp(cmd.name, "next")) @@ -300,6 +303,12 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) break; } + continuation = lkt_get_continuation(srv, c); + if (continuation > 0) { + fprintf(stderr, " * Client should continue from %d\n", continuation); + send_continue(srv, c, continuation); + } +skip_continue: send_status(srv, c, err, cmd.name); end_no_send_status: return err; -- GitLab