File indexing completed on 2024-05-26 05:14:37
0001 /* 0002 SPDX-FileCopyrightText: 2011 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "akthread.h" 0010 #include "storage/dbconfig.h" 0011 0012 #include <QDBusConnection> 0013 0014 namespace Akonadi 0015 { 0016 namespace Server 0017 { 0018 class Collection; 0019 class AkonadiServer; 0020 class DataStore; 0021 0022 /** 0023 * Various database checking/maintenance features. 0024 */ 0025 class StorageJanitor : public AkThread 0026 { 0027 Q_OBJECT 0028 Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Akonadi.Janitor") 0029 0030 protected: 0031 /** 0032 * Use AkThread::create() to create and start a new StorageJanitor thread. 0033 */ 0034 explicit StorageJanitor(AkonadiServer *mAkonadi, DbConfig *config = DbConfig::configuredDatabase()); 0035 0036 public: 0037 /** 0038 * Use AkThread::create() to run StorageJanitor in a separate thread. Only use this constructor 0039 * if you want to run StorageJanitor in the current thread. 0040 */ 0041 explicit StorageJanitor(DbConfig *config); 0042 ~StorageJanitor() override; 0043 0044 public Q_SLOTS: 0045 /** Triggers a consistency check of the internal storage. */ 0046 Q_SCRIPTABLE Q_NOREPLY void check(); 0047 /** Triggers a vacuuming of the database, that is compacting of unused space. */ 0048 Q_SCRIPTABLE Q_NOREPLY void vacuum(); 0049 0050 Q_SIGNALS: 0051 /** Sends informational messages to a possible UI for this. */ 0052 Q_SCRIPTABLE void information(const QString &msg); 0053 Q_SCRIPTABLE void done(); 0054 0055 protected: 0056 void init() override; 0057 void quit() override; 0058 0059 private: 0060 void registerTasks(); 0061 0062 void inform(const char *msg); 0063 void inform(const QString &msg); 0064 /** Create a lost+found collection if necessary. */ 0065 qint64 lostAndFoundCollection(); 0066 0067 /** 0068 * Look for resources in the DB not existing in reality. 0069 */ 0070 void findOrphanedResources(); 0071 0072 /** 0073 * Look for collections belonging to non-existent resources. 0074 */ 0075 void findOrphanedCollections(); 0076 0077 /** 0078 * Verifies that each collection in the collection tree has a path to the root 0079 * and that all collections along that path belong to the same resource. 0080 */ 0081 void checkCollectionTreeConsistency(); 0082 void checkPathToRoot(const Collection &col); 0083 0084 /** 0085 * Look for items belonging to non-existing collections. 0086 */ 0087 void findOrphanedItems(); 0088 0089 /** 0090 * Look for parts belonging to non-existing items. 0091 */ 0092 void findOrphanedParts(); 0093 0094 /** 0095 * Look for item flags belonging to non-existing items. 0096 */ 0097 void findOrphanedPimItemFlags(); 0098 0099 /** 0100 * Look for duplicate item flags and fix them. 0101 */ 0102 void findDuplicateFlags(); 0103 0104 /** 0105 * Look for duplicate mime type names and fix them. 0106 */ 0107 void findDuplicateMimeTypes(); 0108 0109 /** 0110 * Look for duplicate part type names and fix them. 0111 */ 0112 void findDuplicatePartTypes(); 0113 0114 /** 0115 * Look for duplicate tag names and fix them. 0116 */ 0117 void findDuplicateTagTypes(); 0118 0119 /** 0120 * Look for duplicate relation type names and fix them. 0121 */ 0122 void findDuplicateRelationTypes(); 0123 0124 /** 0125 * Look for parts referring to the same external file. 0126 */ 0127 void findOverlappingParts(); 0128 0129 /** 0130 * Verify fs and db part state. 0131 */ 0132 void verifyExternalParts(); 0133 0134 /** 0135 * Look for dirty objects. 0136 */ 0137 void findDirtyObjects(); 0138 0139 /** 0140 * Look for duplicates by RID. 0141 * 0142 * ..and remove the one that doesn't match the parent collections content mimetype. 0143 */ 0144 void findRIDDuplicates(); 0145 0146 /** 0147 * Check whether part sizes match what's in database. 0148 * 0149 * If SizeTreshold has change, it will move parts from or to database 0150 * where necessary. 0151 */ 0152 void checkSizeTreshold(); 0153 0154 /** 0155 * Check if all external payload files are migrated to the levelled folder 0156 * hierarchy and migrates them if necessary 0157 */ 0158 void migrateToLevelledCacheHierarchy(); 0159 0160 /** 0161 * Check if the search index contains any entries that refer to Akonadi 0162 * Items that no longer exist in the DB. 0163 */ 0164 void findOrphanSearchIndexEntries(); 0165 0166 /** 0167 * Make sure that the "Search" collection in the virtual search resource 0168 * exists. It is only created during database initialization, so if user 0169 * somehow manages to delete it, their search would be completely borked. 0170 */ 0171 void ensureSearchCollection(); 0172 0173 /** 0174 * Clear cache that holds pre-computed collection statistics. 0175 * They will be re-computed on demand. 0176 */ 0177 void expireCollectionStatisticsCache(); 0178 0179 private: 0180 qint64 m_lostFoundCollectionId; 0181 AkonadiServer *m_akonadi = nullptr; 0182 DbConfig *m_dbConfig = nullptr; 0183 std::unique_ptr<DataStore> m_dataStore; 0184 0185 struct Task { 0186 QString name; 0187 void (StorageJanitor::*func)(); 0188 }; 0189 QList<Task> m_tasks; 0190 }; 0191 0192 } // namespace Server 0193 } // namespace Akonadi