Add supoort for database transactions
authorAbhay agarwal <ay.agarwal@samsung.com>
Thu, 24 Oct 2019 07:58:13 +0000 (13:28 +0530)
committersaerome.kim <saerome.kim@samsung.com>
Fri, 1 Nov 2019 03:54:25 +0000 (12:54 +0900)
Change-Id: I5b1d1d07ad15385d4186647694f4f3bbbeb3aad0
Signed-off-by: Abhay agarwal <ay.agarwal@samsung.com>
packaging/ua-manager.spec
ua-api/src/ua-event-handler.c
ua-daemon/include/ua-manager-database.h
ua-daemon/src/ua-manager-core.c
ua-daemon/src/ua-manager-db.c
ua-daemon/src/ua-manager-device-db.c

index 2acb0e3..315796c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       ua-manager
 Summary:    User awareness manager
-Version:    0.12.3
+Version:    0.12.4
 Release:    1
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
index 682fd95..98a7c94 100644 (file)
@@ -339,7 +339,7 @@ static void __uam_event_handler(GDBusConnection *connection,
                double values[UAM_SENSOR_MAX_VALUES];
 
                g_variant_get(parameters, "(uutiidddd)", &sensor_bitmask, &status, &timestamp,
-                                               &accuracy, &count, &values[0], &values[1],&values[2], &values[3]);
+                                               &accuracy, &count, &values[0], &values[1], &values[2], &values[3]);
 
                UAM_DBG("%d %d %llu %d %d", sensor_bitmask, status, timestamp, accuracy, count);
 
index bf54a02..5c4f947 100644 (file)
@@ -74,6 +74,10 @@ int _uam_db_deinitialize(void);
 /* delete operations */
 int _uam_db_clear(void);
 
+/* transaction operations */
+int __uam_db_begin_transaction(void);
+int __uam_db_end_transaction(gboolean is_success);
+
 /* USER QUERIES */
 
 typedef struct db_user_info {
index e61386c..3c8fe78 100644 (file)
@@ -266,6 +266,7 @@ static void __remove_user_device(gpointer data)
        dev_info.operating_system = device->os;
        g_strlcpy(dev_info.device_id, device->device_id, UAM_DEVICE_ID_MAX_STRING_LEN);
 
+       ret_if(UAM_ERROR_NONE != __uam_db_begin_transaction());
        for (l = device->tech_list; NULL != l; l = g_slist_next(l)) {
                uam_db_tech_info_t *tech = l->data;
                GSList *l1, *l2;
@@ -321,9 +322,12 @@ static void __remove_user_device(gpointer data)
 
                /* Remove device from database */
                if (UAM_ERROR_NONE != _uam_device_db_delete_device_info(
-                                       dev_info.device_id, dev_info.type, dev_info.mac))
+                                       dev_info.device_id, dev_info.type, dev_info.mac)) {
                        UAM_ERR("_uam_device_db_delete_device_info failed");
+                       __uam_db_end_transaction(0);
+               }
        }
+       __uam_db_end_transaction(1);
 
        __free_user_device(device);
 
@@ -1517,6 +1521,7 @@ int _uam_core_service_add_user(const char *svc_name, const char *account)
        retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
        service = l->data;
 
+       retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
        for (l = user->devices; NULL != l; l = g_slist_next(l)) {
                uam_db_device_info_t *device = l->data;
                GSList *l1;
@@ -1546,6 +1551,7 @@ int _uam_core_service_add_user(const char *svc_name, const char *account)
                                                device->discriminant);
                        if (UAM_ERROR_NONE != ret) {
                                UAM_WARN("Device service addition to persistent DB failed");
+                               __uam_db_end_transaction(0);
                                return ret;
                        }
                        ret = _uam_core_update_svc_dev_info(device->device_id,
@@ -1557,6 +1563,8 @@ int _uam_core_service_add_user(const char *svc_name, const char *account)
                }
        }
 
+       __uam_db_end_transaction(1);
+
        FUNC_EXIT;
        return ret;
 }
@@ -1580,6 +1588,7 @@ int _uam_core_service_remove_user(const char *svc_name, const char *account)
        l = g_slist_find_custom(services, svc_name, __compare_svc_name);
        retv_if(NULL == l, UAM_ERROR_INVALID_PARAMETER);
 
+       retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
        for (l = user->devices; NULL != l; l = g_slist_next(l)) {
                uam_db_device_info_t *device = l->data;
                GSList *l1;
@@ -1607,10 +1616,13 @@ int _uam_core_service_remove_user(const char *svc_name, const char *account)
                        mac = __get_mac_addr(tech);
                        /* Remove service-device from DB */
                        if (UAM_ERROR_NONE != _uam_db_delete_device_service_info(
-                                               device->device_id, tech->tech_type, mac, svc_name))
+                                               device->device_id, tech->tech_type, mac, svc_name)) {
                                UAM_WARN("Device service removal from persistent DB failed");
+                               __uam_db_end_transaction(0);
+                       }
                }
        }
+       __uam_db_end_transaction(1);
 
        FUNC_EXIT;
        return UAM_ERROR_NONE;
@@ -2778,6 +2790,7 @@ void _uam_core_handle_presence_detected(unsigned int sensor,
        tech->presence_state = UAM_PRESENCE_STATE_PRESENT;
        tech->timestamp = (unsigned long long)time(NULL);
 
+       ret_if(UAM_ERROR_NONE != __uam_db_begin_transaction());
        /* Check if IP address was updated then update in DB */
        if (UAM_TECH_TYPE_WIFI == dev_info->type) {
                uam_db_address_info_t *addr_info = NULL;
@@ -2811,21 +2824,28 @@ void _uam_core_handle_presence_detected(unsigned int sensor,
 
                        /* Update address in DB */
                        if (UAM_ERROR_NONE != _uam_device_db_update_device_ip_address(dev_info->device_id,
-                                       dev_info->type, dev_info->mac, dev_info->ipv4_addr))
+                                       dev_info->type, dev_info->mac, dev_info->ipv4_addr)) {
                                UAM_WARN("_uam_device_db_update_device_ip_address failed");
+                               __uam_db_end_transaction(0);
+                       }
                }
        }
 
        /* Update database (presence state & timestamp) */
        if (UAM_ERROR_NONE != _uam_device_db_update_device_timestamp(dev_info->device_id,
-                               dev_info->type, dev_info->mac, tech->timestamp))
+                               dev_info->type, dev_info->mac, tech->timestamp)) {
                UAM_WARN("_uam_device_db_update_device_timestamp failed");
+               __uam_db_end_transaction(0);
+       }
 
        if (UAM_ERROR_NONE != _uam_device_db_update_device_presence(dev_info->device_id,
-                               dev_info->type, dev_info->mac, tech->presence_state))
+                               dev_info->type, dev_info->mac, tech->presence_state)) {
                UAM_WARN("_uam_device_db_update_device_presence failed");
+               __uam_db_end_transaction(0);
+       }
 
        __send_user_presence_event(tech, sensor, dev_info->device_id);
+       __uam_db_end_transaction(1);
 
        FUNC_EXIT;
 }
index ac623a9..4bd0651 100644 (file)
@@ -86,6 +86,7 @@
 
 sqlite3 *database_handle;
 static sqlite3_stmt *select_version;
+static int transaction_cnt;
 
 static int __uam_db_exec_sql(char *sql, void *cb)
 {
@@ -423,7 +424,7 @@ int _uam_db_initialize_once(void)
 {
        FUNC_ENTRY;
        char *sql;
-       int ret= UAM_ERROR_NONE;
+       int ret = UAM_ERROR_NONE;
        int max_retries = 2;
 
        do {
@@ -483,6 +484,7 @@ int _uam_db_initialize(void)
        EXEC(UAM_ERROR_NONE, _uam_device_service_db_initialize(), handle_error);
        EXEC(UAM_ERROR_NONE, _uam_adv_db_initialize(), handle_error);
 
+       transaction_cnt = 0;
        FUNC_EXIT;
        return UAM_ERROR_NONE;
 
@@ -524,3 +526,81 @@ int _uam_db_clear(void)
 handle_error:
        return error_code;
 }
+
+int __uam_db_begin_transaction(void)
+{
+       FUNC_ENTRY;
+       char *sql = NULL;
+       int ret = UAM_ERROR_NONE;
+
+       if (transaction_cnt <= 0) {
+               transaction_cnt = 0;
+               sql = sqlite3_mprintf("BEGIN IMMEDIATE TRANSACTION");
+
+               ret = __uam_db_exec_sql(sql, NULL);
+               if (UAM_ERROR_NONE != ret)
+                       UAM_DBG("failed to begin transaction");
+               else
+                       UAM_DBG("Successful to begin transaction");
+
+               sqlite3_free(sql);
+       }
+       transaction_cnt++;
+       UAM_DBG("transaction_cnt: %d", transaction_cnt);
+
+       FUNC_EXIT;
+       return ret;
+}
+
+static int __uam_db_rollback_transaction(void)
+{
+       FUNC_ENTRY;
+       char *sql = NULL;
+       int ret = UAM_ERROR_NONE;
+
+       sql = sqlite3_mprintf("ROLLBACK TRANSACTION");
+
+       ret = __uam_db_exec_sql(sql, NULL);
+       if (UAM_ERROR_NONE != ret)
+               UAM_DBG("failed to rollback transaction");
+       else
+               UAM_DBG("Successful to rollback transaction");
+
+       sqlite3_free(sql);
+
+       FUNC_EXIT;
+       return ret;
+}
+
+int __uam_db_end_transaction(gboolean is_success)
+{
+       FUNC_ENTRY;
+       char *sql = NULL;
+       int ret = UAM_ERROR_NONE;
+
+       transaction_cnt--;
+
+       if (0 != transaction_cnt) {
+               UAM_DBG("transaction_cnt: %d", transaction_cnt);
+               return ret;
+       }
+
+       if (false == is_success) {
+               ret = __uam_db_rollback_transaction();
+               return ret;
+       }
+
+       sql = sqlite3_mprintf("COMMIT TRANSACTION");
+
+       ret = __uam_db_exec_sql(sql, NULL);
+       if (UAM_ERROR_NONE != ret) {
+               UAM_DBG("failed to commit transaction");
+               ret = __uam_db_rollback_transaction();
+       } else
+               UAM_DBG("Successful to commit transaction");
+
+       sqlite3_free(sql);
+
+       FUNC_EXIT;
+       return ret;
+}
index 863a483..d24c6c0 100644 (file)
@@ -500,9 +500,11 @@ int _uam_device_db_delete_device_info(const char *device_id, int tech_type,
        DB_ACTION(sqlite3_bind_text(stmt, 3, address, -1, SQLITE_STATIC),
                error_code, handle_error);
 
+       retv_if(UAM_ERROR_NONE != __uam_db_begin_transaction(), UAM_ERROR_DB_FAILED);
        error_code = _uam_db_delete_device_service_mapping(device_id, tech_type, address);
        if (UAM_ERROR_NONE != error_code) {
                UAM_ERR("Failed to delete device service mapping");
+               __uam_db_end_transaction(0);
                goto handle_error;
        }
 
@@ -511,9 +513,13 @@ int _uam_device_db_delete_device_info(const char *device_id, int tech_type,
                UAM_ERR("Failed to delete device info [%d:%s]",
                        sql_ret, sqlite3_errmsg(database_handle));
                error_code = UAM_ERROR_DB_FAILED;
+               __uam_db_end_transaction(0);
+               goto handle_error;
        } else
                UAM_DBG("Device info deleted");
 
+       __uam_db_end_transaction(1);
+
 handle_error:
        sqlite3_reset(stmt);
        FUNC_EXIT;