server-sdk/src/serversdk/databasetable.h
2019-11-19 13:40:19 +01:00

164 lines
4.1 KiB
C++

#pragma once
#include <QObject>
#include <QVariantMap>
#include <memory>
#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 {
// Default TABLE_PROPERTY
/** # DatabaseTable
*
* Class for automatic CREATE/INSERT/SELECT and JSON handling
*
* ## Usage
*
* 1. define custom class by subclassint serversdk::DatabaseTable
*
* @code
class Names : public serversdk::DatabaseTable {
Q_OBJECT
TABLE_PROPERTY(int, id, set_id, 0);
TABLE_PROPERTY(QString, name, set_name, 0);
};
int main() {
// Prepare temporary path for database
QTemporaryDir dir;
QString dbpath = dir.path() + "/testdb.sqlite";
serversdk::DatabaseManager db;
db.openSQLite(dbpath);
Names names;
// CREATE TABLE
serversdk::DatabaseUtils utils(&db);
QSqlQuery query = utils.createTable(&names, "names");
// INSERT INTO TABLE
names.set_id(2);
names.set_name("Testname");
utils.insertIntoTable(&names, "names");
// SELECT FROM TABLE
QSqlQuery selectSQL = db.execPlainSql("SELECT * FROM names");
auto list = utils.tableFromQuery<Names>(selectSQL);
}
*
* @endcode
*
* ## Warning
*
* Derivation of derived class from DatabaseTable does not work ( missing properties )
*
* @code
* in: TABLE_PROPERTY
* Q_PROPERTY
* @endcode
*
*
*
*
*/
class DatabaseTable : public QObject
{
Q_OBJECT
public:
explicit DatabaseTable(QObject *parent = nullptr);
/**
* @brief Creates JSON from QMetaObject data ( Q_PROPERTY ) -> TABLE_PROPERTY
* @return text json e.g. { "id": 00344 }
*/
virtual QByteArray jsonData() const;
/**
* @brief Populates object with JSON {"id": 300} )
* @return true if success TODO: not implemented corrrectly
*/
virtual bool fromJson(const QByteArray &data);
/**
* @brief Creates VariantMap from QMetaObject data ( Q_PROPERTY )
* @return QVariantMap containing property with key/value pairs
*/
virtual QVariantMap toVariantMap() const;
/**
* @brief Populates object with QVariantMap
* @return true if success TODO: not implemented corrrectly
*/
bool fromVariantMap(const QVariantMap &variantMap);
/**
* @brief Creates QList of objects from SELECT query
* @param rows with QVariantMap ( rows of key/value pairs )
* @return List of objects
*/
static QList<std::shared_ptr<DatabaseTable>> fromListVariantMap(const QList<QVariantMap> &listMap);
/**
* @brief Convert QVariant type to SQL type
* @param QVariant type ( QString, int, QDateTime )
* @return text form of database type ( INTEGER, TEXT )
*/
virtual QString textSQLIteType(QVariant::Type type) const;
/**
* @brief Convert QVariant type to SQL type
* @param QVariant type ( QString, int, QDateTime )
* @return text form of database type ( INTEGER, TEXT )
*
* # Sublassing
*
* When it is neccessary to use different type it is possible to subclass and override this method.
*
* @code
class BackendTable : public serversdk::DatabaseTable
{
QString textPostgresType(QVariant::Type type) const override;
}
BackendTable::textPostgresType(QVariant::Type type) const override
{
// For case when saving date time as ms since epoch
if (type == QVariant::DateTime) {
return QStringLiteral("INTEGER");
}
return DatabaseTable::textPostgresType(type);
}
* @endcode
*
*
*
*
*/
virtual QString textPostgresType(QVariant::Type type) const;
};
} // namespace serversdk