1115cd2caSopenharmony_ci/*
2115cd2caSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3115cd2caSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4115cd2caSopenharmony_ci * you may not use this file except in compliance with the License.
5115cd2caSopenharmony_ci * You may obtain a copy of the License at
6115cd2caSopenharmony_ci *
7115cd2caSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8115cd2caSopenharmony_ci *
9115cd2caSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10115cd2caSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11115cd2caSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12115cd2caSopenharmony_ci * See the License for the specific language governing permissions and
13115cd2caSopenharmony_ci * limitations under the License.
14115cd2caSopenharmony_ci */
15115cd2caSopenharmony_ci
16115cd2caSopenharmony_ci#include "candidate_status.h"
17115cd2caSopenharmony_ci
18115cd2caSopenharmony_ci#include "common.h"
19115cd2caSopenharmony_ci#include "contacts_columns.h"
20115cd2caSopenharmony_ci#include "contacts_database.h"
21115cd2caSopenharmony_ci#include "hilog_wrapper.h"
22115cd2caSopenharmony_ci#include "merge_utils.h"
23115cd2caSopenharmony_ci
24115cd2caSopenharmony_cinamespace OHOS {
25115cd2caSopenharmony_cinamespace Contacts {
26115cd2caSopenharmony_ciCandidateStatus::CandidateStatus()
27115cd2caSopenharmony_ci{
28115cd2caSopenharmony_ci}
29115cd2caSopenharmony_ci
30115cd2caSopenharmony_ciCandidateStatus::~CandidateStatus()
31115cd2caSopenharmony_ci{
32115cd2caSopenharmony_ci}
33115cd2caSopenharmony_ci
34115cd2caSopenharmony_ci/**
35115cd2caSopenharmony_ci * @brief Query operation for merging candidates
36115cd2caSopenharmony_ci *
37115cd2caSopenharmony_ci * @param store Conditions for query operation
38115cd2caSopenharmony_ci * @param rawId Contacts's raw_contact_id to query
39115cd2caSopenharmony_ci *
40115cd2caSopenharmony_ci * @return Collection of canddidate contacts with the same raw_contact_id
41115cd2caSopenharmony_ci */
42115cd2caSopenharmony_ciCandidate CandidateStatus::QueryAllForMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
43115cd2caSopenharmony_ci{
44115cd2caSopenharmony_ci    Candidate candidate;
45115cd2caSopenharmony_ci    std::shared_ptr<ContactsDataBase> contactsDataBase = ContactsDataBase::GetInstance();
46115cd2caSopenharmony_ci    int nameType = contactsDataBase->GetTypeId(ContentTypeData::NAME);
47115cd2caSopenharmony_ci    int phoneType = contactsDataBase->GetTypeId(ContentTypeData::PHONE);
48115cd2caSopenharmony_ci    MergeUtils mergeUtils;
49115cd2caSopenharmony_ci    std::set<std::string> names = mergeUtils.QueryRawContactByType(store, rawId, nameType);
50115cd2caSopenharmony_ci    // query other name with the raw_contact_id
51115cd2caSopenharmony_ci    std::vector<int> nameIds = mergeUtils.QueryByDataName(rawId, names, store);
52115cd2caSopenharmony_ci    // query current phone
53115cd2caSopenharmony_ci    std::set<std::string> phones = mergeUtils.QueryRawContactByType(store, rawId, phoneType);
54115cd2caSopenharmony_ci    std::set<int> autoIds;
55115cd2caSopenharmony_ci    std::set<int> manualIds;
56115cd2caSopenharmony_ci    unsigned int size = nameIds.size();
57115cd2caSopenharmony_ci    for (unsigned int i = 0; i < size; i++) {
58115cd2caSopenharmony_ci        if (!IsNeedMerge(store, nameIds[i]) || !IsMergeStatus(store, nameIds[i])) {
59115cd2caSopenharmony_ci            continue;
60115cd2caSopenharmony_ci        }
61115cd2caSopenharmony_ci        std::set<std::string> otherPhones = mergeUtils.QueryRawContactByType(store, nameIds[i], phoneType);
62115cd2caSopenharmony_ci        if (phones.empty() && otherPhones.empty()) {
63115cd2caSopenharmony_ci            autoIds.insert(nameIds[i]);
64115cd2caSopenharmony_ci        }
65115cd2caSopenharmony_ci        if (phones.empty() || otherPhones.empty()) {
66115cd2caSopenharmony_ci            manualIds.insert(nameIds[i]);
67115cd2caSopenharmony_ci        }
68115cd2caSopenharmony_ci        if (mergeUtils.SetEqual(phones, otherPhones)) {
69115cd2caSopenharmony_ci            autoIds.insert(nameIds[i]);
70115cd2caSopenharmony_ci        } else {
71115cd2caSopenharmony_ci            manualIds.insert(nameIds[i]);
72115cd2caSopenharmony_ci        }
73115cd2caSopenharmony_ci    }
74115cd2caSopenharmony_ci    candidate.autoIds_ = autoIds;
75115cd2caSopenharmony_ci    candidate.manualIds_ = manualIds;
76115cd2caSopenharmony_ci    AddMergedStatus(candidate);
77115cd2caSopenharmony_ci    HILOG_INFO("QueryAllForMerge mode is : %{public}d ", candidate.mergeMode_);
78115cd2caSopenharmony_ci    candidate.autoIds_.insert(rawId);
79115cd2caSopenharmony_ci    candidate.manualIds_.insert(rawId);
80115cd2caSopenharmony_ci    HILOG_INFO("QueryAllForMerge size is : %{public}zu ", candidate.autoIds_.size());
81115cd2caSopenharmony_ci    HILOG_INFO("QueryAllForMerge candidate.manualIds_ is : %{public}zu ", candidate.manualIds_.size());
82115cd2caSopenharmony_ci    return candidate;
83115cd2caSopenharmony_ci}
84115cd2caSopenharmony_ci
85115cd2caSopenharmony_civoid CandidateStatus::AddMergedStatus(Candidate &candidate)
86115cd2caSopenharmony_ci{
87115cd2caSopenharmony_ci    if (!candidate.autoIds_.empty()) {
88115cd2caSopenharmony_ci        candidate.mergeMode_ = MERGE_MODE_AUTO;
89115cd2caSopenharmony_ci    } else if (!candidate.manualIds_.empty()) {
90115cd2caSopenharmony_ci        candidate.mergeMode_ = MERGE_MODE_MANUAL;
91115cd2caSopenharmony_ci    } else {
92115cd2caSopenharmony_ci        candidate.mergeMode_ = MERGE_MODE_DEFAULT;
93115cd2caSopenharmony_ci    }
94115cd2caSopenharmony_ci}
95115cd2caSopenharmony_ci
96115cd2caSopenharmony_ci/**
97115cd2caSopenharmony_ci * @brief Query operation for checking if candidate marging is needed
98115cd2caSopenharmony_ci *
99115cd2caSopenharmony_ci * @param store Conditions for query operation
100115cd2caSopenharmony_ci * @param rawId Contacts's raw_contact_id to query
101115cd2caSopenharmony_ci *
102115cd2caSopenharmony_ci * @return The result returned by the query operation
103115cd2caSopenharmony_ci */
104115cd2caSopenharmony_cibool CandidateStatus::IsNeedMerge(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
105115cd2caSopenharmony_ci{
106115cd2caSopenharmony_ci    std::string isNeedMergeSql = "SELECT ";
107115cd2caSopenharmony_ci    isNeedMergeSql.append(RawContactColumns::IS_NEED_MERGE)
108115cd2caSopenharmony_ci        .append(" FROM ")
109115cd2caSopenharmony_ci        .append(ContactTableName::RAW_CONTACT)
110115cd2caSopenharmony_ci        .append(" WHERE ")
111115cd2caSopenharmony_ci        .append(ContactPublicColumns::ID)
112115cd2caSopenharmony_ci        .append(" = ")
113115cd2caSopenharmony_ci        .append(std::to_string(rawId));
114115cd2caSopenharmony_ci    auto isNeedMergeSet = store->QuerySql(isNeedMergeSql);
115115cd2caSopenharmony_ci    bool isNeedMerge = false;
116115cd2caSopenharmony_ci    int resultSetNum = isNeedMergeSet->GoToFirstRow();
117115cd2caSopenharmony_ci    while (resultSetNum == OHOS::NativeRdb::E_OK) {
118115cd2caSopenharmony_ci        int value = 0;
119115cd2caSopenharmony_ci        isNeedMergeSet->GetInt(0, value);
120115cd2caSopenharmony_ci        if (value == 1) {
121115cd2caSopenharmony_ci            isNeedMerge = true;
122115cd2caSopenharmony_ci        } else {
123115cd2caSopenharmony_ci            isNeedMerge = false;
124115cd2caSopenharmony_ci        }
125115cd2caSopenharmony_ci        resultSetNum = isNeedMergeSet->GoToNextRow();
126115cd2caSopenharmony_ci    }
127115cd2caSopenharmony_ci    isNeedMergeSet->Close();
128115cd2caSopenharmony_ci    return isNeedMerge;
129115cd2caSopenharmony_ci}
130115cd2caSopenharmony_ci
131115cd2caSopenharmony_ci/**
132115cd2caSopenharmony_ci * @brief Check if the candidate has true merge_status
133115cd2caSopenharmony_ci *
134115cd2caSopenharmony_ci * @param store Conditions for query operation
135115cd2caSopenharmony_ci * @param rawId Contacts's raw_contact_id to query
136115cd2caSopenharmony_ci *
137115cd2caSopenharmony_ci * @return True if the candidate is in the merged status; flase otherwise
138115cd2caSopenharmony_ci */
139115cd2caSopenharmony_cibool CandidateStatus::IsMergeStatus(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
140115cd2caSopenharmony_ci{
141115cd2caSopenharmony_ci    std::string isMergeSwitchSql = "SELECT ";
142115cd2caSopenharmony_ci    isMergeSwitchSql.append(RawContactColumns::MERGE_STATUS)
143115cd2caSopenharmony_ci        .append(" FROM ")
144115cd2caSopenharmony_ci        .append(ContactTableName::RAW_CONTACT)
145115cd2caSopenharmony_ci        .append(" WHERE ")
146115cd2caSopenharmony_ci        .append(ContactPublicColumns::ID)
147115cd2caSopenharmony_ci        .append(" = ")
148115cd2caSopenharmony_ci        .append(std::to_string(rawId));
149115cd2caSopenharmony_ci    auto MergeSwitchSet = store->QuerySql(isMergeSwitchSql);
150115cd2caSopenharmony_ci    bool isMergeSwitch = false;
151115cd2caSopenharmony_ci    int resultSetNum = MergeSwitchSet->GoToFirstRow();
152115cd2caSopenharmony_ci    while (resultSetNum == OHOS::NativeRdb::E_OK) {
153115cd2caSopenharmony_ci        int value = 0;
154115cd2caSopenharmony_ci        MergeSwitchSet->GetInt(0, value);
155115cd2caSopenharmony_ci        if (value == 1) {
156115cd2caSopenharmony_ci            isMergeSwitch = true;
157115cd2caSopenharmony_ci        } else {
158115cd2caSopenharmony_ci            isMergeSwitch = false;
159115cd2caSopenharmony_ci        }
160115cd2caSopenharmony_ci        resultSetNum = MergeSwitchSet->GoToNextRow();
161115cd2caSopenharmony_ci    }
162115cd2caSopenharmony_ci    MergeSwitchSet->Close();
163115cd2caSopenharmony_ci    return isMergeSwitch;
164115cd2caSopenharmony_ci}
165115cd2caSopenharmony_ci
166115cd2caSopenharmony_ci/**
167115cd2caSopenharmony_ci * @brief Check if the candidate has been merged
168115cd2caSopenharmony_ci *
169115cd2caSopenharmony_ci * @param store Conditions for query operation
170115cd2caSopenharmony_ci * @param rawId Contacts's raw_contact_id to query
171115cd2caSopenharmony_ci *
172115cd2caSopenharmony_ci * @return True if the candidate has been merged; false otherwise
173115cd2caSopenharmony_ci */
174115cd2caSopenharmony_cibool CandidateStatus::IsMerged(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId)
175115cd2caSopenharmony_ci{
176115cd2caSopenharmony_ci    std::string isNeedMergeSql = "SELECT ";
177115cd2caSopenharmony_ci    isNeedMergeSql.append(RawContactColumns::MERGE_MODE)
178115cd2caSopenharmony_ci        .append(" FROM ")
179115cd2caSopenharmony_ci        .append(ContactTableName::RAW_CONTACT)
180115cd2caSopenharmony_ci        .append(" WHERE ")
181115cd2caSopenharmony_ci        .append(ContactPublicColumns::ID)
182115cd2caSopenharmony_ci        .append(" = ")
183115cd2caSopenharmony_ci        .append(std::to_string(rawId));
184115cd2caSopenharmony_ci    auto isNeedMergeSet = store->QuerySql(isNeedMergeSql);
185115cd2caSopenharmony_ci    bool mergeMode = false;
186115cd2caSopenharmony_ci    int resultSetNum = isNeedMergeSet->GoToFirstRow();
187115cd2caSopenharmony_ci    while (resultSetNum == OHOS::NativeRdb::E_OK) {
188115cd2caSopenharmony_ci        int value = 0;
189115cd2caSopenharmony_ci        isNeedMergeSet->GetInt(0, value);
190115cd2caSopenharmony_ci        if (value == 0) {
191115cd2caSopenharmony_ci            mergeMode = true;
192115cd2caSopenharmony_ci        } else {
193115cd2caSopenharmony_ci            mergeMode = false;
194115cd2caSopenharmony_ci        }
195115cd2caSopenharmony_ci        resultSetNum = isNeedMergeSet->GoToNextRow();
196115cd2caSopenharmony_ci    }
197115cd2caSopenharmony_ci    isNeedMergeSet->Close();
198115cd2caSopenharmony_ci    bool isMerged = mergeMode && !IsNeedMerge(store, rawId);
199115cd2caSopenharmony_ci    return isMerged;
200115cd2caSopenharmony_ci}
201115cd2caSopenharmony_ci
202115cd2caSopenharmony_cibool CandidateStatus::JudgeDataDifferent(
203115cd2caSopenharmony_ci    std::shared_ptr<OHOS::NativeRdb::RdbStore> store, std::vector<int> ids, int rawId)
204115cd2caSopenharmony_ci{
205115cd2caSopenharmony_ci    std::shared_ptr<ContactsDataBase> contactsDataBase = ContactsDataBase::GetInstance();
206115cd2caSopenharmony_ci    MergeUtils mergeUtils;
207115cd2caSopenharmony_ci    int nameType = contactsDataBase->GetTypeId(ContentTypeData::NAME);
208115cd2caSopenharmony_ci    int phoneType = contactsDataBase->GetTypeId(ContentTypeData::PHONE);
209115cd2caSopenharmony_ci    std::set<std::string> names = mergeUtils.QueryRawContactByType(store, rawId, nameType);
210115cd2caSopenharmony_ci    std::set<std::string> phones = mergeUtils.QueryRawContactByType(store, rawId, phoneType);
211115cd2caSopenharmony_ci    unsigned int size = ids.size();
212115cd2caSopenharmony_ci    for (unsigned int i = 0; i < size; i++) {
213115cd2caSopenharmony_ci        MergeUtils mergeIdUtils;
214115cd2caSopenharmony_ci        std::set<std::string> idNames = mergeIdUtils.QueryRawContactByType(store, ids[i], nameType);
215115cd2caSopenharmony_ci        std::set<std::string> idPhones = mergeIdUtils.QueryRawContactByType(store, ids[i], phoneType);
216115cd2caSopenharmony_ci        if (names != idNames || phones != idPhones) {
217115cd2caSopenharmony_ci            HILOG_INFO("CandidateStatus::JudgeDataDifferent is true");
218115cd2caSopenharmony_ci            return true;
219115cd2caSopenharmony_ci        }
220115cd2caSopenharmony_ci    }
221115cd2caSopenharmony_ci    return false;
222115cd2caSopenharmony_ci}
223115cd2caSopenharmony_ci} // namespace Contacts
224115cd2caSopenharmony_ci} // namespace OHOS
225