Akonadi

resourcebase.h
1 /*
2  This file is part of akonadiresources.
3 
4  SPDX-FileCopyrightText: 2006 Till Adam <[email protected]>
5  SPDX-FileCopyrightText: 2007 Volker Krause <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #pragma once
11 
12 #include "agentbase.h"
13 #include "akonadiagentbase_export.h"
14 // AkonadiCore
15 #include <akonadi/collection.h>
16 #include <akonadi/item.h>
17 #include <akonadi/itemsync.h>
18 
19 class KJob;
20 class Akonadi__ResourceAdaptor;
21 class ResourceState;
22 
23 namespace Akonadi
24 {
25 class ResourceBasePrivate;
26 
27 /**
28  * @short The base class for all Akonadi resources.
29  *
30  * This class should be used as a base class by all resource agents,
31  * because it encapsulates large parts of the protocol between
32  * resource agent, agent manager and the Akonadi storage.
33  *
34  * It provides many convenience methods to make implementing a
35  * new Akonadi resource agent as simple as possible.
36  *
37  * <h4>How to write a resource</h4>
38  *
39  * The following provides an overview of what you need to do to implement
40  * your own Akonadi resource. In the following, the term 'backend' refers
41  * to the entity the resource connects with Akonadi, be it a single file
42  * or a remote server.
43  *
44  * @todo Complete this (online/offline state management)
45  *
46  * <h5>Basic %Resource Framework</h5>
47  *
48  * The following is needed to create a new resource:
49  * - A new class deriving from Akonadi::ResourceBase, implementing at least all
50  * pure-virtual methods, see below for further details.
51  * - call init() in your main() function.
52  * - a .desktop file similar to the following example
53  * \code
54  * [Desktop Entry]
55  * Name=My Akonadi Resource
56  * Type=AkonadiResource
57  * Exec=akonadi_my_resource
58  * Icon=my-icon
59  *
60  * X-Akonadi-MimeTypes=<supported-mimetypes>
61  * X-Akonadi-Capabilities=Resource
62  * X-Akonadi-Identifier=akonadi_my_resource
63  * \endcode
64  *
65  * <h5>Handling PIM Items</h5>
66  *
67  * To follow item changes in the backend, the following steps are necessary:
68  * - Implement retrieveItems() to synchronize all items in the given
69  * collection. If the backend supports incremental retrieval,
70  * implementing support for that is recommended to improve performance.
71  * - Convert the items provided by the backend to Akonadi items.
72  * This typically happens either in retrieveItems() if you retrieved
73  * the collection synchronously (not recommended for network backends) or
74  * in the result slot of the asynchronous retrieval job.
75  * Converting means to create Akonadi::Item objects for every retrieved
76  * item. It's very important that every object has its remote identifier set.
77  * - Call itemsRetrieved() or itemsRetrievedIncremental() respectively
78  * with the item objects created above. The Akonadi storage will then be
79  * updated automatically. Note that it is usually not necessary to manipulate
80  * any item in the Akonadi storage manually.
81  *
82  * To fetch item data on demand, the method retrieveItem() needs to be
83  * reimplemented. Fetch the requested data there and call itemRetrieved()
84  * with the result item.
85  *
86  * To write local changes back to the backend, you need to re-implement
87  * the following three methods:
88  * - itemAdded()
89  * - itemChanged()
90  * - itemRemoved()
91  *
92  * Note that these three functions don't get the full payload of the items by default,
93  * you need to change the item fetch scope of the change recorder to fetch the full
94  * payload. This can be expensive with big payloads, though.<br>
95  * Once you have handled changes in itemAdded() and itemChanged(), call changeCommitted().
96  * Once you have handled changes in itemRemoved(), call changeProcessed();
97  * These methods are called whenever a local item related to this resource is
98  * added, modified or deleted. They are only called if the resource is online, otherwise
99  * all changes are recorded and replayed as soon the resource is online again.
100  *
101  * <h5>Handling Collections</h5>
102  *
103  * To follow collection changes in the backend, the following steps are necessary:
104  * - Implement retrieveCollections() to retrieve collections from the backend.
105  * If the backend supports incremental collections updates, implementing
106  * support for that is recommended to improve performance.
107  * - Convert the collections of the backend to Akonadi collections.
108  * This typically happens either in retrieveCollections() if you retrieved
109  * the collection synchronously (not recommended for network backends) or
110  * in the result slot of the asynchronous retrieval job.
111  * Converting means to create Akonadi::Collection objects for every retrieved
112  * collection. It's very important that every object has its remote identifier
113  * and its parent remote identifier set.
114  * - Call collectionsRetrieved() or collectionsRetrievedIncremental() respectively
115  * with the collection objects created above. The Akonadi storage will then be
116  * updated automatically. Note that it is usually not necessary to manipulate
117  * any collection in the Akonadi storage manually.
118  *
119  *
120  * To write local collection changes back to the backend, you need to re-implement
121  * the following three methods:
122  * - collectionAdded()
123  * - collectionChanged()
124  * - collectionRemoved()
125  * Once you have handled changes in collectionAdded() and collectionChanged(), call changeCommitted().
126  * Once you have handled changes in collectionRemoved(), call changeProcessed();
127  * These methods are called whenever a local collection related to this resource is
128  * added, modified or deleted. They are only called if the resource is online, otherwise
129  * all changes are recorded and replayed as soon the resource is online again.
130  *
131  * @todo Convenience base class for collection-less resources
132  */
133 // FIXME_API: API dox need to be updated for Observer approach (kevin)
134 class AKONADIAGENTBASE_EXPORT ResourceBase : public AgentBase
135 {
136  Q_OBJECT
137 
138 public:
139  /**
140  * Use this method in the main function of your resource
141  * application to initialize your resource subclass.
142  * This method also takes care of creating a KApplication
143  * object and parsing command line arguments.
144  *
145  * @note In case the given class is also derived from AgentBase::Observer
146  * it gets registered as its own observer (see AgentBase::Observer), e.g.
147  * <tt>resourceInstance->registerObserver( resourceInstance );</tt>
148  *
149  * @code
150  *
151  * class MyResource : public ResourceBase
152  * {
153  * ...
154  * };
155  *
156  * int main( int argc, char **argv )
157  * {
158  * return ResourceBase::init<MyResource>( argc, argv );
159  * }
160  *
161  * @endcode
162  *
163  * @param argc number of arguments
164  * @param argv string arguments
165  */
166  template<typename T>
167  static int init(int argc, char **argv)
168  {
169  // Disable session management
170  qunsetenv("SESSION_MANAGER");
171 
172  QApplication app(argc, argv);
173  debugAgent(argc, argv);
174  const QString id = parseArguments(argc, argv);
175  T r(id);
176 
177  // check if T also inherits AgentBase::Observer and
178  // if it does, automatically register it on itself
179  auto observer = dynamic_cast<Observer *>(&r);
180  if (observer != nullptr) {
181  r.registerObserver(observer);
182  }
183 
184  return init(r);
185  }
186 
187  /**
188  * This method is used to set the name of the resource.
189  */
190  void setName(const QString &name);
191 
192  /**
193  * Returns the name of the resource.
194  */
195  Q_REQUIRED_RESULT QString name() const;
196 
197  /**
198  * Enable or disable automatic progress reporting. By default, it is enabled.
199  * When enabled, the resource will automatically emit the signals percent() and status()
200  * while syncing items or collections.
201  *
202  * The automatic progress reporting is done on a per item / per collection basis, so if a
203  * finer granularity is desired, automatic reporting should be disabled and the subclass should
204  * emit the percent() and status() signals itself.
205  *
206  * @param enabled Whether or not automatic emission of the signals is enabled.
207  * @since 4.7
208  */
209  void setAutomaticProgressReporting(bool enabled);
210 
211 Q_SIGNALS:
212  /**
213  * This signal is emitted whenever the name of the resource has changed.
214  *
215  * @param name The new name of the resource.
216  */
217  void nameChanged(const QString &name);
218 
219  /**
220  * Emitted when a full synchronization has been completed.
221  */
222  void synchronized();
223 
224  /**
225  * Emitted when a collection attributes synchronization has been completed.
226  *
227  * @param collectionId The identifier of the collection whose attributes got synchronized.
228  * @since 4.6
229  */
230  void attributesSynchronized(qlonglong collectionId);
231 
232  /**
233  * Emitted when a collection tree synchronization has been completed.
234  *
235  * @since 4.8
236  */
237  void collectionTreeSynchronized();
238 
239  /**
240  * Emitted when the item synchronization processed the current batch and is ready for a new one.
241  * Use this to throttle the delivery to not overload Akonadi.
242  *
243  * Throttling can be used during item retrieval (retrieveItems(Akonadi::Collection)) in streaming mode.
244  * To throttle only deliver itemSyncBatchSize() items, and wait for this signal, then again deliver
245  * @param remainingBatchSize items.
246  *
247  * By always only providing the number of items required to process the batch, the items don't pile
248  * up in memory and items are only provided as fast as Akonadi can process them.
249  *
250  * @see batchSize()
251  *
252  * @since 4.14
253  */
254  void retrieveNextItemSyncBatch(int remainingBatchSize);
255 
256 protected Q_SLOTS:
257  /**
258  * Retrieve the collection tree from the remote server and supply it via
259  * collectionsRetrieved() or collectionsRetrievedIncremental().
260  * @see collectionsRetrieved(), collectionsRetrievedIncremental()
261  */
262  virtual void retrieveCollections() = 0;
263 
264  /**
265  * Retrieve all tags from the backend
266  * @see tagsRetrieved()
267  */
268  virtual void retrieveTags();
269 
270  /**
271  * Retrieve all relations from the backend
272  * @see relationsRetrieved()
273  */
274  virtual void retrieveRelations();
275 
276  /**
277  * Retrieve the attributes of a single collection from the backend. The
278  * collection to retrieve attributes for is provided as @p collection.
279  * Add the attributes parts and call collectionAttributesRetrieved()
280  * when done.
281  *
282  * @param collection The collection whose attributes should be retrieved.
283  * @see collectionAttributesRetrieved()
284  * @since 4.6
285  */
286  virtual void retrieveCollectionAttributes(const Akonadi::Collection &collection);
287 
288  /**
289  * Retrieve all (new/changed) items in collection @p collection.
290  * It is recommended to use incremental retrieval if the backend supports that
291  * and provide the result by calling itemsRetrievedIncremental().
292  * If incremental retrieval is not possible, provide the full listing by calling
293  * itemsRetrieved( const Item::List& ).
294  * In any case, ensure that all items have a correctly set remote identifier
295  * to allow synchronizing with items already existing locally.
296  * In case you don't want to use the built-in item syncing code, store the retrieved
297  * items manually and call itemsRetrieved() once you are done.
298  * @param collection The collection whose items to retrieve.
299  * @see itemsRetrieved( const Item::List& ), itemsRetrievedIncremental(), itemsRetrieved(), currentCollection(), batchSize()
300  */
301  virtual void retrieveItems(const Akonadi::Collection &collection) = 0;
302 
303  /**
304  * Returns the batch size used during the item sync.
305  *
306  * This can be used to throttle the item delivery.
307  *
308  * @see retrieveNextItemSyncBatch(int), retrieveItems(Akonadi::Collection)
309  * @since 4.14
310  */
311  int itemSyncBatchSize() const;
312 
313  /**
314  * Set the batch size used during the item sync.
315  * The default is 10.
316  *
317  * @see retrieveNextItemSyncBatch(int)
318  * @since 4.14
319  */
320  void setItemSyncBatchSize(int batchSize);
321 
322  /**
323  * Set to true to schedule an attribute sync before every item sync.
324  * The default is false.
325  *
326  * @since 4.15
327  */
328  void setScheduleAttributeSyncBeforeItemSync(bool);
329 
330  /**
331  * Retrieve a single item from the backend. The item to retrieve is provided as @p item.
332  * Add the requested payload parts and call itemRetrieved() when done.
333  * @param item The empty item whose payload should be retrieved. Use this object when delivering
334  * the result instead of creating a new item to ensure conflict detection will work.
335  * @param parts The item parts that should be retrieved.
336  * @return false if there is an immediate error when retrieving the item.
337  * @see itemRetrieved()
338  * @deprecated Use retrieveItems(const Akonadi::Item::List &, const QSet<QByteArray> &) instead.
339  */
340  AKONADIAGENTBASE_DEPRECATED virtual bool retrieveItem(const Akonadi::Item &item, const QSet<QByteArray> &parts);
341 
342  /**
343  * Retrieve given @p items from the backend.
344  * Add the requested payload parts and call itemsRetrieved() when done.
345  * It is guaranteed that all @p items in the list belong to the same Collection.
346  *
347  * If the items are retrieved synchronously in this method, in case of an error
348  * emit error(const QString &) and return @c false, which will cancel the current task.
349  * If the items are retrieved asynchronously, in case of an non-immediate error you need
350  * to call cancelTask() or cancelTask(const QString&) in the respective handler methods
351  * explicitly.
352  *
353  * @param items The items whose payload should be retrieved. Use those objects
354  * when delivering the result instead of creating new items to ensure conflict
355  * detection will work.
356  * @param parts The item parts that should be retrieved.
357  * @return false if there is an immediate error when retrieving the items.
358  * @see itemsRetrieved()
359  * @since 5.4
360  *
361  * @todo: Make this method pure virtual once retrieveItem() is gone
362  */
363  virtual bool retrieveItems(const Akonadi::Item::List &items, const QSet<QByteArray> &parts);
364 
365  /**
366  * Abort any activity in progress in the backend. By default this method does nothing.
367  *
368  * @since 4.6
369  */
370  virtual void abortActivity();
371 
372  /**
373  * Dump resource internals, for debugging.
374  * @since 4.9
375  */
377  {
378  return QString();
379  }
380 
381 protected:
382  /**
383  * Creates a base resource.
384  *
385  * @param id The instance id of the resource.
386  */
387  ResourceBase(const QString &id);
388 
389  /**
390  * Destroys the base resource.
391  */
392  ~ResourceBase() override;
393 
394  /**
395  * Call this method from retrieveItem() once the result is available.
396  *
397  * @param item The retrieved item.
398  */
399  void itemRetrieved(const Item &item);
400 
401  /**
402  * Call this method from retrieveCollectionAttributes() once the result is available.
403  *
404  * @param collection The collection whose attributes got retrieved.
405  * @since 4.6
406  */
407  void collectionAttributesRetrieved(const Collection &collection);
408 
409  /**
410  * Resets the dirty flag of the given item and updates the remote id.
411  *
412  * Call whenever you have successfully written changes back to the server.
413  * This implicitly calls changeProcessed().
414  * @param item The changed item.
415  */
416  void changeCommitted(const Item &item);
417 
418  /**
419  * Resets the dirty flag of all given items and updates remote ids.
420  *
421  * Call whenever you have successfully written changes back to the server.
422  * This implicitly calls changeProcessed().
423  * @param items Changed items
424  *
425  * @since 4.11
426  */
427  void changesCommitted(const Item::List &items);
428 
429  /**
430  * Resets the dirty flag of the given tag and updates the remote id.
431  *
432  * Call whenever you have successfully written changes back to the server.
433  * This implicitly calls changeProcessed().
434  * @param tag Changed tag.
435  *
436  * @since 4.13
437  */
438  void changeCommitted(const Tag &tag);
439 
440  /**
441  * Call whenever you have successfully handled or ignored a collection
442  * change notification.
443  *
444  * This will update the remote identifier of @p collection if necessary,
445  * as well as any other collection attributes.
446  * This implicitly calls changeProcessed().
447  * @param collection The collection which changes have been handled.
448  */
449  void changeCommitted(const Collection &collection);
450 
451  /**
452  * Call this to supply the full folder tree retrieved from the remote server.
453  *
454  * @param collections A list of collections.
455  * @see collectionsRetrievedIncremental()
456  */
457  void collectionsRetrieved(const Collection::List &collections);
458 
459  void tagsRetrieved(const Tag::List &tags, const QHash<QString, Item::List> &tagMembers);
460  void relationsRetrieved(const Relation::List &relations);
461 
462  /**
463  * Call this to supply incrementally retrieved collections from the remote server.
464  *
465  * @param changedCollections Collections that have been added or changed.
466  * @param removedCollections Collections that have been deleted.
467  * @see collectionsRetrieved()
468  */
469  void collectionsRetrievedIncremental(const Collection::List &changedCollections, const Collection::List &removedCollections);
470 
471  /**
472  * Enable collection streaming, that is collections don't have to be delivered at once
473  * as result of a retrieveCollections() call but can be delivered by multiple calls
474  * to collectionsRetrieved() or collectionsRetrievedIncremental(). When all collections
475  * have been retrieved, call collectionsRetrievalDone().
476  * @param enable @c true if collection streaming should be enabled, @c false by default
477  */
478  void setCollectionStreamingEnabled(bool enable);
479 
480  /**
481  * Call this method to indicate you finished synchronizing the collection tree.
482  *
483  * This is not needed if you use the built in syncing without collection streaming
484  * and call collectionsRetrieved() or collectionRetrievedIncremental() instead.
485  * If collection streaming is enabled, call this method once all collections have been delivered
486  * using collectionsRetrieved() or collectionsRetrievedIncremental().
487  */
488  void collectionsRetrievalDone();
489 
490  /**
491  * Allows to keep locally changed collection parts during the collection sync.
492  *
493  * This is useful for resources to be able to provide default values during the collection
494  * sync, while preserving eventual more up-to date values.
495  *
496  * Valid values are attribute types and "CONTENTMIMETYPE" for the collections content mimetypes.
497  *
498  * By default this is enabled for the EntityDisplayAttribute.
499  *
500  * @param parts A set parts for which local changes should be preserved.
501  * @since 4.14
502  */
503  void setKeepLocalCollectionChanges(const QSet<QByteArray> &parts);
504 
505  /**
506  * Call this method to supply the full collection listing from the remote server. Items not present in the list
507  * will be dropped from the Akonadi database.
508  *
509  * If the remote server supports incremental listing, it's strongly
510  * recommended to use itemsRetrievedIncremental() instead.
511  * @param items A list of items.
512  * @see itemsRetrievedIncremental().
513  */
514  void itemsRetrieved(const Item::List &items);
515 
516  /**
517  * Call this method when you want to use the itemsRetrieved() method
518  * in streaming mode and indicate the amount of items that will arrive
519  * that way.
520  *
521  * @warning By default this will end the item sync automatically once
522  * sufficient items were delivered. To disable this and only make use
523  * of the progress reporting, use setDisableAutomaticItemDeliveryDone()
524  *
525  * @note The recommended way is therefore:
526  * @code
527  * setDisableAutomaticItemDeliveryDone(true);
528  * setItemStreamingEnabled(true);
529  * setTotalItems(X); // X = sum of all items in all batches
530  * while (...) {
531  * itemsRetrievedIncremental(...);
532  * // or itemsRetrieved(...);
533  * }
534  * itemsRetrievalDone();
535  * @endcode
536  *
537  * @param amount number of items that will arrive in streaming mode
538  * @see setDisableAutomaticItemDeliveryDone(bool)
539  * @see setItemStreamingEnabled(bool)
540  */
541  void setTotalItems(int amount);
542 
543  /**
544  * Disables the automatic completion of the item sync,
545  * based on the number of delivered items.
546  *
547  * This ensures that the item sync only finishes once itemsRetrieved()
548  * is called, while still making it possible to use the automatic progress
549  * reporting based on setTotalItems().
550  *
551  * @note This needs to be called once, before the item sync is started.
552  *
553  * @see setTotalItems(int)
554  * @since 4.14
555  */
556  void setDisableAutomaticItemDeliveryDone(bool disable);
557 
558  /**
559  * Enable item streaming, which is disabled by default.
560  * Item streaming means that the resource can call setTotalItems(),
561  * and then itemsRetrieved() or itemsRetrievedIncremental() multiple times,
562  * in chunks. When all is done, the resource should call itemsRetrievalDone().
563  * @param enable @c true if items are delivered in chunks rather in one big block.
564  * @see setTotalItems(int)
565  */
566  void setItemStreamingEnabled(bool enable);
567 
568  /**
569  * Set transaction mode for item sync'ing.
570  * @param mode item transaction mode
571  * @see Akonadi::ItemSync::TransactionMode
572  * @since 4.6
573  */
574  void setItemTransactionMode(ItemSync::TransactionMode mode);
575 
576  /**
577  * Set merge mode for item sync'ing.
578  *
579  * Default merge mode is RIDMerge.
580  *
581  * @note This method must be called before first call to itemRetrieved(),
582  * itemsRetrieved() or itemsRetrievedIncremental().
583  *
584  * @param mode Item merging mode (see ItemCreateJob for details on item merging)
585  * @see Akonadi::ItemSync::MergeMode
586  * @since 4.14.11
587  */
588  void setItemMergingMode(ItemSync::MergeMode mode);
589 
590  /**
591  * Call this method to supply incrementally retrieved items from the remote server.
592  *
593  * @param changedItems Items changed in the backend.
594  * @param removedItems Items removed from the backend.
595  */
596  void itemsRetrievedIncremental(const Item::List &changedItems, const Item::List &removedItems);
597 
598  /**
599  * Call this method to indicate you finished synchronizing the current collection.
600  *
601  * This is not needed if you use the built in syncing without item streaming
602  * and call itemsRetrieved() or itemsRetrievedIncremental() instead.
603  * If item streaming is enabled, call this method once all items have been delivered
604  * using itemsRetrieved() or itemsRetrievedIncremental().
605  * @see retrieveItems()
606  */
607  void itemsRetrievalDone();
608 
609  /**
610  * Call this method to remove all items and collections of the resource from the
611  * server cache.
612  *
613  * The method should not be used anymore
614  *
615  * @see invalidateCache()
616  * @since 4.3
617  */
618  void clearCache();
619 
620  /**
621  * Call this method to invalidate all cached content in @p collection.
622  *
623  * The method should be used when the backend indicated that the cached content
624  * is no longer valid.
625  *
626  * @param collection parent of the content to be invalidated in cache
627  * @since 4.8
628  */
629  void invalidateCache(const Collection &collection);
630 
631  /**
632  * Returns the collection that is currently synchronized.
633  * @note Calling this method is only allowed during a collection synchronization task, that
634  * is directly or indirectly from retrieveItems().
635  */
636  Collection currentCollection() const;
637 
638  /**
639  * Returns the item that is currently retrieved.
640  * @note Calling this method is only allowed during fetching a single item, that
641  * is directly or indirectly from retrieveItem().
642  */
643  AKONADIAGENTBASE_DEPRECATED Item currentItem() const;
644 
645  /**
646  * Returns the items that are currently retrieved.
647  * @note Calling this method is only allowed during item fetch, that is
648  * directly or indirectly from retrieveItems(Akonadi::Item::List,QSet<QByteArray>)
649  */
650  Item::List currentItems() const;
651 
652  /**
653  * This method is called whenever the resource should start synchronize all data.
654  */
655  void synchronize();
656 
657  /**
658  * This method is called whenever the collection with the given @p id
659  * shall be synchronized.
660  */
661  void synchronizeCollection(qint64 id);
662 
663  /**
664  * This method is called whenever the collection with the given @p id
665  * shall be synchronized.
666  * @param recursive if true, a recursive synchronization is done
667  */
668  void synchronizeCollection(qint64 id, bool recursive);
669 
670  /**
671  * This method is called whenever the collection with the given @p id
672  * shall have its attributes synchronized.
673  *
674  * @param id The id of the collection to synchronize
675  * @since 4.6
676  */
677  void synchronizeCollectionAttributes(qint64 id);
678 
679  /**
680  * Synchronizes the collection attributes.
681  *
682  * @param col The id of the collection to synchronize
683  * @since 4.15
684  */
685  void synchronizeCollectionAttributes(const Akonadi::Collection &col);
686 
687  /**
688  * Refetches the Collections.
689  */
690  void synchronizeCollectionTree();
691 
692  /**
693  * Refetches Tags.
694  */
695  void synchronizeTags();
696 
697  /**
698  * Refetches Relations.
699  */
700  void synchronizeRelations();
701 
702  /**
703  * Stops the execution of the current task and continues with the next one.
704  */
705  void cancelTask();
706 
707  /**
708  * Stops the execution of the current task and continues with the next one.
709  * Additionally an error message is emitted.
710  * @param error additional error message to be emitted
711  */
712  void cancelTask(const QString &error);
713 
714  /**
715  * Suspends the execution of the current task and tries again to execute it.
716  *
717  * This can be used to delay the task processing until the resource has reached a safe
718  * state, e.g. login to a server succeeded.
719  *
720  * @note This does not change the order of tasks so if there is no task with higher priority
721  * e.g. a custom task added with #Prepend the deferred task will be processed again.
722  *
723  * @since 4.3
724  */
725  void deferTask();
726 
727  /**
728  * Inherited from AgentBase.
729  *
730  * When going offline, the scheduler aborts the current task, so you should
731  * do the same in your resource, if the task implementation is asynchronous.
732  */
733  void doSetOnline(bool online) override;
734 
735  /**
736  * Indicate the use of hierarchical remote identifiers.
737  *
738  * This means that it is possible to have two different items with the same
739  * remoteId in different Collections.
740  *
741  * This should be called in the resource constructor as needed.
742  *
743  * @param enable whether to enable use of hierarchical remote identifiers
744  * @since 4.4
745  */
746  void setHierarchicalRemoteIdentifiersEnabled(bool enable);
747 
748  friend class ResourceScheduler;
749  friend class ::ResourceState;
750 
751  /**
752  * Describes the scheduling priority of a task that has been queued
753  * for execution.
754  *
755  * @see scheduleCustomTask
756  * @since 4.4
757  */
759  Prepend, ///< The task will be executed as soon as the current task has finished.
760  AfterChangeReplay, ///< The task is scheduled after the last ChangeReplay task in the queue
761  Append ///< The task will be executed after all tasks currently in the queue are finished
762  };
763 
764  /**
765  * Schedules a custom task in the internal scheduler. It will be queued with
766  * all other tasks such as change replays and retrieval requests and eventually
767  * executed by calling the specified method. With the priority parameter the
768  * time of execution of the Task can be influenced. @see SchedulePriority
769  * @param receiver The object the slot should be called on.
770  * @param method The name of the method (and only the name, not signature, not SLOT(...) macro),
771  * that should be called to execute this task. The method has to be a slot and take a QVariant as
772  * argument.
773  * @param argument A QVariant argument passed to the method specified above. Use this to pass task
774  * parameters.
775  * @param priority Priority of the task. Use this to influence the position in
776  * the execution queue.
777  * @since 4.4
778  */
779  void scheduleCustomTask(QObject *receiver, const char *method, const QVariant &argument, SchedulePriority priority = Append);
780 
781  /**
782  * Indicate that the current task is finished. Use this method from the slot called via scheduleCustomTaks().
783  * As with all the other callbacks, make sure to either call taskDone() or cancelTask()/deferTask() on all
784  * exit paths, otherwise the resource will hang.
785  * @since 4.4
786  */
787  void taskDone();
788 
789  /**
790  * Dump the contents of the current ChangeReplay
791  * @since 4.8.1
792  */
793  QString dumpNotificationListToString() const;
794 
795  /**
796  * Dumps memory usage information to stdout.
797  * For now it outputs the result of glibc's mallinfo().
798  * This is useful to check if your memory problems are due to poor management by glibc.
799  * Look for a high value on fsmblks when interpreting results.
800  * man mallinfo for more details.
801  * @since 4.11
802  */
803  void dumpMemoryInfo() const;
804 
805  /**
806  * Returns a string with memory usage information.
807  * @see dumpMemoryInfo()
808  *
809  * @since 4.11
810  */
811  QString dumpMemoryInfoToString() const;
812 
813  /**
814  * Dump the state of the scheduler
815  * @since 4.8.1
816  */
817  QString dumpSchedulerToString() const;
818 
819 private:
820  static QString parseArguments(int argc, char **argv);
821  static int init(ResourceBase &r);
822 
823  // dbus resource interface
824  friend class ::Akonadi__ResourceAdaptor;
825 
826  void requestItemDelivery(const QVector<qint64> &uids, const QByteArrayList &parts);
827 
828 private:
829  Q_DECLARE_PRIVATE(ResourceBase)
830 
831  Q_PRIVATE_SLOT(d_func(), void slotAbortRequested())
832  Q_PRIVATE_SLOT(d_func(), void slotDeliveryDone(KJob *))
833  Q_PRIVATE_SLOT(d_func(), void slotCollectionSyncDone(KJob *))
834  Q_PRIVATE_SLOT(d_func(), void slotDeleteResourceCollection())
835  Q_PRIVATE_SLOT(d_func(), void slotDeleteResourceCollectionDone(KJob *))
836  Q_PRIVATE_SLOT(d_func(), void slotCollectionDeletionDone(KJob *))
837  Q_PRIVATE_SLOT(d_func(), void slotInvalidateCache(const Akonadi::Collection &))
838  Q_PRIVATE_SLOT(d_func(), void slotLocalListDone(KJob *))
839  Q_PRIVATE_SLOT(d_func(), void slotSynchronizeCollection(const Akonadi::Collection &))
840  Q_PRIVATE_SLOT(d_func(), void slotCollectionListDone(KJob *))
841  Q_PRIVATE_SLOT(d_func(), void slotSynchronizeCollectionAttributes(const Akonadi::Collection &))
842  Q_PRIVATE_SLOT(d_func(), void slotCollectionListForAttributesDone(KJob *))
843  Q_PRIVATE_SLOT(d_func(), void slotCollectionAttributesSyncDone(KJob *))
844  Q_PRIVATE_SLOT(d_func(), void slotItemSyncDone(KJob *))
845  Q_PRIVATE_SLOT(d_func(), void slotPercent(KJob *, quint64))
846  Q_PRIVATE_SLOT(d_func(), void slotDelayedEmitProgress())
847  Q_PRIVATE_SLOT(d_func(), void slotPrepareItemRetrieval(const Akonadi::Item &items))
848  Q_PRIVATE_SLOT(d_func(), void slotPrepareItemRetrievalResult(KJob *))
849  Q_PRIVATE_SLOT(d_func(), void slotPrepareItemsRetrieval(const QVector<Akonadi::Item> &items))
850  Q_PRIVATE_SLOT(d_func(), void slotPrepareItemsRetrievalResult(KJob *))
851  Q_PRIVATE_SLOT(d_func(), void changeCommittedResult(KJob *))
852  Q_PRIVATE_SLOT(d_func(), void slotSessionReconnected())
853  Q_PRIVATE_SLOT(d_func(), void slotRecursiveMoveReplay(RecursiveMover *))
854  Q_PRIVATE_SLOT(d_func(), void slotRecursiveMoveReplayResult(KJob *))
855  Q_PRIVATE_SLOT(d_func(), void slotTagSyncDone(KJob *))
856  Q_PRIVATE_SLOT(d_func(), void slotRelationSyncDone(KJob *job))
857  Q_PRIVATE_SLOT(d_func(), void slotSynchronizeTags())
858  Q_PRIVATE_SLOT(d_func(), void slotSynchronizeRelations())
859  Q_PRIVATE_SLOT(d_func(), void slotItemRetrievalCollectionFetchDone(KJob *))
860  Q_PRIVATE_SLOT(d_func(), void slotAttributeRetrievalCollectionFetchDone(KJob *))
861 };
862 
863 }
864 
865 #ifndef AKONADI_RESOURCE_MAIN
866 /**
867  * Convenience Macro for the most common main() function for Akonadi resources.
868  */
869 #define AKONADI_RESOURCE_MAIN(resourceClass) \
870  int main(int argc, char **argv) \
871  { \
872  return Akonadi::ResourceBase::init<resourceClass>(argc, argv); \
873  }
874 #endif
@ Prepend
The task will be executed as soon as the current task has finished.
Definition: resourcebase.h:759
An Akonadi Tag.
Definition: tag.h:25
QCA_EXPORT void init()
Represents a collection of PIM items.
Definition: collection.h:61
The interface for reacting on monitored or replayed changes.
Definition: agentbase.h:178
TransactionMode
Transaction mode used by ItemSync.
Definition: itemsync.h:125
SchedulePriority
Describes the scheduling priority of a task that has been queued for execution.
Definition: resourcebase.h:758
virtual QString dumpResourceToString() const
Dump resource internals, for debugging.
Definition: resourcebase.h:376
The base class for all Akonadi agents and resources.
Definition: agentbase.h:72
The base class for all Akonadi resources.
Definition: resourcebase.h:134
@ AfterChangeReplay
The task is scheduled after the last ChangeReplay task in the queue.
Definition: resourcebase.h:760
static int init(int argc, char **argv)
Use this method in the main function of your resource application to initialize your resource subclas...
Definition: resourcebase.h:167
Represents a PIM item stored in Akonadi storage.
Definition: item.h:105
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 03:58:07 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.