aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/local/camel-local-folder.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/local/camel-local-folder.c')
-rw-r--r--camel/providers/local/camel-local-folder.c263
1 files changed, 44 insertions, 219 deletions
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index 931c95a114..116a10ea7d 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -42,6 +42,8 @@
#include "camel-mime-filter-from.h"
#include "camel-exception.h"
+#include "camel-local-private.h"
+
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
static CamelFolderClass *parent_class = NULL;
@@ -55,30 +57,11 @@ static int local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *
static void local_unlock(CamelLocalFolder *lf);
static void local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex);
-static gint local_get_message_count(CamelFolder *folder);
-static gint local_get_unread_message_count(CamelFolder *folder);
-
-static GPtrArray *local_get_uids(CamelFolder *folder);
-static GPtrArray *local_get_summary(CamelFolder *folder);
-#if 0
-static void local_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, CamelException *ex);
-static CamelMimeMessage *local_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
-#endif
static void local_expunge(CamelFolder *folder, CamelException *ex);
-static const CamelMessageInfo *local_get_message_info(CamelFolder *folder, const char *uid);
-
static GPtrArray *local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
static void local_search_free(CamelFolder *folder, GPtrArray * result);
-static guint32 local_get_message_flags(CamelFolder *folder, const char *uid);
-static void local_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
-static gboolean local_get_message_user_flag(CamelFolder *folder, const char *uid, const char *name);
-static void local_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value);
-static const char *local_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name);
-static void local_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
-
-
static void local_finalize(CamelObject * object);
static void
@@ -92,26 +75,11 @@ camel_local_folder_class_init(CamelLocalFolderClass * camel_local_folder_class)
/* virtual method overload */
camel_folder_class->sync = local_sync;
- camel_folder_class->get_message_count = local_get_message_count;
- camel_folder_class->get_unread_message_count = local_get_unread_message_count;
- camel_folder_class->get_uids = local_get_uids;
- camel_folder_class->free_uids = camel_folder_free_deep;
- camel_folder_class->get_summary = local_get_summary;
- camel_folder_class->free_summary = camel_folder_free_nop;
camel_folder_class->expunge = local_expunge;
camel_folder_class->search_by_expression = local_search_by_expression;
camel_folder_class->search_free = local_search_free;
- camel_folder_class->get_message_info = local_get_message_info;
-
- camel_folder_class->get_message_flags = local_get_message_flags;
- camel_folder_class->set_message_flags = local_set_message_flags;
- camel_folder_class->get_message_user_flag = local_get_message_user_flag;
- camel_folder_class->set_message_user_flag = local_set_message_user_flag;
- camel_folder_class->get_message_user_tag = local_get_message_user_tag;
- camel_folder_class->set_message_user_tag = local_set_message_user_tag;
-
camel_local_folder_class->lock = local_lock;
camel_local_folder_class->unlock = local_unlock;
}
@@ -129,18 +97,25 @@ local_init(gpointer object, gpointer klass)
CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT |
CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_USER;
- local_folder->summary = NULL;
+ folder->summary = NULL;
local_folder->search = NULL;
+
+ local_folder->priv = g_malloc0(sizeof(*local_folder->priv));
+#ifdef ENABLE_THREADS
+ local_folder->priv->search_lock = g_mutex_new();
+#endif
}
static void
local_finalize(CamelObject * object)
{
CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(object);
+ CamelFolder *folder = (CamelFolder *)object;
- if (local_folder->summary) {
- camel_local_summary_sync(local_folder->summary, FALSE, local_folder->changes, NULL);
- camel_object_unref((CamelObject *)local_folder->summary);
+ if (folder->summary) {
+ camel_local_summary_sync((CamelLocalSummary *)folder->summary, FALSE, local_folder->changes, NULL);
+ camel_object_unref((CamelObject *)folder->summary);
+ folder->summary = NULL;
}
if (local_folder->search) {
@@ -160,6 +135,11 @@ local_finalize(CamelObject * object)
g_free(local_folder->index_path);
camel_folder_change_info_free(local_folder->changes);
+
+#ifdef ENABLE_THREADS
+ g_mutex_free(local_folder->priv->search_lock);
+#endif
+ g_free(local_folder->priv);
}
CamelType camel_local_folder_get_type(void)
@@ -228,8 +208,8 @@ camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store, con
lf->flags = flags;
- lf->summary = CLOCALF_CLASS(lf)->create_summary(lf->summary_path, lf->folder_path, lf->index);
- if (camel_local_summary_load(lf->summary, forceindex, ex) == -1) {
+ folder->summary = (CamelFolderSummary *)CLOCALF_CLASS(lf)->create_summary(lf->summary_path, lf->folder_path, lf->index);
+ if (camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, ex) == -1) {
camel_object_unref (CAMEL_OBJECT (folder));
return NULL;
}
@@ -289,7 +269,7 @@ local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex)
return;
/* if sync fails, we'll pass it up on exit through ex */
- camel_local_summary_sync(lf->summary, expunge, lf->changes, ex);
+ camel_local_summary_sync((CamelLocalSummary *)folder->summary, expunge, lf->changes, ex);
camel_local_folder_unlock(lf);
if (camel_folder_change_info_changed(lf->changes)) {
@@ -300,8 +280,8 @@ local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex)
/* force save of metadata */
if (lf->index)
ibex_save(lf->index);
- if (lf->summary)
- camel_folder_summary_save(CAMEL_FOLDER_SUMMARY(lf->summary));
+ if (folder->summary)
+ camel_folder_summary_save(folder->summary);
}
static void
@@ -310,203 +290,48 @@ local_expunge(CamelFolder *folder, CamelException *ex)
d(printf("expunge\n"));
/* Just do a sync with expunge, serves the same purpose */
- camel_folder_sync(folder, TRUE, ex);
-}
-
-/*
- The following functions all work off the summary, so the default operations provided
- in camel-local-folder will suffice for all subclasses. They may want to
- snoop various operations to ensure the status remains synced, or just wait
- for the sync operation
-*/
-static gint
-local_get_message_count(CamelFolder *folder)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
-
- g_return_val_if_fail(local_folder->summary != NULL, -1);
-
- return camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(local_folder->summary));
-}
-
-static gint
-local_get_unread_message_count(CamelFolder *folder)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
- CamelMessageInfo *info;
- GPtrArray *infolist;
- gint i, max, count = 0;
-
- g_return_val_if_fail(local_folder->summary != NULL, -1);
-
- max = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(local_folder->summary));
- if (max == -1)
- return -1;
-
- infolist = local_get_summary(folder);
-
- for (i = 0; i < infolist->len; i++) {
- info = (CamelMessageInfo *) g_ptr_array_index(infolist, i);
- if (!(info->flags & CAMEL_MESSAGE_SEEN))
- count++;
- }
-
- return count;
+ /* call the callback directly, to avoid locking problems */
+ CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->sync(folder, TRUE, ex);
}
static GPtrArray *
-local_get_uids(CamelFolder *folder)
-{
- GPtrArray *array;
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
- int i, count;
-
- count = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(local_folder->summary));
- array = g_ptr_array_new();
- g_ptr_array_set_size(array, count);
- for (i = 0; i < count; i++) {
- CamelMessageInfo *info = camel_folder_summary_index(CAMEL_FOLDER_SUMMARY(local_folder->summary), i);
-
- array->pdata[i] = g_strdup(camel_message_info_uid(info));
- }
-
- return array;
-}
-
-GPtrArray *
-local_get_summary(CamelFolder *folder)
+local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
{
CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
+ GPtrArray *summary, *matches;
- return CAMEL_FOLDER_SUMMARY(local_folder->summary)->messages;
-}
-
-/* get a single message info, by uid */
-static const CamelMessageInfo *
-local_get_message_info(CamelFolder *folder, const char *uid)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
+ /* NOTE: could get away without the search lock by creating a new
+ search object each time */
- return camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(local_folder->summary), uid);
-}
-
-static GPtrArray *
-local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
+ CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock);
- if (local_folder->search == NULL) {
+ if (local_folder->search == NULL)
local_folder->search = camel_folder_search_new();
- }
camel_folder_search_set_folder(local_folder->search, folder);
- if (local_folder->summary) {
- /* FIXME: dont access summary array directly? */
- camel_folder_search_set_summary(local_folder->search,
- CAMEL_FOLDER_SUMMARY(local_folder->summary)->messages);
- }
-
camel_folder_search_set_body_index(local_folder->search, local_folder->index);
+ summary = camel_folder_get_summary(folder);
+ camel_folder_search_set_summary(local_folder->search, summary);
- return camel_folder_search_execute_expression(local_folder->search, expression, ex);
-}
-
-static void
-local_search_free(CamelFolder *folder, GPtrArray * result)
-{
- CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
-
- camel_folder_search_free_result(local_folder->search, result);
-}
-
-static guint32
-local_get_message_flags(CamelFolder *folder, const char *uid)
-{
- CamelMessageInfo *info;
- CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder);
-
- info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid);
- g_return_val_if_fail(info != NULL, 0);
-
- return info->flags;
-}
-
-static void
-local_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
- CamelMessageInfo *info;
- CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder);
- guint32 new;
-
- info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid);
- g_return_if_fail(info != NULL);
-
- new = (info->flags & ~flags) | (set & flags);
- if (new == info->flags)
- return;
-
- info->flags = new | CAMEL_MESSAGE_FOLDER_FLAGGED;
- camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary));
-
- camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid);
-}
+ matches = camel_folder_search_execute_expression(local_folder->search, expression, ex);
-static gboolean
-local_get_message_user_flag(CamelFolder *folder, const char *uid, const char *name)
-{
- CamelMessageInfo *info;
- CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder);
+ CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
- info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid);
- g_return_val_if_fail(info != NULL, FALSE);
+ camel_folder_free_summary(folder, summary);
- return camel_flag_get(&info->user_flags, name);
+ return matches;
}
static void
-local_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value)
-{
- CamelMessageInfo *info;
- CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder);
-
- info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid);
- g_return_if_fail(info != NULL);
-
- if (!camel_flag_set(&info->user_flags, name, value))
- return;
-
- info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
- camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary));
- camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid);
-}
-
-static const char *
-local_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name)
-{
- CamelMessageInfo *info;
- CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder);
-
- info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid);
- g_return_val_if_fail(info != NULL, FALSE);
-
- return camel_tag_get(&info->user_tags, name);
-}
-
-static void
-local_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value)
+local_search_free(CamelFolder *folder, GPtrArray * result)
{
- CamelMessageInfo *info;
- CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder);
+ CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
- info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid);
- g_return_if_fail(info != NULL);
+ /* we need to lock this free because of the way search_free_result works */
+ /* FIXME: put the lock inside search_free_result */
+ CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock);
- if (!camel_tag_set(&info->user_tags, name, value))
- return;
+ camel_folder_search_free_result(local_folder->search, result);
- info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
- camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary));
- camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid);
+ CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
}
-
-