transitioned urlstorage to LMDBAL, made it possible to build against latest qxmpp
This commit is contained in:
parent
81cf0f8d34
commit
5fbb03fc46
10 changed files with 363 additions and 599 deletions
289
core/components/urlstorage.cpp
Normal file
289
core/components/urlstorage.cpp
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* Squawk messenger.
|
||||
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
|
||||
#include "urlstorage.h"
|
||||
|
||||
Core::UrlStorage::UrlStorage(const QString& p_name):
|
||||
base(p_name),
|
||||
urlToInfo(base.addStorage<QString, UrlInfo>("urlToInfo")),
|
||||
pathToUrl(base.addStorage<QString, QString>("pathToUrl"))
|
||||
{}
|
||||
|
||||
Core::UrlStorage::~UrlStorage() {
|
||||
close();
|
||||
}
|
||||
|
||||
void Core::UrlStorage::open() {
|
||||
base.open();
|
||||
}
|
||||
|
||||
void Core::UrlStorage::close() {
|
||||
base.close();
|
||||
}
|
||||
|
||||
void Core::UrlStorage::writeInfo(const QString& key, const Core::UrlStorage::UrlInfo& info, bool overwrite) {
|
||||
LMDBAL::TransactionID txn = base.beginTransaction();
|
||||
|
||||
try {
|
||||
writeInfo(key, info, txn, overwrite);
|
||||
base.commitTransaction(txn);
|
||||
} catch (...) {
|
||||
base.abortTransaction(txn);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::UrlStorage::writeInfo(const QString& key, const Core::UrlStorage::UrlInfo& info, MDB_txn* txn, bool overwrite) {
|
||||
if (overwrite)
|
||||
urlToInfo->forceRecord(key, info, txn);
|
||||
else
|
||||
urlToInfo->addRecord(key, info, txn);
|
||||
|
||||
if (info.hasPath())
|
||||
pathToUrl->forceRecord(info.getPath(), key, txn);
|
||||
}
|
||||
|
||||
void Core::UrlStorage::addFile(const QString& url) {
|
||||
addToInfo(url, "", "", "");
|
||||
}
|
||||
|
||||
void Core::UrlStorage::addFile(const QString& url, const QString& path) {
|
||||
addToInfo(url, "", "", "", path);
|
||||
}
|
||||
|
||||
void Core::UrlStorage::addFile(const QString& url, const QString& account, const QString& jid, const QString& id) {
|
||||
addToInfo(url, account, jid, id);
|
||||
}
|
||||
|
||||
void Core::UrlStorage::addFile(const QString& url, const QString& path, const QString& account, const QString& jid, const QString& id) {
|
||||
addToInfo(url, account, jid, id, path);
|
||||
}
|
||||
|
||||
void Core::UrlStorage::addFile(const std::list<Shared::MessageInfo>& msgs, const QString& url, const QString& path) {
|
||||
UrlInfo info (path, msgs);
|
||||
writeInfo(url, info, true);
|
||||
}
|
||||
|
||||
QString Core::UrlStorage::addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id){
|
||||
return addToInfo(url, account, jid, id).getPath();
|
||||
}
|
||||
|
||||
Core::UrlStorage::UrlInfo Core::UrlStorage::addToInfo(
|
||||
const QString& url,
|
||||
const QString& account,
|
||||
const QString& jid,
|
||||
const QString& id,
|
||||
const QString& path
|
||||
) {
|
||||
UrlInfo info;
|
||||
LMDBAL::TransactionID txn = base.beginTransaction();
|
||||
|
||||
try {
|
||||
urlToInfo->getRecord(url, info, txn);
|
||||
} catch (const LMDBAL::NotFound& e) {
|
||||
} catch (...) {
|
||||
base.abortTransaction(txn);
|
||||
throw;
|
||||
}
|
||||
|
||||
bool pathChange = false;
|
||||
bool listChange = false;
|
||||
if (path != "-s") {
|
||||
if (info.getPath() != path) {
|
||||
info.setPath(path);
|
||||
pathChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (account.size() > 0 && jid.size() > 0 && id.size() > 0)
|
||||
listChange = info.addMessage(account, jid, id);
|
||||
|
||||
if (pathChange || listChange) {
|
||||
try {
|
||||
writeInfo(url, info, txn, true);
|
||||
base.commitTransaction(txn);
|
||||
} catch (...) {
|
||||
base.abortTransaction(txn);
|
||||
throw;
|
||||
}
|
||||
} else {
|
||||
base.abortTransaction(txn);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
std::list<Shared::MessageInfo> Core::UrlStorage::setPath(const QString& url, const QString& path) {
|
||||
std::list<Shared::MessageInfo> list;
|
||||
LMDBAL::TransactionID txn = base.beginTransaction();
|
||||
UrlInfo info;
|
||||
|
||||
try {
|
||||
urlToInfo->getRecord(url, info, txn);
|
||||
info.getMessages(list);
|
||||
} catch (const LMDBAL::NotFound& e) {
|
||||
} catch (...) {
|
||||
base.abortTransaction(txn);
|
||||
throw;
|
||||
}
|
||||
|
||||
info.setPath(path);
|
||||
try {
|
||||
writeInfo(url, info, txn, true);
|
||||
base.commitTransaction(txn);
|
||||
} catch (...) {
|
||||
base.abortTransaction(txn);
|
||||
throw;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::list<Shared::MessageInfo> Core::UrlStorage::removeFile(const QString& url) {
|
||||
std::list<Shared::MessageInfo> list;
|
||||
LMDBAL::TransactionID txn = base.beginTransaction();
|
||||
UrlInfo info;
|
||||
|
||||
try {
|
||||
urlToInfo->getRecord(url, info, txn);
|
||||
urlToInfo->removeRecord(url);
|
||||
info.getMessages(list);
|
||||
|
||||
if (info.hasPath())
|
||||
pathToUrl->removeRecord(info.getPath());
|
||||
|
||||
base.commitTransaction(txn);
|
||||
} catch (...) {
|
||||
base.abortTransaction(txn);
|
||||
throw;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::list<Shared::MessageInfo> Core::UrlStorage::deletedFile(const QString& path) {
|
||||
std::list<Shared::MessageInfo> list;
|
||||
LMDBAL::TransactionID txn = base.beginTransaction();
|
||||
|
||||
try {
|
||||
QString url = pathToUrl->getRecord(path, txn);
|
||||
pathToUrl->removeRecord(path);
|
||||
|
||||
UrlInfo info = urlToInfo->getRecord(url, txn);
|
||||
info.getMessages(list);
|
||||
info.setPath(QString());
|
||||
urlToInfo->changeRecord(url, info, txn);
|
||||
|
||||
base.commitTransaction(txn);
|
||||
} catch (...) {
|
||||
base.abortTransaction(txn);
|
||||
throw;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QString Core::UrlStorage::getUrl(const QString& path) {
|
||||
return pathToUrl->getRecord(path);
|
||||
}
|
||||
|
||||
std::pair<QString, std::list<Shared::MessageInfo>> Core::UrlStorage::getPath(const QString& url) {
|
||||
UrlInfo info = urlToInfo->getRecord(url);
|
||||
std::list<Shared::MessageInfo> container;
|
||||
info.getMessages(container);
|
||||
return std::make_pair(info.getPath(), container);
|
||||
}
|
||||
|
||||
Core::UrlStorage::UrlInfo::UrlInfo():
|
||||
localPath(),
|
||||
messages() {}
|
||||
|
||||
Core::UrlStorage::UrlInfo::UrlInfo(const QString& path):
|
||||
localPath(path),
|
||||
messages() {}
|
||||
|
||||
Core::UrlStorage::UrlInfo::UrlInfo(const QString& path, const std::list<Shared::MessageInfo>& msgs):
|
||||
localPath(path),
|
||||
messages(msgs) {}
|
||||
|
||||
Core::UrlStorage::UrlInfo::~UrlInfo() {}
|
||||
|
||||
bool Core::UrlStorage::UrlInfo::addMessage(const QString& acc, const QString& jid, const QString& id) {
|
||||
for (const Shared::MessageInfo& info : messages) {
|
||||
if (info.account == acc && info.jid == jid && info.messageId == id) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
messages.emplace_back(acc, jid, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Core::UrlStorage::UrlInfo::serialize(QDataStream& data) const {
|
||||
data << localPath;
|
||||
std::list<Shared::MessageInfo>::size_type size = messages.size();
|
||||
data << quint32(size);
|
||||
for (const Shared::MessageInfo& info : messages) {
|
||||
data << info.account;
|
||||
data << info.jid;
|
||||
data << info.messageId;
|
||||
}
|
||||
}
|
||||
|
||||
QDataStream & operator << (QDataStream& in, const Core::UrlStorage::UrlInfo& info) {
|
||||
info.serialize(in);
|
||||
return in;
|
||||
}
|
||||
|
||||
QDataStream & operator >> (QDataStream& out, Core::UrlStorage::UrlInfo& info) {
|
||||
info.deserialize(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
void Core::UrlStorage::UrlInfo::deserialize(QDataStream& data) {
|
||||
data >> localPath;
|
||||
quint32 size;
|
||||
data >> size;
|
||||
for (quint32 i = 0; i < size; ++i) {
|
||||
messages.emplace_back();
|
||||
Shared::MessageInfo& info = messages.back();
|
||||
data >> info.account;
|
||||
data >> info.jid;
|
||||
data >> info.messageId;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::UrlStorage::UrlInfo::getMessages(std::list<Shared::MessageInfo>& container) const {
|
||||
for (const Shared::MessageInfo& info : messages)
|
||||
container.emplace_back(info);
|
||||
}
|
||||
|
||||
QString Core::UrlStorage::UrlInfo::getPath() const {
|
||||
return localPath;
|
||||
}
|
||||
|
||||
bool Core::UrlStorage::UrlInfo::hasPath() const {
|
||||
return localPath.size() > 0;
|
||||
}
|
||||
|
||||
void Core::UrlStorage::UrlInfo::setPath(const QString& path) {
|
||||
localPath = path;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue