From 052cf487dbd37114ea2ebe354c60ab17da8253a9 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Thu, 7 May 2020 14:31:39 +0200 Subject: [PATCH] Deal with deleted karas from kurisu --- inc/lektor/database.h | 10 +++++++--- src/database/queue.c | 20 +++++++++++++++++++- src/database/update.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/net/downloader.c | 19 ++++++++++++++++++- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/inc/lektor/database.h b/inc/lektor/database.h index 1fe0610a..7d1fc780 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -23,9 +23,10 @@ struct lkt_queue_state { }; /* Update stuff */ -void database_get_update(volatile sqlite3 *db, long *timestamp, long *job, int *current); -void database_stamp (volatile sqlite3 *db); -void database_updated (volatile sqlite3 *db); +void database_get_update (volatile sqlite3 *db, long *timestamp, long *job, int *current); +void database_stamp (volatile sqlite3 *db); +void database_updated (volatile sqlite3 *db); +void database_deleted_kara(volatile sqlite3 *db, int **kara_id, size_t *len); /* Open correctly a database for lektor. */ bool database_new (volatile sqlite3 **db); @@ -42,6 +43,8 @@ bool database_queue_set_paused (volatile sqlite3 *db, bool paused); bool database_queue_set_current_index(volatile sqlite3 *db, int idx); bool database_queue_get_current_file (volatile sqlite3 *db, char filepath[PATH_MAX]); +bool database_get_kara_path(volatile sqlite3 *db, int id, char filepath[PATH_MAX]); + /* Mpv and database synchronisation. */ bool database_sync_mpv_state(volatile sqlite3 *db, mpv_handle **mpv); @@ -49,6 +52,7 @@ bool database_sync_mpv_state(volatile sqlite3 *db, mpv_handle **mpv); bool database_update (volatile sqlite3 *db, const char *kara_dir, int check_timestamp); bool database_update_add (volatile sqlite3 *db, const char *kara_path, struct kara_metadata *mdt, uint64_t id, bool avail); bool database_update_set_available(volatile sqlite3 *db, uint64_t id); +void database_update_del (volatile sqlite3 *db, int id); /* Control the content of the queue. */ bool database_queue_add_uri(volatile sqlite3 *db, struct lkt_uri *uri, int priority); diff --git a/src/database/queue.c b/src/database/queue.c index 2981a045..abce4426 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -508,8 +508,10 @@ database_queue_get_current_file(volatile sqlite3 *db, char filepath[PATH_MAX]) SQLITE_PREPARE(db, stmt, SQL_STMT, error); code = sqlite3_step(stmt); - if (code == SQLITE_ROW) + if (code == SQLITE_ROW) { strncpy(filepath, (const char *) sqlite3_column_text(stmt, 0), PATH_MAX); + filepath[PATH_MAX - 1] = '\0'; + } else { LOG_ERROR_SCT("DB", "Failed to fetch prev kara: %s", sqlite3_errmsg((sqlite3 *) db)); @@ -522,6 +524,22 @@ error: return status; } +bool +database_get_kara_path(volatile sqlite3 *db, int id, char filepath[PATH_MAX]) +{ + sqlite3_stmt *stmt = NULL; + static const char *SQL = "SELECT file_path FROM kara WHERE id = ?;"; + RETURN_UNLESS(id && db && filepath, "Invalid argument", false); + SQLITE_PREPARE(db, stmt, SQL, error); + SQLITE_BIND_INT(db, stmt, 1, id, error); + SQLITE_STEP_ROW(db, stmt, error); + strncpy(filepath, (const char *) sqlite3_column_text(stmt, 0), PATH_MAX); + filepath[PATH_MAX - 1] = '\0'; + return true; +error: + return false; +} + bool database_queue_shuffle(volatile sqlite3 *db) { diff --git a/src/database/update.c b/src/database/update.c index 5a56f927..1ffe8c1d 100644 --- a/src/database/update.c +++ b/src/database/update.c @@ -208,6 +208,34 @@ database_update(volatile sqlite3 *db, const char *kara_dir, int check_timestamp) return true; } +void +database_deleted_kara(volatile sqlite3 *db, int **kara_id, size_t *len) +{ + static const char *SQL = + "SELECT kara.id, file_path FROM kara WHERE kara.id NOT IN" + "(SELECT kara_id FROM updates JOIN misc ON job = update_job);"; + sqlite3_stmt *stmt = NULL; + *kara_id = (int *) calloc(LKT_DEFAULT_LIST_SIZE, sizeof(int)); + *len = 0; + RETURN_UNLESS(*kara_id, "Out of memory", NOTHING); + SQLITE_PREPARE(db, stmt, SQL, out); + size_t size = LKT_DEFAULT_LIST_SIZE; + void *new; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + if (size == *len) { + new = realloc((void *) kara_id, (*len) * 2 * sizeof(void *)); + GOTO_UNLESS(new, "Out of memory", out); + size *= 2; + *kara_id = new; + } + (*kara_id)[(*len)++] = sqlite3_column_int(stmt, 0); + } + +out: + return; +} + void database_get_update(volatile sqlite3 *db, long *timestamp, long *job, int *current) { @@ -226,6 +254,19 @@ error: LOG_WARN_SCT("DB", "Failed to get informations about the last update: %s", sqlite3_errmsg((sqlite3 *) db)); } +void +database_update_del(volatile sqlite3 *db, int id) +{ + static const char *SQL = "DELETE FROM kara WHERE id = ?;"; + sqlite3_stmt *stmt = NULL; + SQLITE_PREPARE(db, stmt, SQL, error); + SQLITE_BIND_INT(db, stmt, 1, id, error); + SQLITE_STEP_OK(db, stmt, error); + LOG_WARN_SCT("DB", "Deleted kara with id '%d' from database", id); +error: + return; +} + #define sqlite_just_exec(func, query) \ void func (volatile sqlite3 *db) { \ SQLITE_EXEC(db, #query, error); \ diff --git a/src/net/downloader.c b/src/net/downloader.c index 2bda911e..9606701e 100644 --- a/src/net/downloader.c +++ b/src/net/downloader.c @@ -4,6 +4,7 @@ #include <stdio.h> #include <unistd.h> #include <string.h> +#include <strings.h> #include <limits.h> #include <stdlib.h> #include <unistd.h> @@ -371,7 +372,6 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, struct json_objec LOG_INFO_SCT("REPO", "Ignore kara '%ld' with path '%s'", kara.id, kara.filename); continue; } - LOG_WARN_SCT("REPO", "Download kara '%ld' with path '%s'", kara.id, kara.filename); if (!database_update_add((sqlite3 *) db, kara.filename, &kara.mdt, kara.id, false)) { LOG_ERROR_SCT("REPO", "Could not add unavailable kara %ld to db", kara.id); @@ -400,6 +400,21 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, struct json_objec } } +static inline void +__handle_deleted_kara(volatile sqlite3 *db) +{ + size_t len, i; + int *kara_ids; + char filepath[PATH_MAX]; + database_deleted_kara(db, &kara_ids, &len); + + for (i = 0; i < len; ++i) { + if (!database_get_kara_path(db, kara_ids[i], filepath)) + continue; + database_update_del(db, kara_ids[i]); + } +} + void * __repo_get_all_id_async(void *arg) { @@ -411,6 +426,8 @@ __repo_get_all_id_async(void *arg) __handle_got_json(repo->db, repo, json); LOG_INFO_SCT("REPO", "%s", "Finished to download and insert kara list"); json_object_put(json); + __handle_deleted_kara(repo->db); + LOG_INFO_SCT("REPO", "%s", "Finished to deal with deleted kara"); database_updated(repo->db); return NULL; } -- GitLab