/* * LMDB Abstraction Layer. * Copyright (C) 2023 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 . */ #pragma once #include #include #include #include "base.h" #include "transaction.h" namespace LMDBAL { class CursorCommon; class StorageCommon { friend class Base; friend class CursorCommon; public: protected: StorageCommon(Base* parent, const std::string& name, bool duplicates = false); virtual ~ StorageCommon(); /** * \brief A private virtual function I need to open each storage in the database * * \param[in] transaction - lmdb transaction to call mdb_dbi_open * \returns MDB_SUCCESS if everything went smooth or MDB_ -like error code */ virtual int open(MDB_txn * transaction) = 0; virtual void close(); virtual void handleDrop(); bool isDBOpened() const; const std::string& dbName() const; void ensureOpened(const std::string& methodName) const; void throwDuplicateOrUnknown(int rc, const std::string& key) const; void throwDuplicateOrUnknown(int rc, TransactionID txn, const std::string& key) const; void throwNotFoundOrUnknown(int rc, const std::string& key) const; void throwNotFoundOrUnknown(int rc, TransactionID txn, const std::string& key) const; void throwUnknown(int rc, TransactionID txn) const; void throwUnknown(int rc) const; void throwUnknown(const std::string& message) const; void throwDuplicate(const std::string& key) const; void throwNotFound(const std::string& key) const; void throwCursorNotReady(const std::string& method) const; TransactionID extractTransactionId(const Transaction& txn, const std::string& action = "") const; TransactionID beginReadOnlyTransaction() const; TransactionID beginTransaction() const; void commitTransaction(TransactionID id); void abortTransaction(TransactionID id) const; virtual void transactionStarted(TransactionID txn, bool readOnly) const; virtual void transactionCommited(TransactionID txn); virtual void transactionAborted(TransactionID txn) const; virtual int drop(TransactionID transaction); virtual SizeType count(TransactionID txn) const; void openCursorTransaction(MDB_cursor** cursor, bool renew = false) const; void closeCursorTransaction(MDB_cursor* cursor, bool closeCursor = false) const; void attachCursorToTransaction(uint32_t cursorId, MDB_cursor* cursorHandle, CursorCommon* pointer) const; void disconnectCursorFromTransaction(uint32_t cursorId, MDB_cursor* cursorHandle) const; int _mdbOpen(MDB_txn* txn, unsigned int flags = 0); int _mdbPut(MDB_txn* txn, MDB_val& key, MDB_val& data, unsigned int flags = 0); int _mdbGet(MDB_txn* txn, MDB_val& key, MDB_val& data) const; int _mdbDel(MDB_txn* txn, MDB_val& key); int _mdbDel(MDB_txn* txn, MDB_val& key, MDB_val& data); int _mdbStat(MDB_txn* txn, MDB_stat& stat) const; int _mdbFlags(MDB_txn* txn, uint32_t& flags) const; int _mdbCursorOpen(MDB_txn* txn, MDB_cursor** cursor) const; void _mdbCursorClose(MDB_cursor* cursor) const; int _mdbCursorGet(MDB_cursor* cursor, MDB_val& key, MDB_val& data, MDB_cursor_op operation) const; int _mdbCursorSet(MDB_cursor* cursor, MDB_val& key) const; int _mdbCursorDel(MDB_cursor* cursor, unsigned int flags = 0); int _mdbCursorPut(MDB_cursor* cursor, MDB_val& key, MDB_val& data, unsigned int flags = 0); int _mdbCursorRenew(MDB_txn* txn, MDB_cursor* cursor) const; MDB_txn* _mdbCursorTxn(MDB_cursor* cursor) const; public: virtual void drop(); virtual int drop(const WriteTransaction& txn); virtual SizeType count() const; virtual SizeType count(const Transaction& txn) const; protected: MDB_dbi dbi; /**<\brief lmdb storage handle*/ Base* db; /**<\brief parent database pointer (borrowed)*/ const std::string name; /**<\brief this storage name*/ const bool duplicates; /**<\brief true if storage supports duplicates*/ inline static const std::string dropMethodName = "drop"; /**<\brief member function name, just for exceptions*/ inline static const std::string countMethodName = "count"; /**<\brief member function name, just for exceptions*/ inline static const std::string flagsMethodName = "flags"; /**<\brief member function name, just for exceptions*/ inline static const std::string addRecordMethodName = "addRecord"; /**<\brief member function name, just for exceptions*/ inline static const std::string forceRecordMethodName = "forceRecord"; /**<\brief member function name, just for exceptions*/ inline static const std::string changeRecordMethodName = "changeRecord"; /**<\brief member function name, just for exceptions*/ inline static const std::string removeRecordMethodName = "removeRecord"; /**<\brief member function name, just for exceptions*/ inline static const std::string checkRecordMethodName = "checkRecord"; /**<\brief member function name, just for exceptions*/ inline static const std::string getRecordMethodName = "getRecord"; /**<\brief member function name, just for exceptions*/ inline static const std::string readAllMethodName = "readAllRecord"; /**<\brief member function name, just for exceptions*/ inline static const std::string replaceAllMethodName = "replaceAll"; /**<\brief member function name, just for exceptions*/ inline static const std::string addRecordsMethodName = "addRecords"; /**<\brief member function name, just for exceptions*/ inline static const std::string openCursorTransactionMethodName = "openCursorTransaction"; /**<\brief member function name, just for exceptions*/ protected: template int makeStorage(MDB_txn* transaction, bool duplicates = false); template static std::string toString(const T& value); }; } #include "storagecommon.hpp"