summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@novell.com>2004-11-01 19:58:38 +0000
committerJeffrey Stedfast <fejj@src.gnome.org>2004-11-01 19:58:38 +0000
commit519d7577b2c57aa34fb326cc4a7c0f129e9958d0 (patch)
tree2a3c9e44db2f02e947d156eb2abf60e46bc8c0e5
parent0baa8a423d3ef6467336d436466d3bd3b156256b (diff)
downloadevolution-data-server-519d7577b2c57aa34fb326cc4a7c0f129e9958d0.tar.gz
Remove expunged messages from the cache.
2004-11-01 Jeffrey Stedfast <fejj@novell.com> * providers/imap4/camel-imap4-summary.c (camel_imap4_summary_expunge): Remove expunged messages from the cache. (camel_imap4_summary_set_uidvalidity): Clear the cache if the UIDVALIDITY has changed. * providers/imap4/camel-imap4-folder.c (imap4_get_message): If the message exists in the cache, use that rather than fetching it from the server and cache messages fetched from the server for later use. (camel_imap4_folder_finalize): Unref the cache if non-NULL. (camel_imap4_folder_new): Create the CamelDataCache.
-rw-r--r--camel/ChangeLog13
-rw-r--r--camel/providers/imap4/camel-imap4-folder.c54
-rw-r--r--camel/providers/imap4/camel-imap4-folder.h2
-rw-r--r--camel/providers/imap4/camel-imap4-store.c3
-rw-r--r--camel/providers/imap4/camel-imap4-summary.c7
5 files changed, 71 insertions, 8 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 498dd064d..14e178699 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,18 @@
2004-11-01 Jeffrey Stedfast <fejj@novell.com>
+ * providers/imap4/camel-imap4-summary.c
+ (camel_imap4_summary_expunge): Remove expunged messages from the
+ cache.
+ (camel_imap4_summary_set_uidvalidity): Clear the cache if the
+ UIDVALIDITY has changed.
+
+ * providers/imap4/camel-imap4-folder.c (imap4_get_message): If the
+ message exists in the cache, use that rather than fetching it from
+ the server and cache messages fetched from the server for later
+ use.
+ (camel_imap4_folder_finalize): Unref the cache if non-NULL.
+ (camel_imap4_folder_new): Create the CamelDataCache.
+
* providers/imap4/camel-imap4-store.c (imap4_create_folder): Cache
the folder-info on the summary if successful.
(imap4_delete_folder): Un-cache the folder-info from the summary.
diff --git a/camel/providers/imap4/camel-imap4-folder.c b/camel/providers/imap4/camel-imap4-folder.c
index 1eadc9890..1b48ef723 100644
--- a/camel/providers/imap4/camel-imap4-folder.c
+++ b/camel/providers/imap4/camel-imap4-folder.c
@@ -129,6 +129,9 @@ camel_imap4_folder_finalize (CamelObject *object)
camel_object_unref (folder->search);
+ if (folder->cache)
+ camel_object_unref (folder->cache);
+
g_free (folder->utf7_name);
g_free (folder->cachedir);
}
@@ -237,6 +240,8 @@ camel_imap4_folder_new (CamelStore *store, const char *full_name, CamelException
imap_folder->cachedir = imap_store_build_filename (store, folder->full_name);
camel_mkdir (imap_folder->cachedir, 0777);
+ imap_folder->cache = camel_data_cache_new (imap_folder->cachedir, 0, NULL);
+
path = imap_get_summary_filename (imap_folder->cachedir);
camel_folder_summary_set_filename (folder->summary, path);
g_free (path);
@@ -635,16 +640,47 @@ static CamelMimeMessage *
imap4_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
+ CamelSession *session = ((CamelService *) folder->parent_store)->session;
+ CamelIMAP4Folder *imap_folder = (CamelIMAP4Folder *) folder;
CamelMimeMessage *message = NULL;
+ CamelStream *stream, *cache;
CamelIMAP4Command *ic;
- CamelStream *stream;
int id;
CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
- /* FIXME: try to pull the message from the cache first. if
- * that fails and we are offline, we're done. else do the
- * following code */
+ if (imap_folder->cache && (stream = camel_data_cache_get (imap_folder->cache, "cache", uid, ex))) {
+ message = camel_mime_message_new ();
+
+ if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) {
+ if (errno == EINTR) {
+ CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
+ camel_exception_setv (ex, CAMEL_EXCEPTION_USER_CANCEL, _("User cancelled"));
+ camel_object_unref (message);
+ camel_object_unref (stream);
+ return NULL;
+ } else {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get message %s: %s"),
+ uid, g_strerror (errno));
+ camel_object_unref (message);
+ message = NULL;
+ }
+ }
+
+ camel_object_unref (stream);
+ }
+
+ if (message != NULL) {
+ CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
+ return message;
+ }
+
+ if (!camel_session_is_online (session)) {
+ CAMEL_SERVICE_UNLOCK (folder->parent_store, connect_lock);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("This message is not available in offline mode."));
+ return NULL;
+ }
/* Note: While some hard-core IMAP extremists are probably
* going to flame me for fetching entire messages here, it's
@@ -682,6 +718,16 @@ imap4_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
camel_stream_reset (stream);
message = camel_mime_message_new ();
camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream);
+ camel_stream_reset (stream);
+
+ /* cache the message locally */
+ if (imap_folder->cache && (cache = camel_data_cache_add (imap_folder->cache, "cache", uid, NULL))) {
+ if (camel_stream_write_to_stream (stream, cache) == -1
+ || camel_stream_flush (cache) == -1)
+ camel_data_cache_remove (imap_folder->cache, "cache", uid, NULL);
+ camel_object_unref (cache);
+ }
+
break;
case CAMEL_IMAP4_RESULT_NO:
/* FIXME: would be good to save the NO reason into the err message */
diff --git a/camel/providers/imap4/camel-imap4-folder.h b/camel/providers/imap4/camel-imap4-folder.h
index a5d3ce3cc..c4936dfab 100644
--- a/camel/providers/imap4/camel-imap4-folder.h
+++ b/camel/providers/imap4/camel-imap4-folder.h
@@ -23,6 +23,7 @@
#include <camel/camel-store.h>
#include <camel/camel-folder.h>
+#include <camel/camel-data-cache.h>
#ifdef __cplusplus
extern "C" {
@@ -43,6 +44,7 @@ struct _CamelIMAP4Folder {
CamelFolder parent_object;
CamelFolderSearch *search;
+ CamelDataCache *cache;
char *cachedir;
char *utf7_name;
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
index ba86ac7de..6d0bf79b6 100644
--- a/camel/providers/imap4/camel-imap4-store.c
+++ b/camel/providers/imap4/camel-imap4-store.c
@@ -1165,10 +1165,7 @@ imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelE
CAMEL_SERVICE_LOCK (store, connect_lock);
if (!camel_session_is_online (session) || engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
- fprintf (stderr, "****************************************************\n");
- fprintf (stderr, "*** Getting folder info in disconnected state... ***\n");
fi = camel_imap4_store_summary_get_folder_info (((CamelIMAP4Store *) store)->summary, top, flags);
- fprintf (stderr, "****************************************************\n");
if (fi == NULL && camel_session_is_online (session)) {
/* folder info hasn't yet been cached and the store hasn't been
* connected yet, but the network is available so we can connect
diff --git a/camel/providers/imap4/camel-imap4-summary.c b/camel/providers/imap4/camel-imap4-summary.c
index f89462427..2ed1e490d 100644
--- a/camel/providers/imap4/camel-imap4-summary.c
+++ b/camel/providers/imap4/camel-imap4-summary.c
@@ -1161,6 +1161,7 @@ camel_imap4_summary_set_uidvalidity (CamelFolderSummary *summary, guint32 uidval
}
camel_folder_summary_clear (summary);
+ camel_data_cache_clear (((CamelIMAP4Folder *) imap4_summary->folder)->cache, "cache", NULL);
if (camel_folder_change_info_changed (changes))
camel_object_trigger_event (imap4_summary->folder, "folder_changed", changes);
@@ -1177,6 +1178,7 @@ camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid)
CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
CamelFolderChangeInfo *changes;
CamelMessageInfo *info;
+ const char *uid;
g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary));
@@ -1186,8 +1188,11 @@ camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid)
imap4_summary->exists--;
+ uid = camel_message_info_uid (info);
+ camel_data_cache_remove (((CamelIMAP4Folder *) imap4_summary->folder)->cache, "cache", uid, NULL);
+
changes = camel_folder_change_info_new ();
- camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
+ camel_folder_change_info_remove_uid (changes, uid);
camel_folder_summary_info_free (summary, info);
camel_folder_summary_remove_index (summary, seqid);