File indexing completed on 2024-11-10 04:40:44
0001 /* 0002 SPDX-FileCopyrightText: 2014 Christian Mollekopf <mollekopf@kolabsys.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 namespace Akonadi 0007 { 0008 class Item; 0009 } 0010 0011 #include "relationsync.h" 0012 #include "akonadicore_debug.h" 0013 0014 #include "jobs/relationcreatejob.h" 0015 #include "jobs/relationdeletejob.h" 0016 #include "jobs/relationfetchjob.h" 0017 0018 using namespace Akonadi; 0019 0020 RelationSync::RelationSync(QObject *parent) 0021 : Job(parent) 0022 { 0023 } 0024 0025 RelationSync::~RelationSync() 0026 { 0027 } 0028 0029 void RelationSync::setRemoteRelations(const Akonadi::Relation::List &relations) 0030 { 0031 mRemoteRelations = relations; 0032 mRemoteRelationsSet = true; 0033 diffRelations(); 0034 } 0035 0036 void RelationSync::doStart() 0037 { 0038 auto fetch = new Akonadi::RelationFetchJob({Akonadi::Relation::GENERIC}, this); 0039 connect(fetch, &KJob::result, this, &RelationSync::onLocalFetchDone); 0040 } 0041 0042 void RelationSync::onLocalFetchDone(KJob *job) 0043 { 0044 auto fetch = static_cast<Akonadi::RelationFetchJob *>(job); 0045 mLocalRelations = fetch->relations(); 0046 mLocalRelationsFetched = true; 0047 diffRelations(); 0048 } 0049 0050 void RelationSync::diffRelations() 0051 { 0052 if (!mRemoteRelationsSet || !mLocalRelationsFetched) { 0053 qCDebug(AKONADICORE_LOG) << "waiting for delivery: " << mRemoteRelationsSet << mLocalRelationsFetched; 0054 return; 0055 } 0056 0057 QHash<QByteArray, Akonadi::Relation> relationByRid; 0058 for (const Akonadi::Relation &localRelation : std::as_const(mLocalRelations)) { 0059 if (!localRelation.remoteId().isEmpty()) { 0060 relationByRid.insert(localRelation.remoteId(), localRelation); 0061 } 0062 } 0063 0064 for (const Akonadi::Relation &remoteRelation : std::as_const(mRemoteRelations)) { 0065 if (relationByRid.contains(remoteRelation.remoteId())) { 0066 relationByRid.remove(remoteRelation.remoteId()); 0067 } else { 0068 // New relation or had its GID updated, so create one now 0069 auto createJob = new RelationCreateJob(remoteRelation, this); 0070 connect(createJob, &KJob::result, this, &RelationSync::checkDone); 0071 } 0072 } 0073 0074 for (const Akonadi::Relation &removedRelation : std::as_const(relationByRid)) { 0075 // Removed remotely, remove locally 0076 auto removeJob = new RelationDeleteJob(removedRelation, this); 0077 connect(removeJob, &KJob::result, this, &RelationSync::checkDone); 0078 } 0079 checkDone(); 0080 } 0081 0082 void RelationSync::slotResult(KJob *job) 0083 { 0084 if (job->error()) { 0085 qCWarning(AKONADICORE_LOG) << "Error during CollectionSync: " << job->errorString() << job->metaObject()->className(); 0086 // pretend there were no errors 0087 Akonadi::Job::removeSubjob(job); 0088 } else { 0089 Akonadi::Job::slotResult(job); 0090 } 0091 } 0092 0093 void RelationSync::checkDone() 0094 { 0095 if (hasSubjobs()) { 0096 qCDebug(AKONADICORE_LOG) << "Still going"; 0097 return; 0098 } 0099 qCDebug(AKONADICORE_LOG) << "done"; 0100 emitResult(); 0101 } 0102 0103 #include "moc_relationsync.cpp"