[evolution-kolab] KolabMailAccess: reworked handling of folder delete



commit 180a1bceec9e2e980e9a485a6456d81c35737aa6
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Wed Sep 19 19:23:50 2012 +0200

    KolabMailAccess: reworked handling of folder delete
    
    * when deleting an existing folder, we bypass the whole
      transaction handling, which has been implemented
      for PIM objects, but is not yet needed for folder
      delete
    * removed the whole InfoDb updating, since in the
      event of a successfully removed folder, the ESource
      for it will be deleted and the cache reaper will
      kill the entire cache directory of that folder
      (so no point updating a DB residing in that same
      folder)

 src/libekolab/kolab-mail-access.c |  158 ++++++++++++++++++-------------------
 1 files changed, 77 insertions(+), 81 deletions(-)
---
diff --git a/src/libekolab/kolab-mail-access.c b/src/libekolab/kolab-mail-access.c
index 8a54173..eaf1ba4 100644
--- a/src/libekolab/kolab-mail-access.c
+++ b/src/libekolab/kolab-mail-access.c
@@ -758,65 +758,53 @@ mail_access_local_delete (KolabMailAccess *self,
 
 	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
 
-	if (kmailhandle != NULL) {
-		/* check whether we have a summary for the mail handle */
-		ok = mail_access_local_handle_attach_summary (self,
-		                                              kmailhandle,
-		                                              &tmp_err);
-		if (! ok) {
-			g_propagate_error (err, tmp_err);
-			return FALSE;
-		}
-		/* get handle details */
-		uid = kolab_mail_handle_get_uid (kmailhandle);
-		location = kolab_mail_handle_get_cache_location (kmailhandle);
-		foldername_del = g_strdup (kolab_mail_handle_get_foldername (kmailhandle));
-		if (g_strcmp0 (foldername, foldername_del) != 0) {
-			g_set_error (err,
-			             KOLAB_BACKEND_ERROR,
-			             KOLAB_BACKEND_ERROR_DATATYPE_INTERNAL,
-			             _("Internal inconsistency detected: PIM Object handle, UID %s, has folder name '%s' set, but supplied folder name to delete it from is '%s'"),
-			             uid, foldername_del, foldername);
-			if (foldername_del != NULL)
-				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 (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);
-		}
+	/* Check whether we should delete a folder instead of deleting a handle
+	 * (if so, we do bypass the whole transaction handling, which is for handles
+	 * only at present). Once we find we need transactions for folder delete,
+	 * we need to remove the skipping here and actually implement the folder
+	 * transactions in KolabMailSynchronizer
+	 */
+	if (kmailhandle == NULL) {
+		do_del = TRUE;
+		foldername_del = g_strdup (foldername);		
+		location = KOLAB_OBJECT_CACHE_LOCATION_IMAP; /* verified by a preceeding online query */
+		goto handle_skip;
+	}
 
-		foldername_del = g_strdup (foldername);
+	/* check whether we have a summary for the mail handle */
+	ok = mail_access_local_handle_attach_summary (self,
+	                                              kmailhandle,
+	                                              &tmp_err);
+	if (! ok) {
+		g_propagate_error (err, tmp_err);
+		return FALSE;
+	}
+	
+	/* get handle details */
+	uid = kolab_mail_handle_get_uid (kmailhandle);
+	location = kolab_mail_handle_get_cache_location (kmailhandle);
+	foldername_del = g_strdup (kolab_mail_handle_get_foldername (kmailhandle));
+	if (g_strcmp0 (foldername, foldername_del) != 0) {
+		g_set_error (err,
+		             KOLAB_BACKEND_ERROR,
+		             KOLAB_BACKEND_ERROR_DATATYPE_INTERNAL,
+		             _("Internal inconsistency detected: PIM Object handle, UID %s, has folder name '%s' set, but supplied folder name to delete it from is '%s'"),
+		             uid, foldername_del, foldername);
+		if (foldername_del != NULL)
+			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;
 	}
 	
 	/* delete transaction preparation */
@@ -856,6 +844,8 @@ mail_access_local_delete (KolabMailAccess *self,
 		return FALSE;
 	}
 
+ handle_skip:
+	
 	if (do_del) {
 		/* online delete operation */
 		if ((location & KOLAB_OBJECT_CACHE_LOCATION_IMAP) &&
@@ -881,14 +871,25 @@ mail_access_local_delete (KolabMailAccess *self,
 				}
 			} else {
 				/* TODO check whether we really want to delete
-				 *      folders which have changes on the server
-				 *      side (this will become an issue once we
-				 *      really delete folders on the server)
+				 *      folders which might have changes on the
+				 *      server...
 				 */
 				ok = kolab_mail_imap_client_delete_folder (priv->client,
 				                                           foldername_del,
 				                                           cancellable,
 				                                           &tmp_err);
+				
+				/* TODO check whether we need to update DBs and friends
+				 *      (most probably no point, since the backend for
+				 *      the folder will be removed and the cache reaper
+				 *      will kill our now-orphaned disk cache)
+				 */
+
+				/* we skip the transaction handling again, which is for
+				 * mail handles only and does not affect folders in the
+				 * delete operation, at present
+				 */
+				goto done;
 			}
 			if (ok) {
 				sync_opmode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE;
@@ -903,6 +904,7 @@ mail_access_local_delete (KolabMailAccess *self,
 				online_ok = FALSE;
 			}
 		}
+		
 		/* offline delete operation (not done if online operation failed before) */
 		if (online_ok && (location & KOLAB_OBJECT_CACHE_LOCATION_SIDE)) {
 			if (kmailhandle != NULL)
@@ -910,6 +912,7 @@ mail_access_local_delete (KolabMailAccess *self,
 				                                   kmailhandle,
 				                                   &tmp_err);
 			else
+				/* skipped at present (cache reaper does the job) */
 				ok = kolab_mail_side_cache_delete_folder (priv->sidecache,
 				                                          foldername_del,
 				                                          &tmp_err);
@@ -927,6 +930,10 @@ mail_access_local_delete (KolabMailAccess *self,
 		}
 	}
 
+	/* remove this if transaction handling for folders is needed */
+	if (kmailhandle == NULL)
+		goto done;
+
 	/* transaction finalization */
 	if (online_ok && offline_ok)
 		ok = kolab_mail_synchronizer_transaction_commit (priv->synchronizer,
@@ -946,7 +953,10 @@ mail_access_local_delete (KolabMailAccess *self,
 		                                                KOLAB_FOLDER_TYPE_AUTO,
 		                                                record,
 		                                                &tmp_err);
+ done:
+	
 	kolab_mail_info_db_record_free (record);
+
 	if (foldername_del != NULL)
 		g_free (foldername_del);
 
@@ -3154,8 +3164,6 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
                                  GError **err)
 {
 	KolabMailAccessPrivate *priv = NULL;
-	GList *folders_desc = NULL;
-	GList *folders_desc_ptr = NULL;
 	gboolean exists = FALSE;
 	gboolean ok = TRUE;
 	GError *tmp_err = NULL;
@@ -3174,7 +3182,6 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
 		             KOLAB_BACKEND_ERROR,
 		             KOLAB_BACKEND_ERROR_STATE_WRONG_FOR_OP,
 		             _("You must be working online to complete this operation"));
-		ok = FALSE;
 		goto exit;
 	}
 
@@ -3191,25 +3198,14 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
 	 * the server and check whether we find the to-be-deleted folder
 	 * there
 	 */
-	folders_desc = kolab_mail_imap_client_query_folder_info_online (priv->client,
-	                                                                cancellable,
-	                                                                &tmp_err);
-	if (tmp_err != NULL) {
-		ok = FALSE;
+	exists = kolab_mail_imap_client_exists_folder (priv->client,
+	                                               sourcename,
+	                                               FALSE, /* online query (no DB update) */
+	                                               cancellable,
+	                                               &tmp_err);
+	if (tmp_err != NULL)
 		goto exit;
-	}
 
-	folders_desc_ptr = folders_desc;
-	while (folders_desc_ptr != NULL) {
-		KolabFolderDescriptor *desc = (KolabFolderDescriptor *) folders_desc_ptr->data;
-		exists = g_str_equal (desc->name, sourcename);
-		if (exists)
-			break;
-		folders_desc_ptr = g_list_next (folders_desc_ptr);
-	}
-
-	kolab_util_folder_descriptor_glist_free (folders_desc);
-	
 	if (! exists) {
 		/* We assume here that if a folder has been deleted,
 		 * the folder annotation has been deleted as well



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