File indexing completed on 2024-11-17 05:00:55
0001 /* 0002 SPDX-FileCopyrightText: 2015 Ivan Cukic <ivan.cukic(at)kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "ResourcesDatabaseSchema.h" 0008 0009 #include <QCoreApplication> 0010 #include <QStandardPaths> 0011 #include <QVariant> 0012 0013 namespace Common 0014 { 0015 namespace ResourcesDatabaseSchema 0016 { 0017 const QString name = QStringLiteral("Resources"); 0018 0019 QLatin1String version() 0020 { 0021 return QLatin1String("2015.02.09"); 0022 } 0023 0024 QStringList schema() 0025 { 0026 return QStringList{ 0027 0028 // Schema information table, used for versioning 0029 QStringLiteral("CREATE TABLE IF NOT EXISTS SchemaInfo (" 0030 "key text PRIMARY KEY, value text" 0031 ")"), 0032 0033 QStringLiteral("INSERT OR IGNORE INTO schemaInfo VALUES ('version', '%1')").arg(version()), 0034 QStringLiteral("UPDATE schemaInfo SET value = '%1' WHERE key = 'version'").arg(version()), 0035 0036 // The ResourceEvent table saves the Opened/Closed event pairs for 0037 // a resource. The Accessed event is mapped to those. 0038 // Focussing events are not stored in order not to get a 0039 // huge database file and to lessen writes to the disk. 0040 QStringLiteral("CREATE TABLE IF NOT EXISTS ResourceEvent (" 0041 "usedActivity TEXT, " 0042 "initiatingAgent TEXT, " 0043 "targettedResource TEXT, " 0044 "start INTEGER, " 0045 "end INTEGER " 0046 ")"), 0047 0048 // The ResourceScoreCache table stores the calculated scores 0049 // for resources based on the recorded events. 0050 QStringLiteral("CREATE TABLE IF NOT EXISTS ResourceScoreCache (" 0051 "usedActivity TEXT, " 0052 "initiatingAgent TEXT, " 0053 "targettedResource TEXT, " 0054 "scoreType INTEGER, " 0055 "cachedScore FLOAT, " 0056 "firstUpdate INTEGER, " 0057 "lastUpdate INTEGER, " 0058 "PRIMARY KEY(usedActivity, initiatingAgent, targettedResource)" 0059 ")"), 0060 0061 // @since 2014.05.05 0062 // The ResourceLink table stores the information, formerly kept by 0063 // Nepomuk, of which resources are linked to which activities. 0064 // The additional features compared to the old days are 0065 // the ability to limit the link to specific applications, and 0066 // to create global links. 0067 QStringLiteral("CREATE TABLE IF NOT EXISTS ResourceLink (" 0068 "usedActivity TEXT, " 0069 "initiatingAgent TEXT, " 0070 "targettedResource TEXT, " 0071 "PRIMARY KEY(usedActivity, initiatingAgent, targettedResource)" 0072 ")"), 0073 0074 // @since 2015.01.18 0075 // The ResourceInfo table stores the collected information about a 0076 // resource that is not agent nor activity related like the 0077 // title and the mime type. 0078 // If these are automatically retrieved (works for files), the 0079 // flag is set to true. This is done for the agents to be able to 0080 // override these. 0081 QStringLiteral("CREATE TABLE IF NOT EXISTS ResourceInfo (" 0082 "targettedResource TEXT, " 0083 "title TEXT, " 0084 "mimetype TEXT, " 0085 "autoTitle INTEGER, " 0086 "autoMimetype INTEGER, " 0087 "PRIMARY KEY(targettedResource)" 0088 ")")} 0089 0090 ; 0091 } 0092 0093 // TODO: This will require some refactoring after we introduce more databases 0094 QString defaultPath() 0095 { 0096 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kactivitymanagerd/resources/database"); 0097 } 0098 0099 const char *overrideFlagProperty = "org.kde.KActivities.ResourcesDatabase.overrideDatabase"; 0100 const char *overrideFileProperty = "org.kde.KActivities.ResourcesDatabase.overrideDatabaseFile"; 0101 0102 QString path() 0103 { 0104 auto app = QCoreApplication::instance(); 0105 0106 return app->property(overrideFlagProperty).toBool() ? app->property(overrideFileProperty).toString() : defaultPath(); 0107 } 0108 0109 void overridePath(const QString &path) 0110 { 0111 auto app = QCoreApplication::instance(); 0112 0113 app->setProperty(overrideFlagProperty, true); 0114 app->setProperty(overrideFileProperty, path); 0115 } 0116 0117 void initSchema(Database &database) 0118 { 0119 QString dbSchemaVersion; 0120 0121 auto query = database.execQuery( // 0122 QStringLiteral("SELECT value FROM SchemaInfo WHERE key = 'version'")); 0123 0124 if (query.next()) { 0125 dbSchemaVersion = query.value(0).toString(); 0126 } 0127 0128 // Early bail-out if the schema is up-to-date 0129 if (dbSchemaVersion == version()) { 0130 return; 0131 } 0132 0133 // Transition to KF5: 0134 // We left the world of Nepomuk, and all the ontologies went 0135 // across the sea to the Undying Lands. 0136 // This needs to be done before executing the schema() queries 0137 // so that we do not create new (empty) tables and block these 0138 // queries from being executed. 0139 if (dbSchemaVersion < QStringLiteral("2014.04.14")) { 0140 database.execQuery( // 0141 QStringLiteral("ALTER TABLE nuao_DesktopEvent RENAME TO ResourceEvent")); 0142 database.execQuery( // 0143 QStringLiteral("ALTER TABLE kext_ResourceScoreCache RENAME TO ResourceScoreCache")); 0144 } 0145 0146 database.execQueries(ResourcesDatabaseSchema::schema()); 0147 0148 // We can not allow empty fields for activity and agent, they need to 0149 // be at least magic values. These do not change the structure 0150 // of the database, but the old data. 0151 if (dbSchemaVersion < QStringLiteral("2015.02.09")) { 0152 const QString updateActivity = QStringLiteral( 0153 "SET usedActivity=':global' " 0154 "WHERE usedActivity IS NULL OR usedActivity = ''"); 0155 0156 const QString updateAgent = QStringLiteral( 0157 "SET initiatingAgent=':global' " 0158 "WHERE initiatingAgent IS NULL OR initiatingAgent = ''"); 0159 0160 // When the activity field was empty, it meant the file was 0161 // linked to all activities (aka :global) 0162 database.execQuery(QStringLiteral("UPDATE ResourceLink ") + updateActivity); 0163 0164 // When the agent field was empty, it meant the file was not 0165 // linked to a specified agent (aka :global) 0166 database.execQuery(QStringLiteral("UPDATE ResourceLink ") + updateAgent); 0167 0168 // These were not supposed to be empty, but in the case they were, 0169 // deal with them as well 0170 database.execQuery(QStringLiteral("UPDATE ResourceEvent ") + updateActivity); 0171 database.execQuery(QStringLiteral("UPDATE ResourceEvent ") + updateAgent); 0172 database.execQuery(QStringLiteral("UPDATE ResourceScoreCache ") + updateActivity); 0173 database.execQuery(QStringLiteral("UPDATE ResourceScoreCache ") + updateAgent); 0174 } 0175 } 0176 0177 } // namespace Common 0178 } // namespace ResourcesDatabaseSchema