File indexing completed on 2024-11-10 04:40:31

0001 /*
0002     SPDX-FileCopyrightText: 2014 Christian Mollekopf <mollekopf@kolabsys.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "relationfetchjob.h"
0008 #include "job_p.h"
0009 #include "private/protocol_p.h"
0010 #include "protocolhelper_p.h"
0011 #include <QTimer>
0012 
0013 using namespace Akonadi;
0014 
0015 class Akonadi::RelationFetchJobPrivate : public JobPrivate
0016 {
0017 public:
0018     explicit RelationFetchJobPrivate(RelationFetchJob *parent)
0019         : JobPrivate(parent)
0020     {
0021         mEmitTimer.setSingleShot(true);
0022         mEmitTimer.setInterval(std::chrono::milliseconds{100});
0023     }
0024 
0025     void init()
0026     {
0027         QObject::connect(&mEmitTimer, &QTimer::timeout, q_ptr, [this]() {
0028             timeout();
0029         });
0030     }
0031 
0032     void aboutToFinish() override
0033     {
0034         timeout();
0035     }
0036 
0037     void timeout()
0038     {
0039         Q_Q(RelationFetchJob);
0040         mEmitTimer.stop(); // in case we are called by result()
0041         if (!mPendingRelations.isEmpty()) {
0042             if (!q->error()) {
0043                 Q_EMIT q->relationsReceived(mPendingRelations);
0044             }
0045             mPendingRelations.clear();
0046         }
0047     }
0048 
0049     Q_DECLARE_PUBLIC(RelationFetchJob)
0050 
0051     Relation::List mResultRelations;
0052     Relation::List mPendingRelations; // relation pending for emitting itemsReceived()
0053     QTimer mEmitTimer;
0054     QList<QByteArray> mTypes;
0055     QString mResource;
0056     Relation mRequestedRelation;
0057 };
0058 
0059 RelationFetchJob::RelationFetchJob(const Relation &relation, QObject *parent)
0060     : Job(new RelationFetchJobPrivate(this), parent)
0061 {
0062     Q_D(RelationFetchJob);
0063     d->init();
0064     d->mRequestedRelation = relation;
0065 }
0066 
0067 RelationFetchJob::RelationFetchJob(const QList<QByteArray> &types, QObject *parent)
0068     : Job(new RelationFetchJobPrivate(this), parent)
0069 {
0070     Q_D(RelationFetchJob);
0071     d->init();
0072     d->mTypes = types;
0073 }
0074 
0075 void RelationFetchJob::doStart()
0076 {
0077     Q_D(RelationFetchJob);
0078 
0079     d->sendCommand(Protocol::FetchRelationsCommandPtr::create(
0080         d->mRequestedRelation.left().id(),
0081         d->mRequestedRelation.right().id(),
0082         (d->mTypes.isEmpty() && !d->mRequestedRelation.type().isEmpty()) ? QList<QByteArray>() << d->mRequestedRelation.type() : d->mTypes,
0083         d->mResource));
0084 }
0085 
0086 bool RelationFetchJob::doHandleResponse(qint64 tag, const Protocol::CommandPtr &response)
0087 {
0088     Q_D(RelationFetchJob);
0089 
0090     if (!response->isResponse() || response->type() != Protocol::Command::FetchRelations) {
0091         return Job::doHandleResponse(tag, response);
0092     }
0093 
0094     const Relation rel = ProtocolHelper::parseRelationFetchResult(Protocol::cmdCast<Protocol::FetchRelationsResponse>(response));
0095     // Invalid response means there will be no more responses
0096     if (!rel.isValid()) {
0097         return true;
0098     }
0099 
0100     d->mResultRelations.append(rel);
0101     d->mPendingRelations.append(rel);
0102     if (!d->mEmitTimer.isActive()) {
0103         d->mEmitTimer.start();
0104     }
0105     return false;
0106 }
0107 
0108 Relation::List RelationFetchJob::relations() const
0109 {
0110     Q_D(const RelationFetchJob);
0111     return d->mResultRelations;
0112 }
0113 
0114 void RelationFetchJob::setResource(const QString &identifier)
0115 {
0116     Q_D(RelationFetchJob);
0117     d->mResource = identifier;
0118 }
0119 
0120 #include "moc_relationfetchjob.cpp"