• 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         int rowId = 0;
709         std::vector<std::string> whereArgs;
710         whereArgs.push_back(std::to_string(contactId));
711         std::string whereCase;
712         whereCase.append(SearchContactColumns::CONTACT_ID).append(" = ?");
713         int delRet = store->Delete(rowId, ContactTableName::SEARCH_CONTACT, whereCase, whereArgs);
714         if (delRet != OHOS::NativeRdb::E_OK) {
715             HILOG_ERROR("deleteRawContact searchContactDelete failed:%{public}d", delRet);
716         }
717         std::vector<int> rawContactIdVector;
718         rawContactIdVector.push_back(rawContactId);
719         ContactsUpdateHelper contactsUpdateHelper;
720         contactsUpdateHelper.UpdateCallLogByPhoneNum(rawContactIdVector, store, true);
721     }
722     g_mtx.unlock();
723 }
724 
725 /**
726  * @brief Delete data from the raw_contact table
727  *
728  * @param rdbPredicates Conditions for delete operation
729  *
730  * @return The result returned by the delete operation
731  */
DeleteRawContact(OHOS::NativeRdb::RdbPredicates & rdbPredicates)732 int ContactsDataBase::DeleteRawContact(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
733 {
734     if (store_ == nullptr) {
735         HILOG_ERROR("ContactsDataBase DeleteRawContact store_ is nullptr");
736         return RDB_OBJECT_EMPTY;
737     }
738     int ret = BeginTransaction();
739     if (ret != OHOS::NativeRdb::E_OK) {
740         return RDB_EXECUTE_FAIL;
741     }
742     std::vector<OHOS::NativeRdb::ValuesBucket> queryValuesBucket = DeleteRawContactQuery(rdbPredicates);
743     int deleteRet = DeleteExecute(queryValuesBucket);
744     if (deleteRet != OHOS::NativeRdb::E_OK) {
745         RollBack();
746         return RDB_EXECUTE_FAIL;
747     }
748     deleteRet = Commit();
749     if (deleteRet != OHOS::NativeRdb::E_OK) {
750         RollBack();
751         return RDB_EXECUTE_FAIL;
752     }
753     DeletedAsyncTask(store_, queryValuesBucket);
754     return deleteRet;
755 }
756 
DeleteContactQuery(OHOS::NativeRdb::RdbPredicates & rdbPredicates)757 std::vector<OHOS::NativeRdb::ValuesBucket> ContactsDataBase::DeleteContactQuery(
758     OHOS::NativeRdb::RdbPredicates &rdbPredicates)
759 {
760     PredicatesConvert predicatesConvert;
761     OHOS::NativeRdb::RdbPredicates newRdbPredicates =
762         predicatesConvert.CopyPredicates(ViewName::VIEW_CONTACT, rdbPredicates);
763     std::vector<std::string> columns;
764     columns.push_back(ContactPublicColumns::ID);
765     columns.push_back(RawContactColumns::DISPLAY_NAME);
766     auto resultSet = store_->Query(newRdbPredicates, columns);
767     int resultSetNum = resultSet->GoToFirstRow();
768     if (resultSetNum != OHOS::NativeRdb::E_OK) {
769         // query size 0
770         std::vector<OHOS::NativeRdb::ValuesBucket> vectorQueryData;
771         resultSet->GoToNextRow();
772         resultSet->Close();
773         return vectorQueryData;
774     }
775     std::vector<std::string> whereArgs;
776     while (resultSetNum == OHOS::NativeRdb::E_OK) {
777         int contactId;
778         resultSet->GetInt(0, contactId);
779         whereArgs.push_back(std::to_string(contactId));
780         resultSetNum = resultSet->GoToNextRow();
781     }
782     resultSet->Close();
783     unsigned int size = whereArgs.size();
784     OHOS::NativeRdb::RdbPredicates rawContactQueryRdbPredicates(ViewName::VIEW_RAW_CONTACT);
785     std::string whereClause;
786     for (unsigned int i = 0; i < size; i++) {
787         whereClause.append(" contact_id = ? ");
788         if (i != size - 1) {
789             whereClause.append(" OR ");
790         }
791     }
792     OHOS::NativeRdb::PredicatesUtils::SetWhereClauseAndArgs(&rawContactQueryRdbPredicates, whereClause, whereArgs);
793     OHOS::NativeRdb::PredicatesUtils::SetAttributes(&rawContactQueryRdbPredicates,
794         rawContactQueryRdbPredicates.IsDistinct(), rawContactQueryRdbPredicates.GetIndex(),
795         rawContactQueryRdbPredicates.GetGroup(), rawContactQueryRdbPredicates.GetOrder(),
796         rawContactQueryRdbPredicates.GetLimit(), rawContactQueryRdbPredicates.GetOffset());
797     return DeleteRawContactQuery(rawContactQueryRdbPredicates);
798 }
799 
DeleteRawContactQuery(OHOS::NativeRdb::RdbPredicates & rdbPredicates)800 std::vector<OHOS::NativeRdb::ValuesBucket> ContactsDataBase::DeleteRawContactQuery(
801     OHOS::NativeRdb::RdbPredicates &rdbPredicates)
802 {
803     std::vector<std::string> columns;
804     columns.push_back(RawContactColumns::DISPLAY_NAME);
805     columns.push_back(ContactColumns::ID);
806     columns.push_back(RawContactColumns::CONTACT_ID);
807     std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet = store_->Query(rdbPredicates, columns);
808     return ResultSetToValuesBucket(resultSet);
809 }
810 
DeleteRawContactLocal(int contactId,int rawContactId,std::string backupData,std::string disPlayName)811 int ContactsDataBase::DeleteRawContactLocal(
812     int contactId, int rawContactId, std::string backupData, std::string disPlayName)
813 {
814     OHOS::NativeRdb::ValuesBucket deleteRawContact;
815     deleteRawContact.PutInt(DeleteRawContactColumns::RAW_CONTACT_ID, rawContactId);
816     deleteRawContact.PutString(DeleteRawContactColumns::BACKUP_DATA, backupData);
817     deleteRawContact.PutString(DeleteRawContactColumns::DISPLAY_NAME, disPlayName);
818     deleteRawContact.PutInt(DeleteRawContactColumns::CONTACT_ID, contactId);
819     int64_t outRowId = OHOS::NativeRdb::E_OK;
820     int ret = store_->Insert(outRowId, ContactTableName::DELETE_RAW_CONTACT, deleteRawContact);
821     if (ret != OHOS::NativeRdb::E_OK) {
822         HILOG_ERROR("deleteRawContact deleteInsert failed:%{public}d", ret);
823         return RDB_EXECUTE_FAIL;
824     }
825     return ret;
826 }
827 
828 /**
829  * @brief Completely delete data from the database
830  *
831  * @param rdbPredicates Conditions for delete operation
832  *
833  * @return The result returned by the delete operation
834  */
CompletelyDelete(OHOS::NativeRdb::RdbPredicates & rdbPredicates)835 int ContactsDataBase::CompletelyDelete(OHOS::NativeRdb::RdbPredicates &rdbPredicates)
836 {
837     int ret = BeginTransaction();
838     if (ret != OHOS::NativeRdb::E_OK) {
839         return RDB_EXECUTE_FAIL;
840     }
841     std::vector<std::string> columns;
842     columns.push_back(DeleteRawContactColumns::CONTACT_ID);
843     auto resultSet = store_->Query(rdbPredicates, columns);
844     std::vector<std::string> contactIds;
845     int resultSetNum = resultSet->GoToFirstRow();
846     while (resultSetNum == OHOS::NativeRdb::E_OK) {
847         int contactId;
848         resultSet->GetInt(0, contactId);
849         contactIds.push_back(std::to_string(contactId));
850         resultSetNum = resultSet->GoToNextRow();
851     }
852     resultSet->Close();
853     int retCode = RDB_EXECUTE_FAIL;
854     unsigned int size = contactIds.size();
855     for (unsigned int index = 0; index < size; index++) {
856         std::string queryViewContact =
857             "SELECT id FROM view_raw_contact WHERE is_deleted = 1 AND contact_id = " + contactIds[index];
858         auto contactIdSet = store_->QuerySql(queryViewContact);
859         resultSetNum = contactIdSet->GoToFirstRow();
860         while (resultSetNum == OHOS::NativeRdb::E_OK) {
861             int value = -1;
862             contactIdSet->GetInt(0, value);
863             retCode = DeleteLocal(value, contactIds[index]);
864             if (retCode != OHOS::NativeRdb::E_OK) {
865                 HILOG_ERROR("CompletelyDelete DeleteLocal error:%{public}d", retCode);
866                 break;
867             }
868             resultSetNum = contactIdSet->GoToNextRow();
869         }
870         contactIdSet->Close();
871         if (retCode != OHOS::NativeRdb::E_OK) {
872             HILOG_ERROR("CompletelyDelete error:%{public}d", retCode);
873             RollBack();
874             return retCode;
875         }
876     }
877     return CompletelyDeleteCommit(retCode);
878 }
879 
CompletelyDeleteCommit(int retCode)880 int ContactsDataBase::CompletelyDeleteCommit(int retCode)
881 {
882     if (retCode != OHOS::NativeRdb::E_OK) {
883         HILOG_ERROR("CompletelyDelete end error:%{public}d", retCode);
884         RollBack();
885         return retCode;
886     }
887     int markRet = Commit();
888     if (markRet != OHOS::NativeRdb::E_OK) {
889         HILOG_ERROR("CompletelyDelete end error:%{public}d", markRet);
890         return RDB_EXECUTE_FAIL;
891     }
892     return retCode;
893 }
894 
DeleteLocal(int rawContactId,std::string contactId)895 int ContactsDataBase::DeleteLocal(int rawContactId, std::string contactId)
896 {
897     if (store_ == nullptr) {
898         HILOG_ERROR("ContactsDataBase DeleteLocal store is nullptr");
899         return RDB_OBJECT_EMPTY;
900     }
901     std::string updateContactSql = "UPDATE contact SET name_raw_contact_id = NULL WHERE id = " + contactId;
902     int retCode = store_->ExecuteSql(updateContactSql);
903     if (retCode != OHOS::NativeRdb::E_OK) {
904         HILOG_ERROR("DeleteLocal updateContactSql code:%{public}d", retCode);
905         return retCode;
906     }
907     std::string updateRawContactSql = "UPDATE raw_contact SET contact_id = NULL WHERE contact_id = " + contactId;
908     retCode = store_->ExecuteSql(updateRawContactSql);
909     if (retCode != OHOS::NativeRdb::E_OK) {
910         HILOG_ERROR("DeleteLocal updateRawContactSql code:%{public}d", retCode);
911         return retCode;
912     }
913     std::string deleteDeleteRawContactSql = "DELETE FROM deleted_raw_contact WHERE contact_id = " + contactId;
914     retCode = store_->ExecuteSql(deleteDeleteRawContactSql);
915     if (retCode != OHOS::NativeRdb::E_OK) {
916         HILOG_ERROR("DeleteLocal deleted_raw_contact code:%{public}d", retCode);
917         return retCode;
918     }
919     std::string deleteSearchContactSql = "DELETE FROM search_contact WHERE contact_id =  " + contactId;
920     retCode = store_->ExecuteSql(deleteSearchContactSql);
921     if (retCode != OHOS::NativeRdb::E_OK) {
922         HILOG_ERROR("DeleteLocal deleteSearchContactSql code:%{public}d", retCode);
923         return retCode;
924     }
925     std::string deleteContactData = "DELETE FROM contact_data WHERE raw_contact_id = " + std::to_string(rawContactId);
926     retCode = store_->ExecuteSql(deleteContactData);
927     if (retCode != OHOS::NativeRdb::E_OK) {
928         HILOG_ERROR("DeleteLocal deleteContactData code:%{public}d", retCode);
929         return retCode;
930     }
931     std::string deleteContactSql = "DELETE FROM contact WHERE id = " + contactId;
932     retCode = store_->ExecuteSql(deleteContactSql);
933     if (retCode != OHOS::NativeRdb::E_OK) {
934         HILOG_ERROR("DeleteLocal deleteContactSql code:%{public}d", retCode);
935         return retCode;
936     }
937     std::string deleteRawContactSql = "DELETE FROM raw_contact WHERE id =  " + std::to_string(rawContactId);
938     retCode = store_->ExecuteSql(deleteRawContactSql);
939     if (retCode != OHOS::NativeRdb::E_OK) {
940         HILOG_ERROR("DeleteLocal deleteRawContactSql code:%{public}d", retCode);
941         return retCode;
942     }
943     return retCode;
944 }
945 
QueryContactDataRawContactId(OHOS::NativeRdb::RdbPredicates & rdbPredicates,std::vector<std::string> & types)946 std::vector<int> ContactsDataBase::QueryContactDataRawContactId(
947     OHOS::NativeRdb::RdbPredicates &rdbPredicates, std::vector<std::string> &types)
948 {
949     std::vector<std::string> columns;
950     columns.push_back(ContactDataColumns::TYPE_ID);
951     columns.push_back(ContactDataColumns::RAW_CONTACT_ID);
952     auto resultSet = store_->Query(rdbPredicates, columns);
953     std::vector<int> rawContactIdVector;
954     std::vector<int> typeIdVector;
955     int resultSetNum = resultSet->GoToFirstRow();
956     while (resultSetNum == OHOS::NativeRdb::E_OK) {
957         std::string columnName = ContactDataColumns::RAW_CONTACT_ID;
958         int columnIndex = 0;
959         resultSet->GetColumnIndex(columnName, columnIndex);
960         int rawContactId = 0;
961         resultSet->GetInt(columnIndex, rawContactId);
962         std::string typeIdKey = ContactDataColumns::TYPE_ID;
963         int columnIndexType = 0;
964         resultSet->GetColumnIndex(typeIdKey, columnIndexType);
965         int typeId = 0;
966         resultSet->GetInt(columnIndexType, typeId);
967         OHOS::NativeRdb::ValueObject typeTextObject;
968         typeIdVector.push_back(typeId);
969         rawContactIdVector.push_back(rawContactId);
970         resultSetNum = resultSet->GoToNextRow();
971     }
972     resultSet->Close();
973     unsigned int typeIdSize = typeIdVector.size();
974     ContactsType contactsType;
975     for (unsigned int i = 0; i < typeIdSize; i++) {
976         std::string typeText = contactsType.GetTypeText(store_, typeIdVector[i]);
977         types.push_back(typeText);
978     }
979     return rawContactIdVector;
980 }
981 
982 /**
983  * @brief Query data according to given conditions
984  *
985  * @param rdbPredicates Conditions for query operation
986  * @param columns Conditions for query operation
987  *
988  * @return The result returned by the query operation
989  */
Query(OHOS::NativeRdb::RdbPredicates & rdbPredicates,std::vector<std::string> & columns)990 std::shared_ptr<OHOS::NativeRdb::ResultSet> ContactsDataBase::Query(
991     OHOS::NativeRdb::RdbPredicates &rdbPredicates, std::vector<std::string> &columns)
992 {
993     if (store_ == nullptr) {
994         HILOG_ERROR("ContactsDataBase Query store_ is nullptr");
995         return nullptr;
996     }
997     int errCode = OHOS::NativeRdb::E_OK;
998     auto resultSet = store_->Query(rdbPredicates, columns);
999     if (errCode != OHOS::NativeRdb::E_OK) {
1000         HILOG_INFO("Query error code is:%{public}d", errCode);
1001     }
1002     return resultSet;
1003 }
1004 
ResultSetToValuesBucket(std::shared_ptr<OHOS::NativeRdb::ResultSet> & resultSet)1005 std::vector<OHOS::NativeRdb::ValuesBucket> ContactsDataBase::ResultSetToValuesBucket(
1006     std::shared_ptr<OHOS::NativeRdb::ResultSet> &resultSet)
1007 {
1008     std::vector<std::string> columnNames;
1009     resultSet->GetAllColumnNames(columnNames);
1010     std::vector<OHOS::NativeRdb::ValuesBucket> vectorQueryData;
1011     int resultSetNum = resultSet->GoToFirstRow();
1012     while (resultSetNum == OHOS::NativeRdb::E_OK) {
1013         OHOS::NativeRdb::ValuesBucket valuesBucketElement;
1014         unsigned int size = columnNames.size();
1015         for (unsigned int i = 0; i < size; i++) {
1016             std::string typeValue = columnNames[i];
1017             int columnIndex = 0;
1018             resultSet->GetColumnIndex(typeValue, columnIndex);
1019             OHOS::NativeRdb::ColumnType columnType;
1020             resultSet->GetColumnType(columnIndex, columnType);
1021             if (columnType == OHOS::NativeRdb::ColumnType::TYPE_INTEGER) {
1022                 int intValue = 0;
1023                 resultSet->GetInt(columnIndex, intValue);
1024                 valuesBucketElement.PutInt(typeValue, intValue);
1025             } else if (columnType == OHOS::NativeRdb::ColumnType::TYPE_FLOAT) {
1026                 double doubleValue = 0;
1027                 resultSet->GetDouble(columnIndex, doubleValue);
1028                 valuesBucketElement.PutDouble(typeValue, doubleValue);
1029             } else if (columnType == OHOS::NativeRdb::ColumnType::TYPE_STRING) {
1030                 std::string stringValue;
1031                 resultSet->GetString(columnIndex, stringValue);
1032                 valuesBucketElement.PutString(typeValue, stringValue);
1033             }
1034         }
1035         vectorQueryData.push_back(valuesBucketElement);
1036         resultSetNum = resultSet->GoToNextRow();
1037     }
1038     resultSet->Close();
1039     return vectorQueryData;
1040 }
1041 
StructureDeleteContactJson(OHOS::NativeRdb::ValuesBucket rawContactValues,std::string rawContactIdColumn,int rawContactId)1042 std::string ContactsDataBase::StructureDeleteContactJson(
1043     OHOS::NativeRdb::ValuesBucket rawContactValues, std::string rawContactIdColumn, int rawContactId)
1044 {
1045     ContactsJsonUtils contactsJsonUtils;
1046     std::vector<std::string> selectionArgs;
1047     selectionArgs.push_back(std::to_string(rawContactId));
1048     std::string queryTabName = ViewName::VIEW_CONTACT_DATA;
1049     std::vector<std::string> contentColumns;
1050     contentColumns.push_back(ContentTypeColumns::CONTENT_TYPE);
1051     contentColumns.push_back(ContactDataColumns::DETAIL_INFO);
1052     contentColumns.push_back(ContactDataColumns::POSITION);
1053     contentColumns.push_back(ContactDataColumns::EXTEND1);
1054     contentColumns.push_back(ContactDataColumns::EXTEND2);
1055     contentColumns.push_back(ContactDataColumns::EXTEND3);
1056     contentColumns.push_back(ContactDataColumns::EXTEND4);
1057     contentColumns.push_back(ContactDataColumns::ALPHA_NAME);
1058     contentColumns.push_back(ContactDataColumns::OTHER_LAN_LAST_NAME);
1059     contentColumns.push_back(ContactDataColumns::OTHER_LAN_FIRST_NAME);
1060     contentColumns.push_back(ContactDataColumns::EXTEND5);
1061     contentColumns.push_back(ContactDataColumns::LAN_STYLE);
1062     contentColumns.push_back(ContactDataColumns::CUSTOM_DATA);
1063     contentColumns.push_back(ContactDataColumns::EXTEND6);
1064     contentColumns.push_back(ContactDataColumns::EXTEND7);
1065     contentColumns.push_back(ContactDataColumns::BLOB_DATA);
1066     std::string queryWhereClause = DeleteRawContactColumns::RAW_CONTACT_ID;
1067     queryWhereClause.append(" = ? ");
1068     std::string sql = "SELECT ";
1069     unsigned int size = contentColumns.size();
1070     for (unsigned int i = 0; i < size; i++) {
1071         sql.append(contentColumns[i]);
1072         if (i != size - 1) {
1073             sql.append(", ");
1074         }
1075     }
1076     sql.append(" FROM ").append(queryTabName).append(" WHERE ").append(queryWhereClause);
1077     std::shared_ptr<OHOS::NativeRdb::ResultSet> contactDataResultSet = store_->QuerySql(sql, selectionArgs);
1078     std::string backupData = contactsJsonUtils.GetDeleteData(contactDataResultSet);
1079     contactDataResultSet->Close();
1080     return backupData;
1081 }
1082 
OnCreate(OHOS::NativeRdb::RdbStore & store)1083 int SqliteOpenHelperContactCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
1084 {
1085     store.ExecuteSql(CREATE_CONTACT);
1086     store.ExecuteSql(CREATE_CONTACT_INDEX);
1087     store.ExecuteSql(CREATE_RAW_CONTACT);
1088     store.ExecuteSql(CREATE_RAW_CONTACT_INDEX);
1089     store.ExecuteSql(CREATE_CONTACT_DATA);
1090     store.ExecuteSql(CREATE_CONTACT_INDEX_DATA1);
1091     store.ExecuteSql(CREATE_CONTACT_INDEX_DATA2);
1092     store.ExecuteSql(CREATE_CONTACT_BLOCKLIST);
1093     store.ExecuteSql(CREATE_LOCAL_LANG);
1094     store.ExecuteSql(CREATE_ACCOUNT);
1095     store.ExecuteSql(CREATE_PHOTO_FILES);
1096     store.ExecuteSql(CREATE_CONTACT_TYPE);
1097     store.ExecuteSql(CREATE_GROUPS);
1098     store.ExecuteSql(CREATE_DELETED_RAW_CONTACT);
1099     store.ExecuteSql(CREATE_SEARCH_CONTACT);
1100     store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX1);
1101     store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX2);
1102     store.ExecuteSql(CREATE_SEARCH_CONTACT_VIEW);
1103     store.ExecuteSql(MERGE_INFO);
1104     store.ExecuteSql(CREATE_VIEW_CONTACT_DATA);
1105     store.ExecuteSql(CREATE_VIEW_RAW_CONTACT);
1106     store.ExecuteSql(CREATE_VIEW_CONTACT);
1107     store.ExecuteSql(CREATE_VIEW_GROUPS);
1108     store.ExecuteSql(CREATE_VIEW_DELETED);
1109     store.ExecuteSql(INSERT_DELETE_RAW_CONTACT);
1110     store.ExecuteSql(UPDATE_RAW_CONTACT_VERSION);
1111     store.ExecuteSql(UPDATE_CONTACT_DATA_VERSION);
1112     store.ExecuteSql(INSERT_CONTACT_QUICK_SEARCH);
1113     store.ExecuteSql(CREATE_DATABASE_BACKUP_TASK);
1114     store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
1115     store.ExecuteSql(UPDATE_CONTACT_BY_INSERT_CONTACT_DATA);
1116     store.ExecuteSql(UPDATE_CONTACT_BY_DELETE_CONTACT_DATA);
1117     store.ExecuteSql(UPDATE_CONTACT_BY_UPDATE_CONTACT_DATA);
1118     store.ExecuteSql(MERGE_INFO_INDEX);
1119     return OHOS::NativeRdb::E_OK;
1120 }
1121 
OnUpgrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1122 int SqliteOpenHelperContactCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1123 {
1124     HILOG_INFO("OnUpgrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
1125     if (oldVersion < newVersion && newVersion == DATABASE_NEW_VERSION) {
1126         store.ExecuteSql("ALTER TABLE database_backup_task ADD COLUMN sync TEXT");
1127     }
1128     if (oldVersion < newVersion && newVersion == DATABASE_VERSION_2) {
1129         UpgradeToV2(store, oldVersion, newVersion);
1130     }
1131     store.SetVersion(newVersion);
1132     return OHOS::NativeRdb::E_OK;
1133 }
1134 
UpgradeToV2(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1135 void SqliteOpenHelperContactCallback::UpgradeToV2(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1136 {
1137     if (oldVersion >= newVersion || newVersion != DATABASE_VERSION_2) {
1138         return;
1139     }
1140     // raw_contact
1141     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN primary_contact INTEGER DEFAULT 0;");
1142     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra1 TEXT;");
1143     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra2 TEXT;");
1144     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra3 TEXT;");
1145     store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra4 TEXT;");
1146     // contact_data
1147     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend8 TEXT;");
1148     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend9 TEXT;");
1149     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend10 TEXT;");
1150     store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend11 TEXT;");
1151     // drop view
1152     store.ExecuteSql("DROP VIEW view_contact;");
1153     store.ExecuteSql("DROP VIEW view_contact_data;");
1154     store.ExecuteSql("DROP VIEW search_contact_view;");
1155     store.ExecuteSql("DROP VIEW view_deleted;");
1156     // create view
1157     store.ExecuteSql(CREATE_VIEW_CONTACT);
1158     store.ExecuteSql(CREATE_VIEW_CONTACT_DATA);
1159     store.ExecuteSql(CREATE_SEARCH_CONTACT_VIEW);
1160     store.ExecuteSql(CREATE_VIEW_DELETED);
1161 }
1162 
OnDowngrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)1163 int SqliteOpenHelperContactCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
1164 {
1165     HILOG_INFO("OnDowngrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
1166     if (oldVersion > newVersion && newVersion == DATABASE_OPEN_VERSION) {
1167         store.ExecuteSql(
1168             "CREATE TABLE IF NOT EXISTS database_backup (id INTEGER PRIMARY KEY AUTOINCREMENT, backup_time "
1169             "TEXT, backup_path TEXT, remarks TEXT)");
1170         store.ExecuteSql(
1171             "INSERT INTO database_backup(id, backup_time, backup_path, remarks) SELECT id, "
1172             "backup_time, backup_path, remarks FROM database_backup_task");
1173         store.ExecuteSql("DROP table database_backup_task");
1174         store.ExecuteSql("ALTER table database_backup RENAME TO database_backup_task");
1175         store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
1176     }
1177     int ret = store.SetVersion(newVersion);
1178     return ret;
1179 }
1180 
DestroyInstanceAndRestore(std::string restorePath)1181 void ContactsDataBase::DestroyInstanceAndRestore(std::string restorePath)
1182 {
1183     g_mtx.lock();
1184     if (access(restorePath.c_str(), F_OK) != 0) {
1185         HILOG_ERROR("Restore file %{private}s does not exist", restorePath.c_str());
1186         g_mtx.unlock();
1187         return;
1188     }
1189     OHOS::NativeRdb::RdbHelper::DeleteRdbStore(g_databaseName);
1190     OHOS::NativeRdb::RdbHelper::ClearCache();
1191     contactDataBase_ = nullptr;
1192     Restore(restorePath);
1193     g_mtx.unlock();
1194 }
1195 
Restore(std::string restorePath)1196 bool ContactsDataBase::Restore(std::string restorePath)
1197 {
1198     HILOG_INFO("ContactsDataBase Restore start ");
1199     if (rename(restorePath.c_str(), g_databaseName.c_str()) == 0) {
1200         HILOG_INFO("ContactsDataBase Restore rename ok ");
1201         return true;
1202     }
1203     return false;
1204 }
1205 
1206 /**
1207  * @brief Select candidates
1208  *
1209  * @return The result returned by the selectCandidate operation
1210  */
SelectCandidate()1211 std::shared_ptr<OHOS::NativeRdb::ResultSet> ContactsDataBase::SelectCandidate()
1212 {
1213     MarkMerge(store_);
1214     MergerContacts mergerContacts;
1215     return mergerContacts.SelectCandidate(store_);
1216 }
1217 
1218 /**
1219  * @brief Perform a split operation
1220  *
1221  * @param predicates Conditions for split operation
1222  *
1223  * @return The result returned by the split operation
1224  */
Split(DataShare::DataSharePredicates predicates)1225 int ContactsDataBase::Split(DataShare::DataSharePredicates predicates)
1226 {
1227     std::vector<std::string> whereArgs = predicates.GetWhereArgs();
1228     if (whereArgs.size() > 1) {
1229         HILOG_ERROR("Invalid parameter passed");
1230         return RDB_EXECUTE_FAIL;
1231     }
1232     MatchCandidate matchCandidate;
1233     int code = RDB_EXECUTE_FAIL;
1234     for (auto value : whereArgs) {
1235         code = matchCandidate.Split(store_, atoi(value.c_str()));
1236     }
1237     if (code != RDB_EXECUTE_OK) {
1238         HILOG_INFO("Split code %{public}d", code);
1239     }
1240     return code;
1241 }
1242 
1243 /**
1244  * @brief Perform an autoMerge operation
1245  *
1246  * @return The result returned by the autoMerge operation
1247  */
ContactMerge()1248 int ContactsDataBase::ContactMerge()
1249 {
1250     MarkMerge(store_);
1251     int code = RDB_EXECUTE_FAIL;
1252     MergerContacts mergerContacts;
1253     if (store_ != nullptr) {
1254         code = mergerContacts.ContactMerge(store_);
1255         if (code != RDB_EXECUTE_OK) {
1256             HILOG_ERROR("ContactMerge ERROR!");
1257         }
1258     }
1259     return code;
1260 }
1261 
1262 /**
1263  * @brief Perform a manualMerge operation
1264  *
1265  * @param predicates Conditions for manualMerge operation
1266  *
1267  * @return The result returned by the manualMerge operation
1268  */
ReContactMerge(DataShare::DataSharePredicates predicates)1269 int ContactsDataBase::ReContactMerge(DataShare::DataSharePredicates predicates)
1270 {
1271     MarkMerge(store_);
1272     int code = RDB_EXECUTE_FAIL;
1273     MergerContacts mergerContacts;
1274     if (store_ != nullptr) {
1275         code = mergerContacts.ReContactMerge(store_, predicates);
1276         if (code != RDB_EXECUTE_OK) {
1277             HILOG_ERROR("ReContactMerge ERROR!");
1278         }
1279     }
1280     return code;
1281 }
1282 
InsertMergeData(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<int> & rawContactIdVector)1283 void ContactsDataBase::InsertMergeData(
1284     std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<int> &rawContactIdVector)
1285 {
1286     unsigned int size = rawContactIdVector.size();
1287     for (unsigned int i = 0; i < size; i++) {
1288         OHOS::NativeRdb::ValuesBucket mergeInfoValues;
1289         mergeInfoValues.PutInt(MergeInfo::RAW_CONTACT_ID, rawContactIdVector[i]);
1290         int64_t mergeInfoRowId = 0;
1291         int mergeInfoRet = store->Insert(mergeInfoRowId, ContactTableName::MERGE_INFO, mergeInfoValues);
1292         if (mergeInfoRet != RDB_EXECUTE_OK) {
1293             HILOG_ERROR("mergeInfo insert error : %{public}d ", mergeInfoRet);
1294         }
1295     }
1296 }
1297 
MergeUpdateTask(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store,std::vector<int> & rawContactIdVector,bool isDeleted)1298 void ContactsDataBase::MergeUpdateTask(
1299     std::shared_ptr<OHOS::NativeRdb::RdbStore> &store, std::vector<int> &rawContactIdVector, bool isDeleted)
1300 {
1301     std::unique_ptr<AsyncItem> task = std::make_unique<AsyncTask>(store_, rawContactIdVector, isDeleted);
1302     g_asyncTaskQueue->Push(task);
1303     g_asyncTaskQueue->Start();
1304 }
1305 
MarkMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> & store)1306 void ContactsDataBase::MarkMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> &store)
1307 {
1308     std::string sql = "SELECT ";
1309     sql.append(MergeInfo::RAW_CONTACT_ID)
1310         .append(" FROM ")
1311         .append(ContactTableName::MERGE_INFO)
1312         .append(" GROUP BY ")
1313         .append(MergeInfo::RAW_CONTACT_ID);
1314     auto resultSet = store->QuerySql(sql);
1315     int mergeResultSetNum = resultSet->GoToFirstRow();
1316     MatchCandidate matchCandidate;
1317     while (mergeResultSetNum == OHOS::NativeRdb::E_OK) {
1318         std::string columnName = MergeInfo::RAW_CONTACT_ID;
1319         int columnIndex = 0;
1320         int rawContactId = 0;
1321         resultSet->GetColumnIndex(columnName, columnIndex);
1322         resultSet->GetInt(columnIndex, rawContactId);
1323         int error = matchCandidate.FindMatchContact(store, rawContactId);
1324         if (error != RDB_EXECUTE_OK) {
1325             HILOG_ERROR("Find error is : %{public}d ", error);
1326         }
1327         std::string deleteMergeInfo = "DELETE FROM ";
1328         deleteMergeInfo.append(ContactTableName::MERGE_INFO)
1329             .append(" WHERE ")
1330             .append(MergeInfo::RAW_CONTACT_ID)
1331             .append(" = ")
1332             .append(std::to_string(rawContactId));
1333         int ret = store->ExecuteSql(deleteMergeInfo);
1334         if (ret != OHOS::NativeRdb::E_OK) {
1335             HILOG_ERROR("deleteMergeInfo error");
1336         }
1337         mergeResultSetNum = resultSet->GoToNextRow();
1338     }
1339     resultSet->Close();
1340 }
1341 
GetTypeId(std::string typeText)1342 int ContactsDataBase::GetTypeId(std::string typeText)
1343 {
1344     ContactsType contactsType;
1345     int typeId = contactsType.LookupTypeId(store_, typeText);
1346     HILOG_INFO("ContactsDataBase GetTypeId %{public}d", typeId);
1347     return typeId;
1348 }
1349 } // namespace Contacts
1350 } // namespace OHOS