Add to check abnormal database and to restore the database 14/195514/3
authorjiyong.min <jiyong.min@samsung.com>
Fri, 14 Dec 2018 05:42:33 +0000 (14:42 +0900)
committerjiyong.min <jiyong.min@samsung.com>
Fri, 14 Dec 2018 07:44:14 +0000 (16:44 +0900)
Change-Id: I8b0c2093edc9ccfed43b918113ae1116dac52bcf

packaging/capi-media-controller.spec
svc/include/media_controller_db_util.h
svc/media_controller_db_util.c
svc/media_controller_svc.c

index 738e0a8..b272138 100755 (executable)
@@ -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
index 24e3711..edc2e18 100755 (executable)
@@ -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);
index aa78f96..363960b 100755 (executable)
@@ -21,6 +21,8 @@
 #include <pwd.h>
 #include <sqlite3.h>
 #include <tzplatform_config.h>
+#include <gio/gio.h>
+#include <sys/stat.h>
 
 #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;
index 1ec5aa5..c8dba7b 100755 (executable)
@@ -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;
        }