Improve code to recreate the IME DB file when the DB file is corrupted 72/158372/2
authorInHong Han <inhong1.han@samsung.com>
Mon, 30 Oct 2017 06:09:01 +0000 (15:09 +0900)
committerInHong Han <inhong1.han@samsung.com>
Mon, 6 Nov 2017 01:24:20 +0000 (10:24 +0900)
Change-Id: I0245200539282336060217271b6bee2066e17e4b
(cherry picked from commit 7c0233c1f726cd76af85bf5efaeea01c1fd9e58f)

ism/src/isf_query_utility.cpp

index 8eb9daa..a1240bd 100644 (file)
@@ -78,10 +78,13 @@ using namespace scim;
 static struct {
     const char* pPath;
     sqlite3* pHandle;
+    bool need_reset;
 } databaseInfo = {
-    DB_PATH, NULL
+    DB_PATH, NULL, false
 };
 
+static inline int _db_disconnect(void);
+
 static inline int _begin_transaction(void)
 {
     sqlite3_stmt* pStmt = NULL;
@@ -148,6 +151,18 @@ static inline int _commit_transaction(void)
     return EXIT_SUCCESS;
 }
 
+static inline int _db_integrity_check_cb(void *NotUsed, int argc, char **argv, char **azColName)
+{
+    std::string result_DB_check = argv[0];
+    std::transform(result_DB_check.begin(), result_DB_check.end(), result_DB_check.begin(), ::tolower);
+    if (result_DB_check != "ok") {
+        databaseInfo.need_reset = true;
+        LOGE ("DB integrity check failed\n");
+    }
+
+    return 0;
+}
+
 static inline int _db_create_ime_info(void)
 {
     char* pException = NULL;
@@ -188,6 +203,7 @@ static inline int _db_init(void)
         if (databaseInfo.pHandle)
             db_util_close(databaseInfo.pHandle);
         databaseInfo.pHandle = NULL;
+        databaseInfo.need_reset = true;
         return -EIO;
     }
 
@@ -218,10 +234,16 @@ static inline int _db_init(void)
         static const char* pQuery = "PRAGMA journal_mode = WAL";
         int ret = sqlite3_exec(databaseInfo.pHandle, pQuery, NULL, NULL, &pException);
         if (ret != SQLITE_OK) {
+            databaseInfo.need_reset = true;
             LOGE ("sqlite3_exec returned %d: %s\n", ret, pException);
         }
     }
 
+    if (SQLITE_CORRUPT == sqlite3_exec(databaseInfo.pHandle, "pragma integrity_check",_db_integrity_check_cb, NULL, NULL)) {
+        databaseInfo.need_reset = true;
+        LOGE ("DB has been corrupted.\n");
+    }
+
     return 0;
 }
 
@@ -229,6 +251,13 @@ static inline int _db_connect(void)
 {
     if (!databaseInfo.pHandle) {
         int ret = _db_init();
+        if (databaseInfo.need_reset) {
+            _db_disconnect();
+            databaseInfo.need_reset = false;
+            remove(databaseInfo.pPath);
+            ret = _db_init();
+        }
+
         if (ret < 0)
         {
             LOGE ("_db_init failed. error code=%d\n", ret);