## KolabMailSynchronizer KolabMailSynchronizer — PIM data (and metadata) synchronization, conflict resolution |

## Stability Level

Unstable, unless otherwise indicated

## Synopsis

    struct              KolabMailSynchronizerClass;
    enum                KolabMailSynchronizerTransactionTypeID;
    gboolean            kolab_mail_synchronizer_bringup     (KolabMailSynchronizer *self,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_configure   (KolabMailSynchronizer *self,
                                                             KolabSettingsHandler *ksettings,
                                                             KolabMailImapClient *client,
                                                             KolabMailInfoDb *infodb,
                                                             KolabMailSideCache *sidecache,
                                                             KolabMailMimeBuilder *mimebuilder,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_full_sync   (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             const gchar *foldername,
                                                             GCancellable *cancellable,
                                                             GError **err);
    KolabMailHandle *   kolab_mail_synchronizer_handle_new_from_infodb
                                                            (KolabMailSynchronizer *self,
                                                             const gchar *uid,
                                                             const gchar *foldername,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_info_sync   (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             const gchar *foldername,
                                                             GCancellable *cancellable,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_shutdown    (KolabMailSynchronizer *self,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_transaction_abort
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             KolabMailInfoDbRecord *record,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_transaction_commit
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             KolabMailInfoDbRecord *record,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_transaction_prepare
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             GHashTable *imap_summaries,
                                                             KolabMailInfoDbRecord **record,
                                                             GCancellable *cancellable,
                                                             GError **err);
    gboolean            kolab_mail_synchronizer_transaction_start
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             KolabMailInfoDbRecord *record,
                                                             GError **err);

## Description

This class implements the infrastructure to sync KolabMailSideCache and KolabMailImapClient with KolabMailInfoDb.

Presently, the KolabMailImapClient used within KolabMailAccess maintains a read-only email cache (this is a limitation of the IMAP implementation used), so any (new) Kolab PIM object which cannot be stored directly via KolabMailImapClient because of offline state (requested by the user or lost server connection) gets stored in KolabMailSideCache for later sync. The same holds true for IMAP folders.

Synchronization actions for KolabMailAccess offline->online transition

Initial action

- get all foldernames on server
- foreach folder, get CamelFolderInfo

         -----------------------+------------------------------------------------
         Folders present in     | Action
         SideCache | ImapClient |
         -----------------------+------------------------------------------------
         -----------------------+------------------------------------------------
         X         | X          | none
         -----------------------+------------------------------------------------
         X         |            | Folder has been deleted on server while
                   |            | Client was offline.
                   |            |
                   |            | SideCache: push unsynced UIDs to server,
                   |            | delete pushed UIDs, delete now-empty folders
                   |            |
                   |            | ImapClient: re-get CamelFolderInfo?
                   |            | re-fetch pushed UIDs (and data) so IMAPX
                   |            | offline cache will be updated?
                   |            |
                   |            | InfoDb: delete UIDs which resided on
                   |            | server only. Unset SideCache location bits
                   |            | for successfully pushed UIDs. Set ImapClient
                   |            | cache location bit if UID data was re-fetched
         -----------------------+------------------------------------------------
                   | X          | Folder has been created on server while
                   |            | Client was offline.
                   |            |
                   |            | SideCache: none
                   |            |
                   |            | ImapClient: none
                   |            |
                   |            | InfoDb: insert new UIDs (no data yet,
                   |            | no cache location bit yet)
         -----------------------+------------------------------------------------
                   |            |
                   |            | TODO what would be the meaning of this?
                   |            |      If CamelFolderInfo has the folder,
                   |            |      we regard it "in the IMAPX cache"
                   |            |
         -----------------------+------------------------------------------------

         -----------------------+------------------------------------------------
         UIDs present in        | Action
         SideCache | ImapClient |
         -----------------------+------------------------------------------------
         -----------------------+------------------------------------------------
         X         | X          | Check whether IMAP UID changed.
                   |            | If so, we have true sync conflict.
                   |            | Resolve according to user pref (use server/
                   |            | use local / use newest / create dupe)
                   |            |
                   |            | SideCache: after sync success, delete UID
                   |            |
                   |            | ImapClient: if server side UID was
                   |            | overwritten, delete UID data on server,
                   |            | push new UID data (new email). Re-fetch
                   |            | data to get it into IMAPX cache
                   |            |
                   |            | InfoDb: unset SideCache location bit
         -----------------------+------------------------------------------------
         X         |            | PIM object was created in offline mode
                   |            |
                   |            | SideCache: after sync success, delete UID
                   |            |
                   |            | ImapClient: Re-fetch data to get it
                   |            | into IMAPX cache
                   |            |
                   |            | InfoDb: unset SideCache location bit
         -----------------------+------------------------------------------------
                   |            | New PIM object was created on the server
                   |            | and has not yet been fetched into IMAPX
                   |            | offline store
                   |            |
                   |            | SideCache: none
                   |            |
                   |            | ImapClient: Fetch data to get it
                   |            | into IMAPX cache
                   |            |
                   |            | InfoDb: set ImapClient cache location bit
         -----------------------+------------------------------------------------

## Details

### struct KolabMailSynchronizerClass

    struct KolabMailSynchronizerClass {
    	GObjectClass parent_class;
    };

### enum KolabMailSynchronizerTransactionTypeID

    typedef enum {
    	KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_INVAL = 0,
    	KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
    	KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_PUSH,
    	KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
    	KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_LAST_TYPE
    } KolabMailSynchronizerTransactionTypeID;

### kolab_mail_synchronizer_bringup ()

    gboolean            kolab_mail_synchronizer_bringup     (KolabMailSynchronizer *self,
                                                             GError **err);

### kolab_mail_synchronizer_configure ()

    gboolean            kolab_mail_synchronizer_configure   (KolabMailSynchronizer *self,
                                                             KolabSettingsHandler *ksettings,
                                                             KolabMailImapClient *client,
                                                             KolabMailInfoDb *infodb,
                                                             KolabMailSideCache *sidecache,
                                                             KolabMailMimeBuilder *mimebuilder,
                                                             GError **err);

### kolab_mail_synchronizer_full_sync ()

    gboolean            kolab_mail_synchronizer_full_sync   (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             const gchar *foldername,
                                                             GCancellable *cancellable,
                                                             GError **err);

### kolab_mail_synchronizer_handle_new_from_infodb ()

    KolabMailHandle *   kolab_mail_synchronizer_handle_new_from_infodb
                                                            (KolabMailSynchronizer *self,
                                                             const gchar *uid,
                                                             const gchar *foldername,
                                                             GError **err);

### kolab_mail_synchronizer_info_sync ()

    gboolean            kolab_mail_synchronizer_info_sync   (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             const gchar *foldername,
                                                             GCancellable *cancellable,
                                                             GError **err);

### kolab_mail_synchronizer_shutdown ()

    gboolean            kolab_mail_synchronizer_shutdown    (KolabMailSynchronizer *self,
                                                             GError **err);

### kolab_mail_synchronizer_transaction_abort ()

    gboolean            kolab_mail_synchronizer_transaction_abort
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             KolabMailInfoDbRecord *record,
                                                             GError **err);

### kolab_mail_synchronizer_transaction_commit ()

    gboolean            kolab_mail_synchronizer_transaction_commit
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             KolabMailInfoDbRecord *record,
                                                             GError **err);

### kolab_mail_synchronizer_transaction_prepare ()

    gboolean            kolab_mail_synchronizer_transaction_prepare
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             GHashTable *imap_summaries,
                                                             KolabMailInfoDbRecord **record,
                                                             GCancellable *cancellable,
                                                             GError **err);

### kolab_mail_synchronizer_transaction_start ()

    gboolean            kolab_mail_synchronizer_transaction_start
                                                            (KolabMailSynchronizer *self,
                                                             KolabMailAccessOpmodeID opmode,
                                                             KolabMailSynchronizerTransactionTypeID ttid,
                                                             KolabMailHandle *kmailhandle,
                                                             const gchar *foldername,
                                                             KolabMailInfoDbRecord *record,
                                                             GError **err);

## See Also

KolabMailAccess, KolabMailInfoDb, KolabMailImapClient, KolabFolderSummary, KolabMailSummary