* Copyright (c) 2021-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "contacts_data_ability.h"
#include <iostream>
#include <mutex>
#include <regex>
#include "blocklist_database.h"
#include "common.h"
#include "contacts_columns.h"
#include "contacts_common_event.h"
#include "contacts_json_utils.h"
#include "contacts_datashare_stub_impl.h"
#include "datashare_ext_ability_context.h"
#include "datashare_predicates.h"
#include "database_disaster_recovery.h"
#include "file_utils.h"
#include "hilog_wrapper.h"
#include "profile_database.h"
#include "rdb_predicates.h"
#include "rdb_utils.h"
#include "sql_analyzer.h"
#include "uri_utils.h"
#include "datashare_helper.h"
#include "datashare_log.h"
#include "datashare_errno.h"
#include "contacts_type.h"
#include "common_tool_type.h"
#include "privacy_contacts_manager.h"
#include "pixel_map_util.h"
#include <fcntl.h>
#include "ability_manager_client.h"
#include "element_name.h"
#include "want.h"
#include "string_wrapper.h"
#include "int_wrapper.h"
#include "os_account_manager.h"
namespace OHOS {
namespace AbilityRuntime {
namespace {
std::mutex g_mutex;
std::mutex g_mutexQuery;
}
std::shared_ptr<Contacts::ContactsDataBase> ContactsDataAbility::contactDataBase_ = nullptr;
std::shared_ptr<Contacts::BlocklistDataBase> ContactsDataAbility::blocklistDataBase_ = nullptr;
std::shared_ptr<Contacts::ProfileDatabase> ContactsDataAbility::profileDataBase_ = nullptr;
std::shared_ptr<Contacts::ContactConnectAbility> ContactsDataAbility::contactsConnectAbility_ = nullptr;
std::map<std::string, int> ContactsDataAbility::uriValueMap_ = {
{"/com.ohos.contactsdataability/contacts/contact", Contacts::CONTACTS_CONTACT},
{"/com.ohos.contactsdataability/contacts/deleted_raw_contact", Contacts::CONTACTS_DELETE},
{"/com.ohos.contactsdataability/contacts/deleted_merge_contact", Contacts::CONTACTS_DELETE_MERGE},
{"/com.ohos.contactsdataability/contacts/deleted_raw_contact_record", Contacts::CONTACTS_DELETE_RECORD},
{"/com.ohos.contactsdataability/contacts/raw_contact", Contacts::CONTACTS_RAW_CONTACT},
{"/com.ohos.contactsdataability/contacts/account", Contacts::ACCOUNT},
{"/com.ohos.contactsdataability/contacts/raw_contact/query_merge_list", Contacts::QUERY_MERGE_LIST},
{"/com.ohos.contactsdataability/contacts/raw_contact/split_contact", Contacts::SPLIT_CONTACT},
{"/com.ohos.contactsdataability/contacts/raw_contact/manual_merge", Contacts::MANUAL_MERGE},
{"/com.ohos.contactsdataability/contacts/raw_contact/auto_merge", Contacts::AUTO_MERGE},
{"/com.ohos.contactsdataability/contacts/contact_data", Contacts::CONTACTS_CONTACT_DATA},
{"/com.ohos.contactsdataability/contacts/contact_type", Contacts::CONTACT_TYPE},
{"/com.ohos.contactsdataability/contacts/groups", Contacts::CONTACTS_GROUPS},
{"/com.ohos.contactsdataability/contacts/contact_blocklist", Contacts::CONTACTS_BLOCKLIST},
{"/com.ohos.contactsdataability/contacts/photo_files", Contacts::CONTACTS_PHOTO_FILES},
{"/com.ohos.contactsdataability/contacts/search_contact", Contacts::CONTACTS_SEARCH_CONTACT},
{"/com.ohos.contactsdataability/contacts/backup", Contacts::CONTACT_BACKUP},
{"/com.ohos.contactsdataability/contacts/cloud", Contacts::CLOUD_DATA},
{"/com.ohos.contactsdataability/contacts/upload_data_to_cloud", Contacts::UPLOAD_DATA_TO_CLOUD},
{"/com.ohos.contactsdataability/contacts/query_uuid_not_in_raw_contact", Contacts::QUERY_UUID_NOT_IN_RAW_CONTACT},
{"/com.ohos.contactsdataability/contacts/sync_contact_data", Contacts::PULLDOWN_SYNC_CONTACT_DATA},
{"/com.ohos.contactsdataability/contacts/setting", Contacts::QUERY_IS_REFRESH_CONTACT},
{"/com.ohos.contactsdataability/contacts/trigger_upload_cloud", Contacts::TRIGGER_UPLOAD_CLOUD},
{"/com.ohos.contactsdataability/contacts/query_big_length_name", Contacts::QUERY_BIG_LENGTH_NAME},
{"/com.ohos.contactsdataability/contacts/backup_restore", Contacts::BACKUP_RESTORE},
{"/com.ohos.contactsdataability/contacts/hw_account", Contacts::HW_ACCOUNT},
{"/com.ohos.contactsdataability/contacts/merge_contact", Contacts::MERGE_CONTACT},
{"/com.ohos.contactsdataability/profile/backup", Contacts::PROFILE_BACKUP},
{"/com.ohos.contactsdataability/contacts/recover", Contacts::CONTACT_RECOVER},
{"/com.ohos.contactsdataability/profile/recover", Contacts::PROFILE_RECOVER},
{"/com.ohos.contactsdataability/profile/contact", Contacts::PROFILE_CONTACT},
{"/com.ohos.contactsdataability/profile/raw_contact", Contacts::PROFILE_RAW_CONTACT},
{"/com.ohos.contactsdataability/profile/contact_data", Contacts::PROFILE_CONTACT_DATA},
{"/com.ohos.contactsdataability/profile/groups", Contacts::PROFILE_GROUPS},
{"/com.ohos.contactsdataability/profile/contact_blocklist", Contacts::PROFILE_BLOCKLIST},
{"/com.ohos.contactsdataability/profile/photo_files", Contacts::PROFILE_PHOTO_FILES},
{"/com.ohos.contactsdataability/profile/search_contact", Contacts::PROFILE_SEARCH_CONTACT},
{"/com.ohos.contactsdataability/profile/deleted_raw_contact_record", Contacts::PROFILE_DELETE_RECORD},
{"/com.ohos.contactsdataability/profile/deleted_raw_contact", Contacts::PROFILE_DELETE},
{"/com.ohos.contactsdataability/profile/contact_type", Contacts::PROFILE_TYPE},
{"/com.ohos.contactsdataability/contacts/recycle_restore", Contacts::RECYCLE_RESTORE},
{"/com.ohos.contactsdataability/raw_contact/place_holder", Contacts::CONTACTS_PLACE_HOLDER},
{"/com.ohos.contactsdataability/contacts/set_full_search_switch_open", Contacts::SET_FULL_SEARCH_SWITCH_OPEN},
{"/com.ohos.contactsdataability/contacts/set_full_search_switch_close", Contacts::SET_FULL_SEARCH_SWITCH_CLOSE},
{"/com.ohos.contactsdataability/contacts/restore_contact_by_double_to_single_upgrade_data",
Contacts::RESTORE_CONTACT_BY_DOUBLE_TO_SINGLE_UPGRADE_DATA},
{"/com.ohos.contactsdataability/contacts/clear_and_recreate_trigger_search_table",
Contacts::CLEAR_AND_RECREATE_TRIGGER_SEARCH_TABLE},
{"/com.ohos.contactsdataability/contacts/split_aggregation_contact", Contacts::SPLIT_AGGREGATION_CONTACT},
{"/com.ohos.contactsdataability/contacts/sync_birthday_to_calendar", Contacts::SYNC_BIRTHDAY_TO_CALENDAR},
{"/com.ohos.contactsdataability/contacts/rebuild_contact_search_index", Contacts::REBUILD_CONTACT_SERACH_INDEX},
{"/com.ohos.contactsdataability/contacts/query_contact_count_double_db", Contacts::QUERY_CONTACT_COUNT_DOUBLE_DB},
{"/com.ohos.contactsdataability/contacts/add_contact_batch", Contacts::ADD_CONTACT_INFO_BATCH},
{"/com.ohos.contactsdataability/contacts/contacts_hard_delete", Contacts::CONTACTS_HARD_DELETE},
{"/com.ohos.contactsdataability/contacts/update_yellow_page_info_for_callLog",
Contacts::UPDATE_YELLOW_PAGE_INFO_FOR_CALLLOG},
{"/com.ohos.contactsdataability/contacts/privacy_contacts_backup", Contacts::PRIVACY_CONTACTS_BACKUP},
{"/com.ohos.contactsdataability/contacts/company_classify", Contacts::CONTACTS_COMPANY_CLASSIFY},
{"/com.ohos.contactsdataability/contacts/query_count_without_company", Contacts::QUERY_COUNT_WITHOUT_COMPANY},
{"/com.ohos.contactsdataability/contacts/location_classify", Contacts::CONTACTS_LOCATION_CLASSIFY},
{"/com.ohos.contactsdataability/contacts/query_count_without_location", Contacts::QUERY_COUNT_WITHOUT_LOCATION},
{"/com.ohos.contactsdataability/contacts/frequent_classify", Contacts::CONTACTS_FREQUENT_CLASSIFY},
{"/com.ohos.contactsdataability/contacts/contact_location", Contacts::CONTACTS_CONTACT_LOCATION},
{"/com.ohos.contactsdataability/contacts/contact_detect_repair", Contacts::CONTACTS_DETECT_REPAIR},
{"/com.ohos.contactsdataability/contacts/poster", Contacts::CONTACTS_POSTER},
{"/com.ohos.contactsdataability/contacts/download_posters", Contacts::CONTACTS_DOWNLOAD_POSTERS},
{"/com.ohos.contactsdataability/contacts/add_failed_delete", Contacts::CONTACTS_ADD_FAILED_DELETE},
{"/com.ohos.contactsdataability/contacts/kit_contacts_sync_info", Contacts::KIT_CONTACTS_SYNC_INFO},
{"/com.ohos.contactsdataability/contacts/delete_all_contacts", Contacts::DELETE_ALL_CONTACTS},
};
ContactsDataAbility* ContactsDataAbility::Create()
{
return new ContactsDataAbility();
}
ContactsDataAbility::ContactsDataAbility() : DataShareExtAbility()
{
}
ContactsDataAbility::~ContactsDataAbility()
{
}
static DataShare::DataShareExtAbility *ContactsDataShareCreator(const std::unique_ptr<Runtime> &runtime)
{
HILOG_INFO("ContactsDataAbility %{public}s", __func__);
return ContactsDataAbility::Create();
}
__attribute__((constructor)) void RegisterDataShareCreator()
{
HILOG_INFO("RegisterDataShareCreator %{public}s", __func__);
DataShare::DataShareExtAbility::SetCreator(ContactsDataShareCreator);
}
sptr<IRemoteObject> ContactsDataAbility::OnConnect(const AAFwk::Want &want)
{
HILOG_INFO("ContactsDataAbility %{public}s begin, ts = %{public}lld", __func__, (long long) time(NULL));
Extension::OnConnect(want);
sptr<DataShare::ContactsDataShareStubImpl> remoteObject =
new (std::nothrow) DataShare::ContactsDataShareStubImpl();
if (remoteObject == nullptr) {
HILOG_ERROR("%{public}s No memory allocated for DataShareStubImpl", __func__);
return nullptr;
}
remoteObject->SetContactsDataAbility(std::static_pointer_cast<ContactsDataAbility>(shared_from_this()));
HILOG_INFO("ContactsDataAbility %{public}s end, begin init ContactsDataBase, "
"ts = %{public}lld", __func__, (long long) time(NULL));
Contacts::ContactsDataBase::GetInstance();
return remoteObject->AsObject();
}
void ContactsDataAbility::OnStart(const Want &want)
{
HILOG_INFO("ContactsDataAbility %{public}s begin, ts = %{public}lld", __func__, (long long) time(NULL));
Extension::OnStart(want);
auto context = AbilityRuntime::Context::GetApplicationContext();
contactsConnectAbility_ = OHOS::Contacts::ContactConnectAbility::GetInstance();
if (context != nullptr) {
std::string basePath = context->GetDatabaseDir();
Contacts::ContactsPath::RDB_PATH = basePath;
Contacts::ContactsPath::RDB_BACKUP_PATH = basePath + "/backup/";
Contacts::ContactsPath::RDB_EL1_PATH = "/data/storage/el1/database";
Contacts::ContactsPath::RDB_EL5_PATH = "/data/storage/el5/database";
}
}
* @brief Check whether BeginTransaction of ContactsDataAbility is empty
*
* @param code the return number of BeginTransaction
* @param mutex transmission parameter : lock
*
* @return True if BeginTransaction is empty; flase otherwise
*/
bool ContactsDataAbility::IsBeginTransactionOK(int code)
{
if (code != 0) {
HILOG_ERROR("IsBeginTransactionOK failed");
return false;
}
return true;
}
* @brief Check if ContactsDataAbility Commit is empty
*
* @param code the return number of Commit
* @param mutex transmission parameter : lock
*
* @return True if ContactsDataAbility Commit is empty; flase otherwise
*/
bool ContactsDataAbility::IsCommitOK(int code)
{
if (code != 0) {
HILOG_ERROR("IsCommitOK failed");
return false;
}
return true;
}
void ContactsDataAbility::handleUpdateCalllogAfterInsertData(int code,
const DataShare::DataShareValuesBucket &value)
{
if (code == Contacts::CONTACTS_CONTACT_DATA) {
std::vector<int> needUpdateCalllogRawIdVector;
contactDataBase_->parseNeedUpdateCalllogRawId(value, needUpdateCalllogRawIdVector);
contactDataBase_->MergeUpdateTask(Contacts::ContactsDataBase::store_,
needUpdateCalllogRawIdVector, false);
}
}
* @brief Insert ContactsDataAbility into the database
*
* @param uri URI of the data table tobe inserted
* @param value Inserted data value of the database
*
* @return Insert database results code
*/
int ContactsDataAbility::Insert(const Uri &uri, const DataShare::DataShareValuesBucket &value)
{
if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
HILOG_ERROR("Permission denied!");
return Contacts::RDB_PERMISSION_ERROR;
}
OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
Contacts::SqlAnalyzer sqlAnalyzer;
bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
if (!isOk) {
HILOG_ERROR("ContactsDataAbility CheckValuesBucket error");
return Contacts::RDB_EXECUTE_FAIL;
}
g_mutex.lock();
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
OHOS::Uri uriTemp = uri;
time_t ts = time(NULL);
HILOG_INFO("getLockThen Insert ts = %{public}lld", (long long) ts);
std::string isSyncFromCloud = UriParseParam(uriTemp);
int code = UriParseAndSwitch(uriTemp);
int ret = contactDataBase_->BeginTransaction();
if (!IsBeginTransactionOK(ret)) {
HILOG_ERROR("ContactsDataAbility Insert IsBeginTransactionOK error");
g_mutex.unlock();
return Contacts::RDB_EXECUTE_FAIL;
}
int resultId = InsertExecute(code, valuesBucket, isSyncFromCloud);
if (resultId == Contacts::OPERATION_ERROR) {
HILOG_ERROR("ContactsDataAbility Insert InsertExecute error");
contactDataBase_->RollBack();
g_mutex.unlock();
return Contacts::OPERATION_ERROR;
}
ret = contactDataBase_->Commit();
if (!IsCommitOK(ret)) {
HILOG_ERROR("ContactsDataAbility Insert IsCommitOK error");
contactDataBase_->RollBack();
g_mutex.unlock();
return Contacts::RDB_EXECUTE_FAIL;
}
handleUpdateCalllogAfterInsertData(code, value);
g_mutex.unlock();
DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri, isSyncFromCloud);
HILOG_INFO("ContactsDataAbility Insert end,resultId = %{public}d,ts = %{public}lld", resultId, (long long) ts);
return resultId;
}
int ContactsDataAbility::InsertExecute(int &code, const OHOS::NativeRdb::ValuesBucket &value, std::string isSync)
{
HILOG_INFO("ContactsDataAbility InsertExecute start code = %{public}d,isSync = %{public}s,ts = %{public}lld",
code, isSync.c_str(), (long long) time(NULL));
int rowId = Contacts::RDB_EXECUTE_FAIL;
switch (code) {
case Contacts::CONTACTS_RAW_CONTACT:
case Contacts::PROFILE_RAW_CONTACT:
rowId = contactDataBase_->InsertRawContact(Contacts::ContactTableName::RAW_CONTACT, value);
break;
case Contacts::CONTACTS_CONTACT_DATA:
case Contacts::PROFILE_CONTACT_DATA:
rowId = contactDataBase_->InsertContactData(Contacts::ContactTableName::CONTACT_DATA, value, isSync);
break;
case Contacts::CONTACTS_GROUPS:
case Contacts::PROFILE_GROUPS:
rowId = contactDataBase_->InsertGroup(Contacts::ContactTableName::GROUPS, value);
break;
case Contacts::CONTACTS_BLOCKLIST:
case Contacts::PROFILE_BLOCKLIST:
rowId = contactDataBase_->InsertBlockList(Contacts::ContactTableName::CONTACT_BLOCKLIST, value);
break;
case Contacts::CLOUD_DATA:
rowId = contactDataBase_->InsertCloudRawContacts(Contacts::ContactTableName::CLOUD_RAW_CONTACT, value);
break;
case Contacts::HW_ACCOUNT:
rowId = contactDataBase_->InsertCloudRawContacts(Contacts::ContactTableName::HW_ACCOUNT, value);
break;
case Contacts::CONTACTS_DELETE:
rowId = contactDataBase_->InsertDeleteRawContact(Contacts::ContactTableName::DELETE_RAW_CONTACT, value);
break;
case Contacts::CONTACTS_PLACE_HOLDER:
rowId = contactDataBase_->UpdateRawContactSeq(value);
break;
case Contacts::PRIVACY_CONTACTS_BACKUP:
rowId = contactDataBase_->InsertPrivacyContactsBackup(
Contacts::ContactTableName::PRIVACY_CONTACTS_BACKUP, value);
break;
case Contacts::CONTACTS_POSTER:
rowId = contactDataBase_->InsertPoster(Contacts::ContactTableName::POSTER, value);
break;
case Contacts::KIT_CONTACTS_SYNC_INFO:
rowId = contactDataBase_->InsertKitContactsSyncInfo(value);
break;
default:
rowId = Contacts::OPERATION_ERROR;
HILOG_INFO("ContactsDataAbility ====>no match uri action, %{public}d", code);
break;
}
return rowId;
}
void ContactsDataAbility::generateDisplayNameBucket(std::vector<DataShare::DataShareValuesBucket> &values)
{
std::vector<OHOS::NativeRdb::ValuesBucket> valuesRdb;
ContactsDataAbility::transferDataShareToRdbBucket(values, valuesRdb);
transferTypeInfo(values, valuesRdb);
int rawContactId = ContactsDataAbility::getIntValueFromRdbBucket(valuesRdb[0],
Contacts::ContactDataColumns::RAW_CONTACT_ID);
int index = 0;
DataShare::DataShareValuesBucket *dataShareValuesBucketDisplayNamePtr = nullptr;
for (auto &value : values) {
int typeId = ContactsDataAbility::getIntValueFromRdbBucket(valuesRdb[index],
Contacts::ContactDataColumns::TYPE_ID);
if (typeId == Contacts::ContentTypeData::NAME_INT_VALUE) {
std::string displayName = ContactsDataAbility::getStringValueFromRdbBucket(valuesRdb[index],
Contacts::ContactDataColumns::DETAIL_INFO);
if (!displayName.empty()) {
return;
}
std::string phoneticName = ContactsDataAbility::getStringValueFromRdbBucket(valuesRdb[index],
Contacts::ContactDataColumns::PHONETIC_NAME);
if (!phoneticName.empty()) {
HILOG_INFO("displayname is empty, get from phoneticName");
putDisplayNameInfo(value, phoneticName, rawContactId);
return;
}
dataShareValuesBucketDisplayNamePtr = &value;
break;
}
++index;
}
std::string displayName = generateDisplayName(valuesRdb);
if (displayName.empty()) {
HILOG_INFO("get displayname from other info finish, displayname is empty");
return;
}
HILOG_INFO("displayname is empty, get from other info");
if (dataShareValuesBucketDisplayNamePtr == nullptr) {
HILOG_INFO("add to bucket displayname");
DataShare::DataShareValuesBucket displayNameBucket;
putDisplayNameInfo(displayNameBucket, displayName, rawContactId);
values.push_back(displayNameBucket);
} else {
HILOG_INFO("update bucket displayname");
putDisplayNameInfo(*dataShareValuesBucketDisplayNamePtr, displayName, rawContactId);
}
}
void ContactsDataAbility::transferTypeInfo(std::vector<DataShare::DataShareValuesBucket> &values,
std::vector<OHOS::NativeRdb::ValuesBucket> &valuesRdb)
{
int index = 0;
for (auto &valueRdb : valuesRdb) {
if (valueRdb.HasColumn(Contacts::ContentTypeColumns::CONTENT_TYPE)) {
std::string typeText = ContactsDataAbility::getStringValueFromRdbBucket(valuesRdb[index],
Contacts::ContentTypeColumns::CONTENT_TYPE);
if (typeText.empty()) {
HILOG_ERROR("GetTypeText type is required");
continue;
}
Contacts::ContactsType contactsType;
int typeId = contactsType.LookupTypeIdOrInsertTypeValue(Contacts::ContactsDataBase::store_, typeText);
if (typeId == Contacts::RDB_EXECUTE_FAIL) {
HILOG_ERROR("insert typeinfo fail");
continue;
}
values[index].valuesMap.erase(Contacts::ContentTypeColumns::CONTENT_TYPE);
values[index].Put(Contacts::ContactDataColumns::TYPE_ID, typeId);
valueRdb.Delete(Contacts::ContentTypeColumns::CONTENT_TYPE);
valueRdb.PutInt(Contacts::ContactDataColumns::TYPE_ID, typeId);
}
++index;
}
}
void ContactsDataAbility::putDisplayNameInfo(DataShare::DataShareValuesBucket &displayNameBucket,
std::string &displayName, int rawContactId)
{
std::map<std::string, DataShare::DataShareValueObject::Type> &valuesMap = displayNameBucket.valuesMap;
valuesMap.erase(Contacts::ContactDataColumns::DETAIL_INFO);
displayNameBucket.Put(Contacts::ContactDataColumns::DETAIL_INFO, displayName);
valuesMap.erase(Contacts::ContactDataColumns::ALPHA_NAME);
displayNameBucket.Put(Contacts::ContactDataColumns::ALPHA_NAME, displayName);
valuesMap.erase(Contacts::ContactDataColumns::TYPE_ID);
displayNameBucket.Put(Contacts::ContactDataColumns::TYPE_ID, Contacts::ContentTypeData::NAME_INT_VALUE);
valuesMap.erase(Contacts::ContactDataColumns::EXTEND7);
displayNameBucket.Put(Contacts::ContactDataColumns::EXTEND7, Contacts::DISPLAY_NAME_GENERATE_FROM_OTHER_INFO_FLAG);
valuesMap.erase(Contacts::ContactDataColumns::RAW_CONTACT_ID);
displayNameBucket.Put(Contacts::ContactDataColumns::RAW_CONTACT_ID, rawContactId);
}
std::string ContactsDataAbility::generateDisplayName(const std::vector<OHOS::NativeRdb::ValuesBucket> &valuesRdb)
{
std::map<int, std::vector<std::string>> typeIdDetailInfoMap;
for (auto &value : valuesRdb) {
int typeId = ContactsDataAbility::getIntValueFromRdbBucket(value, Contacts::ContactDataColumns::TYPE_ID);
std::string detailInfo = ContactsDataAbility::getStringValueFromRdbBucket(value,
Contacts::ContactDataColumns::DETAIL_INFO);
typeIdDetailInfoMap[typeId].push_back(std::move(detailInfo));
if (typeId == Contacts::ContentTypeData::ORGANIZATION_INT_VALUE) {
std::string position = ContactsDataAbility::getStringValueFromRdbBucket(value,
Contacts::ContactDataColumns::POSITION);
typeIdDetailInfoMap[typeId].push_back(std::move(position));
}
}
std::string displayName;
std::vector<int> otherTypeVector = {Contacts::ContentTypeData::NICKNAME_INT_VALUE,
Contacts::ContentTypeData::ORGANIZATION_INT_VALUE,
Contacts::ContentTypeData::PHONE_INT_VALUE,
Contacts::ContentTypeData::EMAIL_INT_VALUE};
for (auto typeId : otherTypeVector) {
for (auto &detailInfo : typeIdDetailInfoMap[typeId]) {
if (!detailInfo.empty()) {
displayName = generateDisplayName(typeId, detailInfo);
return displayName;
}
}
}
return displayName;
}
std::string ContactsDataAbility::generateDisplayName (int &typeId, std::string &fromDetailInfo)
{
std::string displayName;
if (typeId == Contacts::ContentTypeData::NICKNAME_INT_VALUE
|| typeId == Contacts::ContentTypeData::ORGANIZATION_INT_VALUE
|| typeId == Contacts::ContentTypeData::EMAIL_INT_VALUE) {
displayName = fromDetailInfo;
} else if (typeId == Contacts::ContentTypeData::PHONE_INT_VALUE) {
std::regex pattern("\\s");
std::string transferStr = std::regex_replace(fromDetailInfo, pattern, "");
displayName = transferStr;
}
return displayName;
}
std::string ContactsDataAbility::getStringValueFromRdbBucket(const OHOS::NativeRdb::ValuesBucket &valuesBucket,
const std::string &colName)
{
OHOS::NativeRdb::ValueObject value;
std::string colVal;
valuesBucket.GetObject(colName, value);
value.GetString(colVal);
return colVal;
}
void ContactsDataAbility::transferDataShareToRdbBucket(
const std::vector<DataShare::DataShareValuesBucket> &values,
std::vector<OHOS::NativeRdb::ValuesBucket> &valuesRdb)
{
if (values.empty()) {
return;
}
for (const DataShare::DataShareValuesBucket &dataShareValuesBucket : values) {
valuesRdb.push_back(RdbDataShareAdapter::RdbUtils::ToValuesBucket(dataShareValuesBucket));
}
}
int ContactsDataAbility::getIntValueFromRdbBucket(
const OHOS::NativeRdb::ValuesBucket &valuesBucket,
const std::string &colName)
{
int colVal = Contacts::OPERATION_ERROR;
if (!valuesBucket.HasColumn(colName)) {
return colVal;
}
OHOS::NativeRdb::ValueObject value;
valuesBucket.GetObject(colName, value);
if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_NULL) {
HILOG_ERROR("get %{public}s value is nullptr, ts = %{public}lld", colName.c_str(), (long long) time(NULL));
colVal = Contacts::OPERATION_ERROR;
} else if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_INT) {
value.GetInt(colVal);
} else if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_STRING) {
std::string tempString;
value.GetString(tempString);
if (!Contacts::CommonToolType::ConvertToInt(tempString, colVal)) {
HILOG_ERROR("GetContactByValue ValueObjectType String tempString = %{public}s", tempString.c_str());
}
} else if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_DOUBLE) {
double temp = 0;
value.GetDouble(temp);
colVal = ceil(temp);
} else {
HILOG_ERROR("get %{public}s int value from OHOS::NativeRdb::ValuesBucket error, is other type",
colName.c_str());
}
return colVal;
}
* @brief ContactsDataAbility BatchInsert database
*
* @param uri Determine the data table name based on the URI
* @param value Inserted data value of the database
*
* @return BatchInsert database results code
*/
int ContactsDataAbility::BatchInsert(const Uri &uri,
const std::vector<DataShare::DataShareValuesBucket> &values)
{
if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
HILOG_ERROR("Permission denied!");
return Contacts::RDB_PERMISSION_ERROR;
}
unsigned int size = values.size();
if (size < 1) {
HILOG_INFO("ContactsDataAbility BatchInsert values < 1");
return Contacts::RDB_EXECUTE_FAIL;
}
g_mutex.lock();
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
OHOS::Uri uriTemp = uri;
int code = UriParseAndSwitch(uriTemp);
std::vector<DataShare::DataShareValuesBucket> valuesHandle = values;
std::string isSyncFromCloud = UriParseParam(uriTemp);
std::string isFromBatch = UriParseBatchParam(uriTemp);
HILOG_INFO("getLockThen BatchInsert,isSyncFromCloud = %{public}s,isFromBatch = %{public}s",
isSyncFromCloud.c_str(), isFromBatch.c_str());
if (isFromBatch == "true" && (code == Contacts::CONTACTS_CONTACT_DATA || code == Contacts::PROFILE_CONTACT_DATA ||
code == Contacts::CONTACTS_RAW_CONTACT)) {
int batchCode = BatchInsertByMigrate(code, uri, valuesHandle);
handleUpdateCalllogAfterBatchInsertData(batchCode, code, values);
g_mutex.unlock();
return batchCode;
}
if (code == Contacts::PRIVACY_CONTACTS_BACKUP) {
std::vector<OHOS::NativeRdb::ValuesBucket> valueRdb;
ContactsDataAbility::transferDataShareToRdbBucket(valuesHandle, valueRdb);
int batchCode = contactDataBase_->BatchInsertPrivacyContactsBackup(
Contacts::ContactTableName::PRIVACY_CONTACTS_BACKUP, valueRdb);
g_mutex.unlock();
return batchCode;
}
if (code == Contacts::CONTACTS_BLOCKLIST) {
int batchCode = contactDataBase_->BatchInsertBlockList(valuesHandle);
g_mutex.unlock();
return batchCode;
}
if (code == Contacts::ADD_CONTACT_INFO_BATCH) {
int ret = contactDataBase_->addContactInfoBatch(valuesHandle);
DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri, "false");
g_mutex.unlock();
return ret;
}
int ret = batchInsertHandleOneByOne(uri, isSyncFromCloud, code, valuesHandle);
handleUpdateCalllogAfterBatchInsertData(ret, code, values);
g_mutex.unlock();
HandleHwRelationData(values);
return ret;
}
void ContactsDataAbility::handleUpdateCalllogAfterBatchInsertData(int ret,
int code, const std::vector<DataShare::DataShareValuesBucket> &values)
{
if (ret != Contacts::OPERATION_ERROR && code == Contacts::CONTACTS_CONTACT_DATA) {
std::vector<int> needUpdateCalllogRawIdVector;
contactDataBase_->parseNeedUpdateCalllogRawIdBatch(values, needUpdateCalllogRawIdVector);
contactDataBase_->MergeUpdateTask(Contacts::ContactsDataBase::store_, needUpdateCalllogRawIdVector, false);
}
}
* @brief Process the data inserted into the relation linked list.
*
* @param values Inserted data value of the database
*/
void ContactsDataAbility::HandleHwRelationData(const std::vector<DataShare::DataShareValuesBucket> &values)
{
std::vector<OHOS::NativeRdb::ValuesBucket> valuesRdb;
ContactsDataAbility::transferDataShareToRdbBucket(values, valuesRdb);
unsigned int size = valuesRdb.size();
bool isContainPhoneOrEmail = false;
for (unsigned int i = 0; i < size; i++) {
int typeId = getIntValueFromRdbBucket(valuesRdb[i], Contacts::ContactDataColumns::TYPE_ID);
if (typeId == Contacts::ContentTypeData::PHONE_INT_VALUE ||
typeId == Contacts::ContentTypeData::EMAIL_INT_VALUE) {
isContainPhoneOrEmail = true;
break;
}
}
HILOG_INFO("HandleHwRelationData isContainPhoneOrEmail = %{public}s, ts = %{public}lld",
std::to_string(isContainPhoneOrEmail).c_str(), (long long) time(NULL));
}
int ContactsDataAbility::batchInsertHandleOneByOne(const Uri &uri, std::string isSyncFromCloud,
int code, std::vector<DataShare::DataShareValuesBucket> &valuesHandle)
{
unsigned int size = valuesHandle.size();
int ret = contactDataBase_->BeginTransaction();
if (!IsBeginTransactionOK(ret)) {
return Contacts::RDB_EXECUTE_FAIL;
}
bool isContainEvent = false;
int rawContactId = -1;
for (unsigned int i = 0; i < size; i++) {
DataShare::DataShareValuesBucket rawContactValues = valuesHandle[i];
int result = ProcessSingleInsert(rawContactValues, isContainEvent, rawContactId, code, isSyncFromCloud);
if (result != Contacts::OPERATION_OK) {
return result;
}
}
int markRet = contactDataBase_->Commit();
if (!IsCommitOK(markRet)) {
HILOG_ERROR("batchInsertHandleOneByOne IsCommitOK error!");
return Contacts::RDB_EXECUTE_FAIL;
}
if (isContainEvent && rawContactId != -1) {
contactsConnectAbility_ = OHOS::Contacts::ContactConnectAbility::GetInstance();
contactsConnectAbility_->
ConnectEventsHandleAbility(Contacts::CONTACTS_BIRTHDAY_INSERT, std::to_string(rawContactId), "");
}
DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri, isSyncFromCloud);
HILOG_INFO("batchInsertHandleOneByOne end ts = %{public}lld", (long long) time(NULL));
return Contacts::OPERATION_OK;
}
int ContactsDataAbility::ProcessSingleInsert(DataShare::DataShareValuesBucket &rawContactValues,
bool &isContainEvent, int &rawContactId, int &code, std::string &isSyncFromCloud)
{
int errorCode = HandleContactPortrait(rawContactValues);
if (errorCode != Contacts::OPERATION_OK) {
return errorCode;
}
OHOS::NativeRdb::ValuesBucket value = RdbDataShareAdapter::RdbUtils::ToValuesBucket(rawContactValues);
int rowRet = InsertExecute(code, value, isSyncFromCloud);
if (rowRet == Contacts::OPERATION_ERROR) {
HILOG_ERROR("batchInsertHandleOneByOne rowRet error!");
contactDataBase_->RollBack();
return rowRet;
}
if (!isContainEvent) {
int typeId = Contacts::RDB_EXECUTE_FAIL;
int id = OHOS::NativeRdb::E_OK;
std::string typeText;
contactDataBase_->GetTypeText(value, typeId, id, typeText);
if (typeId == Contacts::ContentTypeData::CONTACT_EVENT_INT_VALUE) {
isContainEvent = true;
}
}
if (rawContactId == -1) {
OHOS::NativeRdb::ValueObject valueObject;
value.GetObject(Contacts::ContactDataColumns::RAW_CONTACT_ID, valueObject);
contactDataBase_->GetContactByValue(rawContactId, valueObject);
HILOG_INFO("batchInsertHandleOneByOne rawContactId = %{public}d", rawContactId);
}
return Contacts::OPERATION_OK;
}
int ContactsDataAbility::HandleContactPortrait(DataShare::DataShareValuesBucket &value)
{
std::string portraitFileName = "";
std::string contactId = "";
std::string rawContactId = "";
bool isValid = false;
GetPortraitValue(value, portraitFileName, contactId, rawContactId, isValid);
if (!isValid || portraitFileName.empty() || contactId.empty() || rawContactId.empty()) {
return Contacts::OPERATION_OK;
}
std::string groupPath;
Contacts::FileUtils fileUtils;
if (!fileUtils.GetGroupPath(groupPath) || groupPath.empty()) {
HILOG_ERROR("HandleContactPortrait GetGroupPath failed");
return Contacts::OPERATION_ERROR;
}
std::string srcFilePath = groupPath + portraitFileName;
std::string filePath = groupPath + contactId + "_" + rawContactId;
std::vector<uint8_t> blob;
int32_t blobSource = -1;
if (SavePortraitFileAndBlob(srcFilePath, filePath, blob, blobSource) != Contacts::OPERATION_OK) {
fileUtils.DeleteFile(srcFilePath);
fileUtils.DeleteFile(filePath);
return Contacts::OPERATION_ERROR;
};
fileUtils.DeleteFile(srcFilePath);
BuildPortraitValue(value, contactId, rawContactId, blob, blobSource);
return Contacts::OPERATION_OK;
}
int ContactsDataAbility::SavePortraitFileAndBlob(const std::string &srcFilePath, const std::string &filePath,
std::vector<uint8_t> &blob, int32_t &blobSource)
{
mode_t filePermissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
auto pixelMap = Contacts::PixelMapUtil::GetPixelMapFromFile(srcFilePath);
if (pixelMap == nullptr) {
HILOG_ERROR("SavePortraitFileAndBlob GetPixelMapFromFile failed");
return Contacts::OPERATION_ERROR;
}
int srcFd = open(srcFilePath.c_str(), O_RDONLY, filePermissions);
if (srcFd == Contacts::OPEN_FILE_FAILED) {
HILOG_ERROR("SavePortraitFileAndBlob open srcFilePath failed");
return Contacts::OPERATION_ERROR;
}
Contacts::PixelMapUtil::GetThumbnailPixelMap(pixelMap, srcFd);
close(srcFd);
if (pixelMap == nullptr) {
HILOG_ERROR("SavePortraitFileAndBlob GetThumbnailPixelMap failed");
return Contacts::OPERATION_ERROR;
}
int fd = open(filePath.c_str(), O_CREAT | O_WRONLY, filePermissions);
if (fd == Contacts::OPEN_FILE_FAILED) {
HILOG_ERROR("SavePortraitFileAndBlob open filePath failed");
return Contacts::OPERATION_ERROR;
}
uint32_t errCode = Contacts::PixelMapUtil::SavePixelMapToFile(pixelMap, fd);
close(fd);
if (errCode != Contacts::OPERATION_OK) {
HILOG_ERROR("SavePortraitFileAndBlob pixelMapTofile failed");
return Contacts::OPERATION_ERROR;
}
blobSource = Contacts::PixelMapUtil::GetBlobSourceFromPixelMap(pixelMap);
errCode = Contacts::PixelMapUtil::GetArrayBufferFromPixelMap(pixelMap, blob);
if (errCode != Contacts::OPERATION_OK) {
HILOG_ERROR("SavePortraitFileAndBlob get blob failed");
return Contacts::OPERATION_ERROR;
}
return Contacts::OPERATION_OK;
}
void ContactsDataAbility::BuildPortraitValue(DataShare::DataShareValuesBucket &value, const std::string &contactId,
const std::string &rawContactId, const std::vector<uint8_t> &blob, int32_t blobSource)
{
value.Clear();
value.Put("raw_contact_id", rawContactId);
value.Put("blob_data", blob);
value.Put("type_id", Contacts::ContentTypeData::PHOTO_INT_VALUE);
std::string fileName = "photo/" + contactId + "_" + rawContactId;
value.Put("blob_source", blobSource);
value.Put("detail_info", fileName);
}
void ContactsDataAbility::GetPortraitValue(const DataShare::DataShareValuesBucket &dataShareValue,
std::string &portraitFileName, std::string &contactId, std::string &rawContactId, bool &isValid)
{
portraitFileName = GetStringValueFromDataShareValue(dataShareValue, "PortraitFileName", isValid);
if (!isValid) {
HILOG_DEBUG("not have portraitFileName");
return;
}
contactId = GetStringValueFromDataShareValue(dataShareValue, "contactId", isValid);
if (!isValid) {
HILOG_DEBUG("not have contactId");
return;
}
rawContactId = GetStringValueFromDataShareValue(dataShareValue, "rawContactId", isValid);
if (!isValid) {
HILOG_DEBUG("not have rawContactId");
return;
}
}
std::string ContactsDataAbility::GetStringValueFromDataShareValue(
const DataShare::DataShareValuesBucket &dataShareValue, const std::string &valueName, bool &isValid)
{
std::string value;
DataShare::DataShareValueObject valueObject = dataShareValue.Get(valueName, isValid);
if (!isValid) {
return value;
}
if (const auto* stringPtr = std::get_if<std::string>(&valueObject.value)) {
value = *stringPtr;
}
if (value.empty()) {
isValid = false;
}
return value;
}
* @brief ContactsDataAbility BatchInsert database
*
* @param uri Determine the data table name based on the URI
* @param value Inserted data value of the database
*
* @return BatchInsert database results code
*/
int ContactsDataAbility::BatchInsertByMigrate(
int code, const Uri &uri, const std::vector<DataShare::DataShareValuesBucket> &values)
{
HILOG_INFO("BatchInsertByMigrate start");
OHOS::Uri uriTemp = uri;
std::string isSyncFromCloud = UriParseParam(uriTemp);
HILOG_INFO("ContactsDataAbility BatchInsertByMigrate isSyncFromCloud = %{public}s, code = %{public}d",
isSyncFromCloud.c_str(), code);
int ret = 0;
if (code == Contacts::CONTACTS_RAW_CONTACT) {
ret = contactDataBase_->BatchInsertRawContacts(values);
} else {
ret = contactDataBase_->BatchInsert(Contacts::ContactTableName::CONTACT_DATA, values, isSyncFromCloud);
if (Contacts::PrivacyContactsManager::IsPrivacySpace()) {
Contacts::PrivacyContactsManager::GetInstance()->InsertContactDataToPrivacyBackup(values);
}
}
DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri, isSyncFromCloud);
HILOG_INFO("BatchInsertByMigrate end");
return ret;
}
* @brief Update ContactsDataAbility in the database
*
* @param uri URI of the data table to be inserted
* @param predicates Conditions for updating data value
*
* @return Update database results code
*/
int ContactsDataAbility::Update(
const Uri &uri, const DataShare::DataSharePredicates &predicates, const DataShare::DataShareValuesBucket &value)
{
if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
HILOG_ERROR("Permission denied!");
return Contacts::RDB_PERMISSION_ERROR;
}
OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
Contacts::SqlAnalyzer sqlAnalyzer;
bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
if (!isOk) {
HILOG_ERROR("ContactsDataAbility CheckValuesBucket error");
return Contacts::RDB_EXECUTE_FAIL;
}
g_mutex.lock();
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
int retCode = Contacts::RDB_EXECUTE_FAIL;
OHOS::Uri uriTemp = uri;
std::string isSyncFromCloud = UriParseParam(uriTemp);
HILOG_INFO("getLockThen Update,ts = %{public}lld", (long long) time(NULL));
int code = UriParseAndSwitch(uriTemp);
DataShare::DataSharePredicates dataSharePredicates = predicates;
UpdateExecute(retCode, code, valuesBucket, dataSharePredicates, isSyncFromCloud);
g_mutex.unlock();
if (retCode > 0) {
HILOG_INFO("ContactsDataAbility ====>update row is %{public}d,ts = %{public}lld,uri = %{public}s",
retCode, (long long) time(NULL), Contacts::ContactsDataBase::getUriLogPrintByUri(uriTemp).c_str());
DataBaseNotifyChange(Contacts::CONTACT_UPDATE, uri, isSyncFromCloud);
} else {
HILOG_INFO("ContactsDataAbility ====>update row is %{public}d,ts = %{public}lld, skill notify",
retCode, (long long) time(NULL));
}
return retCode;
}
void ContactsDataAbility::UpdateExecute(int &retCode, int code, const OHOS::NativeRdb::ValuesBucket &value,
DataShare::DataSharePredicates &dataSharePredicates, std::string isSync)
{
Contacts::PredicatesConvert predicatesConvert;
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
std::string manualMergeIdStr;
switch (code) {
case Contacts::CONTACTS_CONTACT:
case Contacts::PROFILE_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT, dataSharePredicates);
retCode = contactDataBase_->Update(value, rdbPredicates);
break;
case Contacts::MERGE_CONTACT:
manualMergeIdStr =
ContactsDataAbility::getStringValueFromRdbBucket(value, "manualMergeIdStr");
contactsConnectAbility_->ConnectAbility("", "", "", "", "mergeContact", manualMergeIdStr);
retCode = 0;
break;
case Contacts::UPDATE_YELLOW_PAGE_INFO_FOR_CALLLOG:
HILOG_INFO("ContactsDataAbility ====>update row UPDATE_YELLOW_PAGE_INFO_FOR_CALLLOG");
contactsConnectAbility_->ConnectAbility("", "", "", "", "updateYellowPageInfo", "");
break;
case Contacts::CONTACTS_RAW_CONTACT:
case Contacts::PROFILE_RAW_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->UpdateRawContact(value, rdbPredicates, isSync);
break;
case Contacts::CONTACTS_CONTACT_DATA:
case Contacts::PROFILE_CONTACT_DATA:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_DATA, dataSharePredicates);
retCode = contactDataBase_->UpdateContactData(value, rdbPredicates, isSync);
break;
case Contacts::CONTACTS_GROUPS:
case Contacts::PROFILE_GROUPS:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::GROUPS, dataSharePredicates);
retCode = contactDataBase_->Update(value, rdbPredicates);
break;
case Contacts::CLOUD_DATA:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CLOUD_RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->UpdateCloudRawContacts(value, rdbPredicates);
break;
case Contacts::QUERY_IS_REFRESH_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::SETTINGS, dataSharePredicates);
retCode = contactDataBase_->UpdateTable(value, rdbPredicates);
break;
case Contacts::PRIVACY_CONTACTS_BACKUP:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::PRIVACY_CONTACTS_BACKUP, dataSharePredicates);
retCode = contactDataBase_->UpdatePrivacyContactsBackup(value, rdbPredicates);
break;
case Contacts::CONTACTS_POSTER:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::POSTER, dataSharePredicates);
retCode = contactDataBase_->Update(value, rdbPredicates);
break;
case Contacts::KIT_CONTACTS_SYNC_INFO:
rdbPredicates =
predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::KIT_CONTACTS_SYNC_INFO, dataSharePredicates);
retCode = contactDataBase_->Update(value, rdbPredicates);
break;
default:
SwitchUpdate(retCode, code, value, dataSharePredicates);
break;
}
}
void ContactsDataAbility::SwitchUpdate(int &retCode, int &code, const OHOS::NativeRdb::ValuesBucket &value,
DataShare::DataSharePredicates &dataSharePredicates)
{
Contacts::PredicatesConvert predicatesConvert;
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
switch (code) {
case Contacts::CONTACTS_BLOCKLIST:
case Contacts::PROFILE_BLOCKLIST:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
retCode = contactDataBase_->UpdateBlockList(value, rdbPredicates);
break;
case Contacts::UPLOAD_DATA_TO_CLOUD:
retCode = contactDataBase_->SyncContacts();
break;
case Contacts::SET_FULL_SEARCH_SWITCH_OPEN:
retCode = contactDataBase_->SetFullSearchSwitch(true);
break;
case Contacts::SET_FULL_SEARCH_SWITCH_CLOSE:
retCode = contactDataBase_->SetFullSearchSwitch(false);
break;
case Contacts::TRIGGER_UPLOAD_CLOUD:
contactsConnectAbility_->ConnectAbility("", "", "", "", "", "");
retCode = Contacts::RDB_EXECUTE_OK;
break;
case Contacts::SPLIT_AGGREGATION_CONTACT:
contactsConnectAbility_->ConnectAbility("", "", "", "", "split_aggregation_contact", "");
retCode = Contacts::RDB_EXECUTE_OK;
break;
case Contacts::HW_ACCOUNT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::HW_ACCOUNT, dataSharePredicates);
retCode = contactDataBase_->Update(value, rdbPredicates);
break;
case Contacts::SPLIT_CONTACT:
retCode = contactDataBase_->Split(dataSharePredicates);
break;
case Contacts::MANUAL_MERGE:
retCode = contactDataBase_->ReContactMerge(dataSharePredicates);
break;
case Contacts::AUTO_MERGE:
retCode = contactDataBase_->ContactMerge();
break;
case Contacts::QUERY_CONTACT_COUNT_DOUBLE_DB:
retCode = contactDataBase_->QueryContactCountDoubleDb();
break;
default:
SwitchUpdateOthers(retCode, code, value, dataSharePredicates);
break;
}
}
void ContactsDataAbility::SwitchUpdateOthers(int &retCode, int &code, const OHOS::NativeRdb::ValuesBucket &value,
DataShare::DataSharePredicates &dataSharePredicates)
{
switch (code) {
case Contacts::RESTORE_CONTACT_BY_DOUBLE_TO_SINGLE_UPGRADE_DATA:
retCode = contactsConnectAbility_->ConnectAbility("", "",
"", "", "restoreContactByDoubleToSingleUpgradeData", "");
break;
case Contacts::CONTACT_BACKUP:
case Contacts::PROFILE_BACKUP:
retCode = BackUp();
break;
case Contacts::CONTACT_RECOVER:
case Contacts::PROFILE_RECOVER:
retCode = Recover(code);
break;
case Contacts::REBUILD_CONTACT_SERACH_INDEX:
case Contacts::CLEAR_AND_RECREATE_TRIGGER_SEARCH_TABLE:
retCode = contactDataBase_->clearAndReCreateTriggerSearchTable();
break;
default:
retCode = Contacts::RDB_EXECUTE_FAIL;
HILOG_ERROR("ContactsDataAbility ====>no match uri action, %{public}d", code);
break;
}
}
* @brief Delete ContactsDataAbility from the database
*
* @param uri URI for the data table storing ContactsDataAbility
* @param predicates Conditions for deleting data values
*
* @return Delete database results code
*/
int ContactsDataAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates)
{
if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
HILOG_ERROR("Permission denied!");
return Contacts::RDB_PERMISSION_ERROR;
}
g_mutex.lock();
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
int retCode = Contacts::RDB_EXECUTE_FAIL;
OHOS::Uri uriTemp = uri;
std::string isSyncFromCloud = UriParseParam(uriTemp);
HILOG_INFO("getLockThen Delete, ts = %{public}lld",
(long long) time(NULL));
int code = UriParseAndSwitch(uriTemp);
std::string handleType = UriParseHandleTypeParam(uriTemp);
DataShare::DataSharePredicates dataSharePredicates = predicates;
DeleteExecute(retCode, code, dataSharePredicates, isSyncFromCloud, handleType);
HILOG_INFO("Delete, size = %{public}d",
retCode);
g_mutex.unlock();
DataBaseNotifyChange(Contacts::CONTACT_DELETE, uri, isSyncFromCloud);
return retCode;
}
void ContactsDataAbility::DeleteExecute(
int &retCode, int code, DataShare::DataSharePredicates &dataSharePredicates,
std::string isSync, std::string handleType)
{
Contacts::PredicatesConvert predicatesConvert;
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
switch (code) {
case Contacts::CONTACTS_CONTACT:
case Contacts::PROFILE_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT, dataSharePredicates);
retCode = contactDataBase_->DeleteContact(rdbPredicates, isSync);
break;
case Contacts::CONTACTS_CONTACT_DATA:
case Contacts::PROFILE_CONTACT_DATA:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_DATA, dataSharePredicates);
retCode = contactDataBase_->DeleteContactData(rdbPredicates, isSync);
break;
case Contacts::CONTACTS_GROUPS:
case Contacts::PROFILE_GROUPS:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::GROUPS, dataSharePredicates);
retCode = contactDataBase_->DeleteGroup(rdbPredicates);
break;
case Contacts::CONTACTS_BLOCKLIST:
case Contacts::PROFILE_BLOCKLIST:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
retCode = contactDataBase_->DeleteBlockList(rdbPredicates);
break;
case Contacts::PRIVACY_CONTACTS_BACKUP:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::PRIVACY_CONTACTS_BACKUP, dataSharePredicates);
retCode = contactDataBase_->DeletePrivacyContactsBackup(rdbPredicates);
break;
case Contacts::CONTACTS_POSTER:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::POSTER, dataSharePredicates);
retCode = contactDataBase_->DeletePoster(rdbPredicates);
break;
case Contacts::KIT_CONTACTS_SYNC_INFO:
rdbPredicates =
predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::KIT_CONTACTS_SYNC_INFO, dataSharePredicates);
retCode = contactDataBase_->DeleteKitContactsSyncInfo(rdbPredicates);
break;
case Contacts::DELETE_ALL_CONTACTS: {
retCode = contactDataBase_->DeleteAllLocalContacts();
break;
}
default:
DeleteExecuteSwitchSplit(retCode, code, dataSharePredicates, isSync, handleType);
break;
}
}
void ContactsDataAbility::DeleteExecuteSwitchSplit(
int &retCode, int code, DataShare::DataSharePredicates &dataSharePredicates,
std::string isSync, std::string handleType)
{
Contacts::PredicatesConvert predicatesConvert;
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
switch (code) {
case Contacts::CONTACTS_DELETE:
case Contacts::PROFILE_DELETE:
rdbPredicates =predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::DELETE_RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->CompletelyDelete(rdbPredicates, handleType);
break;
case Contacts::CONTACTS_HARD_DELETE:
rdbPredicates =predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->HardDelete(rdbPredicates);
break;
case Contacts::CONTACTS_DELETE_RECORD:
case Contacts::PROFILE_DELETE_RECORD:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::DELETE_RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->DeleteRecord(rdbPredicates);
break;
case Contacts::CLOUD_DATA:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::CLOUD_RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->DeleteCloudRawContact(rdbPredicates);
break;
case Contacts::RECYCLE_RESTORE:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::DELETE_RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->RecycleRestore(rdbPredicates, isSync);
break;
case Contacts::CONTACTS_DELETE_MERGE:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::CONTACT, dataSharePredicates);
retCode = contactDataBase_->DeleteMergeRawContact(rdbPredicates);
break;
case Contacts::CONTACTS_ADD_FAILED_DELETE:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::RAW_CONTACT, dataSharePredicates);
retCode = contactDataBase_->HardDelete(rdbPredicates);
break;
default:
retCode = Contacts::OPERATION_ERROR;
break;
}
}
* @brief Query contact data in the database
*
* @param uri URI of the data table that stores the contact data
* @param columns Columns where the contact data is located
* @param predicates Condition for querying data values
*
* @return Database query result
*/
std::shared_ptr<DataShare::DataShareResultSet> ContactsDataAbility::Query(const Uri &uri,
const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns,
DataShare::DatashareBusinessError &businessError)
{
if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::READ_CONTACTS)) {
HILOG_ERROR("ContactsDataAbility ====>Query Permission denied!");
return nullptr;
}
std::lock_guard<std::mutex> lock(g_mutexQuery);
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
std::shared_ptr<OHOS::NativeRdb::ResultSet> result;
OHOS::Uri uriTemp = uri;
int parseCode = UriParseAndSwitch(uriTemp);
HILOG_INFO("getLockThen ====>Query start, uri = %{public}s, ts = %{public}lld",
Contacts::ContactsDataBase::getUriLogPrintByUri(uriTemp).c_str(),
(long long) time(NULL));
std::vector<std::string> columnsTemp = columns;
DataShare::DataSharePredicates dataSharePredicates = predicates;
bool isUriMatch = QueryExecute(result, dataSharePredicates, columnsTemp, parseCode, uriTemp);
if (!isUriMatch) {
return nullptr;
}
if (result == nullptr) {
HILOG_ERROR("AbsSharedResultSet result is nullptr in ContactsDataAbility::Query,ts = %{public}lld", (long long) time(NULL));
return nullptr;
}
auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(result);
std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult =
std::make_shared<DataShare::DataShareResultSet>(queryResultSet);
HILOG_WARN("ContactsDataAbility ====>Query end, uri = %{public}s, ts = %{public}lld",
Contacts::ContactsDataBase::getUriLogPrintByUri(uriTemp).c_str(),
(long long) time(NULL));
return sharedPtrResult;
}
bool ContactsDataAbility::QueryExecute(std::shared_ptr<OHOS::NativeRdb::ResultSet> &result,
DataShare::DataSharePredicates &dataSharePredicates, std::vector<std::string> &columnsTemp,
int &parseCode, OHOS::Uri &uri)
{
Contacts::PredicatesConvert predicatesConvert;
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
bool isUriMatch = true;
switch (parseCode) {
case Contacts::CONTACTS_CONTACT:
case Contacts::PROFILE_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_CONTACT, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::CONTACTS_RAW_CONTACT:
case Contacts::PROFILE_RAW_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_RAW_CONTACT, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::CONTACTS_CONTACT_DATA:
case Contacts::PROFILE_CONTACT_DATA:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_CONTACT_DATA, dataSharePredicates);
AddQueryNotDeleteCondition(rdbPredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::CONTACTS_GROUPS:
case Contacts::PROFILE_GROUPS:
rdbPredicates = predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_GROUPS, dataSharePredicates);
AddQueryNotCCardGroupCondition(rdbPredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::CLOUD_DATA:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CLOUD_RAW_CONTACT, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::QUERY_UUID_NOT_IN_RAW_CONTACT:
result = contactDataBase_->QueryUuidNotInRawContact();
break;
case Contacts::QUERY_BIG_LENGTH_NAME:
result = contactDataBase_->QueryBigLengthNameContact();
break;
case Contacts::HW_ACCOUNT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::HW_ACCOUNT, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::QUERY_IS_REFRESH_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::SETTINGS, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::PRIVACY_CONTACTS_BACKUP:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::PRIVACY_CONTACTS_BACKUP, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::CONTACTS_COMPANY_CLASSIFY:
result = contactDataBase_->QueryContactByCompanyGroup();
break;
case Contacts::QUERY_COUNT_WITHOUT_COMPANY:
result = contactDataBase_->QueryCountWithoutCompany();
break;
case Contacts::CONTACTS_LOCATION_CLASSIFY:
result = contactDataBase_->QueryContactByLocationGroup();
break;
case Contacts::QUERY_COUNT_WITHOUT_LOCATION:
result = contactDataBase_->QueryCountWithoutLocation();
break;
case Contacts::CONTACTS_FREQUENT_CLASSIFY:
result = contactDataBase_->QueryContactByRecentTime();
break;
case Contacts::CONTACTS_CONTACT_LOCATION:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_DATA, dataSharePredicates);
result = contactDataBase_->QueryLocationContact(rdbPredicates, columnsTemp);
break;
case Contacts::CONTACTS_DETECT_REPAIR:
result = contactDataBase_->QueryDetectRepair();
break;
case Contacts::CONTACTS_POSTER:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::POSTER, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::CONTACTS_DOWNLOAD_POSTERS:
if (columnsTemp.size() > 0) {
result = contactDataBase_->DownLoadPosters(columnsTemp[0]);
}
break;
case Contacts::KIT_CONTACTS_SYNC_INFO:
rdbPredicates =
predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::KIT_CONTACTS_SYNC_INFO, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
default:
isUriMatch = QueryExecuteSwitchSplit(result, dataSharePredicates, columnsTemp, parseCode, uri);
break;
}
return isUriMatch;
}
int ContactsDataAbility::ExecuteBatch(
const std::vector<DataShare::OperationStatement> &statements, DataShare::ExecResultSet &result)
{
HILOG_WARN("ExecuteBatch enter, statements size: %{public}zu", statements.size());
if (statements.empty()) {
HILOG_ERROR("ExecuteBatch statements is empty");
return Contacts::RDB_EXECUTE_FAIL;
}
std::map<int32_t, int32_t> operationResultMap;
std::set<std::string> addFailedRawContacts;
std::lock_guard<std::mutex> lock(g_mutex);
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
int ret = contactDataBase_->BeginTransaction();
if (!IsBeginTransactionOK(ret)) {
HILOG_ERROR("ExecuteBatch IsBeginTransactionOK error");
return Contacts::RDB_EXECUTE_FAIL;
}
int32_t index = -1;
for (const auto &statement: statements) {
index++;
int executeResult = ExecuteBatchInner(statement, result, index, operationResultMap, addFailedRawContacts);
if (executeResult == Contacts::OPERATION_ERROR) {
contactDataBase_->RollBack();
return Contacts::RDB_EXECUTE_FAIL;
}
}
int commitRet = contactDataBase_->Commit();
if (!IsCommitOK(commitRet)) {
HILOG_ERROR("ExecuteBatch IsCommitOK error");
contactDataBase_->RollBack();
return Contacts::RDB_EXECUTE_FAIL;
}
result.errorCode = DataShare::ExecErrorCode::EXEC_SUCCESS;
if (!addFailedRawContacts.empty()) {
HandleExecuteBatchFailed(result, addFailedRawContacts);
}
HILOG_WARN("ExecuteBatch end");
return Contacts::RDB_EXECUTE_OK;
}
int ContactsDataAbility::ExecuteBatchInner(const DataShare::OperationStatement &statement,
DataShare::ExecResultSet &result, int32_t index, std::map<int32_t, int32_t> &operationResultMap,
std::set<std::string> &addFailedRawContacts)
{
int executeResult = -1;
DataShare::ExecResult execResult{
statement.operationType, DataShare::ExecErrorCode::EXEC_SUCCESS, std::to_string(-1)};
ExecuteBatchStatement executeBatchStatement{index, statement, execResult};
if (statement.operationType == DataShare::Operation::INSERT) {
executeResult = ProcessExecuteBatchInsert(executeBatchStatement, operationResultMap, addFailedRawContacts,
result);
} else if (statement.operationType == DataShare::Operation::UPDATE) {
executeResult = ProcessExecuteBatchUpdate(executeBatchStatement, result);
} else if (statement.operationType == DataShare::Operation::DELETE) {
executeResult = ProcessExecuteBatchDelete(executeBatchStatement, result);
}
result.results.emplace_back(executeBatchStatement.execResult);
return executeResult;
}
int ContactsDataAbility::ProcessExecuteBatchInsert(ExecuteBatchStatement &executeBatchStatement,
std::map<int32_t, int32_t> &operationResultMap, std::set<std::string> &addFailedRawContacts,
DataShare::ExecResultSet &result)
{
auto &index = executeBatchStatement.index;
auto &statement = executeBatchStatement.statement;
auto &execResult = executeBatchStatement.execResult;
OHOS::Uri uriTemp(statement.uri);
int code = UriParseAndSwitch(uriTemp);
OHOS::NativeRdb::ValuesBucket valuesBucket =
RdbDataShareAdapter::RdbUtils::ToValuesBucket(statement.valuesBucket);
auto processBackReferenceResult = ProcessBackReference(statement, operationResultMap, valuesBucket);
if (processBackReferenceResult == Contacts::ProcessBackReferenceResult::FAILED) {
HILOG_ERROR("ExecuteBatch processBackReferenceResult failed");
execResult.code = DataShare::ExecErrorCode::EXEC_FAILED;
return Contacts::OPERATION_ERROR;
}
std::string isSync = "false";
auto insertResult = InsertExecute(code, valuesBucket, isSync);
if (insertResult != Contacts::OPERATION_ERROR) {
execResult.message = std::to_string(insertResult);
operationResultMap.emplace(index, insertResult);
return insertResult;
}
HILOG_ERROR("ExecuteBatch InsertExecute error");
execResult.code = DataShare::ExecErrorCode::EXEC_FAILED;
if (processBackReferenceResult != Contacts::ProcessBackReferenceResult::SUCCESS) {
return Contacts::OPERATION_ERROR;
}
int32_t fromIndex = statement.backReference.GetFromIndex();
if (operationResultMap.find(fromIndex) != operationResultMap.end()) {
addFailedRawContacts.emplace(std::to_string(operationResultMap.at(fromIndex)));
operationResultMap.erase(fromIndex);
int32_t startIndex = 0;
int32_t endIndex = static_cast<int32_t>(result.results.size());
if (fromIndex > 0) {
startIndex = fromIndex;
}
if (index < endIndex) {
endIndex = index;
}
for (int32_t i = startIndex; i < endIndex; i++) {
result.results[i].code = DataShare::ExecErrorCode::EXEC_FAILED;
result.results[i].message = std::to_string(insertResult);
}
}
return Contacts::OPERATION_ERROR;
}
int ContactsDataAbility::ProcessExecuteBatchUpdate(ExecuteBatchStatement &executeBatchStatement,
DataShare::ExecResultSet &result)
{
auto &statement = executeBatchStatement.statement;
auto &execResult = executeBatchStatement.execResult;
OHOS::Uri uriTemp(statement.uri);
int code = UriParseAndSwitch(uriTemp);
OHOS::NativeRdb::ValuesBucket valuesBucket =
RdbDataShareAdapter::RdbUtils::ToValuesBucket(statement.valuesBucket);
Contacts::SqlAnalyzer sqlAnalyzer;
bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
if (!isOk) {
HILOG_ERROR("ProcessExecuteBatchUpdate checkValueBucket error");
execResult.code = DataShare::ExecErrorCode::EXEC_FAILED;
return Contacts::OPERATION_ERROR;
}
int retCode = Contacts::OPERATION_OK;
std::string isSyncFromCloud = UriParseParam(uriTemp);
UpdateExecute(retCode, code, valuesBucket, statement.predicates, isSyncFromCloud);
if (retCode >= 0) {
execResult.message = std::to_string(retCode);
return retCode;
}
HILOG_ERROR("ExecuteBatch UpdateExecute error, code=%{public}d", retCode);
execResult.code = DataShare::ExecErrorCode::EXEC_FAILED;
return Contacts::OPERATION_ERROR;
}
int ContactsDataAbility::ProcessExecuteBatchDelete(ExecuteBatchStatement &executeBatchStatement,
DataShare::ExecResultSet &result)
{
auto &statement = executeBatchStatement.statement;
auto &execResult = executeBatchStatement.execResult;
OHOS::Uri uriTemp(statement.uri);
int code = UriParseAndSwitch(uriTemp);
int retCode = Contacts::OPERATION_OK;
std::string handleType = UriParseHandleTypeParam(uriTemp);
std::string isSyncFromCloud = UriParseParam(uriTemp);
DeleteExecute(retCode, code, statement.predicates, isSyncFromCloud, handleType);
if (retCode >= 0) {
execResult.message = std::to_string(retCode);
return retCode;
}
HILOG_ERROR("ExecuteBatch DeleteExecute error, code=%{public}d", retCode);
execResult.code = DataShare::ExecErrorCode::EXEC_FAILED;
return Contacts::OPERATION_ERROR;
}
Contacts::ProcessBackReferenceResult ContactsDataAbility::ProcessBackReference(
const DataShare::OperationStatement &statement,
const std::map<int32_t, int32_t> &operationResultMap,
OHOS::NativeRdb::ValuesBucket &valuesBucket)
{
if (statement.HasBackReference()) {
std::string columnName = statement.backReference.GetColumn();
int32_t fromIndex = statement.backReference.GetFromIndex();
if (operationResultMap.find(fromIndex) != operationResultMap.end()) {
valuesBucket.Delete(columnName);
valuesBucket.PutInt(columnName, operationResultMap.at(fromIndex));
return Contacts::ProcessBackReferenceResult::SUCCESS;
}
return Contacts::ProcessBackReferenceResult::FAILED;
}
return Contacts::ProcessBackReferenceResult::NOT_FOUND;
}
int ContactsDataAbility::HandleExecuteBatchFailed(
DataShare::ExecResultSet &result, const std::set<std::string> &addFailedRawContacts)
{
result.errorCode = DataShare::ExecErrorCode::EXEC_PARTIAL_SUCCESS;
if (addFailedRawContacts.size() == result.results.size()) {
result.errorCode = DataShare::ExecErrorCode::EXEC_FAILED;
}
HILOG_ERROR("HandleExecuteBatchFailed, failed num: %{public}zu", addFailedRawContacts.size());
std::vector<std::string> rawContactIds(addFailedRawContacts.begin(), addFailedRawContacts.end());
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
DataShare::DataSharePredicates predicates;
predicates.In("id", rawContactIds);
Contacts::PredicatesConvert predicatesConvert;
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::RAW_CONTACT, predicates);
auto ret = contactDataBase_->HardDelete(rdbPredicates);
if (static_cast<size_t>(ret) == rawContactIds.size()) {
HILOG_WARN("HandleExecuteBatchFailed HardDelete failed, clear dirty data success");
} else {
HILOG_ERROR("HandleExecuteBatchFailed HardDelete failed, clear dirty data failed: %{public}d", ret);
}
return Contacts::OPERATION_OK;
}
* 添加查询不包含名片夹群组的信息条件
* @param rdbPredicates
*/
void ContactsDataAbility::AddQueryNotCCardGroupCondition (OHOS::NativeRdb::RdbPredicates &rdbPredicates)
{
HILOG_INFO("query contactsgroups, add group_name condition, ts = %{public}lld", (long long) time(NULL));
rdbPredicates.And();
rdbPredicates.NotEqualTo(Contacts::GroupsColumns::GROUP_NAME, "PREDEFINED_OHOS_GROUP_CCARD");
}
* 添加查询未删除的信息条件
* @param rdbPredicates
*/
void ContactsDataAbility::AddQueryNotDeleteCondition (OHOS::NativeRdb::RdbPredicates &rdbPredicates)
{
std::string whereSql = rdbPredicates.GetWhereClause();
if (whereSql.find(Contacts::RawContactColumns::IS_DELETED) == std::string::npos) {
HILOG_INFO("query contactdata, not has is_delete conditoin, add condition, ts = %{public}lld", (long long) time(NULL));
rdbPredicates.And();
rdbPredicates.EqualTo(Contacts::RawContactColumns::IS_DELETED, Contacts::NOT_DELETE_MARK);
}
}
bool ContactsDataAbility::QueryExecuteSwitchSplit(std::shared_ptr<OHOS::NativeRdb::ResultSet> &result,
DataShare::DataSharePredicates &dataSharePredicates, std::vector<std::string> &columnsTemp,
int &parseCode, OHOS::Uri &uri)
{
Contacts::PredicatesConvert predicatesConvert;
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
bool isUriMatch = true;
switch (parseCode) {
case Contacts::CONTACTS_BLOCKLIST:
case Contacts::PROFILE_BLOCKLIST:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
result = blocklistDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::PULLDOWN_SYNC_CONTACT_DATA:
contactsConnectAbility_->ConnectAbility("", "", "", "queryUuid", "", "");
break;
case Contacts::SYNC_BIRTHDAY_TO_CALENDAR:
contactsConnectAbility_->ConnectEventsHandleAbility(Contacts::CONTACTS_BIRTHDAY_SYNC, "", "syncBirthdays");
break;
case Contacts::BACKUP_RESTORE:
contactDataBase_->DataSyncAfterPrivateAndMainSpaceDataMigration();
break;
case Contacts::CONTACTS_DELETE:
case Contacts::PROFILE_DELETE:
rdbPredicates = predicatesConvert.ConvertPredicates(
Contacts::ContactTableName::DELETE_RAW_CONTACT, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::CONTACTS_SEARCH_CONTACT:
case Contacts::PROFILE_SEARCH_CONTACT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ViewName::SEARCH_CONTACT_VIEW, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
case Contacts::QUERY_MERGE_LIST:
result = contactDataBase_->SelectCandidate();
break;
case Contacts::CONTACT_TYPE:
case Contacts::PROFILE_TYPE:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_TYPE, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
default:
isUriMatch = QueryExecuteSwitchSplitOthers(result, dataSharePredicates, columnsTemp, parseCode, uri);
break;
}
return isUriMatch;
}
bool ContactsDataAbility::QueryExecuteSwitchSplitOthers(std::shared_ptr<OHOS::NativeRdb::ResultSet> &result,
DataShare::DataSharePredicates &dataSharePredicates, std::vector<std::string> &columnsTemp, int &parseCode,
OHOS::Uri &uri)
{
Contacts::PredicatesConvert predicatesConvert;
OHOS::NativeRdb::RdbPredicates rdbPredicates("");
bool isUriMatch = true;
switch (parseCode) {
case Contacts::ACCOUNT:
rdbPredicates =
predicatesConvert.ConvertPredicates(Contacts::ContactTableName::ACCOUNT, dataSharePredicates);
result = contactDataBase_->Query(rdbPredicates, columnsTemp);
break;
default:
isUriMatch = false;
HILOG_ERROR("ContactsDataAbility ====>no matching uri action");
break;
}
return isUriMatch;
}
std::string ContactsDataAbility::UriParseParam(Uri &uri)
{
Contacts::UriUtils uriUtils;
std::string isSyncFromCloud;
std::map<std::string, std::string> mapParams;
mapParams = uriUtils.getQueryParameter(uri);
if (!mapParams.empty()) {
isSyncFromCloud = mapParams["isSyncFromCloud"];
}
return isSyncFromCloud;
}
std::string ContactsDataAbility::UriParseBatchParam(Uri &uri)
{
Contacts::UriUtils uriUtils;
std::string isFromBatch;
std::map<std::string, std::string> mapParams;
mapParams = uriUtils.getQueryParameter(uri);
if (!mapParams.empty()) {
isFromBatch = mapParams["isFromBatch"];
}
return isFromBatch;
}
std::string ContactsDataAbility::UriParseHandleTypeParam(Uri &uri)
{
Contacts::UriUtils uriUtils;
std::string handleType;
std::map<std::string, std::string> mapParams;
mapParams = uriUtils.getQueryParameter(uri);
if (!mapParams.empty()) {
handleType = mapParams["handleType"];
}
return handleType;
}
int ContactsDataAbility::UriParseAndSwitch(Uri &uri)
{
Contacts::UriUtils uriUtils;
int parseCode = uriUtils.UriParse(uri, uriValueMap_);
if (parseCode != Contacts::OPERATION_ERROR) {
SwitchProfile(uri);
}
return parseCode;
}
void ContactsDataAbility::SwitchProfile(Uri &uri)
{
std::vector<std::string> pathVector;
uri.GetPathSegments(pathVector);
if (pathVector.size() > 1 && pathVector[1].find("profile") == std::string::npos) {
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
contactDataBase_->store_ = contactDataBase_->contactStore_;
} else {
profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
contactDataBase_->store_ = profileDataBase_->store_;
}
}
int ContactsDataAbility::BackUp()
{
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
if (contactDataBase_->store_ == nullptr) {
HILOG_ERROR("store_ is null, skip backup");
return 0;
}
int retCode = contactDataBase_->store_->Backup("contacts.db.bak");
if (retCode != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("backup err,retCode = %{public}d", retCode);
} else {
HILOG_INFO("backup succeed,retCode = %{public}d", retCode);
}
return retCode;
}
int ContactsDataAbility::Recover(int &code)
{
std::string name = Contacts::PROFILE_DATABASE_NAME;
if (code == Contacts::CONTACT_RECOVER) {
name = Contacts::CONTACT_DATABASE_NAME;
}
std::shared_ptr<OHOS::Contacts::DataBaseDisasterRecovery> instance =
OHOS::Contacts::DataBaseDisasterRecovery::GetInstance();
int retCode = instance->RecoveryDatabase(name);
contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
return retCode;
}
void ContactsDataAbility::DataBaseNotifyChange(int code, Uri uri)
{
HILOG_INFO("Contacts DataBaseNotifyChange start.");
Contacts::ContactsCommonEvent::SendContactChange(code);
}
void ContactsDataAbility::DataBaseNotifyChange(int code, Uri uri, std::string isSync)
{
HILOG_INFO("DataBaseNotifyChange isSync start.code = %{public}d, isSync = %{public}s,ts = %{public}lld",
code, isSync.c_str(), (long long) time(NULL));
Contacts::ContactsCommonEvent::SendContactChange(code);
if (isSync != "true") {
contactDataBase_->UpdateDirtyToOne();
contactsConnectAbility_->ConnectAbility("", "", "", "", "", "");
}
contactDataBase_->UpdateContactTimeStamp();
}
}
}