From: Seungha Son Date: Tue, 28 Nov 2017 09:49:07 +0000 (+0900) Subject: Fix logic to recover corrupted db X-Git-Tag: submit/tizen/20171205.040511~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4fb09d00bc7a274d8e8587461cf7587fc1b4656f;p=platform%2Fcore%2Fapi%2Fnotification.git Fix logic to recover corrupted db Signed-off-by: Seungha Son Change-Id: I32acf596972e146751ddcbb39fb981a4daa7e317 --- diff --git a/src/notification_db.c b/src/notification_db.c index ff37d90a..267db26f 100755 --- a/src/notification_db.c +++ b/src/notification_db.c @@ -27,78 +27,92 @@ #include #include "notification_db_query.h" +static bool is_db_corrupted = false; + +static int __check_integrity_cb(void *pid, int argc, char **argv, char **notUsed) +{ + if (!strcmp(argv[0], "ok")) { + NOTIFICATION_ERR("db integrity result : %s" , argv[0]); + is_db_corrupted = true; + return -1; + } + + NOTIFICATION_INFO("db integrity result : %s" , argv[0]); + return 0; +} + +static int __recover_corrupted_db(sqlite3 *db) +{ + int ret = NOTIFICATION_ERROR_NONE; + int sql_ret; + char *errmsg = NULL; + + NOTIFICATION_INFO("DB is corrupted, start to recover corrupted db"); + if (db) + sqlite3_close(db); + unlink(DBPATH); + + sql_ret = sqlite3_open_v2(DBPATH, &db, + SQLITE_OPEN_CREATE |SQLITE_OPEN_READWRITE, + NULL); + if (sql_ret != SQLITE_OK) { + NOTIFICATION_ERR("Failed to open db[%d]", sql_ret); + unlink(DBPATH); + ret = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + sql_ret = sqlite3_exec(db, CREATE_NOTIFICATION_TABLE, NULL, NULL, &errmsg); + if (sql_ret != SQLITE_OK) { + NOTIFICATION_ERR("Failed to exec query[%d][%s]", sql_ret, errmsg); + ret = NOTIFICATION_ERROR_FROM_DB; + } + +out: + if (errmsg) + sqlite3_free(errmsg); + + return ret; +} + EXPORT_API int notification_db_init() { - int ret; + int ret = NOTIFICATION_ERROR_NONE; + int sql_ret; sqlite3 *db = NULL; char *errmsg = NULL; - ret = sqlite3_open_v2(DBPATH, &db, + sql_ret = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL); - if (ret != SQLITE_OK) { + if (sql_ret != SQLITE_OK) { /* LCOV_EXCL_START */ NOTIFICATION_ERR("Failed to open db[%d]", ret); - - if (sqlite3_errcode(db) == SQLITE_CORRUPT) { - if (db) - sqlite3_close(db); - unlink(DBPATH); - - ret = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_CREATE | - SQLITE_OPEN_READWRITE, NULL); - if (ret != SQLITE_OK) { - NOTIFICATION_ERR("Failed to open db[%d]", ret); - unlink(DBPATH); - ret = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - } else { - ret = NOTIFICATION_ERROR_FROM_DB; - goto out; - } + ret = NOTIFICATION_ERROR_FROM_DB; + goto out; /* LCOV_EXCL_STOP */ } - ret = sqlite3_exec(db, CREATE_NOTIFICATION_TABLE, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { + sql_ret = sqlite3_exec(db, CREATE_NOTIFICATION_TABLE, NULL, NULL, &errmsg); + if (sql_ret != SQLITE_OK) { /* LCOV_EXCL_START */ NOTIFICATION_ERR("Failed to exec sqlite[%d][%s]", ret, errmsg); - - if (ret == SQLITE_CORRUPT || ret == SQLITE_NOTADB) { - sqlite3_close(db); - unlink(DBPATH); - ret = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_CREATE | - SQLITE_OPEN_READWRITE, NULL); - if (ret != SQLITE_OK) { - NOTIFICATION_ERR("Failed to open db[%d]", ret); - unlink(DBPATH); - ret = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - - sqlite3_free(errmsg); - ret = sqlite3_exec(db, CREATE_NOTIFICATION_TABLE, NULL, - NULL, &errmsg); - if (ret != SQLITE_OK) { - NOTIFICATION_ERR("Failed to exec sqlite, \ - again[%d][%s]", ret, errmsg); - unlink(DBPATH); - ret = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - } else { - ret = NOTIFICATION_ERROR_FROM_DB; - goto out; - } + ret = NOTIFICATION_ERROR_FROM_DB; + goto out; /* LCOV_EXCL_STOP */ } - ret = NOTIFICATION_ERROR_NONE; + sql_ret = sqlite3_exec(db, "PRAGMA integrity_check", + __check_integrity_cb, NULL, &errmsg); + if (sql_ret != SQLITE_OK || is_db_corrupted) { + NOTIFICATION_ERR("Failed to exec query[%d][%s]", sql_ret, errmsg); + ret = NOTIFICATION_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) sqlite3_close(db); diff --git a/src/notification_db_query.h b/src/notification_db_query.h index 6a22573b..ef11a451 100755 --- a/src/notification_db_query.h +++ b/src/notification_db_query.h @@ -22,7 +22,6 @@ #define CREATE_NOTIFICATION_TABLE \ "PRAGMA journal_mode = PERSIST;\n" \ "PRAGMA synchronous = FULL;\n" \ - "PRAGMA integrity_check;\n" \ "CREATE TABLE IF NOT EXISTS noti_list (\n" \ " type INTEGER NOT NULL,\n" \ " layout INTEGER NOT NULL DEFAULT 0,\n" \