Skip to content

Commit 3ac4bd4

Browse files
Wojtek Rzepeckiwojtekrzepecki
Wojtek Rzepecki
authored andcommitted
[EGD-7127] Store imported contacts in DB
Added API for storing imported contacts list in phonebook database
1 parent 4ec11ba commit 3ac4bd4

12 files changed

+542
-0
lines changed

module-db/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ set(SOURCES
102102
queries/phonebook/QueryContactUpdate.cpp
103103
queries/phonebook/QueryContactRemove.cpp
104104
queries/phonebook/QueryNumberGetByID.cpp
105+
queries/phonebook/QueryMergeContactsList.cpp
106+
queries/phonebook/QueryCheckContactsListDuplicates.cpp
105107
queries/alarms/QueryAlarmsAdd.cpp
106108
queries/alarms/QueryAlarmsRemove.cpp
107109
queries/alarms/QueryAlarmsEdit.cpp

module-db/Interface/ContactRecord.cpp

+77
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "queries/phonebook/QueryContactGetByID.hpp"
77
#include "queries/phonebook/QueryContactUpdate.hpp"
88
#include "queries/phonebook/QueryContactRemove.hpp"
9+
#include "queries/phonebook/QueryMergeContactsList.hpp"
10+
#include "queries/phonebook/QueryCheckContactsListDuplicates.hpp"
911
#include <Utils.hpp>
1012

1113
#include <queries/phonebook/QueryContactGet.hpp>
@@ -159,6 +161,12 @@ auto ContactRecordInterface::runQuery(std::shared_ptr<db::Query> query) -> std::
159161
else if (typeid(*query) == typeid(db::query::NumberGetByID)) {
160162
return numberGetByIdQuery(query);
161163
}
164+
else if (typeid(*query) == typeid(db::query::MergeContactsList)) {
165+
return mergeContactsListQuery(query);
166+
}
167+
else if (typeid(*query) == typeid(db::query::CheckContactsListDuplicates)) {
168+
return checkContactsListDuplicatesQuery(query);
169+
}
162170
else {
163171
error_db_data("Unexpected query type.");
164172
return nullptr;
@@ -357,6 +365,26 @@ auto ContactRecordInterface::numberGetByIdQuery(std::shared_ptr<db::Query> query
357365
return response;
358366
}
359367

368+
auto ContactRecordInterface::mergeContactsListQuery(std::shared_ptr<db::Query> query)
369+
-> std::unique_ptr<db::QueryResult>
370+
{
371+
auto mergeQuery = static_cast<db::query::MergeContactsList *>(query.get());
372+
auto ret = ContactRecordInterface::MergeContactsList(mergeQuery->getContactsList());
373+
auto response = std::make_unique<db::query::MergeContactsListResult>(ret);
374+
response->setRequestQuery(query);
375+
return response;
376+
}
377+
378+
auto ContactRecordInterface::checkContactsListDuplicatesQuery(std::shared_ptr<db::Query> query)
379+
-> std::unique_ptr<db::QueryResult>
380+
{
381+
auto mergeQuery = static_cast<db::query::CheckContactsListDuplicates *>(query.get());
382+
auto response = std::make_unique<db::query::CheckContactsListDuplicatesResult>(
383+
std::move(ContactRecordInterface::CheckContactsListDuplicates(mergeQuery->getContactsList())));
384+
response->setRequestQuery(query);
385+
return response;
386+
}
387+
360388
auto ContactRecordInterface::splitNumberIDs(const std::string &numberIDs) -> std::vector<std::uint32_t>
361389
{
362390
std::stringstream source(numberIDs);
@@ -1172,3 +1200,52 @@ auto ContactRecordInterface::GetNumbersIdsByContact(std::uint32_t contactId) ->
11721200
}
11731201
return numbersIds;
11741202
}
1203+
1204+
auto ContactRecordInterface::MergeContactsList(std::vector<ContactRecord> &contacts) -> bool
1205+
{
1206+
std::vector<ContactNumberHolder> contactNumberHolders;
1207+
auto numberMatcher = buildNumberMatcher(contactNumberHolders);
1208+
1209+
for (auto &contact : contacts) {
1210+
// Important: Comparing only single number contacts
1211+
if (contact.numbers.size() > 1) {
1212+
LOG_WARN("Contact with multiple numbers detected - ignoring all numbers except first");
1213+
}
1214+
auto matchedNumber = numberMatcher.bestMatch(contact.numbers[0].number, utils::PhoneNumber::Match::POSSIBLE);
1215+
1216+
if (matchedNumber == numberMatcher.END) {
1217+
if (!Add(contact)) {
1218+
LOG_ERROR("Contacts list merge fail when adding the contact.");
1219+
return false;
1220+
}
1221+
}
1222+
else {
1223+
// Complete override of the contact data
1224+
contact.ID = matchedNumber->getContactID();
1225+
Update(contact);
1226+
// Rebuild number matcher
1227+
numberMatcher = buildNumberMatcher(contactNumberHolders);
1228+
}
1229+
}
1230+
return true;
1231+
}
1232+
1233+
auto ContactRecordInterface::CheckContactsListDuplicates(std::vector<ContactRecord> &contacts)
1234+
-> std::vector<ContactRecord>
1235+
{
1236+
std::vector<ContactRecord> duplicates;
1237+
std::vector<ContactNumberHolder> contactNumberHolders;
1238+
auto numberMatcher = buildNumberMatcher(contactNumberHolders);
1239+
1240+
for (auto &contact : contacts) {
1241+
// Important: Comparing only single number contacts
1242+
if (contact.numbers.size() > 1) {
1243+
LOG_WARN("Contact with multiple numbers detected - ignoring all numbers except first");
1244+
}
1245+
auto matchedNumber = numberMatcher.bestMatch(contact.numbers[0].number, utils::PhoneNumber::Match::POSSIBLE);
1246+
if (matchedNumber != numberMatcher.END) {
1247+
duplicates.push_back(contact);
1248+
}
1249+
}
1250+
return duplicates;
1251+
}

module-db/Interface/ContactRecord.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,22 @@ class ContactRecordInterface : public RecordInterface<ContactRecord, ContactReco
220220

221221
auto GetNumbersIdsByContact(std::uint32_t contactId) -> std::vector<std::uint32_t>;
222222

223+
/**
224+
* @brief Merge contacts list with overriding the duplicates in contacts DB
225+
*
226+
* @param contacts vector of contacts with single number
227+
* @return boolean status
228+
*/
229+
auto MergeContactsList(std::vector<ContactRecord> &contacts) -> bool;
230+
231+
/**
232+
* @brief Check which contacts in vector are duplicating contacts in DB
233+
*
234+
* @param contacts vector of contacts with single number
235+
* @return vector of contacts with numbers appearing in contacts DB
236+
*/
237+
auto CheckContactsListDuplicates(std::vector<ContactRecord> &contacts) -> std::vector<ContactRecord>;
238+
223239
private:
224240
ContactsDB *contactDB;
225241

@@ -248,4 +264,6 @@ class ContactRecordInterface : public RecordInterface<ContactRecord, ContactReco
248264
auto updateQuery(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
249265
auto removeQuery(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
250266
auto numberGetByIdQuery(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
267+
auto mergeContactsListQuery(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
268+
auto checkContactsListDuplicatesQuery(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
251269
};

module-db/doc/contacts_import.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Sequence of contacts import to contacts DB
2+
3+
![](contacts_import.svg)

module-db/doc/contacts_import.puml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@startuml
2+
3+
participant "Application" as app
4+
participant "ContactRecord" as rec
5+
participant "contacts DB" as db
6+
7+
== Checking for duplicates ==
8+
9+
app -> rec : contacts to check\n(query::CheckContactsListDuplicates)
10+
rec -> db : get numbers
11+
db -> rec
12+
rec -> rec : numbers comparison
13+
rec -> app : duplicated contacts
14+
15+
== Merging contacts list to DB ==
16+
17+
app -> rec : contacts to merge\n(query::MergeContactsList)
18+
rec -> db : get numbers
19+
db -> rec
20+
rec -> rec : numbers comparison
21+
22+
group number not found
23+
rec -> db : Add contact
24+
end
25+
group number found in db
26+
rec -> db : Update contact by overriding old data
27+
end
28+
rec -> app : status response
29+
30+
@enduml

module-db/doc/contacts_import.svg

+40
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
2+
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
3+
4+
#include "QueryCheckContactsListDuplicates.hpp"
5+
#include <string>
6+
7+
using namespace db::query;
8+
9+
CheckContactsListDuplicates::CheckContactsListDuplicates(std::vector<ContactRecord> contacts)
10+
: Query(Query::Type::Read), contacts(std::move(contacts))
11+
{}
12+
13+
std::vector<ContactRecord> &CheckContactsListDuplicates::getContactsList()
14+
{
15+
return contacts;
16+
}
17+
18+
[[nodiscard]] auto CheckContactsListDuplicates::debugInfo() const -> std::string
19+
{
20+
return "CheckContactsListDuplicates";
21+
}
22+
23+
CheckContactsListDuplicatesResult::CheckContactsListDuplicatesResult(std::vector<ContactRecord> duplicates)
24+
: duplicates(std::move(duplicates))
25+
{}
26+
27+
std::vector<ContactRecord> &CheckContactsListDuplicatesResult::getDuplicates()
28+
{
29+
return duplicates;
30+
}
31+
32+
[[nodiscard]] auto CheckContactsListDuplicatesResult::debugInfo() const -> std::string
33+
{
34+
return "CheckContactsListDuplicatesResult";
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
2+
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
3+
4+
#pragma once
5+
6+
#include "Common/Query.hpp"
7+
#include <queries/RecordQuery.hpp>
8+
#include <queries/Filter.hpp>
9+
#include <Interface/ContactRecord.hpp>
10+
11+
#include <string>
12+
13+
namespace db::query
14+
{
15+
16+
class CheckContactsListDuplicates : public Query
17+
{
18+
public:
19+
CheckContactsListDuplicates(std::vector<ContactRecord> contacts);
20+
[[nodiscard]] auto debugInfo() const -> std::string override;
21+
22+
std::vector<ContactRecord> &getContactsList();
23+
24+
private:
25+
std::vector<ContactRecord> contacts;
26+
};
27+
28+
class CheckContactsListDuplicatesResult : public QueryResult
29+
{
30+
public:
31+
CheckContactsListDuplicatesResult(std::vector<ContactRecord> duplicates);
32+
std::vector<ContactRecord> &getDuplicates();
33+
34+
[[nodiscard]] auto debugInfo() const -> std::string override;
35+
36+
private:
37+
std::vector<ContactRecord> duplicates;
38+
};
39+
40+
}; // namespace db::query

0 commit comments

Comments
 (0)