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_database.h"
17
18 #include <cmath>
19 #include <cstdio>
20 #include <mutex>
21 #include <unistd.h>
22
23 #include "account_manager.h"
24 #include "async_task.h"
25 #include "common.h"
26 #include "contacts.h"
27 #include "contacts_account.h"
28 #include "contacts_columns.h"
29 #include "contacts_json_utils.h"
30 #include "contacts_search.h"
31 #include "contacts_type.h"
32 #include "contacts_update_helper.h"
33 #include "database_disaster_recovery.h"
34 #include "hilog_wrapper.h"
35 #include "match_candidate.h"
36 #include "merger_contacts.h"
37 #include "predicates_convert.h"
38 #include "raw_contacts.h"
39
40 namespace OHOS {
41 namespace Contacts {
42 std::shared_ptr<ContactsDataBase> ContactsDataBase::contactDataBase_ = nullptr;
43 std::shared_ptr<CallLogDataBase> ContactsDataBase::callLogDataBase_ = nullptr;
44 std::shared_ptr<OHOS::NativeRdb::RdbStore> ContactsDataBase::store_ = nullptr;
45 std::shared_ptr<OHOS::NativeRdb::RdbStore> ContactsDataBase::contactStore_ = nullptr;
46 static AsyncTaskQueue *g_asyncTaskQueue;
47 static std::string g_databaseName;
48 namespace {
49 std::mutex g_mtx;
50 }
51
ContactsDataBase()52 ContactsDataBase::ContactsDataBase()
53 {
54 g_databaseName = ContactsPath::RDB_PATH + "contacts.db";
55 HILOG_INFO("ContactsDataBase g_databaseName :%{public}s", g_databaseName.c_str());
56 int errCode = OHOS::NativeRdb::E_OK;
57 OHOS::NativeRdb::RdbStoreConfig config(g_databaseName);
58 SqliteOpenHelperContactCallback sqliteOpenHelperCallback;
59 contactStore_ =
60 OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION, sqliteOpenHelperCallback, errCode);
61 if (errCode != OHOS::NativeRdb::E_OK) {
62 HILOG_ERROR("ContactsDataBase :%{public}d", errCode);
63 if (REBASE_SETTING == 0) {
64 std::shared_ptr<OHOS::Contacts::DataBaseDisasterRecovery> instance =
65 OHOS::Contacts::DataBaseDisasterRecovery::GetInstance();
66 instance->RecoveryDatabase(CONTACT_DATABASE_NAME);
67 contactStore_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(
68 config, DATABASE_OPEN_VERSION, sqliteOpenHelperCallback, errCode);
69 }
70 }
71 if (errCode != OHOS::NativeRdb::E_OK) {
72 HILOG_ERROR("ContactsDataBase open error :%{public}d", errCode);
73 return;
74 }
75 store_ = contactStore_;
76 std::shared_ptr<ContactsAccount> contactsAccount = ContactsAccount::GetInstance();
77 contactsAccount->PrepopulateCommonAccountTypes(store_);
78 ContactsType contactsType;
79 contactsType.PrepopulateCommonTypes(store_);
80 callLogDataBase_ = CallLogDataBase::GetInstance();
81 g_asyncTaskQueue = AsyncTaskQueue::Instance();
82 }
83
ContactsDataBase(const ContactsDataBase &)84 ContactsDataBase::ContactsDataBase(const ContactsDataBase &)
85 {
86 }
87
GetInstance()88 std::shared_ptr<ContactsDataBase> ContactsDataBase::GetInstance()
89 {
90 if (contactDataBase_ == nullptr) {
91 contactDataBase_.reset(new ContactsDataBase());
92 }
93 return contactDataBase_;
94 }
95
BeginTransaction()96 int ContactsDataBase::BeginTransaction()
97 {
98 if (store_ == nullptr) {
99 HILOG_ERROR("ContactsDataBase BeginTransaction store_ is nullptr");
100 return RDB_OBJECT_EMPTY;
101 }
102 int ret = store_->BeginTransaction();
103 if (ret != OHOS::NativeRdb::E_OK) {
104 HILOG_ERROR("ContactsDataBase BeginTransaction failed :%{public}d", ret);
105 }
106 return ret;
107 }
108
Commit()109 int ContactsDataBase::Commit()
110 {
111 if (store_ == nullptr) {
112 HILOG_ERROR("ContactsDataBase Commit store_ is nullptr");
113 return RDB_OBJECT_EMPTY;
114 }
115 int ret = store_->Commit();
116 if (ret != OHOS::NativeRdb::E_OK) {
117 HILOG_ERROR("ContactsDataBase Commit failed :%{public}d", ret);
118 }
119 return ret;
120 }
121
RollBack()122 int ContactsDataBase::RollBack()
123 {
124 if (store_ == nullptr) {
125 HILOG_ERROR("ContactsDataBase RollBack store_ is nullptr");
126 return RDB_OBJECT_EMPTY;
127 }
128 int ret = store_->RollBack();
129 if (ret != OHOS::NativeRdb::E_OK) {
130 HILOG_ERROR("ContactsDataBase RollBack failed :%{public}d", ret);
131 }
132 return ret;
133 }
134
135 /**
136 * @brief Insert contact data into the raw_contact table
137 *
138 * @param table Raw_contact table
139 * @param rawContactValues Contact to be inserted
140 *
141 * @return The result returned by the insert
142 */
InsertRawContact(std::string table,OHOS::NativeRdb::ValuesBucket rawContactValues)143 int64_t ContactsDataBase::InsertRawContact(std::string table, OHOS::NativeRdb::ValuesBucket rawContactValues)
144 {
145 if (store_ == nullptr) {
146 HILOG_ERROR("ContactsDataBase InsertRawContact store_ is nullptr");
147 return RDB_OBJECT_EMPTY;
148 }
149 // Get default account
150 AccountManager accountManager;
151 int accountId = accountManager.GetAccount();
152 rawContactValues.PutInt(RawContactColumns::ACCOUNT_ID, accountId);
153 RawContacts rawContacts;
154 int64_t outRawContactId = 0;
155 int rowRet = rawContacts.InsertRawContact(store_, outRawContactId, rawContactValues);
156 if (rowRet != OHOS::NativeRdb::E_OK) {
157 HILOG_ERROR("InsertRawContact insertRawContact failed:%{public}d", rowRet);
158 return RDB_EXECUTE_FAIL;
159 }
160 Contacts contactsContact;
161 int64_t contactId = 0;
162 int rowContactRet = contactsContact.InsertContact(store_, outRawContactId, rawContactValues, contactId);
163 if (rowContactRet != OHOS::NativeRdb::E_OK) {
164 HILOG_ERROR("InsertRawContact insertContact failed:%{public}d", rowContactRet);
165 return RDB_EXECUTE_FAIL;
166 }
167 // update contactId to rawContacts
168 OHOS::NativeRdb::ValuesBucket upRawContactValues;
169 std::string contactIdKey = RawContactColumns::CONTACT_ID;
170 upRawContactValues.PutInt(contactIdKey, contactId);
171 std::string upWhereClause;
172 upWhereClause.append(ContactPublicColumns::ID).append(" = ?");
173 std::vector<std::string> upWhereArgs;
174 upWhereArgs.push_back(std::to_string(outRawContactId));
175 int ret = rawContacts.UpdateRawContact(store_, upRawContactValues, upWhereClause, upWhereArgs);
176 if (ret != OHOS::NativeRdb::E_OK) {
177 HILOG_ERROR("insertRawContact Update contactId to rawContacts failed:%{public}d", rowContactRet);
178 return RDB_EXECUTE_FAIL;
179 }
180 // Search insterted contact data
181 ContactsSearch contactsSearch;
182 int64_t searchContactId = 0;
183 int rowSearchContactRet =
184 contactsSearch.Insert(store_, contactId, outRawContactId, rawContactValues, searchContactId);
185 if (rowSearchContactRet != OHOS::NativeRdb::E_OK) {
186 HILOG_ERROR("InsertRawContact insertSearchContact failed:%{public}d", rowSearchContactRet);
187 return RDB_EXECUTE_FAIL;
188 }
189 return outRawContactId;
190 }
191
GetContactByValue(int & contactValue,OHOS::NativeRdb::ValueObject & value)192 void ContactsDataBase::GetContactByValue(int &contactValue, OHOS::NativeRdb::ValueObject &value)
193 {
194 if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_NULL) {
195 HILOG_ERROR("GetContactByValue value is nullptr");
196 contactValue = 0;
197 return;
198 }
199 if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_INT) {
200 value.GetInt(contactValue);
201 return;
202 }
203 if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_DOUBLE) {
204 double temp = 0;
205 value.GetDouble(temp);
206 contactValue = ceil(temp);
207 return;
208 }
209 if (value.GetType() == OHOS::NativeRdb::ValueObjectType::TYPE_STRING) {
210 std::string tempString;
211 value.GetString(tempString);
212 contactValue = std::stoi(tempString);
213 return;
214 }
215 contactValue = 0;
216 }
217
218 /**
219 * @brief Insert data into table contact_data
220 *
221 * @param table Insert tableName
222 * @param contactDataValues Parameters to be passed for insert operation
223 *
224 * @return The result returned by the insert operation
225 */
InsertContactData(std::string table,OHOS::NativeRdb::ValuesBucket contactDataValues)226 int64_t ContactsDataBase::InsertContactData(std::string table, OHOS::NativeRdb::ValuesBucket contactDataValues)
227 {
228 if (store_ == nullptr) {
229 HILOG_ERROR("ContactsDataBase InsertContactData store_ is nullptr");
230 return RDB_OBJECT_EMPTY;
231 }
232 int rawContactId = OHOS::NativeRdb::E_OK;
233 if (!contactDataValues.HasColumn(ContactDataColumns::RAW_CONTACT_ID)) {
234 HILOG_ERROR("InsertContactData raw_contact_id is required");
235 return RDB_EXECUTE_FAIL;
236 }
237 OHOS::NativeRdb::ValueObject value;
238 contactDataValues.GetObject(ContactDataColumns::RAW_CONTACT_ID, value);
239 GetContactByValue(rawContactId, value);
240 if (rawContactId <= 0) {
241 HILOG_ERROR("InsertContactData raw_contact_id is required %{public}d", rawContactId);
242 return RDB_EXECUTE_FAIL;
243 }
244 int typeId = RDB_EXECUTE_FAIL;
245 std::string typeText;
246 int retCode = GetTypeText(contactDataValues, typeId, rawContactId, typeText);
247 if (retCode != OHOS::NativeRdb::E_OK) {
248 HILOG_ERROR("InsertContactData getTypeText failed:%{public}d", retCode);
249 return retCode;
250 }
251 if (typeId <= 0) {
252 HILOG_ERROR("InsertContactData typeId is required %{public}d", typeId);
253 return RDB_EXECUTE_FAIL;
254 }
255 // delete content_type
256 contactDataValues.Delete(ContentTypeColumns::CONTENT_TYPE);
257 contactDataValues.PutInt(ContactDataColumns::TYPE_ID, typeId);
258 int64_t outDataRowId;
259 int ret = store_->Insert(outDataRowId, table, contactDataValues);
260 if (ret != OHOS::NativeRdb::E_OK) {
261 HILOG_ERROR("InsertContactData failed:%{public}d", ret);
262 return RDB_EXECUTE_FAIL;
263 }
264 std::vector<int> rawContactIdVector;
265 rawContactIdVector.push_back(rawContactId);
266 std::vector<std::string> typeTextVector;
267 typeTextVector.push_back(typeText);
268 ContactsUpdateHelper contactsUpdateHelper;
269 int updateDisplayRet =
270 contactsUpdateHelper.UpdateDisplay(rawContactIdVector, typeTextVector, store_, contactDataValues, false);
271 if (updateDisplayRet != OHOS::NativeRdb::E_OK) {
272 HILOG_ERROR("InsertContactData UpdateDisplay failed:%{public}d", updateDisplayRet);
273 return RDB_EXECUTE_FAIL;
274 }
275 MergeUpdateTask(store_, rawContactIdVector, false);
276 return outDataRowId;
277 }
278
GetTypeText(OHOS::NativeRdb::ValuesBucket & contactDataValues,int & typeId,int & rawContactId,std::string & typeText)279 int ContactsDataBase::GetTypeText(
280 OHOS::NativeRdb::ValuesBucket &contactDataValues, int &typeId, int &rawContactId, std::string &typeText)
281 {
282 // if content_type is added , get type_id by content_type
283 if (contactDataValues.HasColumn(ContentTypeColumns::CONTENT_TYPE)) {
284 OHOS::NativeRdb::ValueObject typeValue;
285 contactDataValues.GetObject(ContentTypeColumns::CONTENT_TYPE, typeValue);
286 typeValue.GetString(typeText);
287 if (typeText.empty()) {
288 HILOG_ERROR("GetTypeText type is required");
289 return PARAMETER_EMPTY;
290 }
291 // get type id
292 ContactsType contactsType;
293 typeId = contactsType.LookupTypeId(store_, typeText);
294 if (typeId == RDB_EXECUTE_FAIL) {
295 // type not found. insert the default type
296 typeId = contactsType.Insert(store_, typeText, RDB_OBJECT_EMPTY);
297 }
298 if (typeId == RDB_EXECUTE_FAIL) {
299 return RDB_EXECUTE_FAIL;
300 }
301 return RDB_EXECUTE_OK;
302 } else if (contactDataValues.HasColumn(ContactDataColumns::TYPE_ID)) {
303 OHOS::NativeRdb::ValueObject typeValue;
304 contactDataValues.GetObject(ContactDataColumns::TYPE_ID, typeValue);
305 GetContactByValue(typeId, typeValue);
306 ContactsType contactsType;
307 typeText = contactsType.GetTypeText(store_, typeId);
308 return RDB_EXECUTE_OK;
309 }
310 return RDB_EXECUTE_FAIL;
311 }
312
313 /**
314 * @brief Insert data into table groups
315 *
316 * @param table Insert tableName
317 * @param initialValues Parameters to be passed for insert operation
318 *
319 * @return The result returned by the insert operation
320 */
InsertGroup(std::string table,OHOS::NativeRdb::ValuesBucket initialValues)321 int64_t ContactsDataBase::InsertGroup(std::string table, OHOS::NativeRdb::ValuesBucket initialValues)
322 {
323 if (store_ == nullptr) {
324 HILOG_ERROR("ContactsDataBase InsertGroup store_ is nullptr");
325 return RDB_OBJECT_EMPTY;
326 }
327 AccountManager accountManager;
328 // get default account
329 int accountId = accountManager.GetAccount();
330 initialValues.PutInt(GroupsColumns::ACCOUNT_ID, accountId);
331 int64_t outGroupRowId = OHOS::NativeRdb::E_OK;
332 int ret = store_->Insert(outGroupRowId, table, initialValues);
333 if (ret != OHOS::NativeRdb::E_OK) {
334 HILOG_ERROR("InsertGroup failed:%{public}d", ret);
335 return RDB_EXECUTE_FAIL;
336 }
337 return outGroupRowId;
338 }
339
340 /**
341 * @brief Insert data into the contact_blocklist table
342 *
343 * @param table Insert tableName
344 * @param initialValues Parameters to be passed for insert operation
345 *
346 * @return The result returned by the insert operation
347 */
InsertBlockList(std::string table,OHOS::NativeRdb::ValuesBucket initialValues)348 int64_t ContactsDataBase::InsertBlockList(std::string table, OHOS::NativeRdb::ValuesBucket initialValues)
349 {
350 int64_t outRowId = OHOS::NativeRdb::E_OK;
351 int ret = store_->Insert(outRowId, table, initialValues);
352 if (ret != OHOS::NativeRdb::E_OK) {
353 return RDB_EXECUTE_FAIL;
354 }
355 return outRowId;
356 }
357
358 /**
359 * @brief Update data into contact_data table
360 *
361 * @param contactDataValues Parameters to be passed for update operation
362 * @param rdbPredicates Conditions for update operation
363 *
364 * @return The result returned by the update operation
365 */
UpdateContactData(OHOS::NativeRdb::ValuesBucket contactDataValues,OHOS::NativeRdb::RdbPredicates & rdbPredicates)366 int ContactsDataBase::UpdateContactData(
367 OHOS::NativeRdb::ValuesBucket contactDataValues, OHOS::NativeRdb::RdbPredicates &rdbPredicates)
368 {
369 if (store_ == nullptr) {
370 HILOG_ERROR("ContactsDataBase UpdateContactData store_ is nullptr");
371 return RDB_OBJECT_EMPTY;
372 }
373 int ret = BeginTransaction();
374 if (ret != OHOS::NativeRdb::E_OK) {
375 return RDB_EXECUTE_FAIL;
376 }
377 std::vector<std::string> types;
378 std::vector<int> rawContactIdVector = QueryContactDataRawContactId(rdbPredicates, types);
379 int changedRows = OHOS::NativeRdb::E_OK;
380 ret = store_->Update(changedRows, contactDataValues, rdbPredicates);
381 if (ret != OHOS::NativeRdb::E_OK) {
382 RollBack();
383 HILOG_ERROR("UpdateContactData failed:%{public}d", ret);
384 return RDB_EXECUTE_FAIL;
385 }
386 ContactsUpdateHelper contactsUpdateHelper;
387 ret = contactsUpdateHelper.UpdateDisplay(rawContactIdVector, types, store_, contactDataValues, false);
388 if (ret != OHOS::NativeRdb::E_OK) {
389 RollBack();
390 HILOG_ERROR("UpdateContactData UpdateDisplay failed:%{public}d", ret);
391 return RDB_EXECUTE_FAIL;
392 }
393 ret = Commit();
394 if (ret != OHOS::NativeRdb::E_OK) {
395 RollBack();
396 return RDB_EXECUTE_FAIL;
397 }
398 MergeUpdateTask(store_, rawContactIdVector, false);
399 return ret;
400 }
401
402 /**
403 * @brief Update data in the raw_contact table
404 *
405 * @param values Parameters to be passed for update operation
406 * @param rdbPredicates Conditions for update operation
407 *
408 * @return The result returned by the update operation
409 */
UpdateRawContact(OHOS::NativeRdb::ValuesBucket values,OHOS::NativeRdb::RdbPredicates & rdbPredicates)410 int ContactsDataBase::UpdateRawContact(
411 OHOS::NativeRdb::ValuesBucket values, OHOS::NativeRdb::RdbPredicates &rdbPredicates)
412 {
413 if (store_ == nullptr) {
414 HILOG_ERROR("ContactsDataBase UpdateRawContact store_ is nullptr");
415 return RDB_OBJECT_EMPTY;
416 }
417 std::vector<std::string> columns;
418 columns.push_back(ContactPublicColumns::ID);
419 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> rawContactResultSet = store_->Query(rdbPredicates, columns);
420 int rawContactResultSetNum = rawContactResultSet->GoToFirstRow();
421 std::vector<int> rawContactIdVector;
422 while (rawContactResultSetNum == OHOS::NativeRdb::E_OK) {
423 std::string columnName = ContactPublicColumns::ID;
424 int columnIndex = 0;
425 int rawContactId = 0;
426 rawContactResultSet->GetColumnIndex(columnName, columnIndex);
427 rawContactResultSet->GetInt(columnIndex, rawContactId);
428 rawContactIdVector.push_back(rawContactId);
429 rawContactResultSetNum = rawContactResultSet->GoToNextRow();
430 }
431 rawContactResultSet->Close();
432 int changedRows = OHOS::NativeRdb::E_OK;
433 int ret = store_->Update(changedRows, values, rdbPredicates);
434 if (ret != OHOS::NativeRdb::E_OK) {
435 HILOG_ERROR("UpdateRawContact failed:%{public}d", ret);
436 return RDB_EXECUTE_FAIL;
437 }
438 // add Restore contact judgment
439 int isDelete = RDB_EXECUTE_FAIL;
440 if (values.HasColumn(RawContactColumns::IS_DELETED)) {
441 OHOS::NativeRdb::ValueObject value;
442 values.GetObject(RawContactColumns::IS_DELETED, value);
443 GetContactByValue(isDelete, value);
444 if (isDelete == 0 && rawContactIdVector.size() > 0) {
445 ContactsUpdateHelper contactsUpdateHelper;
446 contactsUpdateHelper.UpdateCallLogByPhoneNum(rawContactIdVector, store_, false);
447 }
448 }
449 return ret;
450 }
451
452 /**
453 * @brief Update data in the contact_blocklist table
454 *
455 * @param values Parameters to be passed for update operation
456 * @param rdbPredicates Conditions for update operation
457 *
458 * @return The result returned by the update operation
459 */
UpdateBlockList(OHOS::NativeRdb::ValuesBucket values,OHOS::NativeRdb::RdbPredicates & rdbPredicates)460 int ContactsDataBase::UpdateBlockList(
461 OHOS::NativeRdb::ValuesBucket values, OHOS::NativeRdb::RdbPredicates &rdbPredicates)
462 {
463 if (store_ == nullptr) {
464 HILOG_ERROR("ContactsDataBase UpdateBlockList store_ is nullptr");
465 return RDB_OBJECT_EMPTY;
466 }
467 int changedRows = OHOS::NativeRdb::E_OK;
468 int ret = store_->Update(changedRows, values, rdbPredicates);
469 if (ret != OHOS::NativeRdb::E_OK) {
470 HILOG_ERROR("UpdateBlockList failed:%{public}d", ret);
471 return RDB_EXECUTE_FAIL;
472 }
473 HILOG_INFO("UpdateBlockList row:%{public}d", changedRows);
474 return ret;
475 }
476
477 /**
478 * @brief Update data in table groups
479 *
480 * @param values Parameters to be passed for update operation
481 * @param rdbPredicates Conditions for update operation
482 *
483 * @return The result returned by the update operation
484 */
UpdateGroup(OHOS::NativeRdb::ValuesBucket values,OHOS::NativeRdb::RdbPredicates & rdbPredicates)485 int ContactsDataBase::UpdateGroup(OHOS::NativeRdb::ValuesBucket values, OHOS::NativeRdb::RdbPredicates &rdbPredicates)
486 {
487 if (store_ == nullptr) {
488 HILOG_ERROR("ContactsDataBase UpdateGroup store_ is nullptr");
489 return RDB_OBJECT_EMPTY;
490 }
491 int changedRows = OHOS::NativeRdb::E_OK;
492 int ret = store_->Update(changedRows, values, rdbPredicates);
493 if (ret != OHOS::NativeRdb::E_OK) {
494 HILOG_ERROR("UpdateGroup failed:%{public}d", ret);
495 return RDB_EXECUTE_FAIL;
496 }
497 HILOG_INFO("UpdateGroup row:%{public}d", changedRows);
498 return ret;
499 }
500
501 /**
502 * @brief Delete data from contact_blocklist table
503 *
504 * @param rdbPredicates Conditions for delete operation
505 *
506 * @return The result returned by the delete operation
507 */
DeleteBlockList(OHOS::NativeRdb::RdbPredicates & rdbPredicates)508 int ContactsDataBase::DeleteBlockList(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
509 {
510 if (store_ == nullptr) {
511 HILOG_ERROR("ContactsDataBase DeleteBlockList store_ is nullptr");
512 return RDB_OBJECT_EMPTY;
513 }
514 int changedRows = OHOS::NativeRdb::E_OK;
515 int ret = store_->Delete(changedRows, rdbPredicates);
516 if (ret != OHOS::NativeRdb::E_OK) {
517 HILOG_ERROR("DeleteBlockList failed:%{public}d", ret);
518 return RDB_EXECUTE_FAIL;
519 }
520 HILOG_INFO("DeleteBlockList row:%{public}d", changedRows);
521 return ret;
522 }
523
524 /**
525 * @brief Delete data from table groups
526 *
527 * @param rdbPredicates Conditions for delete operation
528 *
529 * @return The result returned by the delete operation
530 */
DeleteGroup(OHOS::NativeRdb::RdbPredicates & rdbPredicates)531 int ContactsDataBase::DeleteGroup(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
532 {
533 if (store_ == nullptr) {
534 HILOG_ERROR("ContactsDataBase DeleteGroup store_ is nullptr");
535 return RDB_OBJECT_EMPTY;
536 }
537 int deletedRows = OHOS::NativeRdb::E_OK;
538 int ret = store_->Delete(deletedRows, rdbPredicates);
539 if (ret != OHOS::NativeRdb::E_OK) {
540 HILOG_ERROR("DeleteGroup failed:%{public}d", ret);
541 return RDB_EXECUTE_FAIL;
542 }
543 HILOG_INFO("DeleteGroup row:%{public}d", deletedRows);
544 return ret;
545 }
546
DeleteRecord(OHOS::NativeRdb::RdbPredicates & rdbPredicates)547 int ContactsDataBase::DeleteRecord(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
548 {
549 if (store_ == nullptr) {
550 HILOG_ERROR("ContactsDataBase DeleteRecord store_ is nullptr");
551 return RDB_OBJECT_EMPTY;
552 }
553 int deletedRows = OHOS::NativeRdb::E_OK;
554 int ret = store_->Delete(deletedRows, rdbPredicates);
555 if (ret != OHOS::NativeRdb::E_OK) {
556 HILOG_ERROR("DeleteRecord raw_contact_deleted failed:%{public}d", ret);
557 return RDB_EXECUTE_FAIL;
558 }
559 HILOG_INFO("DeleteRecord raw_contact_deleted row:%{public}d", deletedRows);
560 return ret;
561 }
562
563 /**
564 * @brief Delete data from contact_data table
565 *
566 * @param rdbPredicates Conditions for delete operation
567 *
568 * @return The result returned by the delete operation
569 */
DeleteContactData(OHOS::NativeRdb::RdbPredicates & rdbPredicates)570 int ContactsDataBase::DeleteContactData(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
571 {
572 if (store_ == nullptr) {
573 HILOG_ERROR("ContactsDataBase DeleteContactData store_ is nullptr");
574 return RDB_OBJECT_EMPTY;
575 }
576 int ret = BeginTransaction();
577 if (ret != OHOS::NativeRdb::E_OK) {
578 return RDB_EXECUTE_FAIL;
579 }
580 std::vector<std::string> types;
581 std::vector<int> rawContactIdVector = QueryContactDataRawContactId(rdbPredicates, types);
582 int deletedRows = OHOS::NativeRdb::E_OK;
583 store_->Delete(deletedRows, rdbPredicates);
584 ContactsUpdateHelper contactsUpdateHelper;
585 OHOS::NativeRdb::ValuesBucket contactDataValues;
586 int updateDisplayRet =
587 contactsUpdateHelper.UpdateDisplay(rawContactIdVector, types, store_, contactDataValues, true);
588 if (updateDisplayRet != OHOS::NativeRdb::E_OK) {
589 RollBack();
590 HILOG_ERROR("deleteContactData UpdateDisplay failed:%{public}d", updateDisplayRet);
591 return RDB_EXECUTE_FAIL;
592 }
593 ret = Commit();
594 if (ret != OHOS::NativeRdb::E_OK) {
595 RollBack();
596 return RDB_EXECUTE_FAIL;
597 }
598 MergeUpdateTask(store_, rawContactIdVector, true);
599 return ret;
600 }
601
602 /**
603 * @brief Delete data from the contact table
604 *
605 * @param rdbPredicates Conditions for delete operation
606 *
607 * @return The result returned by the delete operation
608 */
DeleteContact(OHOS::NativeRdb::RdbPredicates & rdbPredicates)609 int ContactsDataBase::DeleteContact(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
610 {
611 if (store_ == nullptr) {
612 HILOG_ERROR("ContactsDataBase DeleteContact store_ is nullptr");
613 return RDB_OBJECT_EMPTY;
614 }
615 int ret = BeginTransaction();
616 if (ret != OHOS::NativeRdb::E_OK) {
617 return RDB_EXECUTE_FAIL;
618 }
619 std::vector<OHOS::NativeRdb::ValuesBucket> queryValuesBucket = DeleteContactQuery(rdbPredicates);
620 int deleteRet = DeleteExecute(queryValuesBucket);
621 if (deleteRet != OHOS::NativeRdb::E_OK) {
622 RollBack();
623 return RDB_EXECUTE_FAIL;
624 }
625 deleteRet = Commit();
626 if (deleteRet != OHOS::NativeRdb::E_OK) {
627 RollBack();
628 return RDB_EXECUTE_FAIL;
629 }
630 DeletedAsyncTask(store_, queryValuesBucket);
631 return deleteRet;
632 }
633
DeletedAsyncTask(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<OHOS::NativeRdb::ValuesBucket> & queryValuesBucket)634 void ContactsDataBase::DeletedAsyncTask(
635 std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<OHOS::NativeRdb::ValuesBucket> &queryValuesBucket)
636 {
637 std::unique_ptr<AsyncItem> task = std::make_unique<AsyncDeleteContactsTask>(store_, queryValuesBucket);
638 g_asyncTaskQueue->Push(task);
639 g_asyncTaskQueue->Start();
640 }
641
DeleteExecute(std::vector<OHOS::NativeRdb::ValuesBucket> & queryValuesBucket)642 int ContactsDataBase::DeleteExecute(std::vector<OHOS::NativeRdb::ValuesBucket> &queryValuesBucket)
643 {
644 unsigned int size = queryValuesBucket.size();
645 if (size == 0) {
646 return RDB_EXECUTE_FAIL;
647 }
648 int ret = RDB_EXECUTE_FAIL;
649 for (unsigned int i = 0; i < size; i++) {
650 OHOS::NativeRdb::ValuesBucket valuesElement = queryValuesBucket[i];
651 bool hasId = valuesElement.HasColumn(ContactColumns::ID);
652 if (!hasId) {
653 continue;
654 }
655 OHOS::NativeRdb::ValueObject idValue;
656 valuesElement.GetObject(ContactPublicColumns::ID, idValue);
657 int rawContactId = 0;
658 idValue.GetInt(rawContactId);
659 OHOS::NativeRdb::ValuesBucket values;
660 values.PutInt(RawContactColumns::IS_DELETED, DELETE_MARK);
661 int updateRow = OHOS::NativeRdb::E_OK;
662 std::string upWhere = "";
663 upWhere.append(ContactPublicColumns::ID);
664 upWhere.append(" = ? ");
665 std::vector<std::string> upWhereArgs;
666 upWhereArgs.push_back(std::to_string(rawContactId));
667 ret = store_->Update(updateRow, ContactTableName::RAW_CONTACT, values, upWhere, upWhereArgs);
668 if (ret != OHOS::NativeRdb::E_OK) {
669 HILOG_ERROR("deleteRawContact upResultDelete failed:%{public}d", ret);
670 return RDB_EXECUTE_FAIL;
671 }
672 }
673 return ret;
674 }
675
DeleteRecordInsert(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<OHOS::NativeRdb::ValuesBucket> & queryValuesBucket)676 void ContactsDataBase::DeleteRecordInsert(
677 std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<OHOS::NativeRdb::ValuesBucket> &queryValuesBucket)
678 {
679 g_mtx.lock();
680 unsigned int size = queryValuesBucket.size();
681 for (unsigned int i = 0; i < size; i++) {
682 OHOS::NativeRdb::ValuesBucket valuesElement = queryValuesBucket[i];
683 bool hasId = valuesElement.HasColumn(ContactColumns::ID);
684 if (!hasId) {
685 continue;
686 }
687 OHOS::NativeRdb::ValueObject idValue;
688 valuesElement.GetObject(ContactPublicColumns::ID, idValue);
689 int rawContactId = 0;
690 idValue.GetInt(rawContactId);
691 OHOS::NativeRdb::ValueObject contactIdValue;
692 valuesElement.GetObject(RawContactColumns::CONTACT_ID, contactIdValue);
693 int contactId = 0;
694 contactIdValue.GetInt(contactId);
695 OHOS::NativeRdb::ValueObject nameValue;
696 valuesElement.GetObject(RawContactColumns::DISPLAY_NAME, nameValue);
697 std::string disPlayName;
698 nameValue.GetString(disPlayName);
699 std::string backupData =
700 StructureDeleteContactJson(queryValuesBucket[i], ContactPublicColumns::ID, rawContactId);
701 if (backupData.empty()) {
702 HILOG_ERROR("deleteRawContact json :%{public}s", backupData.c_str());
703 }
704 int deleteRet = DeleteRawContactLocal(contactId, rawContactId, backupData, disPlayName);
705 if (deleteRet != OHOS::NativeRdb::E_OK) {
706 HILOG_ERROR("deleteRawContact upResultDelete failed:%{public}d", deleteRet);
707 }
708 std::vector<int> rawContactIdVector;
709 rawContactIdVector.push_back(rawContactId);
710 ContactsUpdateHelper contactsUpdateHelper;
711 contactsUpdateHelper.UpdateCallLogByPhoneNum(rawContactIdVector, store, true);
712 }
713 g_mtx.unlock();
714 }
715
716 /**
717 * @brief Delete data from the raw_contact table
718 *
719 * @param rdbPredicates Conditions for delete operation
720 *
721 * @return The result returned by the delete operation
722 */
DeleteRawContact(OHOS::NativeRdb::RdbPredicates & rdbPredicates)723 int ContactsDataBase::DeleteRawContact(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
724 {
725 if (store_ == nullptr) {
726 HILOG_ERROR("ContactsDataBase DeleteRawContact store_ is nullptr");
727 return RDB_OBJECT_EMPTY;
728 }
729 int ret = BeginTransaction();
730 if (ret != OHOS::NativeRdb::E_OK) {
731 return RDB_EXECUTE_FAIL;
732 }
733 std::vector<OHOS::NativeRdb::ValuesBucket> queryValuesBucket = DeleteRawContactQuery(rdbPredicates);
734 int deleteRet = DeleteExecute(queryValuesBucket);
735 if (deleteRet != OHOS::NativeRdb::E_OK) {
736 RollBack();
737 return RDB_EXECUTE_FAIL;
738 }
739 deleteRet = Commit();
740 if (deleteRet != OHOS::NativeRdb::E_OK) {
741 RollBack();
742 return RDB_EXECUTE_FAIL;
743 }
744 DeletedAsyncTask(store_, queryValuesBucket);
745 return deleteRet;
746 }
747
DeleteContactQuery(OHOS::NativeRdb::RdbPredicates & rdbPredicates)748 std::vector<OHOS::NativeRdb::ValuesBucket> ContactsDataBase::DeleteContactQuery(
749 OHOS::NativeRdb::RdbPredicates &rdbPredicates)
750 {
751 PredicatesConvert predicatesConvert;
752 OHOS::NativeRdb::RdbPredicates newRdbPredicates =
753 predicatesConvert.CopyPredicates(ViewName::VIEW_CONTACT, rdbPredicates);
754 std::vector<std::string> columns;
755 columns.push_back(ContactPublicColumns::ID);
756 columns.push_back(RawContactColumns::DISPLAY_NAME);
757 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = store_->Query(newRdbPredicates, columns);
758 int resultSetNum = resultSet->GoToFirstRow();
759 if (resultSetNum != OHOS::NativeRdb::E_OK) {
760 // query size 0
761 std::vector<OHOS::NativeRdb::ValuesBucket> vectorQueryData;
762 resultSet->GoToNextRow();
763 resultSet->Close();
764 return vectorQueryData;
765 }
766 std::vector<std::string> whereArgs;
767 while (resultSetNum == OHOS::NativeRdb::E_OK) {
768 int contactId;
769 resultSet->GetInt(0, contactId);
770 whereArgs.push_back(std::to_string(contactId));
771 resultSetNum = resultSet->GoToNextRow();
772 }
773 resultSet->Close();
774 unsigned int size = whereArgs.size();
775 OHOS::NativeRdb::RdbPredicates rawContactQueryRdbPredicates(ViewName::VIEW_RAW_CONTACT);
776 std::string whereClause;
777 for (unsigned int i = 0; i < size; i++) {
778 whereClause.append(" contact_id = ? ");
779 if (i != size - 1) {
780 whereClause.append(" OR ");
781 }
782 }
783 OHOS::NativeRdb::PredicatesUtils::SetWhereClauseAndArgs(&rawContactQueryRdbPredicates, whereClause, whereArgs);
784 OHOS::NativeRdb::PredicatesUtils::SetAttributes(&rawContactQueryRdbPredicates,
785 rawContactQueryRdbPredicates.IsDistinct(), rawContactQueryRdbPredicates.GetIndex(),
786 rawContactQueryRdbPredicates.GetGroup(), rawContactQueryRdbPredicates.GetOrder(),
787 rawContactQueryRdbPredicates.GetLimit(), rawContactQueryRdbPredicates.GetOffset());
788 return DeleteRawContactQuery(rawContactQueryRdbPredicates);
789 }
790
DeleteRawContactQuery(OHOS::NativeRdb::RdbPredicates & rdbPredicates)791 std::vector<OHOS::NativeRdb::ValuesBucket> ContactsDataBase::DeleteRawContactQuery(
792 OHOS::NativeRdb::RdbPredicates &rdbPredicates)
793 {
794 std::vector<std::string> columns;
795 columns.push_back(RawContactColumns::DISPLAY_NAME);
796 columns.push_back(ContactColumns::ID);
797 columns.push_back(RawContactColumns::CONTACT_ID);
798 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = store_->Query(rdbPredicates, columns);
799 return ResultSetToValuesBucket(resultSet);
800 }
801
DeleteRawContactLocal(int contactId,int rawContactId,std::string backupData,std::string disPlayName)802 int ContactsDataBase::DeleteRawContactLocal(
803 int contactId, int rawContactId, std::string backupData, std::string disPlayName)
804 {
805 OHOS::NativeRdb::ValuesBucket deleteRawContact;
806 deleteRawContact.PutInt(DeleteRawContactColumns::RAW_CONTACT_ID, rawContactId);
807 deleteRawContact.PutString(DeleteRawContactColumns::BACKUP_DATA, backupData);
808 deleteRawContact.PutString(DeleteRawContactColumns::DISPLAY_NAME, disPlayName);
809 deleteRawContact.PutInt(DeleteRawContactColumns::CONTACT_ID, contactId);
810 int64_t outRowId = OHOS::NativeRdb::E_OK;
811 int ret = store_->Insert(outRowId, ContactTableName::DELETE_RAW_CONTACT, deleteRawContact);
812 if (ret != OHOS::NativeRdb::E_OK) {
813 HILOG_ERROR("deleteRawContact deleteInsert failed:%{public}d", ret);
814 return RDB_EXECUTE_FAIL;
815 }
816 return ret;
817 }
818
819 /**
820 * @brief Completely delete data from the database
821 *
822 * @param rdbPredicates Conditions for delete operation
823 *
824 * @return The result returned by the delete operation
825 */
CompletelyDelete(OHOS::NativeRdb::RdbPredicates & rdbPredicates)826 int ContactsDataBase::CompletelyDelete(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
827 {
828 int ret = BeginTransaction();
829 if (ret != OHOS::NativeRdb::E_OK) {
830 return RDB_EXECUTE_FAIL;
831 }
832 std::vector<std::string> columns;
833 columns.push_back(DeleteRawContactColumns::CONTACT_ID);
834 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = store_->Query(rdbPredicates, columns);
835 std::vector<std::string> contactIds;
836 int resultSetNum = resultSet->GoToFirstRow();
837 while (resultSetNum == OHOS::NativeRdb::E_OK) {
838 int contactId;
839 resultSet->GetInt(0, contactId);
840 contactIds.push_back(std::to_string(contactId));
841 resultSetNum = resultSet->GoToNextRow();
842 }
843 resultSet->Close();
844 int retCode = RDB_EXECUTE_FAIL;
845 unsigned int size = contactIds.size();
846 for (unsigned int index = 0; index < size; index++) {
847 std::string queryViewContact =
848 "SELECT id FROM view_raw_contact WHERE is_deleted = 1 AND contact_id = " + contactIds[index];
849 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> contactIdSet = store_->QuerySql(queryViewContact);
850 resultSetNum = contactIdSet->GoToFirstRow();
851 while (resultSetNum == OHOS::NativeRdb::E_OK) {
852 int value = -1;
853 contactIdSet->GetInt(0, value);
854 retCode = DeleteLocal(value, contactIds[index]);
855 if (retCode != OHOS::NativeRdb::E_OK) {
856 HILOG_ERROR("CompletelyDelete DeleteLocal error:%{public}d", retCode);
857 break;
858 }
859 resultSetNum = contactIdSet->GoToNextRow();
860 }
861 contactIdSet->Close();
862 if (retCode != OHOS::NativeRdb::E_OK) {
863 HILOG_ERROR("CompletelyDelete error:%{public}d", retCode);
864 RollBack();
865 return retCode;
866 }
867 }
868 return CompletelyDeleteCommit(retCode);
869 }
870
CompletelyDeleteCommit(int retCode)871 int ContactsDataBase::CompletelyDeleteCommit(int retCode)
872 {
873 if (retCode != OHOS::NativeRdb::E_OK) {
874 HILOG_ERROR("CompletelyDelete end error:%{public}d", retCode);
875 RollBack();
876 return retCode;
877 }
878 int markRet = Commit();
879 if (markRet != OHOS::NativeRdb::E_OK) {
880 HILOG_ERROR("CompletelyDelete end error:%{public}d", markRet);
881 return RDB_EXECUTE_FAIL;
882 }
883 return retCode;
884 }
885
DeleteLocal(int rawContactId,std::string contactId)886 int ContactsDataBase::DeleteLocal(int rawContactId, std::string contactId)
887 {
888 if (store_ == nullptr) {
889 HILOG_ERROR("ContactsDataBase DeleteLocal store is nullptr");
890 return RDB_OBJECT_EMPTY;
891 }
892 std::string updateContactSql = "UPDATE contact SET name_raw_contact_id = NULL WHERE id = " + contactId;
893 int retCode = store_->ExecuteSql(updateContactSql);
894 if (retCode != OHOS::NativeRdb::E_OK) {
895 HILOG_ERROR("DeleteLocal updateContactSql code:%{public}d", retCode);
896 return retCode;
897 }
898 std::string updateRawContactSql = "UPDATE raw_contact SET contact_id = NULL WHERE contact_id = " + contactId;
899 retCode = store_->ExecuteSql(updateRawContactSql);
900 if (retCode != OHOS::NativeRdb::E_OK) {
901 HILOG_ERROR("DeleteLocal updateRawContactSql code:%{public}d", retCode);
902 return retCode;
903 }
904 std::string deleteDeleteRawContactSql = "DELETE FROM deleted_raw_contact WHERE contact_id = " + contactId;
905 retCode = store_->ExecuteSql(deleteDeleteRawContactSql);
906 if (retCode != OHOS::NativeRdb::E_OK) {
907 HILOG_ERROR("DeleteLocal deleted_raw_contact code:%{public}d", retCode);
908 return retCode;
909 }
910 std::string deleteSearchContactSql = "DELETE FROM search_contact WHERE contact_id = " + contactId;
911 retCode = store_->ExecuteSql(deleteSearchContactSql);
912 if (retCode != OHOS::NativeRdb::E_OK) {
913 HILOG_ERROR("DeleteLocal deleteSearchContactSql code:%{public}d", retCode);
914 return retCode;
915 }
916 std::string deleteContactData = "DELETE FROM contact_data WHERE raw_contact_id = " + std::to_string(rawContactId);
917 retCode = store_->ExecuteSql(deleteContactData);
918 if (retCode != OHOS::NativeRdb::E_OK) {
919 HILOG_ERROR("DeleteLocal deleteContactData code:%{public}d", retCode);
920 return retCode;
921 }
922 std::string deleteContactSql = "DELETE FROM contact WHERE id = " + contactId;
923 retCode = store_->ExecuteSql(deleteContactSql);
924 if (retCode != OHOS::NativeRdb::E_OK) {
925 HILOG_ERROR("DeleteLocal deleteContactSql code:%{public}d", retCode);
926 return retCode;
927 }
928 std::string deleteRawContactSql = "DELETE FROM raw_contact WHERE id = " + std::to_string(rawContactId);
929 retCode = store_->ExecuteSql(deleteRawContactSql);
930 if (retCode != OHOS::NativeRdb::E_OK) {
931 HILOG_ERROR("DeleteLocal deleteRawContactSql code:%{public}d", retCode);
932 return retCode;
933 }
934 return retCode;
935 }
936
QueryContactDataRawContactId(OHOS::NativeRdb::RdbPredicates & rdbPredicates,std::vector<std::string> & types)937 std::vector<int> ContactsDataBase::QueryContactDataRawContactId(
938 OHOS::NativeRdb::RdbPredicates &rdbPredicates, std::vector<std::string> &types)
939 {
940 std::vector<std::string> columns;
941 columns.push_back(ContactDataColumns::TYPE_ID);
942 columns.push_back(ContactDataColumns::RAW_CONTACT_ID);
943 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = store_->Query(rdbPredicates, columns);
944 std::vector<int> rawContactIdVector;
945 std::vector<int> typeIdVector;
946 int resultSetNum = resultSet->GoToFirstRow();
947 while (resultSetNum == OHOS::NativeRdb::E_OK) {
948 std::string columnName = ContactDataColumns::RAW_CONTACT_ID;
949 int columnIndex = 0;
950 resultSet->GetColumnIndex(columnName, columnIndex);
951 int rawContactId = 0;
952 resultSet->GetInt(columnIndex, rawContactId);
953 std::string typeIdKey = ContactDataColumns::TYPE_ID;
954 int columnIndexType = 0;
955 resultSet->GetColumnIndex(typeIdKey, columnIndexType);
956 int typeId = 0;
957 resultSet->GetInt(columnIndexType, typeId);
958 OHOS::NativeRdb::ValueObject typeTextObject;
959 typeIdVector.push_back(typeId);
960 rawContactIdVector.push_back(rawContactId);
961 resultSetNum = resultSet->GoToNextRow();
962 }
963 resultSet->Close();
964 unsigned int typeIdSize = typeIdVector.size();
965 ContactsType contactsType;
966 for (unsigned int i = 0; i < typeIdSize; i++) {
967 std::string typeText = contactsType.GetTypeText(store_, typeIdVector[i]);
968 types.push_back(typeText);
969 }
970 return rawContactIdVector;
971 }
972
973 /**
974 * @brief Query data according to given conditions
975 *
976 * @param rdbPredicates Conditions for query operation
977 * @param columns Conditions for query operation
978 *
979 * @return The result returned by the query operation
980 */
Query(OHOS::NativeRdb::RdbPredicates & rdbPredicates,std::vector<std::string> & columns)981 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> ContactsDataBase::Query(
982 OHOS::NativeRdb::RdbPredicates &rdbPredicates, std::vector<std::string> &columns)
983 {
984 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet;
985 if (store_ == nullptr) {
986 HILOG_ERROR("ContactsDataBase Query store_ is nullptr");
987 return resultSet;
988 }
989 int errCode = OHOS::NativeRdb::E_OK;
990 resultSet = store_->Query(rdbPredicates, columns);
991 if (errCode != OHOS::NativeRdb::E_OK) {
992 HILOG_INFO("Query error code is:%{public}d", errCode);
993 }
994 return resultSet;
995 }
996
ResultSetToValuesBucket(std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> & resultSet)997 std::vector<OHOS::NativeRdb::ValuesBucket> ContactsDataBase::ResultSetToValuesBucket(
998 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> &resultSet)
999 {
1000 std::vector<std::string> columnNames;
1001 resultSet->GetAllColumnNames(columnNames);
1002 std::vector<OHOS::NativeRdb::ValuesBucket> vectorQueryData;
1003 int resultSetNum = resultSet->GoToFirstRow();
1004 while (resultSetNum == OHOS::NativeRdb::E_OK) {
1005 OHOS::NativeRdb::ValuesBucket valuesBucketElement;
1006 unsigned int size = columnNames.size();
1007 for (unsigned int i = 0; i < size; i++) {
1008 std::string typeValue = columnNames[i];
1009 int columnIndex = 0;
1010 resultSet->GetColumnIndex(typeValue, columnIndex);
1011 OHOS::NativeRdb::ColumnType columnType;
1012 resultSet->GetColumnType(columnIndex, columnType);
1013 if (columnType == OHOS::NativeRdb::ColumnType::TYPE_INTEGER) {
1014 int intValue = 0;
1015 resultSet->GetInt(columnIndex, intValue);
1016 valuesBucketElement.PutInt(typeValue, intValue);
1017 } else if (columnType == OHOS::NativeRdb::ColumnType::TYPE_FLOAT) {
1018 double doubleValue = 0;
1019 resultSet->GetDouble(columnIndex, doubleValue);
1020 valuesBucketElement.PutDouble(typeValue, doubleValue);
1021 } else if (columnType == OHOS::NativeRdb::ColumnType::TYPE_STRING) {
1022 std::string stringValue;
1023 resultSet->GetString(columnIndex, stringValue);
1024 valuesBucketElement.PutString(typeValue, stringValue);
1025 }
1026 }
1027 vectorQueryData.push_back(valuesBucketElement);
1028 resultSetNum = resultSet->GoToNextRow();
1029 }
1030 resultSet->Close();
1031 return vectorQueryData;
1032 }
1033
StructureDeleteContactJson(OHOS::NativeRdb::ValuesBucket rawContactValues,std::string rawContactIdColumn,int rawContactId)1034 std::string ContactsDataBase::StructureDeleteContactJson(
1035 OHOS::NativeRdb::ValuesBucket rawContactValues, std::string rawContactIdColumn, int rawContactId)
1036 {
1037 ContactsJsonUtils contactsJsonUtils;
1038 std::vector<std::string> selectionArgs;
1039 selectionArgs.push_back(std::to_string(rawContactId));
1040 std::string queryTabName = ViewName::VIEW_CONTACT_DATA;
1041 std::vector<std::string> contentColumns;
1042 contentColumns.push_back(ContentTypeColumns::CONTENT_TYPE);
1043 contentColumns.push_back(ContactDataColumns::DETAIL_INFO);
1044 contentColumns.push_back(ContactDataColumns::POSITION);
1045 contentColumns.push_back(ContactDataColumns::EXTEND1);
1046 contentColumns.push_back(ContactDataColumns::EXTEND2);
1047 contentColumns.push_back(ContactDataColumns::EXTEND3);
1048 contentColumns.push_back(ContactDataColumns::EXTEND4);
1049 contentColumns.push_back(ContactDataColumns::ALPHA_NAME);
1050 contentColumns.push_back(ContactDataColumns::OTHER_LAN_LAST_NAME);
1051 contentColumns.push_back(ContactDataColumns::OTHER_LAN_FIRST_NAME);
1052 contentColumns.push_back(ContactDataColumns::EXTEND5);
1053 contentColumns.push_back(ContactDataColumns::LAN_STYLE);
1054 contentColumns.push_back(ContactDataColumns::CUSTOM_DATA);
1055 contentColumns.push_back(ContactDataColumns::EXTEND6);
1056 contentColumns.push_back(ContactDataColumns::EXTEND7);
1057 contentColumns.push_back(ContactDataColumns::BLOB_DATA);
1058 std::string queryWhereClause = DeleteRawContactColumns::RAW_CONTACT_ID;
1059 queryWhereClause.append(" = ? ");
1060 std::string sql = "SELECT ";
1061 unsigned int size = contentColumns.size();
1062 for (unsigned int i = 0; i < size; i++) {
1063 sql.append(contentColumns[i]);
1064 if (i != size - 1) {
1065 sql.append(", ");
1066 }
1067 }
1068 sql.append(" FROM ").append(queryTabName).append(" WHERE ").append(queryWhereClause);
1069 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> contactDataResultSet = store_->QuerySql(sql, selectionArgs);
1070 std::string backupData = contactsJsonUtils.GetDeleteData(contactDataResultSet);
1071 contactDataResultSet->Close();
1072 return backupData;
1073 }
1074
OnCreate(OHOS::NativeRdb::RdbStore & store)1075 int SqliteOpenHelperContactCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
1076 {
1077 store.ExecuteSql(CREATE_CONTACT);
1078 store.ExecuteSql(CREATE_CONTACT_INDEX);
1079 store.ExecuteSql(CREATE_RAW_CONTACT);
1080 store.ExecuteSql(CREATE_RAW_CONTACT_INDEX);
1081 store.ExecuteSql(CREATE_CONTACT_DATA);
1082 store.ExecuteSql(CREATE_CONTACT_INDEX_DATA1);
1083 store.ExecuteSql(CREATE_CONTACT_INDEX_DATA2);
1084 store.ExecuteSql(CREATE_CONTACT_BLOCKLIST);
1085 store.ExecuteSql(CREATE_LOCAL_LANG);
1086 store.ExecuteSql(CREATE_ACCOUNT);
1087 store.ExecuteSql(CREATE_PHOTO_FILES);
1088 store.ExecuteSql(CREATE_CONTACT_TYPE);
1089 store.ExecuteSql(CREATE_GROUPS);
1090 store.ExecuteSql(CREATE_DELETED_RAW_CONTACT);
1091 store.ExecuteSql(CREATE_SEARCH_CONTACT);
1092 store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX1);
1093 store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX2);
1094 store.ExecuteSql(CREATE_SEARCH_CONTACT_VIEW);
1095 store.ExecuteSql(MERGE_INFO);
1096 store.ExecuteSql(CREATE_VIEW_CONTACT_DATA);
1097 store.ExecuteSql(CREATE_VIEW_RAW_CONTACT);
1098 store.ExecuteSql(CREATE_VIEW_CONTACT);
1099 store.ExecuteSql(CREATE_VIEW_GROUPS);
1100 store.ExecuteSql(CREATE_VIEW_DELETED);
1101 store.ExecuteSql(INSERT_DELETE_RAW_CONTACT);
1102 store.ExecuteSql(UPDATE_RAW_CONTACT_VERSION);
1103 store.ExecuteSql(UPDATE_CONTACT_DATA_VERSION);
1104 store.ExecuteSql(INSERT_CONTACT_QUICK_SEARCH);
1105 store.ExecuteSql(CREATE_DATABASE_BACKUP_TASK);
1106 store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
1107 store.ExecuteSql(UPDATE_CONTACT_BY_INSERT_CONTACT_DATA);
1108 store.ExecuteSql(UPDATE_CONTACT_BY_DELETE_CONTACT_DATA);
1109 store.ExecuteSql(UPDATE_CONTACT_BY_UPDATE_CONTACT_DATA);
1110 store.ExecuteSql(MERGE_INFO_INDEX);
1111 return OHOS::NativeRdb::E_OK;
1112 }
1113
OnUpgrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1114 int SqliteOpenHelperContactCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1115 {
1116 HILOG_INFO("OnUpgrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
1117 if (oldVersion < newVersion && newVersion == DATABASE_NEW_VERSION) {
1118 store.ExecuteSql("ALTER TABLE database_backup_task ADD COLUMN sync TEXT");
1119 }
1120 store.SetVersion(newVersion);
1121 return OHOS::NativeRdb::E_OK;
1122 }
1123
OnDowngrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1124 int SqliteOpenHelperContactCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1125 {
1126 HILOG_INFO("OnDowngrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
1127 if (oldVersion > newVersion && newVersion == DATABASE_OPEN_VERSION) {
1128 store.ExecuteSql(
1129 "CREATE TABLE IF NOT EXISTS database_backup (id INTEGER PRIMARY KEY AUTOINCREMENT, backup_time "
1130 "TEXT, backup_path TEXT, remarks TEXT)");
1131 store.ExecuteSql(
1132 "INSERT INTO database_backup(id, backup_time, backup_path, remarks) SELECT id, "
1133 "backup_time, backup_path, remarks FROM database_backup_task");
1134 store.ExecuteSql("DROP table database_backup_task");
1135 store.ExecuteSql("ALTER table database_backup RENAME TO database_backup_task");
1136 store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
1137 }
1138 int ret = store.SetVersion(newVersion);
1139 return ret;
1140 }
1141
DestroyInstanceAndRestore(std::string restorePath)1142 void ContactsDataBase::DestroyInstanceAndRestore(std::string restorePath)
1143 {
1144 g_mtx.lock();
1145 if (access(restorePath.c_str(), F_OK) != 0) {
1146 HILOG_ERROR("Restore file %{private}s does not exist", restorePath.c_str());
1147 g_mtx.unlock();
1148 return;
1149 }
1150 OHOS::NativeRdb::RdbHelper::DeleteRdbStore(g_databaseName);
1151 OHOS::NativeRdb::RdbHelper::ClearCache();
1152 contactDataBase_ = nullptr;
1153 Restore(restorePath);
1154 g_mtx.unlock();
1155 }
1156
Restore(std::string restorePath)1157 bool ContactsDataBase::Restore(std::string restorePath)
1158 {
1159 HILOG_INFO("ContactsDataBase Restore start ");
1160 if (rename(restorePath.c_str(), g_databaseName.c_str()) == 0) {
1161 HILOG_INFO("ContactsDataBase Restore rename ok ");
1162 return true;
1163 }
1164 return false;
1165 }
1166
1167 /**
1168 * @brief Select candidates
1169 *
1170 * @return The result returned by the selectCandidate operation
1171 */
SelectCandidate()1172 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> ContactsDataBase::SelectCandidate()
1173 {
1174 MarkMerge(store_);
1175 MergerContacts mergerContacts;
1176 return mergerContacts.SelectCandidate(store_);
1177 }
1178
1179 /**
1180 * @brief Perform a split operation
1181 *
1182 * @param predicates Conditions for split operation
1183 *
1184 * @return The result returned by the split operation
1185 */
Split(DataShare::DataSharePredicates predicates)1186 int ContactsDataBase::Split(DataShare::DataSharePredicates predicates)
1187 {
1188 std::vector<std::string> whereArgs = predicates.GetWhereArgs();
1189 if (whereArgs.size() > 1) {
1190 HILOG_ERROR("Invalid parameter passed");
1191 return RDB_EXECUTE_FAIL;
1192 }
1193 MatchCandidate matchCandidate;
1194 int code = RDB_EXECUTE_FAIL;
1195 for (auto value : whereArgs) {
1196 code = matchCandidate.Split(store_, atoi(value.c_str()));
1197 }
1198 if (code != RDB_EXECUTE_OK) {
1199 HILOG_INFO("Split code %{public}d", code);
1200 }
1201 return code;
1202 }
1203
1204 /**
1205 * @brief Perform an autoMerge operation
1206 *
1207 * @return The result returned by the autoMerge operation
1208 */
ContactMerge()1209 int ContactsDataBase::ContactMerge()
1210 {
1211 MarkMerge(store_);
1212 int code = RDB_EXECUTE_FAIL;
1213 MergerContacts mergerContacts;
1214 if (store_ != nullptr) {
1215 code = mergerContacts.ContactMerge(store_);
1216 if (code != RDB_EXECUTE_OK) {
1217 HILOG_ERROR("ContactMerge ERROR!");
1218 }
1219 }
1220 return code;
1221 }
1222
1223 /**
1224 * @brief Perform a manualMerge operation
1225 *
1226 * @param predicates Conditions for manualMerge operation
1227 *
1228 * @return The result returned by the manualMerge operation
1229 */
ReContactMerge(DataShare::DataSharePredicates predicates)1230 int ContactsDataBase::ReContactMerge(DataShare::DataSharePredicates predicates)
1231 {
1232 MarkMerge(store_);
1233 int code = RDB_EXECUTE_FAIL;
1234 MergerContacts mergerContacts;
1235 if (store_ != nullptr) {
1236 code = mergerContacts.ReContactMerge(store_, predicates);
1237 if (code != RDB_EXECUTE_OK) {
1238 HILOG_ERROR("ReContactMerge ERROR!");
1239 }
1240 }
1241 return code;
1242 }
1243
InsertMergeData(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<int> & rawContactIdVector)1244 void ContactsDataBase::InsertMergeData(
1245 std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<int> &rawContactIdVector)
1246 {
1247 unsigned int size = rawContactIdVector.size();
1248 for (unsigned int i = 0; i < size; i++) {
1249 OHOS::NativeRdb::ValuesBucket mergeInfoValues;
1250 mergeInfoValues.PutInt(MergeInfo::RAW_CONTACT_ID, rawContactIdVector[i]);
1251 int64_t mergeInfoRowId = 0;
1252 int mergeInfoRet = store->Insert(mergeInfoRowId, ContactTableName::MERGE_INFO, mergeInfoValues);
1253 if (mergeInfoRet != RDB_EXECUTE_OK) {
1254 HILOG_ERROR("mergeInfo insert error : %{public}d ", mergeInfoRet);
1255 }
1256 }
1257 }
1258
MergeUpdateTask(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<int> & rawContactIdVector,bool isDeleted)1259 void ContactsDataBase::MergeUpdateTask(
1260 std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<int> &rawContactIdVector, bool isDeleted)
1261 {
1262 std::unique_ptr<AsyncItem> task = std::make_unique<AsyncTask>(store_, rawContactIdVector, isDeleted);
1263 g_asyncTaskQueue->Push(task);
1264 g_asyncTaskQueue->Start();
1265 }
1266
MarkMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store)1267 void ContactsDataBase::MarkMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> &store)
1268 {
1269 std::string sql = "SELECT ";
1270 sql.append(MergeInfo::RAW_CONTACT_ID)
1271 .append(" FROM ")
1272 .append(ContactTableName::MERGE_INFO)
1273 .append(" GROUP BY ")
1274 .append(MergeInfo::RAW_CONTACT_ID);
1275 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = store->QuerySql(sql);
1276 int mergeResultSetNum = resultSet->GoToFirstRow();
1277 MatchCandidate matchCandidate;
1278 while (mergeResultSetNum == OHOS::NativeRdb::E_OK) {
1279 std::string columnName = MergeInfo::RAW_CONTACT_ID;
1280 int columnIndex = 0;
1281 int rawContactId = 0;
1282 resultSet->GetColumnIndex(columnName, columnIndex);
1283 resultSet->GetInt(columnIndex, rawContactId);
1284 int error = matchCandidate.FindMatchContact(store, rawContactId);
1285 if (error != RDB_EXECUTE_OK) {
1286 HILOG_ERROR("Find error is : %{public}d ", error);
1287 }
1288 std::string deleteMergeInfo = "DELETE FROM ";
1289 deleteMergeInfo.append(ContactTableName::MERGE_INFO)
1290 .append(" WHERE ")
1291 .append(MergeInfo::RAW_CONTACT_ID)
1292 .append(" = ")
1293 .append(std::to_string(rawContactId));
1294 int ret = store->ExecuteSql(deleteMergeInfo);
1295 if (ret != OHOS::NativeRdb::E_OK) {
1296 HILOG_ERROR("deleteMergeInfo error");
1297 }
1298 mergeResultSetNum = resultSet->GoToNextRow();
1299 }
1300 resultSet->Close();
1301 }
1302
GetTypeId(std::string typeText)1303 int ContactsDataBase::GetTypeId(std::string typeText)
1304 {
1305 ContactsType contactsType;
1306 int typeId = contactsType.LookupTypeId(store_, typeText);
1307 HILOG_INFO("ContactsDataBase GetTypeId %{public}d", typeId);
1308 return typeId;
1309 }
1310 } // namespace Contacts
1311 } // namespace OHOS