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