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 "merge_utils.h"
17
18#include "contacts_columns.h"
19#include "contacts_database.h"
20
21namespace OHOS {
22namespace Contacts {
23MergeUtils::MergeUtils(void)
24{
25}
26
27MergeUtils::~MergeUtils()
28{
29}
30
31std::set<std::string> MergeUtils::QueryRawContactByType(
32    std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId, int typeId)
33{
34    std::string sql = "SELECT ";
35    sql.append(ContactPublicColumns::ID)
36        .append(" FROM ")
37        .append(ContactTableName::RAW_CONTACT)
38        .append(" WHERE ")
39        .append(RawContactColumns::CONTACT_ID)
40        .append(" = (SELECT ")
41        .append(RawContactColumns::CONTACT_ID)
42        .append(" FROM ")
43        .append(ContactTableName::RAW_CONTACT)
44        .append(" WHERE ")
45        .append(ContactPublicColumns::ID)
46        .append(" = ?")
47        .append(" AND is_deleted = 0 )");
48    std::vector<std::string> selectionArgs;
49    selectionArgs.push_back(std::to_string(rawId));
50    auto rawIdsSet = store->QuerySql(sql, selectionArgs);
51    std::set<int> rawIds;
52    int resultSetNum = rawIdsSet->GoToFirstRow();
53    while (resultSetNum == OHOS::NativeRdb::E_OK) {
54        int value = 0;
55        rawIdsSet->GetInt(0, value);
56        rawIds.insert(value);
57        resultSetNum = rawIdsSet->GoToNextRow();
58    }
59    rawIdsSet->Close();
60    return QueryDataExecute(store, rawIds, typeId);
61}
62
63std::set<std::string> MergeUtils::QueryDataExecute(
64    std::shared_ptr<OHOS::NativeRdb::RdbStore> store, std::set<int> rawIds, int typeId)
65{
66    std::set<std::string> result;
67    unsigned int size = rawIds.size();
68    if (size < 1) {
69        return result;
70    }
71    std::string query = "SELECT ";
72    query.append(ContactDataColumns::DETAIL_INFO)
73        .append(" FROM ")
74        .append(ContactTableName::CONTACT_DATA)
75        .append(" WHERE ");
76    for (auto rawId = rawIds.begin(); rawId != rawIds.end(); ++rawId) {
77        query.append(ContactDataColumns::RAW_CONTACT_ID)
78            .append(" = ")
79            .append(std::to_string(*rawId))
80            .append(" AND ")
81            .append(ContactDataColumns::TYPE_ID)
82            .append(" = ? ");
83        if (*rawId != *rawIds.rbegin()) {
84            query.append(" OR ");
85        }
86    }
87    std::vector<std::string> selectionArgs;
88    selectionArgs.push_back(std::to_string(typeId));
89    auto resultSet = store->QuerySql(query, selectionArgs);
90    int resultSetNum = resultSet->GoToFirstRow();
91    while (resultSetNum == OHOS::NativeRdb::E_OK) {
92        std::string value;
93        resultSet->GetString(0, value);
94        if (!value.empty()) {
95            result.insert(value);
96        }
97        resultSetNum = resultSet->GoToNextRow();
98    }
99    resultSet->Close();
100    return result;
101}
102
103std::vector<int> MergeUtils::QueryByDataName(
104    int rawId, std::set<std::string> data, std::shared_ptr<OHOS::NativeRdb::RdbStore> store)
105{
106    std::vector<int> ids;
107    std::shared_ptr<ContactsDataBase> contactsDataBase = ContactsDataBase::GetInstance();
108    int nameType = contactsDataBase->GetTypeId(ContentTypeData::NAME);
109    for (auto it = data.begin(); it != data.end(); it++) {
110        std::string query = "SELECT ";
111        query.append(ContactDataColumns::RAW_CONTACT_ID)
112            .append(" FROM ")
113            .append(ViewName::VIEW_CONTACT_DATA)
114            .append(" WHERE ")
115            .append(ContactDataColumns::DETAIL_INFO)
116            .append(" = '")
117            .append(*it)
118            .append("' AND ")
119            .append(ContactDataColumns::TYPE_ID)
120            .append(" = ")
121            .append(std::to_string(nameType))
122            .append(" AND is_deleted = 0");
123        auto resultSet = store->QuerySql(query);
124        int resultSetNum = resultSet->GoToFirstRow();
125        while (resultSetNum == OHOS::NativeRdb::E_OK) {
126            int value = 0;
127            resultSet->GetInt(0, value);
128            if (value != rawId) {
129                ids.push_back(value);
130            }
131            resultSetNum = resultSet->GoToNextRow();
132        }
133        resultSet->Close();
134    }
135    return ids;
136}
137
138bool MergeUtils::SetEqual(std::set<std::string> setLeft, std::set<std::string> setRight)
139{
140    if (setLeft.size() != setRight.size()) {
141        return false;
142    }
143    std::map<std::set<std::string>, std::string> mTemp;
144    mTemp[setLeft] = "1";
145    if (mTemp.find(setRight) == mTemp.end()) {
146        return false;
147    }
148    return true;
149}
150
151void MergeUtils::AddHasJudgeForRawId(
152    std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId, OHOS::NativeRdb::ValuesBucket &values)
153{
154    std::shared_ptr<ContactsDataBase> contactsDataBase = ContactsDataBase::GetInstance();
155    int nameType = contactsDataBase->GetTypeId(ContentTypeData::NAME);
156    int phoneType = contactsDataBase->GetTypeId(ContentTypeData::PHONE);
157    int emailType = contactsDataBase->GetTypeId(ContentTypeData::EMAIL);
158    int groupType = contactsDataBase->GetTypeId(ContentTypeData::GROUP_MEMBERSHIP);
159    std::vector<int> types;
160    types.push_back(nameType);
161    types.push_back(phoneType);
162    types.push_back(emailType);
163    types.push_back(groupType);
164    unsigned int size = types.size();
165    for (unsigned int i = 0; i < size; i++) {
166        std::string sql = "SELECT 1 FROM contact_data WHERE type_id = " + std::to_string(types[i]);
167        sql.append(" AND raw_contact_id = " + std::to_string(rawId)).append(" LIMIT 1");
168        auto resultSet = store->QuerySql(sql);
169        int resultSetNum = resultSet->GoToFirstRow();
170        if (resultSetNum == 0) {
171            switch (i) {
172                case HAS_NAME:
173                    values.Delete(ContactColumns::HAS_DISPLAY_NAME);
174                    values.PutInt(ContactColumns::HAS_DISPLAY_NAME, 1);
175                    break;
176                case HAS_PHONE:
177                    values.Delete(ContactColumns::HAS_PHONE_NUMBER);
178                    values.PutInt(ContactColumns::HAS_PHONE_NUMBER, 1);
179                    break;
180                case HAS_EMAIL:
181                    values.Delete(ContactColumns::HAS_EMAIL);
182                    values.PutInt(ContactColumns::HAS_EMAIL, 1);
183                    break;
184                case HAS_GROUP:
185                    values.Delete(ContactColumns::HAS_GROUP);
186                    values.PutInt(ContactColumns::HAS_GROUP, 1);
187                    break;
188                default:
189                    HILOG_ERROR("AddHasJudge switch code error");
190                    break;
191            }
192        }
193    }
194}
195
196void MergeUtils::GetRawIdsByRawId(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId, std::set<int> &rawIds)
197{
198    std::string queryMergeId = "SELECT ";
199    queryMergeId.append(ContactPublicColumns::ID)
200        .append(" FROM ")
201        .append(ContactTableName::RAW_CONTACT)
202        .append(" WHERE ")
203        .append(RawContactColumns::CONTACT_ID)
204        .append(" = ")
205        .append(" (SELECT ")
206        .append(RawContactColumns::CONTACT_ID)
207        .append(" FROM ")
208        .append(ContactTableName::RAW_CONTACT)
209        .append(" WHERE ")
210        .append(ContactPublicColumns::ID)
211        .append(" = ? ")
212        .append(" ) AND is_deleted = 0");
213    std::vector<std::string> selectionArgs;
214    selectionArgs.push_back(std::to_string(rawId));
215    auto rawIdsSet = store->QuerySql(queryMergeId, selectionArgs);
216    int resultSetNum = rawIdsSet->GoToFirstRow();
217    while (resultSetNum == OHOS::NativeRdb::E_OK) {
218        int value = 0;
219        rawIdsSet->GetInt(0, value);
220        if (value != rawId) {
221            rawIds.insert(value);
222        }
223        resultSetNum = rawIdsSet->GoToNextRow();
224    }
225    rawIdsSet->Close();
226}
227} // namespace Contacts
228} // namespace OHOS