[evolution-kolab/ek-wip-porting: 7/8] KolabMailAccess: relax folder type checking, adapt to synchronizer API changes



commit 7c671c2209cbd6a7122a55f6529d6b1b801f24b1
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Fri Aug 31 17:47:53 2012 +0200

    KolabMailAccess: relax folder type checking, adapt to synchronizer API changes
    
    * when creating sources, we need to pass in folder type
      information to make the folder creation operation
      agnostic to the currently-configured folder context
      and creation type
    * when creating folders, we need to by-pass the existence
      checks, since the new folder will not yet be listed in
      the KolabMailInfoDb (work in progress)

 src/libekolab/kolab-mail-access.c |  155 ++++++++++++++++++++++++++-----------
 src/libekolab/kolab-mail-access.h |    1 +
 2 files changed, 109 insertions(+), 47 deletions(-)
---
diff --git a/src/libekolab/kolab-mail-access.c b/src/libekolab/kolab-mail-access.c
index fa86a74..973f4a4 100644
--- a/src/libekolab/kolab-mail-access.c
+++ b/src/libekolab/kolab-mail-access.c
@@ -203,6 +203,7 @@ kolab_mail_access_class_init (KolabMailAccessClass *klass)
 static gchar*
 mail_access_foldername_new_from_sourcename (KolabMailAccess *self,
                                             const gchar *sourcename,
+                                            gboolean check_exists,
                                             GError **err)
 {
 	KolabMailAccessPrivate *priv = NULL;
@@ -218,6 +219,9 @@ mail_access_foldername_new_from_sourcename (KolabMailAccess *self,
 	if (sourcename == NULL)
 		return NULL;
 
+	if (! check_exists)
+		goto done;
+	
 	/* foldername may exist in KolabMailSideCache only */
 	exists = kolab_mail_info_db_exists_foldername (priv->infodb,
 	                                               sourcename,
@@ -236,6 +240,8 @@ mail_access_foldername_new_from_sourcename (KolabMailAccess *self,
 		return NULL;
 	}
 
+ done:
+	
 	return g_strdup (sourcename);
 }
 
@@ -485,6 +491,7 @@ static gboolean
 mail_access_local_store (KolabMailAccess *self,
                          KolabMailHandle *kmailhandle,
                          const gchar *foldername,
+                         KolabFolderTypeID foldertype,
                          GCancellable *cancellable,
                          GError **err)
 {
@@ -511,11 +518,8 @@ mail_access_local_store (KolabMailAccess *self,
 	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
 
 	/* check whether we should create a new folder instead of storing a handle */
-	if (kmailhandle == NULL) {
-		g_warning ("%s: creating new folders not yet implemented",
-		           __func__);
-		g_assert_not_reached ();
-	}
+	if (kmailhandle == NULL)
+		goto handle_skip;
 
 	/* get (and replace) local handle */
 	local_handle = mail_access_local_handle_get (self,
@@ -563,11 +567,15 @@ mail_access_local_store (KolabMailAccess *self,
 		g_propagate_error (err, tmp_err);
 		return FALSE;
 	}
+
+ handle_skip:
+	
 	do_store = kolab_mail_synchronizer_transaction_prepare (priv->synchronizer,
 	                                                        priv->state->opmode,
 	                                                        KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
 	                                                        local_handle,
 	                                                        foldername,
+	                                                        foldertype,
 	                                                        imap_summaries,
 	                                                        &record,
 	                                                        cancellable,
@@ -587,6 +595,7 @@ mail_access_local_store (KolabMailAccess *self,
 	                                                KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
 	                                                local_handle,
 	                                                foldername,
+	                                                foldertype,
 	                                                record,
 	                                                &tmp_err);
 	if (! ok) {
@@ -595,6 +604,9 @@ mail_access_local_store (KolabMailAccess *self,
 		return FALSE;
 	}
 
+	if (kmailhandle == NULL)
+		goto offline_skip;
+
 	/* offline store operation (also done in online mode, serves as a
 	 * data loss failsafe guard in case online operation fails. If online
 	 * operation completes successfully, this item is removed from side
@@ -618,19 +630,35 @@ mail_access_local_store (KolabMailAccess *self,
 		}
 	}
 
+ offline_skip:
+	
 	/* online store operation */
 	if (do_store && (! offline_fail) && (priv->state->opmode == KOLAB_MAIL_ACCESS_OPMODE_ONLINE)) {
-		ok = kolab_mail_imap_client_store (priv->client,
-		                                   local_handle,
-		                                   foldername,
-		                                   FALSE, /* folder already updated */
-		                                   cancellable,
-		                                   &tmp_err);
-		if (ok) {
-			sync_opmode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE;
-			kolab_mail_handle_set_cache_location (local_handle,
-			                                      KOLAB_OBJECT_CACHE_LOCATION_IMAP);
+
+		if (kmailhandle != NULL) {
+			/* store PIM object */
+			ok = kolab_mail_imap_client_store (priv->client,
+			                                   local_handle,
+			                                   foldername,
+			                                   FALSE, /* folder already updated */
+			                                   cancellable,
+			                                   &tmp_err);
+			if (ok) {
+				sync_opmode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE;
+				kolab_mail_handle_set_cache_location (local_handle,
+				                                      KOLAB_OBJECT_CACHE_LOCATION_IMAP);
+			}
 		} else {
+			/* create folder (online operation required) */
+			ok = kolab_mail_imap_client_create_folder (priv->client,
+			                                           foldername,
+			                                           foldertype,
+			                                           cancellable,
+			                                           &tmp_err);
+			/* TODO check whether we need to update DBs and friends */
+		}
+		
+		if (tmp_err != NULL) {
 			g_warning ("%s online mode failure: %s",
 			           __func__, tmp_err->message);
 			g_error_free (tmp_err);
@@ -641,11 +669,13 @@ mail_access_local_store (KolabMailAccess *self,
 
 	/* set handle incomplete */
 	/* TODO check whether this is the right place */
-	summary = kolab_mail_handle_get_summary_nonconst (local_handle);
-	g_assert (summary != NULL);
-	kolab_mail_summary_set_bool_field (summary,
-	                                   KOLAB_MAIL_SUMMARY_BOOL_FIELD_COMPLETE,
-	                                   FALSE);
+	if (kmailhandle != NULL) {
+		summary = kolab_mail_handle_get_summary_nonconst (local_handle);
+		g_assert (summary != NULL);
+		kolab_mail_summary_set_bool_field (summary,
+		                                   KOLAB_MAIL_SUMMARY_BOOL_FIELD_COMPLETE,
+		                                   FALSE);
+	}
 
 	/* transaction finalization */
 	if (offline_fail || online_fail) {
@@ -654,6 +684,7 @@ mail_access_local_store (KolabMailAccess *self,
 		                                                KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
 		                                                local_handle,
 		                                                foldername,
+		                                                foldertype,
 		                                                record,
 		                                                &tmp_err);
 	} else {
@@ -662,6 +693,7 @@ mail_access_local_store (KolabMailAccess *self,
 		                                                 KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_STORE,
 		                                                 local_handle,
 		                                                 foldername,
+		                                                 foldertype,
 		                                                 record,
 		                                                 &tmp_err);
 	}
@@ -738,40 +770,51 @@ mail_access_local_delete (KolabMailAccess *self,
 				g_free (foldername_del);
 			return FALSE;
 		}
+		/* TODO can we switch from full summaries table to simple UID list here ? */
+		imap_summaries = kolab_mail_imap_client_query_summaries (priv->client,
+		                                                         foldername,
+		                                                         NULL,
+		                                                         TRUE, /* update folder */
+		                                                         cancellable,
+		                                                         &tmp_err);
+		if (tmp_err != NULL) {
+			g_propagate_error (err, tmp_err);
+			return FALSE;
+		}
 	} else {
 		/* get folder location bits */
 		KolabFolderSummary *summary = NULL;
 		summary = kolab_mail_info_db_query_folder_summary (priv->infodb,
 		                                                   foldername,
 		                                                   &tmp_err);
-		if (summary == NULL) {
+		if (tmp_err != NULL) {
 			g_propagate_error (err, tmp_err);
 			return FALSE;
 		}
+		if (summary != NULL) {
+			location =
+				kolab_folder_summary_get_uint_field (summary,
+				                                     KOLAB_FOLDER_SUMMARY_UINT_FIELD_CACHE_LOCATION);
+			kolab_folder_summary_free (summary);
+		} else {
+			/* location bits will now not be set - we can still
+			 * try server side folder delete, if the folder does
+			 * not exist there, the server will tell us
+			 */
+			g_warning ("%s()[%u] Got no folder summary for (%s)",
+			           __func__, __LINE__, foldername);
+		}
 
-		location = kolab_folder_summary_get_uint_field (summary,
-		                                                KOLAB_FOLDER_SUMMARY_UINT_FIELD_CACHE_LOCATION);
-		kolab_folder_summary_free (summary);
 		foldername_del = g_strdup (foldername);
 	}
-
-	/* TODO can we switch from full summaries table to simple UID list here ? */
-	imap_summaries = kolab_mail_imap_client_query_summaries (priv->client,
-	                                                         foldername,
-	                                                         NULL,
-	                                                         TRUE, /* need to update folder here */
-	                                                         cancellable,
-	                                                         &tmp_err);
-	if (tmp_err != NULL) {
-		g_propagate_error (err, tmp_err);
-		return FALSE;
-	}
+	
 	/* delete transaction preparation */
 	do_del = kolab_mail_synchronizer_transaction_prepare (priv->synchronizer,
 	                                                      priv->state->opmode,
 	                                                      KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
 	                                                      kmailhandle,
 	                                                      foldername_del,
+	                                                      KOLAB_FOLDER_TYPE_AUTO,
 	                                                      imap_summaries,
 	                                                      &record,
 	                                                      cancellable,
@@ -791,6 +834,7 @@ mail_access_local_delete (KolabMailAccess *self,
 	                                                KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
 	                                                kmailhandle,
 	                                                foldername_del,
+	                                                KOLAB_FOLDER_TYPE_AUTO,
 	                                                record,
 	                                                &tmp_err);
 	if (! ok) {
@@ -879,6 +923,7 @@ mail_access_local_delete (KolabMailAccess *self,
 		                                                 KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
 		                                                 kmailhandle,
 		                                                 foldername_del,
+		                                                 KOLAB_FOLDER_TYPE_AUTO,
 		                                                 record,
 		                                                 &tmp_err);
 	else
@@ -887,6 +932,7 @@ mail_access_local_delete (KolabMailAccess *self,
 		                                                KOLAB_MAIL_SYNCHRONIZER_TRANSACTION_TYPE_DELETE,
 		                                                kmailhandle,
 		                                                foldername_del,
+		                                                KOLAB_FOLDER_TYPE_AUTO,
 		                                                record,
 		                                                &tmp_err);
 	kolab_mail_info_db_record_free (record);
@@ -1976,6 +2022,7 @@ kolab_mail_access_query_uids (KolabMailAccess *self,
 
 	foldername = mail_access_foldername_new_from_sourcename (self,
 	                                                         sourcename,
+	                                                         TRUE,
 	                                                         &tmp_err);
 	if (foldername == NULL)
 		goto exit;
@@ -2058,6 +2105,7 @@ kolab_mail_access_query_changed_uids (KolabMailAccess *self,
 
 	foldername = mail_access_foldername_new_from_sourcename (self,
 	                                                         sourcename,
+	                                                         TRUE,
 	                                                         &tmp_err);
 	if (tmp_err != NULL)
 		goto exit;
@@ -2158,6 +2206,7 @@ kolab_mail_access_get_handle (KolabMailAccess *self,
 	/* map Evo calendar name to Kolab folder name */
 	foldername = mail_access_foldername_new_from_sourcename (self,
 	                                                         sourcename,
+	                                                         TRUE,
 	                                                         &tmp_err);
 	if (tmp_err != NULL)
 		goto exit;
@@ -2311,6 +2360,7 @@ kolab_mail_access_store_handle (KolabMailAccess *self,
 	/* sourcename data */
 	sourcename_fn = mail_access_foldername_new_from_sourcename (self,
 	                                                            sourcename,
+	                                                            TRUE,
 	                                                            &tmp_err);
 	if (sourcename_fn == NULL)
 		goto exit;
@@ -2350,6 +2400,7 @@ kolab_mail_access_store_handle (KolabMailAccess *self,
 	ok = mail_access_local_store (self,
 	                              kmailhandle,
 	                              sourcename_fn,
+	                              KOLAB_FOLDER_TYPE_AUTO, /* use the preconfigured type */
 	                              cancellable,
 	                              &tmp_err);
 	if (! ok)
@@ -2702,6 +2753,7 @@ kolab_mail_access_delete_by_uid (KolabMailAccess *self,
 
 	foldername = mail_access_foldername_new_from_sourcename (self,
 	                                                         sourcename,
+	                                                         TRUE,
 	                                                         &tmp_err);
 	if (tmp_err != NULL)
 		goto exit;
@@ -2908,27 +2960,26 @@ kolab_mail_access_query_folder_info_online (KolabMailAccess *self,
  * kolab_mail_access_create_source:
  * @self: a #KolabMailAccess instance
  * @sourcename: the name of the source to create
+ * @sourcetype: the Kolab type of the source to create
  * @cancellable: A cancellation stack
  * @err: a #GError object (or NULL)
  *
- * Creates a source (address book or calendar) of the given name. A source
+ * Creates a source (email, address book or calendar) of the given name and type. A source
  * needs to be created using this function prior to storing a #KolabMailHandle
  * into this source. If the @sourcename supplied already exists, the function
  * simply returns successfully.
  *
- * If #KolabMailAccess is in online operational mode, the source gets created on
- * the Kolab server right away. If that fails or if #KolabMailAccess is in offline
- * operational mode, the source gets created in the local cache only and is
- * synchronized with the server at the next synchronization point. If the source
- * was created locally only, you can nonetheless store #KolabMailHandle objects
- * in it.
+ * #KolabMailAccess is required to be in online operational mode for this function.
+ * This is to ensure the source could actually be created on the server before storing
+ * PIM objects in it. This is to minimize chances that PIM objects are stored
+ * locally in a source for which no folder can be created on the server.
  *
- * Returns: TRUE on success,
- *          FALSE if offline creation failed (with @err set)
+ * Returns: TRUE on success, FALSE otherwise
  */
 gboolean
 kolab_mail_access_create_source (KolabMailAccess *self,
                                  const gchar *sourcename,
+                                 KolabFolderTypeID sourcetype,
                                  GCancellable *cancellable,
                                  GError **err)
 {
@@ -2946,8 +2997,14 @@ kolab_mail_access_create_source (KolabMailAccess *self,
 
 	g_mutex_lock (&(priv->big_lock));
 
-	if (priv->state->opmode <= KOLAB_MAIL_ACCESS_OPMODE_CONFIGURED)
+	if (priv->state->opmode <= KOLAB_MAIL_ACCESS_OPMODE_OFFLINE) {
+		g_set_error (&tmp_err,
+		             KOLAB_BACKEND_ERROR,
+		             KOLAB_BACKEND_ERROR_STATE_WRONG_FOR_OP,
+		             _("You must be working online to complete this operation"));
+		ok = FALSE;
 		goto exit;
+	}
 
 	/* check whether folder exists */
 	exists = kolab_mail_info_db_exists_foldername (priv->infodb,
@@ -2965,6 +3022,7 @@ kolab_mail_access_create_source (KolabMailAccess *self,
 	ok = mail_access_local_store (self,
 	                              NULL,
 	                              sourcename,
+	                              sourcetype,
 	                              cancellable,
 	                              &tmp_err);
  exit:
@@ -3013,7 +3071,7 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
                                  GError **err)
 {
 	KolabMailAccessPrivate *priv = NULL;
-	gboolean exists = FALSE;
+	/* gboolean exists = FALSE; */
 	gboolean ok = TRUE;
 	GError *tmp_err = NULL;
 
@@ -3028,6 +3086,7 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
 
 	if (priv->state->opmode <= KOLAB_MAIL_ACCESS_OPMODE_CONFIGURED)
 		goto exit;
+#if 0
 
 	/* check whether folder exists */
 	exists = kolab_mail_info_db_exists_foldername (priv->infodb,
@@ -3040,6 +3099,7 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
 
 	if (! exists)
 		goto exit;
+#endif
 
 	/* delete folder */
 	ok = mail_access_local_delete (self,
@@ -3186,6 +3246,7 @@ kolab_mail_access_synchronize (KolabMailAccess *self,
 	/* foldername will be NULL if sourcename is NULL */
 	foldername = mail_access_foldername_new_from_sourcename (self,
 	                                                         sourcename,
+	                                                         TRUE,
 	                                                         &tmp_err);
 	if (tmp_err != NULL) {
 		ok = FALSE;
diff --git a/src/libekolab/kolab-mail-access.h b/src/libekolab/kolab-mail-access.h
index 49b7382..163d399 100644
--- a/src/libekolab/kolab-mail-access.h
+++ b/src/libekolab/kolab-mail-access.h
@@ -177,6 +177,7 @@ kolab_mail_access_query_folder_info_online (KolabMailAccess *self,
 gboolean
 kolab_mail_access_create_source (KolabMailAccess *self,
                                  const gchar *sourcename,
+                                 KolabFolderTypeID sourcetype,
                                  GCancellable *cancellable,
                                  GError **err);
 



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