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 auto rawContactResultSet = rdbStore->QuerySql(queryContactIdSql);
179 int contactId = 0;
180 if (rawContactResultSet->GoToFirstRow() == OHOS::NativeRdb::E_OK) {
181 std::string columnName = RawContactColumns::CONTACT_ID;
182 int columnIndex = 0;
183 rawContactResultSet->GetColumnIndex(columnName, columnIndex);
184 rawContactResultSet->GetInt(columnIndex, contactId);
185 rawContactResultSet->GoToNextRow();
186 }
187 rawContactResultSet->Close();
188 if (contactId <= 0) {
189 return;
190 }
191 auto resultSet = QueryDataForCallLog(rdbStore, contactId);
192 DataToUpdateCallLog(isDelete, contactId, resultSet);
193 }
194 }
195
DataToUpdateCallLog(bool isDelete,int contactId,std::shared_ptr<OHOS::NativeRdb::ResultSet> & resultSet)196 void ContactsUpdateHelper::DataToUpdateCallLog(
197 bool isDelete, int contactId, std::shared_ptr<OHOS::NativeRdb::ResultSet> &resultSet)
198 {
199 int rowCount = 0;
200 resultSet->GetRowCount(rowCount);
201 int resultSetNum = resultSet->GoToFirstRow();
202 while (resultSetNum == OHOS::NativeRdb::E_OK) {
203 std::string phoneNumber;
204 std::string name;
205 std::string quickSearch;
206 // not delete contact
207 if (!isDelete) {
208 resultSet->GetString(0, name);
209 }
210 resultSet->GetString(RESULT_GET_ONE, phoneNumber);
211 resultSet->GetString(RESULT_GET_TWO, quickSearch);
212 UpdateCallLog(phoneNumber, name, quickSearch, isDelete, true);
213 UpdateCallLog(phoneNumber, name, quickSearch, isDelete, false);
214 resultSetNum = resultSet->GoToNextRow();
215 }
216 resultSet->Close();
217 if (rowCount == 0) {
218 // contact data update callLog not found
219 std::string quickSearch = std::to_string(contactId);
220 std::string name;
221 UpdateCallLogNameNull(name, quickSearch, true);
222 UpdateCallLogNameNull(name, quickSearch, false);
223 }
224 }
225
QueryDataForCallLog(std::shared_ptr<OHOS::NativeRdb::RdbStore> & rdbStore,int contactId)226 std::shared_ptr<OHOS::NativeRdb::ResultSet> ContactsUpdateHelper::QueryDataForCallLog(
227 std::shared_ptr<OHOS::NativeRdb::RdbStore> &rdbStore, int contactId)
228 {
229 ContactsType contactsType;
230 int typeNameId = contactsType.LookupTypeId(rdbStore, ContentTypeData::PHONE);
231 std::string sql;
232 sql.append("SELECT ")
233 .append(RawContactColumns::DISPLAY_NAME)
234 .append(",")
235 .append(ContactDataColumns::DETAIL_INFO)
236 .append(",")
237 .append(RawContactColumns::CONTACT_ID)
238 .append(" FROM ")
239 .append(ViewName::VIEW_CONTACT_DATA)
240 .append(" WHERE ")
241 .append(ContactDataColumns::RAW_CONTACT_ID)
242 .append(" = (SELECT min(")
243 .append(ContactDataColumns::RAW_CONTACT_ID)
244 .append(") FROM ")
245 .append(ViewName::VIEW_CONTACT_DATA)
246 .append(" WHERE ")
247 .append(RawContactColumns::CONTACT_ID)
248 .append(" = ")
249 .append(std::to_string(contactId))
250 .append(" AND ")
251 .append(ContentTypeColumns::CONTENT_TYPE)
252 .append(" = '")
253 .append(ContentTypeData::PHONE)
254 .append("') AND ")
255 .append(ContactDataColumns::TYPE_ID)
256 .append(" = ")
257 .append(std::to_string(typeNameId));
258 auto resultSet = rdbStore->QuerySql(sql);
259 if (resultSet == nullptr) {
260 HILOG_ERROR("ContactsUpdateHelper QueryDataForCallLog resultSet is nullptr ");
261 }
262 return resultSet;
263 }
264
UpdateCallLogNameNull(std::string & name,std::string & quickSearch,bool isCallLog)265 int ContactsUpdateHelper::UpdateCallLogNameNull(std::string &name, std::string &quickSearch, bool isCallLog)
266 {
267 std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
268 OHOS::NativeRdb::ValuesBucket updateCallLogValues;
269 updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
270 updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
271 std::string tabName = CallsTableName::VOICEMAIL;
272 if (isCallLog) {
273 tabName = CallsTableName::CALLLOG;
274 }
275 auto predicates = OHOS::NativeRdb::RdbPredicates(tabName);
276 std::string updateWheres;
277 updateWheres.append(CallLogColumns::QUICK_SEARCH_KEY).append(" = ? ");
278 std::vector<std::string> updateArgs;
279 updateArgs.push_back(quickSearch);
280 predicates.SetWhereClause(updateWheres);
281 predicates.SetWhereArgs(updateArgs);
282 int ret = RDB_EXECUTE_FAIL;
283 if (isCallLog) {
284 ret = callLogDataBase->UpdateCallLog(updateCallLogValues, predicates);
285 } else {
286 ret = VoiceMailDataBase::GetInstance()->UpdateVoiceMail(updateCallLogValues, predicates);
287 }
288 if (ret != OHOS::NativeRdb::E_OK) {
289 HILOG_ERROR("UpdateCallLogPhone name error, phone number is %{public}d", ret);
290 return RDB_EXECUTE_FAIL;
291 }
292 return ret;
293 }
294
295 /**
296 * @brief Update table calllog
297 *
298 * @param phoneNumber Contacts's phone number
299 * @param name CallLog name to update
300 * @param quickSearch Contacts's quick search key
301 * @param isDelete Contacts field value to update
302 * @param isCallLog Contacts field value to update
303 *
304 * @return Update calllog results code
305 */
UpdateCallLog(std::string & phoneNumber,std::string & name,std::string & quickSearch,bool isDelete,bool isCallLog)306 int ContactsUpdateHelper::UpdateCallLog(
307 std::string &phoneNumber, std::string &name, std::string &quickSearch, bool isDelete, bool isCallLog)
308 {
309 if (phoneNumber.empty()) {
310 return RDB_EXECUTE_OK;
311 }
312 std::shared_ptr<CallLogDataBase> callLogDataBase = CallLogDataBase::GetInstance();
313 OHOS::NativeRdb::ValuesBucket updateCallLogValues;
314 if (isDelete) {
315 updateCallLogValues.PutNull(CallLogColumns::DISPLAY_NAME);
316 updateCallLogValues.PutNull(CallLogColumns::QUICK_SEARCH_KEY);
317 } else {
318 updateCallLogValues.PutString(CallLogColumns::DISPLAY_NAME, name);
319 updateCallLogValues.PutString(CallLogColumns::QUICK_SEARCH_KEY, quickSearch);
320 }
321 updateCallLogValues.PutString(CallLogColumns::PHONE_NUMBER, phoneNumber);
322 std::string tabName = CallsTableName::VOICEMAIL;
323 if (isCallLog) {
324 tabName = CallsTableName::CALLLOG;
325 }
326 auto predicates = OHOS::NativeRdb::RdbPredicates(tabName);
327 std::string updateWheres;
328 updateWheres.append(CallLogColumns::PHONE_NUMBER).append(" = ? ");
329 std::vector<std::string> updateArgs;
330 updateArgs.push_back(phoneNumber);
331 predicates.SetWhereClause(updateWheres);
332 predicates.SetWhereArgs(updateArgs);
333 int ret = RDB_EXECUTE_FAIL;
334 if (isCallLog) {
335 ret = callLogDataBase->UpdateCallLog(updateCallLogValues, predicates);
336 } else {
337 ret = VoiceMailDataBase::GetInstance()->UpdateVoiceMail(updateCallLogValues, predicates);
338 }
339 if (ret != OHOS::NativeRdb::E_OK) {
340 HILOG_ERROR("UpdateCallLogPhone name error, phone number is %{public}d", ret);
341 return RDB_EXECUTE_FAIL;
342 }
343 return ret;
344 }
345
GetUpdateDisPlayNameValuesBucket(OHOS::NativeRdb::ValuesBucket linkDataDataValues,bool isDelete)346 OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateDisPlayNameValuesBucket(
347 OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
348 {
349 OHOS::NativeRdb::ValuesBucket valuesBucket;
350 if (isDelete) {
351 valuesBucket.PutNull(RawContactColumns::DISPLAY_NAME);
352 valuesBucket.PutNull(RawContactColumns::SORT_FIRST_LETTER);
353 valuesBucket.PutNull(RawContactColumns::SORT);
354 return valuesBucket;
355 }
356 std::string displayName;
357 if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
358 OHOS::NativeRdb::ValueObject typeValue;
359 linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
360 typeValue.GetString(displayName);
361 }
362 valuesBucket.PutString(RawContactColumns::DISPLAY_NAME, displayName);
363 std::string phoneticName;
364 if (linkDataDataValues.HasColumn(RawContactColumns::PHONETIC_NAME)) {
365 OHOS::NativeRdb::ValueObject typeValue;
366 linkDataDataValues.GetObject(ContactDataColumns::PHONETIC_NAME, typeValue);
367 typeValue.GetString(phoneticName);
368 }
369 valuesBucket.PutString(RawContactColumns::PHONETIC_NAME, phoneticName);
370 return valuesBucket;
371 }
372
GetUpdateSearchNameValuesBucket(OHOS::NativeRdb::ValuesBucket linkDataDataValues,bool isDelete)373 OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateSearchNameValuesBucket(
374 OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
375 {
376 OHOS::NativeRdb::ValuesBucket valuesBucket;
377 if (isDelete) {
378 valuesBucket.PutNull(SearchContactColumns::SEARCH_NAME);
379 return valuesBucket;
380 }
381 std::string displayName;
382 if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
383 OHOS::NativeRdb::ValueObject typeValue;
384 linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
385 typeValue.GetString(displayName);
386 }
387 valuesBucket.PutString(RawContactColumns::DISPLAY_NAME, displayName);
388 return valuesBucket;
389 }
390
GetUpdateCompanyValuesBucket(OHOS::NativeRdb::ValuesBucket linkDataDataValues,bool isDelete)391 OHOS::NativeRdb::ValuesBucket ContactsUpdateHelper::GetUpdateCompanyValuesBucket(
392 OHOS::NativeRdb::ValuesBucket linkDataDataValues, bool isDelete)
393 {
394 OHOS::NativeRdb::ValuesBucket valuesBucket;
395 if (isDelete) {
396 valuesBucket.PutNull(RawContactColumns::COMPANY);
397 valuesBucket.PutNull(RawContactColumns::POSITION);
398 return valuesBucket;
399 }
400 if (linkDataDataValues.HasColumn(ContactDataColumns::DETAIL_INFO)) {
401 std::string company;
402 OHOS::NativeRdb::ValueObject typeValue;
403 linkDataDataValues.GetObject(ContactDataColumns::DETAIL_INFO, typeValue);
404 typeValue.GetString(company);
405 valuesBucket.PutString(RawContactColumns::COMPANY, company);
406 }
407 if (linkDataDataValues.HasColumn(ContactDataColumns::POSITION)) {
408 std::string position;
409 OHOS::NativeRdb::ValueObject typeValue;
410 linkDataDataValues.GetObject(ContactDataColumns::POSITION, typeValue);
411 typeValue.GetString(position);
412 valuesBucket.PutString(RawContactColumns::POSITION, position);
413 }
414 return valuesBucket;
415 }
416 } // namespace Contacts
417 } // namespace OHOS