• 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     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