File indexing completed on 2024-06-16 04:50:14
0001 /* 0002 SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "akonadicore_export.h" 0010 #include "item.h" 0011 #include "job.h" 0012 0013 #include <QDateTime> 0014 0015 namespace Akonadi 0016 { 0017 class Collection; 0018 class ItemSyncPrivate; 0019 0020 /** 0021 * @short Syncs between items known to a client (usually a resource) and the Akonadi storage. 0022 * 0023 * Remote Id must only be set by the resource storing the item, other clients 0024 * should leave it empty, since the resource responsible for the target collection 0025 * will be notified about the addition and then create a suitable remote Id. 0026 * 0027 * There are two different forms of ItemSync usage: 0028 * - Full-Sync: meaning the client provides all valid items, i.e. any item not 0029 * part of the list but currently stored in Akonadi will be removed 0030 * - Incremental-Sync: meaning the client provides two lists, one for items which 0031 * are new or modified and one for items which should be removed. Any item not 0032 * part of either list but currently stored in Akonadi will not be changed. 0033 * 0034 * @note This is provided for convenience to implement "save all" like behavior, 0035 * however it is strongly recommended to use single item jobs whenever 0036 * possible, e.g. ItemCreateJob, ItemModifyJob and ItemDeleteJob 0037 * 0038 * @author Tobias Koenig <tokoe@kde.org> 0039 */ 0040 class AKONADICORE_EXPORT ItemSync : public Job 0041 { 0042 Q_OBJECT 0043 0044 public: 0045 enum MergeMode { 0046 RIDMerge, 0047 GIDMerge, 0048 }; 0049 0050 /** 0051 * Creates a new item synchronizer. 0052 * 0053 * @param collection The collection we are syncing. 0054 * @param timestamp Optional timestamp of itemsync start. Will be used to detect local changes that happen 0055 while the ItemSync is running. 0056 * @param parent The parent object. 0057 */ 0058 explicit ItemSync(const Collection &collection, const QDateTime ×tamp = {}, QObject *parent = nullptr); 0059 0060 /** 0061 * Destroys the item synchronizer. 0062 */ 0063 ~ItemSync() override; 0064 0065 /** 0066 * Sets the full item list for the collection. 0067 * 0068 * Usually the result of a full item listing. 0069 * 0070 * @warning If the client using this is a resource, all items must have 0071 * a valid remote identifier. 0072 * 0073 * @param items A list of items. 0074 */ 0075 void setFullSyncItems(const Item::List &items); 0076 0077 /** 0078 * Set the amount of items which you are going to return in total 0079 * by using the setFullSyncItems()/setIncrementalSyncItems() methods. 0080 * 0081 * @warning By default the item sync will automatically end once 0082 * sufficient items have been provided. 0083 * To disable this use setDisableAutomaticDeliveryDone 0084 * 0085 * @see setDisableAutomaticDeliveryDone 0086 * @param amount The amount of items in total. 0087 */ 0088 void setTotalItems(int amount); 0089 0090 /** 0091 Enable item streaming. Item streaming means that the items delivered by setXItems() calls 0092 are delivered in chunks and you manually indicate when all items have been delivered 0093 by calling deliveryDone(). 0094 @param enable @c true to enable item streaming 0095 */ 0096 void setStreamingEnabled(bool enable); 0097 0098 /** 0099 Notify ItemSync that all remote items have been delivered. 0100 Only call this in streaming mode. 0101 */ 0102 void deliveryDone(); 0103 0104 /** 0105 * Sets the item lists for incrementally syncing the collection. 0106 * 0107 * Usually the result of an incremental remote item listing. 0108 * 0109 * @warning If the client using this is a resource, all items must have 0110 * a valid remote identifier. 0111 * 0112 * @param changedItems A list of items added or changed by the client. 0113 * @param removedItems A list of items deleted by the client. 0114 */ 0115 void setIncrementalSyncItems(const Item::List &changedItems, const Item::List &removedItems); 0116 0117 /** 0118 * Aborts the sync process and rolls back all not yet committed transactions. 0119 * Use this if an external error occurred during the sync process (such as the 0120 * user canceling it). 0121 * @since 4.5 0122 */ 0123 void rollback(); 0124 0125 /** 0126 * Transaction mode used by ItemSync. 0127 * @since 4.6 0128 */ 0129 enum TransactionMode { 0130 SingleTransaction, ///< Use a single transaction for the entire sync process (default), provides maximum consistency ("all or nothing") and best 0131 ///< performance 0132 MultipleTransactions, ///< Use one transaction per chunk of delivered items, good compromise between the other two when using streaming 0133 NoTransaction ///< Use no transaction at all, provides highest responsiveness (might therefore feel faster even when actually taking slightly longer), 0134 ///< no consistency guaranteed (can fail anywhere in the sync process) 0135 }; 0136 0137 /** 0138 * Set the transaction mode to use for this sync. 0139 * @note You must call this method before starting the sync, changes afterwards lead to undefined results. 0140 * @param mode the transaction mode to use 0141 * @since 4.6 0142 */ 0143 void setTransactionMode(TransactionMode mode); 0144 0145 /** 0146 * Minimum number of items required to start processing in streaming mode. 0147 * When MultipleTransactions is used, one transaction per batch will be created. 0148 * 0149 * @see setBatchSize() 0150 * @since 4.14 0151 */ 0152 [[nodiscard]] int batchSize() const; 0153 0154 /** 0155 * Set the batch size. 0156 * 0157 * The default is 10. 0158 * 0159 * @note You must call this method before starting the sync, changes afterwards lead to undefined results. 0160 * @see batchSize() 0161 * @since 4.14 0162 */ 0163 void setBatchSize(int); 0164 0165 /** 0166 * Disables the automatic completion of the item sync, 0167 * based on the number of delivered items. 0168 * 0169 * This ensures that the item sync only finishes once deliveryDone() 0170 * is called, while still making it possible to use the progress 0171 * reporting of the ItemSync. 0172 * 0173 * @note You must call this method before starting the sync, changes afterwards lead to undefined results. 0174 * @see setTotalItems 0175 * @since 4.14 0176 */ 0177 void setDisableAutomaticDeliveryDone(bool disable); 0178 0179 /** 0180 * Returns current merge mode 0181 * 0182 * @see setMergeMode() 0183 * @since 5.1 0184 */ 0185 [[nodiscard]] MergeMode mergeMode() const; 0186 0187 /** 0188 * Set what merge method should be used for next ItemSync run 0189 * 0190 * By default ItemSync uses RIDMerge method. 0191 * 0192 * See ItemCreateJob for details on Item merging. 0193 * 0194 * @note You must call this method before starting the sync, changes afterwards lead to undefined results. 0195 * @see mergeMode 0196 * @since 4.14.11 0197 */ 0198 void setMergeMode(MergeMode mergeMode); 0199 0200 Q_SIGNALS: 0201 /** 0202 * Signals the resource that new items can be delivered. 0203 * @param remainingBatchSize the number of items required to complete the batch (typically the same as batchSize()) 0204 * 0205 * @since 4.14 0206 */ 0207 void readyForNextBatch(int remainingBatchSize); 0208 0209 /** 0210 * @internal 0211 * Emitted whenever a transaction is committed. This is for testing only. 0212 * 0213 * @since 4.14 0214 */ 0215 void transactionCommitted(); 0216 0217 protected: 0218 void doStart() override; 0219 void slotResult(KJob *job) override; 0220 0221 private: 0222 /// @cond PRIVATE 0223 Q_DECLARE_PRIVATE(ItemSync) 0224 0225 Q_PRIVATE_SLOT(d_func(), void slotLocalListDone(KJob *)) 0226 Q_PRIVATE_SLOT(d_func(), void slotTransactionResult(KJob *)) 0227 Q_PRIVATE_SLOT(d_func(), void slotItemsReceived(const Akonadi::Item::List &)) 0228 /// @endcond 0229 }; 0230 0231 }