diff --git a/inc/lektor/database.h b/inc/lektor/database.h index 03b451faeb6566acfb53fa726c936767dc5dcfa1..5772ac9e9bbaf05da9c4455d369ef891e40dbbe1 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -82,9 +82,7 @@ struct lkt_callback { }; /* List the content of the queue */ -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); +bool database_queue_list(sqlite3 *db, size_t from, size_t to, 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 94381e9ac974ed539caea1df7c0813d0727e509a..6c3477e0932e5e5d489c329f875838db1a8106a1 100644 --- a/src/commands.c +++ b/src/commands.c @@ -887,7 +887,7 @@ command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_ unsigned int count, from, to, tmp_switch; long val, ret; char *endptr, *str; - size_t continuation = lkt_get_continuation(srv, c); + struct lkt_queue_state state; struct lkt_callback callback = { .call = lkt_callback_send_row_v1, .srv = srv, @@ -956,20 +956,23 @@ 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: - count -= continuation; + if (!database_queue_state(srv->db, &state)) { + fprintf(stderr, " . command_queue_list: Could not get current position in queue\n"); + return false; + } + if (count < lkt_remaining_msg(srv, c) - 1) { lkt_set_continuation(srv, c, 0); - return database_queue_list_from(srv->db, count, &continuation, &callback); + return database_queue_list(srv->db, state.current, state.current+ count, &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); + ret = database_queue_list(srv->db, state.current, state.current + count, &callback); return ret; } /* The command is used with a range specifier. */ is_absolute: - ret = database_queue_list_abs(srv->db, from, to, &continuation, &callback); + ret = database_queue_list(srv->db, from, to, &callback); return ret; } diff --git a/src/database/queue.c b/src/database/queue.c index 8419740dcbe4b0a67cb2f5fa9d2b3d43c377ec82..a73019391310d3edee36c335d77d9482e74c6e80 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -79,8 +79,9 @@ database_queue_current_kara(sqlite3 *db, struct kara_metadata *res, int *id) res->song_number = sqlite3_column_int(stmt, 6); no_metadata: /* Most of the time this will be NULL. */ - if (id) + if (id && sqlite3_column_type(stmt, 7) != SQLITE_NULL) { *id = sqlite3_column_int(stmt, 7); + } } else { fprintf(stderr, " ! database_queue_current_kara: failed: %s\n", sqlite3_errmsg(db)); @@ -673,26 +674,22 @@ error: } bool -database_queue_list_abs(sqlite3 *db, size_t from, size_t to, size_t *continuation, - struct lkt_callback *callback) +database_queue_list(sqlite3 *db, size_t from, size_t to, struct lkt_callback *callback) { - const char *SQL_TEMPLATE = + const char *SQL_STMT = "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 LIMIT %d OFFSET %d)" + " GROUP BY position ORDER BY position)" "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, (int) from, error); SQLITE_BIND_INT(db, stmt, 2, (int) to, error); @@ -701,58 +698,6 @@ database_queue_list_abs(sqlite3 *db, size_t from, size_t to, size_t *continuatio code = sqlite3_step(stmt); - if (code == SQLITE_ROW) { - id = sqlite3_column_int(stmt, 0); - row = (const char *) sqlite3_column_text(stmt, 1); - id_len = sqlite3_column_int(stmt, 2); - ++(callback->iterations); - if (callback->call(callback, id, id_len, row)) - continue; - else - break; - } - - else if (code == SQLITE_OK || code == SQLITE_DONE) - goto done; - - else - break; - } - -done: - ret = true; -error: - sqlite3_finalize(stmt); - return ret; -} - -bool -database_queue_list_from(sqlite3 *db, size_t count, size_t *continuation, struct lkt_callback *callback) -{ - const char *SQL_TEMPLATE = - "WITH content AS (" - " SELECT kara.id AS id, string, LENGTH(CAST(kara.id AS TEXT)) AS len" - " FROM queue_" - " JOIN queue_state ON queue_.position >= CASE" - " 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 OFFSET %d)" - "SELECT id, string, (SELECT MAX(len) FROM content)" - " FROM content;"; - char SQL_STMT[LKT_MAX_SQLITE_STATEMENT]; - int code, id, id_len; - const char *row; - bool ret = false; - sqlite3_stmt *stmt; - - 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 (;;) { - code = sqlite3_step(stmt); - if (code == SQLITE_ROW) { id = sqlite3_column_int(stmt, 0); row = (const char *) sqlite3_column_text(stmt, 1);