Added support for database maintenance. Added core plugin.

print
Josef Rokos 9 years ago
parent 1264b2547a
commit 7c90c66468

@ -4,7 +4,7 @@
# #
#------------------------------------------------- #-------------------------------------------------
QT += core gui QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

@ -20,33 +20,6 @@ public:
virtual ~AutoTableModel() {} virtual ~AutoTableModel() {}
private:
class Comparator
{
public:
Comparator(const QString &property, Qt::SortOrder order)
{
m_property = property;
m_order = order;
}
bool operator()(QSharedPointer<T> entA, QSharedPointer<T> entB) {
QObject *rawEntityA = (QObject*)entA.data();
QObject *rawEntityB = (QObject*)entB.data();
if (m_order == Qt::AscendingOrder) {
return rawEntityA->property(m_property.toStdString().c_str()) < rawEntityB->property(m_property.toStdString().c_str());
} else {
return rawEntityB->property(m_property.toStdString().c_str()) < rawEntityA->property(m_property.toStdString().c_str());
}
}
private:
QString m_property;
Qt::SortOrder m_order;
};
// QAbstractItemModel interface // QAbstractItemModel interface
public: public:
int rowCount(const QModelIndex &parent = QModelIndex()) const int rowCount(const QModelIndex &parent = QModelIndex()) const
@ -117,10 +90,18 @@ public:
} }
beginResetModel(); beginResetModel();
QObject *rawEntity = (QObject*)m_list.at(0).data(); QObject *rawEntity = (QObject*)m_list.at(0).data();
Comparator c(rawEntity->metaObject()->property(column + 1).name(), order); const char *prop = rawEntity->metaObject()->property(column + 1).name();
std::sort(m_list.begin(), m_list.end(), [prop, order](QSharedPointer<T> entA, QSharedPointer<T> entB) -> bool {
if (order == Qt::AscendingOrder) {
return ((QObject*)entA.data())->property(prop) < ((QObject*)entB.data())->property(prop);
} else {
return ((QObject*)entB.data())->property(prop) < ((QObject*)entA.data())->property(prop);
}
});
std::sort(m_list.begin(), m_list.end(), c);
endResetModel(); endResetModel();
} }

@ -1,10 +1,16 @@
#include <QDir> #include <QDir>
#include <QApplication> #include <QApplication>
#include <QPluginLoader> #include <QPluginLoader>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlResult>
#include <QSqlError>
#include <QDebug>
#include <odb/sqlite/database.hxx> #include <odb/sqlite/database.hxx>
#include "core.h" #include "core.h"
#include "coreplugin.h"
Context &Context::instance() Context &Context::instance()
{ {
@ -17,8 +23,22 @@ QList<IPlugin *> Context::plugins()
return m_plugins; return m_plugins;
} }
IPlugin *Context::plugin(const QString &pluginId)
{
QList<IPlugin*>::iterator it = std::find_if(m_plugins.begin(), m_plugins.end(), [&pluginId](IPlugin *p) { return p->pluginId() == pluginId; });
if (it != m_plugins.end())
{
return *it;
}
return NULL;
}
void Context::loadPlugins() void Context::loadPlugins()
{ {
IPlugin *corePlugin = new CorePlugin();
m_plugins.append(corePlugin);
QDir pluginsDir(qApp->applicationDirPath() + "/../../plugins"); QDir pluginsDir(qApp->applicationDirPath() + "/../../plugins");
foreach (QString fileName, pluginsDir.entryList(QStringList() << "*.so" << "*.dll")) { foreach (QString fileName, pluginsDir.entryList(QStringList() << "*.so" << "*.dll")) {
@ -41,6 +61,7 @@ void Context::openDb(const QString &path)
delete m_db; delete m_db;
} }
checkDb(path);
m_db = new odb::sqlite::database(path.toStdString()); m_db = new odb::sqlite::database(path.toStdString());
} }
@ -48,3 +69,68 @@ Context::Context()
{ {
m_db = NULL; m_db = NULL;
} }
void Context::checkDb(const QString &path)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(path);
db.open();
QSqlQuery q(db);
QString verSql = "SELECT pluginId, schemaVersion FROM system";
QString createSysSql = "CREATE TABLE \"system\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"pluginId\" TEXT NULL, \"schemaVersion\" TEXT NULL)";
if (q.exec(verSql))
{
QMap<QString, int> schemas;
while (q.next())
{
schemas[q.value("pluginId").toString()] = q.value("schemaVersion").toInt();
}
checkSchema(db, schemas);
}
else
{
q.exec(createSysSql);
checkSchema(db, QMap<QString, int>());
}
db.close();
}
void Context::checkSchema(const QSqlDatabase &db, const QMap<QString, int> &schemaMap)
{
foreach (IPlugin *plugin, m_plugins) {
if (!schemaMap.contains(plugin->pluginId()) || schemaMap[plugin->pluginId()] < plugin->schemaVersion())
{
int ver = schemaMap[plugin->pluginId()];
for (int i = 0; i < plugin->schemas().count(); i++)
{
if (!schemaMap.contains(plugin->pluginId()) || i >= ver)
{
QString sql = plugin->schemas()[i];
QSqlQuery q(db);
QStringList sqlList = sql.split(";");
foreach (QString s, sqlList) {
if (!q.exec(s))
{
qDebug() << q.lastError().text();
}
}
if (ver == 0)
{
sql = "INSERT INTO system(pluginId, schemaVersion) VALUES('" + plugin->pluginId() + "', 1)";
}
else
{
sql = "UPDATE system SET schemaVersion = " + QString::number(i + 1) + " WHERE pluginId = '" + plugin->pluginId() + "'";
}
q.exec(sql);
}
}
}
}
}

@ -2,6 +2,10 @@
#define CONTEXT_H #define CONTEXT_H
#include <QList> #include <QList>
#include <QMap>
#include <QString>
#include <QSqlDatabase>
#include "core_global.h" #include "core_global.h"
#include "transaction.h" #include "transaction.h"
@ -14,6 +18,7 @@ class CORESHARED_EXPORT Context
public: public:
static Context &instance(); static Context &instance();
QList<IPlugin*> plugins(); QList<IPlugin*> plugins();
IPlugin *plugin(const QString &pluginId);
void loadPlugins(); void loadPlugins();
void openDb(const QString &path); void openDb(const QString &path);
odb::database *db() { return m_db; } odb::database *db() { return m_db; }
@ -22,6 +27,9 @@ private:
Context(); Context();
QList<IPlugin*> m_plugins; QList<IPlugin*> m_plugins;
odb::database *m_db; odb::database *m_db;
void checkDb(const QString &path);
void checkSchema(const QSqlDatabase &db, const QMap<QString, int> &schemaMap);
}; };
#endif // CONTEXT_H #endif // CONTEXT_H

@ -4,7 +4,7 @@
# #
#------------------------------------------------- #-------------------------------------------------
QT += widgets QT += widgets sql
TARGET = core TARGET = core
TEMPLATE = lib TEMPLATE = lib
@ -18,7 +18,8 @@ SOURCES += \
transaction.cpp \ transaction.cpp \
emptystringvalidator.cpp \ emptystringvalidator.cpp \
data/role.cpp \ data/role.cpp \
data/permission.cpp data/permission.cpp \
coreplugin.cpp
HEADERS += core.h\ HEADERS += core.h\
core_global.h \ core_global.h \
@ -34,7 +35,8 @@ HEADERS += core.h\
emptystringvalidator.h \ emptystringvalidator.h \
data/role.h \ data/role.h \
data/permission.h \ data/permission.h \
data/core-data.h data/core-data.h \
coreplugin.h
unix { unix {
target.path = /usr/lib target.path = /usr/lib
@ -45,3 +47,9 @@ ODB_FILES = core/data/core-data.h
H_DIR = $$PWD/data/*.h H_DIR = $$PWD/data/*.h
include(../odb.pri) include(../odb.pri)
RESOURCES += \
rc.qrc
DISTFILES += \
metaData.json

@ -0,0 +1,25 @@
#include "coreplugin.h"
#include <QJsonDocument>
#include <QFile>
CorePlugin::CorePlugin()
{
Q_INIT_RESOURCE(rc);
QFile f(":/metaData.json");
f.open(QIODevice::ReadOnly | QIODevice::Text);
QJsonDocument d = QJsonDocument::fromJson(f.readAll());
init(d.object());
f.close();
}
CorePlugin::~CorePlugin()
{
}
void CorePlugin::initServiceUi()
{
m_service = NULL;
m_ui = NULL;
}

@ -0,0 +1,17 @@
#ifndef COREPLUGIN_H
#define COREPLUGIN_H
#include "imetadataplugin.h"
class CorePlugin : public IMetaDataPlugin
{
public:
CorePlugin();
~CorePlugin();
// IMetaDataPlugin interface
protected:
virtual void initServiceUi();
};
#endif // COREPLUGIN_H

@ -1,6 +1,7 @@
#include "imetadataplugin.h" #include "imetadataplugin.h"
#include <QJsonValue> #include <QJsonValue>
#include <QJsonArray>
#include <QLocale> #include <QLocale>
#include <QDebug> #include <QDebug>
@ -27,6 +28,16 @@ QString IMetaDataPlugin::pluginDescription()
return m_description; return m_description;
} }
int IMetaDataPlugin::schemaVersion()
{
return m_schemaVersion;
}
QStringList IMetaDataPlugin::schemas()
{
return m_schemas;
}
void IMetaDataPlugin::init(const QJsonObject &metaData) void IMetaDataPlugin::init(const QJsonObject &metaData)
{ {
parseMetaData(metaData); parseMetaData(metaData);
@ -44,6 +55,11 @@ void IMetaDataPlugin::parseMetaData(const QJsonObject &metaData)
m_name = parseLocaleText(data.toObject()["name"].toObject()); m_name = parseLocaleText(data.toObject()["name"].toObject());
m_description = parseLocaleText(data.toObject()["description"].toObject()); m_description = parseLocaleText(data.toObject()["description"].toObject());
m_id = data.toObject()["id"].toString(); m_id = data.toObject()["id"].toString();
m_schemaVersion = data.toObject()["schemaVersion"].toInt();
foreach (QJsonValue schVal, data.toObject()["sql"].toArray()) {
m_schemas.append(schVal.toString());
}
} }
QString IMetaDataPlugin::parseLocaleText(const QJsonObject &object) QString IMetaDataPlugin::parseLocaleText(const QJsonObject &object)

@ -17,6 +17,8 @@ public:
virtual QString pluginName(); virtual QString pluginName();
virtual QString pluginId(); virtual QString pluginId();
virtual QString pluginDescription(); virtual QString pluginDescription();
virtual int schemaVersion();
virtual QStringList schemas();
virtual void init(const QJsonObject &metaData); virtual void init(const QJsonObject &metaData);
protected: protected:
@ -27,6 +29,8 @@ private:
QString m_name; QString m_name;
QString m_id; QString m_id;
QString m_description; QString m_description;
int m_schemaVersion;
QStringList m_schemas;
QString parseLocaleText(const QJsonObject &object); QString parseLocaleText(const QJsonObject &object);
}; };

@ -5,6 +5,7 @@
#include <QWidget> #include <QWidget>
#include <QtPlugin> #include <QtPlugin>
#include <QJsonObject> #include <QJsonObject>
#include <QStringList>
#include "service.h" #include "service.h"
@ -20,6 +21,8 @@ public:
virtual QString pluginName() = 0; virtual QString pluginName() = 0;
virtual QString pluginId() = 0; virtual QString pluginId() = 0;
virtual QString pluginDescription() = 0; virtual QString pluginDescription() = 0;
virtual int schemaVersion() = 0;
virtual QStringList schemas() = 0;
virtual void init(const QJsonObject &metaData) = 0; virtual void init(const QJsonObject &metaData) = 0;
virtual QWidget *ui() { virtual QWidget *ui() {
return m_ui; return m_ui;

@ -0,0 +1,73 @@
{
"MetaData" : {
"id" : "CORE",
"name" : {
"default" : "Core plugin",
"CZ" : "Jádro"
},
"descriptoin" : {
"default" : "",
"CZ" : ""
},
"schemaVersion" : 1,
"sql" : [
"CREATE TABLE \"User\" (
\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
\"login\" TEXT NULL,
\"password\" TEXT NULL,
\"name\" TEXT NULL,
\"lastModDate\" TEXT NULL,
\"createDate\" TEXT NULL,
\"active\" INTEGER NOT NULL,
\"isAdmin\" INTEGER NOT NULL);
CREATE TABLE \"User_listRoles\" (
\"object_id\" INTEGER NOT NULL,
\"value\" INTEGER NOT NULL,
CONSTRAINT \"object_id_fk\"
FOREIGN KEY (\"object_id\")
REFERENCES \"User\" (\"id\")
ON DELETE CASCADE,
CONSTRAINT \"value_fk\"
FOREIGN KEY (\"value\")
REFERENCES \"Role\" (\"id\")
DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX \"User_listRoles_object_id_i\"
ON \"User_listRoles\" (\"object_id\");
CREATE TABLE \"Role\" (
\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
\"name\" TEXT NULL,
\"lastModDate\" TEXT NULL,
\"createDate\" TEXT NULL,
\"active\" INTEGER NOT NULL);
CREATE TABLE \"Role_listPermissions\" (
\"object_id\" INTEGER NOT NULL,
\"value\" INTEGER NOT NULL,
CONSTRAINT \"object_id_fk\"
FOREIGN KEY (\"object_id\")
REFERENCES \"Role\" (\"id\")
ON DELETE CASCADE,
CONSTRAINT \"value_fk\"
FOREIGN KEY (\"value\")
REFERENCES \"Permission\" (\"id\")
DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX \"Role_listPermissions_object_id_i\"
ON \"Role_listPermissions\" (\"object_id\");
CREATE TABLE \"Permission\" (
\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
\"pluginId\" TEXT NULL,
\"permissionName\" TEXT NULL,
\"lastModDate\" TEXT NULL,
\"createDate\" TEXT NULL,
\"active\" INTEGER NOT NULL);"
],
"dependencies" : []
}
}

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>metaData.json</file>
</qresource>
</RCC>

@ -3,6 +3,7 @@
#include <QList> #include <QList>
#include <QSharedPointer> #include <QSharedPointer>
#include <QString>
#include <odb/core.hxx> #include <odb/core.hxx>
#include <odb/transaction.hxx> #include <odb/transaction.hxx>
@ -39,6 +40,9 @@ public:
void save(QSharedPointer<T> entity) { void save(QSharedPointer<T> entity) {
odb::database *db = Context::instance().db(); odb::database *db = Context::instance().db();
Q_ASSERT(db);
Transaction tx; Transaction tx;
db->persist(entity); db->persist(entity);
tx.commit(); tx.commit();
@ -46,11 +50,21 @@ public:
QSharedPointer<T> loadById(int id) { QSharedPointer<T> loadById(int id) {
odb::database *db = Context::instance().db(); odb::database *db = Context::instance().db();
Q_ASSERT(db);
Transaction tx; Transaction tx;
QSharedPointer<T> entity = db->template load<T>(id); QSharedPointer<T> entity = db->template load<T>(id);
tx.commit(); tx.commit();
return entity; return entity;
} }
void setPluginId(const QString &pluginId) {
m_pluginId = pluginId;
}
private:
QString m_pluginId;
}; };
#endif // SERVICE_H #endif // SERVICE_H

@ -11,6 +11,10 @@ Transaction::Transaction()
m_tr = new odb::transaction(Context::instance().db()->begin()); m_tr = new odb::transaction(Context::instance().db()->begin());
Transaction::m_inTransaction = true; Transaction::m_inTransaction = true;
} }
else
{
m_tr = NULL;
}
} }
Transaction::~Transaction() Transaction::~Transaction()

Loading…
Cancel
Save