• 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 "candidate_status.h"
17 
18 #include "common.h"
19 #include "contacts_columns.h"
20 #include "contacts_database.h"
21 #include "hilog_wrapper.h"
22 #include "merge_utils.h"
23 
24 namespace OHOS {
25 namespace Contacts {
CandidateStatus()26 CandidateStatus::CandidateStatus()
27 {
28 }
29 
~CandidateStatus()30 CandidateStatus::~CandidateStatus()
31 {
32 }
33 
34 /**
35  * @brief Query operation for merging candidates
36  *
37  * @param store Conditions for query operation
38  * @param rawId Contacts's raw_contact_id to query
39  *
40  * @return Collection of canddidate contacts with the same raw_contact_id
41  */
QueryAllForMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> store,int rawId)42 Candidate CandidateStatus::QueryAllForMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
43 {
44     Candidate candidate;
45     std::shared_ptr<ContactsDataBase> contactsDataBase = ContactsDataBase::GetInstance();
46     int nameType = contactsDataBase->GetTypeId(ContentTypeData::NAME);
47     int phoneType = contactsDataBase->GetTypeId(ContentTypeData::PHONE);
48     MergeUtils mergeUtils;
49     std::set<std::string> names = mergeUtils.QueryRawContactByType(store, rawId, nameType);
50     // query other name with the raw_contact_id
51     std::vector<int> nameIds = mergeUtils.QueryByDataName(rawId, names, store);
52     // query current phone
53     std::set<std::string> phones = mergeUtils.QueryRawContactByType(store, rawId, phoneType);
54     std::set<int> autoIds;
55     std::set<int> manualIds;
56     unsigned int size = nameIds.size();
57     for (unsigned int i = 0; i < size; i++) {
58         if (!IsNeedMerge(store, nameIds[i]) || !IsMergeStatus(store, nameIds[i])) {
59             continue;
60         }
61         std::set<std::string> otherPhones = mergeUtils.QueryRawContactByType(store, nameIds[i], phoneType);
62         if (phones.empty() && otherPhones.empty()) {
63             autoIds.insert(nameIds[i]);
64         }
65         if (phones.empty() || otherPhones.empty()) {
66             manualIds.insert(nameIds[i]);
67         }
68         if (mergeUtils.SetEqual(phones, otherPhones)) {
69             autoIds.insert(nameIds[i]);
70         } else {
71             manualIds.insert(nameIds[i]);
72         }
73     }
74     candidate.autoIds_ = autoIds;
75     candidate.manualIds_ = manualIds;
76     AddMergedStatus(candidate);
77     HILOG_INFO("QueryAllForMerge mode is : %{public}d ", candidate.mergeMode_);
78     candidate.autoIds_.insert(rawId);
79     candidate.manualIds_.insert(rawId);
80     HILOG_INFO("QueryAllForMerge size is : %{public}zu ", candidate.autoIds_.size());
81     HILOG_INFO("QueryAllForMerge candidate.manualIds_ is : %{public}zu ", candidate.manualIds_.size());
82     return candidate;
83 }
84 
AddMergedStatus(Candidate & candidate)85 void CandidateStatus::AddMergedStatus(Candidate &candidate)
86 {
87     if (!candidate.autoIds_.empty()) {
88         candidate.mergeMode_ = MERGE_MODE_AUTO;
89     } else if (!candidate.manualIds_.empty()) {
90         candidate.mergeMode_ = MERGE_MODE_MANUAL;
91     } else {
92         candidate.mergeMode_ = MERGE_MODE_DEFAULT;
93     }
94 }
95 
96 /**
97  * @brief Query operation for checking if candidate marging is needed
98  *
99  * @param store Conditions for query operation
100  * @param rawId Contacts's raw_contact_id to query
101  *
102  * @return The result returned by the query operation
103  */
IsNeedMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> store,int rawId)104 bool CandidateStatus::IsNeedMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
105 {
106     std::string isNeedMergeSql = "SELECT ";
107     isNeedMergeSql.append(RawContactColumns::IS_NEED_MERGE)
108         .append(" FROM ")
109         .append(ContactTableName::RAW_CONTACT)
110         .append(" WHERE ")
111         .append(ContactPublicColumns::ID)
112         .append(" = ")
113         .append(std::to_string(rawId));
114     auto isNeedMergeSet = store->QuerySql(isNeedMergeSql);
115     bool isNeedMerge = false;
116     int resultSetNum = isNeedMergeSet->GoToFirstRow();
117     while (resultSetNum == OHOS::NativeRdb::E_OK) {
118         int value = 0;
119         isNeedMergeSet->GetInt(0, value);
120         if (value == 1) {
121             isNeedMerge = true;
122         } else {
123             isNeedMerge = false;
124         }
125         resultSetNum = isNeedMergeSet->GoToNextRow();
126     }
127     isNeedMergeSet->Close();
128     return isNeedMerge;
129 }
130 
131 /**
132  * @brief Check if the candidate has true merge_status
133  *
134  * @param store Conditions for query operation
135  * @param rawId Contacts's raw_contact_id to query
136  *
137  * @return True if the candidate is in the merged status; flase otherwise
138  */
IsMergeStatus(std::shared_ptr<OHOS::NativeRdb::RdbStore> store,int rawId)139 bool CandidateStatus::IsMergeStatus(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
140 {
141     std::string isMergeSwitchSql = "SELECT ";
142     isMergeSwitchSql.append(RawContactColumns::MERGE_STATUS)
143         .append(" FROM ")
144         .append(ContactTableName::RAW_CONTACT)
145         .append(" WHERE ")
146         .append(ContactPublicColumns::ID)
147         .append(" = ")
148         .append(std::to_string(rawId));
149     auto MergeSwitchSet = store->QuerySql(isMergeSwitchSql);
150     bool isMergeSwitch = false;
151     int resultSetNum = MergeSwitchSet->GoToFirstRow();
152     while (resultSetNum == OHOS::NativeRdb::E_OK) {
153         int value = 0;
154         MergeSwitchSet->GetInt(0, value);
155         if (value == 1) {
156             isMergeSwitch = true;
157         } else {
158             isMergeSwitch = false;
159         }
160         resultSetNum = MergeSwitchSet->GoToNextRow();
161     }
162     MergeSwitchSet->Close();
163     return isMergeSwitch;
164 }
165 
166 /**
167  * @brief Check if the candidate has been merged
168  *
169  * @param store Conditions for query operation
170  * @param rawId Contacts's raw_contact_id to query
171  *
172  * @return True if the candidate has been merged; false otherwise
173  */
IsMerged(std::shared_ptr<OHOS::NativeRdb::RdbStore> store,int rawId)174 bool CandidateStatus::IsMerged(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
175 {
176     std::string isNeedMergeSql = "SELECT ";
177     isNeedMergeSql.append(RawContactColumns::MERGE_MODE)
178         .append(" FROM ")
179         .append(ContactTableName::RAW_CONTACT)
180         .append(" WHERE ")
181         .append(ContactPublicColumns::ID)
182         .append(" = ")
183         .append(std::to_string(rawId));
184     auto isNeedMergeSet = store->QuerySql(isNeedMergeSql);
185     bool mergeMode = false;
186     int resultSetNum = isNeedMergeSet->GoToFirstRow();
187     while (resultSetNum == OHOS::NativeRdb::E_OK) {
188         int value = 0;
189         isNeedMergeSet->GetInt(0, value);
190         if (value == 0) {
191             mergeMode = true;
192         } else {
193             mergeMode = false;
194         }
195         resultSetNum = isNeedMergeSet->GoToNextRow();
196     }
197     isNeedMergeSet->Close();
198     bool isMerged = mergeMode && !IsNeedMerge(store, rawId);
199     return isMerged;
200 }
201 
JudgeDataDifferent(std::shared_ptr<OHOS::NativeRdb::RdbStore> store,std::vector<int> ids,int rawId)202 bool CandidateStatus::JudgeDataDifferent(
203     std::shared_ptr<OHOS::NativeRdb::RdbStore> store, std::vector<int> ids, int rawId)
204 {
205     std::shared_ptr<ContactsDataBase> contactsDataBase = ContactsDataBase::GetInstance();
206     MergeUtils mergeUtils;
207     int nameType = contactsDataBase->GetTypeId(ContentTypeData::NAME);
208     int phoneType = contactsDataBase->GetTypeId(ContentTypeData::PHONE);
209     std::set<std::string> names = mergeUtils.QueryRawContactByType(store, rawId, nameType);
210     std::set<std::string> phones = mergeUtils.QueryRawContactByType(store, rawId, phoneType);
211     unsigned int size = ids.size();
212     for (unsigned int i = 0; i < size; i++) {
213         MergeUtils mergeIdUtils;
214         std::set<std::string> idNames = mergeIdUtils.QueryRawContactByType(store, ids[i], nameType);
215         std::set<std::string> idPhones = mergeIdUtils.QueryRawContactByType(store, ids[i], phoneType);
216         if (names != idNames || phones != idPhones) {
217             HILOG_INFO("CandidateStatus::JudgeDataDifferent is true");
218             return true;
219         }
220     }
221     return false;
222 }
223 } // namespace Contacts
224 } // namespace OHOS
225