forked from blue/lmdbal
Temp ideas
This commit is contained in:
parent
a3f58bd3c3
commit
c3139974f1
@ -25,6 +25,8 @@ endif ()
|
|||||||
add_executable(storage
|
add_executable(storage
|
||||||
main.cpp
|
main.cpp
|
||||||
exception.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