From 2ae75a4b916b01b91a8e55bb005a6bbf7b23246f Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 20 Aug 2022 00:28:59 +0300 Subject: [PATCH] New object for cached database, also ClientInfo class --- core/account.cpp | 2 ++ core/squawk.h | 3 ++ core/storage/CMakeLists.txt | 2 ++ core/storage/cache.cpp | 69 +++++++++++++++++++++++++++++++++++++ core/storage/cache.h | 50 +++++++++++++++++++++++++++ core/storage/storage.cpp | 52 +++++++++++++++++++--------- core/storage/storage.h | 7 ++-- shared/CMakeLists.txt | 2 ++ shared/clientinfo.cpp | 69 +++++++++++++++++++++++++++++++++++++ shared/clientinfo.h | 50 +++++++++++++++++++++++++++ 10 files changed, 287 insertions(+), 19 deletions(-) create mode 100644 core/storage/cache.cpp create mode 100644 core/storage/cache.h create mode 100644 shared/clientinfo.cpp create mode 100644 shared/clientinfo.h diff --git a/core/account.cpp b/core/account.cpp index 3b9d7ec..0cb159d 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -93,6 +93,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& QObject::connect(reconnectTimer, &QTimer::timeout, this, &Account::onReconnectTimer); if (name == "Test") { + qDebug() << "Presence capabilities: " << presence.capabilityNode(); + QXmppLogger* logger = new QXmppLogger(this); logger->setLoggingType(QXmppLogger::SignalLogging); client.setLogger(logger); diff --git a/core/squawk.h b/core/squawk.h index c82b1c8..3b8073b 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -31,8 +31,10 @@ #include "shared/enums.h" #include "shared/message.h" #include "shared/global.h" +#include "shared/clientinfo.h" #include "networkaccess.h" #include "external/simpleCrypt/simplecrypt.h" +#include #ifdef WITH_KWALLET #include "passwordStorageEngines/kwallet.h" @@ -135,6 +137,7 @@ private: Shared::Availability state; NetworkAccess network; bool isInitialized; + //Cache clientCache; #ifdef WITH_KWALLET PSE::KWallet kwallet; diff --git a/core/storage/CMakeLists.txt b/core/storage/CMakeLists.txt index 4c263d5..5d34b7c 100644 --- a/core/storage/CMakeLists.txt +++ b/core/storage/CMakeLists.txt @@ -5,4 +5,6 @@ target_sources(squawk PRIVATE storage.h urlstorage.cpp urlstorage.h + cache.cpp + cache.h ) diff --git a/core/storage/cache.cpp b/core/storage/cache.cpp new file mode 100644 index 0000000..71fe369 --- /dev/null +++ b/core/storage/cache.cpp @@ -0,0 +1,69 @@ +// Squawk messenger. +// Copyright (C) 2019 Yury Gubich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "cache.h" + +#include + +template class Core::Cache; + +template +Core::Cache::Cache(const QString& name): + storage(name), + cache(new std::map ()) {} + +template +Core::Cache::~Cache() { + close(); + delete cache; +} + +template +void Core::Cache::open() { + storage.open();} + +template +void Core::Cache::close() { + storage.close();} + +template +void Core::Cache::addRecord(const QString& key, const T& value) { + storage.addRecord(key, value); + cache->insert(std::make_pair(key, value)); +} + +template +T Core::Cache::getRecord(const QString& key) const { + typename std::map::const_iterator itr = cache->find(key); + if (itr == cache->end()) { + T value = storage.getRecord(key); + itr = cache->insert(std::make_pair(key, value)).first; + } + + return itr->second; +} + +template +void Core::Cache::changeRecord(const QString& key, const T& value) { + storage.changeRecord(key, value); + cache->at(key) = value; +} + +template +void Core::Cache::removeRecord(const QString& key) { + storage.removeRecord(key); + cache->erase(key); +} diff --git a/core/storage/cache.h b/core/storage/cache.h new file mode 100644 index 0000000..e5b1b88 --- /dev/null +++ b/core/storage/cache.h @@ -0,0 +1,50 @@ +// Squawk messenger. +// Copyright (C) 2019 Yury Gubich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef CORE_CACHE_H +#define CORE_CACHE_H + +#include + +#include + +#include + +namespace Core { + +template +class Cache +{ +public: + Cache(const QString& name); + ~Cache(); + + void open(); + void close(); + + void addRecord(const QString& key, const T& value); + void changeRecord(const QString& key, const T& value); + void removeRecord(const QString& key); + T getRecord(const QString& key) const; + +private: + Core::Storage storage; + std::map* cache; +}; + +} + +#endif // CORE_CACHE_H diff --git a/core/storage/storage.cpp b/core/storage/storage.cpp index 7ff0ef7..99db8af 100644 --- a/core/storage/storage.cpp +++ b/core/storage/storage.cpp @@ -21,7 +21,12 @@ #include "storage.h" -Core::Storage::Storage(const QString& p_name): +#include + +template class Core::Storage; + +template +Core::Storage::Storage(const QString& p_name): name(p_name), opened(false), environment(), @@ -29,12 +34,14 @@ Core::Storage::Storage(const QString& p_name): { } -Core::Storage::~Storage() +template +Core::Storage::~Storage() { close(); } -void Core::Storage::open() +template +void Core::Storage::open() { if (!opened) { mdb_env_create(&environment); @@ -61,7 +68,8 @@ void Core::Storage::open() } } -void Core::Storage::close() +template +void Core::Storage::close() { if (opened) { mdb_dbi_close(environment, base); @@ -70,19 +78,22 @@ void Core::Storage::close() } } -void Core::Storage::addRecord(const QString& key, const QString& value) +template +void Core::Storage::addRecord(const QString& key, const T& value) { if (!opened) { throw Archive::Closed("addRecord", name.toStdString()); } + QByteArray ba; + QDataStream ds(&ba, QIODevice::WriteOnly); const std::string& id = key.toStdString(); - const std::string& val = value.toStdString(); + ds << value; MDB_val lmdbKey, lmdbData; lmdbKey.mv_size = id.size(); lmdbKey.mv_data = (char*)id.c_str(); - lmdbData.mv_size = val.size(); - lmdbData.mv_data = (char*)val.c_str(); + lmdbData.mv_size = ba.size(); + lmdbData.mv_data = (uint8_t*)ba.data(); MDB_txn *txn; mdb_txn_begin(environment, NULL, 0, &txn); int rc; @@ -99,19 +110,23 @@ void Core::Storage::addRecord(const QString& key, const QString& value) } } -void Core::Storage::changeRecord(const QString& key, const QString& value) +template +void Core::Storage::changeRecord(const QString& key, const T& value) { if (!opened) { throw Archive::Closed("changeRecord", name.toStdString()); } + + QByteArray ba; + QDataStream ds(&ba, QIODevice::WriteOnly); const std::string& id = key.toStdString(); - const std::string& val = value.toStdString(); + ds << value; MDB_val lmdbKey, lmdbData; lmdbKey.mv_size = id.size(); lmdbKey.mv_data = (char*)id.c_str(); - lmdbData.mv_size = val.size(); - lmdbData.mv_data = (char*)val.c_str(); + lmdbData.mv_size = ba.size(); + lmdbData.mv_data = (uint8_t*)ba.data(); MDB_txn *txn; mdb_txn_begin(environment, NULL, 0, &txn); int rc; @@ -126,7 +141,8 @@ void Core::Storage::changeRecord(const QString& key, const QString& value) } } -QString Core::Storage::getRecord(const QString& key) const +template +T Core::Storage::getRecord(const QString& key) const { if (!opened) { throw Archive::Closed("addElement", name.toStdString()); @@ -149,14 +165,18 @@ QString Core::Storage::getRecord(const QString& key) const throw Archive::Unknown(name.toStdString(), mdb_strerror(rc)); } } else { - std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size); - QString value(sId.c_str()); + QByteArray ba((char*)lmdbData.mv_data, lmdbData.mv_size); + QDataStream ds(&ba, QIODevice::ReadOnly); + T value; + ds >> value; mdb_txn_abort(txn); + return value; } } -void Core::Storage::removeRecord(const QString& key) +template +void Core::Storage::removeRecord(const QString& key) { if (!opened) { throw Archive::Closed("addElement", name.toStdString()); diff --git a/core/storage/storage.h b/core/storage/storage.h index d2abfde..5942c0f 100644 --- a/core/storage/storage.h +++ b/core/storage/storage.h @@ -29,6 +29,7 @@ namespace Core { /** * @todo write docs */ +template class Storage { public: @@ -38,10 +39,10 @@ public: void open(); void close(); - void addRecord(const QString& key, const QString& value); - void changeRecord(const QString& key, const QString& value); + void addRecord(const QString& key, const T& value); + void changeRecord(const QString& key, const T& value); void removeRecord(const QString& key); - QString getRecord(const QString& key) const; + T getRecord(const QString& key) const; private: diff --git a/shared/CMakeLists.txt b/shared/CMakeLists.txt index 0ab7dbd..1e47618 100644 --- a/shared/CMakeLists.txt +++ b/shared/CMakeLists.txt @@ -18,4 +18,6 @@ target_sources(squawk PRIVATE vcard.h pathcheck.cpp pathcheck.h + clientinfo.h + clientinfo.cpp ) diff --git a/shared/clientinfo.cpp b/shared/clientinfo.cpp new file mode 100644 index 0000000..745bd54 --- /dev/null +++ b/shared/clientinfo.cpp @@ -0,0 +1,69 @@ +// Squawk messenger. +// Copyright (C) 2019 Yury Gubich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "clientinfo.h" + +Shared::ClientInfo::ClientInfo(): + name(), + category(), + type(), + capabilitiesNode(), + capabilitiesVerification(), + capabilitiesHash(), + capabilitiesExtensions() {} + +QDataStream & Shared::ClientInfo::operator >> (QDataStream& stream) const { + stream << name; + stream << category; + stream << type; + stream << capabilitiesNode; + stream << capabilitiesVerification; + stream << capabilitiesHash; + stream << (quint8)capabilitiesExtensions.size(); + for (const QString& ext : capabilitiesExtensions) { + stream << ext; + } + + return stream; +} + +QDataStream & Shared::ClientInfo::operator << (QDataStream& stream) { + stream >> name; + stream >> category; + stream >> type; + stream >> capabilitiesNode; + stream >> capabilitiesVerification; + stream >> capabilitiesHash; + + quint8 size; + stream >> size; + for (quint8 i = 0; i < size; ++i) { + QString ext; + stream >> ext; + capabilitiesExtensions.insert(ext); + } + + return stream; +} + +QDataStream& operator<< (QDataStream& stream, const Shared::ClientInfo& image) { + image >> stream; + return stream; +} +QDataStream& operator>> (QDataStream& stream, Shared::ClientInfo& image) { + image << stream; + return stream; +} diff --git a/shared/clientinfo.h b/shared/clientinfo.h new file mode 100644 index 0000000..742e49a --- /dev/null +++ b/shared/clientinfo.h @@ -0,0 +1,50 @@ +// Squawk messenger. +// Copyright (C) 2019 Yury Gubich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SHARED_CLIENTINFO_H +#define SHARED_CLIENTINFO_H + +#include + +#include +#include + +namespace Shared { + +class ClientInfo +{ +public: + ClientInfo(); + + QDataStream& operator << (QDataStream& stream); + QDataStream& operator >> (QDataStream& stream) const; + +public: + QString name; + QString category; + QString type; + QString capabilitiesNode; + QString capabilitiesVerification; + QString capabilitiesHash; + std::set capabilitiesExtensions; +}; + +} + +QDataStream& operator<< (QDataStream& stream, const Shared::ClientInfo& image); +QDataStream& operator>> (QDataStream& stream, Shared::ClientInfo& image); + +#endif // SHARED_CLIENTINFO_H