[evolution-data-server/imap-pop-mobile: 2/12] Add sync+async apis for Fetch Messages and Purge Message Cache.



commit 27911712922569a7035f087ef08d75f54936024f
Author: Srinivasa Ragavan <sragavan gnome org>
Date:   Tue Jan 10 16:37:26 2012 +0530

    Add sync+async apis for Fetch Messages and Purge Message Cache.

 camel/camel-enums.h  |   12 ++-
 camel/camel-folder.c |  367 ++++++++++++++++++++++++++++++++++++++++++++++++++
 camel/camel-folder.h |   81 +++++++++++-
 3 files changed, 458 insertions(+), 2 deletions(-)
---
diff --git a/camel/camel-enums.h b/camel/camel-enums.h
index 3335be0..1ad1682 100644
--- a/camel/camel-enums.h
+++ b/camel/camel-enums.h
@@ -276,6 +276,13 @@ typedef enum {
  *   Provider may use a real trash folder instead of a virtual folder.
  * @CAMEL_PROVIDER_ALLOW_REAL_JUNK_FOLDER:
  *   Provider may use a real junk folder instead of a virtual folder.
+ * @CAMEL_PROVIDER_SUPPORTS_MOBILE_DEVICES:
+ *  Download limited set of emails instead of operating on full cache.
+ * @CAMEL_PROVIDER_SUPPORTS_BATCH_FETCH:
+ *  Support to fetch messages in batch.
+ * @CAMEL_PROVIDER_SUPPORTS_PURGE_MESSAGE_CACHE:
+ *  Support to remove oldest downloaded messages to conserve space.
+ *
  **/
 typedef enum { /*< flags >*/
 	CAMEL_PROVIDER_IS_REMOTE               = 1 << 0,
@@ -287,7 +294,10 @@ typedef enum { /*< flags >*/
 	CAMEL_PROVIDER_HAS_LICENSE             = 1 << 6,
 	CAMEL_PROVIDER_DISABLE_SENT_FOLDER     = 1 << 7,
 	CAMEL_PROVIDER_ALLOW_REAL_TRASH_FOLDER = 1 << 8,
-	CAMEL_PROVIDER_ALLOW_REAL_JUNK_FOLDER  = 1 << 9
+	CAMEL_PROVIDER_ALLOW_REAL_JUNK_FOLDER  = 1 << 9,
+	CAMEL_PROVIDER_SUPPORTS_MOBILE_DEVICES = 1 << 10,
+	CAMEL_PROVIDER_SUPPORTS_BATCH_FETCH    = 1 << 11,
+	CAMEL_PROVIDER_SUPPORTS_PURGE_MESSAGE_CACHE = 1 << 12
 } CamelProviderFlags;
 
 typedef enum {
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index ae0b405..7eaf143 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -76,10 +76,15 @@ struct _AsyncContext {
 	gchar *message_uid;         /* also a result */
 	gboolean delete_originals;
 	gboolean expunge;
+	CamelFetchType fetch_type;
+	int limit;
+	gchar *start_uid;
+	gchar *end_uid;
 
 	/* results */
 	GPtrArray *transferred_uids;
 	CamelFolderQuotaInfo *quota_info;
+	gboolean success; /* A result that mention that there are more messages in fetch_messages operation */
 };
 
 struct _CamelFolderChangeInfoPrivate {
@@ -151,6 +156,8 @@ async_context_free (AsyncContext *async_context)
 		camel_folder_quota_info_free (async_context->quota_info);
 
 	g_free (async_context->message_uid);
+	g_free (async_context->start_uid);
+	g_free (async_context->end_uid);
 
 	g_slice_free (AsyncContext, async_context);
 }
@@ -1066,6 +1073,72 @@ folder_expunge_finish (CamelFolder *folder,
 }
 
 static void
+fetch_messages_thread (GSimpleAsyncResult *simple,
+                       GObject *object,
+                       GCancellable *cancellable)
+{
+	AsyncContext *async_context;
+	GError *error = NULL;
+
+	async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+	async_context->success = camel_folder_fetch_messages_sync (
+		CAMEL_FOLDER (object), async_context->fetch_type, async_context->limit, cancellable, &error);
+
+	if (error != NULL)
+		g_simple_async_result_take_error (simple, error);
+}
+
+static void
+fetch_messages (CamelFolder *folder,
+		CamelFetchType type,
+		int limit,
+                gint io_priority,
+                GCancellable *cancellable,
+                GAsyncReadyCallback callback,
+                gpointer user_data)
+{
+	GSimpleAsyncResult *simple;
+	AsyncContext *async_context;
+
+	async_context = g_slice_new0 (AsyncContext);
+	async_context->fetch_type = type;
+	async_context->limit = limit;
+
+	simple = g_simple_async_result_new (
+		G_OBJECT (folder), callback, user_data, fetch_messages);
+
+	g_simple_async_result_set_op_res_gpointer (
+		simple, async_context, (GDestroyNotify) async_context_free);
+
+	g_simple_async_result_run_in_thread (
+		simple, fetch_messages_thread, io_priority, cancellable);
+
+	g_object_unref (simple);
+}
+
+static gboolean
+fetch_messages_finish (CamelFolder *folder,
+                       GAsyncResult *result,
+                       GError **error)
+{
+	GSimpleAsyncResult *simple;
+	AsyncContext *async_context;
+
+	g_return_val_if_fail (
+		g_simple_async_result_is_valid (
+		result, G_OBJECT (folder), fetch_messages), FALSE);
+
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+	async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+	/* Assume success unless a GError is set. */
+	g_simple_async_result_propagate_error (simple, error);
+
+	return async_context->success;
+}
+
+static void
 folder_get_message_thread (GSimpleAsyncResult *simple,
                            GObject *object,
                            GCancellable *cancellable)
@@ -1212,6 +1285,72 @@ folder_get_quota_info_finish (CamelFolder *folder,
 }
 
 static void
+purge_message_cache_thread (GSimpleAsyncResult *simple,
+                       GObject *object,
+                       GCancellable *cancellable)
+{
+	AsyncContext *async_context;
+	GError *error = NULL;
+
+	async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+	async_context->success = camel_folder_purge_message_cache_sync (
+		CAMEL_FOLDER (object), async_context->start_uid, async_context->end_uid, cancellable, &error);
+
+	if (error != NULL)
+		g_simple_async_result_take_error (simple, error);
+}
+
+static void
+purge_message_cache (CamelFolder *folder,
+		     gchar *start_uid,
+		     gchar *end_uid,
+		     gint io_priority,
+		     GCancellable *cancellable,
+		     GAsyncReadyCallback callback,
+		     gpointer user_data)
+{
+	GSimpleAsyncResult *simple;
+	AsyncContext *async_context;
+
+	async_context = g_slice_new0 (AsyncContext);
+	async_context->start_uid = g_strdup (start_uid);
+	async_context->end_uid = g_strdup (end_uid);
+
+	simple = g_simple_async_result_new (
+		G_OBJECT (folder), callback, user_data, purge_message_cache);
+
+	g_simple_async_result_set_op_res_gpointer (
+		simple, async_context, (GDestroyNotify) async_context_free);
+
+	g_simple_async_result_run_in_thread (
+		simple, purge_message_cache_thread, io_priority, cancellable);
+
+	g_object_unref (simple);
+}
+
+static gboolean
+purge_message_cache_finish (CamelFolder *folder,
+     	                    GAsyncResult *result,
+			    GError **error)
+{
+	GSimpleAsyncResult *simple;
+	AsyncContext *async_context;
+
+	g_return_val_if_fail (
+		g_simple_async_result_is_valid (
+		result, G_OBJECT (folder), purge_message_cache), FALSE);
+
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+	async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+	/* Assume success unless a GError is set. */
+	g_simple_async_result_propagate_error (simple, error);
+
+	return async_context->success;
+}
+
+static void
 folder_refresh_info_thread (GSimpleAsyncResult *simple,
                             GObject *object,
                             GCancellable *cancellable)
@@ -1608,10 +1747,14 @@ camel_folder_class_init (CamelFolderClass *class)
 	class->append_message_finish = folder_append_message_finish;
 	class->expunge = folder_expunge;
 	class->expunge_finish = folder_expunge_finish;
+	class->fetch_messages= fetch_messages;
+	class->fetch_messages_finish = fetch_messages_finish;	
 	class->get_message = folder_get_message;
 	class->get_message_finish = folder_get_message_finish;
 	class->get_quota_info = folder_get_quota_info;
 	class->get_quota_info_finish = folder_get_quota_info_finish;
+	class->purge_message_cache= purge_message_cache;
+	class->purge_message_cache_finish = purge_message_cache_finish;		
 	class->refresh_info = folder_refresh_info;
 	class->refresh_info_finish = folder_refresh_info_finish;
 	class->synchronize = folder_synchronize;
@@ -3247,6 +3390,118 @@ camel_folder_expunge_finish (CamelFolder *folder,
 }
 
 /**
+ * camel_folder_fetch_messages_sync :
+ * @folder: a #CamelFolder
+ * @type: Type to specify fetch old or new messages.
+ * #limit: Limit to specify the number of messages to download.
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Downloads old or new specified number of messages from the server. It is optimized for mobile client usage. Desktop clients should keep away from this api and use @camel_folder_refresh_info.
+ *
+ * Returns: %TRUE if there are more messages to fetch, %FALSE if there are no more messages. 
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_folder_fetch_messages_sync (CamelFolder *folder,
+				  CamelFetchType type,
+				  int limit,
+                           	  GCancellable *cancellable,
+                               	  GError **error)
+{
+	CamelFolderClass *class;
+	gboolean success = TRUE;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+
+	/* Some backends that wont support mobile mode, won't have this api implemented. */
+	if (class->fetch_messages_sync == NULL)
+		return FALSE;
+
+	camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+	/* Check for cancellation after locking. */
+	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+		camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+		return FALSE;
+	}
+
+	success = class->fetch_messages_sync (folder, type, limit, cancellable, error);
+	CAMEL_CHECK_GERROR (folder, fetch_messages_sync, success, error);
+
+	camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+	return success;
+}
+
+/**
+ * camel_folder_fetch_messages:
+ * @folder: a #CamelFolder
+ * @type: Type to specify fetch old or new messages.
+ * #limit: Limit to specify the number of messages to download.
+ * @io_priority: the I/O priority of the request
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: data to pass to the callback function
+ *
+ * Asynchronously download new or old messages from the server.
+ *
+ * When the operation is finished, @callback will be called.  You can then
+ * call camel_folder_fetch_messages_finish() to get the result of the operation.
+ *
+ * Since: 3.4
+ **/
+void
+camel_folder_fetch_messages (CamelFolder *folder,
+			     CamelFetchType type,
+			     int limit,
+	                     gint io_priority,
+			     GCancellable *cancellable,
+			     GAsyncReadyCallback callback,
+			     gpointer user_data)
+{
+	CamelFolderClass *class;
+
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->fetch_messages != NULL);
+
+	class->fetch_messages (folder, type, limit, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_fetch_messages_finish:
+ * @folder: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_folder_fetch_messages().
+ *
+ * Returns: %TRUE if there are more messages to fetch, %FALSE if there are no more messages.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_folder_fetch_messages_finish (CamelFolder *folder,
+                             	    GAsyncResult *result,
+				    GError **error)
+{
+	CamelFolderClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->fetch_messages_finish != NULL, FALSE);
+
+	return class->fetch_messages_finish (folder, result, error);
+}
+
+/**
  * camel_folder_get_message_sync:
  * @folder: a #CamelFolder
  * @message_uid: the message UID
@@ -3501,6 +3756,118 @@ camel_folder_get_quota_info_finish (CamelFolder *folder,
 }
 
 /**
+ * camel_folder_purge_message_cache_sync :
+ * @folder: a #CamelFolder
+ * @start_uid: the start message UID
+ * @end_uid: the end message UID
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Delete the local cache of all messages between these uids.
+ *
+ * Returns: %TRUE if success, %FALSE if there are any errors. 
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_folder_purge_message_cache_sync (CamelFolder *folder,
+				       gchar *start_uid,
+				       gchar *end_uid,
+				       GCancellable *cancellable,
+				       GError **error)
+{
+	CamelFolderClass *class;
+	gboolean success = TRUE;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+
+	/* Some backends that wont support mobile mode, won't have this api implemented. */
+	if (class->purge_message_cache_sync == NULL)
+		return FALSE;
+
+	camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
+
+	/* Check for cancellation after locking. */
+	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+		camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+		return FALSE;
+	}
+
+	success = class->purge_message_cache_sync (folder, start_uid, end_uid, cancellable, error);
+	CAMEL_CHECK_GERROR (folder, purge_message_cache_sync, success, error);
+
+	camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
+
+	return success;
+}
+
+/**
+ * camel_folder_purge_message_cache:
+ * @folder: a #CamelFolder
+ * @start_uid: the start message UID
+ * @end_uid: the end message UID 
+ * @io_priority: the I/O priority of the request
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: data to pass to the callback function
+ *
+ * Delete the local cache of all messages between these uids.
+ * 
+ * When the operation is finished, @callback will be called.  You can then
+ * call camel_folder_purge_message_cache_finish() to get the result of the operation.
+ *
+ * Since: 3.4
+ **/
+void
+camel_folder_purge_message_cache (CamelFolder *folder,
+				  gchar *start_uid,
+				  gchar *end_uid,
+				  gint io_priority,
+				  GCancellable *cancellable,
+				  GAsyncReadyCallback callback,
+				  gpointer user_data)
+{
+	CamelFolderClass *class;
+
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_if_fail (class->purge_message_cache != NULL);
+
+	class->purge_message_cache (folder, start_uid, end_uid, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * camel_folder_purge_message_cache_finish:
+ * @folder: a #CamelFolder
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with camel_folder_purge_message_cache().
+ *
+ * Returns: %TRUE if cache is deleted, %FALSE if there are any errors.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_folder_purge_message_cache_finish (CamelFolder *folder,
+                             	    GAsyncResult *result,
+				    GError **error)
+{
+	CamelFolderClass *class;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	class = CAMEL_FOLDER_GET_CLASS (folder);
+	g_return_val_if_fail (class->purge_message_cache_finish != NULL, FALSE);
+
+	return class->purge_message_cache_finish (folder, result, error);
+}
+
+/**
  * camel_folder_refresh_info_sync:
  * @folder: a #CamelFolder
  * @cancellable: optional #GCancellable object, or %NULL
diff --git a/camel/camel-folder.h b/camel/camel-folder.h
index 3e49886..f226681 100644
--- a/camel/camel-folder.h
+++ b/camel/camel-folder.h
@@ -87,6 +87,16 @@ typedef enum {
 } CamelFolderError;
 
 /**
+ * CamelFetchType:
+ *
+ * Since: 3.4
+ **/
+typedef enum {
+	CAMEL_FETCH_OLD_MESSAGES,
+	CAMEL_FETCH_NEW_MESSAGES
+} CamelFetchType;
+
+/**
  * CamelFolderLock:
  *
  * Since: 2.32
@@ -208,7 +218,7 @@ struct _CamelFolderClass {
 			(*get_message_cached)	(CamelFolder *folder,
 						 const gchar *message_uid,
 						 GCancellable *cancellable);
-
+		
 	/* Synchronous I/O Methods */
 	gboolean	(*append_message_sync)	(CamelFolder *folder,
 						 CamelMimeMessage *message,
@@ -219,6 +229,11 @@ struct _CamelFolderClass {
 	gboolean	(*expunge_sync)		(CamelFolder *folder,
 						 GCancellable *cancellable,
 						 GError **error);
+	gboolean 	(*fetch_messages_sync)	(CamelFolder *folder,
+						 CamelFetchType type,
+						 int limit,
+						 GCancellable *cancellable,
+						 GError **error);
 	CamelMimeMessage *
 			(*get_message_sync)	(CamelFolder *folder,
 						 const gchar *message_uid,
@@ -228,6 +243,12 @@ struct _CamelFolderClass {
 			(*get_quota_info_sync)	(CamelFolder *folder,
 						 GCancellable *cancellable,
 						 GError **error);
+	gboolean 	(*purge_message_cache_sync)	
+						(CamelFolder *folder,
+						 gchar *start_uid,
+						 gchar *end_uid,
+						 GCancellable *cancellable,
+						 GError **error);	
 	gboolean	(*refresh_info_sync)	(CamelFolder *folder,
 						 GCancellable *cancellable,
 						 GError **error);
@@ -270,6 +291,17 @@ struct _CamelFolderClass {
 	gboolean	(*expunge_finish)	(CamelFolder *folder,
 						 GAsyncResult *result,
 						 GError **error);
+	void 		(*fetch_messages)	(CamelFolder *folder,
+						 CamelFetchType type,
+						 int limit,
+						 gint io_priority,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+	gboolean	(*fetch_messages_finish)	
+						(CamelFolder *folder,
+						 GAsyncResult *result,
+						 GError **error);	
 	void		(*get_message)		(CamelFolder *folder,
 						 const gchar *message_uid,
 						 gint io_priority,
@@ -290,6 +322,18 @@ struct _CamelFolderClass {
 						(CamelFolder *folder,
 						 GAsyncResult *result,
 						 GError **error);
+	void 		(*purge_message_cache)	(CamelFolder *folder,
+						 gchar *start_uid,
+						 gchar *end_uid,
+						 gint io_priority,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+	gboolean	(*purge_message_cache_finish)	
+						(CamelFolder *folder,
+						 GAsyncResult *result,
+						 GError **error);	
+
 	void		(*refresh_info)		(CamelFolder *folder,
 						 gint io_priority,
 						 GCancellable *cancellable,
@@ -498,6 +542,23 @@ void		camel_folder_expunge		(CamelFolder *folder,
 gboolean	camel_folder_expunge_finish	(CamelFolder *folder,
 						 GAsyncResult *result,
 						 GError **error);
+gboolean 	camel_folder_fetch_messages_sync
+						(CamelFolder *folder,
+						 CamelFetchType type,
+						 int limit,
+						 GCancellable *cancellable,
+						 GError **error);
+void	 	camel_folder_fetch_messages	(CamelFolder *folder,
+						 CamelFetchType type,
+						 int limit,
+						 gint io_priority,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+gboolean 	camel_folder_fetch_messages_finish
+						(CamelFolder *folder,
+						 GAsyncResult *result,
+						 GError **error);
 CamelMimeMessage *
 		camel_folder_get_message_sync	(CamelFolder *folder,
 						 const gchar *message_uid,
@@ -528,6 +589,24 @@ CamelFolderQuotaInfo *
 						(CamelFolder *folder,
 						 GAsyncResult *result,
 						 GError **error);
+gboolean 	camel_folder_purge_message_cache_sync
+						(CamelFolder *folder,
+						 gchar *start_uid,
+						 gchar *end_uid,
+						 GCancellable *cancellable,
+						 GError **error);
+void	 	camel_folder_purge_message_cache
+						(CamelFolder *folder,
+						 gchar *start_uid,
+						 gchar *end_uid,
+						 gint io_priority,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+gboolean 	camel_folder_purge_message_cache_finish
+						(CamelFolder *folder,
+						 GAsyncResult *result,
+						 GError **error);
 gboolean	camel_folder_refresh_info_sync	(CamelFolder *folder,
 						 GCancellable *cancellable,
 						 GError **error);



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