* Copyright (c) 2021-2022 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_update_helper.h"
#include "calllog_database.h"
#include "character_transliterate.h"
#include "common.h"
#include "construction_name.h"
#include "contacts.h"
#include "contacts_columns.h"
#include "contacts_database.h"
#include "contacts_search.h"
#include "contacts_type.h"
#include "hilog_wrapper.h"
#include "raw_contacts.h"
#include "voicemail_database.h"
#include "contacts_common_event.h"
#include "rdb_utils.h"
#include "dataobs_mgr_client.h"
namespace OHOS {
namespace Contacts {
using DataObsMgrClient = OHOS::AAFwk::DataObsMgrClient;
ContactsUpdateHelper::ContactsUpdateHelper(void)
{}
ContactsUpdateHelper::~ContactsUpdateHelper()
{}
int ContactsUpdateHelper::UpdateDisplay(std::vector<int> rawContactIdVector, std::vector<std::string> types,
std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore, OHOS::NativeRdb::ValuesBucket contactDataDataValues,
bool isDelete)
{
int ret = RDB_EXECUTE_OK;
unsigned int count = rawContactIdVector.size();
unsigned int countType = types.size();
if (countType != count) {
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay Illegal rawContactId size type:%{public}d", count);
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay Illegal type size :%{public}d", countType);
return ret;
}
ret = UpdateDisplayResult(rawContactIdVector, types, rdbStore, contactDataDataValues, isDelete, count);
return ret;
}
int ContactsUpdateHelper::UpdateDisplayResult(std::vector<int> rawContactIdVector, std::vector<std::string> types,
std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore, OHOS::NativeRdb::ValuesBucket contactDataDataValues,
bool isDelete, unsigned int count)
{
int ret = RDB_EXECUTE_OK;
RawContacts rawContacts;
Contacts contactsContact;
for (unsigned int i = 0; i < count; i++) {
int rawContactId = rawContactIdVector[i];
std::string type = types[i];
if (strcmp(type.c_str(), ContentTypeData::ORGANIZATION) == 0) {
OHOS::NativeRdb::ValuesBucket rawContactValues =
GetUpdateCompanyValuesBucket(contactDataDataValues, isDelete);
if (rawContactValues.Size() <= 0) {
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay Illegal rawContactValues.Size() :%{public}d",
rawContactValues.Size());
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay failed type:%{public}s", type.c_str());
return ret;
}
ret = rawContacts.UpdateRawContactById(rawContactId, type, rdbStore, rawContactValues);
if (ret != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed type:%{public}s", type.c_str());
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed:%{public}d", ret);
return ret;
}
OHOS::NativeRdb::ValuesBucket contactValues = GetUpdateCompanyValuesBucket(contactDataDataValues, isDelete);
if (contactValues.Size() <= 0) {
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay Illegal contactValues.Size() :%{public}d",
contactValues.Size());
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay failed type:%{public}s", type.c_str());
return ret;
}
ret = contactsContact.UpdateContact(rawContactId, rdbStore, contactValues);
if (ret != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateContact failed type:%{public}s", type.c_str());
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateContact failed:%{public}d", ret);
return ret;
}
} else if (strcmp(type.c_str(), ContentTypeData::NAME) == 0) {
ret = UpdateName(contactDataDataValues, isDelete, rawContactId, type, rdbStore);
if (ret != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateRawContact failed type:%{public}s", type.c_str());
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed:%{public}d", ret);
return ret;
}
} else {
ret = RDB_EXECUTE_OK;
}
}
return ret;
}
int ContactsUpdateHelper::UpdateName(OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete, int rawContactId,
std::string type, std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)
{
OHOS::NativeRdb::ValuesBucket rawContactValues = GetUpdateDisPlayNameValuesBucket(linkDataDataValues, isDelete);
OHOS::NativeRdb::ValuesBucket searchContactValues = GetUpdateSearchNameValuesBucket(linkDataDataValues, isDelete);
std::string disPlayName;
OHOS::NativeRdb::ValueObject typeValue;
rawContactValues.GetObject(RawContactColumns::DISPLAY_NAME, typeValue);
typeValue.GetString(disPlayName);
if (!disPlayName.empty()) {
ConstructionName name;
name.GetConstructionName(disPlayName, name);
std::string searchName;
searchName.append(disPlayName);
if (!name.nameFullFight_.empty()) {
searchName.append("||");
searchName.append(name.nameFullFight_);
}
if (!name.initials_.empty()) {
searchName.append("||");
searchName.append(name.initials_);
}
if (!searchName.empty()) {
searchContactValues.PutString(SearchContactColumns::SEARCH_NAME, searchName);
}
rawContactValues.PutString(RawContactColumns::PHOTO_FIRST_NAME, name.photoFirstName_);
if (!name.sortFirstLetter_.empty()) {
rawContactValues.PutString(RawContactColumns::SORT_FIRST_LETTER, name.sortFirstLetter_);
rawContactValues.PutString(RawContactColumns::SORT, std::to_string(name.sortFirstLetterCode_));
}
if (!name.sortKey.empty()) {
rawContactValues.PutString(RawContactColumns::SORT_KEY, name.sortKey);
}
}
int ret = UpdateNameResult(rawContactValues, rawContactId, type, rdbStore);
if (searchContactValues.Size() > 0) {
ContactsSearch contactsSearch;
ret = contactsSearch.UpdateSearchContact(rawContactId, type, rdbStore, searchContactValues);
if (ret != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateSearchContact failed type:%{public}s", type.c_str());
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateSearchContact failed:%{public}d", ret);
return ret;
}
}
return ret;
}
int ContactsUpdateHelper::UpdateNameResult(OHOS::NativeRdb::ValuesBucket rawContactValues, int rawContactId,
std::string type, std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)
{
int ret = RDB_EXECUTE_OK;
if (rawContactValues.Size() > 0) {
RawContacts rawContacts;
rawContacts.UpdateRawContactById(rawContactId, type, rdbStore, rawContactValues);
if (ret != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed type:%{public}s", type.c_str());
HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed:%{public}d", ret);
return ret;
}
}
return ret;
}
* @brief ContactsUpdateHelper update table calllog
*
* @param rawContactIdVector Collection of IDs to update
* @param rdbStore Database that stores the table calllog
*
* @return Update calllog results code
*/
void ContactsUpdateHelper::UpdateCallLogWhenBatchDelContact(
std::vector<std::string> &contactIdVector, std::shared_ptr<OHOS::NativeRdb::RdbStore> &rdbStore)
{
if (contactIdVector.empty()) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogWhenBatchDelContact contactIdVector is empty");
return;
}
std::set<std::string> detailInfoSet;
std::vector<std::string> detailInfos = QueryDeletedPhoneData(contactIdVector, detailInfoSet, rdbStore);
if (detailInfos.empty()) {
HILOG_WARN("ContactsUpdateHelper UpdateCallLogWhenBatchDelContact detailInfos is empty");
return;
}
std::map<std::string, std::pair<std::string, int>> phoneToNewContactId =
CheckPhoneInOtherContact(contactIdVector, detailInfos, detailInfoSet, rdbStore);
std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
HILOG_WARN("ContactsUpdateHelper UpdateCallLogWhenBatchDelContact detailInfoSet size:%{public}ld,"
"phoneToNewContactId size:%{public}ld",
(long) detailInfoSet.size(),
(long) phoneToNewContactId.size());
int ret = 0;
if (!detailInfoSet.empty()) {
std::vector<std::string> deletePhoneVector;
deletePhoneVector.assign(detailInfoSet.begin(), detailInfoSet.end());
OHOS::NativeRdb::ValuesBucket updateCallLogValues;
updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
updateCallLogValues.PutNull(CallLogColumns::EXTRA1);
std::string tabName = CallsTableName::CALLLOG;
auto predicates = OHOS::NativeRdb::RdbPredicates(tabName);
predicates.In(CallLogColumns::QUICK_SEARCH_KEY, contactIdVector);
predicates.And();
predicates.BeginWrap();
predicates.In(CallLogColumns::FORMAT_PHONE_NUMBER, deletePhoneVector);
predicates.Or();
predicates.In(CallLogColumns::PHONE_NUMBER, deletePhoneVector);
predicates.EndWrap();
ret = callLogDataBase->UpdateCallLog(updateCallLogValues, predicates);
if (ret < RDB_EXECUTE_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogWhenBatchDelContact error,ret:%{public}d,", ret);
return;
}
}
if (!phoneToNewContactId.empty()) {
ret += UpdateCallLogToOtherContact(phoneToNewContactId, callLogDataBase);
}
HILOG_INFO("ContactsUpdateHelper UpdateCallLogWhenBatchDelContact,ret = %{public}d", ret);
UpdateCallLogByPhoneNumNotifyChange(ret);
}
std::vector<std::string> ContactsUpdateHelper::QueryDeletedPhoneData(std::vector<std::string> &contactIdArr,
std::set<std::string> &detailInfoSet, std::shared_ptr<OHOS::NativeRdb::RdbStore> &store_)
{
auto predicates = OHOS::NativeRdb::RdbPredicates(ViewName::VIEW_CONTACT_DATA);
predicates.In(RawContactColumns::CONTACT_ID, contactIdArr);
predicates.And();
predicates.EqualTo(ContactDataColumns::TYPE_ID, ContentTypeData::PHONE_INT_VALUE);
std::vector<std::string> columns = {ContactDataColumns::DETAIL_INFO, ContactDataColumns::FORMAT_PHONE_NUMBER};
auto resultSet = store_->Query(predicates, columns);
int getRowResult = resultSet->GoToFirstRow();
std::vector<std::string> detailInfos;
while (getRowResult == OHOS::NativeRdb::E_OK) {
std::string detailInfo;
resultSet->GetString(INDEX_ZERO, detailInfo);
std::string formatPhoneNumber;
resultSet->GetString(INDEX_ONE, formatPhoneNumber);
if (!formatPhoneNumber.empty()) {
detailInfos.push_back(formatPhoneNumber);
detailInfoSet.insert(formatPhoneNumber);
} else {
detailInfos.push_back(detailInfo);
detailInfoSet.insert(detailInfo);
}
getRowResult = resultSet->GoToNextRow();
}
resultSet->Close();
return detailInfos;
}
std::map<std::string, std::pair<std::string, int>> ContactsUpdateHelper::CheckPhoneInOtherContact(
std::vector<std::string> &contactIdArr, std::vector<std::string> &detailInfos, std::set<std::string> &detailInfoSet,
std::shared_ptr<OHOS::NativeRdb::RdbStore> &store_)
{
std::map<std::string, std::pair<std::string, int>> phoneToNewContactId;
auto predicates = OHOS::NativeRdb::RdbPredicates(ViewName::VIEW_CONTACT_DATA);
predicates.NotIn(RawContactColumns::CONTACT_ID, contactIdArr);
predicates.And();
predicates.BeginWrap();
predicates.In(ContactDataColumns::FORMAT_PHONE_NUMBER, detailInfos);
predicates.Or();
predicates.In(ContactDataColumns::DETAIL_INFO, detailInfos);
predicates.EndWrap();
predicates.And();
predicates.EqualTo(RawContactColumns::IS_DELETED, 0);
predicates.And();
predicates.EqualTo(ContactDataColumns::TYPE_ID, ContentTypeData::PHONE_INT_VALUE);
std::vector<std::string> columns = {ContactDataColumns::DETAIL_INFO,
ContactDataColumns::FORMAT_PHONE_NUMBER,
RawContactColumns::CONTACT_ID,
RawContactColumns::DISPLAY_NAME};
auto queryResultSet = store_->Query(predicates, columns);
int getRowResult = queryResultSet->GoToFirstRow();
while (getRowResult == OHOS::NativeRdb::E_OK) {
std::string formatPhoneNumber;
queryResultSet->GetString(INDEX_ONE, formatPhoneNumber);
int contactId;
queryResultSet->GetInt(INDEX_TWO, contactId);
std::string displayName;
queryResultSet->GetString(INDEX_THREE, displayName);
if (!formatPhoneNumber.empty()) {
detailInfoSet.erase(formatPhoneNumber);
phoneToNewContactId.insert(std::pair<std::string, std::pair<std::string, int>>(
formatPhoneNumber, std::pair<std::string, int>(displayName, contactId)));
} else {
std::string detailInfo;
queryResultSet->GetString(INDEX_ZERO, detailInfo);
detailInfoSet.erase(detailInfo);
phoneToNewContactId.insert(std::pair<std::string, std::pair<std::string, int>>(
detailInfo, std::pair<std::string, int>(displayName, contactId)));
}
getRowResult = queryResultSet->GoToNextRow();
}
queryResultSet->Close();
return phoneToNewContactId;
}
int ContactsUpdateHelper::UpdateCallLogToOtherContact(
std::map<std::string, std::pair<std::string, int>> &phoneToNewContactId,
std::shared_ptr<CallLogDataBase> &callLogDataBase)
{
int updateNum = 0;
for (const auto &pair : phoneToNewContactId) {
OHOS::NativeRdb::ValuesBucket updateCallLogValues;
updateCallLogValues.PutString(CallLogColumns::DISPLAY_NAME, pair.second.first);
updateCallLogValues.PutString(CallLogColumns::QUICK_SEARCH_KEY, std::to_string(pair.second.second));
updateCallLogValues.PutString(CallLogColumns::EXTRA1, std::to_string(pair.second.second));
auto predicates = OHOS::NativeRdb::RdbPredicates(CallsTableName::CALLLOG);
predicates.EqualTo(CallLogColumns::FORMAT_PHONE_NUMBER, pair.first);
predicates.Or();
predicates.EqualTo(CallLogColumns::PHONE_NUMBER, pair.first);
int ret = CallLogDataBase::GetInstance()->UpdateCallLog(updateCallLogValues, predicates);
if (ret < RDB_EXECUTE_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogToOtherContact error,ret:%{public}d", ret);
return RDB_EXECUTE_FAIL;
} else {
updateNum += ret;
}
}
return updateNum;
}
* @brief ContactsUpdateHelper update table calllog
*
* @param rawContactIdVector Collection of IDs to update
* @param rdbStore Database that stores the table calllog
* @param isDelete Contacts field value to update
*
* @return Update calllog results code
*/
void ContactsUpdateHelper::UpdateCallLogByPhoneNum(
std::vector<int> &rawContactIdVector, std::shared_ptr<OHOS::NativeRdb::RdbStore> &rdbStore, bool isDelete)
{
std::shared_ptr<ContactsDataBase> contactDataBase_ = ContactsDataBase::GetInstance();
if (rdbStore != contactDataBase_->contactStore_) {
HILOG_ERROR("UpdateCallLogByPhoneNum rdbStore is profile, not need update");
return;
}
unsigned int count = rawContactIdVector.size();
int totalUpdateRow = 0;
for (unsigned int i = 0; i < count; i++) {
auto rawPredicates = OHOS::NativeRdb::RdbPredicates(ContactTableName::RAW_CONTACT);
rawPredicates.EqualTo(ContactPublicColumns::ID, rawContactIdVector[i]);
rawPredicates.And();
rawPredicates.NotEqualTo(RawContactColumns::PRIMARY_CONTACT, 1);
std::vector<std::string> columns;
columns.push_back(RawContactColumns::CONTACT_ID);
columns.push_back(RawContactColumns::IS_DELETED);
auto rawResultSet = rdbStore->Query(rawPredicates, columns);
int contactId = 0;
int isDeleteDb = 0;
if (rawResultSet->GoToFirstRow() == OHOS::NativeRdb::E_OK) {
rawResultSet->GetInt(0, contactId);
rawResultSet->GetInt(1, isDeleteDb);
}
rawResultSet->Close();
if (contactId <= 0) {
HILOG_ERROR("queryContactId error,contactId:%{public}d,rawId:%{public}d", contactId, rawContactIdVector[i]);
continue;
}
if (isDeleteDb == 1 && !isDelete) {
HILOG_ERROR("rawId isDelete is 1, task deleteFlag is false:%{public}d,rawId:%{public}d",
contactId, rawContactIdVector[i]);
continue;
}
auto resultSet = QueryDataForCallLog(rdbStore, contactId);
int updateRow = DataToUpdateCallLog(isDelete, contactId, resultSet);
if (updateRow > 0) {
totalUpdateRow = totalUpdateRow + updateRow;
}
}
time_t ts = time(NULL);
HILOG_INFO("ContactsUpdateHelper::UpdateCallLogByPhoneNum,totalUpdateRow = %{public}d,ts = %{public}lld",
totalUpdateRow,
(long long) ts);
UpdateCallLogByPhoneNumNotifyChange(totalUpdateRow);
}
void ContactsUpdateHelper::UpdateCallLogPhoto(
std::vector<int> &rawContactIdVector, std::shared_ptr<OHOS::NativeRdb::RdbStore> &rdbStore)
{
std::shared_ptr<ContactsDataBase> contactDataBase_ = ContactsDataBase::GetInstance();
if (rdbStore != contactDataBase_->contactStore_) {
HILOG_ERROR("UpdateCallLogPhoto rdbStore is profile, not need update");
return;
}
unsigned int count = rawContactIdVector.size();
int totalUpdateRow = 0;
int photoContactId = 0;
std::string photoExtra3;
for (unsigned int i = 0; i < count; i++) {
int rawId = rawContactIdVector[i];
int contactId = 0;
auto rawPredicates = OHOS::NativeRdb::RdbPredicates(ContactTableName::RAW_CONTACT);
rawPredicates.EqualTo(ContactPublicColumns::ID, rawId);
std::vector<std::string> columns;
columns.push_back(RawContactColumns::EXTRA3);
columns.push_back(RawContactColumns::CONTACT_ID);
auto rawResultSet = rdbStore->Query(rawPredicates, columns);
std::string extra3;
if (rawResultSet->GoToFirstRow() == OHOS::NativeRdb::E_OK) {
rawResultSet->GetString(0, extra3);
rawResultSet->GetInt(1, contactId);
rawResultSet->Close();
} else {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogPhoto resultSet is empty,rawId = %{public}d", rawId);
rawResultSet->Close();
continue;
}
HILOG_WARN("ContactsUpdateHelper UpdateCallLogPhoto contactId = %{public}d", contactId);
int updateRow = 0;
OHOS::NativeRdb::ValuesBucket updateCallLogValues;
updateCallLogValues.PutString(CallLogColumns::EXTRA4, extra3);
auto predicates = OHOS::NativeRdb::RdbPredicates(CallsTableName::CALLLOG);
predicates.EqualTo(CallLogColumns::QUICK_SEARCH_KEY, contactId);
updateRow = CallLogDataBase::GetInstance()->UpdateCallLog(updateCallLogValues, predicates);
if (updateRow > 0) {
totalUpdateRow = totalUpdateRow + updateRow;
}
photoContactId = contactId;
photoExtra3 = extra3;
}
HILOG_INFO("ContactsUpdateHelper::UpdateCallLogPhoto,photoContactId = %{public}d, totalUpdateRow = %{public}d,"
"photoExtra3 = %{public}s,ts = %{public}lld",
photoContactId, totalUpdateRow, getExtra3Print(photoExtra3).c_str(), (long long) time(NULL));
UpdateCallLogByPhoneNumNotifyChange(totalUpdateRow);
}
std::string ContactsUpdateHelper::getExtra3Print(std::string extra3)
{
std::size_t index = extra3.rfind("/");
std::string extra3Print = extra3;
if (index >= 0 && index < extra3.length()) {
extra3Print = extra3.substr(index);
} else {
extra3Print = extra3;
}
return extra3Print;
}
void ContactsUpdateHelper::UpdateCallLogByPhoneNumNotifyChange(int totalUpdateRow)
{
time_t ts = time(NULL);
if (totalUpdateRow > 0) {
HILOG_INFO("UpdateCallLogByPhoneNum Calllog SendCallLogChange start,ts = %{public}lld", (long long) ts);
ContactsCommonEvent::SendCallLogChange(CONTACT_UPDATE);
auto obsMgrClient = DataObsMgrClient::GetInstance();
if (obsMgrClient == nullptr) {
HILOG_ERROR("%{public}s obsMgrClient is nullptr", __func__);
return;
}
HILOG_INFO("UpdateCallLogByPhoneNum Calllog obsMgrClient->NotifyChange start,ts = %{public}lld", (long long) ts);
Uri uri = Uri("datashare:///com.ohos.calllogability/calls/calllog");
ErrCode ret = obsMgrClient->NotifyChange(uri);
if (ret != ERR_OK) {
HILOG_ERROR("%{public}s obsMgrClient->NotifyChange error return %{public}d", __func__, ret);
return;
} else {
HILOG_INFO("%{public}s obsMgrClient->NotifyChange succeed return %{public}d, ts = %{public}lld",
__func__,
ret,
(long long) time(NULL));
}
std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
callLogDataBase->NotifyCallLogChange();
}
}
int ContactsUpdateHelper::DataToUpdateCallLog(
bool isDelete, int contactId, std::shared_ptr<OHOS::NativeRdb::ResultSet> &resultSet)
{
int rowCount = 0;
resultSet->GetRowCount(rowCount);
int updateRow = 0;
int resultSetNum = resultSet->GoToFirstRow();
if (resultSetNum == OHOS::NativeRdb::E_OK) {
std::vector<std::string> phoneNumberArr;
std::vector<std::string> formatPhoneNumberArr;
std::string name;
std::string quickSearch;
std::string extra3;
if (!isDelete) {
resultSet->GetString(0, name);
}
resultSet->GetString(RESULT_GET_TWO, quickSearch);
resultSet->GetString(RESULT_GET_THERR, extra3);
while (resultSetNum == OHOS::NativeRdb::E_OK) {
std::string formatPhoneNumber;
resultSet->GetString(RESULT_GET_FOUR, formatPhoneNumber);
if (!formatPhoneNumber.empty()) {
formatPhoneNumberArr.push_back(formatPhoneNumber);
resultSetNum = resultSet->GoToNextRow();
} else {
std::string phoneNumber;
resultSet->GetString(RESULT_GET_ONE, phoneNumber);
phoneNumberArr.push_back(phoneNumber);
resultSetNum = resultSet->GoToNextRow();
}
}
resultSet->Close();
updateRow = UpdateCallLog(phoneNumberArr, formatPhoneNumberArr, name, quickSearch, extra3, isDelete);
HILOG_INFO("ContactsUpdateHelper::UpdateCallLog,isDelete:%{public}s,contactId:%{public}d,"
"extra3:%{public}s,nameLength:%{public}ld,"
"updateRow:%{public}d", isDelete ? "Y" : "N", contactId,
getExtra3Print(extra3).c_str(), (long) name.size(), updateRow);
}
if (rowCount == 0) {
std::string quickSearch = std::to_string(contactId);
std::string name;
int isCallLogUpdateRow = UpdateCallLogNameNull(name, quickSearch);
if (isCallLogUpdateRow > 0) {
updateRow = updateRow + isCallLogUpdateRow;
}
HILOG_INFO("ContactsUpdateHelper::UpdateCallLogNameNull,contactId:%{public}d,"
"nameLength:%{public}ld,isCallLogUpdateRow:%{public}d,"
"updateRow:%{public}d",
contactId, (long) name.size(), isCallLogUpdateRow, updateRow);
}
return updateRow;
}
std::shared_ptr<OHOS::NativeRdb::ResultSet> ContactsUpdateHelper::QueryDataForCallLog(
std::shared_ptr<OHOS::NativeRdb::RdbStore> &rdbStore, int contactId)
{
ContactsType contactsType;
int typeNameId = contactsType.LookupTypeId(rdbStore, ContentTypeData::PHONE);
std::string sql;
通过联系人 id 查出该联系人所有手机
SELECT
RawContactColumns.DISPLAY_NAME,
ContactDataColumns.DETAIL_INFO,
RawContactColumns.CONTACT_ID,
RawContactColumns.EXTRA3
FROM
ViewName.VIEW_CONTACT_DATA
WHERE
ContactDataColumns.RAW_CONTACT_ID = (
SELECT
MIN(ContactDataColumns.RAW_CONTACT_ID)
FROM
ViewName.VIEW_CONTACT_DATA
WHERE
RawContactColumns.CONTACT_ID = contactId
AND ContentTypeColumns.CONTENT_TYPE = 'PHONE'
)
AND ContactDataColumns.TYPE_ID = typeNameId;
*/
sql.append("SELECT ")
.append(RawContactColumns::DISPLAY_NAME)
.append(",")
.append(ContactDataColumns::DETAIL_INFO)
.append(",")
.append(RawContactColumns::CONTACT_ID)
.append(",")
.append(RawContactColumns::EXTRA3)
.append(",")
.append(ContactDataColumns::FORMAT_PHONE_NUMBER)
.append(" FROM ")
.append(ViewName::VIEW_CONTACT_DATA)
.append(" WHERE ")
.append(ContactDataColumns::RAW_CONTACT_ID)
.append(" IN (SELECT ")
.append(ContactDataColumns::RAW_CONTACT_ID)
.append(" FROM ")
.append(ViewName::VIEW_CONTACT_DATA)
.append(" WHERE ")
.append(RawContactColumns::CONTACT_ID)
.append(" = ")
.append(std::to_string(contactId))
.append(" AND ")
.append(ContentTypeColumns::CONTENT_TYPE)
.append(" = '")
.append(ContentTypeData::PHONE)
.append("') AND ")
.append(ContactDataColumns::TYPE_ID)
.append(" = ")
.append(std::to_string(typeNameId));
auto resultSet = rdbStore->QuerySql(sql);
if (resultSet == nullptr) {
HILOG_ERROR("ContactsUpdateHelper QueryDataForCallLog resultSet is nullptr ");
}
return resultSet;
}
int ContactsUpdateHelper::UpdateCallLogNameNull(std::string &name, std::string &quickSearch)
{
std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
OHOS::NativeRdb::ValuesBucket updateCallLogValues;
updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
std::string tabName = CallsTableName::CALLLOG;
updateCallLogValues.PutNull(CallLogColumns::EXTRA1);
auto predicates = OHOS::NativeRdb::RdbPredicates(tabName);
std::string updateWheres;
updateWheres.append(CallLogColumns::QUICK_SEARCH_KEY).append(" = ? ");
std::vector<std::string> updateArgs;
updateArgs.push_back(quickSearch);
predicates.SetWhereClause(updateWheres);
predicates.SetWhereArgs(updateArgs);
int ret = callLogDataBase->UpdateCallLog(updateCallLogValues, predicates);
if (ret < RDB_EXECUTE_OK) {
HILOG_ERROR("UpdateCallLogNameNull error,ret:%{public}d,nameSize:%{public}ld,quickSearch:%{public}s,",
ret,
(long) name.size(),
quickSearch.c_str());
return RDB_EXECUTE_FAIL;
}
return ret;
}
* @brief Update table calllog
*
* @param phoneNumber Contacts's phone number
* @param name CallLog name to update
* @param quickSearch Contacts's quick search key
* @param isDelete Contacts field value to update
*
* @return Update calllog results code
*/
int ContactsUpdateHelper::UpdateCallLog(std::vector<std::string> &phoneNumberArr,
std::vector<std::string> &formatPhoneNumberArr, std::string &name, std::string &quickSearch, std::string &extra3,
bool isDelete)
{
int updateRow = 0;
if (isDelete) {
int isCallLogUpdateRow = UpdateCallLogWhenDeleteContact(phoneNumberArr, formatPhoneNumberArr, quickSearch);
if (isCallLogUpdateRow > 0) {
updateRow = updateRow + isCallLogUpdateRow;
}
} else {
int isCallLogUpdateRow =
UpdateCallLogWhenContactChange(phoneNumberArr, formatPhoneNumberArr, name, quickSearch, extra3);
if (isCallLogUpdateRow > 0) {
updateRow = updateRow + isCallLogUpdateRow;
}
}
return updateRow;
}
int ContactsUpdateHelper::UpdateCallLogWhenDeleteContact(
std::vector<std::string> &phoneNumberArr, std::vector<std::string> &formatPhoneNumberArr, std::string &quickSearch)
{
if (phoneNumberArr.empty() && formatPhoneNumberArr.empty()) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogWhenDeleteContact phoneNumberArr is empty");
return RDB_EXECUTE_OK;
}
std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
OHOS::NativeRdb::ValuesBucket updateCallLogValues;
updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
updateCallLogValues.PutNull(CallLogColumns::EXTRA1);
std::string tabName = CallsTableName::CALLLOG;
auto rdbPredicates = OHOS::NativeRdb::RdbPredicates(tabName);
rdbPredicates.EqualTo(CallLogColumns::QUICK_SEARCH_KEY, quickSearch);
int totalRet = 0;
int ret = callLogDataBase->UpdateCallLog(updateCallLogValues, rdbPredicates);
if (ret < RDB_EXECUTE_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogWhenDeleteContact error,ret:%{public}d,"
"quickSearch:%{public}s",
ret,
quickSearch.c_str());
return RDB_EXECUTE_FAIL;
}
totalRet = totalRet + ret;
HILOG_INFO("ContactsUpdateHelper DeleteContact,totalRet = %{public}d", totalRet);
return totalRet;
}
int ContactsUpdateHelper::UpdateCallLogWhenContactChange(std::vector<std::string> &phoneNumberArr,
std::vector<std::string> &formatPhoneNumberArr, std::string &name, std::string &quickSearch, std::string &extra3)
{
if (phoneNumberArr.empty() && formatPhoneNumberArr.empty()) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogWhenContactChange phoneNumberArr is empty");
return RDB_EXECUTE_OK;
}
int totalRet = 0;
int retAdd = RDB_EXECUTE_FAIL;
int retDel = RDB_EXECUTE_FAIL;
if (!formatPhoneNumberArr.empty()) {
retAdd = UpdateCallLogAddPhoneNumber(formatPhoneNumberArr, name, quickSearch, extra3, true);
if (retAdd < RDB_EXECUTE_OK) {
return RDB_EXECUTE_FAIL;
}
totalRet = totalRet + retAdd;
retDel = UpdateCallLogDelPhoneNumber(formatPhoneNumberArr, phoneNumberArr, name, quickSearch);
if (retDel < RDB_EXECUTE_OK) {
return RDB_EXECUTE_FAIL;
}
totalRet = totalRet + retDel;
}
if (phoneNumberArr.empty()) {
return totalRet;
}
retAdd = UpdateCallLogAddPhoneNumber(phoneNumberArr, name, quickSearch, extra3, false);
if (retAdd < RDB_EXECUTE_OK) {
return RDB_EXECUTE_FAIL;
}
totalRet = totalRet + retAdd;
retDel = UpdateCallLogDelPhoneNumber(formatPhoneNumberArr, phoneNumberArr, name, quickSearch);
if (retDel < RDB_EXECUTE_OK) {
return RDB_EXECUTE_FAIL;
}
totalRet = totalRet + retDel;
return totalRet;
}
int ContactsUpdateHelper::UpdateCallLogAddPhoneNumber(std::vector<std::string> &phoneNumberArr, std::string &name,
std::string &quickSearch, std::string &extra3, bool isFormatNumber)
{
OHOS::NativeRdb::ValuesBucket updateCallLogValues;
updateCallLogValues.PutString(CallLogColumns::DISPLAY_NAME, name);
updateCallLogValues.PutString(CallLogColumns::QUICK_SEARCH_KEY, quickSearch);
updateCallLogValues.PutString(CallLogColumns::EXTRA1, quickSearch);
updateCallLogValues.PutString(CallLogColumns::EXTRA4, extra3);
updateCallLogValues.PutInt(CallLogColumns::IS_CNAP, 0);
auto predicates = OHOS::NativeRdb::RdbPredicates(CallsTableName::CALLLOG);
if (isFormatNumber) {
predicates.In(CallLogColumns::FORMAT_PHONE_NUMBER, phoneNumberArr);
} else {
predicates.In(CallLogColumns::PHONE_NUMBER, phoneNumberArr);
}
predicates.And();
predicates.BeginWrap();
predicates.EqualTo(CallLogColumns::QUICK_SEARCH_KEY, "");
predicates.Or();
predicates.IsNull(CallLogColumns::QUICK_SEARCH_KEY);
predicates.Or();
predicates.EqualTo(CallLogColumns::QUICK_SEARCH_KEY, quickSearch);
predicates.EndWrap();
int ret = CallLogDataBase::GetInstance()->UpdateCallLog(updateCallLogValues, predicates);
if (ret < RDB_EXECUTE_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogWhenContactChange error,ret:%{public}d,nameSize:%{public}ld,"
"quickSearch:%{public}s",
ret,
(long) name.size(),
quickSearch.c_str());
return RDB_EXECUTE_FAIL;
}
return ret;
}
int ContactsUpdateHelper::UpdateCallLogDelPhoneNumber(std::vector<std::string> &formatPhoneNumberArr,
std::vector<std::string> &phoneNumberArr, std::string &name, std::string &quickSearch)
{
OHOS::NativeRdb::ValuesBucket updateCallLogValues;
updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
updateCallLogValues.PutNull(CallLogColumns::EXTRA1);
auto predicates = OHOS::NativeRdb::RdbPredicates(CallsTableName::CALLLOG);
predicates.NotIn(CallLogColumns::FORMAT_PHONE_NUMBER, formatPhoneNumberArr);
predicates.And();
predicates.NotIn(CallLogColumns::PHONE_NUMBER, phoneNumberArr);
predicates.And();
predicates.EqualTo(CallLogColumns::QUICK_SEARCH_KEY, quickSearch);
int ret = CallLogDataBase::GetInstance()->UpdateCallLog(updateCallLogValues, predicates);
if (ret < RDB_EXECUTE_OK) {
HILOG_ERROR("ContactsUpdateHelper UpdateCallLogWhenContactChange error,ret:%{public}d,nameSize:%{public}ld,"
"quickSearch:%{public}s",
ret,
(long) name.size(),
quickSearch.c_str());
return RDB_EXECUTE_FAIL;
}
return ret;
}
OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateDisPlayNameValuesBucket(
OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
{
OHOS::NativeRdb::ValuesBucket valuesBucket;
if (isDelete) {
valuesBucket.PutNull(RawContactColumns::DISPLAY_NAME);
valuesBucket.PutString(RawContactColumns::SORT_FIRST_LETTER, ANONYMOUS_SORT_FIRST_LETTER);
valuesBucket.PutString(RawContactColumns::SORT, ANONYMOUS_SORT);
valuesBucket.PutNull(RawContactColumns::SORT_KEY);
return valuesBucket;
}
std::string displayName;
if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
OHOS::NativeRdb::ValueObject typeValue;
linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
typeValue.GetString(displayName);
}
valuesBucket.PutString(RawContactColumns::DISPLAY_NAME, displayName);
std::string phoneticName;
if (linkDataDataValues.HasColumn(RawContactColumns::PHONETIC_NAME)) {
OHOS::NativeRdb::ValueObject typeValue;
linkDataDataValues.GetObject(ContactDataColumns::PHONETIC_NAME, typeValue);
typeValue.GetString(phoneticName);
}
valuesBucket.PutString(RawContactColumns::PHONETIC_NAME, phoneticName);
return valuesBucket;
}
OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateSearchNameValuesBucket(
OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
{
OHOS::NativeRdb::ValuesBucket valuesBucket;
if (isDelete) {
valuesBucket.PutNull(SearchContactColumns::SEARCH_NAME);
return valuesBucket;
}
std::string displayName;
if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
OHOS::NativeRdb::ValueObject typeValue;
linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
typeValue.GetString(displayName);
}
valuesBucket.PutString(RawContactColumns::DISPLAY_NAME, displayName);
return valuesBucket;
}
OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateCompanyValuesBucket(
OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
{
OHOS::NativeRdb::ValuesBucket valuesBucket;
if (isDelete) {
valuesBucket.PutNull(RawContactColumns::COMPANY);
valuesBucket.PutNull(RawContactColumns::POSITION);
return valuesBucket;
}
if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
std::string company;
OHOS::NativeRdb::ValueObject typeValue;
linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
typeValue.GetString(company);
valuesBucket.PutString(RawContactColumns::COMPANY, company);
}
if (linkDataDataValues.HasColumn(ContactDataColumns::POSITION)) {
std::string position;
OHOS::NativeRdb::ValueObject typeValue;
linkDataDataValues.GetObject(ContactDataColumns::POSITION, typeValue);
typeValue.GetString(position);
valuesBucket.PutString(RawContactColumns::POSITION, position);
}
return valuesBucket;
}
}
}