|
Rex Dieter |
d28f28 |
commit 992096665110674e8e9bc5be6e91c5b78249266e
|
|
Rex Dieter |
d28f28 |
Author: David Faure <faure@kde.org>
|
|
Rex Dieter |
d28f28 |
Date: Fri Jan 20 00:23:55 2012 +0100
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
New cleanup in "akonadictl fsck": clean up orphan resources from the DB
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
The only way this can ever happen is when hacking agentsrc and removing
|
|
Rex Dieter |
d28f28 |
resources from it (or removing the whole ~/.config). But then you get
|
|
Rex Dieter |
d28f28 |
dead collection trees in kmail, always red, always unusable, and this is
|
|
Rex Dieter |
d28f28 |
the only way to clean this up.
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
diff --git a/server/src/storagejanitor.cpp b/server/src/storagejanitor.cpp
|
|
Rex Dieter |
d28f28 |
index ea520a8..0e26596 100644
|
|
Rex Dieter |
d28f28 |
--- a/server/src/storagejanitor.cpp
|
|
Rex Dieter |
d28f28 |
+++ b/server/src/storagejanitor.cpp
|
|
Rex Dieter |
d28f28 |
@@ -21,6 +21,7 @@
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
#include "storage/datastore.h"
|
|
Rex Dieter |
d28f28 |
#include "storage/selectquerybuilder.h"
|
|
Rex Dieter |
d28f28 |
+#include "resourcemanager.h"
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
#include <akdbus.h>
|
|
Rex Dieter |
d28f28 |
#include <akdebug.h>
|
|
Rex Dieter |
d28f28 |
@@ -29,6 +30,8 @@
|
|
Rex Dieter |
d28f28 |
#include <libs/protocol_p.h>
|
|
Rex Dieter |
d28f28 |
#include <libs/xdgbasedirs_p.h>
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
+#include <agentmanagerinterface.h>
|
|
Rex Dieter |
d28f28 |
+
|
|
Rex Dieter |
d28f28 |
#include <QStringBuilder>
|
|
Rex Dieter |
d28f28 |
#include <QtDBus/QDBusConnection>
|
|
Rex Dieter |
d28f28 |
#include <QtSql/QSqlQuery>
|
|
Rex Dieter |
d28f28 |
@@ -70,8 +73,11 @@ StorageJanitor::~StorageJanitor()
|
|
Rex Dieter |
d28f28 |
DataStore::self()->close();
|
|
Rex Dieter |
d28f28 |
}
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
-void StorageJanitor::check()
|
|
Rex Dieter |
d28f28 |
+void StorageJanitor::check() // implementation of `akonadictl fsck`
|
|
Rex Dieter |
d28f28 |
{
|
|
Rex Dieter |
d28f28 |
+ inform( "Looking for resources in the DB not matching a configured resource..." );
|
|
Rex Dieter |
d28f28 |
+ findOrphanedResources();
|
|
Rex Dieter |
d28f28 |
+
|
|
Rex Dieter |
d28f28 |
inform( "Looking for collections not belonging to a valid resource..." );
|
|
Rex Dieter |
d28f28 |
findOrphanedCollections();
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
@@ -106,6 +112,43 @@ void StorageJanitor::check()
|
|
Rex Dieter |
d28f28 |
inform( "Consistency check done." );
|
|
Rex Dieter |
d28f28 |
}
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
+void StorageJanitor::findOrphanedResources()
|
|
Rex Dieter |
d28f28 |
+{
|
|
Rex Dieter |
d28f28 |
+ SelectQueryBuilder<Resource> qbres;
|
|
Rex Dieter |
d28f28 |
+ OrgFreedesktopAkonadiAgentManagerInterface iface(
|
|
Rex Dieter |
d28f28 |
+ AkDBus::serviceName(AkDBus::Control),
|
|
Rex Dieter |
d28f28 |
+ QLatin1String( "/AgentManager" ),
|
|
Rex Dieter |
d28f28 |
+ QDBusConnection::sessionBus(),
|
|
Rex Dieter |
d28f28 |
+ this
|
|
Rex Dieter |
d28f28 |
+ );
|
|
Rex Dieter |
d28f28 |
+ if (!iface.isValid()) {
|
|
Rex Dieter |
d28f28 |
+ inform( QString::fromLatin1("ERROR: Couldn't talk to %1").arg(AkDBus::Control) );
|
|
Rex Dieter |
d28f28 |
+ return;
|
|
Rex Dieter |
d28f28 |
+ }
|
|
Rex Dieter |
d28f28 |
+ const QStringList knownResources = iface.agentInstances();
|
|
Rex Dieter |
d28f28 |
+ if (knownResources.isEmpty()) {
|
|
Rex Dieter |
d28f28 |
+ inform( QString::fromLatin1("ERROR: no known resources. This must be a mistake?") );
|
|
Rex Dieter |
d28f28 |
+ return;
|
|
Rex Dieter |
d28f28 |
+ }
|
|
Rex Dieter |
d28f28 |
+ akDebug() << "Known resources:" << knownResources;
|
|
Rex Dieter |
d28f28 |
+ qbres.addValueCondition( Resource::nameFullColumnName(), Query::NotIn, QVariant(knownResources) );
|
|
Rex Dieter |
d28f28 |
+ qbres.addValueCondition( Resource::idFullColumnName(), Query::NotEquals, 1 ); // skip akonadi_search_resource
|
|
Rex Dieter |
d28f28 |
+ qbres.exec();
|
|
Rex Dieter |
d28f28 |
+ //akDebug() << "SQL:" << qbres.query().lastQuery();
|
|
Rex Dieter |
d28f28 |
+ const Resource::List orphanResources = qbres.result();
|
|
Rex Dieter |
d28f28 |
+ if ( orphanResources.size() > 0 ) {
|
|
Rex Dieter |
d28f28 |
+ QStringList resourceNames;
|
|
Rex Dieter |
d28f28 |
+ foreach ( const Resource& resource, orphanResources ) {
|
|
Rex Dieter |
d28f28 |
+ resourceNames.append(resource.name());
|
|
Rex Dieter |
d28f28 |
+ }
|
|
Rex Dieter |
d28f28 |
+ inform( QString::fromLatin1( "Found %1 orphan resources: %2" ).arg( orphanResources.size() ). arg( resourceNames.join(QLatin1String(",")) ) );
|
|
Rex Dieter |
d28f28 |
+ foreach ( const QString& resourceName, resourceNames ) {
|
|
Rex Dieter |
d28f28 |
+ inform( QString::fromLatin1( "Removing resource %1" ).arg( resourceName ) );
|
|
Rex Dieter |
d28f28 |
+ ResourceManager::self()->removeResourceInstance( resourceName );
|
|
Rex Dieter |
d28f28 |
+ }
|
|
Rex Dieter |
d28f28 |
+ }
|
|
Rex Dieter |
d28f28 |
+}
|
|
Rex Dieter |
d28f28 |
+
|
|
Rex Dieter |
d28f28 |
void StorageJanitor::findOrphanedCollections()
|
|
Rex Dieter |
d28f28 |
{
|
|
Rex Dieter |
d28f28 |
SelectQueryBuilder<Collection> qb;
|
|
Rex Dieter |
d28f28 |
@@ -137,7 +180,7 @@ void StorageJanitor::checkPathToRoot(const Akonadi::Collection& col)
|
|
Rex Dieter |
d28f28 |
+ QLatin1Literal( ") belongs to a different resource than its parent." ) );
|
|
Rex Dieter |
d28f28 |
// can/should we actually fix that?
|
|
Rex Dieter |
d28f28 |
}
|
|
Rex Dieter |
d28f28 |
-
|
|
Rex Dieter |
d28f28 |
+
|
|
Rex Dieter |
d28f28 |
checkPathToRoot( parent );
|
|
Rex Dieter |
d28f28 |
}
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
diff --git a/server/src/storagejanitor.h b/server/src/storagejanitor.h
|
|
Rex Dieter |
d28f28 |
index afc79c6..be3442e 100644
|
|
Rex Dieter |
d28f28 |
--- a/server/src/storagejanitor.h
|
|
Rex Dieter |
d28f28 |
+++ b/server/src/storagejanitor.h
|
|
Rex Dieter |
d28f28 |
@@ -63,6 +63,11 @@ class StorageJanitor : public QObject
|
|
Rex Dieter |
d28f28 |
void inform( const QString &msg );
|
|
Rex Dieter |
d28f28 |
|
|
Rex Dieter |
d28f28 |
/**
|
|
Rex Dieter |
d28f28 |
+ * Look for resources in the DB not existing in reality.
|
|
Rex Dieter |
d28f28 |
+ */
|
|
Rex Dieter |
d28f28 |
+ void findOrphanedResources();
|
|
Rex Dieter |
d28f28 |
+
|
|
Rex Dieter |
d28f28 |
+ /**
|
|
Rex Dieter |
d28f28 |
* Look for collections belonging to non-existent resources.
|
|
Rex Dieter |
d28f28 |
*/
|
|
Rex Dieter |
d28f28 |
void findOrphanedCollections();
|