mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-06-18 05:21:24 -04:00
252 lines
8.6 KiB
C++
252 lines
8.6 KiB
C++
#include "ContactsTable.hpp"
|
|
#include <log/log.hpp>
|
|
|
|
namespace ColumnName
|
|
{
|
|
const uint8_t id = 0;
|
|
const uint8_t name_id = 1;
|
|
const uint8_t numbers_id = 2;
|
|
const uint8_t ring_id = 3;
|
|
const uint8_t address_id = 4;
|
|
const uint8_t type = 5;
|
|
const uint8_t speeddial = 6;
|
|
}; // namespace ColumnName
|
|
|
|
ContactsTable::ContactsTable(Database *db) : Table(db)
|
|
{}
|
|
|
|
ContactsTable::~ContactsTable()
|
|
{}
|
|
|
|
bool ContactsTable::create()
|
|
{
|
|
return db->execute(createTableQuery);
|
|
}
|
|
|
|
bool ContactsTable::add(ContactsTableRow entry)
|
|
{
|
|
return db->execute("insert or ignore into contacts (name_id, numbers_id, ring_id, address_id, type, speeddial) "
|
|
" VALUES (%lu, '%q', %lu, %lu, %lu, '%q');",
|
|
entry.nameID,
|
|
entry.numbersID.c_str(),
|
|
entry.ringID,
|
|
entry.addressID,
|
|
entry.type,
|
|
entry.speedDial.c_str());
|
|
}
|
|
|
|
bool ContactsTable::removeById(uint32_t id)
|
|
{
|
|
return db->execute("DELETE FROM contacts where _id = %u;", id);
|
|
}
|
|
|
|
bool ContactsTable::BlockByID(uint32_t id, bool shouldBeBlocked)
|
|
{
|
|
return db->execute("UPDATE contacts SET blacklist=%lu WHERE _id=%lu", shouldBeBlocked ? 1 : 0, id);
|
|
}
|
|
|
|
bool ContactsTable::update(ContactsTableRow entry)
|
|
{
|
|
return db->execute("UPDATE contacts SET name_id = %lu, numbers_id = '%q', ring_id = %lu, address_id = %lu, type "
|
|
" = %lu, speeddial = '%q' WHERE _id=%lu;",
|
|
entry.nameID,
|
|
entry.numbersID.c_str(),
|
|
entry.ringID,
|
|
entry.addressID,
|
|
entry.type,
|
|
entry.speedDial.c_str(),
|
|
entry.ID);
|
|
}
|
|
|
|
ContactsTableRow ContactsTable::getById(uint32_t id)
|
|
{
|
|
auto retQuery = db->query("SELECT * FROM contacts WHERE _id= %lu;", id);
|
|
|
|
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
|
|
return ContactsTableRow();
|
|
}
|
|
|
|
return ContactsTableRow{
|
|
(*retQuery)[ColumnName::id].getUInt32(),
|
|
(*retQuery)[ColumnName::name_id].getUInt32(),
|
|
(*retQuery)[ColumnName::numbers_id].getString(),
|
|
(*retQuery)[ColumnName::ring_id].getUInt32(),
|
|
(*retQuery)[ColumnName::address_id].getUInt32(),
|
|
static_cast<ContactType>((*retQuery)[ColumnName::type].getUInt32()),
|
|
(*retQuery)[ColumnName::speeddial].getString(),
|
|
};
|
|
}
|
|
|
|
std::vector<ContactsTableRow> ContactsTable::Search(const std::string &primaryName,
|
|
const std::string &alternativeName,
|
|
const std::string &number)
|
|
{
|
|
std::vector<ContactsTableRow> ret;
|
|
|
|
if (primaryName.empty() && alternativeName.empty() && number.empty()) {
|
|
return (ret);
|
|
}
|
|
|
|
std::string q = "select t1.*,t2.name_primary,t2.name_alternative from contacts t1 inner join contact_name "
|
|
"t2 "
|
|
"on t1._id=t2.contact_id inner join contact_number t3 on t1._id=t3.contact_id where ";
|
|
|
|
if (!primaryName.empty()) {
|
|
q += "t2.name_primary like '%%" + primaryName + "%%'";
|
|
if (!alternativeName.empty())
|
|
q += " or ";
|
|
}
|
|
|
|
if (!alternativeName.empty()) {
|
|
q += "t2.name_alternative like '%%" + alternativeName + "%%'";
|
|
if (!number.empty())
|
|
q += " or ";
|
|
}
|
|
|
|
if (!number.empty())
|
|
q += "t3.number_e164 like '%%" + number + "%%'";
|
|
|
|
LOG_DEBUG("query: \"%s\"", q.c_str());
|
|
auto retQuery = db->query(q.c_str());
|
|
|
|
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
|
|
return std::vector<ContactsTableRow>();
|
|
}
|
|
|
|
do {
|
|
ret.push_back(ContactsTableRow{
|
|
(*retQuery)[ColumnName::id].getUInt32(),
|
|
(*retQuery)[ColumnName::name_id].getUInt32(),
|
|
(*retQuery)[ColumnName::numbers_id].getString(),
|
|
(*retQuery)[ColumnName::ring_id].getUInt32(),
|
|
(*retQuery)[ColumnName::address_id].getUInt32(),
|
|
static_cast<ContactType>((*retQuery)[ColumnName::type].getUInt32()),
|
|
(*retQuery)[ColumnName::speeddial].getString(),
|
|
(*retQuery)[ColumnName::speeddial + 1].getString(), // primaryName
|
|
(*retQuery)[ColumnName::speeddial + 2].getString(), // alternativeName (WTF!)
|
|
});
|
|
} while (retQuery->nextRow());
|
|
|
|
return ret;
|
|
}
|
|
|
|
std::vector<std::uint32_t> ContactsTable::GetIDsByTextNumber(const std::string &filter,
|
|
std::size_t limit,
|
|
std::size_t offset)
|
|
{
|
|
std::vector<std::uint32_t> ids;
|
|
std::string query = "SELECT DISTINCT contacts._id"
|
|
" FROM contacts"
|
|
" INNER JOIN contact_name ON contacts._id == contact_name.contact_id"
|
|
" INNER JOIN contact_number ON contacts._id == contact_number.contact_id"
|
|
" WHERE contact_number.number_user LIKE '%%" +
|
|
filter +
|
|
"%%'"
|
|
" ORDER BY contacts.favourites DESC, name_alternative || ' ' || name_primary";
|
|
|
|
if (limit > 0) {
|
|
query += " LIMIT " + std::to_string(limit);
|
|
query += " OFFSET " + std::to_string(offset);
|
|
}
|
|
|
|
auto queryRet = db->query(query.c_str());
|
|
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
|
|
return ids;
|
|
}
|
|
|
|
do {
|
|
ids.push_back((*queryRet)[0].getUInt32());
|
|
} while (queryRet->nextRow());
|
|
|
|
return ids;
|
|
}
|
|
|
|
std::vector<ContactsTableRow> ContactsTable::getLimitOffset(uint32_t offset, uint32_t limit)
|
|
{
|
|
auto retQuery = db->query("SELECT * from contacts ORDER BY name_id LIMIT %lu OFFSET %lu;", limit, offset);
|
|
|
|
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
|
|
return std::vector<ContactsTableRow>();
|
|
}
|
|
|
|
std::vector<ContactsTableRow> ret;
|
|
|
|
do {
|
|
ret.push_back(ContactsTableRow{
|
|
(*retQuery)[ColumnName::id].getUInt32(), // ID
|
|
(*retQuery)[ColumnName::name_id].getUInt32(), // nameID
|
|
(*retQuery)[ColumnName::numbers_id].getString(), // numbersID
|
|
(*retQuery)[ColumnName::ring_id].getUInt32(), // ringID
|
|
(*retQuery)[ColumnName::address_id].getUInt32(), // addressID
|
|
static_cast<ContactType>((*retQuery)[ColumnName::type].getUInt32()), // type
|
|
(*retQuery)[ColumnName::speeddial].getString(), // speed dial key
|
|
});
|
|
} while (retQuery->nextRow());
|
|
|
|
return ret;
|
|
}
|
|
|
|
std::vector<ContactsTableRow> ContactsTable::getLimitOffsetByField(uint32_t offset,
|
|
uint32_t limit,
|
|
ContactTableFields field,
|
|
const char *str)
|
|
{
|
|
|
|
std::string fieldName;
|
|
switch (field) {
|
|
case ContactTableFields ::SpeedDial:
|
|
fieldName = "speeddial";
|
|
break;
|
|
default:
|
|
return std::vector<ContactsTableRow>();
|
|
}
|
|
|
|
auto retQuery = db->query("SELECT * from contacts WHERE %q='%q' ORDER BY name_id LIMIT %lu OFFSET %lu;",
|
|
fieldName.c_str(),
|
|
str,
|
|
limit,
|
|
offset);
|
|
|
|
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
|
|
return std::vector<ContactsTableRow>();
|
|
}
|
|
|
|
std::vector<ContactsTableRow> ret;
|
|
|
|
do {
|
|
ret.push_back(ContactsTableRow{
|
|
(*retQuery)[ColumnName::id].getUInt32(),
|
|
(*retQuery)[ColumnName::name_id].getUInt32(),
|
|
(*retQuery)[ColumnName::numbers_id].getString(),
|
|
(*retQuery)[ColumnName::ring_id].getUInt32(),
|
|
(*retQuery)[ColumnName::address_id].getUInt32(),
|
|
static_cast<ContactType>((*retQuery)[5].getUInt32()),
|
|
(*retQuery)[ColumnName::speeddial].getString(),
|
|
});
|
|
} while (retQuery->nextRow());
|
|
|
|
return ret;
|
|
}
|
|
|
|
uint32_t ContactsTable::count()
|
|
{
|
|
auto queryRet = db->query("SELECT COUNT(*) FROM contacts;");
|
|
|
|
if (queryRet->getRowCount() == 0) {
|
|
return 0;
|
|
}
|
|
|
|
return uint32_t{(*queryRet)[0].getUInt32()};
|
|
}
|
|
|
|
uint32_t ContactsTable::countByFieldId(const char *field, uint32_t id)
|
|
{
|
|
auto queryRet = db->query("SELECT COUNT(*) FROM contacts WHERE %q=%lu;", field, id);
|
|
|
|
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
|
|
return 0;
|
|
}
|
|
|
|
return uint32_t{(*queryRet)[0].getUInt32()};
|
|
}
|