• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     auto 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     auto 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::shared_ptr<OHOS::NativeRdb::ResultSet> 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     auto 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         auto 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     auto 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::shared_ptr<OHOS::NativeRdb::ResultSet> ContactsDataBase::Query(
982     OHOS::NativeRdb::RdbPredicates &rdbPredicates, std::vector<std::string> &columns)
983 {
984     if (store_ == nullptr) {
985         HILOG_ERROR("ContactsDataBase Query store_ is nullptr");
986         return nullptr;
987     }
988     int errCode = OHOS::NativeRdb::E_OK;
989     auto resultSet = store_->Query(rdbPredicates, columns);
990     if (errCode != OHOS::NativeRdb::E_OK) {
991         HILOG_INFO("Query error code is:%{public}d", errCode);
992     }
993     return resultSet;
994 }
995 
ResultSetToValuesBucket(std::shared_ptr<OHOS::NativeRdb::ResultSet> & resultSet)996 std::vector<OHOS::NativeRdb::ValuesBucket> ContactsDataBase::ResultSetToValuesBucket(
997     std::shared_ptr<OHOS::NativeRdb::ResultSet> &resultSet)
998 {
999     std::vector<std::string> columnNames;
1000     resultSet->GetAllColumnNames(columnNames);
1001     std::vector<OHOS::NativeRdb::ValuesBucket> vectorQueryData;
1002     int resultSetNum = resultSet->GoToFirstRow();
1003     while (resultSetNum == OHOS::NativeRdb::E_OK) {
1004         OHOS::NativeRdb::ValuesBucket valuesBucketElement;
1005         unsigned int size = columnNames.size();
1006         for (unsigned int i = 0; i < size; i++) {
1007             std::string typeValue = columnNames[i];
1008             int columnIndex = 0;
1009             resultSet->GetColumnIndex(typeValue, columnIndex);
1010             OHOS::NativeRdb::ColumnType columnType;
1011             resultSet->GetColumnType(columnIndex, columnType);
1012             if (columnType == OHOS::NativeRdb::ColumnType::TYPE_INTEGER) {
1013                 int intValue = 0;
1014                 resultSet->GetInt(columnIndex, intValue);
1015                 valuesBucketElement.PutInt(typeValue, intValue);
1016             } else if (columnType == OHOS::NativeRdb::ColumnType::TYPE_FLOAT) {
1017                 double doubleValue = 0;
1018                 resultSet->GetDouble(columnIndex, doubleValue);
1019                 valuesBucketElement.PutDouble(typeValue, doubleValue);
1020             } else if (columnType == OHOS::NativeRdb::ColumnType::TYPE_STRING) {
1021                 std::string stringValue;
1022                 resultSet->GetString(columnIndex, stringValue);
1023                 valuesBucketElement.PutString(typeValue, stringValue);
1024             }
1025         }
1026         vectorQueryData.push_back(valuesBucketElement);
1027         resultSetNum = resultSet->GoToNextRow();
1028     }
1029     resultSet->Close();
1030     return vectorQueryData;
1031 }
1032 
StructureDeleteContactJson(OHOS::NativeRdb::ValuesBucket rawContactValues,std::string rawContactIdColumn,int rawContactId)1033 std::string ContactsDataBase::StructureDeleteContactJson(
1034     OHOS::NativeRdb::ValuesBucket rawContactValues, std::string rawContactIdColumn, int rawContactId)
1035 {
1036     ContactsJsonUtils contactsJsonUtils;
1037     std::vector<std::string> selectionArgs;
1038     selectionArgs.push_back(std::to_string(rawContactId));
1039     std::string queryTabName = ViewName::VIEW_CONTACT_DATA;
1040     std::vector<std::string> contentColumns;
1041     contentColumns.push_back(ContentTypeColumns::CONTENT_TYPE);
1042     contentColumns.push_back(ContactDataColumns::DETAIL_INFO);
1043     contentColumns.push_back(ContactDataColumns::POSITION);
1044     contentColumns.push_back(ContactDataColumns::EXTEND1);
1045     contentColumns.push_back(ContactDataColumns::EXTEND2);
1046     contentColumns.push_back(ContactDataColumns::EXTEND3);
1047     contentColumns.push_back(ContactDataColumns::EXTEND4);
1048     contentColumns.push_back(ContactDataColumns::ALPHA_NAME);
1049     contentColumns.push_back(ContactDataColumns::OTHER_LAN_LAST_NAME);
1050     contentColumns.push_back(ContactDataColumns::OTHER_LAN_FIRST_NAME);
1051     contentColumns.push_back(ContactDataColumns::EXTEND5);
1052     contentColumns.push_back(ContactDataColumns::LAN_STYLE);
1053     contentColumns.push_back(ContactDataColumns::CUSTOM_DATA);
1054     contentColumns.push_back(ContactDataColumns::EXTEND6);
1055     contentColumns.push_back(ContactDataColumns::EXTEND7);
1056     contentColumns.push_back(ContactDataColumns::BLOB_DATA);
1057     std::string queryWhereClause = DeleteRawContactColumns::RAW_CONTACT_ID;
1058     queryWhereClause.append(" = ? ");
1059     std::string sql = "SELECT ";
1060     unsigned int size = contentColumns.size();
1061     for (unsigned int i = 0; i < size; i++) {
1062         sql.append(contentColumns[i]);
1063         if (i != size - 1) {
1064             sql.append(", ");
1065         }
1066     }
1067     sql.append(" FROM ").append(queryTabName).append(" WHERE ").append(queryWhereClause);
1068     std::shared_ptr<OHOS::NativeRdb::ResultSet> contactDataResultSet = store_->QuerySql(sql, selectionArgs);
1069     std::string backupData = contactsJsonUtils.GetDeleteData(contactDataResultSet);
1070     contactDataResultSet->Close();
1071     return backupData;
1072 }
1073 
OnCreate(OHOS::NativeRdb::RdbStore & store)1074 int SqliteOpenHelperContactCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
1075 {
1076     store.ExecuteSql(CREATE_CONTACT);
1077     store.ExecuteSql(CREATE_CONTACT_INDEX);
1078     store.ExecuteSql(CREATE_RAW_CONTACT);
1079     store.ExecuteSql(CREATE_RAW_CONTACT_INDEX);
1080     store.ExecuteSql(CREATE_CONTACT_DATA);
1081     store.ExecuteSql(CREATE_CONTACT_INDEX_DATA1);
1082     store.ExecuteSql(CREATE_CONTACT_INDEX_DATA2);
1083     store.ExecuteSql(CREATE_CONTACT_BLOCKLIST);
1084     store.ExecuteSql(CREATE_LOCAL_LANG);
1085     store.ExecuteSql(CREATE_ACCOUNT);
1086     store.ExecuteSql(CREATE_PHOTO_FILES);
1087     store.ExecuteSql(CREATE_CONTACT_TYPE);
1088     store.ExecuteSql(CREATE_GROUPS);
1089     store.ExecuteSql(CREATE_DELETED_RAW_CONTACT);
1090     store.ExecuteSql(CREATE_SEARCH_CONTACT);
1091     store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX1);
1092     store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX2);
1093     store.ExecuteSql(CREATE_SEARCH_CONTACT_VIEW);
1094     store.ExecuteSql(MERGE_INFO);
1095     store.ExecuteSql(CREATE_VIEW_CONTACT_DATA);
1096     store.ExecuteSql(CREATE_VIEW_RAW_CONTACT);
1097     store.ExecuteSql(CREATE_VIEW_CONTACT);
1098     store.ExecuteSql(CREATE_VIEW_GROUPS);
1099     store.ExecuteSql(CREATE_VIEW_DELETED);
1100     store.ExecuteSql(INSERT_DELETE_RAW_CONTACT);
1101     store.ExecuteSql(UPDATE_RAW_CONTACT_VERSION);
1102     store.ExecuteSql(UPDATE_CONTACT_DATA_VERSION);
1103     store.ExecuteSql(INSERT_CONTACT_QUICK_SEARCH);
1104     store.ExecuteSql(CREATE_DATABASE_BACKUP_TASK);
1105     store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
1106     store.ExecuteSql(UPDATE_CONTACT_BY_INSERT_CONTACT_DATA);
1107     store.ExecuteSql(UPDATE_CONTACT_BY_DELETE_CONTACT_DATA);
1108     store.ExecuteSql(UPDATE_CONTACT_BY_UPDATE_CONTACT_DATA);
1109     store.ExecuteSql(MERGE_INFO_INDEX);
1110     return OHOS::NativeRdb::E_OK;
1111 }
1112 
OnUpgrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1113 int SqliteOpenHelperContactCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1114 {
1115     HILOG_INFO("OnUpgrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
1116     if (oldVersion < newVersion && newVersion == DATABASE_NEW_VERSION) {
1117         store.ExecuteSql("ALTER TABLE database_backup_task ADD COLUMN sync TEXT");
1118     }
1119     if (oldVersion < newVersion && newVersion == DATABASE_VERSION_2) {
1120         UpgradeToV2(store, oldVersion, newVersion);
1121     }
1122     store.SetVersion(newVersion);
1123     return OHOS::NativeRdb::E_OK;
1124 }
1125 
UpgradeToV2(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1126 void SqliteOpenHelperContactCallback::UpgradeToV2(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1127 {
1128     if (oldVersion >= newVersion || newVersion != DATABASE_VERSION_2) {
1129         return;
1130     }
1131     // raw_contact
1132     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN primary_contact INTEGER DEFAULT 0;");
1133     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra1 TEXT;");
1134     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra2 TEXT;");
1135     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra3 TEXT;");
1136     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra4 TEXT;");
1137     // contact_data
1138     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend8 TEXT;");
1139     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend9 TEXT;");
1140     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend10 TEXT;");
1141     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend11 TEXT;");
1142     // drop view
1143     store.ExecuteSql("DROP VIEW view_contact;");
1144     store.ExecuteSql("DROP VIEW view_contact_data;");
1145     store.ExecuteSql("DROP VIEW search_contact_view;");
1146     store.ExecuteSql("DROP VIEW view_deleted;");
1147     // create view
1148     store.ExecuteSql(CREATE_VIEW_CONTACT);
1149     store.ExecuteSql(CREATE_VIEW_CONTACT_DATA);
1150     store.ExecuteSql(CREATE_SEARCH_CONTACT_VIEW);
1151     store.ExecuteSql(CREATE_VIEW_DELETED);
1152 }
1153 
OnDowngrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1154 int SqliteOpenHelperContactCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1155 {
1156     HILOG_INFO("OnDowngrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
1157     if (oldVersion > newVersion && newVersion == DATABASE_OPEN_VERSION) {
1158         store.ExecuteSql(
1159             "CREATE TABLE IF NOT EXISTS database_backup (id INTEGER PRIMARY KEY AUTOINCREMENT, backup_time "
1160             "TEXT, backup_path TEXT, remarks TEXT)");
1161         store.ExecuteSql(
1162             "INSERT INTO database_backup(id, backup_time, backup_path, remarks) SELECT id, "
1163             "backup_time, backup_path, remarks FROM database_backup_task");
1164         store.ExecuteSql("DROP table database_backup_task");
1165         store.ExecuteSql("ALTER table database_backup RENAME TO database_backup_task");
1166         store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
1167     }
1168     int ret = store.SetVersion(newVersion);
1169     return ret;
1170 }
1171 
DestroyInstanceAndRestore(std::string restorePath)1172 void ContactsDataBase::DestroyInstanceAndRestore(std::string restorePath)
1173 {
1174     g_mtx.lock();
1175     if (access(restorePath.c_str(), F_OK) != 0) {
1176         HILOG_ERROR("Restore file %{private}s does not exist", restorePath.c_str());
1177         g_mtx.unlock();
1178         return;
1179     }
1180     OHOS::NativeRdb::RdbHelper::DeleteRdbStore(g_databaseName);
1181     OHOS::NativeRdb::RdbHelper::ClearCache();
1182     contactDataBase_ = nullptr;
1183     Restore(restorePath);
1184     g_mtx.unlock();
1185 }
1186 
Restore(std::string restorePath)1187 bool ContactsDataBase::Restore(std::string restorePath)
1188 {
1189     HILOG_INFO("ContactsDataBase Restore start ");
1190     if (rename(restorePath.c_str(), g_databaseName.c_str()) == 0) {
1191         HILOG_INFO("ContactsDataBase Restore rename ok ");
1192         return true;
1193     }
1194     return false;
1195 }
1196 
1197 /**
1198  * @brief Select candidates
1199  *
1200  * @return The result returned by the selectCandidate operation
1201  */
SelectCandidate()1202 std::shared_ptr<OHOS::NativeRdb::ResultSet> ContactsDataBase::SelectCandidate()
1203 {
1204     MarkMerge(store_);
1205     MergerContacts mergerContacts;
1206     return mergerContacts.SelectCandidate(store_);
1207 }
1208 
1209 /**
1210  * @brief Perform a split operation
1211  *
1212  * @param predicates Conditions for split operation
1213  *
1214  * @return The result returned by the split operation
1215  */
Split(DataShare::DataSharePredicates predicates)1216 int ContactsDataBase::Split(DataShare::DataSharePredicates predicates)
1217 {
1218     std::vector<std::string> whereArgs = predicates.GetWhereArgs();
1219     if (whereArgs.size() > 1) {
1220         HILOG_ERROR("Invalid parameter passed");
1221         return RDB_EXECUTE_FAIL;
1222     }
1223     MatchCandidate matchCandidate;
1224     int code = RDB_EXECUTE_FAIL;
1225     for (auto value : whereArgs) {
1226         code = matchCandidate.Split(store_, atoi(value.c_str()));
1227     }
1228     if (code != RDB_EXECUTE_OK) {
1229         HILOG_INFO("Split code %{public}d", code);
1230     }
1231     return code;
1232 }
1233 
1234 /**
1235  * @brief Perform an autoMerge operation
1236  *
1237  * @return The result returned by the autoMerge operation
1238  */
ContactMerge()1239 int ContactsDataBase::ContactMerge()
1240 {
1241     MarkMerge(store_);
1242     int code = RDB_EXECUTE_FAIL;
1243     MergerContacts mergerContacts;
1244     if (store_ != nullptr) {
1245         code = mergerContacts.ContactMerge(store_);
1246         if (code != RDB_EXECUTE_OK) {
1247             HILOG_ERROR("ContactMerge ERROR!");
1248         }
1249     }
1250     return code;
1251 }
1252 
1253 /**
1254  * @brief Perform a manualMerge operation
1255  *
1256  * @param predicates Conditions for manualMerge operation
1257  *
1258  * @return The result returned by the manualMerge operation
1259  */
ReContactMerge(DataShare::DataSharePredicates predicates)1260 int ContactsDataBase::ReContactMerge(DataShare::DataSharePredicates predicates)
1261 {
1262     MarkMerge(store_);
1263     int code = RDB_EXECUTE_FAIL;
1264     MergerContacts mergerContacts;
1265     if (store_ != nullptr) {
1266         code = mergerContacts.ReContactMerge(store_, predicates);
1267         if (code != RDB_EXECUTE_OK) {
1268             HILOG_ERROR("ReContactMerge ERROR!");
1269         }
1270     }
1271     return code;
1272 }
1273 
InsertMergeData(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<int> & rawContactIdVector)1274 void ContactsDataBase::InsertMergeData(
1275     std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<int> &rawContactIdVector)
1276 {
1277     unsigned int size = rawContactIdVector.size();
1278     for (unsigned int i = 0; i < size; i++) {
1279         OHOS::NativeRdb::ValuesBucket mergeInfoValues;
1280         mergeInfoValues.PutInt(MergeInfo::RAW_CONTACT_ID, rawContactIdVector[i]);
1281         int64_t mergeInfoRowId = 0;
1282         int mergeInfoRet = store->Insert(mergeInfoRowId, ContactTableName::MERGE_INFO, mergeInfoValues);
1283         if (mergeInfoRet != RDB_EXECUTE_OK) {
1284             HILOG_ERROR("mergeInfo insert error : %{public}d ", mergeInfoRet);
1285         }
1286     }
1287 }
1288 
MergeUpdateTask(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<int> & rawContactIdVector,bool isDeleted)1289 void ContactsDataBase::MergeUpdateTask(
1290     std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<int> &rawContactIdVector, bool isDeleted)
1291 {
1292     std::unique_ptr<AsyncItem> task = std::make_unique<AsyncTask>(store_, rawContactIdVector, isDeleted);
1293     g_asyncTaskQueue->Push(task);
1294     g_asyncTaskQueue->Start();
1295 }
1296 
MarkMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store)1297 void ContactsDataBase::MarkMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> &store)
1298 {
1299     std::string sql = "SELECT ";
1300     sql.append(MergeInfo::RAW_CONTACT_ID)
1301         .append(" FROM ")
1302         .append(ContactTableName::MERGE_INFO)
1303         .append(" GROUP BY ")
1304         .append(MergeInfo::RAW_CONTACT_ID);
1305     auto resultSet = store->QuerySql(sql);
1306     int mergeResultSetNum = resultSet->GoToFirstRow();
1307     MatchCandidate matchCandidate;
1308     while (mergeResultSetNum == OHOS::NativeRdb::E_OK) {
1309         std::string columnName = MergeInfo::RAW_CONTACT_ID;
1310         int columnIndex = 0;
1311         int rawContactId = 0;
1312         resultSet->GetColumnIndex(columnName, columnIndex);
1313         resultSet->GetInt(columnIndex, rawContactId);
1314         int error = matchCandidate.FindMatchContact(store, rawContactId);
1315         if (error != RDB_EXECUTE_OK) {
1316             HILOG_ERROR("Find error is : %{public}d ", error);
1317         }
1318         std::string deleteMergeInfo = "DELETE FROM ";
1319         deleteMergeInfo.append(ContactTableName::MERGE_INFO)
1320             .append(" WHERE ")
1321             .append(MergeInfo::RAW_CONTACT_ID)
1322             .append(" = ")
1323             .append(std::to_string(rawContactId));
1324         int ret = store->ExecuteSql(deleteMergeInfo);
1325         if (ret != OHOS::NativeRdb::E_OK) {
1326             HILOG_ERROR("deleteMergeInfo error");
1327         }
1328         mergeResultSetNum = resultSet->GoToNextRow();
1329     }
1330     resultSet->Close();
1331 }
1332 
GetTypeId(std::string typeText)1333 int ContactsDataBase::GetTypeId(std::string typeText)
1334 {
1335     ContactsType contactsType;
1336     int typeId = contactsType.LookupTypeId(store_, typeText);
1337     HILOG_INFO("ContactsDataBase GetTypeId %{public}d", typeId);
1338     return typeId;
1339 }
1340 } // namespace Contacts
1341 } // namespace OHOS