Support for TLC(Tizen Library cache) (#260)
[platform/core/dotnet/launcher.git] / NativeLauncher / util / db_manager.cc
index f18eb5a..0e05814 100644 (file)
  * limitations under the License.
  */
 
-#include "db_manager.h"
 #include "log.h"
+#include "db_manager.h"
+
+#include <algorithm>
 
 #ifdef  LOG_TAG
 #undef  LOG_TAG
 #endif
 #define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
 
-sqlite3* dbCreate(std::string path)
+static int dbIntegrityCheckCb(void *user_data, int argc, char **argv, char **not_used)
+{
+       bool* is_db_corrupted = static_cast<bool*>(user_data);
+       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") {
+               *is_db_corrupted = true;
+               _ERR("DB integrity check failed");
+               return -1;
+       }
+       _INFO("DB integrity result : %s", argv[0]);
+       return 0;
+}
+
+sqlite3* dbCreate(std::string path, std::string query)
 {
        sqlite3 *sqlite = NULL;
+       bool is_db_corrupted = false;
        int ret = sqlite3_open(path.c_str(), &sqlite);
        if (ret != SQLITE_OK) {
-               _ERR("Sqlite error : [%d] : path [%s]", ret, path.c_str());
-               return NULL;
+               _INFO("DB file is corrupted, start to recover corrupted db");
+               return sqlite;
        }
        ret = sqlite3_exec(sqlite, "PRAGMA journal_mode = PERSIST", NULL, NULL, NULL);
        if (ret != SQLITE_OK) {
-               _ERR("Sqlite error : [%d]", ret);
-               return NULL;
+               _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+               sqlite3_close(sqlite);
+               sqlite = NULL;
+               return sqlite;
        }
-       ret = sqlite3_exec(sqlite, CREATE_TAC_DB_TABLE, NULL, NULL, NULL);
+       ret = sqlite3_exec(sqlite, query.c_str(), NULL, NULL, NULL);
        if (ret != SQLITE_OK) {
-               _ERR("Sqlite error : [%d] : path [%s]", ret, path.c_str());
-               return NULL;
+               _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+               sqlite3_close(sqlite);
+               sqlite = NULL;
+               return sqlite;
+       }
+       ret = sqlite3_exec(sqlite, "PRAGMA integrity_check", dbIntegrityCheckCb, &is_db_corrupted, NULL);
+       if (ret == SQLITE_CORRUPT || is_db_corrupted) {
+               _INFO("DB file is corrupted, start to recover corrupted db");
+               sqlite3_close(sqlite);
+               sqlite = NULL;
+               return sqlite;
        }
        return sqlite;
 }
 
-bool dbOpen(sqlite3 *tac_db, std::string path)
+sqlite3* dbOpen(std::string path)
 {
-       if (!tac_db) {
-               int ret = sqlite3_open(path.c_str(), &tac_db);
-               if (ret != SQLITE_OK) {
-                       _ERR("Sqlite error : [%d] : path [%s]", ret, path.c_str());
-                       return false;
-               }
+       sqlite3 *sqlite = NULL;
+       bool is_db_corrupted = false;
+       int ret = sqlite3_open(path.c_str(), &sqlite);
+       if (ret != SQLITE_OK) {
+               _INFO("DB file is corrupted, start to recover corrupted db");
+               return sqlite;
        }
-       return true;
+       ret = sqlite3_exec(sqlite, "PRAGMA integrity_check", dbIntegrityCheckCb, &is_db_corrupted, NULL);
+       if (ret == SQLITE_CORRUPT || is_db_corrupted) {
+               _INFO("DB file is corrupted, start to recover corrupted db");
+               sqlite3_close(sqlite);
+               sqlite = NULL;
+               return sqlite;
+       }
+       return sqlite;
 }
 
 void dbFinalize(sqlite3_stmt *stmt)
@@ -63,113 +98,100 @@ void dbFinalize(sqlite3_stmt *stmt)
        }
 }
 
-void dbClose(sqlite3 *tac_db)
+void dbClose(sqlite3 *sqlite)
 {
-       if (tac_db) {
-               sqlite3_exec(tac_db, "COMMIT;", NULL, NULL, NULL);
-               sqlite3_close(tac_db);
-               tac_db = NULL;
+       if (sqlite) {
+               sqlite3_exec(sqlite, "COMMIT;", NULL, NULL, NULL);
+               sqlite3_close(sqlite);
+               sqlite = NULL;
        }
 }
 
-void dbRollback(sqlite3 *tac_db)
+void dbRollback(sqlite3 *sqlite)
 {
-       if (tac_db) {
-               sqlite3_exec(tac_db, "ROLLBACK;", NULL, NULL, NULL);
-               sqlite3_close(tac_db);
-               tac_db = NULL;
+       if (sqlite) {
+               sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, NULL);
+               sqlite3_close(sqlite);
+               sqlite = NULL;
        }
 }
 
-bool dbUpdate(sqlite3 *tac_db, std::string path, std::string query)
+bool dbUpdate(sqlite3 *sqlite, std::string path, std::string query)
 {
        sqlite3_stmt *stmt = NULL;
-       if (!dbOpen(tac_db, path)) {
-               return false;
-       }
-       int ret = sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
-       ret = sqlite3_prepare(tac_db, query.c_str(), QUERY_MAX_LEN , &stmt, NULL);
+       int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
+       ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
        if (ret != SQLITE_OK) {
-               _ERR("Sqlite error : [%s, %s]", query.c_str(), sqlite3_errmsg(tac_db));
-               dbClose(tac_db);
+               _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+               dbClose(sqlite);
                return false;
        }
        ret = sqlite3_step(stmt);
        if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
-               _ERR("Sqlite error [%d]", ret);
+               _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
                dbFinalize(stmt);
-               dbClose(tac_db);
+               dbClose(sqlite);
                return false;
        }
        dbFinalize(stmt);
        return true;
 }
 
-bool dbInsert(sqlite3 *tac_db, std::string path, std::string query)
+bool dbInsert(sqlite3 *sqlite, std::string path, std::string query)
 {
        sqlite3_stmt *stmt = NULL;
-       if (!dbOpen(tac_db, path)) {
-               return false;
-       }
-       int ret = sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
-       ret = sqlite3_prepare(tac_db, query.c_str(), QUERY_MAX_LEN , &stmt, NULL);
+       int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
+       ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
        if (ret != SQLITE_OK) {
-               _ERR("Sqlite error : [%s,%s]", query.c_str(), sqlite3_errmsg(tac_db));
-               dbClose(tac_db);
+               _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+               dbClose(sqlite);
                return false;
        }
        ret = sqlite3_step(stmt);
        if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
-               _ERR("Sqlite error [%d]", ret);
+               _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
                dbFinalize(stmt);
-               dbClose(tac_db);
+               dbClose(sqlite);
                return false;
        }
        dbFinalize(stmt);
        return true;
 }
 
-std::vector<std::string> dbSelect(sqlite3 *tac_db, std::string path, std::string query)
+std::vector<std::string> dbSelect(sqlite3 *sqlite, std::string path, std::string query)
 {
        std::vector<std::string> updateDB;
        sqlite3_stmt* stmt = NULL;
        const char* str = NULL;
-       if (!dbOpen(tac_db, path)) {
-               return updateDB;
-       }
-       int ret = sqlite3_prepare_v2(tac_db, query.c_str(), strlen(query.c_str()), &stmt, NULL);
+       int ret = sqlite3_prepare_v2(sqlite, query.c_str(), query.size(), &stmt, NULL);
        if (ret != SQLITE_OK) {
-               _ERR("Sqlite error : [%s,%s]", query.c_str(), sqlite3_errmsg(tac_db));
-               dbClose(tac_db);
+               _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+               dbClose(sqlite);
                return updateDB;
        }
        while (sqlite3_step(stmt) == SQLITE_ROW) {
                str = (const char *) sqlite3_column_text(stmt, 2);
-               _DBG("Nuget : %s", (!str || !strlen(str)) ? NULL : strdup(str));
                updateDB.push_back((!str || !strlen(str)) ? NULL : strdup(str));
        }
        dbFinalize(stmt);
        return updateDB;
 }
 
-bool dbDelete(sqlite3 *tac_db, std::string path, std::string query)
+bool dbDelete(sqlite3 *sqlite, std::string path, std::string query)
 {
        sqlite3_stmt *stmt = NULL;
-       if (!dbOpen(tac_db, path)) {
-               return false;
-       }
-       int ret = sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
-       ret = sqlite3_prepare(tac_db, query.c_str(), QUERY_MAX_LEN , &stmt, NULL);
+       int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
+       ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
        if (ret != SQLITE_OK) {
-               _ERR("Sqlite error : [%s,%s]", query.c_str(), sqlite3_errmsg(tac_db));
-               dbClose(tac_db);
+               _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+               dbClose(sqlite);
                return false;
        }
        ret = sqlite3_step(stmt);
        if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
-               _ERR("Sqlite error [%d]", ret);
+               _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
                dbFinalize(stmt);
-               dbClose(tac_db);
+               dbClose(sqlite);
                return false;
        }
        dbFinalize(stmt);