diff --git a/src/common/database/Database.cpp b/src/common/database/Database.cpp --- a/src/common/database/Database.cpp +++ b/src/common/database/Database.cpp @@ -181,7 +181,7 @@ ptr->d->database.reset(new QSqlDatabaseWrapper(info)); if (!ptr->d->database->isOpen()) { - return Q_NULLPTR; + return nullptr; } databases[info] = ptr; @@ -202,9 +202,10 @@ auto walResult = ptr->pragma(QStringLiteral("journal_mode = WAL")); if (walResult != "wal") { - qFatal("KActivities: Database can not be opened in WAL mode. Check the " - "SQLite version (required >3.7.0). And whether your filesystem " - "supports shared memory"); + qWarning() << "KActivities: Database can not be opened in WAL mode. Check the " + "SQLite version (required >3.7.0). And whether your filesystem " + "supports shared memory"; + return nullptr; } // We don't have a big database, lets flush the WAL when diff --git a/src/service/Application.cpp b/src/service/Application.cpp --- a/src/service/Application.cpp +++ b/src/service/Application.cpp @@ -185,13 +185,20 @@ auto &modules = Module::get(); if (pluginInstance) { - pluginInstance->init(modules); + bool success = pluginInstance->init(modules); - pluginIds << plugin.pluginId(); - plugins << pluginInstance; + if (success) { + pluginIds << plugin.pluginId(); + plugins << pluginInstance; - qCDebug(KAMD_LOG_APPLICATION) << "[ OK ] loaded: " << plugin.pluginId(); - return true; + qCDebug(KAMD_LOG_APPLICATION) << "[ OK ] loaded: " << plugin.pluginId(); + return true; + } else { + qCWarning(KAMD_LOG_APPLICATION) << "[ FAILED ] init: " << plugin.pluginId() << loader.errorString(); + // TODO: Show a notification for a plugin that failed to load + delete pluginInstance; + return false; + } } else { qCWarning(KAMD_LOG_APPLICATION) << "[ FAILED ] loading: " << plugin.pluginId() << loader.errorString(); diff --git a/src/service/plugins/sqlite/Database.h b/src/service/plugins/sqlite/Database.h --- a/src/service/plugins/sqlite/Database.h +++ b/src/service/plugins/sqlite/Database.h @@ -33,6 +33,7 @@ // Local #include +#include class QDateTime; class QSqlDatabase; @@ -56,9 +57,9 @@ D_PTR; - friend Common::Database &resourcesDatabase(); + friend Common::Database::Ptr resourcesDatabase(); }; -Common::Database &resourcesDatabase(); +Common::Database::Ptr resourcesDatabase(); #endif // PLUGINS_SQLITE_RESOURCESDATABASE_H diff --git a/src/service/plugins/sqlite/Database.cpp b/src/service/plugins/sqlite/Database.cpp --- a/src/service/plugins/sqlite/Database.cpp +++ b/src/service/plugins/sqlite/Database.cpp @@ -53,35 +53,13 @@ }; -Common::Database &resourcesDatabase() +Common::Database::Ptr resourcesDatabase() { static ResourcesDatabaseMigrator instance; - return *(instance.d->database); -} - -void ResourcesDatabaseMigrator::migrateDatabase(const QString &newDatabaseFile) const -{ - // Checking whether we need to transfer the KActivities/KDE4 - // sqlite database file to the new location. - if (QFile(newDatabaseFile).exists()) { - return; - } - - // Testing for kdehome - Kdelibs4Migration migration; - if (!migration.kdeHomeFound()) { - return; - } - - QString oldDatabaseFile( - migration.locateLocal("data", "activitymanager/resources/database")); - if (!oldDatabaseFile.isEmpty()) { - QFile(oldDatabaseFile).copy(newDatabaseFile); - } + return instance.d->database; } ResourcesDatabaseMigrator::ResourcesDatabaseMigrator() - : d() { const QString databaseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) @@ -94,18 +72,13 @@ qWarning() << "Database folder can not be created!"; } - const QString newDatabaseFile = databaseDir + QStringLiteral("database"); - - migrateDatabase(newDatabaseFile); - d->database = Common::Database::instance( Common::Database::ResourcesDatabase, Common::Database::ReadWrite); - Q_ASSERT_X(d->database, "SQLite plugin/Database constructor", - "Database could not be opened"); - - Common::ResourcesDatabaseSchema::initSchema(*d->database); + if (d->database) { + Common::ResourcesDatabaseSchema::initSchema(*d->database); + } } ResourcesDatabaseMigrator::~ResourcesDatabaseMigrator() diff --git a/src/service/plugins/sqlite/ResourceLinking.cpp b/src/service/plugins/sqlite/ResourceLinking.cpp --- a/src/service/plugins/sqlite/ResourceLinking.cpp +++ b/src/service/plugins/sqlite/ResourceLinking.cpp @@ -87,7 +87,7 @@ "ResourceLinking::LinkResourceToActivity", "Resource shoud not be empty"); - Utils::prepare(resourcesDatabase(), linkResourceToActivityQuery, + Utils::prepare(*resourcesDatabase(), linkResourceToActivityQuery, QStringLiteral( "INSERT OR REPLACE INTO ResourceLink" " (usedActivity, initiatingAgent, targettedResource) " @@ -98,7 +98,7 @@ ")" )); - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); Utils::exec(Utils::FailOnError, *linkResourceToActivityQuery, ":usedActivity" , usedActivity, @@ -147,16 +147,16 @@ QSqlQuery *query = nullptr; if (usedActivity == ":any") { - Utils::prepare(resourcesDatabase(), unlinkResourceFromAllActivitiesQuery, + Utils::prepare(*resourcesDatabase(), unlinkResourceFromAllActivitiesQuery, QStringLiteral( "DELETE FROM ResourceLink " "WHERE " "initiatingAgent = COALESCE(:initiatingAgent , '') AND " "targettedResource = COALESCE(:targettedResource, '') " )); query = unlinkResourceFromAllActivitiesQuery.get(); } else { - Utils::prepare(resourcesDatabase(), unlinkResourceFromActivityQuery, + Utils::prepare(*resourcesDatabase(), unlinkResourceFromActivityQuery, QStringLiteral( "DELETE FROM ResourceLink " "WHERE " @@ -167,7 +167,7 @@ query = unlinkResourceFromActivityQuery.get(); } - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); Utils::exec(Utils::FailOnError, *query, ":usedActivity" , usedActivity, @@ -213,7 +213,7 @@ "ResourceLinking::IsResourceLinkedToActivity", "Resource shoud not be empty"); - Utils::prepare(resourcesDatabase(), isResourceLinkedToActivityQuery, + Utils::prepare(*resourcesDatabase(), isResourceLinkedToActivityQuery, QStringLiteral( "SELECT * FROM ResourceLink " "WHERE " diff --git a/src/service/plugins/sqlite/ResourceScoreCache.cpp b/src/service/plugins/sqlite/ResourceScoreCache.cpp --- a/src/service/plugins/sqlite/ResourceScoreCache.cpp +++ b/src/service/plugins/sqlite/ResourceScoreCache.cpp @@ -38,31 +38,31 @@ class ResourceScoreCache::Queries { private: Queries() - : createResourceScoreCacheQuery(resourcesDatabase().createQuery()) - , getResourceScoreCacheQuery(resourcesDatabase().createQuery()) - , updateResourceScoreCacheQuery(resourcesDatabase().createQuery()) - , getScoreAdditionQuery(resourcesDatabase().createQuery()) + : createResourceScoreCacheQuery(resourcesDatabase()->createQuery()) + , getResourceScoreCacheQuery(resourcesDatabase()->createQuery()) + , updateResourceScoreCacheQuery(resourcesDatabase()->createQuery()) + , getScoreAdditionQuery(resourcesDatabase()->createQuery()) { - Utils::prepare(resourcesDatabase(), + Utils::prepare(*resourcesDatabase(), createResourceScoreCacheQuery, QStringLiteral( "INSERT INTO ResourceScoreCache " "VALUES (:usedActivity, :initiatingAgent, :targettedResource, " "0, 0, " // type, score ":firstUpdate, " // lastUpdate ":firstUpdate)" )); - Utils::prepare(resourcesDatabase(), + Utils::prepare(*resourcesDatabase(), getResourceScoreCacheQuery, QStringLiteral( "SELECT cachedScore, lastUpdate, firstUpdate FROM ResourceScoreCache " "WHERE " ":usedActivity = usedActivity AND " ":initiatingAgent = initiatingAgent AND " ":targettedResource = targettedResource " )); - Utils::prepare(resourcesDatabase(), + Utils::prepare(*resourcesDatabase(), updateResourceScoreCacheQuery, QStringLiteral( "UPDATE ResourceScoreCache SET " "cachedScore = :cachedScore, " @@ -73,7 +73,7 @@ ":targettedResource = targettedResource " )); - Utils::prepare(resourcesDatabase(), + Utils::prepare(*resourcesDatabase(), getScoreAdditionQuery, QStringLiteral( "SELECT start, end " "FROM ResourceEvent " @@ -153,7 +153,7 @@ QDateTime currentTime = QDateTime::currentDateTime(); qreal score = 0; - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); qDebug() << "Creating the cache for: " << d->resource; diff --git a/src/service/plugins/sqlite/StatsPlugin.cpp b/src/service/plugins/sqlite/StatsPlugin.cpp --- a/src/service/plugins/sqlite/StatsPlugin.cpp +++ b/src/service/plugins/sqlite/StatsPlugin.cpp @@ -69,14 +69,15 @@ { Plugin::init(modules); + if (!resourcesDatabase()) { + return false; + } + m_activities = modules[QStringLiteral("activities")]; m_resources = modules[QStringLiteral("resources")]; m_resourceLinking->init(); - // Initializing the database - resourcesDatabase(); - connect(m_resources, SIGNAL(ProcessedResourceEvents(EventList)), this, SLOT(addEvents(EventList))); connect(m_resources, SIGNAL(RegisteredResourceMimetype(QString, QString)), @@ -165,7 +166,7 @@ detectResourceInfo(targettedResource); - Utils::prepare(resourcesDatabase(), openResourceEventQuery, QStringLiteral( + Utils::prepare(*resourcesDatabase(), openResourceEventQuery, QStringLiteral( "INSERT INTO ResourceEvent" " (usedActivity, initiatingAgent, targettedResource, start, end) " "VALUES (:usedActivity, :initiatingAgent, :targettedResource, :start, :end)" @@ -195,7 +196,7 @@ "StatsPlugin::closeResourceEvent", "Resource shoud not be empty"); - Utils::prepare(resourcesDatabase(), closeResourceEventQuery, QStringLiteral( + Utils::prepare(*resourcesDatabase(), closeResourceEventQuery, QStringLiteral( "UPDATE ResourceEvent " "SET end = :end " "WHERE " @@ -236,7 +237,7 @@ bool StatsPlugin::insertResourceInfo(const QString &uri) { - Utils::prepare(resourcesDatabase(), getResourceInfoQuery, QStringLiteral( + Utils::prepare(*resourcesDatabase(), getResourceInfoQuery, QStringLiteral( "SELECT targettedResource FROM ResourceInfo WHERE " " targettedResource = :targettedResource " )); @@ -248,7 +249,7 @@ return false; } - Utils::prepare(resourcesDatabase(), insertResourceInfoQuery, QStringLiteral( + Utils::prepare(*resourcesDatabase(), insertResourceInfoQuery, QStringLiteral( "INSERT INTO ResourceInfo( " " targettedResource" ", title" @@ -276,9 +277,9 @@ { insertResourceInfo(uri); - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); - Utils::prepare(resourcesDatabase(), saveResourceTitleQuery, QStringLiteral( + Utils::prepare(*resourcesDatabase(), saveResourceTitleQuery, QStringLiteral( "UPDATE ResourceInfo SET " " title = :title" ", autoTitle = :autoTitle " @@ -299,9 +300,9 @@ { insertResourceInfo(uri); - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); - Utils::prepare(resourcesDatabase(), saveResourceMimetypeQuery, QStringLiteral( + Utils::prepare(*resourcesDatabase(), saveResourceMimetypeQuery, QStringLiteral( "UPDATE ResourceInfo SET " " mimetype = :mimetype" ", autoMimetype = :autoMimetype " @@ -392,7 +393,7 @@ if (eventsToProcess.begin() == eventsToProcess.end()) return; - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); for (auto event : eventsToProcess) { @@ -444,19 +445,19 @@ // If we need to delete everything, // no need to bother with the count and the date - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); if (what == QStringLiteral("everything")) { // Instantiating these every time is not a big overhead // since this method is rarely executed. - auto removeEventsQuery = resourcesDatabase().createQuery(); + auto removeEventsQuery = resourcesDatabase()->createQuery(); removeEventsQuery.prepare( "DELETE FROM ResourceEvent " "WHERE usedActivity = COALESCE(:usedActivity, usedActivity)" ); - auto removeScoreCachesQuery = resourcesDatabase().createQuery(); + auto removeScoreCachesQuery = resourcesDatabase()->createQuery(); removeScoreCachesQuery.prepare( "DELETE FROM ResourceScoreCache " "WHERE usedActivity = COALESCE(:usedActivity, usedActivity)"); @@ -480,14 +481,14 @@ // if something was accessed before, and the user did not // remove the history, it is not really a secret. - auto removeEventsQuery = resourcesDatabase().createQuery(); + auto removeEventsQuery = resourcesDatabase()->createQuery(); removeEventsQuery.prepare( "DELETE FROM ResourceEvent " "WHERE usedActivity = COALESCE(:usedActivity, usedActivity) " "AND end > :since" ); - auto removeScoreCachesQuery = resourcesDatabase().createQuery(); + auto removeScoreCachesQuery = resourcesDatabase()->createQuery(); removeScoreCachesQuery.prepare( "DELETE FROM ResourceScoreCache " "WHERE usedActivity = COALESCE(:usedActivity, usedActivity) " @@ -515,20 +516,20 @@ // Deleting a specified length of time - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); const auto time = QDateTime::currentDateTime().addMonths(-months); const auto usedActivity = activity.isEmpty() ? QVariant() : QVariant(activity); - auto removeEventsQuery = resourcesDatabase().createQuery(); + auto removeEventsQuery = resourcesDatabase()->createQuery(); removeEventsQuery.prepare( "DELETE FROM ResourceEvent " "WHERE usedActivity = COALESCE(:usedActivity, usedActivity) " "AND start < :time" ); - auto removeScoreCachesQuery = resourcesDatabase().createQuery(); + auto removeScoreCachesQuery = resourcesDatabase()->createQuery(); removeScoreCachesQuery.prepare( "DELETE FROM ResourceScoreCache " "WHERE usedActivity = COALESCE(:usedActivity, usedActivity) " @@ -564,7 +565,7 @@ "StatsPlugin::DeleteStatsForResource", "We can not handle CURRENT_AGENT_TAG here"); - DATABASE_TRANSACTION(resourcesDatabase()); + DATABASE_TRANSACTION(*resourcesDatabase()); // Check against sql injection if (activity.contains('\'') || client.contains('\'')) return; @@ -580,16 +581,16 @@ client == ANY_AGENT_TAG ? " 1 " : QStringLiteral(" initiatingAgent = '%1' ").arg(client); - auto removeEventsQuery = resourcesDatabase().createQuery(); + auto removeEventsQuery = resourcesDatabase()->createQuery(); removeEventsQuery.prepare( "DELETE FROM ResourceEvent " "WHERE " + activityFilter + " AND " + clientFilter + " AND " + "targettedResource LIKE :targettedResource ESCAPE '\\'" ); - auto removeScoreCachesQuery = resourcesDatabase().createQuery(); + auto removeScoreCachesQuery = resourcesDatabase()->createQuery(); removeScoreCachesQuery.prepare( "DELETE FROM ResourceScoreCache " "WHERE "