forked from blue/lmdbal
finally, first working prototype
This commit is contained in:
parent
d67a3c32eb
commit
5f90a21fe6
23
database.cpp
23
database.cpp
@ -18,7 +18,7 @@
|
|||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
||||||
Core::DataBase::DataBase(const QString& p_name, uint16_t mapSize):
|
DataBase::DataBase(const QString& p_name, uint16_t mapSize):
|
||||||
name(p_name.toStdString()),
|
name(p_name.toStdString()),
|
||||||
opened(false),
|
opened(false),
|
||||||
size(mapSize),
|
size(mapSize),
|
||||||
@ -27,7 +27,7 @@ Core::DataBase::DataBase(const QString& p_name, uint16_t mapSize):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::DataBase::~DataBase()
|
DataBase::~DataBase()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
||||||
@ -35,7 +35,7 @@ Core::DataBase::~DataBase()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::DataBase::close()
|
void DataBase::close()
|
||||||
{
|
{
|
||||||
if (opened) {
|
if (opened) {
|
||||||
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
||||||
@ -47,7 +47,7 @@ void Core::DataBase::close()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::DataBase::open()
|
void DataBase::open()
|
||||||
{
|
{
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
mdb_env_create(&environment);
|
mdb_env_create(&environment);
|
||||||
@ -71,7 +71,7 @@ void Core::DataBase::open()
|
|||||||
|
|
||||||
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
for (const std::pair<const std::string, _Table*>& pair : tables) {
|
||||||
_Table* table = pair.second;
|
_Table* table = pair.second;
|
||||||
int rc = mdb_dbi_open(txn, pair.first.c_str(), MDB_CREATE, &table->dbi);
|
int rc = table->createTable(txn);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
throw Unknown(name, mdb_strerror(rc));
|
throw Unknown(name, mdb_strerror(rc));
|
||||||
}
|
}
|
||||||
@ -82,18 +82,9 @@ void Core::DataBase::open()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Core::DataBase::getName() const
|
QString DataBase::getName() const
|
||||||
{
|
{
|
||||||
return QString::fromStdString(name);
|
return QString::fromStdString(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class V>
|
|
||||||
Core::DataBase::Table<K, V>* Core::DataBase::addTable(const QString& p_name) {
|
|
||||||
std::string nm = p_name.toStdString();
|
|
||||||
if (opened) {
|
|
||||||
throw Core::DataBase::Opened(name, nm);
|
|
||||||
}
|
|
||||||
Core::DataBase::Table<K, V>* table = new Core::DataBase::Table<K, V>(nm, this);
|
|
||||||
tables.insert(std::make_pair(nm, table));
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
13
database.h
13
database.h
@ -25,8 +25,6 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <lmdb.h>
|
#include <lmdb.h>
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
|
|
||||||
class DataBase
|
class DataBase
|
||||||
{
|
{
|
||||||
class _Table;
|
class _Table;
|
||||||
@ -63,6 +61,17 @@ private:
|
|||||||
std::map<std::string, _Table*> tables;
|
std::map<std::string, _Table*> tables;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "exceptions.h"
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
DataBase::Table<K, V>* DataBase::addTable(const QString& p_name) {
|
||||||
|
std::string nm = p_name.toStdString();
|
||||||
|
if (opened) {
|
||||||
|
throw Opened(name, nm);
|
||||||
|
}
|
||||||
|
DataBase::Table<K, V>* table = new DataBase::Table<K, V>(nm, this);
|
||||||
|
tables.insert(std::make_pair(nm, (_Table*)table));
|
||||||
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CORE_DATABASE_H
|
#endif // CORE_DATABASE_H
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
|
|
||||||
Core::DataBase::Directory::Directory(const std::string& p_path):
|
DataBase::Directory::Directory(const std::string& p_path):
|
||||||
Exception(),
|
Exception(),
|
||||||
path(p_path) {}
|
path(p_path) {}
|
||||||
|
|
||||||
std::string Core::DataBase::Directory::getMessage() const {
|
std::string DataBase::Directory::getMessage() const {
|
||||||
return "Can't create directory for database at " + path;}
|
return "Can't create directory for database at " + path;}
|
||||||
|
|
||||||
Core::DataBase::Closed::Closed(
|
DataBase::Closed::Closed(
|
||||||
const std::string& p_operation,
|
const std::string& p_operation,
|
||||||
const std::string& p_dbName,
|
const std::string& p_dbName,
|
||||||
const std::string& p_tableName
|
const std::string& p_tableName
|
||||||
@ -33,26 +33,26 @@ Core::DataBase::Closed::Closed(
|
|||||||
dbName(p_dbName),
|
dbName(p_dbName),
|
||||||
tableName(p_tableName) {}
|
tableName(p_tableName) {}
|
||||||
|
|
||||||
std::string Core::DataBase::Closed::getMessage() const {
|
std::string DataBase::Closed::getMessage() const {
|
||||||
return "An attempt to perform operation " + operation
|
return "An attempt to perform operation " + operation
|
||||||
+ " on closed database " + dbName
|
+ " on closed database " + dbName
|
||||||
+ " on table " + tableName;
|
+ " on table " + tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::DataBase::Opened::Opened(const std::string& p_dbName, const std::string& p_tableName):
|
DataBase::Opened::Opened(const std::string& p_dbName, const std::string& p_tableName):
|
||||||
Exception(),
|
Exception(),
|
||||||
dbName(p_dbName),
|
dbName(p_dbName),
|
||||||
tableName(p_tableName) {}
|
tableName(p_tableName) {}
|
||||||
|
|
||||||
|
|
||||||
std::string Core::DataBase::Opened::getMessage() const {
|
std::string DataBase::Opened::getMessage() const {
|
||||||
return "An attempt to add table " + tableName
|
return "An attempt to add table " + tableName
|
||||||
+ " to the database " + dbName
|
+ " to the database " + dbName
|
||||||
+ " but it's can't be done because the DataBase is already opened."
|
+ " but it's can't be done because the DataBase is already opened."
|
||||||
+ " Please add all tables before opening DataBase.";
|
+ " Please add all tables before opening DataBase.";
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::DataBase::NotFound::NotFound(
|
DataBase::NotFound::NotFound(
|
||||||
const std::string& p_key,
|
const std::string& p_key,
|
||||||
const std::string& p_dbName,
|
const std::string& p_dbName,
|
||||||
const std::string& p_tableName
|
const std::string& p_tableName
|
||||||
@ -62,12 +62,12 @@ Core::DataBase::NotFound::NotFound(
|
|||||||
dbName(p_dbName),
|
dbName(p_dbName),
|
||||||
tableName(p_tableName) {}
|
tableName(p_tableName) {}
|
||||||
|
|
||||||
std::string Core::DataBase::NotFound::getMessage() const {
|
std::string DataBase::NotFound::getMessage() const {
|
||||||
return "Element for id " + key + " wasn't found "
|
return "Element for id " + key + " wasn't found "
|
||||||
+ " in database " + dbName
|
+ " in database " + dbName
|
||||||
+ " in table " + tableName;}
|
+ " in table " + tableName;}
|
||||||
|
|
||||||
Core::DataBase::Exist::Exist(
|
DataBase::Exist::Exist(
|
||||||
const std::string& p_key,
|
const std::string& p_key,
|
||||||
const std::string& p_dbName,
|
const std::string& p_dbName,
|
||||||
const std::string& p_tableName
|
const std::string& p_tableName
|
||||||
@ -77,14 +77,14 @@ Core::DataBase::Exist::Exist(
|
|||||||
dbName(p_dbName),
|
dbName(p_dbName),
|
||||||
tableName(p_tableName) {}
|
tableName(p_tableName) {}
|
||||||
|
|
||||||
std::string Core::DataBase::Exist::getMessage() const {
|
std::string DataBase::Exist::getMessage() const {
|
||||||
return "An attempt to insert element with key " + key
|
return "An attempt to insert element with key " + key
|
||||||
+ " to database " + dbName
|
+ " to database " + dbName
|
||||||
+ " to table " + tableName
|
+ " to table " + tableName
|
||||||
+ " but it already has an element with given id";
|
+ " but it already has an element with given id";
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::DataBase::Unknown::Unknown(
|
DataBase::Unknown::Unknown(
|
||||||
const std::string& p_dbName,
|
const std::string& p_dbName,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::optional<std::string>& p_tableName
|
const std::optional<std::string>& p_tableName
|
||||||
@ -94,7 +94,7 @@ Core::DataBase::Unknown::Unknown(
|
|||||||
tableName(p_tableName),
|
tableName(p_tableName),
|
||||||
msg(message) {}
|
msg(message) {}
|
||||||
|
|
||||||
std::string Core::DataBase::Unknown::getMessage() const
|
std::string DataBase::Unknown::getMessage() const
|
||||||
{
|
{
|
||||||
std::string result = "Unknown error in database " + dbName;
|
std::string result = "Unknown error in database " + dbName;
|
||||||
if (tableName.has_value()) {
|
if (tableName.has_value()) {
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
|
|
||||||
class DataBase::Directory: public Utils::Exception {
|
class DataBase::Directory: public Utils::Exception {
|
||||||
public:
|
public:
|
||||||
Directory(const std::string& path);
|
Directory(const std::string& path);
|
||||||
@ -84,5 +82,5 @@ private:
|
|||||||
std::optional<std::string> tableName;
|
std::optional<std::string> tableName;
|
||||||
std::string msg;
|
std::string msg;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
#endif //CORE_DATABASE_EXCEPTIONS_H
|
#endif //CORE_DATABASE_EXCEPTIONS_H
|
||||||
|
43
main.cpp
43
main.cpp
@ -4,38 +4,31 @@
|
|||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
class Serializer {
|
|
||||||
public:
|
|
||||||
Serializer(const T& value):val(value) {}
|
|
||||||
|
|
||||||
void print() {
|
|
||||||
std::cout << val << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
T val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
class Serializer<int> {
|
|
||||||
public:
|
|
||||||
Serializer(int v): value(v) {}
|
|
||||||
|
|
||||||
int value;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
Core::DataBase base("test1");
|
DataBase base("test1");
|
||||||
Core::DataBase::Table<uint32_t, uint32_t>* table1 = base.addTable<uint32_t, uint32_t>("table1");
|
DataBase::Table<uint32_t, uint32_t>* table1 = base.addTable<uint32_t, uint32_t>("table1");
|
||||||
Core::DataBase::Table<QString, QString>* table2 = base.addTable<QString, QString>("table2");
|
DataBase::Table<QString, QString>* table2 = base.addTable<QString, QString>("table2");
|
||||||
|
|
||||||
base.open();
|
base.open();
|
||||||
|
|
||||||
table1->addRecord(1, 2);
|
try {
|
||||||
|
table1->addRecord(1, 2);
|
||||||
|
} catch (const DataBase::Exist& error) {
|
||||||
|
std::cout << error.getMessage() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rec1 = table1->getRecord(1);
|
||||||
|
std::cout << "table1 record under 1 is " << rec1 << std::endl;
|
||||||
|
|
||||||
|
try {
|
||||||
|
table2->addRecord("hello", "world");
|
||||||
|
} catch (const DataBase::Exist& error) {
|
||||||
|
std::cout << error.getMessage() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString rec2 = table2->getRecord("hello");
|
||||||
|
std::cout << "table2 record under hello is " << rec2.toStdString() << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class DataBase::Serializer
|
class DataBase::Serializer
|
||||||
{
|
{
|
||||||
@ -33,6 +31,7 @@ public:
|
|||||||
Serializer(const T& value);
|
Serializer(const T& value);
|
||||||
~Serializer();
|
~Serializer();
|
||||||
|
|
||||||
|
T deserialize(const MDB_val& value);
|
||||||
MDB_val setData(const T& value);
|
MDB_val setData(const T& value);
|
||||||
MDB_val getData();
|
MDB_val getData();
|
||||||
void clear();
|
void clear();
|
||||||
@ -47,6 +46,7 @@ private:
|
|||||||
QDataStream stream;
|
QDataStream stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
#include "serializer.hpp"
|
||||||
|
#include "serializer_uint32.hpp"
|
||||||
|
|
||||||
#endif // CORE_DATABASE_SERIALIZER_H
|
#endif // CORE_DATABASE_SERIALIZER_H
|
||||||
|
@ -14,57 +14,73 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CORE_DATABASE_SERIALIZER_HPP
|
||||||
|
#define CORE_DATABASE_SERIALIZER_HPP
|
||||||
|
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Core::DataBase::Serializer<T>::Serializer() :
|
DataBase::Serializer<T>::Serializer() :
|
||||||
bytes(),
|
bytes(),
|
||||||
buffer(&bytes),
|
buffer(&bytes),
|
||||||
stream(&buffer)
|
stream(&buffer)
|
||||||
{
|
{
|
||||||
buffer.open(QIODevice::WriteOnly);
|
buffer.open(QIODevice::ReadWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Core::DataBase::Serializer<T>::Serializer(const T& value) :
|
DataBase::Serializer<T>::Serializer(const T& value) :
|
||||||
bytes(),
|
bytes(),
|
||||||
buffer(&bytes),
|
buffer(&bytes),
|
||||||
stream(&buffer)
|
stream(&buffer)
|
||||||
{
|
{
|
||||||
buffer.open(QIODevice::WriteOnly);
|
buffer.open(QIODevice::ReadWrite);
|
||||||
_setValue(value);
|
_setValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Core::DataBase::Serializer<T>::~Serializer() {
|
DataBase::Serializer<T>::~Serializer() {
|
||||||
buffer.close();
|
buffer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
MDB_val Core::DataBase::Serializer<T>::setData(const T& value) {
|
MDB_val DataBase::Serializer<T>::setData(const T& value) {
|
||||||
clear();
|
clear();
|
||||||
_setValue(value);
|
_setData(value);
|
||||||
return getValue();
|
return getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Core::DataBase::Serializer<T>::_setData(const T& value) {
|
T DataBase::Serializer<T>::deserialize(const MDB_val& value) {
|
||||||
|
clear();
|
||||||
|
bytes.setRawData((char*)value.mv_data, value.mv_size);
|
||||||
|
T result;
|
||||||
|
stream >> result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void DataBase::Serializer<T>::_setData(const T& value) {
|
||||||
stream << value;
|
stream << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Core::DataBase::Serializer<T>::clear() {
|
void DataBase::Serializer<T>::clear() {
|
||||||
if (buffer.pos() > 0) {
|
if (buffer.pos() > 0) {
|
||||||
buffer.seek(0);
|
buffer.seek(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
MDB_val Core::DataBase::Serializer<T>::getData() {
|
MDB_val DataBase::Serializer<T>::getData() {
|
||||||
MDB_val val;
|
MDB_val val;
|
||||||
|
|
||||||
val.mv_size = buffer.pos();
|
val.mv_size = buffer.pos();
|
||||||
val.mv_data = (uint8_t*)bytes.data();
|
val.mv_data = (char*)bytes.data();
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif //CORE_DATABASE_SERIALIZER_HPP
|
||||||
|
50
serializer_uint32.hpp
Normal file
50
serializer_uint32.hpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// 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_SERIALIZER_UINT32_HPP
|
||||||
|
#define CORE_DATABASE_SERIALIZER_UINT32_HPP
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class DataBase::Serializer<uint32_t>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Serializer():value(0) {};
|
||||||
|
Serializer(const uint32_t& p_value):value(p_value) {};
|
||||||
|
~Serializer() {};
|
||||||
|
|
||||||
|
uint32_t deserialize(const MDB_val& data) {
|
||||||
|
std::memcpy(&value, data.mv_data, 4);
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
MDB_val setData(const uint32_t& data) {
|
||||||
|
value = data;
|
||||||
|
return getData();
|
||||||
|
};
|
||||||
|
MDB_val getData() {
|
||||||
|
MDB_val result;
|
||||||
|
result.mv_data = &value,
|
||||||
|
result.mv_size = 4;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
void clear() {}; //not possible;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CORE_DATABASE_SERIALIZER_UINT32_HPP
|
@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
||||||
Core::DataBase::_Table::_Table(const std::string& p_name, DataBase* parent):
|
DataBase::_Table::_Table(const std::string& p_name, DataBase* parent):
|
||||||
dbi(),
|
dbi(),
|
||||||
db(parent),
|
db(parent),
|
||||||
name(p_name)
|
name(p_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::DataBase::_Table::~_Table() {}
|
DataBase::_Table::~_Table() {}
|
||||||
|
22
table.h
22
table.h
@ -20,17 +20,23 @@
|
|||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
|
|
||||||
class DataBase::_Table {
|
class DataBase::_Table {
|
||||||
public:
|
public:
|
||||||
_Table(const std::string& name, DataBase* parent);
|
_Table(const std::string& name, DataBase* parent);
|
||||||
virtual ~_Table();
|
virtual ~_Table();
|
||||||
|
|
||||||
|
virtual int createTable(MDB_txn * transaction) = 0;
|
||||||
public:
|
public:
|
||||||
MDB_dbi dbi;
|
MDB_dbi dbi;
|
||||||
DataBase* db;
|
DataBase* db;
|
||||||
const std::string name;
|
const std::string name;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template <class T>
|
||||||
|
int makeTable(MDB_txn* transaction);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static std::string toString(const T& value);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class K, class V>
|
template <class K, class V>
|
||||||
@ -47,16 +53,12 @@ public:
|
|||||||
V getRecord(const K& key) const;
|
V getRecord(const K& key) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Serializer<K> keySerializer;
|
Serializer<K>* keySerializer;
|
||||||
Serializer<V> valueSerializer;
|
Serializer<V>* valueSerializer;
|
||||||
|
|
||||||
|
int createTable(MDB_txn* transaction) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
std::string to_string(const QString& str);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "table.hpp"
|
#include "table.hpp"
|
||||||
|
|
||||||
#endif // CORE_TABLE_H
|
#endif // CORE_TABLE_H
|
||||||
|
76
table.hpp
76
table.hpp
@ -20,26 +20,28 @@
|
|||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<class K, class V>
|
||||||
Core::DataBase::Table<K, V>::Table(const std::string& p_name, Core::DataBase* parent):
|
DataBase::Table<K, V>::Table(const std::string& p_name, DataBase* parent):
|
||||||
_Table(p_name, parent),
|
_Table(p_name, parent),
|
||||||
keySerializer(),
|
keySerializer(new Serializer<K>()),
|
||||||
valueSerializer()
|
valueSerializer(new Serializer<V>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<class K, class V>
|
||||||
Core::DataBase::Table<K, V>::~Table() {
|
DataBase::Table<K, V>::~Table() {
|
||||||
|
delete valueSerializer;
|
||||||
|
delete keySerializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<class K, class V>
|
||||||
void Core::DataBase::Table<K, V>::addRecord(const K& key, const V& value) {
|
void DataBase::Table<K, V>::addRecord(const K& key, const V& value) {
|
||||||
if (!db->opened) {
|
if (!db->opened) {
|
||||||
throw Closed("addRecord", db->name, name);
|
throw Closed("addRecord", db->name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
MDB_val lmdbKey = keySerializer.setData(key);
|
MDB_val lmdbKey = keySerializer->setData(key);
|
||||||
MDB_val lmdbData = valueSerializer.setData(value);
|
MDB_val lmdbData = valueSerializer->setData(value);
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
mdb_txn_begin(db->environment, NULL, 0, &txn);
|
mdb_txn_begin(db->environment, NULL, 0, &txn);
|
||||||
int rc;
|
int rc;
|
||||||
@ -47,7 +49,7 @@ void Core::DataBase::Table<K, V>::addRecord(const K& key, const V& value) {
|
|||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
if (rc == MDB_KEYEXIST) {
|
if (rc == MDB_KEYEXIST) {
|
||||||
throw Exist(std::to_string(key), db->name, name);
|
throw Exist(toString(key), db->name, name);
|
||||||
} else {
|
} else {
|
||||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||||
}
|
}
|
||||||
@ -58,14 +60,14 @@ void Core::DataBase::Table<K, V>::addRecord(const K& key, const V& value) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<class K, class V>
|
||||||
void Core::DataBase::Table<K, V>::changeRecord(const K& key, const V& value) {
|
void DataBase::Table<K, V>::changeRecord(const K& key, const V& value) {
|
||||||
if (!db->opened) {
|
if (!db->opened) {
|
||||||
throw Closed("changeRecord", db->name, name);
|
throw Closed("changeRecord", db->name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
MDB_val lmdbKey = keySerializer.setData(key);
|
MDB_val lmdbKey = keySerializer->setData(key);
|
||||||
MDB_val lmdbData = valueSerializer.setData(value);
|
MDB_val lmdbData = valueSerializer->setData(value);
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
mdb_txn_begin(db->environment, NULL, 0, &txn);
|
mdb_txn_begin(db->environment, NULL, 0, &txn);
|
||||||
int rc;
|
int rc;
|
||||||
@ -80,13 +82,13 @@ void Core::DataBase::Table<K, V>::changeRecord(const K& key, const V& value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<class K, class V>
|
||||||
V Core::DataBase::Table<K, V>::getRecord(const K& key) const {
|
V DataBase::Table<K, V>::getRecord(const K& key) const {
|
||||||
if (!db->opened) {
|
if (!db->opened) {
|
||||||
throw Closed("getRecord", db->name, name);
|
throw Closed("getRecord", db->name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
MDB_val lmdbKey = keySerializer.setData(key);
|
MDB_val lmdbKey = keySerializer->setData(key);
|
||||||
MDB_val lmdbData;
|
MDB_val lmdbData;
|
||||||
|
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
@ -96,26 +98,25 @@ V Core::DataBase::Table<K, V>::getRecord(const K& key) const {
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
if (rc == MDB_NOTFOUND) {
|
if (rc == MDB_NOTFOUND) {
|
||||||
throw NotFound(std::to_string(key), db->name, name);
|
throw NotFound(toString(key), db->name, name);
|
||||||
} else {
|
} else {
|
||||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
V value;
|
V value = valueSerializer->deserialize(lmdbData);
|
||||||
lmdbData >> value;
|
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<class K, class V>
|
||||||
void Core::DataBase::Table<K, V>::removeRecord(const K& key) {
|
void DataBase::Table<K, V>::removeRecord(const K& key) {
|
||||||
if (!db->opened) {
|
if (!db->opened) {
|
||||||
throw Closed("removeRecord", db->name, name);
|
throw Closed("removeRecord", db->name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
MDB_val lmdbKey = keySerializer.setData(key);
|
MDB_val lmdbKey = keySerializer->setData(key);
|
||||||
|
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
int rc;
|
int rc;
|
||||||
@ -124,7 +125,7 @@ void Core::DataBase::Table<K, V>::removeRecord(const K& key) {
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
if (rc == MDB_NOTFOUND) {
|
if (rc == MDB_NOTFOUND) {
|
||||||
throw NotFound(std::to_string(key), db->name, name);
|
throw NotFound(toString(key), db->name, name);
|
||||||
} else {
|
} else {
|
||||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||||
}
|
}
|
||||||
@ -133,8 +134,29 @@ void Core::DataBase::Table<K, V>::removeRecord(const K& key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string std::to_string(const QString& str) {
|
template<class K, class V>
|
||||||
return str.toStdString();
|
int DataBase::Table<K, V>::createTable(MDB_txn* transaction) {
|
||||||
|
return makeTable<K>(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K>
|
||||||
|
inline int DataBase::_Table::makeTable(MDB_txn* transaction) {
|
||||||
|
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE, &dbi);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline int DataBase::_Table::makeTable<uint32_t>(MDB_txn* transaction) {
|
||||||
|
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline std::string DataBase::_Table::toString(const T& value) {
|
||||||
|
return std::to_string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline std::string DataBase::_Table::toString(const QString& value) {
|
||||||
|
return value.toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //CORE_TABLE_HPP
|
#endif //CORE_TABLE_HPP
|
||||||
|
Loading…
Reference in New Issue
Block a user