/* * 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 #include #include #include "urlstorage.h" Core::UrlStorage::UrlStorage(const QString& p_name): base(p_name), urlToInfo(base.addStorage("urlToInfo")), pathToUrl(base.addStorage("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::WriteTransaction txn = base.beginTransaction(); writeInfo(key, info, txn, overwrite); txn.commit(); } void Core::UrlStorage::writeInfo(const QString& key, const Core::UrlStorage::UrlInfo& info, const LMDBAL::WriteTransaction& 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& 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::WriteTransaction txn = base.beginTransaction(); try { urlToInfo->getRecord(url, info, txn); } catch (const LMDBAL::NotFound& e) {} 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) { writeInfo(url, info, txn, true); txn.commit(); } return info; } std::list Core::UrlStorage::setPath(const QString& url, const QString& path) { std::list list; LMDBAL::WriteTransaction txn = base.beginTransaction(); UrlInfo info; try { urlToInfo->getRecord(url, info, txn); info.getMessages(list); } catch (const LMDBAL::NotFound& e) {} info.setPath(path); writeInfo(url, info, txn, true); txn.commit(); return list; } std::list Core::UrlStorage::removeFile(const QString& url) { std::list list; LMDBAL::WriteTransaction txn = base.beginTransaction(); UrlInfo info; urlToInfo->getRecord(url, info, txn); urlToInfo->removeRecord(url, txn); info.getMessages(list); if (info.hasPath()) pathToUrl->removeRecord(info.getPath(), txn); txn.commit(); return list; } std::list Core::UrlStorage::deletedFile(const QString& path) { std::list list; LMDBAL::WriteTransaction txn = base.beginTransaction(); QString url = pathToUrl->getRecord(path, txn); pathToUrl->removeRecord(path, txn); UrlInfo info = urlToInfo->getRecord(url, txn); info.getMessages(list); info.setPath(QString()); urlToInfo->changeRecord(url, info, txn); txn.commit(); return list; } QString Core::UrlStorage::getUrl(const QString& path) { return pathToUrl->getRecord(path); } std::pair> Core::UrlStorage::getPath(const QString& url) { UrlInfo info = urlToInfo->getRecord(url); std::list 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& 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::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& 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; }