From 07bb7084375d6b89c3950f03946039458760b2bf Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Sun, 15 Nov 2015 22:26:50 +0100 Subject: [PATCH] Implemented dependency solving for db schemas creation. Added macro for begin/end iterator. --- core/autotablemodel.h | 3 +- core/context.cpp | 76 ++++++++++++++++++++++++++++------------ core/context.h | 6 ++++ core/core.h | 1 + core/core.pro | 3 +- core/define.h | 7 ++++ core/imetadataplugin.cpp | 9 +++++ core/imetadataplugin.h | 3 ++ core/iplugin.h | 4 +++ core/ivalidator.h | 2 ++ 10 files changed, 89 insertions(+), 25 deletions(-) create mode 100644 core/define.h diff --git a/core/autotablemodel.h b/core/autotablemodel.h index 206079d..407761f 100644 --- a/core/autotablemodel.h +++ b/core/autotablemodel.h @@ -6,6 +6,7 @@ #include #include +#include "define.h" #include "core_global.h" template @@ -94,7 +95,7 @@ public: QObject *rawEntity = (QObject*)m_list.at(0).data(); const char *prop = rawEntity->metaObject()->property(column + 1).name(); - std::sort(m_list.begin(), m_list.end(), [prop, order](QSharedPointer entA, QSharedPointer entB) -> bool { + std::sort(ALL(m_list), [prop, order](QSharedPointer entA, QSharedPointer entB) -> bool { if (order == Qt::AscendingOrder) { return ((QObject*)entA.data())->property(prop) < ((QObject*)entB.data())->property(prop); } else { diff --git a/core/context.cpp b/core/context.cpp index 4346eaf..426759a 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -25,7 +25,7 @@ QList Context::plugins() IPlugin *Context::plugin(const QString &pluginId) { - QList::iterator it = std::find_if(m_plugins.begin(), m_plugins.end(), [&pluginId](IPlugin *p) { return p->pluginId() == pluginId; }); + QList::iterator it = std::find_if(ALL(m_plugins), [&pluginId](IPlugin *p) { return p->pluginId() == pluginId; }); if (it != m_plugins.end()) { return *it; @@ -100,36 +100,66 @@ void Context::checkDb(const QString &path) void Context::checkSchema(const QSqlDatabase &db, const QMap &schemaMap) { foreach (IPlugin *plugin, m_plugins) { - if (!schemaMap.contains(plugin->pluginId()) || schemaMap[plugin->pluginId()] < plugin->schemaVersion()) + solveDep(plugin, db, schemaMap); + } +} + +void Context::solveDep(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap) +{ + foreach (QString dep, plugin->dependsOn()) { + QList::iterator it = std::find_if(ALL(m_plugins), [&dep](IPlugin *p) { return p->pluginId() == dep; }); + + if (it != m_plugins.end()) { - int ver = schemaMap[plugin->pluginId()]; + solveDep(*it, db, schemaMap); + } - for (int i = 0; i < plugin->schemas().count(); i++) - { - if (!schemaMap.contains(plugin->pluginId()) || i >= ver) - { - QString sql = plugin->schemas()[i]; - QSqlQuery q(db); + if (m_solved.contains(plugin->pluginId())) + { + createSchema(plugin, db, schemaMap); + m_solved.append(plugin->pluginId()); + } + } +} + +void Context::createSchema(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap) +{ + if (!schemaMap.contains(plugin->pluginId()) || schemaMap[plugin->pluginId()] < plugin->schemaVersion()) + { + int ver = schemaMap[plugin->pluginId()]; - QStringList sqlList = sql.split(";"); + for (int i = 0; i < plugin->schemas().count(); i++) + { + if (!schemaMap.contains(plugin->pluginId()) || i >= ver) + { + QString sql = plugin->schemas()[i]; + QSqlQuery q(db); - foreach (QString s, sqlList) { - if (!q.exec(s)) - { - qDebug() << q.lastError().text(); - } - } + QStringList sqlList = sql.split(";"); + bool error = false; - if (ver == 0) + foreach (QString s, sqlList) { + if (!q.exec(s)) { - sql = "INSERT INTO system(pluginId, schemaVersion) VALUES('" + plugin->pluginId() + "', 1)"; + qDebug() << q.lastError().text(); + error = true; } - else - { - sql = "UPDATE system SET schemaVersion = " + QString::number(i + 1) + " WHERE pluginId = '" + plugin->pluginId() + "'"; - } - q.exec(sql); } + + if (error) + { + continue; + } + + 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); } } } diff --git a/core/context.h b/core/context.h index 6ce07b3..2840708 100644 --- a/core/context.h +++ b/core/context.h @@ -5,7 +5,9 @@ #include #include #include +#include +#include "define.h" #include "core_global.h" #include "transaction.h" @@ -28,8 +30,12 @@ private: QList m_plugins; odb::database *m_db; + QStringList m_solved; + void checkDb(const QString &path); void checkSchema(const QSqlDatabase &db, const QMap &schemaMap); + void solveDep(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap); + void createSchema(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap); }; #endif // CONTEXT_H diff --git a/core/core.h b/core/core.h index b603be4..b196637 100644 --- a/core/core.h +++ b/core/core.h @@ -1,6 +1,7 @@ #ifndef CORE_H #define CORE_H +#include "define.h" #include "context.h" #include "iplugin.h" #include "imetadataplugin.h" diff --git a/core/core.pro b/core/core.pro index 94cfa39..b1e9b3e 100644 --- a/core/core.pro +++ b/core/core.pro @@ -36,7 +36,8 @@ HEADERS += core.h\ data/role.h \ data/permission.h \ data/core-data.h \ - coreplugin.h + coreplugin.h \ + define.h unix { target.path = /usr/lib diff --git a/core/define.h b/core/define.h new file mode 100644 index 0000000..683daf4 --- /dev/null +++ b/core/define.h @@ -0,0 +1,7 @@ +#ifndef DEFINE_H +#define DEFINE_H + +#define ALL(arr) arr.begin(), arr.end() + +#endif // DEFINE_H + diff --git a/core/imetadataplugin.cpp b/core/imetadataplugin.cpp index f14760d..290d0f4 100644 --- a/core/imetadataplugin.cpp +++ b/core/imetadataplugin.cpp @@ -38,6 +38,11 @@ QStringList IMetaDataPlugin::schemas() return m_schemas; } +QStringList IMetaDataPlugin::dependsOn() +{ + return m_dependsOn; +} + void IMetaDataPlugin::init(const QJsonObject &metaData) { parseMetaData(metaData); @@ -60,6 +65,10 @@ void IMetaDataPlugin::parseMetaData(const QJsonObject &metaData) foreach (QJsonValue schVal, data.toObject()["sql"].toArray()) { m_schemas.append(schVal.toString()); } + + foreach (QJsonValue depVal, data.toObject()["dependecies"].toArray()) { + m_dependsOn.append(depVal.toString()); + } } QString IMetaDataPlugin::parseLocaleText(const QJsonObject &object) diff --git a/core/imetadataplugin.h b/core/imetadataplugin.h index 5ee3c0a..a9c7f2d 100644 --- a/core/imetadataplugin.h +++ b/core/imetadataplugin.h @@ -19,6 +19,8 @@ public: virtual QString pluginDescription(); virtual int schemaVersion(); virtual QStringList schemas(); + virtual QStringList dependsOn(); + virtual void init(const QJsonObject &metaData); protected: @@ -31,6 +33,7 @@ private: QString m_description; int m_schemaVersion; QStringList m_schemas; + QStringList m_dependsOn; QString parseLocaleText(const QJsonObject &object); }; diff --git a/core/iplugin.h b/core/iplugin.h index 96ad791..b9c8aa8 100644 --- a/core/iplugin.h +++ b/core/iplugin.h @@ -23,10 +23,14 @@ public: virtual QString pluginDescription() = 0; virtual int schemaVersion() = 0; virtual QStringList schemas() = 0; + virtual QStringList dependsOn() = 0; + virtual void init(const QJsonObject &metaData) = 0; + virtual QWidget *ui() { return m_ui; } + template Service *service() { return (Service*)m_service; diff --git a/core/ivalidator.h b/core/ivalidator.h index f0aa0e5..10f0285 100644 --- a/core/ivalidator.h +++ b/core/ivalidator.h @@ -15,6 +15,8 @@ public: m_errMessage = errMessage; } + virtual ~IValidator() {} + virtual bool validate() = 0; QString errMessage()