// 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 "database.h" #include "exceptions.h" #include "table.h" DataBase::DataBase(const QString& p_name, uint16_t mapSize): name(p_name.toStdString()), opened(false), size(mapSize), environment(), tables() { } DataBase::~DataBase() { close(); for (const std::pair& pair : tables) { delete pair.second; } } void DataBase::close() { if (opened) { for (const std::pair& pair : tables) { _Table* table = pair.second; mdb_dbi_close(environment, table->dbi); } mdb_env_close(environment); opened = false; } } void DataBase::open() { if (!opened) { mdb_env_create(&environment); QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); path += "/" + getName(); QDir cache(path); if (!cache.exists()) { bool res = cache.mkpath(path); if (!res) { throw Directory(path.toStdString()); } } mdb_env_set_maxdbs(environment, tables.size()); mdb_env_set_mapsize(environment, size * 1024UL * 1024UL); mdb_env_open(environment, path.toStdString().c_str(), 0, 0664); MDB_txn *txn; mdb_txn_begin(environment, NULL, 0, &txn); for (const std::pair& pair : tables) { _Table* table = pair.second; int rc = table->createTable(txn); if (rc) { throw Unknown(name, mdb_strerror(rc)); } } mdb_txn_commit(txn); opened = true; } } bool DataBase::removeDirectory() { if (opened) { throw Opened(name, "remove database directory"); } QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); path += "/" + getName(); QDir cache(path); if (cache.exists()) { return cache.removeRecursively(); } else { return true; } } QString DataBase::getName() const { return QString::fromStdString(name); } bool DataBase::ready() const { return opened; } void DataBase::drop() { if (!opened) { throw Closed("drop", name); } MDB_txn *txn; int rc = mdb_txn_begin(environment, NULL, 0, &txn); if (rc) { throw Unknown(name, mdb_strerror(rc)); } for (const std::pair& pair : tables) { rc = pair.second->drop(txn); if (rc) { throw Unknown(name, mdb_strerror(rc), pair.first); } } mdb_txn_commit(txn); }