/* * 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 . */ #include "storage.h" #define UNUSED(x) (void)(x) LMDBAL::iStorage::iStorage(const std::string& p_name, Base* parent): dbi(), db(parent), name(p_name) {} LMDBAL::iStorage::~iStorage() {} void LMDBAL::iStorage::drop() { ensureOpened(dropMethodName); TransactionID txn = db->beginTransaction(); int rc = iStorage::drop(txn); if (rc != MDB_SUCCESS) { abortTransaction(txn); throw Unknown(db->name, mdb_strerror(rc), name); } db->commitTransaction(txn); } int LMDBAL::iStorage::drop(TransactionID transaction) { return mdb_drop(transaction, dbi, 0); } void LMDBAL::iStorage::ensureOpened(const std::string& methodName) const { if (!db->opened) throw Closed(methodName, db->name, name); } LMDBAL::SizeType LMDBAL::iStorage::count() const { ensureOpened(countMethodName); TransactionID txn = beginReadOnlyTransaction(); SizeType amount; try { amount = count(txn); } catch (...) { abortTransaction(txn); throw; } abortTransaction(txn); return amount; } LMDBAL::SizeType LMDBAL::iStorage::count(TransactionID txn) const { MDB_stat stat; int rc = mdb_stat(txn, dbi, &stat); if (rc != MDB_SUCCESS) throw Unknown(db->name, mdb_strerror(rc), name); return stat.ms_entries; } void LMDBAL::iStorage::throwDuplicateOrUnknown(int rc, TransactionID txn, const std::string& key) const { abortTransaction(txn); throwDuplicateOrUnknown(rc, key); } void LMDBAL::iStorage::throwNotFoundOrUnknown(int rc, LMDBAL::TransactionID txn, const std::string& key) const { abortTransaction(txn); throwNotFoundOrUnknown(rc, key); } void LMDBAL::iStorage::throwDuplicateOrUnknown(int rc, const std::string& key) const { if (rc == MDB_KEYEXIST) throwDuplicate(key); else throwUnknown(rc); } void LMDBAL::iStorage::throwNotFoundOrUnknown(int rc, const std::string& key) const { if (rc == MDB_NOTFOUND) throwNotFound(key); else throwUnknown(rc); } void LMDBAL::iStorage::throwUnknown(int rc, LMDBAL::TransactionID txn) const { abortTransaction(txn); throwUnknown(rc); } const std::string & LMDBAL::iStorage::dbName() const { return db->name;} bool LMDBAL::iStorage::isDBOpened() const { return db->opened;} void LMDBAL::iStorage::throwUnknown(int rc) const { throw Unknown(db->name, mdb_strerror(rc), name);} void LMDBAL::iStorage::throwDuplicate(const std::string& key) const { throw Exist(key, db->name, name);} void LMDBAL::iStorage::throwNotFound(const std::string& key) const { throw NotFound(key, db->name, name);} LMDBAL::TransactionID LMDBAL::iStorage::beginReadOnlyTransaction() const { return db->beginPrivateReadOnlyTransaction(name);} LMDBAL::TransactionID LMDBAL::iStorage::beginTransaction() const { return db->beginPrivateTransaction(name);} void LMDBAL::iStorage::abortTransaction(LMDBAL::TransactionID id) const { db->abortPrivateTransaction(id, name);} void LMDBAL::iStorage::commitTransaction(LMDBAL::TransactionID id) { db->commitPrivateTransaction(id, name);} void LMDBAL::iStorage::transactionStarted(LMDBAL::TransactionID txn, bool readOnly) const { UNUSED(txn); UNUSED(readOnly); } void LMDBAL::iStorage::transactionCommited(LMDBAL::TransactionID txn) { UNUSED(txn);} void LMDBAL::iStorage::transactionAborted(LMDBAL::TransactionID txn) const { UNUSED(txn);}