app/core/CalendarSyncApply.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QList> | ||
| 4 | #include <QString> | ||
| 5 | #include <QStringList> | ||
| 6 | |||
| 7 | #include "data/CalendarModels.h" | ||
| 8 | |||
| 9 | class CalendarStore; | ||
| 10 | struct DavCollectionChanges; | ||
| 11 | |||
| 12 | // Sprint 96 S96.3.0 (CAL-SYNC-TRUNCATION) / S96.3.2: applies DAV read | ||
| 13 | // results to the CalendarStore with one contract for every trigger (poll, | ||
| 14 | // push, manual): each result is ONE transaction that holds its rows, its | ||
| 15 | // removals, its token/checkpoint and — after the last page — the CTag. A | ||
| 16 | // failed write rolls everything back and advances nothing. | ||
| 17 | // | ||
| 18 | // Invariants: | ||
| 19 | // - A token-less sync-collection is an enumeration. Its pages only upsert; | ||
| 20 | // stale rows are pruned after the last page (seen UIDs persist across | ||
| 21 | // restarts, see CalendarStore::enumerationState()). | ||
| 22 | // - A truncated page (507) is a checkpoint, never "collection complete". | ||
| 23 | // - A page with failed members (error status / no calendar-data) is | ||
| 24 | // applied but advances no token: those members are neither deleted nor | ||
| 25 | // counted as synced. | ||
| 26 | // - Resources with a queued local change (outbox) are never overwritten or | ||
| 27 | // pruned. | ||
| 28 | class CalendarSyncApply { | ||
| 29 | public: | ||
| 30 | 948 | explicit CalendarSyncApply(CalendarStore *store) : m_store(store) {} | |
| 31 | |||
| 32 | // The token the next sync-collection of a collection starts from: the | ||
| 33 | // checkpoint of an unfinished enumeration, else the committed token. | ||
| 34 | QString nextRequestToken(const QString &accountId, const QString &path) const; | ||
| 35 | |||
| 36 | enum class PageResult { Committed, Continue, Failed }; | ||
| 37 | struct PageOutcome { | ||
| 38 | PageResult result = PageResult::Failed; | ||
| 39 | QString continueToken; // Continue: request the next page with it | ||
| 40 | QString error; // Failed: technical reason (log/details) | ||
| 41 | bool localFailure = false; // Failed in this computer's store, not on the server | ||
| 42 | int appliedResources = 0; // resources written or removed | ||
| 43 | }; | ||
| 44 | // `ctag` is committed with the last page ("" = keep the stored one). | ||
| 45 | PageOutcome applySyncPage(const QString &accountId, const QString &path, | ||
| 46 | const DavCollectionChanges &changes, const QString &ctag); | ||
| 47 | |||
| 48 | // calendar-query fallback: one component kind of a collection. Prunes | ||
| 49 | // that kind only when the result is complete. | ||
| 50 | bool applyQueryEvents(const QString &accountId, const QString &path, | ||
| 51 | const QList<CalendarEvent> &events, bool complete); | ||
| 52 | bool applyQueryTasks(const QString &accountId, const QString &path, | ||
| 53 | const QList<CalendarTask> &tasks, bool complete); | ||
| 54 | |||
| 55 | // The server rejected the token (RFC 6578 valid-sync-token): forget the | ||
| 56 | // committed token and any enumeration; the next request is token-less. | ||
| 57 | bool resetCollectionToken(const QString &accountId, const QString &path); | ||
| 58 | |||
| 59 | private: | ||
| 60 | bool writeEvents(const QString &accountId, const QString &path, | ||
| 61 | const QList<CalendarEvent> &events, const QStringList &queued, int *applied); | ||
| 62 | bool writeTasks(const QString &accountId, const QString &path, | ||
| 63 | const QList<CalendarTask> &tasks, const QStringList &queued, int *applied); | ||
| 64 | bool writePage(const QString &accountId, const QString &path, const DavCollectionChanges &changes, | ||
| 65 | bool enumeration, const QString &ctag, PageOutcome *outcome); | ||
| 66 | |||
| 67 | CalendarStore *m_store = nullptr; | ||
| 68 | }; | ||
| 69 |