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