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_data_ability.h"
17
18 #include <mutex>
19
20 #include "ability_loader.h"
21 #include "common.h"
22 #include "contacts_columns.h"
23 #include "contacts_common_event.h"
24 #include "contacts_datashare_stub_impl.h"
25 #include "datashare_ext_ability_context.h"
26 #include "datashare_predicates.h"
27 #include "database_disaster_recovery.h"
28 #include "file_utils.h"
29 #include "hilog_wrapper.h"
30 #include "profile_database.h"
31 #include "rdb_predicates.h"
32 #include "rdb_utils.h"
33 #include "sql_analyzer.h"
34 #include "uri_utils.h"
35
36 namespace OHOS {
37 namespace AbilityRuntime {
38 namespace {
39 std::mutex g_mutex;
40 }
41 std::shared_ptr<Contacts::ContactsDataBase> ContactsDataAbility::contactDataBase_ = nullptr;
42 std::shared_ptr<Contacts::ProfileDatabase> ContactsDataAbility::profileDataBase_ = nullptr;
43 std::map<std::string, int> ContactsDataAbility::uriValueMap_ = {
44 {"/com.ohos.contactsdataability/contacts/contact", Contacts::CONTACTS_CONTACT},
45 {"/com.ohos.contactsdataability/contacts/deleted_raw_contact", Contacts::CONTACTS_DELETE},
46 {"/com.ohos.contactsdataability/contacts/deleted_raw_contact_record", Contacts::CONTACTS_DELETE_RECORD},
47 {"/com.ohos.contactsdataability/contacts/raw_contact", Contacts::CONTACTS_RAW_CONTACT},
48 {"/com.ohos.contactsdataability/contacts/account", Contacts::ACCOUNT},
49 {"/com.ohos.contactsdataability/contacts/raw_contact/query_merge_list", Contacts::QUERY_MERGE_LIST},
50 {"/com.ohos.contactsdataability/contacts/raw_contact/split_contact", Contacts::SPLIT_CONTACT},
51 {"/com.ohos.contactsdataability/contacts/raw_contact/manual_merge", Contacts::MANUAL_MERGE},
52 {"/com.ohos.contactsdataability/contacts/raw_contact/auto_merge", Contacts::AUTO_MERGE},
53 {"/com.ohos.contactsdataability/contacts/contact_data", Contacts::CONTACTS_CONTACT_DATA},
54 {"/com.ohos.contactsdataability/contacts/contact_type", Contacts::CONTACT_TYPE},
55 {"/com.ohos.contactsdataability/contacts/groups", Contacts::CONTACTS_GROUPS},
56 {"/com.ohos.contactsdataability/contacts/contact_blocklist", Contacts::CONTACTS_BLOCKLIST},
57 {"/com.ohos.contactsdataability/contacts/photo_files", Contacts::CONTACTS_PHOTO_FILES},
58 {"/com.ohos.contactsdataability/contacts/search_contact", Contacts::CONTACTS_SEARCH_CONTACT},
59 {"/com.ohos.contactsdataability/contacts/backup", Contacts::CONTACT_BACKUP},
60 {"/com.ohos.contactsdataability/profile/backup", Contacts::PROFILE_BACKUP},
61 {"/com.ohos.contactsdataability/contacts/recover", Contacts::CONTACT_RECOVER},
62 {"/com.ohos.contactsdataability/profile/recover", Contacts::PROFILE_RECOVER},
63 {"/com.ohos.contactsdataability/profile/contact", Contacts::PROFILE_CONTACT},
64 {"/com.ohos.contactsdataability/profile/raw_contact", Contacts::PROFILE_RAW_CONTACT},
65 {"/com.ohos.contactsdataability/profile/contact_data", Contacts::PROFILE_CONTACT_DATA},
66 {"/com.ohos.contactsdataability/profile/groups", Contacts::PROFILE_GROUPS},
67 {"/com.ohos.contactsdataability/profile/contact_blocklist", Contacts::PROFILE_BLOCKLIST},
68 {"/com.ohos.contactsdataability/profile/photo_files", Contacts::PROFILE_PHOTO_FILES},
69 {"/com.ohos.contactsdataability/profile/search_contact", Contacts::PROFILE_SEARCH_CONTACT},
70 {"/com.ohos.contactsdataability/profile/deleted_raw_contact_record", Contacts::PROFILE_DELETE_RECORD},
71 {"/com.ohos.contactsdataability/profile/deleted_raw_contact", Contacts::PROFILE_DELETE},
72 {"/com.ohos.contactsdataability/profile/contact_type", Contacts::PROFILE_TYPE}
73 };
74
Create()75 ContactsDataAbility* ContactsDataAbility::Create()
76 {
77 return new ContactsDataAbility();
78 }
79
ContactsDataAbility()80 ContactsDataAbility::ContactsDataAbility() : DataShareExtAbility()
81 {
82 }
83
~ContactsDataAbility()84 ContactsDataAbility::~ContactsDataAbility()
85 {
86 }
87
ContactsDataShareCreator(const std::unique_ptr<Runtime> & runtime)88 static DataShare::DataShareExtAbility *ContactsDataShareCreator(const std::unique_ptr<Runtime> &runtime)
89 {
90 HILOG_INFO("ContactsDataCreator::%{public}s", __func__);
91 return ContactsDataAbility::Create();
92 }
93
RegisterDataShareCreator()94 __attribute__((constructor)) void RegisterDataShareCreator()
95 {
96 HILOG_INFO("ContactsDataCreator::%{public}s", __func__);
97 DataShare::DataShareExtAbility::SetCreator(ContactsDataShareCreator);
98 }
99
OnConnect(const AAFwk::Want & want)100 sptr<IRemoteObject> ContactsDataAbility::OnConnect(const AAFwk::Want &want)
101 {
102 HILOG_INFO("ContactsDataAbility %{public}s begin.", __func__);
103 Extension::OnConnect(want);
104 sptr<DataShare::ContactsDataShareStubImpl> remoteObject = new (std::nothrow) DataShare::ContactsDataShareStubImpl(
105 std::static_pointer_cast<ContactsDataAbility>(shared_from_this()));
106 if (remoteObject == nullptr) {
107 HILOG_ERROR("%{public}s No memory allocated for DataShareStubImpl", __func__);
108 return nullptr;
109 }
110 HILOG_INFO("ContactsDataAbility %{public}s end.", __func__);
111 return remoteObject->AsObject();
112 }
113
OnStart(const Want & want)114 void ContactsDataAbility::OnStart(const Want &want)
115 {
116 HILOG_INFO("ContactsDataAbility %{public}s begin.", __func__);
117 Extension::OnStart(want);
118 auto context = AbilityRuntime::Context::GetApplicationContext();
119 if (context != nullptr) {
120 std::string basePath = context->GetDatabaseDir();
121 Contacts::ContactsPath::RDB_PATH = basePath + "/";
122 Contacts::ContactsPath::RDB_BACKUP_PATH = basePath + "/backup/";
123 }
124 }
125
126 /**
127 * @brief Check whether BeginTransaction of ContactsDataAbility is empty
128 *
129 * @param code the return number of BeginTransaction
130 * @param mutex transmission parameter : lock
131 *
132 * @return True if BeginTransaction is empty; flase otherwise
133 */
IsBeginTransactionOK(int code,std::mutex & mutex)134 bool ContactsDataAbility::IsBeginTransactionOK(int code, std::mutex &mutex)
135 {
136 mutex.try_lock();
137 if (code != 0) {
138 HILOG_ERROR("IsBeginTransactionOK failed");
139 mutex.unlock();
140 return false;
141 }
142 return true;
143 }
144
145 /**
146 * @brief Check if ContactsDataAbility Commit is empty
147 *
148 * @param code the return number of Commit
149 * @param mutex transmission parameter : lock
150 *
151 * @return True if ContactsDataAbility Commit is empty; flase otherwise
152 */
IsCommitOK(int code,std::mutex & mutex)153 bool ContactsDataAbility::IsCommitOK(int code, std::mutex &mutex)
154 {
155 mutex.try_lock();
156 if (code != 0) {
157 HILOG_ERROR("IsCommitOK failed");
158 mutex.unlock();
159 return false;
160 }
161 return true;
162 }
163
164 /**
165 * @brief Insert ContactsDataAbility into the database
166 *
167 * @param uri URI of the data table tobe inserted
168 * @param value Inserted data value of the database
169 *
170 * @return Insert database results code
171 */
Insert(const Uri & uri,const DataShare::DataShareValuesBucket & value)172 int ContactsDataAbility::Insert(const Uri &uri, const DataShare::DataShareValuesBucket &value)
173 {
174 HILOG_INFO("ContactsDataAbility Insert start");
175 OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
176 Contacts::SqlAnalyzer sqlAnalyzer;
177 bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
178 if (!isOk) {
179 HILOG_ERROR("ContactsDataAbility CheckValuesBucket error");
180 return Contacts::RDB_EXECUTE_FAIL;
181 }
182 g_mutex.lock();
183 contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
184 profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
185 int resultId = Contacts::RDB_EXECUTE_FAIL;
186 OHOS::Uri uriTemp = uri;
187 int code = UriParseAndSwitch(uriTemp);
188 int ret = contactDataBase_->BeginTransaction();
189 if (!IsBeginTransactionOK(ret, g_mutex)) {
190 g_mutex.unlock();
191 return Contacts::RDB_EXECUTE_FAIL;
192 }
193 resultId = InsertExecute(code, valuesBucket);
194 HILOG_INFO("Insert id = %{public}d", resultId);
195 if (resultId == Contacts::OPERATION_ERROR) {
196 contactDataBase_->RollBack();
197 g_mutex.unlock();
198 return Contacts::OPERATION_ERROR;
199 }
200 ret = contactDataBase_->Commit();
201 if (!IsCommitOK(ret, g_mutex)) {
202 contactDataBase_->RollBack();
203 g_mutex.unlock();
204 return Contacts::RDB_EXECUTE_FAIL;
205 }
206 g_mutex.unlock();
207 DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
208 HILOG_INFO("ContactsDataAbility Insert end");
209 return resultId;
210 }
211
InsertExecute(int & code,const OHOS::NativeRdb::ValuesBucket & value)212 int ContactsDataAbility::InsertExecute(int &code, const OHOS::NativeRdb::ValuesBucket &value)
213 {
214 int rowId = Contacts::RDB_EXECUTE_FAIL;
215 switch (code) {
216 case Contacts::CONTACTS_RAW_CONTACT:
217 case Contacts::PROFILE_RAW_CONTACT:
218 // contact Basic Information
219 rowId = contactDataBase_->InsertRawContact(Contacts::ContactTableName::RAW_CONTACT, value);
220 break;
221 case Contacts::CONTACTS_CONTACT_DATA:
222 case Contacts::PROFILE_CONTACT_DATA:
223 // contact Information add
224 rowId = contactDataBase_->InsertContactData(Contacts::ContactTableName::CONTACT_DATA, value);
225 break;
226 case Contacts::CONTACTS_GROUPS:
227 case Contacts::PROFILE_GROUPS:
228 // insert group
229 rowId = contactDataBase_->InsertGroup(Contacts::ContactTableName::GROUPS, value);
230 break;
231 case Contacts::CONTACTS_BLOCKLIST:
232 case Contacts::PROFILE_BLOCKLIST:
233 // add blocklist
234 rowId = contactDataBase_->InsertBlockList(Contacts::ContactTableName::CONTACT_BLOCKLIST, value);
235 break;
236 default:
237 rowId = Contacts::OPERATION_ERROR;
238 HILOG_INFO("ContactsDataAbility ====>no match uri action");
239 break;
240 }
241 return rowId;
242 }
243
244 /**
245 * @brief ContactsDataAbility BatchInsert database
246 *
247 * @param uri Determine the data table name based on the URI
248 * @param value Inserted data value of the database
249 *
250 * @return BatchInsert database results code
251 */
BatchInsert(const Uri & uri,const std::vector<DataShare::DataShareValuesBucket> & values)252 int ContactsDataAbility::BatchInsert(const Uri &uri, const std::vector<DataShare::DataShareValuesBucket> &values)
253 {
254 unsigned int size = values.size();
255 if (size <= 0) {
256 return Contacts::RDB_EXECUTE_FAIL;
257 }
258 g_mutex.lock();
259 contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
260 profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
261 OHOS::Uri uriTemp = uri;
262 int code = UriParseAndSwitch(uriTemp);
263 int ret = contactDataBase_->BeginTransaction();
264 if (!IsBeginTransactionOK(ret, g_mutex)) {
265 g_mutex.unlock();
266 return Contacts::RDB_EXECUTE_FAIL;
267 }
268 int count = 0;
269 for (unsigned int i = 0; i < size; i++) {
270 ++count;
271 DataShare::DataShareValuesBucket rawContactValues = values[i];
272 OHOS::NativeRdb::ValuesBucket value = RdbDataShareAdapter::RdbUtils::ToValuesBucket(rawContactValues);
273 int rowRet = InsertExecute(code, value);
274 if (rowRet == Contacts::OPERATION_ERROR) {
275 contactDataBase_->RollBack();
276 g_mutex.unlock();
277 return rowRet;
278 }
279 if (count % Contacts::BATCH_INSERT_COUNT == 0) {
280 int markRet = contactDataBase_->Commit();
281 int beginRet = contactDataBase_->BeginTransaction();
282 if (!IsCommitOK(markRet, g_mutex) || !IsBeginTransactionOK(beginRet, g_mutex)) {
283 contactDataBase_->RollBack();
284 g_mutex.unlock();
285 return Contacts::RDB_EXECUTE_FAIL;
286 }
287 }
288 }
289 int markRet = contactDataBase_->Commit();
290 if (!IsCommitOK(markRet, g_mutex)) {
291 g_mutex.unlock();
292 return Contacts::RDB_EXECUTE_FAIL;
293 }
294 DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
295 g_mutex.unlock();
296 return Contacts::OPERATION_OK;
297 }
298
299 /**
300 * @brief Update ContactsDataAbility in the database
301 *
302 * @param uri URI of the data table to be inserted
303 * @param predicates Conditions for updating data value
304 *
305 * @return Update database results code
306 */
Update(const Uri & uri,const DataShare::DataSharePredicates & predicates,const DataShare::DataShareValuesBucket & value)307 int ContactsDataAbility::Update(
308 const Uri &uri, const DataShare::DataSharePredicates &predicates, const DataShare::DataShareValuesBucket &value)
309 {
310 OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
311 Contacts::SqlAnalyzer sqlAnalyzer;
312 bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
313 if (!isOk) {
314 HILOG_ERROR("ContactsDataAbility CheckValuesBucket error");
315 return Contacts::RDB_EXECUTE_FAIL;
316 }
317 g_mutex.lock();
318 contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
319 profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
320 int retCode = Contacts::RDB_EXECUTE_FAIL;
321 OHOS::Uri uriTemp = uri;
322 int code = UriParseAndSwitch(uriTemp);
323 DataShare::DataSharePredicates dataSharePredicates = predicates;
324 UpdateExecute(retCode, code, valuesBucket, dataSharePredicates);
325 g_mutex.unlock();
326 DataBaseNotifyChange(Contacts::CONTACT_UPDATE, uri);
327 return retCode;
328 }
329
UpdateExecute(int & retCode,int code,const OHOS::NativeRdb::ValuesBucket & value,DataShare::DataSharePredicates & dataSharePredicates)330 void ContactsDataAbility::UpdateExecute(int &retCode, int code, const OHOS::NativeRdb::ValuesBucket &value,
331 DataShare::DataSharePredicates &dataSharePredicates)
332 {
333 Contacts::PredicatesConvert predicatesConvert;
334 OHOS::NativeRdb::RdbPredicates rdbPredicates("");
335 switch (code) {
336 case Contacts::CONTACTS_CONTACT:
337 case Contacts::PROFILE_CONTACT:
338 break;
339 case Contacts::CONTACTS_RAW_CONTACT:
340 case Contacts::PROFILE_RAW_CONTACT:
341 rdbPredicates =
342 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::RAW_CONTACT, dataSharePredicates);
343 retCode = contactDataBase_->UpdateRawContact(value, rdbPredicates);
344 break;
345 case Contacts::CONTACTS_CONTACT_DATA:
346 case Contacts::PROFILE_CONTACT_DATA:
347 rdbPredicates =
348 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_DATA, dataSharePredicates);
349 retCode = contactDataBase_->UpdateContactData(value, rdbPredicates);
350 break;
351 case Contacts::CONTACTS_GROUPS:
352 case Contacts::PROFILE_GROUPS:
353 rdbPredicates =
354 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::GROUPS, dataSharePredicates);
355 retCode = contactDataBase_->UpdateGroup(value, rdbPredicates);
356 break;
357 case Contacts::CONTACTS_BLOCKLIST:
358 case Contacts::PROFILE_BLOCKLIST:
359 rdbPredicates = predicatesConvert.ConvertPredicates(
360 Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
361 retCode = contactDataBase_->UpdateBlockList(value, rdbPredicates);
362 break;
363 default:
364 SwitchUpdate(retCode, code, value, dataSharePredicates);
365 break;
366 }
367 }
368
SwitchUpdate(int & retCode,int & code,const OHOS::NativeRdb::ValuesBucket & value,DataShare::DataSharePredicates & dataSharePredicates)369 void ContactsDataAbility::SwitchUpdate(int &retCode, int &code, const OHOS::NativeRdb::ValuesBucket &value,
370 DataShare::DataSharePredicates &dataSharePredicates)
371 {
372 Contacts::PredicatesConvert predicatesConvert;
373 OHOS::NativeRdb::RdbPredicates rdbPredicates("");
374 switch (code) {
375 case Contacts::SPLIT_CONTACT:
376 retCode = contactDataBase_->Split(dataSharePredicates);
377 break;
378 case Contacts::MANUAL_MERGE:
379 retCode = contactDataBase_->ReContactMerge(dataSharePredicates);
380 break;
381 case Contacts::AUTO_MERGE:
382 retCode = contactDataBase_->ContactMerge();
383 break;
384 case Contacts::CONTACT_BACKUP:
385 case Contacts::PROFILE_BACKUP:
386 retCode = BackUp();
387 break;
388 case Contacts::CONTACT_RECOVER:
389 case Contacts::PROFILE_RECOVER:
390 retCode = Recover(code);
391 break;
392 default:
393 retCode = Contacts::RDB_EXECUTE_FAIL;
394 HILOG_ERROR("ContactsDataAbility ====>no match uri action");
395 break;
396 }
397 }
398
399 /**
400 * @brief Delete ContactsDataAbility from the database
401 *
402 * @param uri URI for the data table storing ContactsDataAbility
403 * @param predicates Conditions for deleting data values
404 *
405 * @return Delete database results code
406 */
Delete(const Uri & uri,const DataShare::DataSharePredicates & predicates)407 int ContactsDataAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates)
408 {
409 HILOG_INFO("ContactsDataAbility ====>Delete");
410 g_mutex.lock();
411 contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
412 profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
413 int retCode = Contacts::RDB_EXECUTE_FAIL;
414 OHOS::Uri uriTemp = uri;
415 int code = UriParseAndSwitch(uriTemp);
416 DataShare::DataSharePredicates dataSharePredicates = predicates;
417 DeleteExecute(retCode, code, dataSharePredicates);
418 g_mutex.unlock();
419 DataBaseNotifyChange(Contacts::CONTACT_DELETE, uri);
420 return retCode;
421 }
422
DeleteExecute(int & retCode,int code,DataShare::DataSharePredicates & dataSharePredicates)423 void ContactsDataAbility::DeleteExecute(
424 int &retCode, int code, DataShare::DataSharePredicates &dataSharePredicates)
425 {
426 Contacts::PredicatesConvert predicatesConvert;
427 OHOS::NativeRdb::RdbPredicates rdbPredicates("");
428 switch (code) {
429 case Contacts::CONTACTS_CONTACT:
430 case Contacts::PROFILE_CONTACT:
431 rdbPredicates =
432 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT, dataSharePredicates);
433 retCode = contactDataBase_->DeleteContact(rdbPredicates);
434 break;
435 case Contacts::CONTACTS_RAW_CONTACT:
436 case Contacts::PROFILE_RAW_CONTACT:
437 rdbPredicates =
438 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::RAW_CONTACT, dataSharePredicates);
439 retCode = contactDataBase_->DeleteRawContact(rdbPredicates);
440 break;
441 case Contacts::CONTACTS_CONTACT_DATA:
442 case Contacts::PROFILE_CONTACT_DATA:
443 rdbPredicates =
444 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_DATA, dataSharePredicates);
445 retCode = contactDataBase_->DeleteContactData(rdbPredicates);
446 break;
447 case Contacts::CONTACTS_GROUPS:
448 case Contacts::PROFILE_GROUPS:
449 rdbPredicates =
450 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::GROUPS, dataSharePredicates);
451 retCode = contactDataBase_->DeleteGroup(rdbPredicates);
452 break;
453 case Contacts::CONTACTS_BLOCKLIST:
454 case Contacts::PROFILE_BLOCKLIST:
455 rdbPredicates = predicatesConvert.ConvertPredicates(
456 Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
457 retCode = contactDataBase_->DeleteBlockList(rdbPredicates);
458 break;
459 case Contacts::CONTACTS_DELETE:
460 case Contacts::PROFILE_DELETE:
461 rdbPredicates =
462 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_DELETED, dataSharePredicates);
463 retCode = contactDataBase_->CompletelyDelete(rdbPredicates);
464 break;
465 case Contacts::CONTACTS_DELETE_RECORD:
466 case Contacts::PROFILE_DELETE_RECORD:
467 rdbPredicates = predicatesConvert.ConvertPredicates(
468 Contacts::ContactTableName::DELETE_RAW_CONTACT, dataSharePredicates);
469 retCode = contactDataBase_->DeleteRecord(rdbPredicates);
470 break;
471 default:
472 retCode = Contacts::OPERATION_ERROR;
473 HILOG_ERROR("ContactsDataAbility ====>No matching URI action");
474 break;
475 }
476 }
477
478 /**
479 * @brief Query contact data in the database
480 *
481 * @param uri URI of the data table that stores the contact data
482 * @param columns Columns where the contact data is located
483 * @param predicates Condition for querying data values
484 *
485 * @return Database query result
486 */
Query(const Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns)487 std::shared_ptr<DataShare::DataShareResultSet> ContactsDataAbility::Query(
488 const Uri &uri, const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns)
489 {
490 HILOG_INFO("ContactsDataAbility ====>Query start");
491 g_mutex.lock();
492 contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
493 profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
494 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> result;
495 OHOS::Uri uriTemp = uri;
496 int parseCode = UriParseAndSwitch(uriTemp);
497 std::vector<std::string> columnsTemp = columns;
498 DataShare::DataSharePredicates dataSharePredicates = predicates;
499 bool isUriMatch = QueryExecute(result, dataSharePredicates, columnsTemp, parseCode);
500 if (!isUriMatch) {
501 g_mutex.unlock();
502 return nullptr;
503 }
504 auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(result);
505 std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult =
506 std::make_shared<DataShare::DataShareResultSet>(queryResultSet);
507 g_mutex.unlock();
508 HILOG_INFO("ContactsDataAbility ====>Query end");
509 return sharedPtrResult;
510 }
511
QueryExecute(std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> & result,DataShare::DataSharePredicates & dataSharePredicates,std::vector<std::string> & columnsTemp,int & parseCode)512 bool ContactsDataAbility::QueryExecute(std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> &result,
513 DataShare::DataSharePredicates &dataSharePredicates, std::vector<std::string> &columnsTemp,
514 int &parseCode)
515 {
516 Contacts::PredicatesConvert predicatesConvert;
517 OHOS::NativeRdb::RdbPredicates rdbPredicates("");
518 bool isUriMatch = true;
519 switch (parseCode) {
520 case Contacts::CONTACTS_CONTACT:
521 case Contacts::PROFILE_CONTACT:
522 rdbPredicates =
523 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_CONTACT, dataSharePredicates);
524 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
525 break;
526 case Contacts::CONTACTS_RAW_CONTACT:
527 case Contacts::PROFILE_RAW_CONTACT:
528 rdbPredicates =
529 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_RAW_CONTACT, dataSharePredicates);
530 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
531 break;
532 case Contacts::CONTACTS_CONTACT_DATA:
533 case Contacts::PROFILE_CONTACT_DATA:
534 rdbPredicates =
535 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_CONTACT_DATA, dataSharePredicates);
536 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
537 break;
538 case Contacts::CONTACTS_GROUPS:
539 case Contacts::PROFILE_GROUPS:
540 rdbPredicates = predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_GROUPS, dataSharePredicates);
541 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
542 break;
543 default:
544 isUriMatch = QueryExecuteSwitchSplit(result, dataSharePredicates, columnsTemp, parseCode);
545 break;
546 }
547 return isUriMatch;
548 }
549
QueryExecuteSwitchSplit(std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> & result,DataShare::DataSharePredicates & dataSharePredicates,std::vector<std::string> & columnsTemp,int & parseCode)550 bool ContactsDataAbility::QueryExecuteSwitchSplit(std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> &result,
551 DataShare::DataSharePredicates &dataSharePredicates, std::vector<std::string> &columnsTemp,
552 int &parseCode)
553 {
554 Contacts::PredicatesConvert predicatesConvert;
555 OHOS::NativeRdb::RdbPredicates rdbPredicates("");
556 bool isUriMatch = true;
557 switch (parseCode) {
558 case Contacts::CONTACTS_BLOCKLIST:
559 case Contacts::PROFILE_BLOCKLIST:
560 rdbPredicates = predicatesConvert.ConvertPredicates(
561 Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
562 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
563 break;
564 case Contacts::CONTACTS_DELETE:
565 case Contacts::PROFILE_DELETE:
566 rdbPredicates =
567 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_DELETED, dataSharePredicates);
568 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
569 break;
570 case Contacts::CONTACTS_SEARCH_CONTACT:
571 case Contacts::PROFILE_SEARCH_CONTACT:
572 rdbPredicates =
573 predicatesConvert.ConvertPredicates(Contacts::ViewName::SEARCH_CONTACT_VIEW, dataSharePredicates);
574 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
575 break;
576 case Contacts::QUERY_MERGE_LIST:
577 result = contactDataBase_->SelectCandidate();
578 break;
579 case Contacts::CONTACT_TYPE:
580 case Contacts::PROFILE_TYPE:
581 rdbPredicates =
582 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_TYPE, dataSharePredicates);
583 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
584 break;
585 case Contacts::ACCOUNT:
586 rdbPredicates =
587 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::ACCOUNT, dataSharePredicates);
588 result = contactDataBase_->Query(rdbPredicates, columnsTemp);
589 break;
590 default:
591 isUriMatch = false;
592 HILOG_ERROR("ContactsDataAbility ====>no matching uri action");
593 break;
594 }
595 return isUriMatch;
596 }
597
UriParseAndSwitch(Uri & uri)598 int ContactsDataAbility::UriParseAndSwitch(Uri &uri)
599 {
600 Contacts::UriUtils uriUtils;
601 int parseCode = uriUtils.UriParse(uri, uriValueMap_);
602 if (parseCode != Contacts::OPERATION_ERROR) {
603 SwitchProfile(uri);
604 }
605 return parseCode;
606 }
607
SwitchProfile(Uri & uri)608 void ContactsDataAbility::SwitchProfile(Uri &uri)
609 {
610 std::vector<std::string> pathVector;
611 uri.GetPathSegments(pathVector);
612 if (pathVector.size() > 1 && pathVector[1].find("profile") == std::string::npos) {
613 contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
614 contactDataBase_->store_ = contactDataBase_->contactStore_;
615 } else {
616 profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
617 contactDataBase_->store_ = profileDataBase_->store_;
618 }
619 }
620
BackUp()621 int ContactsDataAbility::BackUp()
622 {
623 std::shared_ptr<OHOS::Contacts::DataBaseDisasterRecovery> instance =
624 OHOS::Contacts::DataBaseDisasterRecovery::GetInstance();
625 int retCode = instance->SQLiteCheckDb();
626 if (retCode == 0) {
627 retCode = instance->BackDatabase();
628 }
629 return retCode;
630 }
631
Recover(int & code)632 int ContactsDataAbility::Recover(int &code)
633 {
634 std::string name = Contacts::PROFILE_DATABASE_NAME;
635 if (code == Contacts::CONTACT_RECOVER) {
636 name = Contacts::CONTACT_DATABASE_NAME;
637 }
638 std::shared_ptr<OHOS::Contacts::DataBaseDisasterRecovery> instance =
639 OHOS::Contacts::DataBaseDisasterRecovery::GetInstance();
640 int retCode = instance->RecoveryDatabase(name);
641 contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
642 profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
643 return retCode;
644 }
645
DataBaseNotifyChange(int code,Uri uri)646 void ContactsDataAbility::DataBaseNotifyChange(int code, Uri uri)
647 {
648 Contacts::ContactsCommonEvent::SendContactChange(code);
649 }
650 } // namespace AbilityRuntime
651 } // namespace OHOS