From 0ae7b9a51b97b03347b4c5258ee864ab967057e0 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Sat, 11 Apr 2020 11:41:03 +0200 Subject: [PATCH] deleteid command working correctly --- inc/lektor/database.h | 2 +- src/commands.c | 12 +++++++++++- src/database/queue.c | 25 +++++++++++++++++-------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/inc/lektor/database.h b/inc/lektor/database.h index e26b78f1..475206c5 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -30,7 +30,7 @@ bool database_detach(sqlite3 *db, const char *name); /* Get information on the queue and currently playing kara. */ bool database_queue_state(sqlite3 *db, struct lkt_queue_state *res); -bool database_queue_current_kara(sqlite3 *db, struct kara_metadata *res); +bool database_queue_current_kara(sqlite3 *db, struct kara_metadata *res, int *id); bool database_queue_set_paused(sqlite3 *db, bool paused); bool database_queue_set_current_index(sqlite3 *db, int idx); diff --git a/src/commands.c b/src/commands.c index cc65c13a..1c525462 100644 --- a/src/commands.c +++ b/src/commands.c @@ -98,7 +98,7 @@ command_currentsong(struct lkt_state *srv, size_t c) memset(&kara, 0, sizeof(struct kara_metadata)); - if (!database_queue_current_kara(srv->db, &kara)) + if (!database_queue_current_kara(srv->db, &kara, NULL)) fprintf(stderr, " ! command_currentsong: Failed to get information about the current kara\n"); out = lkt_message_new(); @@ -371,6 +371,7 @@ command_delid(sqlite3 *db, struct lkt_win *win, char *id_str, enum mpd_idle_flag (void) win; long id; char *endptr; + int uri = 0; errno = 0; *watch_mask_ptr |= MPD_IDLE_PLAYLIST; @@ -386,6 +387,15 @@ command_delid(sqlite3 *db, struct lkt_win *win, char *id_str, enum mpd_idle_flag return false; } + /* If one day we allow suppression of the current kara, will need the `win` + pointer to reload the kara in the same position (but the kara won't be + the same). */ + database_queue_current_kara(db, NULL, &uri); + if (id == (long) uri) { + fprintf(stderr, " . command_delid: Can't delete the currently playing kara\n"); + return false; + } + return database_queue_del_id(db, id); } diff --git a/src/database/queue.c b/src/database/queue.c index 473a03df..1ec0e429 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -53,10 +53,10 @@ error: } bool -database_queue_current_kara(sqlite3 *db, struct kara_metadata *res) +database_queue_current_kara(sqlite3 *db, struct kara_metadata *res, int *id) { static const char *SQL_STMT = - "SELECT song_name, source_name, category, language, author_name, song_type, song_number" + "SELECT song_name, source_name, category, language, author_name, song_type, song_number, kara_id" " FROM kara" " JOIN queue_ ON kara_id = kara.id" " JOIN queue_state ON current = position"; @@ -64,9 +64,12 @@ database_queue_current_kara(sqlite3 *db, struct kara_metadata *res) int ret = false; SQLITE_PREPARE(db, stmt, SQL_STMT, error); - memset(res, 0, sizeof(struct kara_metadata)); if (sqlite3_step(stmt) == SQLITE_ROW) { + /* Here use gotos because of optimisations done by compilators. + Most of the time it won't be NULL. */ + if (!res) + goto no_metadata; strncpy(res->song_name, (const char *) sqlite3_column_text(stmt, 0), LEKTOR_TAG_MAX - 1); strncpy(res->source_name, (const char *) sqlite3_column_text(stmt, 1), LEKTOR_TAG_MAX - 1); strncpy(res->category, (const char *) sqlite3_column_text(stmt, 2), LEKTOR_TAG_MAX - 1); @@ -74,6 +77,10 @@ database_queue_current_kara(sqlite3 *db, struct kara_metadata *res) strncpy(res->author_name, (const char *) sqlite3_column_text(stmt, 4), LEKTOR_TAG_MAX - 1); strncpy(res->song_type, (const char *) sqlite3_column_text(stmt, 5), LEKTOR_TAG_MAX - 1); res->song_number = sqlite3_column_int(stmt, 6); +no_metadata: + /* Most of the time this will be NULL. */ + if (id) + *id = sqlite3_column_int(stmt, 7); } else { fprintf(stderr, " ! database_queue_current_kara: failed: %s\n", sqlite3_errmsg(db)); @@ -307,14 +314,16 @@ bool database_queue_del_id(sqlite3 *db, int id) { static const char *SQL_TEMPLATE = - "WITH before(pos) AS (SELECT position FROM queue_ JOIN queue_state WHERE position < current ORDER BY position DESC LIMIT 1)" + "BEGIN TRANSACTION;" + "WITH before(pos) AS (SELECT position FROM queue_ JOIN queue_state WHERE position < current ORDER BY position DESC LIMIT 1) " "UPDATE queue_state SET current = CASE" " WHEN current IS NULL THEN NULL" - " ELSE (SELECT pos FROM before)" - "END WHERE current >= (SELECT position FROM queue_ WHERE kara_id = %d);" - "DELETE FROM queue WHERE kara_id = %d;"; + " ELSE (SELECT pos FROM before) " + "END WHERE current > (SELECT position FROM queue_ WHERE kara_id = %d);" + "DELETE FROM queue WHERE kara_id = %d;" + "COMMIT TRANSACTION;"; char SQL[LKT_MAX_SQLITE_STATEMENT]; - snprintf(SQL, LKT_MAX_SQLITE_STATEMENT - 1, SQL_TEMPLATE, id, id); + snprintf(SQL, LKT_MAX_SQLITE_STATEMENT - 1, SQL_TEMPLATE, id, id, id); SQL[LKT_MAX_SQLITE_STATEMENT - 1] = '\0'; SQLITE_EXEC(db, SQL, error); return true; -- GitLab