From 928558539c2be2181c2e2019f617ec573b9974a5 Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 15 Oct 2022 13:54:34 +0300 Subject: [PATCH] serializer for QByteArray, method to read all records --- CMakeLists.txt | 1 + cache.h | 1 + cache.hpp | 16 +++++++++++ serializer.h | 1 + serializer_qbytearray.hpp | 58 +++++++++++++++++++++++++++++++++++++++ table.h | 1 + table.hpp | 33 ++++++++++++++++++++++ 7 files changed, 111 insertions(+) create mode 100644 serializer_qbytearray.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index eab713e..9eb708d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ set(HEADERS serializer_double.hpp serializer_stdstring.hpp serializer_qstring.hpp + serializer_qbytearray.hpp ) if (BUILD_STATIC) diff --git a/cache.h b/cache.h index 8bd3c4b..4c30fac 100644 --- a/cache.h +++ b/cache.h @@ -44,6 +44,7 @@ public: virtual V getRecord(const K& key) const override; virtual uint32_t count() const override; virtual int drop(MDB_txn * transaction) override; + virtual std::map readAll() const override; protected: Mode* mode; diff --git a/cache.hpp b/cache.hpp index 6a36df9..9a509b3 100644 --- a/cache.hpp +++ b/cache.hpp @@ -115,6 +115,22 @@ V DataBase::Cache::getRecord(const K& key) const { } } +template +std::map DataBase::Cache::readAll() const { + if (!DataBase::Table::db->opened) { + throw Closed("readAll", DataBase::Table::db->name, DataBase::Table::name); + } + + if (*mode != Mode::full) { //there is a room for optimization + *mode = Mode::full; //I can read and deserialize only those values + *cache = DataBase::Table::readAll(); //that are missing in the cache + abscent->clear(); + *sizeDifference = 0; + } + + return *cache; +} + template void DataBase::Cache::removeRecord(const K& key) { if (!DataBase::Table::db->opened) { diff --git a/serializer.h b/serializer.h index 3350e8b..9ff3c18 100644 --- a/serializer.h +++ b/serializer.h @@ -61,5 +61,6 @@ private: #include "serializer_double.hpp" #include "serializer_stdstring.hpp" #include "serializer_qstring.hpp" +#include "serializer_qbytearray.hpp" #endif // CORE_DATABASE_SERIALIZER_H diff --git a/serializer_qbytearray.hpp b/serializer_qbytearray.hpp new file mode 100644 index 0000000..741bf34 --- /dev/null +++ b/serializer_qbytearray.hpp @@ -0,0 +1,58 @@ +// 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_DATABASE_SERIALIZER_QBYTEARRAY_HPP +#define CORE_DATABASE_SERIALIZER_QBYTEARRAY_HPP + +#include + +template<> +class DataBase::Serializer +{ +public: + Serializer():value() {}; + Serializer(const QByteArray& p_value):value(p_value) {}; + ~Serializer() {}; + + QByteArray deserialize(const MDB_val& data) { + value.setRawData((char*)data.mv_data, data.mv_size); + return value; + }; + MDB_val setData(const QByteArray& data) { + value = data; + return getData(); + }; + MDB_val getData() { + MDB_val result; + result.mv_data = value.data(); + result.mv_size = value.size(); + return result; + }; + void clear() { + value.clear(); + }; + +private: + QByteArray value; +}; + + +#endif //CORE_DATABASE_SERIALIZER_QBYTEARRAY_HPP + + + + diff --git a/table.h b/table.h index 51d2335..a2abe81 100644 --- a/table.h +++ b/table.h @@ -58,6 +58,7 @@ public: virtual void changeRecord(const K& key, const V& value); virtual void removeRecord(const K& key); virtual V getRecord(const K& key) const; + virtual std::map readAll() const; protected: Serializer* keySerializer; diff --git a/table.hpp b/table.hpp index 8fa315b..db4f428 100644 --- a/table.hpp +++ b/table.hpp @@ -110,6 +110,39 @@ V DataBase::Table::getRecord(const K& key) const { } } +template +std::map DataBase::Table::readAll() const { + if (!db->opened) { + throw Closed("readAll", db->name, name); + } + + std::map result; + MDB_txn *txn; + MDB_cursor* cursor; + MDB_val lmdbKey, lmdbData; + int rc = mdb_txn_begin(db->environment, NULL, MDB_RDONLY, &txn); + if (rc != MDB_SUCCESS) { + throw Unknown(db->name, mdb_strerror(rc), name); + } + rc = mdb_cursor_open(txn, dbi, &cursor); + if (rc != MDB_SUCCESS) { + throw Unknown(db->name, mdb_strerror(rc), name); + } + rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST); + while (rc == MDB_SUCCESS) { + K key = keySerializer->deserialize(lmdbKey); + V value = valueSerializer->deserialize(lmdbData); + result.insert(std::make_pair(key, value)); + rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_NEXT); + } + + if (rc != MDB_NOTFOUND) { + throw Unknown(db->name, mdb_strerror(rc), name); + } + + return result; +} + template void DataBase::Table::removeRecord(const K& key) { if (!db->opened) {