From 8feb88ba089010789171779bcc4d2e938180d200 Mon Sep 17 00:00:00 2001 From: "jiyong.min" Date: Fri, 14 Dec 2018 14:42:33 +0900 Subject: [PATCH] Add to check abnormal database and to restore the database Change-Id: I8b0c2093edc9ccfed43b918113ae1116dac52bcf --- packaging/capi-media-controller.spec | 2 +- svc/include/media_controller_db_util.h | 3 + svc/media_controller_db_util.c | 110 ++++++++++++++++++++++++++++++++- svc/media_controller_svc.c | 50 ++++++++++++++- 4 files changed, 161 insertions(+), 4 deletions(-) diff --git a/packaging/capi-media-controller.spec b/packaging/capi-media-controller.spec index 738e0a8..b272138 100755 --- a/packaging/capi-media-controller.spec +++ b/packaging/capi-media-controller.spec @@ -1,6 +1,6 @@ Name: capi-media-controller Summary: A media controller library in Tizen Native API -Version: 0.1.79 +Version: 0.1.80 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/svc/include/media_controller_db_util.h b/svc/include/media_controller_db_util.h index 24e3711..edc2e18 100755 --- a/svc/include/media_controller_db_util.h +++ b/svc/include/media_controller_db_util.h @@ -21,6 +21,9 @@ int mc_db_util_connect(void **handle, uid_t uid); int mc_db_util_disconnect(void *handle); +int mc_db_util_check_size(uid_t uid); +int mc_db_util_check_integrity(void *handle); +int mc_db_util_remove_db(uid_t uid); int mc_db_util_create_tables(void *handle); int mc_db_util_update_db(void *handle, const char *sql_str); int mc_db_util_delete_whole_server_tables(void *handle); diff --git a/svc/media_controller_db_util.c b/svc/media_controller_db_util.c index aa78f96..363960b 100755 --- a/svc/media_controller_db_util.c +++ b/svc/media_controller_db_util.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "media_controller_private.h" #include "media_controller_db_util.h" @@ -294,7 +296,7 @@ int mc_db_util_connect(void **handle, uid_t uid) *handle = db_handle; char *sql = NULL; - sql = sqlite3_mprintf("%s", "PRAGMA journal_mode = PERSIST"); + sql = sqlite3_mprintf("%s", "PRAGMA journal_mode = OFF"); mc_retvm_if(!MC_STRING_VALID(sql), MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "SQL string is null"); ret = sqlite3_exec(*handle, sql, NULL, NULL, NULL); sqlite3_free(sql); @@ -331,6 +333,112 @@ int mc_db_util_disconnect(void *handle) return MEDIA_CONTROLLER_ERROR_NONE; } +int mc_db_util_check_size(uid_t uid) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + char * db_name = NULL; + struct stat buf; + + db_name = __mc_get_db_name(uid); + + if (db_name == NULL) { + mc_error("error when get db path"); + return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + + if (stat(db_name, &buf) == 0) { + if (buf.st_size == 0) { + mc_stderror("The size of database failed"); + ret = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + } else { + mc_stderror("stat failed"); + ret = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + + MC_SAFE_FREE(db_name); + + return ret; +} + +int mc_db_util_check_integrity(void *handle) +{ + int ret = 0; + sqlite3 *db_handle = (sqlite3 *)handle; + sqlite3_stmt *stmt = NULL; + const char integrity_check_query[] = "PRAGMA integrity_check"; + + mc_retvm_if(db_handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + + ret = sqlite3_prepare_v2(db_handle, integrity_check_query, strlen(integrity_check_query), &stmt, NULL); + if (ret != SQLITE_OK) { + mc_error("prepare error, ret = %d, error = %s", ret, sqlite3_errmsg(db_handle)); + return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_ROW) { + mc_error("integrity_check failed in step"); + sqlite3_finalize(stmt); + return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + + char* check_result = (char*) sqlite3_column_text(stmt, 0); + if (check_result == NULL || strncmp(check_result, "ok", strlen(check_result))) { + mc_error("integrity_check failed - result(%s)\n", check_result); + sqlite3_finalize(stmt); + return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + sqlite3_finalize(stmt); + + return MEDIA_CONTROLLER_ERROR_NONE; +} + +int mc_db_util_remove_db(uid_t uid) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + char * db_name = NULL; + GFile *db_file = NULL; + gboolean result = FALSE; + GError *g_error = NULL; + + mc_debug_fenter(); + + db_name = __mc_get_db_name(uid); + + mc_warning("The db(%d) is abnormal. So it will be removed.", db_name); + + if (db_name == NULL) { + mc_error("error when get db path"); + return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + + db_file = g_file_new_for_path(db_name); + if (db_file == NULL) { + mc_error("could not open file"); + MC_SAFE_FREE(db_name); + return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + MC_SAFE_FREE(db_name); + + result = g_file_delete(db_file, NULL, &g_error); + if (!result) { + mc_error("g_file_delete failed: %s", g_error ? g_error->message : "none"); + ret = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } else { + mc_warning("Abnormal db has been removed."); + } + + if (db_file) + g_object_unref(db_file); + if (g_error) + g_error_free(g_error); + + mc_debug_fleave(); + + return ret; +} + int mc_db_util_create_tables(void *handle) { int ret = MEDIA_CONTROLLER_ERROR_NONE; diff --git a/svc/media_controller_svc.c b/svc/media_controller_svc.c index 1ec5aa5..c8dba7b 100755 --- a/svc/media_controller_svc.c +++ b/svc/media_controller_svc.c @@ -195,6 +195,39 @@ static void _mc_service_deinit(mc_service_t *data) } } +static int _mc_service_check_db(uid_t uid) +{ + int res = MEDIA_CONTROLLER_ERROR_NONE; + void *db_handle = NULL; + + res = mc_db_util_check_size(uid); + if (res != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to check the size of DB"); + return res; + } + + /* Connect media controller DB*/ + res = mc_db_util_connect(&db_handle, uid); + if (res != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to connect DB"); + return res; + } + + res = mc_db_util_check_integrity(db_handle); + if (res != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("check interity failed"); + mc_db_util_disconnect(db_handle); + return res; + } + + /* Disconnect media controller DB*/ + res = mc_db_util_disconnect(db_handle); + if (res != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("Failed to disconnect DB"); + + return MEDIA_CONTROLLER_ERROR_NONE; +} + static int _mc_service_reset_db(uid_t uid) { int res = MEDIA_CONTROLLER_ERROR_NONE; @@ -204,7 +237,7 @@ static int _mc_service_reset_db(uid_t uid) res = mc_db_util_connect(&db_handle, uid); if (res != MEDIA_CONTROLLER_ERROR_NONE) { mc_error("Failed to connect DB"); - return FALSE; + return res; } /* Destroy tables */ @@ -228,6 +261,7 @@ static int _mc_service_reset_db(uid_t uid) res = mc_db_util_disconnect(db_handle); if (res != MEDIA_CONTROLLER_ERROR_NONE) mc_error("Failed to disconnect DB"); + return MEDIA_CONTROLLER_ERROR_NONE; } @@ -628,10 +662,22 @@ gboolean mc_svc_thread(void *data) mc_debug("%d sys get UID[%d]", ret, uid); } + /* Check database */ + ret = _mc_service_check_db(uid); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to check database"); + ret = mc_db_util_remove_db(uid); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to delete abnormal database file"); + _mc_service_deinit(mc_service_data); + return FALSE; + } + } + /* Reset database */ ret = _mc_service_reset_db(uid); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { - mc_error("Failed to create data"); + mc_error("Failed to reset database"); _mc_service_deinit(mc_service_data); return FALSE; } -- 2.7.4