From a073f1dc46aa6d3635578d954f6f7392d5fa65c0 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Fri, 4 Mar 2016 20:05:41 +0900 Subject: [PATCH] Tizen 2.4.0 rev3 SDK Public Release --- CMakeLists.txt | 2 +- NOTICE | 0 include/account.h | 8 +- include/account_internal.h | 134 +++++- packaging/libaccounts-svc.spec | 2 +- src/account_offline.c | 960 ++++++++++++++++++++++++++++++++++++++++- 6 files changed, 1074 insertions(+), 32 deletions(-) mode change 100755 => 100644 NOTICE diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d3381d..16b0aa5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,6 @@ SET(EXEC_PREFIX "\${prefix}") SET(LIBDIR "\${prefix}/lib") SET(INCLUDEDIR "\${prefix}/include ") SET(VERSION_MAJOR 0) -SET(VERSION "${VERSION_MAJOR}.3.5") +SET(VERSION "${VERSION_MAJOR}.3.6") ADD_SUBDIRECTORY(src) diff --git a/NOTICE b/NOTICE old mode 100755 new mode 100644 diff --git a/include/account.h b/include/account.h index edbedc5..b503e25 100644 --- a/include/account.h +++ b/include/account.h @@ -1659,10 +1659,10 @@ int account_type_query_label_by_app_id(account_label_cb callback, const char* ap * @brief Retrieves the account provider information with your application ID. * * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.4 @endif - * @privlevel public - * @privilege %http://tizen.org/privilege/account.read - * @param[in] app_id The application ID to search - * @param[out] account_type The account handle which is created by account_type_create() + * @privlevel public + * @privilege %http://tizen.org/privilege/account.read + * @param[in] app_id The application ID to search + * @param[in/out] account_type The account handle which has to be created by account_type_create() before calling this function and released by account_type_destroy() after calling this function. * * @return @c 0 on success, * otherwise a negative error value diff --git a/include/account_internal.h b/include/account_internal.h index 1fc0524..cf81234 100644 --- a/include/account_internal.h +++ b/include/account_internal.h @@ -39,40 +39,43 @@ extern "C" * @brief This file contains the Account API for account management. */ + /** * @internal - * @brief Deletes an account from the account database by package name. + * @brief Updates the account details to the account database. * * @since_tizen 2.4 * @privlevel public * @privilege %http://tizen.org/privilege/account.read \n * %http://tizen.org/privilege/account.write * @remarks This API need both privileges - * @param[in] package_name The package name of account(s) to delete + * @param[in] account The account handle + * @param[in] account_id The account ID to update * * @return @c 0 on success, * otherwise a negative error value * @retval #ACCOUNT_ERROR_NONE Successful + * @retval #ACCOUNT_ERROR_OUT_OF_MEMORY Out of Memory * @retval #ACCOUNT_ERROR_INVALID_PARAMETER Invalid parameter * @retval #ACCOUNT_ERROR_DB_FAILED Database operation failed + * @retval #ACCOUNT_ERROR_RECORD_NOT_FOUND The account to update does not exist * @retval #ACCOUNT_ERROR_PERMISSION_DENIED DB Access fail by permission * @retval #ACCOUNT_ERROR_DATABASE_BUSY SQLite handler is busy * @retval #ACCOUNT_ERROR_DB_NOT_OPENED Account database did not opened * - * @see account_connect() * @see account_insert_to_db() * @see account_delete_from_db_by_id() * @see account_delete_from_db_by_user_name() - * @see account_update_to_db_by_id() + * @see account_delete_from_db_by_package_name() * @see account_update_to_db_by_user_name() */ -int account_delete_from_db_by_package_name_offline(const char *package_name); +int account_update_to_db_by_id_offline(account_h account, int account_id); /** * @internal * @brief Updates the account details to the account database without checking provider's permission. * - * @since_tizen 2.3 + * @since_tizen 2.4 * @privlevel public * @privilege %http://tizen.org/privilege/account.read \n * %http://tizen.org/privilege/account.write @@ -91,9 +94,6 @@ int account_delete_from_db_by_package_name_offline(const char *package_name); * @retval #ACCOUNT_ERROR_DATABASE_BUSY SQLite handler is busy * @retval #ACCOUNT_ERROR_DB_NOT_OPENED Account database did not opened * - * @pre This function requires an open connection to an account service by account_connect(). - * - * @see account_connect() * @see account_insert_to_db() * @see account_delete_from_db_by_id() * @see account_delete_from_db_by_user_name() @@ -393,10 +393,126 @@ int account_unsubscribe_notification_ex(account_subscribe_h account_subscribe); int account_get_total_count_from_db_ex(int *count); /*offline apis*/ + +/** + * @internal + * @brief Retrieves all accounts with the package name using only account library. + * + * @since_tizen 2.4 + * @privlevel public + * @privilege %http://tizen.org/privilege/account.read + * @param[in] callback The callback function to invoke + * @param[in] package_name The package name to search + * @param[in] user_data The user data to be passed to the callback function + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ACCOUNT_ERROR_NONE Successful + * @retval #ACCOUNT_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #ACCOUNT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ACCOUNT_ERROR_DB_FAILED Database operation failed + * @retval #ACCOUNT_ERROR_PERMISSION_DENIED DB Access fail by permission + * @retval #ACCOUNT_ERROR_DATABASE_BUSY SQLite handler is busy + * @retval #ACCOUNT_ERROR_DB_NOT_OPENED Account database did not opened + * + * @pre This function requires an open connection to an account service by account_connect(). + * @post This function invokes account_cb(). + * + * @see account_connect() + * @see account_foreach_account_from_db() + * @see account_query_account_by_account_id() + * @see account_query_account_by_user_name() + * @see account_query_account_by_capability() + */ +int account_query_account_by_package_name_offline(account_cb callback, const char *package_name, void *user_data); + + +/** + * @internal + * @brief Deletes an account from the account database by package name using only account library. + * + * @since_tizen 2.4 + * @privlevel public + * @privilege %http://tizen.org/privilege/account.read \n + * %http://tizen.org/privilege/account.write + * @remarks This API need both privileges + * @param[in] package_name The package name of account(s) to delete + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ACCOUNT_ERROR_NONE Successful + * @retval #ACCOUNT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ACCOUNT_ERROR_DB_FAILED Database operation failed + * @retval #ACCOUNT_ERROR_PERMISSION_DENIED DB Access fail by permission + * @retval #ACCOUNT_ERROR_DATABASE_BUSY SQLite handler is busy + * @retval #ACCOUNT_ERROR_DB_NOT_OPENED Account database did not opened + * + * @see account_connect() + * @see account_insert_to_db() + * @see account_delete_from_db_by_id() + * @see account_delete_from_db_by_user_name() + * @see account_update_to_db_by_id() + * @see account_update_to_db_by_user_name() + */ +int account_delete_from_db_by_package_name_offline(const char *package_name); + +/** + * @internal + * @brief Inserts the account provider details to the database using only account library. + * + * @since_tizen 2.4 + * @privlevel public + * @privilege %http://tizen.org/privilege/account.read \n + * %http://tizen.org/privilege/account.write + * @remarks this API need both privileges + * @param[in] account_type The account handle which is created by account_type_create() \n + * @param[out] account_type_id The account provider ID to be assigned after inserting the account provider handle + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ACCOUNT_ERROR_NONE Successful + * @retval #ACCOUNT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ACCOUNT_ERROR_DB_FAILED Database operation failed + * @retval #ACCOUNT_ERROR_PERMISSION_DENIED DB Access fail by permission + * @retval #ACCOUNT_ERROR_DATABASE_BUSY SQLite handler is busy + * @retval #ACCOUNT_ERROR_DB_NOT_OPENED Account database did not opened + * + * @pre This function requires an open connection to an account service by account_connect(). + * @post account_disconnect() is recommended after insertion. + * + * @see account_connect() + * @see account_disconnect() + */ int account_type_insert_to_db_offline(account_type_h account_type, int* account_type_id); +/** + * @internal + * @brief Deletes the account provider from the account database by application ID using only account library. + * + * @since_tizen 2.4 + * @privlevel public + * @privilege %http://tizen.org/privilege/account.read \n + * %http://tizen.org/privilege/account.write + * @remarks this API need both privileges + * @param[in] app_id The application ID of account provider to be deleted + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ACCOUNT_ERROR_NONE Successful + * @retval #ACCOUNT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ACCOUNT_ERROR_DB_FAILED Database operation failed + * @retval #ACCOUNT_ERROR_PERMISSION_DENIED DB Access fail by permission + * @retval #ACCOUNT_ERROR_DATABASE_BUSY SQLite handler is busy + * @retval #ACCOUNT_ERROR_DB_NOT_OPENED Account database did not opened + * + * @pre This function requires an open connection to an account service by account_connect(). + * + */ int account_type_delete_by_app_id_offline(const char* app_id); + + + /** * @} */ diff --git a/packaging/libaccounts-svc.spec b/packaging/libaccounts-svc.spec index cac7fa0..1e0d414 100644 --- a/packaging/libaccounts-svc.spec +++ b/packaging/libaccounts-svc.spec @@ -1,7 +1,7 @@ Name: libaccounts-svc Summary: Account DB library -Version: 0.3.5 +Version: 0.3.6 Release: 1 Group: TO_BE/FILLED_IN License: Apache-2.0 diff --git a/src/account_offline.c b/src/account_offline.c index 9308c88..25cf02e 100644 --- a/src/account_offline.c +++ b/src/account_offline.c @@ -46,6 +46,16 @@ static sqlite3* g_hAccountDB = NULL; static int g_refCntDB = 0; pthread_mutex_t account_mutex = PTHREAD_MUTEX_INITIALIZER; +static char *_account_get_text(const char *text_data) +{ + char *text_value = NULL; + + if (text_data != NULL) { + text_value = strdup(text_data); + } + return text_value; +} + static const char *_account_db_err_msg() { return sqlite3_errmsg(g_hAccountDB); @@ -1022,9 +1032,434 @@ static void _account_convert_column_to_account(account_stmt hstmt, account_s *ac account_record->user_data_int[4] = _account_query_table_column_int(hstmt, ACCOUNT_FIELD_USER_INT_4); } +static void _account_convert_column_to_capability(account_stmt hstmt, account_capability_s *capability_record) +{ + const char *textbuf = NULL; + + _INFO("start _account_convert_column_to_capability()"); + capability_record->id = _account_query_table_column_int(hstmt, CAPABILITY_FIELD_ID); + + textbuf = _account_query_table_column_text(hstmt, CAPABILITY_FIELD_KEY); + _account_db_data_to_text(textbuf, &(capability_record->type)); + + capability_record->value = _account_query_table_column_int(hstmt, CAPABILITY_FIELD_VALUE); + + textbuf = _account_query_table_column_text(hstmt, CAPABILITY_FIELD_PACKAGE_NAME); + _account_db_data_to_text(textbuf, &(capability_record->package_name)); + + textbuf = _account_query_table_column_text(hstmt, CAPABILITY_FIELD_USER_NAME); + _account_db_data_to_text(textbuf, &(capability_record->user_name)); + + capability_record->account_id = _account_query_table_column_int(hstmt, CAPABILITY_FIELD_ACCOUNT_ID); + _INFO("type = %s, value = %d", capability_record->type, capability_record->value); + _INFO("end _account_convert_column_to_capability()"); +} + +static void _account_convert_column_to_custom(account_stmt hstmt, account_custom_s *custom_record) +{ + _INFO("start _account_convert_column_to_custom()"); + const char *textbuf = NULL; + + custom_record->account_id = _account_query_table_column_int(hstmt, ACCOUNT_CUSTOM_FIELD_ACCOUNT_ID); + + textbuf = _account_query_table_column_text(hstmt, ACCOUNT_CUSTOM_FIELD_APP_ID); + _account_db_data_to_text(textbuf, &(custom_record->app_id)); + + textbuf = _account_query_table_column_text(hstmt, ACCOUNT_CUSTOM_FIELD_KEY); + _account_db_data_to_text(textbuf, &(custom_record->key)); + + textbuf = _account_query_table_column_text(hstmt, ACCOUNT_CUSTOM_FIELD_VALUE); + _account_db_data_to_text(textbuf, &(custom_record->value)); + _INFO("key = %s, value = %s", custom_record->key, custom_record->value); + _INFO("end _account_convert_column_to_custom()"); +} + +static int _account_convert_account_to_sql(account_s *account, account_stmt hstmt, char *sql_value) +{ + _INFO("start"); + + int count = 1; + + /*Caution : Keep insert query orders.*/ + + /* 1. user name*/ + _account_query_bind_text(hstmt, count++, (char*)account->user_name); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], user_name=%s", account->id, account->user_name); + + /* 2. email address*/ + _account_query_bind_text(hstmt, count++, (char*)account->email_address); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], email_address=%s", account->id, account->email_address); + + /* 3. display name*/ + _account_query_bind_text(hstmt, count++, (char*)account->display_name); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], display_name=%s", account->id, account->display_name); + + /* 4. icon path*/ + _account_query_bind_text(hstmt, count++, (char*)account->icon_path); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], icon_path=%s", account->id, account->icon_path); + + /* 5. source*/ + _account_query_bind_text(hstmt, count++, (char*)account->source); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], source=%s", account->id, account->source); + + /* 6. package name*/ + _account_query_bind_text(hstmt, count++, (char*)account->package_name); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], package_name=%s", account->id, account->package_name); + + /* 7. access token*/ + _account_query_bind_text(hstmt, count++, (char*)account->access_token); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], access_token=%s", account->id, account->access_token); + + /* 8. domain name*/ + _account_query_bind_text(hstmt, count++, (char*)account->domain_name); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], domain_name=%s", account->id, account->domain_name); + + /* 9. auth type*/ + _account_query_bind_int(hstmt, count++, account->auth_type); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], auth_type=%d", account->id, account->auth_type); + + /* 10. secret */ + _account_query_bind_int(hstmt, count++, account->secret); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], secret=%d", account->id, account->secret); + + /* 11. sync_support */ + _account_query_bind_int(hstmt, count++, account->sync_support); + _INFO("account_update_to_db_by_id_ex_p : after convert() : account_id[%d], sync_support=%d", account->id, account->sync_support); + + int i; + + /* 12. user text*/ + for(i=0; i< USER_TXT_CNT; i++) + _account_query_bind_text(hstmt, count++, (char*)account->user_data_txt[i]); + + /* 13. user integer */ + for(i=0; i< USER_INT_CNT; i++) + { + _account_query_bind_int(hstmt, count++, account->user_data_int[i]); + _INFO("convert user_data_int : marshal_user_int data_int[%d]=%d", i, account->user_data_int[i]); + } + + _INFO("end"); + + return count; +} + +static bool _account_get_capability_text_cb(const char* capability_type, account_capability_state_e capability_value, void *user_data) +{ + account_s *data = (account_s*)user_data; + + account_capability_s *cap_data = (account_capability_s*)malloc(sizeof(account_capability_s)); + + if (cap_data == NULL) + return FALSE; + ACCOUNT_MEMSET(cap_data, 0, sizeof(account_capability_s)); + + cap_data->type = _account_get_text(capability_type); + cap_data->value = capability_value; + _INFO("cap_data->type = %s, cap_data->value = %d", cap_data->type, cap_data->value); + + data->capablity_list = g_slist_append(data->capablity_list, (gpointer)cap_data); + + return TRUE; +} + +static bool _account_get_custom_text_cb(char* key, char* value, void *user_data) +{ + account_s *data = (account_s*)user_data; + + account_custom_s *custom_data = (account_custom_s*)malloc(sizeof(account_custom_s)); + + if (custom_data == NULL) { + ACCOUNT_DEBUG("_account_get_custom_text_cb :: malloc fail\n"); + return FALSE; + } + ACCOUNT_MEMSET(custom_data, 0, sizeof(account_custom_s)); + + custom_data->account_id = data->id; + custom_data->app_id = _account_get_text(data->package_name); + custom_data->key = _account_get_text(key); + custom_data->value = _account_get_text(value); + _INFO("custom_data->key = %s, custom_data->value = %s", custom_data->key, custom_data->value); + + data->custom_list = g_slist_append(data->custom_list, (gpointer)custom_data); + + return TRUE; +} + +static int _account_query_capability_by_account_id(capability_cb callback, int account_id, void *user_data ) +{ + int error_code = ACCOUNT_ERROR_NONE; + account_stmt hstmt = NULL; + char query[ACCOUNT_SQL_LEN_MAX] = {0, }; + int rc = 0; + + ACCOUNT_RETURN_VAL((account_id > 0), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("ACCOUNT INDEX IS LESS THAN 0")); + ACCOUNT_RETURN_VAL((callback != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("NO CALLBACK FUNCTION")); + ACCOUNT_RETURN_VAL((g_hAccountDB != NULL), {}, ACCOUNT_ERROR_DB_NOT_OPENED, ("The database isn't connected.")); + + ACCOUNT_MEMSET(query, 0x00, ACCOUNT_SQL_LEN_MAX); + + ACCOUNT_SNPRINTF(query, sizeof(query), "SELECT * FROM %s WHERE account_id = %d", CAPABILITY_TABLE, account_id); + hstmt = _account_prepare_query(query); + + if( _account_db_err_code() == SQLITE_PERM ){ + ACCOUNT_ERROR( "Access failed(%s)", _account_db_err_msg()); + return ACCOUNT_ERROR_PERMISSION_DENIED; + } + + rc = _account_query_step(hstmt); + ACCOUNT_CATCH_ERROR(rc == SQLITE_ROW, {}, ACCOUNT_ERROR_RECORD_NOT_FOUND, ("The record isn't found.\n")); + + account_capability_s* capability_record = NULL; + + while (rc == SQLITE_ROW) { + bool cb_ret = FALSE; + capability_record = (account_capability_s*) malloc(sizeof(account_capability_s)); + + if (capability_record == NULL) { + ACCOUNT_FATAL("malloc Failed"); + break; + } + + ACCOUNT_MEMSET(capability_record, 0x00, sizeof(account_capability_s)); + + _account_convert_column_to_capability(hstmt, capability_record); + + cb_ret = callback(capability_record->type, capability_record->value, user_data); + + _account_free_capability_with_items(capability_record); + + ACCOUNT_CATCH_ERROR(cb_ret == TRUE, {}, ACCOUNT_ERROR_NONE, ("Callback func returs FALSE, its iteration is stopped!!!!\n")); + + rc = _account_query_step(hstmt); + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + error_code = ACCOUNT_ERROR_NONE; + +CATCH: + if (hstmt != NULL) { + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + } + + pthread_mutex_unlock(&account_mutex); + return error_code; +} + +static int _account_query_custom_by_account_id(account_custom_cb callback, int account_id, void *user_data ) +{ + int error_code = ACCOUNT_ERROR_NONE; + account_stmt hstmt = NULL; + char query[ACCOUNT_SQL_LEN_MAX] = {0, }; + int rc = 0; + + ACCOUNT_RETURN_VAL((account_id > 0), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("ACCOUNT INDEX IS LESS THAN 0")); + ACCOUNT_RETURN_VAL((callback != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("NO CALLBACK FUNCTION")); + ACCOUNT_RETURN_VAL((g_hAccountDB != NULL), {}, ACCOUNT_ERROR_DB_NOT_OPENED, ("The database isn't connected.")); + + ACCOUNT_MEMSET(query, 0x00, ACCOUNT_SQL_LEN_MAX); + + ACCOUNT_SNPRINTF(query, sizeof(query), "SELECT * FROM %s WHERE AccountId = %d", ACCOUNT_CUSTOM_TABLE, account_id); + hstmt = _account_prepare_query(query); + + if( _account_db_err_code() == SQLITE_PERM ){ + ACCOUNT_ERROR( "Access failed(%s)", _account_db_err_msg()); + return ACCOUNT_ERROR_PERMISSION_DENIED; + } + + rc = _account_query_step(hstmt); + + ACCOUNT_CATCH_ERROR(rc == SQLITE_ROW, {}, ACCOUNT_ERROR_RECORD_NOT_FOUND, ("The record isn't found.\n")); + + account_custom_s* custom_record = NULL; + + while (rc == SQLITE_ROW) { + bool cb_ret = FALSE; + custom_record = (account_custom_s*) malloc(sizeof(account_custom_s)); + + if (custom_record == NULL) { + ACCOUNT_FATAL("malloc Failed"); + break; + } + + ACCOUNT_MEMSET(custom_record, 0x00, sizeof(account_custom_s)); + + _account_convert_column_to_custom(hstmt, custom_record); + + cb_ret = callback(custom_record->key, custom_record->value, user_data); + + _account_free_custom_with_items(custom_record); + + ACCOUNT_CATCH_ERROR(cb_ret == TRUE, {}, ACCOUNT_ERROR_NONE, ("Callback func returs FALSE, its iteration is stopped!!!!\n")); + + rc = _account_query_step(hstmt); + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + error_code = ACCOUNT_ERROR_NONE; + +CATCH: + if (hstmt != NULL) { + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + } + + pthread_mutex_unlock(&account_mutex); + return error_code; +} + +static int _account_compare_old_record(account_s *new_account, int account_id) +{ + int error_code = ACCOUNT_ERROR_NONE; + account_stmt hstmt = NULL; + char query[ACCOUNT_SQL_LEN_MAX] = {0, }; + int rc = 0; + account_s *old_account = NULL; + + ACCOUNT_RETURN_VAL((account_id > 0), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("ACCOUNT INDEX IS LESS THAN 0")); + ACCOUNT_RETURN_VAL((new_account != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("ACCOUNT IS NULL")); + ACCOUNT_RETURN_VAL((g_hAccountDB != NULL), {}, ACCOUNT_ERROR_DB_NOT_OPENED, ("The database isn't connected.")); + + old_account = (account_s*)calloc(1, sizeof(account_s)); + if (old_account == NULL) { + _ERR("Out of Memory"); + return ACCOUNT_ERROR_OUT_OF_MEMORY; + } + + ACCOUNT_MEMSET(query, 0x00, ACCOUNT_SQL_LEN_MAX); + + ACCOUNT_SNPRINTF(query, sizeof(query), "SELECT * FROM %s WHERE _id = %d", ACCOUNT_TABLE, account_id); + hstmt = _account_prepare_query(query); + + rc = _account_query_step(hstmt); + ACCOUNT_CATCH_ERROR(rc == SQLITE_ROW, {}, ACCOUNT_ERROR_RECORD_NOT_FOUND, ("The record isn't found.\n")); + + while (rc == SQLITE_ROW) { + _account_convert_column_to_account(hstmt, old_account); + rc = _account_query_step(hstmt); + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_CATCH_ERROR((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + // get capability + error_code = _account_query_capability_by_account_id(_account_get_capability_text_cb, old_account->id, (void*)old_account); + ACCOUNT_CATCH_ERROR((error_code == ACCOUNT_ERROR_NONE), {}, error_code, ("account_query_capability_by_account_id error")); + + // get custom text + error_code = _account_query_custom_by_account_id(_account_get_custom_text_cb, old_account->id, (void*)old_account); + ACCOUNT_CATCH_ERROR((error_code == ACCOUNT_ERROR_NONE), {}, error_code, ("_account_query_custom_by_account_id error")); + + // compare + + new_account->id = old_account->id; + + //user name + if(!new_account->user_name) { + if(old_account->user_name) + new_account->user_name = _account_get_text(old_account->user_name); + } + + // display name + if(!new_account->display_name) { + if(old_account->display_name) + new_account->display_name = _account_get_text(old_account->display_name); + } + + // email address + if(!new_account->email_address) { + if(old_account->email_address) + new_account->email_address = _account_get_text(old_account->email_address); + } + + // domain name + if(!new_account->domain_name) { + if(old_account->domain_name) + new_account->domain_name = _account_get_text(old_account->domain_name); + } + + // icon path + if(!new_account->icon_path) { + if(old_account->icon_path) + new_account->icon_path = _account_get_text(old_account->icon_path); + } + + // source + if(!new_account->source) { + if(old_account->source) + new_account->source = _account_get_text(old_account->source); + } + + _ACCOUNT_FREE(new_account->package_name); + new_account->package_name = _account_get_text(old_account->package_name); + + // access token + if(!new_account->access_token) { + if(old_account->access_token) + new_account->access_token = _account_get_text(old_account->access_token); + } + + // user text + int i; + for(i=0;iuser_data_txt[i]) { + if(old_account->user_data_txt[i]) + new_account->user_data_txt[i] = _account_get_text(old_account->user_data_txt[i]); + } + } + + // auth type + if(new_account->auth_type == ACCOUNT_AUTH_TYPE_INVALID) { + new_account->auth_type = old_account->auth_type; + } + + //secret + if(new_account->secret== ACCOUNT_SECRECY_INVALID) { + new_account->secret = old_account->secret; + } + + // sync support + if(new_account->sync_support == ACCOUNT_SYNC_INVALID) { + new_account->sync_support = old_account->sync_support; + } + + // user int + for(i=0;iuser_data_int[i] == 0) { + new_account->user_data_int[i] = old_account->user_data_int[i]; + } + } + + // capability + + // user custom table + +CATCH: + if (old_account) + _account_free_account_with_items(old_account); + + if (hstmt != NULL) { + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + } + + return ACCOUNT_ERROR_NONE; +} + GList* _account_query_account_by_package_name(const char* package_name, int *error_code) { - _INFO("_account_query_account_by_package_name"); + _INFO("_account_query_account_by_package_name start, package_name=[%s]", package_name); *error_code = ACCOUNT_ERROR_NONE; account_stmt hstmt = NULL; @@ -1093,7 +1528,7 @@ GList* _account_query_account_by_package_name(const char* package_name, int *err rc = _account_query_finalize(hstmt); ACCOUNT_CATCH_ERROR_P((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); hstmt = NULL; -/* + GList *iter; tmp = g_list_length(account_head->account_list); @@ -1104,7 +1539,7 @@ GList* _account_query_account_by_package_name(const char* package_name, int *err _account_query_capability_by_account_id(_account_get_capability_text_cb, testaccount->id, (void*)testaccount); _account_query_custom_by_account_id(_account_get_custom_text_cb, testaccount->id, (void*)testaccount); } -*/ + *error_code = ACCOUNT_ERROR_NONE; CATCH: @@ -1137,26 +1572,92 @@ CATCH: return NULL; } -static void _account_insert_delete_update_notification_send(char *noti_name, int pid) +ACCOUNT_INTERNAL_API int account_query_account_by_package_name_offline(account_cb callback, const char *package_name, void *user_data) { - vsm_context_h ctx; - vsm_zone_h effective_zone, real_zone; + _INFO("account_query_from_db_by_package_name_offline"); - if (!noti_name) { - _ERR("Noti Name is NULL!!!!!!\n"); - return; - } + ACCOUNT_RETURN_VAL((package_name != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("package_name is null!")); + ACCOUNT_RETURN_VAL((callback != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("callback is null!")); - //Tizen zone [[ - ctx = vsm_create_context(); + int return_code = -1; + GList* account_list = NULL; + GList* iter; - if(ctx == NULL) { - _ERR( "Failed to initialize domain control vsm context."); - return; + return_code = _account_db_open(0); + if (return_code != ACCOUNT_ERROR_NONE) + { + _ERR("_account_db_open() error, ret = %d", return_code); + + goto RETURN; } - effective_zone = vsm_lookup_zone_by_pid(ctx, pid); - if(effective_zone == NULL) { + int uid = getuid(); + if (uid != 0) + { + _ERR("current process user is not root, uid=%d", uid); + return_code = ACCOUNT_ERROR_PERMISSION_DENIED; + goto RETURN; + } + + _INFO("before _account_query_from_db_by_package_name"); + account_list = _account_query_account_by_package_name(package_name, &return_code); + _INFO("after _account_query_from_db_by_package_name=[%d]", return_code); + + if (return_code != ACCOUNT_ERROR_NONE) + { + _ERR("_account_query_from_db_by_package_name error"); + goto RETURN; + } + + for (iter = account_list; iter != NULL; iter = g_list_next(iter)) + { + _INFO("iterating received account_list"); + account_s *account = NULL; + account = (account_s*)iter->data; + + if (callback((account_h)account, user_data) == false) + { + _INFO("application callback requested to discontinue."); + break; + } + } + +RETURN: + _account_glist_account_free(account_list); + if( g_hAccountDB == NULL ) + return return_code; + + return_code = _account_db_close(); + if (return_code != ACCOUNT_ERROR_NONE) + { + ACCOUNT_DEBUG("_account_db_close() fail[%d]", return_code); + return_code = ACCOUNT_ERROR_DB_FAILED; + } + + _INFO("account_query_account_by_package_name_offline end"); + return return_code; +} + +static void _account_insert_delete_update_notification_send(char *noti_name, int pid) +{ + vsm_context_h ctx; + vsm_zone_h effective_zone, real_zone; + + if (!noti_name) { + _ERR("Noti Name is NULL!!!!!!\n"); + return; + } + + //Tizen zone [[ + ctx = vsm_create_context(); + + if(ctx == NULL) { + _ERR( "Failed to initialize domain control vsm context."); + return; + } + + effective_zone = vsm_lookup_zone_by_pid(ctx, pid); + if(effective_zone == NULL) { _ERR( "Failed vsm_lookup_zone_by_pid."); return; } @@ -1402,3 +1903,428 @@ RETURN: return return_code; } + +static int _account_get_package_name_from_account_id(int account_id, char **package_name) +{ + int error_code = ACCOUNT_ERROR_NONE; + account_stmt hstmt = NULL; + char query[ACCOUNT_SQL_LEN_MAX] = {0, }; + int rc = 0; + account_s *old_account = NULL; + + ACCOUNT_RETURN_VAL((account_id > 0), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("ACCOUNT INDEX IS LESS THAN 0")); + ACCOUNT_RETURN_VAL((g_hAccountDB != NULL), {}, ACCOUNT_ERROR_DB_NOT_OPENED, ("The database isn't connected.")); + + old_account = (account_s*)calloc(1, sizeof(account_s)); + if (old_account == NULL) { + _ERR("Out Of memory"); + return ACCOUNT_ERROR_OUT_OF_MEMORY; + } + + ACCOUNT_MEMSET(query, 0x00, ACCOUNT_SQL_LEN_MAX); + + ACCOUNT_SNPRINTF(query, sizeof(query), "SELECT * FROM %s WHERE _id = %d", ACCOUNT_TABLE, account_id); + hstmt = _account_prepare_query(query); + + rc = _account_query_step(hstmt); + ACCOUNT_CATCH_ERROR(rc == SQLITE_ROW, {}, ACCOUNT_ERROR_RECORD_NOT_FOUND, ("The record isn't found.\n")); + + while (rc == SQLITE_ROW) { + _account_convert_column_to_account(hstmt, old_account); + rc = _account_query_step(hstmt); + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_CATCH_ERROR((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + // get package name. + *package_name = _account_get_text(old_account->package_name); + + + CATCH: + if (old_account) + _account_free_account_with_items(old_account); + + if (hstmt != NULL) { + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + } + + return error_code; + +} + +static int _account_update_capability(account_s *account, int account_id) +{ + int rc, count = 1; + char query[ACCOUNT_SQL_LEN_MAX] = {0, }; + account_stmt hstmt = NULL; + + ACCOUNT_RETURN_VAL((account != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("ACCOUNT HANDLE IS NULL")); + + if (g_slist_length( account->capablity_list)==0) { + ACCOUNT_ERROR( "_account_update_capability, no capability\n"); + return ACCOUNT_ERROR_NONE; + } + + ACCOUNT_SNPRINTF(query, sizeof(query), "SELECT COUNT(*) from %s where _id=%d", ACCOUNT_TABLE, account_id); + + rc = _account_get_record_count(query); + + if (rc <= 0) { + ACCOUNT_SLOGI( "_account_update_capability : related account item is not existed rc=%d , %s", rc, _account_db_err_msg()); + return ACCOUNT_ERROR_RECORD_NOT_FOUND; + } + + ACCOUNT_MEMSET(query, 0x00, sizeof(query)); + + ACCOUNT_SNPRINTF(query, sizeof(query), "DELETE FROM %s WHERE account_id=? ", CAPABILITY_TABLE); + hstmt = _account_prepare_query(query); + count = 1; + _account_query_bind_int(hstmt, count++, (int)account_id); + rc = _account_query_step(hstmt); + + if (rc != SQLITE_DONE) { + ACCOUNT_ERROR( "_account_query_step() failed(%d, %s)", rc, _account_db_err_msg()); + return ACCOUNT_ERROR_DB_FAILED; + } + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + GSList *iter; + + for (iter = account->capablity_list; iter != NULL; iter = g_slist_next(iter)) { + int ret; + count = 1; + ACCOUNT_MEMSET(query, 0x00, sizeof(query)); + ACCOUNT_SNPRINTF(query, sizeof(query), "INSERT INTO %s(key, value, package_name, user_name, account_id) VALUES " + "(?, ?, ?, ?, ?) ", CAPABILITY_TABLE); + + hstmt = _account_prepare_query(query); + + ACCOUNT_RETURN_VAL((hstmt != NULL), {}, ACCOUNT_ERROR_DB_FAILED, ("_account_prepare_query() failed(%s).\n", _account_db_err_msg())); + + account_capability_s* cap_data = NULL; + cap_data = (account_capability_s*)iter->data; + + ret = _account_query_bind_text(hstmt, count++, cap_data->type); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Text binding fail")); + ret = _account_query_bind_int(hstmt, count++, cap_data->value); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Integer binding fail")); + ret = _account_query_bind_text(hstmt, count++, (char*)account->package_name); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Text binding fail")); + ret = _account_query_bind_text(hstmt, count++, (char*)account->user_name); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Text binding fail")); + ret = _account_query_bind_int(hstmt, count++, (int)account_id); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Integer binding fail")); + + rc = _account_query_step(hstmt); + + if (rc != SQLITE_DONE) { + ACCOUNT_ERROR( "_account_query_step() failed(%d, %s)", rc, _account_db_err_msg()); + break; + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + } + + return ACCOUNT_ERROR_NONE; +} + +static int _account_update_custom(account_s *account, int account_id) +{ + int rc, count = 1; + char query[ACCOUNT_SQL_LEN_MAX] = {0, }; + account_stmt hstmt = NULL; + + ACCOUNT_RETURN_VAL((account != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("ACCOUNT HANDLE IS NULL")); + + if (g_slist_length( account->custom_list)==0) { + ACCOUNT_DEBUG( "_account_update_custom, no custom data\n"); + return ACCOUNT_ERROR_NONE; + } + + ACCOUNT_SNPRINTF(query, sizeof(query), "SELECT COUNT(*) from %s where _id=%d", ACCOUNT_TABLE, account_id); + + rc = _account_get_record_count(query); + + if( _account_db_err_code() == SQLITE_PERM ){ + ACCOUNT_ERROR( "Access failed(%s)", _account_db_err_msg()); + pthread_mutex_unlock(&account_mutex); + return ACCOUNT_ERROR_PERMISSION_DENIED; + } else if( _account_db_err_code() == SQLITE_BUSY ){ + ACCOUNT_ERROR( "database busy(%s)", _account_db_err_msg()); + pthread_mutex_unlock(&account_mutex); + return ACCOUNT_ERROR_DATABASE_BUSY; + } + + if (rc <= 0) { + ACCOUNT_SLOGE( "_account_update_custom : related account item is not existed rc=%d , %s", rc, _account_db_err_msg()); + return ACCOUNT_ERROR_RECORD_NOT_FOUND; + } + + ACCOUNT_MEMSET(query, 0x00, sizeof(query)); + + ACCOUNT_SNPRINTF(query, sizeof(query), "DELETE FROM %s WHERE AccountId=? ", ACCOUNT_CUSTOM_TABLE); + hstmt = _account_prepare_query(query); + count = 1; + _account_query_bind_int(hstmt, count++, (int)account_id); + rc = _account_query_step(hstmt); + + if (rc == SQLITE_BUSY) { + ACCOUNT_ERROR( "_account_query_step() failed(%d, %s)", rc, _account_db_err_msg()); + return ACCOUNT_ERROR_DATABASE_BUSY; + } else if (rc != SQLITE_DONE) { + ACCOUNT_ERROR( "_account_query_step() failed(%d, %s)", rc, _account_db_err_msg()); + return ACCOUNT_ERROR_DB_FAILED; + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + GSList *iter; + + for (iter = account->custom_list; iter != NULL; iter = g_slist_next(iter)) { + int ret; + count = 1; + ACCOUNT_MEMSET(query, 0x00, sizeof(query)); + ACCOUNT_SNPRINTF(query, sizeof(query), "INSERT INTO %s(AccountId, AppId, Key, Value) VALUES " + "(?, ?, ?, ?) ", ACCOUNT_CUSTOM_TABLE); + + hstmt = _account_prepare_query(query); + + if( _account_db_err_code() == SQLITE_PERM ){ + ACCOUNT_ERROR( "Access failed(%s)", _account_db_err_msg()); + return ACCOUNT_ERROR_PERMISSION_DENIED; + } + + ACCOUNT_RETURN_VAL((hstmt != NULL), {}, ACCOUNT_ERROR_DB_FAILED, ("_account_prepare_query() failed(%s).\n", _account_db_err_msg())); + + account_custom_s* custom_data = NULL; + custom_data = (account_custom_s*)iter->data; + + ret = _account_query_bind_int(hstmt, count++, (int)account_id); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Int binding fail")); + ret = _account_query_bind_text(hstmt, count++, (char*)account->package_name); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Text binding fail")); + ret = _account_query_bind_text(hstmt, count++, (char*)custom_data->key); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Text binding fail")); + ret = _account_query_bind_text(hstmt, count++, (char*)custom_data->value); + ACCOUNT_RETURN_VAL((ret == ACCOUNT_ERROR_NONE), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Text binding fail")); + + rc = _account_query_step(hstmt); + + if (rc != SQLITE_DONE) { + ACCOUNT_ERROR( "_account_query_step() failed(%d, %s)", rc, _account_db_err_msg()); + break; + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + } + + return ACCOUNT_ERROR_NONE; +} + +int _account_update_account(account_s *account, int account_id) +{ + int rc = 0, binding_count =0; + char query[ACCOUNT_SQL_LEN_MAX] = {0, }; + int error_code = ACCOUNT_ERROR_NONE, count=0, ret_transaction = 0; + account_stmt hstmt = NULL; + + if (!account->package_name) { + ACCOUNT_ERROR("Package name is mandetory field, it can not be NULL!!!!\n"); + return ACCOUNT_ERROR_INVALID_PARAMETER; + } + + /* Check account_id*/ + char *package_name = NULL; + + error_code = _account_get_package_name_from_account_id(account_id, &package_name); + + if(error_code != ACCOUNT_ERROR_NONE || package_name == NULL){ + ACCOUNT_ERROR("No package name with account_id\n"); + _ACCOUNT_FREE(package_name); + return ACCOUNT_ERROR_RECORD_NOT_FOUND; + } + + _ACCOUNT_FREE(package_name); + + if (error_code != ACCOUNT_ERROR_NONE) { + ACCOUNT_ERROR("No permission to update\n"); + return ACCOUNT_ERROR_PERMISSION_DENIED; + } + + error_code = _account_compare_old_record(account, account_id); + if (error_code != ACCOUNT_ERROR_NONE) { + ACCOUNT_ERROR("_account_compare_old_record fail\n"); + return error_code; + } + + if (_account_db_err_code() == SQLITE_PERM ) { + ACCOUNT_ERROR( "Access failed(%s)", _account_db_err_msg()); + return ACCOUNT_ERROR_PERMISSION_DENIED; + } else if( _account_db_err_code() == SQLITE_BUSY ) { + ACCOUNT_ERROR( "database busy(%s)", _account_db_err_msg()); + return ACCOUNT_ERROR_DATABASE_BUSY; + } + + if (!account->user_name && !account->display_name && !account->email_address) { + ACCOUNT_ERROR("One field should be set among user name, display name, email address\n"); + return ACCOUNT_ERROR_INVALID_PARAMETER; + } + + ACCOUNT_MEMSET(query, 0x00, sizeof(query)); + + ACCOUNT_SNPRINTF(query, sizeof(query), "SELECT COUNT(*) FROM %s WHERE _id = %d ", ACCOUNT_TABLE, account_id); + + count = _account_get_record_count(query); + if (count <= 0) { + ACCOUNT_DEBUG(" Account record not found, count = %d\n", count); + return ACCOUNT_ERROR_RECORD_NOT_FOUND; + } + + /* transaction control required*/ + ret_transaction = _account_begin_transaction(); + if( ret_transaction == ACCOUNT_ERROR_DATABASE_BUSY ){ + ACCOUNT_ERROR( "database busy(%s)", _account_db_err_msg()); + pthread_mutex_unlock(&account_mutex); + return ACCOUNT_ERROR_DATABASE_BUSY; + } + + ACCOUNT_MEMSET(query, 0x00, sizeof(query)); + ACCOUNT_SNPRINTF(query, sizeof(query), "UPDATE %s SET user_name=?, email_address =?, display_name =?, " + "icon_path =?, source =?, package_name =? , access_token =?, domain_name =?, auth_type =?, secret =?, sync_support =?," + "txt_custom0=?, txt_custom1=?, txt_custom2=?, txt_custom3=?, txt_custom4=?, " + "int_custom0=?, int_custom1=?, int_custom2=?, int_custom3=?, int_custom4=? WHERE _id=? ", ACCOUNT_TABLE); + + hstmt = _account_prepare_query(query); + + if( _account_db_err_code() == SQLITE_PERM ){ + ret_transaction = _account_end_transaction(FALSE); + ACCOUNT_ERROR( "Access failed(%s)", _account_db_err_msg()); + return ACCOUNT_ERROR_PERMISSION_DENIED; + } + + ACCOUNT_RETURN_VAL((hstmt != NULL), {}, ACCOUNT_ERROR_DB_FAILED, ("_account_svc_query_prepare() failed(%s)(%x).\n", _account_db_err_msg(), _account_end_transaction(FALSE))); + + binding_count = _account_convert_account_to_sql(account, hstmt, query); + _account_query_bind_int(hstmt, binding_count++, account_id); + + rc = _account_query_step(hstmt); + if (rc != SQLITE_DONE) { + ACCOUNT_SLOGE( "account_db_query_step() failed(%d, %s)", rc, _account_db_err_msg()); + } + + rc = _account_query_finalize(hstmt); + ACCOUNT_RETURN_VAL((rc == ACCOUNT_ERROR_NONE), {}, rc, ("finalize error")); + hstmt = NULL; + + _INFO("update query=%s", query); + + /*update capability*/ + error_code = _account_update_capability(account, account_id); + if(error_code != ACCOUNT_ERROR_NONE && error_code!= ACCOUNT_ERROR_RECORD_NOT_FOUND){ + ret_transaction = _account_end_transaction(FALSE); + ACCOUNT_ERROR("update capability Failed, trying to roll back(%x) !!!\n", ret_transaction); + return error_code; + } + + /* update custom */ + error_code = _account_update_custom(account, account_id); + if(error_code != ACCOUNT_ERROR_NONE && error_code!= ACCOUNT_ERROR_RECORD_NOT_FOUND){ + ret_transaction = _account_end_transaction(FALSE); + ACCOUNT_ERROR("update capability Failed, trying to roll back(%x) !!!\n", ret_transaction); + return error_code; + } + + ret_transaction = _account_end_transaction(TRUE); + + _INFO("update end"); + return error_code; +} + +int _account_update_to_db_by_id_offline(account_s* account, int account_id) +{ + ACCOUNT_RETURN_VAL((account != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("DATA IS NULL")); + ACCOUNT_RETURN_VAL((account_id > 0), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("Account id is not valid")); + ACCOUNT_RETURN_VAL((g_hAccountDB != NULL), {}, ACCOUNT_ERROR_DB_NOT_OPENED, ("The database isn't connected.")); + int error_code = ACCOUNT_ERROR_NONE; + account_s* data = (account_s*)account; + + pthread_mutex_lock(&account_mutex); + + error_code = _account_update_account(data, account_id); + + if(error_code != ACCOUNT_ERROR_NONE) { + pthread_mutex_unlock(&account_mutex); + return error_code; + } + + pthread_mutex_unlock(&account_mutex); + + char buf[64]={0,}; + ACCOUNT_SNPRINTF(buf, sizeof(buf), "%s:%d", ACCOUNT_NOTI_NAME_UPDATE, account_id); + _account_insert_delete_update_notification_send(buf, getpid()); + + return ACCOUNT_ERROR_NONE; +} + +ACCOUNT_INTERNAL_API int account_update_to_db_by_id_offline(account_h account, int account_id) +{ + _INFO("account_update_to_db_by_id_offline"); + + ACCOUNT_RETURN_VAL((account != NULL), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("account_h is null!")); + ACCOUNT_RETURN_VAL((account_id >= 0), {}, ACCOUNT_ERROR_INVALID_PARAMETER, ("account_id is invalid data!")); + + int return_code = _account_db_open(1); + if (return_code != ACCOUNT_ERROR_NONE) + { + _ERR("_account_db_open() error, ret = %d", return_code); + + goto RETURN; + } + + int uid = getuid(); + if (uid != 0) + { + _ERR("current process user is not root, uid=%d", uid); + return_code = ACCOUNT_ERROR_PERMISSION_DENIED; + goto RETURN; + } + + _INFO("before _account_update_to_db_by_id_offline"); + return_code = _account_update_to_db_by_id_offline((account_s *)account, account_id); + _INFO("after _account_update_to_db_by_id_offline=[%d]", return_code); + + if (return_code != ACCOUNT_ERROR_NONE) + { + _ERR("_account_update_to_db_by_id_offline error"); + goto RETURN; + } + +RETURN: + _INFO("account_update_to_db_by_id_offline end"); + + if( g_hAccountDB == NULL ) + return return_code; + + return_code = _account_db_close(); + if (return_code != ACCOUNT_ERROR_NONE) + { + ACCOUNT_DEBUG("_account_db_close() fail[%d]", return_code); + return_code = ACCOUNT_ERROR_DB_FAILED; + } + + return return_code; +} -- 2.7.4