1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "contacts_update_helper.h"
17
18 #include "calllog_database.h"
19 #include "character_transliterate.h"
20 #include "common.h"
21 #include "construction_name.h"
22 #include "contacts.h"
23 #include "contacts_columns.h"
24 #include "contacts_database.h"
25 #include "contacts_search.h"
26 #include "contacts_type.h"
27 #include "hilog_wrapper.h"
28 #include "raw_contacts.h"
29 #include "voicemail_database.h"
30
31 namespace OHOS {
32 namespace Contacts {
ContactsUpdateHelper(void)33 ContactsUpdateHelper::ContactsUpdateHelper(void)
34 {
35 }
36
~ContactsUpdateHelper()37 ContactsUpdateHelper::~ContactsUpdateHelper()
38 {
39 }
40
UpdateDisplay(std::vector<int> rawContactIdVector,std::vector<std::string> types,std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore,OHOS::NativeRdb::ValuesBucket contactDataDataValues,bool isDelete)41 int ContactsUpdateHelper::UpdateDisplay(std::vector<int> rawContactIdVector, std::vector<std::string> types,
42 std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore, OHOS::NativeRdb::ValuesBucket contactDataDataValues,
43 bool isDelete)
44 {
45 int ret = RDB_EXECUTE_OK;
46 unsigned int count = rawContactIdVector.size();
47 unsigned int countType = types.size();
48 if (countType != count) {
49 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay Illegal rawContactId size type:%{public}d", count);
50 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay Illegal type size :%{public}d", countType);
51 return ret;
52 }
53 ContactsSearch contactsSearch;
54 RawContacts rawContacts;
55 Contacts contactsContact;
56 for (unsigned int i = 0; i < count; i++) {
57 int rawContactId = rawContactIdVector[i];
58 std::string type = types[i];
59 if (strcmp(type.c_str(), ContentTypeData::ORGANIZATION) == 0) {
60 OHOS::NativeRdb::ValuesBucket rawContactValues =
61 GetUpdateCompanyValuesBucket(contactDataDataValues, isDelete);
62 if (rawContactValues.Size() <= 0) {
63 return ret;
64 }
65 ret = rawContacts.UpdateRawContactById(rawContactId, type, rdbStore, rawContactValues);
66 if (ret != OHOS::NativeRdb::E_OK) {
67 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed type:%{public}s", type.c_str());
68 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed:%{public}d", ret);
69 return ret;
70 }
71 OHOS::NativeRdb::ValuesBucket contactValues = GetUpdateCompanyValuesBucket(contactDataDataValues, isDelete);
72 if (contactValues.Size() <= 0) {
73 return ret;
74 }
75 ret = contactsContact.UpdateContact(rawContactId, rdbStore, contactValues);
76 if (ret != OHOS::NativeRdb::E_OK) {
77 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateContact failed type:%{public}s", type.c_str());
78 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateContact failed:%{public}d", ret);
79 return ret;
80 }
81 } else if (strcmp(type.c_str(), ContentTypeData::NAME) == 0) {
82 ret = UpdateName(contactDataDataValues, isDelete, rawContactId, type, rdbStore);
83 if (ret != OHOS::NativeRdb::E_OK) {
84 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed type:%{public}s", type.c_str());
85 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed:%{public}d", ret);
86 return ret;
87 }
88 } else {
89 ret = RDB_EXECUTE_OK;
90 }
91 }
92 return ret;
93 }
94
UpdateName(OHOS::NativeRdb::ValuesBucket linkDataDataValues,bool isDelete,int rawContactId,std::string type,std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)95 int ContactsUpdateHelper::UpdateName(OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete, int rawContactId,
96 std::string type, std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)
97 {
98 OHOS::NativeRdb::ValuesBucket rawContactValues = GetUpdateDisPlayNameValuesBucket(linkDataDataValues, isDelete);
99 OHOS::NativeRdb::ValuesBucket searchContactValues = GetUpdateSearchNameValuesBucket(linkDataDataValues, isDelete);
100 std::string disPlayName;
101 OHOS::NativeRdb::ValueObject typeValue;
102 rawContactValues.GetObject(RawContactColumns::DISPLAY_NAME, typeValue);
103 typeValue.GetString(disPlayName);
104 if (!disPlayName.empty()) {
105 ConstructionName name;
106 name.GetConstructionName(disPlayName, name);
107 std::string searchName;
108 searchName.append(disPlayName);
109 if (!name.nameFullFight_.empty()) {
110 searchName.append("||");
111 searchName.append(name.nameFullFight_);
112 }
113 if (!name.initials_.empty()) {
114 searchName.append("||");
115 searchName.append(name.initials_);
116 }
117 if (!searchName.empty()) {
118 searchContactValues.PutString(SearchContactColumns::SEARCH_NAME, searchName);
119 }
120 rawContactValues.PutString(RawContactColumns::PHOTO_FIRST_NAME, name.photoFirstName_);
121 if (!name.sortFirstLetter_.empty()) {
122 // add sort and sort_first_letter
123 rawContactValues.PutString(RawContactColumns::SORT_FIRST_LETTER, name.sortFirstLetter_);
124 rawContactValues.PutString(RawContactColumns::SORT, std::to_string(name.sortFirstLetterCode_));
125 }
126 }
127 int ret = RDB_EXECUTE_OK;
128 if (rawContactValues.Size() > 0) {
129 RawContacts rawContacts;
130 rawContacts.UpdateRawContactById(rawContactId, type, rdbStore, rawContactValues);
131 if (ret != OHOS::NativeRdb::E_OK) {
132 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed type:%{public}s", type.c_str());
133 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateRawContact failed:%{public}d", ret);
134 return ret;
135 }
136 }
137 if (searchContactValues.Size() > 0) {
138 // update SearchContact name
139 ContactsSearch contactsSearch;
140 ret = contactsSearch.UpdateSearchContact(rawContactId, type, rdbStore, searchContactValues);
141 if (ret != OHOS::NativeRdb::E_OK) {
142 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateSearchContact failed type:%{public}s", type.c_str());
143 HILOG_ERROR("ContactsUpdateHelper UpdateDisplay UpdateSearchContact failed:%{public}d", ret);
144 return ret;
145 }
146 }
147 return ret;
148 }
149
150 /**
151 * @brief ContactsUpdateHelper update table calllog
152 *
153 * @param rawContactIdVector Collection of IDs to update
154 * @param rdbStore Database that stores the table calllog
155 * @param isDelete Contacts field value to update
156 *
157 * @return Update calllog results code
158 */
UpdateCallLogByPhoneNum(std::vector<int> & rawContactIdVector,std::shared_ptr<OHOS::NativeRdb::RdbStore> & rdbStore,bool isDelete)159 void ContactsUpdateHelper::UpdateCallLogByPhoneNum(
160 std::vector<int> &rawContactIdVector, std::shared_ptr<OHOS::NativeRdb::RdbStore> &rdbStore, bool isDelete)
161 {
162 std::shared_ptr<ContactsDataBase> contactDataBase_ = ContactsDataBase::GetInstance();
163 if (rdbStore != contactDataBase_->contactStore_) {
164 HILOG_ERROR("UpdateCallLogByPhoneNum rdbStore is profile, not need update");
165 return;
166 }
167 unsigned int count = rawContactIdVector.size();
168 for (unsigned int i = 0; i < count; i++) {
169 std::string queryContactIdSql;
170 queryContactIdSql.append(" SELECT ")
171 .append(RawContactColumns::CONTACT_ID)
172 .append(" FROM ")
173 .append(ViewName::VIEW_RAW_CONTACT)
174 .append(" WHERE ")
175 .append(ContactPublicColumns::ID)
176 .append(" = ")
177 .append(std::to_string(rawContactIdVector[i]));
178 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> rawContactResultSet =
179 rdbStore->QuerySql(queryContactIdSql);
180 int contactId = 0;
181 if (rawContactResultSet->GoToFirstRow() == OHOS::NativeRdb::E_OK) {
182 std::string columnName = RawContactColumns::CONTACT_ID;
183 int columnIndex = 0;
184 rawContactResultSet->GetColumnIndex(columnName, columnIndex);
185 rawContactResultSet->GetInt(columnIndex, contactId);
186 rawContactResultSet->GoToNextRow();
187 }
188 rawContactResultSet->Close();
189 if (contactId <= 0) {
190 return;
191 }
192 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = QueryDataForCallLog(rdbStore, contactId);
193 DataToUpdateCallLog(isDelete, contactId, resultSet);
194 }
195 }
196
DataToUpdateCallLog(bool isDelete,int contactId,std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> & resultSet)197 void ContactsUpdateHelper::DataToUpdateCallLog(
198 bool isDelete, int contactId, std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> &resultSet)
199 {
200 int rowCount = 0;
201 resultSet->GetRowCount(rowCount);
202 int resultSetNum = resultSet->GoToFirstRow();
203 while (resultSetNum == OHOS::NativeRdb::E_OK) {
204 std::string phoneNumber;
205 std::string name;
206 std::string quickSearch;
207 // not delete contact
208 if (!isDelete) {
209 resultSet->GetString(0, name);
210 }
211 resultSet->GetString(RESULT_GET_ONE, phoneNumber);
212 resultSet->GetString(RESULT_GET_TWO, quickSearch);
213 UpdateCallLog(phoneNumber, name, quickSearch, isDelete, true);
214 UpdateCallLog(phoneNumber, name, quickSearch, isDelete, false);
215 resultSetNum = resultSet->GoToNextRow();
216 }
217 resultSet->Close();
218 if (rowCount == 0) {
219 // contact data update callLog not found
220 std::string quickSearch = std::to_string(contactId);
221 std::string name;
222 UpdateCallLogNameNull(name, quickSearch, true);
223 UpdateCallLogNameNull(name, quickSearch, false);
224 }
225 }
226
QueryDataForCallLog(std::shared_ptr<OHOS::NativeRdb::RdbStore> & rdbStore,int contactId)227 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> ContactsUpdateHelper::QueryDataForCallLog(
228 std::shared_ptr<OHOS::NativeRdb::RdbStore> &rdbStore, int contactId)
229 {
230 ContactsType contactsType;
231 int typeNameId = contactsType.LookupTypeId(rdbStore, ContentTypeData::PHONE);
232 std::string sql;
233 sql.append("SELECT ")
234 .append(RawContactColumns::DISPLAY_NAME)
235 .append(",")
236 .append(ContactDataColumns::DETAIL_INFO)
237 .append(",")
238 .append(RawContactColumns::CONTACT_ID)
239 .append(" FROM ")
240 .append(ViewName::VIEW_CONTACT_DATA)
241 .append(" WHERE ")
242 .append(ContactDataColumns::RAW_CONTACT_ID)
243 .append(" = (SELECT min(")
244 .append(ContactDataColumns::RAW_CONTACT_ID)
245 .append(") FROM ")
246 .append(ViewName::VIEW_CONTACT_DATA)
247 .append(" WHERE ")
248 .append(RawContactColumns::CONTACT_ID)
249 .append(" = ")
250 .append(std::to_string(contactId))
251 .append(" AND ")
252 .append(ContentTypeColumns::CONTENT_TYPE)
253 .append(" = '")
254 .append(ContentTypeData::PHONE)
255 .append("') AND ")
256 .append(ContactDataColumns::TYPE_ID)
257 .append(" = ")
258 .append(std::to_string(typeNameId));
259 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = rdbStore->QuerySql(sql);
260 if (resultSet == nullptr) {
261 HILOG_ERROR("ContactsUpdateHelper QueryDataForCallLog resultSet is nullptr ");
262 }
263 return resultSet;
264 }
265
UpdateCallLogNameNull(std::string & name,std::string & quickSearch,bool isCallLog)266 int ContactsUpdateHelper::UpdateCallLogNameNull(std::string &name, std::string &quickSearch, bool isCallLog)
267 {
268 std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
269 OHOS::NativeRdb::ValuesBucket updateCallLogValues;
270 updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
271 updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
272 std::string tabName = CallsTableName::VOICEMAIL;
273 if (isCallLog) {
274 tabName = CallsTableName::CALLLOG;
275 }
276 auto predicates = OHOS::NativeRdb::RdbPredicates(tabName);
277 std::string updateWheres;
278 updateWheres.append(CallLogColumns::QUICK_SEARCH_KEY).append(" = ? ");
279 std::vector<std::string> updateArgs;
280 updateArgs.push_back(quickSearch);
281 predicates.SetWhereClause(updateWheres);
282 predicates.SetWhereArgs(updateArgs);
283 int ret = RDB_EXECUTE_FAIL;
284 if (isCallLog) {
285 ret = callLogDataBase->UpdateCallLog(updateCallLogValues, predicates);
286 } else {
287 ret = VoiceMailDataBase::GetInstance()->UpdateVoiceMail(updateCallLogValues, predicates);
288 }
289 if (ret != OHOS::NativeRdb::E_OK) {
290 HILOG_ERROR("UpdateCallLogPhone name error, phone number is %{public}d", ret);
291 return RDB_EXECUTE_FAIL;
292 }
293 return ret;
294 }
295
296 /**
297 * @brief Update table calllog
298 *
299 * @param phoneNumber Contacts's phone number
300 * @param name CallLog name to update
301 * @param quickSearch Contacts's quick search key
302 * @param isDelete Contacts field value to update
303 * @param isCallLog Contacts field value to update
304 *
305 * @return Update calllog results code
306 */
UpdateCallLog(std::string & phoneNumber,std::string & name,std::string & quickSearch,bool isDelete,bool isCallLog)307 int ContactsUpdateHelper::UpdateCallLog(
308 std::string &phoneNumber, std::string &name, std::string &quickSearch, bool isDelete, bool isCallLog)
309 {
310 if (phoneNumber.empty()) {
311 return RDB_EXECUTE_OK;
312 }
313 std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
314 OHOS::NativeRdb::ValuesBucket updateCallLogValues;
315 if (isDelete) {
316 updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
317 updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
318 } else {
319 updateCallLogValues.PutString(CallLogColumns::DISPLAY_NAME, name);
320 updateCallLogValues.PutString(CallLogColumns::QUICK_SEARCH_KEY, quickSearch);
321 }
322 updateCallLogValues.PutString(CallLogColumns::PHONE_NUMBER, phoneNumber);
323 std::string tabName = CallsTableName::VOICEMAIL;
324 if (isCallLog) {
325 tabName = CallsTableName::CALLLOG;
326 }
327 auto predicates = OHOS::NativeRdb::RdbPredicates(tabName);
328 std::string updateWheres;
329 updateWheres.append(CallLogColumns::PHONE_NUMBER).append(" = ? ");
330 std::vector<std::string> updateArgs;
331 updateArgs.push_back(phoneNumber);
332 predicates.SetWhereClause(updateWheres);
333 predicates.SetWhereArgs(updateArgs);
334 int ret = RDB_EXECUTE_FAIL;
335 if (isCallLog) {
336 ret = callLogDataBase->UpdateCallLog(updateCallLogValues, predicates);
337 } else {
338 ret = VoiceMailDataBase::GetInstance()->UpdateVoiceMail(updateCallLogValues, predicates);
339 }
340 if (ret != OHOS::NativeRdb::E_OK) {
341 HILOG_ERROR("UpdateCallLogPhone name error, phone number is %{public}d", ret);
342 return RDB_EXECUTE_FAIL;
343 }
344 return ret;
345 }
346
GetUpdateDisPlayNameValuesBucket(OHOS::NativeRdb::ValuesBucket linkDataDataValues,bool isDelete)347 OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateDisPlayNameValuesBucket(
348 OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
349 {
350 OHOS::NativeRdb::ValuesBucket valuesBucket;
351 if (isDelete) {
352 valuesBucket.PutNull(RawContactColumns::DISPLAY_NAME);
353 valuesBucket.PutNull(RawContactColumns::SORT_FIRST_LETTER);
354 valuesBucket.PutNull(RawContactColumns::SORT);
355 return valuesBucket;
356 }
357 std::string displayName;
358 if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
359 OHOS::NativeRdb::ValueObject typeValue;
360 linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
361 typeValue.GetString(displayName);
362 }
363 valuesBucket.PutString(RawContactColumns::DISPLAY_NAME, displayName);
364 std::string phoneticName;
365 if (linkDataDataValues.HasColumn(RawContactColumns::PHONETIC_NAME)) {
366 OHOS::NativeRdb::ValueObject typeValue;
367 linkDataDataValues.GetObject(ContactDataColumns::PHONETIC_NAME, typeValue);
368 typeValue.GetString(phoneticName);
369 }
370 valuesBucket.PutString(RawContactColumns::PHONETIC_NAME, phoneticName);
371 return valuesBucket;
372 }
373
GetUpdateSearchNameValuesBucket(OHOS::NativeRdb::ValuesBucket linkDataDataValues,bool isDelete)374 OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateSearchNameValuesBucket(
375 OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
376 {
377 OHOS::NativeRdb::ValuesBucket valuesBucket;
378 if (isDelete) {
379 valuesBucket.PutNull(SearchContactColumns::SEARCH_NAME);
380 return valuesBucket;
381 }
382 std::string displayName;
383 if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
384 OHOS::NativeRdb::ValueObject typeValue;
385 linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
386 typeValue.GetString(displayName);
387 }
388 valuesBucket.PutString(RawContactColumns::DISPLAY_NAME, displayName);
389 return valuesBucket;
390 }
391
GetUpdateCompanyValuesBucket(OHOS::NativeRdb::ValuesBucket linkDataDataValues,bool isDelete)392 OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateCompanyValuesBucket(
393 OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
394 {
395 OHOS::NativeRdb::ValuesBucket valuesBucket;
396 if (isDelete) {
397 valuesBucket.PutNull(RawContactColumns::COMPANY);
398 valuesBucket.PutNull(RawContactColumns::POSITION);
399 return valuesBucket;
400 }
401 if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
402 std::string company;
403 OHOS::NativeRdb::ValueObject typeValue;
404 linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
405 typeValue.GetString(company);
406 valuesBucket.PutString(RawContactColumns::COMPANY, company);
407 }
408 if (linkDataDataValues.HasColumn(ContactDataColumns::POSITION)) {
409 std::string position;
410 OHOS::NativeRdb::ValueObject typeValue;
411 linkDataDataValues.GetObject(ContactDataColumns::POSITION, typeValue);
412 typeValue.GetString(position);
413 valuesBucket.PutString(RawContactColumns::POSITION, position);
414 }
415 return valuesBucket;
416 }
417 } // namespace Contacts
418 } // namespace OHOS