mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-04 03:48:46 -05:00
When thread record is modified during connection with Mudita Center, notification of that action should be collected in outbox endpoint to keep contacts data synchronized between MuditaOS and Mudita Center.
298 lines
11 KiB
C++
298 lines
11 KiB
C++
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "ThreadRecord.hpp"
|
|
#include "SMSRecord.hpp"
|
|
#include "ContactRecord.hpp"
|
|
|
|
#include <queries/messages/threads/QueryThreadGetByID.hpp>
|
|
#include <queries/messages/threads/QueryThreadGetByNumber.hpp>
|
|
#include <queries/messages/threads/QueryThreadRemove.hpp>
|
|
#include <queries/messages/threads/QueryThreadsGet.hpp>
|
|
#include <queries/messages/threads/QueryThreadsGetForList.hpp>
|
|
#include <queries/messages/threads/QueryThreadsSearchForList.hpp>
|
|
#include <queries/messages/threads/QueryThreadsGetCount.hpp>
|
|
|
|
#include <cassert>
|
|
#include <log/log.hpp>
|
|
|
|
ThreadRecordInterface::ThreadRecordInterface(SmsDB *smsDb, ContactsDB *contactsDb)
|
|
: smsDB(smsDb), contactsDB(contactsDb)
|
|
{}
|
|
|
|
bool ThreadRecordInterface::Add(const ThreadRecord &rec)
|
|
{
|
|
auto result = smsDB->threads.add(ThreadsTableRow{Record(rec.ID),
|
|
.date = rec.date,
|
|
.msgCount = rec.msgCount,
|
|
.unreadMsgCount = rec.unreadMsgCount,
|
|
.numberID = rec.numberID,
|
|
.snippet = rec.snippet,
|
|
.type = rec.type});
|
|
|
|
return result;
|
|
}
|
|
|
|
bool ThreadRecordInterface::RemoveByID(uint32_t id)
|
|
{
|
|
auto result = smsDB->threads.removeById(id);
|
|
if (!result) {
|
|
return false;
|
|
}
|
|
|
|
SMSRecordInterface smsRecordInterface(smsDB, contactsDB);
|
|
return smsRecordInterface.RemoveByField(SMSRecordField::ThreadID, std::to_string(id).c_str());
|
|
}
|
|
|
|
bool ThreadRecordInterface::Update(const ThreadRecord &rec)
|
|
{
|
|
return smsDB->threads.update(ThreadsTableRow{Record(rec.ID),
|
|
.date = rec.date,
|
|
.msgCount = rec.msgCount,
|
|
.unreadMsgCount = rec.unreadMsgCount,
|
|
.numberID = rec.numberID,
|
|
.snippet = rec.snippet,
|
|
.type = rec.type
|
|
|
|
});
|
|
}
|
|
|
|
uint32_t ThreadRecordInterface::GetCount()
|
|
{
|
|
return smsDB->threads.count();
|
|
}
|
|
|
|
uint32_t ThreadRecordInterface::GetCount(EntryState state)
|
|
{
|
|
return smsDB->threads.count(state);
|
|
}
|
|
|
|
std::unique_ptr<std::vector<ThreadRecord>> ThreadRecordInterface::GetLimitOffset(uint32_t offset, uint32_t limit)
|
|
{
|
|
auto records = std::make_unique<std::vector<ThreadRecord>>();
|
|
|
|
auto result = smsDB->threads.getLimitOffset(offset, limit);
|
|
|
|
for (const auto &w : result) {
|
|
records->push_back(w);
|
|
}
|
|
|
|
return records;
|
|
}
|
|
|
|
std::unique_ptr<std::vector<ThreadRecord>> ThreadRecordInterface::GetLimitOffsetByField(uint32_t offset,
|
|
uint32_t limit,
|
|
ThreadRecordField field,
|
|
const char *str)
|
|
{
|
|
auto records = std::make_unique<std::vector<ThreadRecord>>();
|
|
|
|
ThreadsTableFields threadsField = ThreadsTableFields();
|
|
switch (field) {
|
|
case ThreadRecordField::NumberID: {
|
|
threadsField = ThreadsTableFields::NumberID;
|
|
} break;
|
|
default:
|
|
LOG_ERROR("Invalid field type %u", static_cast<unsigned>(field));
|
|
return records;
|
|
}
|
|
|
|
auto result = smsDB->threads.getLimitOffsetByField(offset, limit, threadsField, str);
|
|
for (const auto &w : result) {
|
|
records->push_back(w);
|
|
}
|
|
|
|
return records;
|
|
}
|
|
|
|
ThreadRecord ThreadRecordInterface::GetByID(uint32_t id)
|
|
{
|
|
auto rec = smsDB->threads.getById(id);
|
|
if (!rec.isValid()) {
|
|
return ThreadRecord();
|
|
}
|
|
|
|
return ThreadRecord(rec);
|
|
}
|
|
|
|
ThreadRecord ThreadRecordInterface::GetByNumber(const utils::PhoneNumber::View &phoneNumber)
|
|
{
|
|
auto contactInterface = ContactRecordInterface(contactsDB);
|
|
auto match = contactInterface.MatchByNumber(phoneNumber);
|
|
|
|
if (!match.has_value()) {
|
|
return ThreadRecord();
|
|
}
|
|
|
|
auto threadRec = GetLimitOffsetByField(0, 1, ThreadRecordField::NumberID, std::to_string(match->numberId).c_str());
|
|
|
|
if (threadRec->size() == 0) {
|
|
return ThreadRecord();
|
|
}
|
|
|
|
return threadRec->at(0);
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::runQuery(std::shared_ptr<db::Query> query)
|
|
{
|
|
if (typeid(*query) == typeid(db::query::ThreadsSearchForList)) {
|
|
return threadSearchForListQuery(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::MarkAsRead)) {
|
|
return markAsReadQuery(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::ThreadsGet)) {
|
|
return threadsGetQuery(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::ThreadsGetWithTotalCount)) {
|
|
return threadsGetQueryWithTotalCount(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::ThreadsGetForList)) {
|
|
return threadsGetForListQuery(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::ThreadGetByID)) {
|
|
return threadGetByIDQuery(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::ThreadGetByNumber)) {
|
|
return threadGetByNumberQuery(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::ThreadRemove)) {
|
|
return threadRemoveQuery(query);
|
|
}
|
|
else if (typeid(*query) == typeid(db::query::ThreadGetCount)) {
|
|
return threadsGetCount(query);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadSearchForListQuery(
|
|
const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::ThreadsSearchForList *>(query.get());
|
|
auto dbResult = smsDB->threads.getBySMSQuery(localQuery->textToSearch, localQuery->offset, localQuery->limit);
|
|
|
|
auto records = std::vector<ThreadRecord>(dbResult.second.begin(), dbResult.second.end());
|
|
auto count = dbResult.first;
|
|
|
|
std::vector<ContactRecord> contacts;
|
|
|
|
auto contactDb = ContactRecordInterface(contactsDB);
|
|
for (const auto &record : records) {
|
|
if (auto contact = contactDb.GetByNumberID(record.numberID); contact.has_value()) {
|
|
contacts.push_back(contact.value());
|
|
}
|
|
}
|
|
|
|
auto response = std::make_unique<db::query::ThreadsSearchResultForList>(records, contacts, count);
|
|
response->setRequestQuery(query);
|
|
return response;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::markAsReadQuery(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::MarkAsRead *>(query.get());
|
|
auto record = GetByID(localQuery->id);
|
|
auto result = false;
|
|
|
|
if (record.isValid()) {
|
|
LOG_DEBUG("query-read %d", static_cast<int>(localQuery->read));
|
|
record.unreadMsgCount = localQuery->read == db::query::MarkAsRead::Read::True ? 0 : 1;
|
|
result = Update(record);
|
|
}
|
|
|
|
auto response = std::make_unique<db::query::MarkAsReadResult>(result);
|
|
response->setRequestQuery(query);
|
|
response->setRecordID(localQuery->id);
|
|
return response;
|
|
}
|
|
|
|
std::vector<ThreadRecord> ThreadRecordInterface::getThreads(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::ThreadsGet *>(query.get());
|
|
auto dbResult = smsDB->threads.getLimitOffset(localQuery->offset, localQuery->limit);
|
|
return std::vector<ThreadRecord>(dbResult.begin(), dbResult.end());
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadsGetQuery(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
auto response = std::make_unique<db::query::ThreadsGetResults>(std::move(getThreads(query)));
|
|
response->setRequestQuery(query);
|
|
return response;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadsGetQueryWithTotalCount(
|
|
const std::shared_ptr<db::Query> &query)
|
|
{
|
|
auto count = smsDB->threads.count();
|
|
auto response = std::make_unique<db::query::ThreadsGetResultsWithTotalCount>(std::move(getThreads(query)), count);
|
|
response->setRequestQuery(query);
|
|
return response;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadsGetForListQuery(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::ThreadsGetForList *>(query.get());
|
|
|
|
auto dbResult = smsDB->threads.getLimitOffset(localQuery->offset, localQuery->limit);
|
|
auto records = std::vector<ThreadRecord>(dbResult.begin(), dbResult.end());
|
|
|
|
std::vector<ContactRecord> contacts;
|
|
std::vector<utils::PhoneNumber::View> numbers;
|
|
|
|
auto contactDb = ContactRecordInterface(contactsDB);
|
|
for (const auto &record : records) {
|
|
if (auto contact = contactDb.GetByNumberID(record.numberID); contact.has_value()) {
|
|
contacts.push_back(contact.value());
|
|
}
|
|
numbers.push_back(contactDb.GetNumberById(record.numberID));
|
|
}
|
|
|
|
auto count = smsDB->threads.count();
|
|
|
|
auto response = std::make_unique<db::query::ThreadsGetForListResults>(records, contacts, numbers, count);
|
|
response->setRequestQuery(query);
|
|
return response;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadGetByIDQuery(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::ThreadGetByID *>(query.get());
|
|
|
|
const auto ret = GetByID(localQuery->id);
|
|
auto response = std::make_unique<db::query::ThreadGetByIDResult>(ret.isValid() ? std::optional<ThreadRecord>{ret}
|
|
: std::nullopt);
|
|
response->setRequestQuery(query);
|
|
return response;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadGetByNumberQuery(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::ThreadGetByNumber *>(query.get());
|
|
|
|
auto response = std::make_unique<db::query::ThreadGetByNumberResult>(GetByNumber(localQuery->getNumber()));
|
|
response->setRequestQuery(query);
|
|
return response;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadRemoveQuery(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::ThreadRemove *>(query.get());
|
|
|
|
const auto result = RemoveByID(localQuery->id);
|
|
auto response = std::make_unique<db::query::ThreadRemoveResult>(result);
|
|
response->setRequestQuery(query);
|
|
response->setRecordID(localQuery->id);
|
|
return response;
|
|
}
|
|
|
|
std::unique_ptr<db::QueryResult> ThreadRecordInterface::threadsGetCount(const std::shared_ptr<db::Query> &query)
|
|
{
|
|
const auto localQuery = static_cast<const db::query::ThreadGetCount *>(query.get());
|
|
|
|
auto count = GetCount(localQuery->getState());
|
|
auto response = std::make_unique<db::query::ThreadGetCountResult>(localQuery->getState(), count);
|
|
response->setRequestQuery(query);
|
|
return response;
|
|
}
|