some more primitive specializations, counting rows, dropping tables, tests
This commit is contained in:
parent
047f96b54a
commit
2f34fa69e8
@ -44,6 +44,14 @@ set(HEADERS
|
||||
serializer_uint16.hpp
|
||||
serializer_uint32.hpp
|
||||
serializer_uint64.hpp
|
||||
serializer_int8.hpp
|
||||
serializer_int16.hpp
|
||||
serializer_int32.hpp
|
||||
serializer_int64.hpp
|
||||
serializer_float.hpp
|
||||
serializer_double.hpp
|
||||
serializer_stdstring.hpp
|
||||
serializer_qstring.hpp
|
||||
)
|
||||
|
||||
if (BUILD_STATIC)
|
||||
|
24
database.cpp
24
database.cpp
@ -85,7 +85,7 @@ void DataBase::open()
|
||||
bool DataBase::removeDirectory()
|
||||
{
|
||||
if (opened) {
|
||||
throw Opened(name, "");
|
||||
throw Opened(name, "remove database directory");
|
||||
}
|
||||
QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
|
||||
path += "/" + getName();
|
||||
@ -108,3 +108,25 @@ 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<const std::string, _Table*>& pair : tables) {
|
||||
rc = pair.second->drop(txn);
|
||||
if (rc) {
|
||||
throw Unknown(name, mdb_strerror(rc), pair.first);
|
||||
}
|
||||
}
|
||||
|
||||
mdb_txn_commit(txn);
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
bool ready() const;
|
||||
bool removeDirectory();
|
||||
QString getName() const;
|
||||
void drop();
|
||||
|
||||
template <class K, class V>
|
||||
Table<K, V>* addTable(const std::string& name);
|
||||
@ -72,7 +73,7 @@ private:
|
||||
template <class K, class V>
|
||||
DataBase::Table<K, V>* DataBase::addTable(const std::string& p_name) {
|
||||
if (opened) {
|
||||
throw Opened(name, p_name);
|
||||
throw Opened(name, "add table " + p_name);
|
||||
}
|
||||
DataBase::Table<K, V>* table = new DataBase::Table<K, V>(p_name, this);
|
||||
tables.insert(std::make_pair(p_name, (_Table*)table));
|
||||
|
@ -38,7 +38,7 @@ std::string DataBase::Directory::getMessage() const {
|
||||
DataBase::Closed::Closed(
|
||||
const std::string& p_operation,
|
||||
const std::string& p_dbName,
|
||||
const std::string& p_tableName
|
||||
const std::optional<std::string>& p_tableName
|
||||
):
|
||||
Exception(),
|
||||
operation(p_operation),
|
||||
@ -46,22 +46,25 @@ DataBase::Closed::Closed(
|
||||
tableName(p_tableName) {}
|
||||
|
||||
std::string DataBase::Closed::getMessage() const {
|
||||
return "An attempt to perform operation " + operation
|
||||
+ " on closed database " + dbName
|
||||
+ " on table " + tableName;
|
||||
std::string msg = "An attempt to perform operation " + operation
|
||||
+ " on closed database " + dbName;
|
||||
if (tableName.has_value()) {
|
||||
msg += + " on table " + tableName.value();
|
||||
}
|
||||
return msg;
|
||||
|
||||
}
|
||||
|
||||
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_action):
|
||||
Exception(),
|
||||
dbName(p_dbName),
|
||||
tableName(p_tableName) {}
|
||||
action(p_action) {}
|
||||
|
||||
|
||||
std::string DataBase::Opened::getMessage() const {
|
||||
return "An attempt to add table " + tableName
|
||||
+ " to the database " + dbName
|
||||
+ " but it's can't be done because the DataBase is already opened."
|
||||
+ " Please add all tables before opening DataBase.";
|
||||
return "An attempt to " + action
|
||||
+ " (the database " + dbName
|
||||
+ ") but it's can't be done because the DataBase is already opened";
|
||||
}
|
||||
|
||||
DataBase::NotFound::NotFound(
|
||||
|
@ -43,23 +43,23 @@ private:
|
||||
|
||||
class DataBase::Closed : public DataBase::Exception {
|
||||
public:
|
||||
Closed(const std::string& p_operation, const std::string& dbName, const std::string& tableName);
|
||||
Closed(const std::string& p_operation, const std::string& dbName, const std::optional<std::string>& tableName = std::nullopt);
|
||||
|
||||
std::string getMessage() const;
|
||||
private:
|
||||
std::string operation;
|
||||
std::string dbName;
|
||||
std::string tableName;
|
||||
std::optional<std::string> tableName;
|
||||
};
|
||||
|
||||
class DataBase::Opened : public DataBase::Exception {
|
||||
public:
|
||||
Opened(const std::string& dbName, const std::string& tableName);
|
||||
Opened(const std::string& dbName, const std::string& action);
|
||||
|
||||
std::string getMessage() const;
|
||||
private:
|
||||
std::string dbName;
|
||||
std::string tableName;
|
||||
std::string action;
|
||||
};
|
||||
|
||||
class DataBase::NotFound : public DataBase::Exception {
|
||||
|
@ -51,5 +51,13 @@ private:
|
||||
#include "serializer_uint32.hpp"
|
||||
#include "serializer_uint16.hpp"
|
||||
#include "serializer_uint8.hpp"
|
||||
#include "serializer_int64.hpp"
|
||||
#include "serializer_int32.hpp"
|
||||
#include "serializer_int16.hpp"
|
||||
#include "serializer_int8.hpp"
|
||||
#include "serializer_float.hpp"
|
||||
#include "serializer_double.hpp"
|
||||
#include "serializer_stdstring.hpp"
|
||||
#include "serializer_qstring.hpp"
|
||||
|
||||
#endif // CORE_DATABASE_SERIALIZER_H
|
||||
|
53
serializer_double.hpp
Normal file
53
serializer_double.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_DATABASE_SERIALIZER_DOUBLE_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_DOUBLE_HPP
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<double>
|
||||
{
|
||||
public:
|
||||
Serializer():value(0) {};
|
||||
Serializer(const double& p_value):value(p_value) {};
|
||||
~Serializer() {};
|
||||
|
||||
double deserialize(const MDB_val& data) {
|
||||
std::memcpy(&value, data.mv_data, 8);
|
||||
return value;
|
||||
};
|
||||
MDB_val setData(const double& data) {
|
||||
value = data;
|
||||
return getData();
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 8;
|
||||
return result;
|
||||
};
|
||||
void clear() {}; //not possible;
|
||||
|
||||
private:
|
||||
double value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_DOUBLE_HPP
|
||||
|
||||
|
||||
|
53
serializer_float.hpp
Normal file
53
serializer_float.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_DATABASE_SERIALIZER_FLOAT_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_FLOAT_HPP
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<float>
|
||||
{
|
||||
public:
|
||||
Serializer():value(0) {};
|
||||
Serializer(const float& p_value):value(p_value) {};
|
||||
~Serializer() {};
|
||||
|
||||
float deserialize(const MDB_val& data) {
|
||||
std::memcpy(&value, data.mv_data, 4);
|
||||
return value;
|
||||
};
|
||||
MDB_val setData(const float& 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:
|
||||
float value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_FLOAT_HPP
|
||||
|
||||
|
||||
|
50
serializer_int16.hpp
Normal file
50
serializer_int16.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_INT16_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_INT16_HPP
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<int16_t>
|
||||
{
|
||||
public:
|
||||
Serializer():value(0) {};
|
||||
Serializer(const int16_t& p_value):value(p_value) {};
|
||||
~Serializer() {};
|
||||
|
||||
int16_t deserialize(const MDB_val& data) {
|
||||
std::memcpy(&value, data.mv_data, 2);
|
||||
return value;
|
||||
};
|
||||
MDB_val setData(const int16_t& data) {
|
||||
value = data;
|
||||
return getData();
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 2;
|
||||
return result;
|
||||
};
|
||||
void clear() {}; //not possible;
|
||||
|
||||
private:
|
||||
int16_t value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_INT16_HPP
|
53
serializer_int32.hpp
Normal file
53
serializer_int32.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_DATABASE_SERIALIZER_INT32_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_INT32_HPP
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<int32_t>
|
||||
{
|
||||
public:
|
||||
Serializer():value(0) {};
|
||||
Serializer(const int32_t& p_value):value(p_value) {};
|
||||
~Serializer() {};
|
||||
|
||||
int32_t deserialize(const MDB_val& data) {
|
||||
std::memcpy(&value, data.mv_data, 4);
|
||||
return value;
|
||||
};
|
||||
MDB_val setData(const int32_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:
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_INT32_HPP
|
||||
|
||||
|
||||
|
53
serializer_int64.hpp
Normal file
53
serializer_int64.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_DATABASE_SERIALIZER_INT64_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_INT64_HPP
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<int64_t>
|
||||
{
|
||||
public:
|
||||
Serializer():value(0) {};
|
||||
Serializer(const int64_t& p_value):value(p_value) {};
|
||||
~Serializer() {};
|
||||
|
||||
int64_t deserialize(const MDB_val& data) {
|
||||
std::memcpy(&value, data.mv_data, 8);
|
||||
return value;
|
||||
};
|
||||
MDB_val setData(const int64_t& data) {
|
||||
value = data;
|
||||
return getData();
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 8;
|
||||
return result;
|
||||
};
|
||||
void clear() {}; //not possible;
|
||||
|
||||
private:
|
||||
int64_t value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_INT64_HPP
|
||||
|
||||
|
||||
|
53
serializer_int8.hpp
Normal file
53
serializer_int8.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_DATABASE_SERIALIZER_INT8_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_INT8_HPP
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<int8_t>
|
||||
{
|
||||
public:
|
||||
Serializer():value(0) {};
|
||||
Serializer(const int8_t& p_value):value(p_value) {};
|
||||
~Serializer() {};
|
||||
|
||||
int8_t deserialize(const MDB_val& data) {
|
||||
std::memcpy(&value, data.mv_data, 1);
|
||||
return value;
|
||||
};
|
||||
MDB_val setData(const int8_t& data) {
|
||||
value = data;
|
||||
return getData();
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 1;
|
||||
return result;
|
||||
};
|
||||
void clear() {}; //not possible;
|
||||
|
||||
private:
|
||||
int8_t value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_INT8_HPP
|
||||
|
||||
|
||||
|
58
serializer_qstring.hpp
Normal file
58
serializer_qstring.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
// 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_QSTRING_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_QSTRING_HPP
|
||||
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<QString>
|
||||
{
|
||||
public:
|
||||
Serializer():value() {};
|
||||
Serializer(const QString& p_value):value(p_value.toUtf8()) {};
|
||||
~Serializer() {};
|
||||
|
||||
QString deserialize(const MDB_val& data) {
|
||||
value = QByteArray((char*)data.mv_data, data.mv_size);
|
||||
return QString::fromUtf8(value);
|
||||
};
|
||||
MDB_val setData(const QString& data) {
|
||||
value = data.toUtf8();
|
||||
return getData();
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = value.data();
|
||||
result.mv_size = value.size();
|
||||
return result;
|
||||
};
|
||||
void clear() {}; //not possible;
|
||||
|
||||
private:
|
||||
QByteArray value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_QSTRING_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
|
54
serializer_stdstring.hpp
Normal file
54
serializer_stdstring.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// 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_STDSTRING_HPP
|
||||
#define CORE_DATABASE_SERIALIZER_STDSTRING_HPP
|
||||
|
||||
template<>
|
||||
class DataBase::Serializer<std::string>
|
||||
{
|
||||
public:
|
||||
Serializer():value() {};
|
||||
Serializer(const std::string& p_value):value(p_value) {};
|
||||
~Serializer() {};
|
||||
|
||||
std::string deserialize(const MDB_val& data) {
|
||||
value = std::string((char*)data.mv_data, data.mv_size);
|
||||
return value;
|
||||
};
|
||||
MDB_val setData(const std::string& data) {
|
||||
value = data;
|
||||
return getData();
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = (char*)value.c_str();
|
||||
result.mv_size = value.size();
|
||||
return result;
|
||||
};
|
||||
void clear() {}; //not possible;
|
||||
|
||||
private:
|
||||
std::string value;
|
||||
};
|
||||
|
||||
|
||||
#endif //CORE_DATABASE_SERIALIZER_STDSTRING_HPP
|
||||
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value,
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 2;
|
||||
return result;
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value,
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 4;
|
||||
return result;
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value,
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 8;
|
||||
return result;
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
};
|
||||
MDB_val getData() {
|
||||
MDB_val result;
|
||||
result.mv_data = &value,
|
||||
result.mv_data = &value;
|
||||
result.mv_size = 1;
|
||||
return result;
|
||||
};
|
||||
|
43
table.cpp
43
table.cpp
@ -24,3 +24,46 @@ DataBase::_Table::_Table(const std::string& p_name, DataBase* parent):
|
||||
}
|
||||
|
||||
DataBase::_Table::~_Table() {}
|
||||
|
||||
|
||||
void DataBase::_Table::drop()
|
||||
{
|
||||
if (!db->opened) {
|
||||
throw Closed("drop", db->name, name);
|
||||
}
|
||||
|
||||
MDB_txn *txn;
|
||||
int rc = mdb_txn_begin(db->environment, NULL, 0, &txn);
|
||||
if (rc) {
|
||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||
}
|
||||
rc = drop(txn);
|
||||
if (rc) {
|
||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||
}
|
||||
|
||||
mdb_txn_commit(txn);
|
||||
}
|
||||
|
||||
int DataBase::_Table::drop(MDB_txn* transaction)
|
||||
{
|
||||
return mdb_drop(transaction, dbi, 0);
|
||||
}
|
||||
|
||||
uint32_t DataBase::_Table::count() const
|
||||
{
|
||||
if (!db->opened) {
|
||||
throw Closed("count", db->name, name);
|
||||
}
|
||||
|
||||
MDB_txn *txn;
|
||||
MDB_stat stat;
|
||||
int rc = mdb_txn_begin(db->environment, NULL, 0, &txn);
|
||||
rc = mdb_stat(txn, dbi, &stat);
|
||||
if (rc) {
|
||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||
}
|
||||
uint32_t amount = stat.ms_entries;
|
||||
mdb_txn_abort(txn);
|
||||
return amount;
|
||||
}
|
||||
|
11
table.h
11
table.h
@ -21,12 +21,19 @@
|
||||
#include "serializer.h"
|
||||
|
||||
class DataBase::_Table {
|
||||
public:
|
||||
friend class DataBase;
|
||||
protected:
|
||||
_Table(const std::string& name, DataBase* parent);
|
||||
virtual ~_Table();
|
||||
|
||||
virtual int createTable(MDB_txn * transaction) = 0;
|
||||
virtual int drop(MDB_txn * transaction);
|
||||
|
||||
public:
|
||||
virtual void drop();
|
||||
virtual uint32_t count() const;
|
||||
|
||||
protected:
|
||||
MDB_dbi dbi;
|
||||
DataBase* db;
|
||||
const std::string name;
|
||||
@ -40,7 +47,7 @@ protected:
|
||||
};
|
||||
|
||||
template <class K, class V>
|
||||
class DataBase::Table : private DataBase::_Table {
|
||||
class DataBase::Table : public DataBase::_Table {
|
||||
friend class DataBase;
|
||||
private:
|
||||
Table(const std::string& name, DataBase* parent);
|
||||
|
20
table.hpp
20
table.hpp
@ -164,6 +164,26 @@ inline int DataBase::_Table::makeTable<uint8_t>(MDB_txn* transaction) {
|
||||
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int DataBase::_Table::makeTable<int64_t>(MDB_txn* transaction) {
|
||||
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int DataBase::_Table::makeTable<int32_t>(MDB_txn* transaction) {
|
||||
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int DataBase::_Table::makeTable<int16_t>(MDB_txn* transaction) {
|
||||
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int DataBase::_Table::makeTable<int8_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);
|
||||
|
112
test/basic.cpp
112
test/basic.cpp
@ -12,8 +12,7 @@ protected:
|
||||
t1(db->getTable<uint32_t, uint32_t>("table1")),
|
||||
t2(db->getTable<QString, QString>("table2")) {}
|
||||
|
||||
~DataBaseTest() {
|
||||
}
|
||||
~DataBaseTest() {}
|
||||
|
||||
static void SetUpTestSuite() {
|
||||
if (db == nullptr) {
|
||||
@ -43,7 +42,12 @@ TEST_F(DataBaseTest, RemovingDirectory) {
|
||||
EXPECT_EQ(db->removeDirectory(), true);
|
||||
}
|
||||
|
||||
TEST_F(DataBaseTest, OpeningDatabase) {
|
||||
TEST_F(DataBaseTest, OpeningClosingDatabase) {
|
||||
EXPECT_EQ(db->ready(), false);
|
||||
db->open();
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
db->close();
|
||||
EXPECT_EQ(db->ready(), false);
|
||||
db->open();
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
}
|
||||
@ -51,16 +55,112 @@ TEST_F(DataBaseTest, OpeningDatabase) {
|
||||
TEST_F(DataBaseTest, AddingIntegerKey) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
t1->addRecord(1, 2);
|
||||
t1->addRecord(2, 2);
|
||||
t1->addRecord(3, 15);
|
||||
EXPECT_EQ(t1->getRecord(1), 2);
|
||||
}
|
||||
|
||||
TEST_F(DataBaseTest, AddingQStringKey) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
t2->addRecord("hello", "world");
|
||||
t2->addRecord("aaa", "gagdfsdf");
|
||||
t2->addRecord("sdfhga", "DSFFDG");
|
||||
t2->addRecord("sdfsda", "shgsdgfa");
|
||||
EXPECT_EQ(t2->getRecord("hello"), "world");
|
||||
}
|
||||
|
||||
TEST_F(DataBaseTest, ClosingDatabase) {
|
||||
db->close();
|
||||
EXPECT_EQ(db->ready(), false);
|
||||
TEST_F(DataBaseTest, AddingRepeatingIntegerKey) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
bool thrown = false;
|
||||
try {
|
||||
t1->addRecord(3, 24);
|
||||
} catch (const DataBase::Exist e) {
|
||||
thrown = true;
|
||||
}
|
||||
ASSERT_EQ(thrown, true) << "The expected behaviour is to throw exception on duplicate, but it didn't happened";
|
||||
EXPECT_EQ(t1->getRecord(3), 15);
|
||||
}
|
||||
|
||||
TEST_F(DataBaseTest, AddingRepeatingStringKey) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
bool thrown = false;
|
||||
try {
|
||||
t2->addRecord("sdfhga", "world");
|
||||
} catch (const DataBase::Exist e) {
|
||||
thrown = true;
|
||||
}
|
||||
ASSERT_EQ(thrown, true) << "The expected behaviour is to throw exception on duplicate, but it didn't happened";
|
||||
EXPECT_EQ(t2->getRecord("sdfhga"), "DSFFDG");
|
||||
}
|
||||
|
||||
TEST_F(DataBaseTest, GettingNotExistingKeys) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
bool thrown = false;
|
||||
try {
|
||||
QString wrong = t2->getRecord("almonds");
|
||||
} catch (const DataBase::NotFound e) {
|
||||
thrown = true;
|
||||
}
|
||||
ASSERT_EQ(thrown, true) << "The expected behaviour is to throw exception on duplicate, but it didn't happened";
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
uint32_t wrong = t1->getRecord(64);
|
||||
} catch (const DataBase::NotFound e) {
|
||||
thrown = true;
|
||||
}
|
||||
ASSERT_EQ(thrown, true) << "The expected behaviour is to throw exception on duplicate, but it didn't happened";
|
||||
}
|
||||
|
||||
TEST_F(DataBaseTest, Persistence) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
db->close();
|
||||
delete db;
|
||||
|
||||
db = new DataBase("testBase");
|
||||
t1 = db->addTable<uint32_t, uint32_t>("table1");
|
||||
t2 = db->addTable<QString, QString>("table2");
|
||||
db->open();
|
||||
|
||||
EXPECT_EQ(t1->getRecord(3), 15);
|
||||
EXPECT_EQ(t1->getRecord(1), 2);
|
||||
EXPECT_EQ(t1->getRecord(2), 2);
|
||||
EXPECT_EQ(t2->getRecord("hello"), "world");
|
||||
EXPECT_EQ(t2->getRecord("aaa"), "gagdfsdf");
|
||||
EXPECT_EQ(t2->getRecord("sdfhga"), "DSFFDG");
|
||||
EXPECT_EQ(t2->getRecord("sdfsda"), "shgsdgfa");
|
||||
|
||||
bool thrown = false;
|
||||
try {
|
||||
QString wrong = t2->getRecord("cats");
|
||||
} catch (const DataBase::NotFound e) {
|
||||
thrown = true;
|
||||
}
|
||||
ASSERT_EQ(thrown, true) << "The expected behaviour is to throw exception on duplicate, but it didn't happened";
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
uint32_t wrong = t1->getRecord(7893);
|
||||
} catch (const DataBase::NotFound e) {
|
||||
thrown = true;
|
||||
}
|
||||
ASSERT_EQ(thrown, true) << "The expected behaviour is to throw exception on duplicate, but it didn't happened";
|
||||
}
|
||||
|
||||
TEST_F(DataBaseTest, CountAndDrop) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
EXPECT_EQ(t1->count(), 3);
|
||||
EXPECT_EQ(t2->count(), 4);
|
||||
|
||||
db->drop();
|
||||
|
||||
EXPECT_EQ(t1->count(), 0);
|
||||
EXPECT_EQ(t2->count(), 0);
|
||||
|
||||
t1->addRecord(2, 2);
|
||||
t2->addRecord("sdfhga", "world");
|
||||
|
||||
EXPECT_EQ(t1->count(), 1);
|
||||
EXPECT_EQ(t2->count(), 1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user