File indexing completed on 2025-01-05 04:46:59

0001 /*
0002     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <QDateTime>
0010 #include <QObject>
0011 
0012 #include "../exception.h"
0013 #include "entities.h"
0014 
0015 #include "private/imapset_p.h"
0016 #include "private/scope_p.h"
0017 
0018 #include <optional>
0019 
0020 AKONADI_EXCEPTION_MAKE_INSTANCE(ItemRetrieverException);
0021 
0022 namespace Akonadi
0023 {
0024 namespace Server
0025 {
0026 class Connection;
0027 class CommandContext;
0028 class ItemRetrievalManager;
0029 class ItemRetrievalRequest;
0030 
0031 /**
0032   Helper class for retrieving missing items parts from remote resources.
0033 
0034   Stuff in here happens in the calling thread and does not access shared data.
0035 
0036   @todo make usable for Fetch by allowing to share queries
0037 */
0038 class ItemRetriever : public QObject
0039 {
0040     Q_OBJECT
0041 
0042 public:
0043     explicit ItemRetriever(ItemRetrievalManager &manager, Connection *connection, const CommandContext &context);
0044 
0045     Connection *connection() const;
0046 
0047     void setRetrieveParts(const QList<QByteArray> &parts);
0048     QList<QByteArray> retrieveParts() const;
0049     void setRetrieveFullPayload(bool fullPayload);
0050     void setChangedSince(const QDateTime &changedSince);
0051     void setItemSet(const ImapSet &set, const Collection &collection = Collection());
0052     void setItemSet(const ImapSet &set, bool isUid);
0053     void setItem(Entity::Id id);
0054     /** Retrieve all items in the given collection. */
0055     void setCollection(const Collection &collection, bool recursive = true);
0056 
0057     /** Retrieve all items matching the given item scope. */
0058     void setScope(const Scope &scope);
0059     Scope scope() const;
0060 
0061     bool exec();
0062 
0063     QByteArray lastError() const;
0064 
0065 Q_SIGNALS:
0066     void itemsRetrieved(const QList<qint64> &ids);
0067 
0068 private:
0069     QSqlQuery buildQuery() const;
0070 
0071     /**
0072      * Checks if external files are still present
0073      * This costs extra, but allows us to automatically recover from something changing the external file storage.
0074      */
0075     void verifyCache();
0076 
0077     /// Execute the retrieval
0078     bool runItemRetrievalRequests(std::list<ItemRetrievalRequest> requests);
0079     struct PreparedRequests {
0080         std::list<ItemRetrievalRequest> requests;
0081         QList<qint64> readyItems;
0082     };
0083     std::optional<PreparedRequests> prepareRequests(QSqlQuery &query, const QByteArrayList &parts);
0084 
0085     Akonadi::ImapSet mItemSet;
0086     Collection mCollection;
0087     Scope mScope;
0088     ItemRetrievalManager &mItemRetrievalManager;
0089     Connection *mConnection = nullptr;
0090     const CommandContext &mContext;
0091     QList<QByteArray> mParts;
0092     bool mFullPayload;
0093     bool mRecursive;
0094     QDateTime mChangedSince;
0095     mutable QByteArray mLastError;
0096     bool mCanceled;
0097 };
0098 
0099 } // namespace Server
0100 } // namespace Akonadi