#include #include #include #include #include #include #include #include #include #include "core.h" #include "coreplugin.h" Context &Context::instance() { static Context ctx; return ctx; } QList Context::plugins() { return m_plugins; } IPlugin *Context::plugin(const QString &pluginId) { QList::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); 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(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 schemas; while (q.next()) { schemas[q.value("pluginId").toString()] = q.value("schemaVersion").toInt(); } checkSchema(db, schemas); } else { q.exec(createSysSql); checkSchema(db, QMap()); } db.close(); } void Context::checkSchema(const QSqlDatabase &db, const QMap &schemaMap) { foreach (IPlugin *plugin, m_plugins) { 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()) { 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 &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 (!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); } } } }