mirror of
https://gitlab.com/spaceti-app/integrations/common/server-sdk.git
synced 2026-07-12 12:50:50 +02:00
Adding database Table class for automated handling tables
This commit is contained in:
parent
b04332059f
commit
d98ddf6c5f
@ -26,6 +26,7 @@ else:win32:CONFIG(debug, debug|release): LIBS += -L$$SDKDIR/debug/ -lserversdk
|
||||
else:unix: LIBS += -L$$SDKDIR/ -lserversdk -lz
|
||||
|
||||
QT += network sql
|
||||
CONFIG += c++14
|
||||
INCLUDEPATH += $$PWD/src/
|
||||
DEPENDPATH += $$PWD/src/serversdk
|
||||
|
||||
|
||||
61
src/serversdk/databasetable.cpp
Normal file
61
src/serversdk/databasetable.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "databasetable.h"
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <QMetaProperty>
|
||||
|
||||
namespace serversdk {
|
||||
|
||||
DatabaseTable::DatabaseTable(QObject *parent) : QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Creates universal variant structure to hold key / value pairs */
|
||||
QVariantMap DatabaseTable::toVariantMap()
|
||||
{
|
||||
QVariantMap variantMap;
|
||||
|
||||
const QMetaObject *metaObj = this->metaObject();
|
||||
qDebug() << "properties: ";
|
||||
for (int i = metaObj->propertyOffset(); i < metaObj->propertyCount(); ++i) {
|
||||
QMetaProperty prop = metaObj->property(i);
|
||||
// Skip non USER so -> ( Q_PROPERTY( ...... USER false ) only
|
||||
if (!prop.isUser())
|
||||
continue;
|
||||
|
||||
// Get key -> value pairs
|
||||
QString name = prop.name();
|
||||
QVariant::Type type = prop.type();
|
||||
QVariant value(type);
|
||||
value.setValue(prop.read(this));
|
||||
|
||||
variantMap.insert(name, value);
|
||||
}
|
||||
return variantMap;
|
||||
}
|
||||
|
||||
QString DatabaseTable::createTableSQL() const
|
||||
{
|
||||
QString sql = QString("CREATE TABLE %1").arg(this->metaObject()->className());
|
||||
|
||||
QVariantMap variantMap;
|
||||
|
||||
const QMetaObject *metaObj = this->metaObject();
|
||||
qDebug() << "properties: ";
|
||||
for (int i = metaObj->propertyOffset(); i < metaObj->propertyCount(); ++i) {
|
||||
QMetaProperty prop = metaObj->property(i);
|
||||
// Skip non USER so -> ( Q_PROPERTY( ...... USER false ) only
|
||||
if (!prop.isUser())
|
||||
continue;
|
||||
|
||||
QString name = prop.name();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace serversdk
|
||||
40
src/serversdk/databasetable.h
Normal file
40
src/serversdk/databasetable.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
|
||||
// Default TABLE_PROPERTY
|
||||
#define TABLE_PROPERTY(TYPE, NAME, SETNAME, INITVAL) \
|
||||
Q_PROPERTY(TYPE NAME READ NAME WRITE SETNAME NOTIFY NAME ## Changed USER true) \
|
||||
public: \
|
||||
TYPE NAME() const { return a_ ## NAME ; } \
|
||||
Q_SLOT void SETNAME(TYPE value) { \
|
||||
if (a_ ## NAME == value) return; \
|
||||
a_ ## NAME = value; \
|
||||
emit NAME ## Changed(value); \
|
||||
} \
|
||||
Q_SIGNAL void NAME ## Changed(TYPE value);\
|
||||
protected: \
|
||||
TYPE a_ ## NAME = INITVAL;
|
||||
|
||||
namespace serversdk {
|
||||
|
||||
class DatabaseTable : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
TABLE_PROPERTY(int, id, setId, 0);
|
||||
TABLE_PROPERTY(QString, name, setName, QString());
|
||||
public:
|
||||
explicit DatabaseTable(QObject *parent = nullptr);
|
||||
QVariantMap toVariantMap();
|
||||
QString createTableSQL() const;
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
} // namespace serversdk
|
||||
|
||||
134
src/serversdk/databaseutils.cpp
Normal file
134
src/serversdk/databaseutils.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include "databaseutils.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <QMetaProperty>
|
||||
|
||||
namespace serversdk {
|
||||
|
||||
/**
|
||||
* @brief DatabaseUtils::createTableSQL
|
||||
* @param table
|
||||
* @return
|
||||
*
|
||||
* @code{sql}
|
||||
* "CREATE TABLE colnod_subject ("
|
||||
"id character(36) primary key NOT NULL,"
|
||||
"description character varying(255),"
|
||||
"last_update timestamp NOT NULL,"
|
||||
"name character varying(255),"
|
||||
"pin character varying(255),"
|
||||
"last_modified timestamp,"
|
||||
"deleted BOOLEAN)"
|
||||
* @endcode
|
||||
*
|
||||
* Default types:
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
DatabaseUtils::DatabaseUtils(const QString type)
|
||||
: mSqlType(type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString DatabaseUtils::createTableSQL(const DatabaseTable *table, const QString tableName) const
|
||||
{
|
||||
QString userData;
|
||||
|
||||
if (tableName.isEmpty())
|
||||
return QString();
|
||||
|
||||
// out: "CREATE TABLE colnod_subject ( "
|
||||
QString sql = QString("CREATE TABLE %1 ( ").arg(tableName);
|
||||
|
||||
const QMetaObject *metaObj = table->metaObject();
|
||||
int total = metaObj->propertyCount();
|
||||
int first = true;
|
||||
for (int i = metaObj->propertyOffset(); i < total; ++i) {
|
||||
QMetaProperty prop = metaObj->property(i);
|
||||
// Skip non USER so -> ( Q_PROPERTY( ...... USER false ) only
|
||||
if (!prop.isUser())
|
||||
continue;
|
||||
|
||||
QString name = prop.name();
|
||||
QVariant::Type type = prop.type();
|
||||
QString textType;
|
||||
|
||||
|
||||
// Getting correct type based on QVariant
|
||||
if (sqlType() == "SQLITE") {
|
||||
textType = this->textSQLIteType(type);
|
||||
} else if (sqlType() == "PSQL") {
|
||||
qCDebug(sdkdb) << "Implemented only for SQLITE";
|
||||
return QString();
|
||||
|
||||
} else {
|
||||
qCDebug(sdkdb) << "Implemented only for SQLITE";
|
||||
return QString();
|
||||
}
|
||||
|
||||
// in: id TEXT
|
||||
// out: "CREATE TABLE colnod_subject ( id TEXT "
|
||||
sql += QString("%1 %2").arg(name,textType);
|
||||
|
||||
// in: PRIMARY KEY
|
||||
// out: "CREATE TABLE colnod_subject ( id TEXT PRIMARY KEY"
|
||||
if (first) { // first row
|
||||
sql += " PRIMARY KEY";
|
||||
first = false;
|
||||
}
|
||||
|
||||
// in: NOT NULL
|
||||
// out: "CREATE TABLE colnod_subject ( id TEXT PRIMARY KEY NOT NULL"
|
||||
if (!userData.isEmpty()) {
|
||||
sql += " " + userData;
|
||||
}
|
||||
|
||||
// out: "CREATE TABLE colnod_subject ( id TEXT PRIMARY KEY NOT NULL,"
|
||||
if (i < (total-1)) { // second last
|
||||
sql += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
// out: ".. subject_id TEXT)"
|
||||
sql+= " )";
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
QString DatabaseUtils::sqlType() const
|
||||
{
|
||||
return mSqlType;
|
||||
}
|
||||
|
||||
void DatabaseUtils::setSqlType(const QString &sqlType)
|
||||
{
|
||||
mSqlType = sqlType;
|
||||
}
|
||||
|
||||
QString DatabaseUtils::textSQLIteType(QVariant::Type type) const
|
||||
{
|
||||
switch (type) {
|
||||
case QVariant::Int:
|
||||
return QStringLiteral("INTEGER");
|
||||
break;
|
||||
case QVariant::Uuid:
|
||||
return QStringLiteral("TEXT");
|
||||
break;
|
||||
case QVariant::String:
|
||||
return QStringLiteral("TEXT");
|
||||
break;
|
||||
case QVariant::DateTime:
|
||||
return QStringLiteral("INTEGER");
|
||||
break;
|
||||
case QVariant::Bool:
|
||||
return QStringLiteral("INTEGER");
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace serversdk
|
||||
26
src/serversdk/databaseutils.h
Normal file
26
src/serversdk/databaseutils.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "databasetable.h"
|
||||
|
||||
namespace serversdk {
|
||||
|
||||
class DatabaseUtils : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DatabaseUtils(const QString type = "SQLITE");
|
||||
QString createTableSQL(const DatabaseTable *table, const QString table_name) const;
|
||||
|
||||
QString sqlType() const;
|
||||
void setSqlType(const QString &sqlType);
|
||||
|
||||
private:
|
||||
QString textSQLIteType(QVariant::Type type) const;
|
||||
private:
|
||||
QString mSqlType;
|
||||
};
|
||||
|
||||
} // namespace serversdk
|
||||
|
||||
@ -8,21 +8,25 @@ CONFIG += c++14
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/core.cpp \
|
||||
$$PWD/databasemanager.cpp \
|
||||
$$PWD/logger.cpp \
|
||||
$$PWD/loggermessage.cpp \
|
||||
$$PWD/requestmanager.cpp \
|
||||
$$PWD/request.cpp \
|
||||
$$PWD/utils.cpp \
|
||||
$$PWD/soaprequest.cpp
|
||||
core.cpp \
|
||||
databasemanager.cpp \
|
||||
databaseutils.cpp \
|
||||
logger.cpp \
|
||||
loggermessage.cpp \
|
||||
requestmanager.cpp \
|
||||
request.cpp \
|
||||
utils.cpp \
|
||||
soaprequest.cpp \
|
||||
databasetable.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/core.h \
|
||||
$$PWD/databasemanager.h \
|
||||
$$PWD/logger.h \
|
||||
$$PWD/loggermessage.h \
|
||||
$$PWD/requestmanager.h \
|
||||
$$PWD/request.h \
|
||||
$$PWD/utils.h \
|
||||
$$PWD/soaprequest.h
|
||||
core.h \
|
||||
databasemanager.h \
|
||||
databaseutils.h \
|
||||
logger.h \
|
||||
loggermessage.h \
|
||||
requestmanager.h \
|
||||
request.h \
|
||||
utils.h \
|
||||
soaprequest.h \
|
||||
databasetable.h
|
||||
|
||||
@ -3,6 +3,8 @@ TEMPLATE = subdirs
|
||||
SUBDIRS += \
|
||||
tst_soap \
|
||||
tst_request \
|
||||
tst_database/tst_database.pro \
|
||||
tst_database/tst_sqlite.pro \
|
||||
database/tst_databasemanager.pro \
|
||||
database/tst_sqlite.pro \
|
||||
database/tst_databasetable.pro \
|
||||
database/tst_databaseutils.pro \
|
||||
tst_utils
|
||||
|
||||
@ -33,4 +33,4 @@ void DatabaseTest::createDb_test()
|
||||
|
||||
QTEST_APPLESS_MAIN(DatabaseTest)
|
||||
|
||||
#include "tst_databasetest.moc"
|
||||
#include "tst_databasemanager.moc"
|
||||
11
test/auto/database/tst_databasemanager.pro
Normal file
11
test/auto/database/tst_databasemanager.pro
Normal file
@ -0,0 +1,11 @@
|
||||
QT += testlib
|
||||
QT -= gui
|
||||
|
||||
CONFIG += qt console warn_on depend_includepath testcase
|
||||
CONFIG -= app_bundle
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += tst_databasemanager.cpp
|
||||
|
||||
include(../../test.pri)
|
||||
54
test/auto/database/tst_databasetable.cpp
Normal file
54
test/auto/database/tst_databasetable.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "serversdk/databasetable.h"
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
|
||||
class BookTable : public serversdk::DatabaseTable
|
||||
{
|
||||
Q_OBJECT
|
||||
TABLE_PROPERTY(QUuid, uuid, setUuid, QUuid());
|
||||
TABLE_PROPERTY(int, id, setId, 0);
|
||||
TABLE_PROPERTY(QString, name, setName, "Test");
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DatabaseTableTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DatabaseTableTest();
|
||||
~DatabaseTableTest();
|
||||
|
||||
private slots:
|
||||
void constructor_test();
|
||||
void qvariant_test();
|
||||
|
||||
};
|
||||
|
||||
DatabaseTableTest::DatabaseTableTest()
|
||||
{
|
||||
}
|
||||
|
||||
DatabaseTableTest::~DatabaseTableTest()
|
||||
{
|
||||
}
|
||||
|
||||
void DatabaseTableTest::constructor_test()
|
||||
{
|
||||
auto table = std::make_unique<BookTable>();
|
||||
QCOMPARE(table->id(), 0);
|
||||
QCOMPARE(table->name(), QStringLiteral("Test"));
|
||||
}
|
||||
|
||||
void DatabaseTableTest::qvariant_test()
|
||||
{
|
||||
auto table = std::make_unique<BookTable>();
|
||||
QVariantMap map = table->toVariantMap();
|
||||
QCOMPARE(map.count(), 3);
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(DatabaseTableTest)
|
||||
|
||||
#include "tst_databasetable.moc"
|
||||
@ -6,6 +6,6 @@ CONFIG -= app_bundle
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += tst_databasetest.cpp
|
||||
SOURCES += tst_databasetable.cpp
|
||||
|
||||
include(../../test.pri)
|
||||
68
test/auto/database/tst_databaseutils.cpp
Normal file
68
test/auto/database/tst_databaseutils.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "serversdk/databaseutils.h"
|
||||
#include "serversdk/databasetable.h"
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
|
||||
class BookTable : public serversdk::DatabaseTable
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("default_table", "books")
|
||||
TABLE_PROPERTY(QUuid, id, set_id, QUuid());
|
||||
TABLE_PROPERTY(QString, description, set_description, "");
|
||||
TABLE_PROPERTY(QDateTime, last_update, set_last_update, QDateTime::fromSecsSinceEpoch(0));
|
||||
TABLE_PROPERTY(QString, name, set_name, QString());
|
||||
TABLE_PROPERTY(QString, pin, set_pin, QString());
|
||||
TABLE_PROPERTY(QDateTime, last_modified, set_last_modified, QDateTime::fromSecsSinceEpoch(0));
|
||||
TABLE_PROPERTY(bool, deleted, set_deleted, false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DatabaseUtilsTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DatabaseUtilsTest();
|
||||
~DatabaseUtilsTest();
|
||||
QString uuid() const;
|
||||
void setUuid(QString value);
|
||||
|
||||
private slots:
|
||||
void createTable_test();
|
||||
|
||||
};
|
||||
|
||||
DatabaseUtilsTest::DatabaseUtilsTest()
|
||||
{
|
||||
}
|
||||
|
||||
DatabaseUtilsTest::~DatabaseUtilsTest()
|
||||
{
|
||||
}
|
||||
|
||||
void DatabaseUtilsTest::createTable_test()
|
||||
{
|
||||
auto table = std::make_unique<BookTable>();
|
||||
|
||||
serversdk::DatabaseUtils utils;
|
||||
QString sql = utils.createTableSQL(table.get(), "subjects");
|
||||
|
||||
QString expected = "CREATE TABLE subjects ( "
|
||||
"id TEXT PRIMARY KEY, "
|
||||
"description TEXT, "
|
||||
"last_update INTEGER, "
|
||||
"name TEXT, "
|
||||
"pin TEXT, "
|
||||
"last_modified INTEGER, "
|
||||
"deleted INTEGER )";
|
||||
|
||||
QCOMPARE(sql, expected);
|
||||
}
|
||||
|
||||
|
||||
|
||||
QTEST_APPLESS_MAIN(DatabaseUtilsTest)
|
||||
|
||||
#include "tst_databaseutils.moc"
|
||||
11
test/auto/database/tst_databaseutils.pro
Normal file
11
test/auto/database/tst_databaseutils.pro
Normal file
@ -0,0 +1,11 @@
|
||||
QT += testlib
|
||||
QT -= gui
|
||||
|
||||
CONFIG += qt console warn_on depend_includepath testcase
|
||||
CONFIG -= app_bundle
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += tst_databaseutils.cpp
|
||||
|
||||
include(../../test.pri)
|
||||
Loading…
x
Reference in New Issue
Block a user