[evolution-kolab/ek-wip-porting] KolabMailAccess: separated out syncing from connecting, new API



commit 29a8702623191ee87f70d06e8e0c27bf8273c3fc
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Fri Jul 13 14:09:17 2012 +0200

    KolabMailAccess: separated out syncing from connecting, new API
    
    * moved sync point code to separate function, exposed via API
    * can connect to server (go online) without immediate sync now
    * sync function needs to be called separately now (not yet sure
      exactly where to call it, as long as we do not yet have a
      dedicated backend synchronize() function which gets triggered
      by some EClient action)

 src/libekolab/kolab-mail-access.c |  268 ++++++++++++++++++++++++-------------
 src/libekolab/kolab-mail-access.h |    7 +
 2 files changed, 179 insertions(+), 96 deletions(-)
---
diff --git a/src/libekolab/kolab-mail-access.c b/src/libekolab/kolab-mail-access.c
index 9c0f985..057d221 100644
--- a/src/libekolab/kolab-mail-access.c
+++ b/src/libekolab/kolab-mail-access.c
@@ -952,6 +952,90 @@ mail_access_local_delete (KolabMailAccess *self,
 	return TRUE;
 }
 
+static gboolean
+mail_access_sync_with_server (KolabMailAccess *self,
+                              KolabMailAccessOpmodeID opmode,
+                              const gchar *foldername,
+                              gboolean full_sync,
+                              GCancellable *cancellable,
+                              GError **err)
+{
+	KolabMailAccessPrivate *priv = NULL;
+	GList *folders_lst = NULL;
+	GList *folders_lst_ptr = NULL;
+	gboolean ok = TRUE;
+	GError *tmp_err = NULL;
+
+	g_assert (KOLAB_IS_MAIL_ACCESS (self));
+	/* foldername may be NULL */
+	/* cancellable may be NULL */
+	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
+
+	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
+
+	/* sync folder / object info */
+	ok = kolab_mail_synchronizer_info_sync (priv->synchronizer,
+	                                        opmode,
+	                                        foldername, /* NULL means all folders */
+	                                        cancellable,
+	                                        &tmp_err);
+	if (! ok) {
+		g_propagate_error (err, tmp_err);
+		return FALSE;
+	}
+
+	/* if we're updating folder info only, we're done */
+	if (! full_sync)
+		return TRUE;
+
+	/* push all objects from SideCache to server,
+	 * execute deferred offline deletion operations
+	 */
+	ok = kolab_mail_synchronizer_full_sync (priv->synchronizer,
+	                                        opmode,
+	                                        foldername, /* NULL means all folders */
+	                                        cancellable,
+	                                        &tmp_err);
+	if (! ok) {
+		g_warning ("%s: %s", __func__, tmp_err->message);
+		g_error_free (tmp_err);
+		tmp_err = NULL;
+	}
+
+	/* update hash table of KolabMailHandles */
+	if (foldername == NULL) {
+		/* all folders */
+		folders_lst = kolab_mail_info_db_query_foldernames (priv->infodb,
+		                                                    &tmp_err);
+		if (tmp_err != NULL) {
+			g_propagate_error (err, tmp_err);
+			return FALSE;
+		}
+	} else {
+		/* single folder only */
+		folders_lst = g_list_prepend (folders_lst,
+		                              (gpointer) g_strdup (foldername));
+	}
+	folders_lst_ptr = folders_lst;
+	while (folders_lst_ptr != NULL) {
+		gchar *foldername = (gchar *)(folders_lst_ptr->data);
+		ok = mail_access_update_handles_from_infodb (self,
+		                                             foldername,
+		                                             NULL, /* sexp */
+		                                             &tmp_err);
+		if (! ok)
+			break;
+		folders_lst_ptr = g_list_next (folders_lst_ptr);
+	}
+	kolab_util_glib_glist_free (folders_lst);
+	if (! ok) {
+		g_propagate_error (err, tmp_err);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 /*----------------------------------------------------------------------------*/
 /* object state transition table and functions */
 
@@ -1098,8 +1182,6 @@ mail_access_strans_offline_online (KolabMailAccess *self,
                                    GError **err)
 {
 	KolabMailAccessPrivate *priv = NULL;
-	GList *folders_lst = NULL;
-	GList *folders_lst_ptr = NULL;
 	gboolean ok = FALSE;
 	GError *tmp_err = NULL;
 
@@ -1131,54 +1213,13 @@ mail_access_strans_offline_online (KolabMailAccess *self,
 		return FALSE;
 	}
 
-	/* sync pim metadata */
-	ok = kolab_mail_synchronizer_info_sync (priv->synchronizer,
-	                                        KOLAB_MAIL_ACCESS_OPMODE_ONLINE,
-	                                        NULL,
-	                                        cancellable,
-	                                        &tmp_err);
-	if (! ok) {
-		g_propagate_error (err, tmp_err);
-		return FALSE;
-	}
-
-	/* push all objects from SideCache to server,
-	 * execute deferred offline deletion operations
+	/* Up to 3.4, we've been synchronizing folder metadata and
+	 * PIM payload data with the Kolab server here. This is now
+	 * being done in a separate synchronization function, which
+	 * can be called upon per user request or at any place internally
+	 * where it seems fit (e.g. when switching views - but beware,
+	 * that operation can become quite bulky and time consuming)
 	 */
-	ok = kolab_mail_synchronizer_full_sync (priv->synchronizer,
-	                                        KOLAB_MAIL_ACCESS_OPMODE_ONLINE,
-	                                        NULL,
-	                                        cancellable,
-	                                        &tmp_err);
-	if (! ok) {
-		g_warning ("%s: %s", __func__, tmp_err->message);
-		g_error_free (tmp_err);
-		tmp_err = NULL;
-	}
-
-	/* update hash table of KolabMailHandles */
-	folders_lst = kolab_mail_info_db_query_foldernames (priv->infodb,
-	                                                    &tmp_err);
-	if (tmp_err != NULL) {
-		g_propagate_error (err, tmp_err);
-		return FALSE;
-	}
-	folders_lst_ptr = folders_lst;
-	while (folders_lst_ptr != NULL) {
-		gchar *foldername = (gchar *)(folders_lst_ptr->data);
-		ok = mail_access_update_handles_from_infodb (self,
-		                                             foldername,
-		                                             NULL, /* sexp */
-		                                             &tmp_err);
-		if (! ok)
-			break;
-		folders_lst_ptr = g_list_next (folders_lst_ptr);
-	}
-	kolab_util_glib_glist_free (folders_lst);
-	if (! ok) {
-		g_propagate_error (err, tmp_err);
-		return FALSE;
-	}
 
 	g_debug ("KolabMailAccess: new state: online");
 	priv->state->opmode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE;
@@ -1223,8 +1264,6 @@ mail_access_strans_online_offline (KolabMailAccess *self,
                                    GError **err)
 {
 	KolabMailAccessPrivate *priv = NULL;
-	GList *folders_lst = NULL;
-	GList *folders_lst_ptr = NULL;
 	gboolean ok = FALSE;
 	GError *tmp_err = NULL;
 
@@ -1262,25 +1301,13 @@ mail_access_strans_online_offline (KolabMailAccess *self,
 	 *      Todo:   When to drop objects from SideCache which we
 	 *	        permanently fail to push onto the server?
 	 */
-	ok = kolab_mail_synchronizer_info_sync (priv->synchronizer,
-	                                        KOLAB_MAIL_ACCESS_OPMODE_ONLINE,
-	                                        NULL,
-	                                        cancellable,
-	                                        &tmp_err);
-	if (! ok) {
-		g_propagate_error (err, tmp_err);
-		return FALSE;
-	}
-	/* push all objects from SideCache to server (though SideCache should
-	 * be empty by now, it could contain objects for which the online
-	 * operation failed before so we try again here to get them pushed
-	 * onto the server)
-	 */
-	ok = kolab_mail_synchronizer_full_sync (priv->synchronizer,
-	                                        KOLAB_MAIL_ACCESS_OPMODE_ONLINE,
-	                                        NULL,
-	                                        cancellable,
-	                                        &tmp_err);
+
+	ok = mail_access_sync_with_server (self,
+	                                   KOLAB_MAIL_ACCESS_OPMODE_ONLINE,
+	                                   NULL, /* all folders */
+	                                   TRUE, /* full sync */
+	                                   cancellable,
+	                                   &tmp_err);
 	if (! ok) {
 		g_propagate_error (err, tmp_err);
 		return FALSE;
@@ -1295,33 +1322,7 @@ mail_access_strans_online_offline (KolabMailAccess *self,
 		return FALSE;
 	}
 
-	folders_lst = kolab_mail_info_db_query_foldernames (priv->infodb,
-	                                                    &tmp_err);
-	if (tmp_err != NULL) {
-		g_propagate_error (err, tmp_err);
-		return FALSE;
-	}
-
-	/* update hash table of KolabMailHandles */
-	folders_lst_ptr = folders_lst;
-	while (folders_lst_ptr != NULL) {
-		gchar *foldername = (gchar *)(folders_lst_ptr->data);
-		ok = mail_access_update_handles_from_infodb (self,
-		                                             foldername,
-		                                             NULL, /* sexp */
-		                                             &tmp_err);
-		if (! ok)
-			break;
-		folders_lst_ptr = g_list_next (folders_lst_ptr);
-	}
-	kolab_util_glib_glist_free (folders_lst);
-	if (! ok) {
-		g_propagate_error (err, tmp_err);
-		return FALSE;
-	}
-
 	g_debug ("KolabMailAccess: new state: offline");
-
 	priv->state->opmode = KOLAB_MAIL_ACCESS_OPMODE_OFFLINE;
 	return TRUE;
 }
@@ -3121,4 +3122,79 @@ kolab_mail_access_source_fbtrigger_needed (KolabMailAccess *self,
 	return trigger_needed;
 }
 
+/**
+ * kolab_mail_access_synchronize:
+ * @self: a #KolabMailAccess instance
+ * @sourcename: the name of the source to sync (NULL for all)
+ * @full_sync: if FALSE, only folder/object metadata is synced
+ *             (set to TRUE do to a full payload sync, too)
+ * @cancellable: A cancellation stack
+ * @err: a #GError object (or NULL)
+ *
+ * Synchronize folder metadata and the local PIM object caches
+ * with the Kolab server. If a @sourcename is given, only the
+ * associated folder will be synchronized (pass in NULL to sync
+ * all folders). If @full_sync is set to FALSE, only the folder
+ * metadata and PIM object information is downsynced and available
+ * for query. If set to TRUE, new payload PIM data is also
+ * downsynced from the server and local PIM objects are spooled
+ * up to the server. This can cause synchronization conflicts.
+ * In case of networking failures, PIM objects which could not
+ * be spooled up to the server remain in the local cache for later
+ * syncing.
+ *
+ * Returns: TRUE on success, FALSE otherwise
+ *
+ * Since: 3.6
+ */
+gboolean
+kolab_mail_access_synchronize (KolabMailAccess *self,
+                               const gchar *sourcename,
+                               gboolean full_sync,
+                               GCancellable *cancellable,
+                               GError **err)
+{
+	KolabMailAccessPrivate *priv = NULL;
+	gchar *foldername = NULL;
+	gboolean ok = TRUE;
+	GError *tmp_err = NULL;
+
+	g_assert (KOLAB_IS_MAIL_ACCESS (self));
+	/* sourcename may be NULL  */
+	/* cancellable may be NULL */
+	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
+
+	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
+
+	g_mutex_lock (&(priv->big_lock));
+
+	if (priv->state->opmode < KOLAB_MAIL_ACCESS_OPMODE_ONLINE)
+		goto exit;
+
+	/* foldername will be NULL if sourcename is NULL */
+	foldername = mail_access_foldername_new_from_sourcename (self,
+	                                                         sourcename,
+	                                                         &tmp_err);
+	if (tmp_err != NULL) {
+		ok = FALSE;
+		goto exit;
+	}
+
+	ok = mail_access_sync_with_server (self,
+	                                   KOLAB_MAIL_ACCESS_OPMODE_ONLINE,
+	                                   foldername, /* NULL means all folders */
+	                                   full_sync,
+	                                   cancellable,
+	                                   &tmp_err);
+ exit:
+	if (foldername != NULL)
+		g_free (foldername);
+	if (tmp_err != NULL)
+		g_propagate_error (err, tmp_err);
+
+	g_mutex_unlock (&(priv->big_lock));
+
+	return ok;
+}
+
 /*----------------------------------------------------------------------------*/
diff --git a/src/libekolab/kolab-mail-access.h b/src/libekolab/kolab-mail-access.h
index 21a6906..b984050 100644
--- a/src/libekolab/kolab-mail-access.h
+++ b/src/libekolab/kolab-mail-access.h
@@ -232,6 +232,13 @@ kolab_mail_access_delete_by_uid (KolabMailAccess *self,
                                  GCancellable *cancellable,
                                  GError **err);
 
+gboolean
+kolab_mail_access_synchronize (KolabMailAccess *self,
+                               const gchar *sourcename,
+                               gboolean full_sync,
+                               GCancellable *cancellable,
+                               GError **err);
+
 G_END_DECLS
 
 /*----------------------------------------------------------------------------*/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]