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 
21 namespace OHOS {
22 namespace Contacts {
MergeUtils(void)23 MergeUtils::MergeUtils(void)
24 {
25 }
26 
~MergeUtils()27 MergeUtils::~MergeUtils()
28 {
29 }
30 
QueryRawContactByType( std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId, int typeId)31 std::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 
QueryDataExecute( std::shared_ptr<OHOS::NativeRdb::RdbStore> store, std::set<int> rawIds, int typeId)63 std::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 
QueryByDataName( int rawId, std::set<std::string> data, std::shared_ptr<OHOS::NativeRdb::RdbStore> store)103 std::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 
SetEqual(std::set<std::string> setLeft, std::set<std::string> setRight)138 bool 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 
AddHasJudgeForRawId( std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId, OHOS::NativeRdb::ValuesBucket &values)151 void 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 
GetRawIdsByRawId(std::shared_ptr<OHOS::NativeRdb::RdbStore> store, int rawId, std::set<int> &rawIds)196 void 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