diff --git a/inc/lektor/database.h b/inc/lektor/database.h index d1e31ddf0fb089041450e9b0575a47fb022f2e04..1fe0610ac3812d2edb3b123657694b4cfc2d77da 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -22,6 +22,7 @@ struct lkt_queue_state { int length; }; +/* 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); diff --git a/scripts/init.sql b/scripts/init.sql index 99029bd90404c148daa089cf73b80477b78c8803..285457514f1585114e3412b91a7b73c46e9147fa 100644 --- a/scripts/init.sql +++ b/scripts/init.sql @@ -125,7 +125,7 @@ CREATE TABLE IF NOT EXISTS 'stickers.plt' -- when a kara was here, but was deleted on kurisu. CREATE TABLE IF NOT EXISTS updates - ( job INTEGER NOT NULL CHECK(job > 0) + ( job INTEGER NOT NULL CHECK(job >= 0) , kara_id INTEGER NOT NULL CHECK(kara_id > 0) , PRIMARY KEY (job, kara_id) ) WITHOUT ROWID; diff --git a/src/database/open.c b/src/database/open.c index c6d7a4e62cce3216e7427313eccaa27a04aff9d3..cb3cb0b17d30a6cef6fa7bb9dddca9f0afbeb642 100644 --- a/src/database/open.c +++ b/src/database/open.c @@ -189,37 +189,3 @@ error: LOG_ERROR_SCT("DB", "Failed to init the 'disk' database, path was '%s'", dbpath); return false; } - -void -database_get_update(volatile sqlite3 *db, long *timestamp, long *job, int *current) -{ - static const char *SQL = "SELECT last_update, update_job, last_update > last_end_update FROM misc WHERE id = 42;"; - sqlite3_stmt *stmt; - SQLITE_PREPARE(db, stmt, SQL, error); - SQLITE_STEP_ROW(db, stmt, error); - if (timestamp) - *timestamp = sqlite3_column_int(stmt, 0); - if (job) - *job = sqlite3_column_int(stmt, 1); - if (current) - *current = sqlite3_column_int(stmt, 2); - return; -error: - LOG_WARN_SCT("DB", "Failed to get informations about the last update: %s", sqlite3_errmsg((sqlite3 *) db)); -} - -void -database_stamp(volatile sqlite3 *db) -{ - SQLITE_EXEC(db, "UPDATE misc SET last_update = strftime('%s','now');", error); -error: - return; -} - -void -database_updated(volatile sqlite3 *db) -{ - SQLITE_EXEC(db, "UPDATE misc SET last_end_update = strftime('%s','now'), update_job = update_job + 1;", error); -error: - return; -} diff --git a/src/database/update.c b/src/database/update.c index d5ad26f6ceadbdb7f99648e40be90bd59d5dfd68..9bde1c69e48f48187b390a6be2a75eb5c3f40214 100644 --- a/src/database/update.c +++ b/src/database/update.c @@ -13,8 +13,25 @@ #include <time.h> #include <linux/limits.h> -static bool -database_add_kara(volatile sqlite3 *db, const char *filename) +static inline bool +__add_kara_to_update_job(volatile sqlite3 *db, size_t id) +{ + static const char *SQL = NULL; + if (id) + SQL = "INSERT INTO updates (job, kara_id) SELECT MAX(update_job), ? FROM misc;"; + else + SQL = "INSERT INTO updates (job, kara_id) SELECT MAX(update_job), last_insert_rowid() FROM misc;"; + sqlite3_stmt *stmt; + SQLITE_PREPARE(db, stmt, SQL, error); + SQLITE_BIND_INT(db, stmt, 1, (int) id, error); + SQLITE_STEP_OK(db, stmt, error); + return true; +error: + return false; +} + +static inline bool +__database_add_kara(volatile sqlite3 *db, const char *filename) { RETURN_UNLESS(db || filename, "Invalid argument", false); static const char *SQL_STMT = @@ -26,7 +43,7 @@ database_add_kara(volatile sqlite3 *db, const char *filename) "kara (song_name, source_name, category, song_type, language, file_path, is_new, author_name, author_year, song_number, id)" "SELECT ?, ?, ?, ?, ?, ?, ?, ?, strftime('%s','now'), ?, ?"; sqlite3_stmt *stmt = NULL; - long code = SQLITE_OK, status = false, kara_id; + long code = SQLITE_OK, status = false, kara_id = 0; struct kara_metadata data; time_t the_time = time(NULL); struct tm *the_local_time = localtime(&the_time); @@ -42,6 +59,8 @@ database_add_kara(volatile sqlite3 *db, const char *filename) return false; } + SQLITE_EXEC(db, "BEGIN TRANSACTION;", error); + /* Try to find an id in the filename, reuse of variables, it's ugly */ path[PATH_MAX - 1] = '\0'; memcpy(path, filename, (strlen(filename) + 1) * sizeof(char)); @@ -74,9 +93,15 @@ database_add_kara(volatile sqlite3 *db, const char *filename) goto error; } SQLITE_STEP_DONE(db, stmt, error); - status = true; + sqlite3_finalize(stmt); + + if (__add_kara_to_update_job(db, kara_id)) { + SQLITE_EXEC(db, "COMMIT;", error); + return true; + } error: sqlite3_finalize(stmt); + SQLITE_DO_ROLLBACK(db); return status; } @@ -101,7 +126,7 @@ error: bool database_update_add(volatile sqlite3 *db, const char *kara_path, struct kara_metadata *mdt, uint64_t id, bool avail) { - RETURN_UNLESS(db && kara_path && mdt, "Invalid argument", false); + RETURN_UNLESS(db && kara_path && mdt && id, "Invalid argument", false); static const char *SQL_STMT = "INSERT OR REPLACE INTO " "kara (song_name, source_name, category, song_type, language, file_path, is_new, author_name, author_year, song_number, id, available)" @@ -135,7 +160,7 @@ database_update_add(volatile sqlite3 *db, const char *kara_path, struct kara_met } SQLITE_STEP_DONE(db, stmt, error); - ret = true; + ret = __add_kara_to_update_job(db, id); error: sqlite3_finalize(stmt); error_no_sqlite: @@ -167,7 +192,7 @@ database_update(volatile sqlite3 *db, const char *kara_dir, int check_timestamp) LOG_INFO_SCT("DB", "Skip update of kara '%s' be cause of timestamps", path); continue; } - database_add_kara(db, path); + __database_add_kara(db, path); database_stamp(db); } @@ -182,3 +207,37 @@ database_update(volatile sqlite3 *db, const char *kara_dir, int check_timestamp) closedir(d); return true; } + +void +database_get_update(volatile sqlite3 *db, long *timestamp, long *job, int *current) +{ + static const char *SQL = "SELECT last_update, update_job, last_update > last_end_update FROM misc WHERE id = 42;"; + sqlite3_stmt *stmt; + SQLITE_PREPARE(db, stmt, SQL, error); + SQLITE_STEP_ROW(db, stmt, error); + if (timestamp) + *timestamp = sqlite3_column_int(stmt, 0); + if (job) + *job = sqlite3_column_int(stmt, 1); + if (current) + *current = sqlite3_column_int(stmt, 2); + return; +error: + LOG_WARN_SCT("DB", "Failed to get informations about the last update: %s", sqlite3_errmsg((sqlite3 *) db)); +} + +void +database_stamp(volatile sqlite3 *db) +{ + SQLITE_EXEC(db, "UPDATE misc SET last_update = strftime('%s','now');", error); +error: + return; +} + +void +database_updated(volatile sqlite3 *db) +{ + SQLITE_EXEC(db, "UPDATE misc SET last_end_update = strftime('%s','now'), update_job = update_job + 1;", error); +error: + return; +}