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

KDE's Doxygen guidelines are available online.