forked from blue/lmdbal
Temp ideas
This commit is contained in:
parent
a3f58bd3c3
commit
c3139974f1
@ -25,6 +25,8 @@ endif ()
|
||||
add_executable(storage
|
||||
main.cpp
|
||||
exception.cpp
|
||||
table.cpp
|
||||
database.cpp
|
||||
)
|
||||
|
||||
|
||||
|
98
database.cpp
Normal file
98
database.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
// Squawk messenger.
|
||||
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "database.h"
|
||||
#include "exceptions.h"
|
||||
#include "table.h"
|
||||
|
||||
Core::DataBase::DataBase(const QString& p_name, uint16_t mapSize):
|
||||
name(p_name.toStdString()),
|
||||
opened(false),
|
||||
size(mapSize),
|
||||
environment(),
|
||||
tables()
|
||||
{
|
||||
}
|
||||
|
||||
Core::DataBase::~DataBase()
|
||||
{
|
||||
close();
|
||||
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
||||
delete pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DataBase::close()
|
||||
{
|
||||
if (opened) {
|
||||
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
||||
_Table* table = pair.second;
|
||||
mdb_dbi_close(environment, table->dbi);
|
||||
}
|
||||
mdb_env_close(environment);
|
||||
opened = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::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<const std::string, _Table*>& pair : tables) {
|
||||
_Table* table = pair.second;
|
||||
int rc = mdb_dbi_open(txn, pair.first.c_str(), MDB_CREATE, &table->dbi);
|
||||
if (rc) {
|
||||
throw Unknown(name, mdb_strerror(rc));
|
||||
}
|
||||
|
||||
}
|
||||
mdb_txn_commit(txn);
|
||||
opened = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString Core::DataBase::getName() const
|
||||
{
|
||||
return QString::fromStdString(name);
|
||||
}
|
||||
|
||||
template <class K, class V>
|
||||
Core::DataBase::Table<K, V>* Core::DataBase::addTable(const QString& p_name) {
|
||||
if (opened) {
|
||||
throw Core::DataBase::Opened(name);
|
||||
}
|
||||
Core::DataBase::Table<K, V>* table = new Core::DataBase::Table<K, V>();
|
||||
tables.insert(std::make_pair(p_name.toStdString(), table));
|
||||
return table;
|
||||
}
|
68
database.h
Normal file
68
database.h
Normal file
@ -0,0 +1,68 @@
|
||||
// Squawk messenger.
|
||||
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef CORE_DATABASE_H
|
||||
#define CORE_DATABASE_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <QString>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <lmdb.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class DataBase
|
||||
{
|
||||
class _Table;
|
||||
public:
|
||||
template <class K, class V>
|
||||
class Table;
|
||||
|
||||
DataBase(const QString& name, uint16_t mapSize = 10);
|
||||
~DataBase();
|
||||
|
||||
void open();
|
||||
void close();
|
||||
QString getName() const;
|
||||
|
||||
template <class K, class V>
|
||||
Table<K, V>* addTable(const QString& name);
|
||||
|
||||
public:
|
||||
//exceptions
|
||||
class Directory;
|
||||
class Closed;
|
||||
class Opened;
|
||||
class NotFound;
|
||||
class Empty;
|
||||
class Exist;
|
||||
class NoAvatar;
|
||||
class Unknown;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
bool opened;
|
||||
uint16_t size;
|
||||
MDB_env* environment;
|
||||
std::map<std::string, _Table*> tables;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CORE_DATABASE_H
|
106
exceptions.h
Normal file
106
exceptions.h
Normal file
@ -0,0 +1,106 @@
|
||||
// Squawk messenger.
|
||||
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef CORE_DATABASE_EXCEPTIONS_H
|
||||
#define CORE_DATABASE_EXCEPTIONS_H
|
||||
|
||||
#include "exception.h"
|
||||
#include "database.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
class DataBase::Directory: public Utils::Exception {
|
||||
public:
|
||||
Directory(const std::string& p_path):Exception(), path(p_path){}
|
||||
|
||||
std::string getMessage() const{return "Can't create directory for database at " + path;}
|
||||
private:
|
||||
std::string path;
|
||||
};
|
||||
|
||||
class DataBase::Closed : public Utils::Exception {
|
||||
public:
|
||||
Closed(const std::string& op, const std::string& acc):Exception(), operation(op), account(acc){}
|
||||
|
||||
std::string getMessage() const{return "An attempt to perform operation " + operation + " on closed archive for " + account;}
|
||||
private:
|
||||
std::string operation;
|
||||
std::string account;
|
||||
};
|
||||
|
||||
class DataBase::Opened : public Utils::Exception {
|
||||
public:
|
||||
Opened(const std::string& tn):Exception(), tableName(tn){}
|
||||
|
||||
std::string getMessage() const{return "An attempt to add table " + tableName + " but it's impossible to do if the DataBase is already opened";}
|
||||
private:
|
||||
std::string tableName;
|
||||
};
|
||||
|
||||
class DataBase::NotFound : public Utils::Exception {
|
||||
public:
|
||||
NotFound(const std::string& k, const std::string& acc):Exception(), key(k), account(acc){}
|
||||
|
||||
std::string getMessage() const{return "Element for id " + key + " wasn't found in database " + account;}
|
||||
private:
|
||||
std::string key;
|
||||
std::string account;
|
||||
};
|
||||
|
||||
class DataBase::Empty : public Utils::Exception {
|
||||
public:
|
||||
Empty(const std::string& acc):Exception(), account(acc){}
|
||||
|
||||
std::string getMessage() const{return "An attempt to read ordered elements from database " + account + " but it's empty";}
|
||||
private:
|
||||
std::string account;
|
||||
};
|
||||
|
||||
class DataBase::Exist : public Utils::Exception {
|
||||
public:
|
||||
Exist(const std::string& acc, const std::string& p_key):Exception(), account(acc), key(p_key){}
|
||||
|
||||
std::string getMessage() const{return "An attempt to insert element " + key + " to database " + account + " but it already has an element with given id";}
|
||||
private:
|
||||
std::string account;
|
||||
std::string key;
|
||||
};
|
||||
|
||||
class DataBase::NoAvatar : public Utils::Exception {
|
||||
public:
|
||||
NoAvatar(const std::string& el, const std::string& res):Exception(), element(el), resource(res){
|
||||
if (resource.size() == 0) {
|
||||
resource = "for himself";
|
||||
}
|
||||
}
|
||||
|
||||
std::string getMessage() const{return "Element " + element + " has no avatar for " + resource ;}
|
||||
private:
|
||||
std::string element;
|
||||
std::string resource;
|
||||
};
|
||||
|
||||
class DataBase::Unknown : public Utils::Exception {
|
||||
public:
|
||||
Unknown(const std::string& acc, const std::string& message):Exception(), account(acc), msg(message){}
|
||||
|
||||
std::string getMessage() const{return "Unknown error on database " + account + ": " + msg;}
|
||||
private:
|
||||
std::string account;
|
||||
std::string msg;
|
||||
};
|
||||
}
|
||||
#endif //CORE_DATABASE_EXCEPTIONS_H
|
25
table.cpp
Normal file
25
table.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Squawk messenger.
|
||||
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "table.h"
|
||||
|
||||
Core::DataBase::_Table::_Table(DataBase* parent):
|
||||
dbi(),
|
||||
db(parent)
|
||||
{
|
||||
}
|
||||
|
||||
Core::DataBase::_Table::~_Table() {}
|
52
table.h
Normal file
52
table.h
Normal file
@ -0,0 +1,52 @@
|
||||
// Squawk messenger.
|
||||
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef CORE_TABLE_H
|
||||
#define CORE_TABLE_H
|
||||
|
||||
#include "database.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
class DataBase::_Table {
|
||||
public:
|
||||
_Table(DataBase* parent);
|
||||
virtual ~_Table();
|
||||
|
||||
public:
|
||||
MDB_dbi dbi;
|
||||
DataBase* db;
|
||||
};
|
||||
|
||||
template <class K, class V>
|
||||
class DataBase::Table : private DataBase::_Table {
|
||||
friend class DataBase;
|
||||
private:
|
||||
Table(DataBase* parent);
|
||||
~Table() override;
|
||||
|
||||
public:
|
||||
void addRecord(const K& key, const V& value);
|
||||
void changeRecord(const K& key, const V& value);
|
||||
void removeRecord(const K& key);
|
||||
V getRecord(const K& key) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "table.hpp"
|
||||
|
||||
#endif // CORE_TABLE_H
|
53
table.hpp
Normal file
53
table.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
// Squawk messenger.
|
||||
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef CORE_TABLE_HPP
|
||||
#define CORE_TABLE_HPP
|
||||
|
||||
#include "table.h"
|
||||
|
||||
|
||||
template<typename K, typename V>
|
||||
void Core::DataBase::Table<K, V>::addRecord(const K& key, const V& value) {
|
||||
if (!db->opened) {
|
||||
throw Closed("addRecord", db->name);
|
||||
}
|
||||
QByteArray ba;
|
||||
QDataStream ds(&ba, QIODevice::WriteOnly);
|
||||
ds << value;
|
||||
|
||||
MDB_val lmdbKey, lmdbData;
|
||||
lmdbKey << key;
|
||||
|
||||
lmdbData.mv_size = ba.size();
|
||||
lmdbData.mv_data = (uint8_t*)ba.data();
|
||||
MDB_txn *txn;
|
||||
mdb_txn_begin(db->environment, NULL, 0, &txn);
|
||||
int rc;
|
||||
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, MDB_NOOVERWRITE);
|
||||
if (rc != 0) {
|
||||
mdb_txn_abort(txn);
|
||||
if (rc == MDB_KEYEXIST) {
|
||||
throw Exist(db->name, std::to_string(key));
|
||||
} else {
|
||||
throw Unknown(db->name, mdb_strerror(rc));
|
||||
}
|
||||
} else {
|
||||
mdb_txn_commit(txn);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //CORE_TABLE_HPP
|
Loading…
Reference in New Issue
Block a user