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 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> 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 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> 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 std::unique_ptr<OHOS::NativeRdb::AbsSharedResultSet> 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