[evolution-ews] Bug 794116 - Delete messages in chunks to not exceed maximum limit



commit 3f06cb5ece5055a84919edcaae704665dd708a6e
Author: Milan Crha <mcrha redhat com>
Date:   Tue Mar 13 16:20:28 2018 +0100

    Bug 794116 - Delete messages in chunks to not exceed maximum limit

 src/camel/camel-ews-folder.c  |    4 +-
 src/server/e-ews-connection.c |   67 ++++++++++++++++++++++++++++++++++++++++-
 src/server/e-ews-connection.h |   13 +++++++-
 3 files changed, 79 insertions(+), 5 deletions(-)
---
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index 3dda672..e3157c5 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -2446,9 +2446,9 @@ ews_delete_messages_from_server (CamelEwsStore *ews_store,
 
        cnc = camel_ews_store_ref_connection (ews_store);
 
-       ret = e_ews_connection_delete_items_sync (
+       ret = e_ews_connection_delete_items_in_chunks_sync (
                cnc, EWS_PRIORITY_MEDIUM, deleted_items, delete_type,
-               EWS_SEND_TO_NONE, FALSE, cancellable, error);
+               EWS_SEND_TO_NONE, EWS_NONE_OCCURRENCES, cancellable, error);
 
        g_object_unref (cnc);
 
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 3a62687..a0bae8b 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -4892,6 +4892,8 @@ static const gchar *
 ews_affected_tasks_to_str (EwsAffectedTaskOccurrencesType affected_tasks)
 {
        switch (affected_tasks) {
+               case EWS_NONE_OCCURRENCES:
+                       return NULL;
                case EWS_ALL_OCCURRENCES:
                        return "AllOccurrences";
                case EWS_SPECIFIED_OCCURRENCE_ONLY:
@@ -5033,7 +5035,7 @@ e_ews_connection_delete_item (EEwsConnection *cnc,
                        msg, "SendMeetingCancellations",
                        ews_send_cancels_to_str (send_cancels), NULL, NULL);
 
-       if (affected_tasks)
+       if (affected_tasks != EWS_NONE_OCCURRENCES)
                e_soap_message_add_attribute (
                        msg, "AffectedTaskOccurrences",
                        ews_affected_tasks_to_str (affected_tasks), NULL, NULL);
@@ -5161,6 +5163,69 @@ e_ews_connection_delete_item_sync (EEwsConnection *cnc,
        return success;
 }
 
+gboolean
+e_ews_connection_delete_items_in_chunks_sync (EEwsConnection *cnc,
+                                             gint pri,
+                                             const GSList *ids,
+                                             EwsDeleteType delete_type,
+                                             EwsSendMeetingCancellationsType send_cancels,
+                                             EwsAffectedTaskOccurrencesType affected_tasks,
+                                             GCancellable *cancellable,
+                                             GError **error)
+{
+       const GSList *iter;
+       guint total_ids = 0, done_ids = 0;
+       gboolean success = TRUE;
+
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+
+       g_object_ref (cnc);
+
+       iter = ids;
+
+       while (success && iter) {
+               guint n_ids;
+               const GSList *tmp_iter;
+
+               for (tmp_iter = iter, n_ids = 0; tmp_iter && n_ids < EWS_MOVE_ITEMS_CHUNK_SIZE; tmp_iter = 
g_slist_next (tmp_iter), n_ids++) {
+                       /* Only check bounds first, to avoid unnecessary allocations */
+               }
+
+               if (tmp_iter) {
+                       GSList *shorter = NULL;
+
+                       if (total_ids == 0)
+                               total_ids = g_slist_length ((GSList *) ids);
+
+                       for (n_ids = 0; iter && n_ids < EWS_MOVE_ITEMS_CHUNK_SIZE; iter = g_slist_next 
(iter), n_ids++) {
+                               shorter = g_slist_prepend (shorter, iter->data);
+                       }
+
+                       shorter = g_slist_reverse (shorter);
+
+                       success = e_ews_connection_delete_items_sync (cnc, pri, shorter, delete_type, 
send_cancels,
+                               affected_tasks, cancellable, error);
+
+                       g_slist_free (shorter);
+
+                       done_ids += n_ids;
+               } else {
+                       success = e_ews_connection_delete_items_sync (cnc, pri, iter, delete_type, 
send_cancels,
+                               affected_tasks, cancellable, error);
+
+                       iter = NULL;
+                       done_ids = total_ids;
+               }
+
+               if (total_ids > 0)
+                       camel_operation_progress (cancellable, 100 * (gdouble) done_ids / (gdouble) 
total_ids);
+       }
+
+       g_object_unref (cnc);
+
+       return success;
+}
+
 static xmlXPathObjectPtr
 xpath_eval (xmlXPathContextPtr ctx,
            const gchar *format,
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index fdff192..108205f 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -107,7 +107,8 @@ typedef enum {
 } EwsSendMeetingCancellationsType;
 
 typedef enum {
-       EWS_ALL_OCCURRENCES = 1,
+       EWS_NONE_OCCURRENCES = 0,
+       EWS_ALL_OCCURRENCES,
        EWS_SPECIFIED_OCCURRENCE_ONLY
 } EwsAffectedTaskOccurrencesType;
 
@@ -626,7 +627,15 @@ gboolean   e_ews_connection_delete_items_sync
                                                 EwsAffectedTaskOccurrencesType affected_tasks,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
+gboolean       e_ews_connection_delete_items_in_chunks_sync
+                                               (EEwsConnection *cnc,
+                                                gint pri,
+                                                const GSList *ids,
+                                                EwsDeleteType delete_type,
+                                                EwsSendMeetingCancellationsType send_cancels,
+                                                EwsAffectedTaskOccurrencesType affected_tasks,
+                                                GCancellable *cancellable,
+                                                GError **error);
 void           e_ews_connection_delete_item    (EEwsConnection *cnc,
                                                 gint pri,
                                                 EwsId *id,


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