From d58ca7481cea6a60a85f61d32b35099894db2144 Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Tue, 28 Nov 2017 10:57:45 +0900 Subject: [PATCH] Fix logic to recover corrupted db Signed-off-by: Seungha Son Change-Id: I65ec296c7dcf3e14df999f4d51402541af8eff39 --- src/badge_db.c | 109 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/src/badge_db.c b/src/badge_db.c index fa61e33..e05af86 100755 --- a/src/badge_db.c +++ b/src/badge_db.c @@ -30,7 +30,6 @@ #define CREATE_BADGE_TABLE " \ PRAGMA journal_mode = PERSIST; \ PRAGMA synchronous = FULL; \ -PRAGMA integrity_check; \ CREATE TABLE IF NOT EXISTS badge_data ( \ uid INTEGER, \ pkgname TEXT NOT NULL, \ @@ -53,6 +52,54 @@ CREATE TABLE IF NOT EXISTS badge_setting ( \ UNIQUE (uid, pkgname, appid) \ ); " +static bool is_db_corrupted = false; + +static int __check_integrity_cb(void *pid, int argc, char **argv, char **notUsed) +{ + if (!strcmp(argv[0], "ok")) { + ERR("db integrity result : %s" , argv[0]); + is_db_corrupted = true; + return -1; + } + + INFO("db integrity result : %s" , argv[0]); + return 0; +} + +static int __recover_corrupted_db(sqlite3 *db) +{ + int ret = BADGE_ERROR_NONE; + int sql_ret; + char *errmsg = NULL; + + INFO("DB is corrupted, start to recover corrupted db"); + if (db) + sqlite3_close(db); + unlink(BADGE_DB_PATH); + + sql_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, + SQLITE_OPEN_CREATE |SQLITE_OPEN_READWRITE, + NULL); + if (sql_ret != SQLITE_OK) { + ERR("Failed to open badge db[%d]", sql_ret); + unlink(BADGE_DB_PATH); + ret = BADGE_ERROR_FROM_DB; + goto out; + } + + sql_ret = sqlite3_exec(db, CREATE_BADGE_TABLE, NULL, NULL, &errmsg); + if (sql_ret != SQLITE_OK) { + ERR("Failed to exec query[%d][%s]", sql_ret, errmsg); + ret = BADGE_ERROR_FROM_DB; + } + +out: + if (errmsg) + sqlite3_free(errmsg); + + return ret; +} + EXPORT_API int badge_db_init() { @@ -65,65 +112,29 @@ int badge_db_init() SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL); if (sql_ret != SQLITE_OK) { ERR("Failed to open badge db[%d]", sql_ret); - - if (sqlite3_errcode(db) == SQLITE_CORRUPT) { - if (db) - sqlite3_close(db); - unlink(BADGE_DB_PATH); - - sql_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, - SQLITE_OPEN_CREATE |SQLITE_OPEN_READWRITE, - NULL); - if (sql_ret != SQLITE_OK) { - ERR("Failed to open badge db[%d]", sql_ret); - unlink(BADGE_DB_PATH); - ret = BADGE_ERROR_FROM_DB; - goto out; - } - } else { - ret = BADGE_ERROR_FROM_DB; - goto out; - } + ret = BADGE_ERROR_FROM_DB; + goto out; } sql_ret = sqlite3_exec(db, CREATE_BADGE_TABLE, NULL, NULL, &errmsg); if (sql_ret != SQLITE_OK) { ERR("Failed to exec query[%d][%s]", sql_ret, errmsg); + ret = BADGE_ERROR_FROM_DB; + goto out; + } - if (sql_ret == SQLITE_CORRUPT || sql_ret == SQLITE_NOTADB) { - sqlite3_close(db); - unlink(BADGE_DB_PATH); - - sql_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - NULL); - if (sql_ret != SQLITE_OK) { - ERR("Failed to open db[%d]", sql_ret); - unlink(BADGE_DB_PATH); - ret = BADGE_ERROR_FROM_DB; - goto out; - } - - sqlite3_free(errmsg); - sql_ret = sqlite3_exec(db, CREATE_BADGE_TABLE, NULL, - NULL, &errmsg); - if (sql_ret != SQLITE_OK) { - ERR("Failed to exec sqlite, again[%d][%s]", - sql_ret, errmsg); - unlink(BADGE_DB_PATH); - ret = BADGE_ERROR_FROM_DB; - goto out; - } - } else { - ret = BADGE_ERROR_FROM_DB; - goto out; - } + sql_ret = sqlite3_exec(db, "PRAGMA integrity_check", + __check_integrity_cb, NULL, &errmsg); + if (sql_ret != SQLITE_OK || is_db_corrupted) { + ERR("Failed to exec query[%d][%s]", sql_ret, errmsg); + ret = BADGE_ERROR_FROM_DB; } out: + if (sql_ret == SQLITE_CORRUPT || sql_ret == SQLITE_NOTADB || is_db_corrupted) + ret = __recover_corrupted_db(db); if (errmsg) sqlite3_free(errmsg); - if (db) db_util_close(db); -- 2.7.4