[evolution-data-server/gnome-2-30] Add proper QRESYNC support on SELECT; use it for refresh_info



commit bf6d9c9bd6aa906296f15aac1e9470b51ec58824
Author: David Woodhouse <David Woodhouse intel com>
Date:   Wed Jun 30 09:49:12 2010 +0100

    Add proper QRESYNC support on SELECT; use it for refresh_info
    
    We aren't yet correctly updating the folder's modseq every time, so we're
    often asking for more than we need. That's better than asking for _less_ than
    we need though -- will go over that part very carefully in separate commit(s).
    
    We still aren't handling uidvalidity either. RSN...
    (cherry picked from commit 7dcedc3ef77ddcf4b7ca6bb1fbab7d3246edca34)
    
    (Disabled the UI configuration option for it, since it's a new string)

 camel/providers/imapx/camel-imapx-provider.c |    4 +
 camel/providers/imapx/camel-imapx-server.c   |   91 ++++++++++++++++++++++++--
 camel/providers/imapx/camel-imapx-server.h   |    2 +
 camel/providers/imapx/camel-imapx-store.c    |    3 +
 camel/providers/imapx/camel-imapx-store.h    |    1 +
 5 files changed, 95 insertions(+), 6 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-provider.c b/camel/providers/imapx/camel-imapx-provider.c
index 01f547d..2a5a13f 100644
--- a/camel/providers/imapx/camel-imapx-provider.c
+++ b/camel/providers/imapx/camel-imapx-provider.c
@@ -42,6 +42,10 @@ static gint  imapx_url_equal (gconstpointer a, gconstpointer b);
 CamelProviderConfEntry imapx_conf_entries[] = {
 		{ CAMEL_PROVIDER_CONF_SECTION_START, "mailcheck", NULL,
 	  N_("Checking for New Mail") },
+#if 0 /* Not for stable branch -- new string. Set it with gconf-editor instead */
+	{ CAMEL_PROVIDER_CONF_CHECKBOX, "use_qresync", NULL,
+	  N_("Use _Quick Resync if the server supports it"), "1" },
+#endif
 	{ CAMEL_PROVIDER_CONF_CHECKBOX, "use_idle", NULL,
 	  N_("Use I_dle if the server supports it"), "1" },
 	{ CAMEL_PROVIDER_CONF_CHECKBOX, "check_all", NULL,
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 7d20cab..c730cd8 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -2376,6 +2376,66 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, CamelE
 	is->state = IMAPX_INITIALISED;
 
 	ic = camel_imapx_command_new(is, "SELECT", NULL, "SELECT %f", folder);
+
+	if (is->use_qresync) {
+		CamelIMAPXSummary *isum = (CamelIMAPXSummary *)folder->summary;
+		CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)folder;
+		gint total = camel_folder_summary_count(folder->summary);
+		const gchar *uid = "1";
+
+		if (total)
+		    uid = camel_folder_summary_uid_from_index (folder->summary, 1);
+
+		if (isum->modseq && ifolder->uidvalidity_on_server) {
+			c(printf("SELECT QRESYNC %ld %ld\n", ifolder->uidvalidity_on_server, isum->modseq));
+			camel_imapx_command_add(ic, " (QRESYNC (%ld %ld %s:*", ifolder->uidvalidity_on_server, isum->modseq, uid);
+
+			if (total > 10) {
+				int i;
+				GString *seqs, *uids;
+
+				seqs = g_string_new(" ");
+				uids = g_string_new(")");
+
+				/* Include some seq/uid pairs to avoid a huge VANISHED list 
+				   (see RFC5162 §3.1). Work backwards exponentially from the
+				   end of the mailbox, starting with the message 9 from the
+				   end, then 27 from the end, then 81 from the end... */
+				i = 3;
+				do {
+					gchar buf[10];
+
+					i *= 3;
+					if (i > total)
+						i = total;
+
+					if (i != 9) { /* If not the first time */
+						g_string_prepend(seqs, ",");
+						g_string_prepend(uids, ",");
+					}
+
+					/* IMAP sequence numbers are one higher than the corresponding
+					   indices in our folder summary -- they start from one, while
+					   the summary starts from zero. */
+					sprintf(buf, "%d", total - i + 1);
+					g_string_prepend(seqs, buf);
+ 					g_string_prepend(uids, camel_folder_summary_uid_from_index(folder->summary, total - i));
+				} while (i < total);
+
+				g_string_prepend(seqs, " (");
+
+				c(printf("adding QRESYNC seq/uidset %s%s\n", seqs->str, uids->str));
+				camel_imapx_command_add(ic, seqs->str);
+				camel_imapx_command_add(ic, uids->str);
+				
+				g_string_free(seqs, TRUE);
+				g_string_free(uids, TRUE);
+
+			}
+			camel_imapx_command_add(ic, "))");
+		}
+	}
+
 	ic->complete = imapx_command_select_done;
 	imapx_command_start (is, ic);
 }
@@ -2857,7 +2917,8 @@ imapx_reconnect (CamelIMAPXServer *is, CamelException *ex)
 		if (camel_exception_is_set (ex))
 			goto exception;
 	}
-	if (is->cinfo->capa & IMAPX_CAPABILITY_QRESYNC) {
+	if (((CamelIMAPXStore *)is->store)->rec_options & IMAPX_USE_QRESYNC &&
+	    is->cinfo->capa & IMAPX_CAPABILITY_QRESYNC) {
 		ic = camel_imapx_command_new (is, "ENABLE", NULL, "ENABLE CONDSTORE QRESYNC");
 		imapx_command_run (is, ic);
 		camel_exception_xfer (ex, ic->ex);
@@ -2865,7 +2926,11 @@ imapx_reconnect (CamelIMAPXServer *is, CamelException *ex)
 
 		if (camel_exception_is_set (ex))
 			goto exception;
-	}
+
+		is->use_qresync = TRUE;
+	} else
+		is->use_qresync = FALSE;
+
 	if (((CamelIMAPXStore *) is->store)->summary->namespaces == NULL) {
 		CamelIMAPXNamespaceList *nsl = NULL;
 		CamelIMAPXStoreNamespace *ns = NULL;
@@ -3607,6 +3672,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 	CamelException *ex = job->ex;
 	gboolean need_rescan = FALSE;
 	gboolean is_selected = FALSE;
+	gboolean can_qresync = FALSE;
 
 	/* Sync changes first, else unread count will not
 	   match. Need to think about better ways for this */
@@ -3637,6 +3703,9 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 	if ((isum->modseq && !ifolder->modseq_on_server))
 		need_rescan = FALSE;
 
+	if (is->use_qresync && isum->modseq && ifolder->uidvalidity_on_server)
+		can_qresync = TRUE;
+
 	/* If we don't think there's anything to do, poke it to check */
 	if (!need_rescan) {
 		CamelIMAPXCommand *ic;
@@ -3709,14 +3778,24 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 		imapx_server_fetch_new_messages (is, folder, FALSE, job->ex);
 		if (camel_exception_is_set (job->ex))
 			goto done;
+
+		/* If QRESYNC-capable we'll have got all flags changes in SELECT */
+		if (can_qresync)
+			goto done;
 	}
 
-	/* Refetch flags for the entire folder */
-	if (need_rescan) {
-		imapx_job_scan_changes_start (is, job);
-		return;
+	if (!need_rescan)
+		goto done;
+
+	if (can_qresync) {
+		/* Actually we only want to select it; no need for the NOOP */
+		camel_imapx_server_noop(is, folder, ex);
+		goto done;
 	}
 
+	imapx_job_scan_changes_start (is, job);
+	return;
+
 done:
 	imapx_job_done (is, job);
 }
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index 824e123..31c8fe2 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -102,6 +102,8 @@ struct _CamelIMAPXServer {
 	struct _CamelIMAPXIdle *idle;
 	gboolean use_idle;
 
+	gboolean use_qresync;
+
 	/* used for storing eflags to syncronize duplicate get_message requests */
 	GHashTable *uid_eflags;
 };
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 90b4780..be30538 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -124,6 +124,9 @@ imapx_parse_receiving_options (CamelIMAPXStore *istore, CamelURL *url)
 
 	if (camel_url_get_param (url, "use_idle"))
 		istore->rec_options |= IMAPX_USE_IDLE;
+
+	if (camel_url_get_param (url, "use_qresync"))
+		istore->rec_options |= IMAPX_USE_QRESYNC;
 }
 
 static void
diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h
index 3cb1227..e5af0a2 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -47,6 +47,7 @@ extern "C" {
 #define IMAPX_SUBSCRIPTIONS		(1 << 5)
 #define IMAPX_CHECK_LSUB		(1 << 6)
 #define IMAPX_USE_IDLE			(1 << 7)
+#define IMAPX_USE_QRESYNC		(1 << 8)
 
 typedef struct {
 	CamelOfflineStore parent_object;



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