Add to check db integrity and restore logic 09/157909/4
authorWonnam Jang <wn.jang@samsung.com>
Fri, 27 Oct 2017 01:19:37 +0000 (10:19 +0900)
committerWonnam Jang <wn.jang@samsung.com>
Fri, 27 Oct 2017 04:30:09 +0000 (13:30 +0900)
Change-Id: Ibf2f91c1eca9a00c43ed80e5c8cb3f5dbb55c12a
Signed-off-by: Wonnam Jang <wn.jang@samsung.com>
client/vc.c
common/vc_cmd_db.c
common/vc_cmd_db.h
common/vc_defs.h
common/vc_info_parser.c
common/vc_json_parser.c [changed mode: 0755->0644]

index cc99912..2afb878 100644 (file)
@@ -51,6 +51,7 @@ static vc_h g_vc = NULL;
 static int g_daemon_pid = 0;
 
 static int g_feature_enabled = -1;
+static bool g_backup = false;
 
 static int g_privilege_allowed = -1;
 static cynara *p_cynara = NULL;
@@ -397,6 +398,8 @@ static void __vc_internal_unprepare(void)
 
 int vc_deinitialize(void)
 {
+       int ret = VC_ERROR_NONE;
+
        if (0 != __vc_get_feature_enabled()) {
                return VC_ERROR_NOT_SUPPORTED;
        }
@@ -439,7 +442,15 @@ int vc_deinitialize(void)
        }
 
        SLOG(LOG_DEBUG, TAG_VCC, "Success: destroy");
-       int ret = vc_db_finalize();
+
+       if (true == g_backup) {
+               ret = vc_db_backup_command();
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to backup command, ret(%d)", ret);
+               }
+       }
+
+       ret = vc_db_finalize();
        if (0 != ret) {
                SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to finalize DB, ret(%d)", ret);
        }
@@ -1111,6 +1122,9 @@ int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type)
                invocation_name = NULL;
        }
 
+       if (VC_COMMAND_TYPE_BACKGROUND == type)
+               g_backup = true;
+
        SLOG(LOG_DEBUG, TAG_VCC, "@@@");
 
        return ret;
index 1105002..5b1face 100644 (file)
@@ -56,12 +56,14 @@ const char* vc_db_tag()
 
 
 //#define DB_PATH tzplatform_mkpath(TZ_USER_DB, ".vc_info.db")
-static sqlite3* db_handle = NULL;
-char* path = NULL;
+static sqlite3* g_db_handle = NULL;
+static sqlite3* g_db_backup_handle = NULL;
+char* g_path = NULL;
+char* g_backup_path = NULL;
 int g_fpid = -1;
 int g_ref_cnt = 0;
 
-static int __vc_db_transaction(const char* transaction)
+static int __vc_db_transaction(sqlite3* db_handle, const char* transaction)
 {
        sqlite3_stmt* pStmt = NULL;
 
@@ -81,25 +83,25 @@ static int __vc_db_transaction(const char* transaction)
        return VC_DB_ERROR_NONE;
 }
 
-static int __vc_db_begin_transaction(void)
+static int __vc_db_begin_transaction(sqlite3* db_handle)
 {
-       int ret = __vc_db_transaction("BEGIN TRANSACTION");
+       int ret = __vc_db_transaction(db_handle, "BEGIN TRANSACTION");
        return ret;
 }
 
-static int __vc_db_rollback_transaction(void)
+static int __vc_db_rollback_transaction(sqlite3* db_handle)
 {
-       int ret = __vc_db_transaction("ROLLBACK TRANSACTION");
+       int ret = __vc_db_transaction(db_handle, "ROLLBACK TRANSACTION");
        return ret;
 }
 
-static int __vc_db_commit_transaction(void)
+static int __vc_db_commit_transaction(sqlite3* db_handle)
 {
-       int ret = __vc_db_transaction("COMMIT TRANSACTION");
+       int ret = __vc_db_transaction(db_handle, "COMMIT TRANSACTION");
        return ret;
 }
 
-static int __vc_db_exec_query(const char* sql)
+static int __vc_db_exec_query(sqlite3* db_handle, const char* sql)
 {
        char* err_msg = NULL;
 
@@ -112,7 +114,7 @@ static int __vc_db_exec_query(const char* sql)
        return VC_DB_ERROR_NONE;
 }
 
-static int __vc_db_delete_commands(int pid, vc_cmd_type_e type, const char* appid)
+static int __vc_db_delete_commands(sqlite3* db_handle, int pid, vc_cmd_type_e type, const char* appid)
 {
        sqlite3_stmt* stmt = NULL;
        char* sql = NULL;
@@ -191,7 +193,7 @@ static int __vc_db_delete_commands(int pid, vc_cmd_type_e type, const char* appi
        return VC_DB_ERROR_NONE;
 }
 
-static int __vc_db_insert_commands(int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
+static int __vc_db_insert_commands(sqlite3* db_handle, int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
 {
        SLOG(LOG_DEBUG, vc_db_tag(), "pid(%d), type(%d)", pid, type);
 
@@ -290,7 +292,7 @@ static int __vc_db_insert_commands(int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
        return VC_DB_ERROR_NONE;
 }
 
-static int __vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list)
+static int __vc_db_get_commands(sqlite3* db_handle, int pid, vc_cmd_type_e type, GSList** cmd_list)
 {
        SLOG(LOG_DEBUG, vc_db_tag(), "pid(%d), type(%d)", pid, type);
 
@@ -500,7 +502,7 @@ static int __vc_db_get_pid(const char* appid, int* pid)
        return VC_DB_ERROR_NONE;
 }
 
-static int __vc_db_insert_result(const char* result_text, int event, const char* msg, bool exclusive, vc_cmd_s* cmd)
+static int __vc_db_insert_result(sqlite3* db_handle, const char* result_text, int event, const char* msg, bool exclusive, vc_cmd_s* cmd)
 {
        SLOG(LOG_DEBUG, vc_db_tag(), "result_text(%s), event(%d), msg(%s), exclusive(%d), cmd(%p)", result_text, event, msg, exclusive, cmd);
 
@@ -707,7 +709,7 @@ static int __vc_db_extract_unfixed_command(char* command, char* fixed, char** te
        return VC_DB_ERROR_NONE;
 }
 
-static int __vc_db_get_result(char** result_text, int* event, char** msg, int pid, char* appid, vc_cmd_list_h vc_cmd_list, bool exclusive)
+static int __vc_db_get_result(sqlite3* db_handle, char** result_text, int* event, char** msg, int pid, char* appid, vc_cmd_list_h vc_cmd_list, bool exclusive)
 {
        int ret = 0;
        sqlite3_stmt* stmt = NULL;
@@ -929,7 +931,7 @@ void __vc_db_demandable_client_free(void* data)
        }
 }
 
-static int __vc_db_get_appid(const char* result, GSList** app_list)
+static int __vc_db_get_appid(sqlite3* db_handle, const char* result, GSList** app_list)
 {
        GSList* temp_app_list = NULL;
 
@@ -1001,7 +1003,7 @@ static int __vc_db_get_appid(const char* result, GSList** app_list)
        return VC_DB_ERROR_NONE;
 }
 
-int __vc_db_get_result_pid_list(const char* result, GSList** pid_list)
+int __vc_db_get_result_pid_list(sqlite3* db_handle, const char* result, GSList** pid_list)
 {
        GSList* temp_pid_list = NULL;
 
@@ -1070,7 +1072,7 @@ int __vc_db_get_result_pid_list(const char* result, GSList** pid_list)
        return VC_DB_ERROR_NONE;
 }
 
-static int __vc_db_append_commands(int pid, int type, vc_cmd_list_h vc_cmd_list)
+static int __vc_db_append_commands(sqlite3* db_handle, int pid, int type, vc_cmd_list_h vc_cmd_list)
 {
        SLOG(LOG_ERROR, vc_db_tag(), "pid(%d), type(%d)", pid, type);
 
@@ -1229,73 +1231,182 @@ static vc_cmd_s* __vc_db_command_copy(vc_cmd_s* src_cmd)
        return temp_cmd;
 }
 
-int vc_db_initialize(void)
+int __vc_db_create_table(sqlite3* db_handle)
 {
-       SLOG(LOG_INFO, vc_db_tag(), "DB initialization");
+       const char* vc_info_sql = "CREATE TABLE IF NOT EXISTS vc_info (id INTEGER PRIMARY KEY AUTOINCREMENT, pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, \
+                                       command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);";
+       const char* vc_result_sql = "CREATE TABLE IF NOT EXISTS vc_result (id INTEGER PRIMARY KEY AUTOINCREMENT, result TEXT, event INTEGER, msg TEXT, exclusive INTEGER,\
+                                       pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);";
 
-       if (0 < g_ref_cnt) {
-               g_ref_cnt++;
-               return VC_DB_ERROR_NONE;
+       int ret = __vc_db_exec_query(db_handle, vc_info_sql);
+       if (ret != VC_DB_ERROR_NONE) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret);
+               return VC_DB_ERROR_OPERATION_FAILED;
        }
+       SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_info_sql);
 
-       path = (char*)calloc(256, sizeof(char));
-       if (NULL == path) {
-               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory");
-               return VC_DB_ERROR_OUT_OF_MEMORY;
+       ret = __vc_db_exec_query(db_handle, vc_result_sql);
+       if (ret != VC_DB_ERROR_NONE) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret);
+               return ret;
        }
+       SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_result_sql);
 
-       /* This should be changed to general DB space - TZ_USER_DB */
-       snprintf(path, 256, "%s/.vc_info.db", VC_RUNTIME_INFO_ROOT);
+       return VC_DB_ERROR_NONE;
+}
 
+int __vc_db_open_db(char** path, sqlite3** db_handle)
+{
        struct stat stat;
-       int ret = db_util_open(path, &db_handle, DB_UTIL_REGISTER_HOOK_METHOD);
+       int ret = db_util_open(*path, db_handle, DB_UTIL_REGISTER_HOOK_METHOD);
        if (ret != SQLITE_OK) {
-               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open db, path = %s, ret %d: %s", path, ret, sqlite3_errmsg(db_handle));
-               if (db_handle) {
-                       db_util_close(db_handle);
-                       db_handle = NULL;
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open db, path = %s, ret %d: %s", *path, ret, sqlite3_errmsg(*db_handle));
+               if (*db_handle) {
+                       db_util_close(*db_handle);
+                       *db_handle = NULL;
                }
 
-               free(path);
-               path = NULL;
+               free(*path);
+               *path = NULL;
                return VC_DB_ERROR_OPERATION_FAILED;
        }
 
-       if (lstat(path, &stat) < 0) {
+       if (lstat(*path, &stat) < 0) {
                char buf_err[256];
                SLOG(LOG_ERROR, vc_db_tag(), "%d", strerror_r(errno, buf_err, sizeof(buf_err)));
-               if (db_handle)
-                       db_util_close(db_handle);
-               db_handle = NULL;
+               if (*db_handle)
+                       db_util_close(*db_handle);
+               *db_handle = NULL;
 
-               free(path);
-               path = NULL;
+               free(*path);
+               *path = NULL;
                return VC_DB_ERROR_OPERATION_FAILED;
        }
 
        if (!S_ISREG(stat.st_mode)) {
                SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] S_ISREG failed");
-               if (db_handle)
-                       db_util_close(db_handle);
-               db_handle = NULL;
+               if (*db_handle)
+                       db_util_close(*db_handle);
+               *db_handle = NULL;
 
-               free(path);
-               path = NULL;
+               free(*path);
+               *path = NULL;
                return VC_DB_ERROR_OPERATION_FAILED;
        }
 
        if (!stat.st_size) {
-           vc_db_create_table();
+               __vc_db_begin_transaction(*db_handle);
+
+               int ret = __vc_db_create_table(*db_handle);
+               if (ret != VC_DB_ERROR_NONE) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret);
+                       __vc_db_rollback_transaction(*db_handle);
+                       return VC_DB_ERROR_OPERATION_FAILED;
+               }
+
+               __vc_db_commit_transaction(*db_handle);
        }
 
-       if (db_handle) {
+       if (*db_handle) {
                char* err_msg = NULL;
                static const const char* sql = "PRAGMA journal_mode = WAL";
-               int ret = sqlite3_exec(db_handle, sql, NULL, NULL, &err_msg);
+               int ret = sqlite3_exec(*db_handle, sql, NULL, NULL, &err_msg);
                if (ret != SQLITE_OK) {
                        SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_exec returned %d: %s", ret, err_msg);
                }
        }
+       return VC_DB_ERROR_NONE;
+}
+
+static int __vc_db_integrity_check_cb(void *NotUsed, int argc, char **argv, char **azColName)
+{
+       SLOG(LOG_INFO, vc_db_tag(), "integrity check cb is called");
+       return 0;
+}
+
+int vc_db_initialize(void)
+{
+       SLOG(LOG_INFO, vc_db_tag(), "DB initialization");
+
+       if (0 < g_ref_cnt) {
+               g_ref_cnt++;
+               return VC_DB_ERROR_NONE;
+       }
+
+       /* For voice control DB */
+       g_path = (char*)calloc(256, sizeof(char));
+       if (NULL == g_path) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory");
+               return VC_DB_ERROR_OUT_OF_MEMORY;
+       }
+       /* This should be changed to general DB space - TZ_USER_DB */
+       snprintf(g_path, 256, "%s/.vc_info.db", VC_RUNTIME_INFO_ROOT);
+
+       /* For Backup DB */
+       g_backup_path = (char*)calloc(256, sizeof(char));
+       if (NULL == g_backup_path) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory");
+               return VC_DB_ERROR_OUT_OF_MEMORY;
+       }
+       snprintf(g_backup_path, 256, "%s/.vc_backup.db", VC_RUNTIME_INFO_ROOT);
+
+       if (0 != __vc_db_open_db(&g_path, &g_db_handle)) {
+               int cnt = 0;
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB");
+               if (0 != remove(g_path)) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[Error] remove file(%s) is failed", g_path);
+               }
+               if (0 != __vc_db_open_db(&g_path, &g_db_handle)) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB");
+               }
+               while (cnt <= 5) {
+                       if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) {
+                               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB");
+                       } else {
+                               break;
+                       }
+                       cnt++;
+               }
+               if (0 != vc_db_restore_command()) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to restore command");
+               }
+       }
+
+       if (SQLITE_CORRUPT == sqlite3_exec(g_db_handle, "pragma integrity_check", __vc_db_integrity_check_cb, NULL, NULL)) {
+               int cnt = 0;
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB");
+               if (0 != remove(g_path)) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[Error] remove file(%s) is failed", g_path);
+               }
+               if (0 != __vc_db_open_db(&g_path, &g_db_handle)) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB");
+               }
+               while (cnt <= 5) {
+                       if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) {
+                               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB");
+                       } else {
+                               break;
+                       }
+                       cnt++;
+               }
+               if (0 != vc_db_restore_command()) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to restore command");
+               }
+       }
+
+       if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB");
+               if (0 != remove(g_backup_path)) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[Error] remove file(%s) is failed", g_backup_path);
+               }
+               if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB");
+               }
+               if (0 != vc_db_backup_command()) {
+                       SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to backup command");
+               }
+       }
+
        g_ref_cnt++;
        return VC_DB_ERROR_NONE;
 }
@@ -1306,56 +1417,51 @@ int vc_db_finalize(void)
        if (0 != --g_ref_cnt)
                return VC_DB_ERROR_NONE;
 
-       if (NULL != path) {
-               free(path);
-               path = NULL;
+       if (NULL != g_path) {
+               free(g_path);
+               g_path = NULL;
+       }
+
+       if (NULL != g_backup_path) {
+               free(g_backup_path);
+               g_backup_path = NULL;
        }
 
-       if (!db_handle)
+       if (!g_db_handle)
                return 0;
+       db_util_close(g_db_handle);
+       g_db_handle = NULL;
 
-       db_util_close(db_handle);
+       if (!g_db_backup_handle)
+               return 0;
+       db_util_close(g_db_backup_handle);
+       g_db_backup_handle = NULL;
 
-       db_handle = NULL;
        return VC_DB_ERROR_NONE;
 }
 
-int vc_db_create_table(void)
+int vc_db_create_table()
 {
-       __vc_db_begin_transaction();
+       __vc_db_begin_transaction(g_db_handle);
 
-       const char* vc_info_sql = "CREATE TABLE IF NOT EXISTS vc_info (id INTEGER PRIMARY KEY AUTOINCREMENT, pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, \
-                                       command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);";
-       const char* vc_result_sql = "CREATE TABLE IF NOT EXISTS vc_result (id INTEGER PRIMARY KEY AUTOINCREMENT, result TEXT, event INTEGER, msg TEXT, exclusive INTEGER,\
-                                       pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);";
-
-       int ret = __vc_db_exec_query(vc_info_sql);
+       int ret = __vc_db_create_table(g_db_handle);
        if (ret != VC_DB_ERROR_NONE) {
                SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret);
-               __vc_db_rollback_transaction();
+               __vc_db_rollback_transaction(g_db_handle);
                return VC_DB_ERROR_OPERATION_FAILED;
        }
-       SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_info_sql);
 
-       ret = __vc_db_exec_query(vc_result_sql);
-       if (ret != VC_DB_ERROR_NONE) {
-               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret);
-               __vc_db_rollback_transaction();
-               return ret;
-       }
-       SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_result_sql);
-
-       __vc_db_commit_transaction();
+       __vc_db_commit_transaction(g_db_handle);
        return VC_DB_ERROR_NONE;
 }
 
-int vc_db_delete_table(const char* table)
+int __vc_db_delete_table(sqlite3* db_handle, const char* table)
 {
        char* sql = NULL;
-       if (0 == strncmp(table, "result", strlen(table))) {
+       if (0 == strncmp(table, VC_RESULT_TABLE, strlen(table))) {
                sql = strdup("DELETE FROM vc_result;");
-       } else if (0 == strncmp(table, "command", strlen(table))) {
-               sql = strdup("DELETE_FROM vc_info;");
+       } else if (0 == strncmp(table, VC_INFO_TABLE, strlen(table))) {
+               sql = strdup("DELETE FROM vc_info;");
        } else {
                return VC_DB_ERROR_INVALID_PARAMETER;
        }
@@ -1365,12 +1471,9 @@ int vc_db_delete_table(const char* table)
                return VC_DB_ERROR_OUT_OF_MEMORY;
        }
 
-       __vc_db_begin_transaction();
-
-       int ret = __vc_db_exec_query(sql);
+       int ret = __vc_db_exec_query(db_handle, sql);
        if (ret != VC_DB_ERROR_NONE) {
                SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table, %d", ret);
-               __vc_db_rollback_transaction();
                free(sql);
                sql = NULL;
                return ret;
@@ -1379,9 +1482,9 @@ int vc_db_delete_table(const char* table)
        free(sql);
        sql = NULL;
 
-       if (0 == strncmp(table, "result", strlen(table))) {
+       if (0 == strncmp(table, VC_RESULT_TABLE, strlen(table))) {
                sql = strdup("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='vc_result';");
-       } else if (0 == strncmp(table, "command", strlen(table))) {
+       } else if (0 == strncmp(table, VC_INFO_TABLE, strlen(table))) {
                sql = strdup("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='vc_info';");
        }
 
@@ -1390,38 +1493,52 @@ int vc_db_delete_table(const char* table)
                return VC_DB_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = __vc_db_exec_query(sql);
+       ret = __vc_db_exec_query(db_handle, sql);
        if (ret != VC_DB_ERROR_NONE) {
                SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table, %d", ret);
-               __vc_db_rollback_transaction();
                free(sql);
                sql = NULL;
                return ret;
        }
 
        SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", sql);
-       __vc_db_commit_transaction();
 
        free(sql);
        sql = NULL;
        return VC_DB_ERROR_NONE;
 }
 
+int vc_db_delete_table(const char* table)
+{
+       __vc_db_begin_transaction(g_db_handle);
+
+       int ret = __vc_db_delete_table(g_db_handle, table);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table");
+               __vc_db_rollback_transaction(g_db_handle);
+               return ret;
+       }
+
+       __vc_db_commit_transaction(g_db_handle);
+
+       return VC_DB_ERROR_NONE;
+}
+
 int vc_db_begin_transaction(void)
 {
-       int ret = __vc_db_begin_transaction();
+       int ret = __vc_db_begin_transaction(g_db_handle);
        return ret;
 }
 
 int vc_db_rollback_transaction(void)
 {
-       int ret = __vc_db_rollback_transaction();
+       int ret = __vc_db_rollback_transaction(g_db_handle);
        return ret;
 }
 
 int vc_db_commit_transaction(void)
 {
-       int ret = __vc_db_commit_transaction();
+       int ret = __vc_db_commit_transaction(g_db_handle);
        return ret;
 }
 
@@ -1562,7 +1679,7 @@ static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cm
        return VC_DB_ERROR_NONE;
 }
 
-int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
+static int __vc_db_insert_command(sqlite3* db_handle, int pid, vc_cmd_type_e type, vc_cmd_s* cmd, bool skip_invocation)
 {
        GSList* cmd_list = NULL;
        char* fixed_cmd = NULL;
@@ -1597,7 +1714,7 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
                                else
                                        tmp_cmd->fixed = NULL;
 
-                               ret = __vc_db_insert_commands(pid, type, tmp_cmd);
+                               ret = __vc_db_insert_commands(db_handle, pid, type, tmp_cmd);
                                if (ret != VC_DB_ERROR_NONE) {
                                        if (NULL != fixed_cmd) {
                                                free(fixed_cmd);
@@ -1607,7 +1724,7 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
                                        break;
                                }
 
-                               if (VC_COMMAND_TYPE_BACKGROUND == type && NULL != tmp_cmd->invocation_name) {
+                               if (VC_COMMAND_TYPE_BACKGROUND == type && NULL != tmp_cmd->invocation_name && false == skip_invocation) {
                                        char temp[256] = {0, };
                                        snprintf(temp, 256, "%s %s", tmp_cmd->invocation_name, tmp_cmd->command);
                                        if (NULL != tmp_cmd->command)
@@ -1615,7 +1732,7 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
 
                                        tmp_cmd->command = strdup(temp);
 
-                                       ret = __vc_db_insert_commands(pid, type, tmp_cmd);
+                                       ret = __vc_db_insert_commands(db_handle, pid, type, tmp_cmd);
                                        if (ret != VC_DB_ERROR_NONE) {
                                                if (NULL != fixed_cmd) {
                                                        free(fixed_cmd);
@@ -1661,7 +1778,17 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd)
        return VC_DB_ERROR_NONE;
 }
 
-int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name)
+int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd, bool skip_invocation)
+{
+       int ret = __vc_db_insert_command(g_db_handle, pid, type, cmd, skip_invocation);
+       if (0 != ret) {
+               SLOG(LOG_DEBUG, vc_db_tag(), "[ERROR] Fail to insert command, %d", ret);
+       }
+       return ret;
+}
+
+
+static int __vc_db_insert_commands_list(sqlite3* db_handle, int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name, bool skip_invocation)
 {
        GSList *iter = NULL;
        vc_cmd_s *temp_cmd;
@@ -1672,8 +1799,6 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch
 
        SLOG(LOG_DEBUG, vc_db_tag(), "list count : %d", count);
 
-       __vc_db_begin_transaction();
-
        for (i = 0; i < count; i++) {
                if (NULL == iter)
                        break;
@@ -1689,10 +1814,9 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch
                        if (NULL != invocation_name)
                                temp_cmd->invocation_name = strdup(invocation_name);
 
-                       int ret = vc_db_insert_command(pid, type, temp_cmd);
+                       int ret = __vc_db_insert_command(db_handle, pid, type, temp_cmd, skip_invocation);
                        if (ret != VC_DB_ERROR_NONE) {
                                SLOG(LOG_ERROR, vc_db_tag(), "Fail to insert command, ret(%d)", ret);
-                               __vc_db_rollback_transaction();
                                return ret;
                        }
                } else {
@@ -1701,22 +1825,35 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch
                iter = g_slist_next(iter);
        }
 
-       __vc_db_commit_transaction();
+       return VC_DB_ERROR_NONE;
+}
+
+int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name, bool skip_invocation)
+{
+       __vc_db_begin_transaction(g_db_handle);
+
+       int ret = __vc_db_insert_commands_list(g_db_handle, pid, type, cmd_list, invocation_name, false);
+       if (ret != VC_DB_ERROR_NONE) {
+               __vc_db_rollback_transaction(g_db_handle);
+               return ret;
+       }
+
+       __vc_db_commit_transaction(g_db_handle);
 
        return VC_DB_ERROR_NONE;
 }
 
 int vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list)
 {
-       __vc_db_begin_transaction();
+       __vc_db_begin_transaction(g_db_handle);
 
-       int ret = __vc_db_get_commands(pid, type, cmd_list);
+       int ret = __vc_db_get_commands(g_db_handle, pid, type, cmd_list);
        if (ret != VC_DB_ERROR_NONE) {
-               __vc_db_rollback_transaction();
+               __vc_db_rollback_transaction(g_db_handle);
                return ret;
        }
 
-       __vc_db_commit_transaction();
+       __vc_db_commit_transaction(g_db_handle);
        return VC_DB_ERROR_NONE;
 }
 
@@ -1727,18 +1864,18 @@ int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_
                return VC_DB_ERROR_INVALID_PARAMETER;
        }
 
-       int ret = vc_db_delete_table("result");
+       int ret = vc_db_delete_table(VC_RESULT_TABLE);
        if (0 != ret)
                LOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table");
 
        if (NULL == vc_cmd_list) {
-               __vc_db_begin_transaction();
-               int ret = __vc_db_insert_result(result_text, event, msg, exclusive, NULL);
+               __vc_db_begin_transaction(g_db_handle);
+               int ret = __vc_db_insert_result(g_db_handle, result_text, event, msg, exclusive, NULL);
                if (ret != VC_DB_ERROR_NONE) {
-                       __vc_db_rollback_transaction();
+                       __vc_db_rollback_transaction(g_db_handle);
                        return ret;
                }
-               __vc_db_commit_transaction();
+               __vc_db_commit_transaction(g_db_handle);
                return VC_DB_ERROR_NONE;
        }
 
@@ -1760,13 +1897,13 @@ int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_
                vc_cmd_s* temp_cmd = NULL;
                temp_cmd = (vc_cmd_s*)vc_command;
 
-               __vc_db_begin_transaction();
-               ret = __vc_db_insert_result(result_text, event, msg, exclusive, temp_cmd);
+               __vc_db_begin_transaction(g_db_handle);
+               ret = __vc_db_insert_result(g_db_handle, result_text, event, msg, exclusive, temp_cmd);
                if (ret != VC_DB_ERROR_NONE) {
-                       __vc_db_rollback_transaction();
+                       __vc_db_rollback_transaction(g_db_handle);
                        return ret;
                }
-               __vc_db_commit_transaction();
+               __vc_db_commit_transaction(g_db_handle);
 
                ret = vc_cmd_list_next(vc_cmd_list);
        }
@@ -1776,11 +1913,11 @@ int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_
 
 int vc_db_get_result(char** result_text, int* event, char** msg, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive)
 {
-       __vc_db_begin_transaction();
+       __vc_db_begin_transaction(g_db_handle);
 
-       int ret = __vc_db_get_result(result_text, event, msg, pid, NULL, vc_cmd_list, exclusive);
+       int ret = __vc_db_get_result(g_db_handle, result_text, event, msg, pid, NULL, vc_cmd_list, exclusive);
        if (ret != VC_DB_ERROR_NONE) {
-               __vc_db_rollback_transaction();
+               __vc_db_rollback_transaction(g_db_handle);
                return VC_DB_ERROR_OPERATION_FAILED;
        }
 
@@ -1797,9 +1934,9 @@ int vc_db_get_result(char** result_text, int* event, char** msg, int pid, vc_cmd
                        if (APP_MANAGER_ERROR_NONE != ret) {
                                SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] fail to get app id, ret(%d), pid(%d)", ret, pid);
                        }
-                       ret = __vc_db_get_result(result_text, event, msg, pid, appid, vc_cmd_list, exclusive);
+                       ret = __vc_db_get_result(g_db_handle, result_text, event, msg, pid, appid, vc_cmd_list, exclusive);
                        if (ret != VC_DB_ERROR_NONE) {
-                               __vc_db_rollback_transaction();
+                               __vc_db_rollback_transaction(g_db_handle);
                                return ret;
                        }
                        if (NULL != appid) {
@@ -1808,63 +1945,122 @@ int vc_db_get_result(char** result_text, int* event, char** msg, int pid, vc_cmd
                        }
                }
        }
-       __vc_db_commit_transaction();
+       __vc_db_commit_transaction(g_db_handle);
        return VC_DB_ERROR_NONE;
 }
 
 int vc_db_get_appid_list(const char* result, GSList** app_list)
 {
-       __vc_db_begin_transaction();
+       __vc_db_begin_transaction(g_db_handle);
 
-       int ret = __vc_db_get_appid(result, app_list);
+       int ret = __vc_db_get_appid(g_db_handle, result, app_list);
        if (ret != VC_DB_ERROR_NONE) {
-               __vc_db_rollback_transaction();
+               __vc_db_rollback_transaction(g_db_handle);
                return ret;
        }
 
-       __vc_db_commit_transaction();
+       __vc_db_commit_transaction(g_db_handle);
        return VC_DB_ERROR_NONE;
 }
 
 int vc_db_get_result_pid_list(const char* result, GSList** pid_list)
 {
-       __vc_db_begin_transaction();
+       __vc_db_begin_transaction(g_db_handle);
 
-       int ret = __vc_db_get_result_pid_list(result, pid_list);
+       int ret = __vc_db_get_result_pid_list(g_db_handle, result, pid_list);
        if (ret != VC_DB_ERROR_NONE) {
-               __vc_db_rollback_transaction();
+               __vc_db_rollback_transaction(g_db_handle);
                return ret;
        }
 
-       __vc_db_commit_transaction();
+       __vc_db_commit_transaction(g_db_handle);
        return VC_DB_ERROR_NONE;
 }
 
 int vc_db_append_commands(int pid, int type, vc_cmd_list_h vc_cmd_list)
 {
-       __vc_db_begin_transaction();
+       __vc_db_begin_transaction(g_db_handle);
 
-       int ret = __vc_db_append_commands(pid, type, vc_cmd_list);
+       int ret = __vc_db_append_commands(g_db_handle, pid, type, vc_cmd_list);
        if (ret != VC_DB_ERROR_NONE) {
-               __vc_db_rollback_transaction();
+               __vc_db_rollback_transaction(g_db_handle);
                return ret;
        }
 
-       __vc_db_commit_transaction();
+       __vc_db_commit_transaction(g_db_handle);
        return VC_DB_ERROR_NONE;
 }
 
 int vc_db_delete_commands(int pid, vc_cmd_type_e type, char* appid)
 {
-       __vc_db_begin_transaction();
+       __vc_db_begin_transaction(g_db_handle);
 
        int ret = 0;
-       ret = __vc_db_delete_commands(pid, type, appid);
+       ret = __vc_db_delete_commands(g_db_handle, pid, type, appid);
+       if (ret != VC_DB_ERROR_NONE) {
+               __vc_db_rollback_transaction(g_db_handle);
+               return ret;
+       }
+
+       __vc_db_commit_transaction(g_db_handle);
+       return VC_DB_ERROR_NONE;
+}
+
+int vc_db_backup_command()
+{
+       GSList* list = NULL;
+
+       __vc_db_begin_transaction(g_db_backup_handle);
+
+       int ret = __vc_db_delete_table(g_db_backup_handle, VC_INFO_TABLE);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table");
+               __vc_db_rollback_transaction(g_db_backup_handle);
+               return ret;
+       }
+       __vc_db_commit_transaction(g_db_backup_handle);
+
+       ret = vc_db_get_commands(-1, VC_COMMAND_TYPE_BACKGROUND, &list);
+       if (ret != VC_DB_ERROR_NONE) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get commands");
+               return ret;
+       }
+
+       __vc_db_begin_transaction(g_db_backup_handle);
+
+       ret = __vc_db_insert_commands_list(g_db_backup_handle, -1, VC_COMMAND_TYPE_BACKGROUND, list, NULL, true);
+       if (ret != VC_DB_ERROR_NONE) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to insert command list to backup db");
+               __vc_db_rollback_transaction(g_db_backup_handle);
+               return ret;
+       }
+
+       __vc_db_commit_transaction(g_db_backup_handle);
+
+       SLOG(LOG_ERROR, vc_db_tag(), "[SUCCESS] Backup commands");
+       return VC_DB_ERROR_NONE;
+}
+
+int vc_db_restore_command()
+{
+       GSList* list = NULL;
+
+       __vc_db_begin_transaction(g_db_backup_handle);
+
+       int ret = __vc_db_get_commands(g_db_backup_handle, -1, VC_COMMAND_TYPE_BACKGROUND, &list);
+       if (ret != VC_DB_ERROR_NONE) {
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get commands from backup db");
+               __vc_db_rollback_transaction(g_db_backup_handle);
+               return ret;
+       }
+       __vc_db_commit_transaction(g_db_backup_handle);
+
+       ret = vc_db_insert_commands_list(-1, VC_COMMAND_TYPE_BACKGROUND, list, NULL, true);
        if (ret != VC_DB_ERROR_NONE) {
-               __vc_db_rollback_transaction();
+               SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to insert command list");
                return ret;
        }
 
-       __vc_db_commit_transaction();
+       SLOG(LOG_ERROR, vc_db_tag(), "[SUCCESS] Restore commands");
        return VC_DB_ERROR_NONE;
 }
index b7a97df..0a4f76a 100644 (file)
@@ -43,6 +43,9 @@ typedef enum {
        VC_DB_ERROR_SERVICE_RESET       = TIZEN_ERROR_VOICE_CONTROL | 0x018     /**< Service daemon reset (Since 3.0) */
 } vc_db_error_e;
 
+#define VC_INFO_TABLE  "vc_info"
+#define VC_RESULT_TABLE        "vc_result"
+
 typedef struct _deactivated_app_s {
        char*   appid;
 } vc_deactivated_app_s;
@@ -61,9 +64,9 @@ int vc_db_rollback_transaction(void);
 
 int vc_db_commit_transaction(void);
 
-int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd);
+int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd, bool skip_invocation);
 
-int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name);
+int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name, bool skip_invocation);
 
 int vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list);
 
@@ -81,6 +84,9 @@ int vc_db_select_by_pid(int pid);
 
 int vc_db_delete_commands(int pid, vc_cmd_type_e type, char* appid);
 
+int vc_db_backup_command();
+
+int vc_db_restore_command();
 
 #ifdef __cplusplus
 }
index 7947a92..ed3a88a 100755 (executable)
@@ -168,35 +168,35 @@ extern "C" {
 * Definitions for configuration
 *******************************************************************************************/
 
-#define VC_DAEMON_PATH                 tzplatform_mkpath(TZ_SYS_BIN, "vc-daemon")
+#define VC_DAEMON_PATH                 tzplatform_mkpath(tzplatform_getid("TZ_SYS_BIN"), "vc-daemon")
 
-#define VC_CONFIG_DEFAULT              tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/vc-config.xml")
+#define VC_CONFIG_DEFAULT              tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/vc-config.xml")
 
-#define VC_DEFAULT_BASE                        tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0")
+#define VC_DEFAULT_BASE                        tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0")
 
-#define VC_DEFAULT_ENGINE              tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/engine")
+#define VC_DEFAULT_ENGINE              tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/engine")
 
-#define VC_DEFAULT_ENGINE_SETTING      tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/engine-setting")
+#define VC_DEFAULT_ENGINE_SETTING      tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/engine-setting")
 
-#define VC_DEFAULT_ENGINE_INFO         tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/engine-info")
+#define VC_DEFAULT_ENGINE_INFO         tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/engine-info")
 
-#define VC_CONFIG_BASE                 tzplatform_mkpath(TZ_USER_HOME, "share/.voice")
+#define VC_CONFIG_BASE                 tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice")
 
-#define VC_CONFIG                      tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc-config.xml")
+#define VC_CONFIG                      tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc-config.xml")
 
-#define VC_RUNTIME_INFO_ROOT           tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc")
+#define VC_RUNTIME_INFO_ROOT           tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc")
 
-#define VC_RUNTIME_INFO_FOREGROUND     tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-info-foreground.xml")
+#define VC_RUNTIME_INFO_FOREGROUND     tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-info-foreground.xml")
 
-#define VC_RUNTIME_INFO_DEMANDABLE_LIST        tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-demandable-client.xml")
+#define VC_RUNTIME_INFO_DEMANDABLE_LIST        tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-demandable-client.xml")
 
-#define VC_RUNTIME_INFO_RESULT         tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-result.xml")
+#define VC_RUNTIME_INFO_RESULT         tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-result.xml")
 
-#define VC_RUNTIME_INFO_EX_RESULT      tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-ex-result.xml")
+#define VC_RUNTIME_INFO_EX_RESULT      tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-ex-result.xml")
 
-#define VC_RUNTIME_INFO_NLU_RESULT     tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-nlu-result.xml")
+#define VC_RUNTIME_INFO_NLU_RESULT     tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-nlu-result.xml")
 
-#define VC_RUNTIME_INFO_CLIENT         tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-client-info.xml")
+#define VC_RUNTIME_INFO_CLIENT         tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-client-info.xml")
 
 #define VC_NO_FOREGROUND_PID           -1
 #define VC_BASE_LANGUAGE               "en_US"
index 8fda8ae..864f470 100644 (file)
@@ -91,7 +91,7 @@ int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list, char*
                return -1;
        }
 
-       int ret = vc_db_insert_commands_list(pid, type, cmd_list, invocation_name);
+       int ret = vc_db_insert_commands_list(pid, type, cmd_list, invocation_name, false);
        if (0 != ret) {
                SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret);
        }
@@ -357,7 +357,7 @@ int vc_info_parser_get_result(char** result_text, int* event, char** result_mess
 int vc_info_parser_unset_result(bool exclusive)
 {
        int ret = 0;
-       ret = vc_db_delete_table("result");
+       ret = vc_db_delete_table(VC_RESULT_TABLE);
        if (0 != ret) {
                SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to delete result table");
        }
old mode 100755 (executable)
new mode 100644 (file)
index 79e6b31..06386f4
@@ -328,7 +328,7 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati
                        }
                }
 
-               ret = vc_db_insert_command(cmd->pid, type, cmd);
+               ret = vc_db_insert_command(cmd->pid, type, cmd, false);
                if (VC_ERROR_NONE != ret) {
                        SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to insert command into db, type(%s), command(%s)", temp_type, temp_text);
                        if (NULL != cmd->command)               free(cmd->command);