You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
4.3 KiB
C++
169 lines
4.3 KiB
C++
#include <QDir>
|
|
#include <QApplication>
|
|
#include <QPluginLoader>
|
|
#include <QSqlDatabase>
|
|
#include <QSqlQuery>
|
|
#include <QSqlResult>
|
|
#include <QSqlError>
|
|
#include <QDebug>
|
|
|
|
#include <odb/sqlite/database.hxx>
|
|
|
|
#include "core.h"
|
|
#include "coreplugin.h"
|
|
#include "users/users.h"
|
|
|
|
Context &Context::instance()
|
|
{
|
|
static Context ctx;
|
|
return ctx;
|
|
}
|
|
|
|
QList<IPlugin *> Context::plugins()
|
|
{
|
|
return m_plugins;
|
|
}
|
|
|
|
IPlugin *Context::plugin(const QString &pluginId)
|
|
{
|
|
QList<IPlugin*>::iterator it = std::find_if(ALL(m_plugins), [&pluginId](IPlugin *p) { return p->pluginId() == pluginId; });
|
|
if (it != m_plugins.end())
|
|
{
|
|
return *it;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void Context::loadPlugins()
|
|
{
|
|
IPlugin *corePlugin = new CorePlugin();
|
|
m_plugins.append(corePlugin);
|
|
m_plugins.append(new Users);
|
|
|
|
QDir pluginsDir(qApp->applicationDirPath() + "/../plugins");
|
|
|
|
foreach (QString fileName, pluginsDir.entryList(QStringList() << "*.so" << "*.dll")) {
|
|
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
|
|
QObject *p = pluginLoader.instance();
|
|
|
|
if (p != NULL) {
|
|
IPlugin *plugin = qobject_cast<IPlugin*>(p);
|
|
if (plugin != NULL) {
|
|
plugin->init(pluginLoader.metaData());
|
|
m_plugins.append(plugin);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Context::openDb(const QString &path)
|
|
{
|
|
if (m_db != NULL) {
|
|
delete m_db;
|
|
}
|
|
|
|
checkDb(path);
|
|
m_db = new odb::sqlite::database(path.toStdString());
|
|
}
|
|
|
|
Context::Context()
|
|
{
|
|
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) {
|
|
solveDep(plugin, db, schemaMap);
|
|
}
|
|
}
|
|
|
|
void Context::solveDep(IPlugin *plugin, const QSqlDatabase &db, const QMap<QString, int> &schemaMap)
|
|
{
|
|
foreach (QString dep, plugin->dependsOn()) {
|
|
QList<IPlugin*>::iterator it = std::find_if(ALL(m_plugins), [&dep](IPlugin *p) { return p->pluginId() == dep; });
|
|
|
|
if (it != m_plugins.end())
|
|
{
|
|
solveDep(*it, db, schemaMap);
|
|
}
|
|
}
|
|
|
|
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<QString, int> &schemaMap)
|
|
{
|
|
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(";");
|
|
bool error = false;
|
|
|
|
foreach (QString s, sqlList) {
|
|
if (!s.isEmpty() && !q.exec(s))
|
|
{
|
|
qDebug() << q.lastError().text();
|
|
error = true;
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|