From 6f92ee281a80475438ac7e2e1260a69b7c64539c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 24 Apr 2009 20:22:23 +0200 Subject: [PATCH] Define camel_folder_cmp_uids to compare UIDs properly ** Part of fix for bug #563954 Subclass for some providers. --- camel/ChangeLog | 19 ++++++++ camel/camel-db.c | 4 +- camel/camel-db.h | 4 +- camel/camel-folder-summary.c | 26 +++++++++- camel/camel-folder-summary.h | 2 + camel/camel-folder.c | 55 ++++++++++++++++------ camel/camel-folder.h | 2 + camel/providers/groupwise/ChangeLog | 8 ++++ camel/providers/groupwise/camel-groupwise-folder.c | 11 ++++- camel/providers/local/ChangeLog | 14 ++++++ camel/providers/local/camel-maildir-folder.c | 47 ++++++++++++++++++ camel/providers/local/camel-mbox-folder.c | 43 +++++++++++++++++ camel/providers/local/camel-mh-summary.c | 27 +---------- 13 files changed, 217 insertions(+), 45 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 90c30d6..fe422ed 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,24 @@ 2009-04-24 Milan Crha + ** Part of fix for bug #563954 + + * camel-folder.h: (camel_folder_cmp_uids), (struct CamelFolder): + * camel-folder.c: (cmp_uids), (camel_folder_class_init), + (camel_folder_cmp_uids), (cmp_array_uids), (sort_uids): + Define camel_folder_cmp_uids to compare UIDs properly. + * camel-folder-summary.h: (camel_folder_summary_ensure_infos_loaded): + * camel-folder-summary.c: (camel_folder_summary_ensure_infos_loaded): + Define new function. + + * camel-db.h: (camel_db_get_folder_uids), + (camel_db_get_folder_uids_flags): + * camel-db.c: (camel_db_get_folder_uids), + (camel_db_get_folder_uids_flags): + * camel-folder-summary.c: (camel_folder_summary_load_from_db): + Functions prototype cleanup. + +2009-04-24 Milan Crha + ** Part of fix for bug #571206 * camel-vee-folder.c: (camel_vee_folder_add_folder), (vee_sync): diff --git a/camel/camel-db.c b/camel/camel-db.c index af28366..4d38fce 100644 --- a/camel/camel-db.c +++ b/camel/camel-db.c @@ -901,7 +901,7 @@ read_uids_flags_callback (void *ref, int ncol, char ** cols, char ** name) } int -camel_db_get_folder_uids_flags (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex) +camel_db_get_folder_uids_flags (CamelDB *db, const char *folder_name, const char *sort_by, const char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex) { GPtrArray *uids = summary; GPtrArray *flags = g_ptr_array_new (); @@ -946,7 +946,7 @@ read_uids_callback (void *ref, int ncol, char ** cols, char ** name) } int -camel_db_get_folder_uids (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *array, CamelException *ex) +camel_db_get_folder_uids (CamelDB *db, const char *folder_name, const char *sort_by, const char *collate, GPtrArray *array, CamelException *ex) { char *sel_query; int ret; diff --git a/camel/camel-db.h b/camel/camel-db.h index 3eaeeb1..577713d 100644 --- a/camel/camel-db.h +++ b/camel/camel-db.h @@ -162,8 +162,8 @@ GPtrArray * camel_db_get_vuids_from_vfolder (CamelDB *db, char *folder_name, cha int camel_db_add_to_vfolder (CamelDB *db, char *folder_name, char *vuid, CamelException *ex); int camel_db_add_to_vfolder_transaction (CamelDB *db, char *folder_name, char *vuid, CamelException *ex); -int camel_db_get_folder_uids (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *array, CamelException *ex); -int camel_db_get_folder_uids_flags (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex); +int camel_db_get_folder_uids (CamelDB *db, const char *folder_name, const char *sort_by, const char *collate, GPtrArray *array, CamelException *ex); +int camel_db_get_folder_uids_flags (CamelDB *db, const char *folder_name, const char *sort_by, const char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex); GPtrArray * camel_db_get_folder_junk_uids (CamelDB *db, char *folder_name, CamelException *ex); GPtrArray * camel_db_get_folder_deleted_uids (CamelDB *db, char *folder_name, CamelException *ex); diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index eda5713..23be990 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -924,6 +924,30 @@ camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex) return ret == 0 ? 0 : -1; } +/** + * camel_folder_summary_ensure_infos_loaded: + * @s: #CamelFolderSummary object + * @at_least: How many infos already loaded are considered fine to not reload all of them. + * Use -1 to force reload of all of them if not in memory yet. + * @ex: #CamelException object. + * + * Loads all infos into memory, if they are not yet. + **/ +void +camel_folder_summary_ensure_infos_loaded (CamelFolderSummary *s, int at_least, CamelException *ex) +{ + guint loaded, known; + + g_return_if_fail (s != NULL); + + loaded = camel_folder_summary_cache_size (s); + known = camel_folder_summary_count (s); + + if ((at_least == -1 && known != loaded) || at_least > loaded) { + camel_folder_summary_reload_from_db (s, ex); + } +} + static void camel_folder_summary_dump (CamelFolderSummary *s) { @@ -963,7 +987,7 @@ camel_folder_summary_load_from_db (CamelFolderSummary *s, CamelException *ex) folder_name = s->folder->full_name; cdb = s->folder->parent_store->cdb_r; - ret = camel_db_get_folder_uids_flags (cdb, folder_name, (char *)s->sort_by, (char *)s->collate, s->uids, p->flag_cache, ex); + ret = camel_db_get_folder_uids_flags (cdb, folder_name, s->sort_by, s->collate, s->uids, p->flag_cache, ex); /* camel_folder_summary_dump (s); */ #if 0 diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index dac18f1..d6f120e 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -365,6 +365,8 @@ GPtrArray * camel_folder_summary_get_changed (CamelFolderSummary *s); int camel_folder_summary_cache_size (CamelFolderSummary *s); /* reload the summary at any required point if required */ int camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex); +/* ensures all CamelMessagesInfos loaded in memory */ +void camel_folder_summary_ensure_infos_loaded (CamelFolderSummary *s, int at_least, CamelException *ex); /* insert mi to summary */ void camel_folder_summary_insert (CamelFolderSummary *s, CamelMessageInfo *info, gboolean load); diff --git a/camel/camel-folder.c b/camel/camel-folder.c index 66a1e74..200ba6b 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -91,6 +91,7 @@ static GPtrArray *get_uids (CamelFolder *folder); static GPtrArray *get_uncached_uids (CamelFolder *, GPtrArray * uids, CamelException *); static void free_uids (CamelFolder *folder, GPtrArray *array); +static gint cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2); static void sort_uids (CamelFolder *folder, GPtrArray *uids); static GPtrArray *get_summary (CamelFolder *folder); @@ -155,6 +156,7 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->get_uids = get_uids; camel_folder_class->get_uncached_uids = get_uncached_uids; camel_folder_class->free_uids = free_uids; + camel_folder_class->cmp_uids = cmp_uids; camel_folder_class->sort_uids = sort_uids; camel_folder_class->get_summary = get_summary; camel_folder_class->free_summary = free_summary; @@ -1281,27 +1283,52 @@ camel_folder_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelExce return CF_CLASS (folder)->get_uncached_uids(folder, uids, ex); } +static gint +cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2) +{ + g_return_val_if_fail (uid1 != NULL, 0); + g_return_val_if_fail (uid2 != NULL, 0); -static int -uidcmp (const void *v0, const void *v1) + return strtoul (uid1, NULL, 10) - strtoul (uid2, NULL, 10); +} + +/** + * camel_folder_cmp_uids: + * @folder: a #CamelFolder object + * @uid1: The first uid. + * @uid2: the second uid. + * + * Compares two uids. The return value meaning is the same as in any other compare function. + * + * Note that the default compare function expects a decimal number at the beginning of a uid, + * thus if provider uses different uid values, then it should subclass this function. + **/ +gint +camel_folder_cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2) { - const char *str0 = *(const char **) v0; - const char *str1 = *(const char **) v1; - guint32 uid0 = strtoul (str0, NULL, 10); - guint32 uid1 = strtoul (str1, NULL, 10); - - if (uid0 < uid1) - return -1; - else if (uid0 == uid1) - return 0; - else - return 1; + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0); + g_return_val_if_fail (uid1 != NULL, 0); + g_return_val_if_fail (uid2 != NULL, 0); + + return CF_CLASS (folder)->cmp_uids (folder, uid1, uid2); +} + +static gint +cmp_array_uids (gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *uid1 = *(const char **) a; + const char *uid2 = *(const char **) b; + CamelFolder *folder = user_data; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0); + + return camel_folder_cmp_uids (folder, uid1, uid2); } static void sort_uids (CamelFolder *folder, GPtrArray *uids) { - qsort (uids->pdata, uids->len, sizeof (void *), uidcmp); + g_qsort_with_data (uids->pdata, uids->len, sizeof (void *), cmp_array_uids, folder); } diff --git a/camel/camel-folder.h b/camel/camel-folder.h index adbbe4a..2eacd12 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -178,6 +178,7 @@ typedef struct { void (*free_uids) (CamelFolder *folder, GPtrArray *array); + gint (* cmp_uids) (CamelFolder *folder, const char *uid1, const char *uid2); void (* sort_uids) (CamelFolder *folder, GPtrArray *uids); GPtrArray * (*get_summary) (CamelFolder *folder); @@ -320,6 +321,7 @@ void camel_folder_free_uids (CamelFolder *folder, GPtrArray * camel_folder_get_uncached_uids (CamelFolder *, GPtrArray * uids, CamelException *); +gint camel_folder_cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2); void camel_folder_sort_uids (CamelFolder *folder, GPtrArray *uids); diff --git a/camel/providers/groupwise/ChangeLog b/camel/providers/groupwise/ChangeLog index 93b7baa..9ade1be 100644 --- a/camel/providers/groupwise/ChangeLog +++ b/camel/providers/groupwise/ChangeLog @@ -1,3 +1,11 @@ +2009-04-24 Milan Crha + + ** Part of fix for bug #563954 + + * camel-groupwise-folder.c: (groupwise_cmp_uids), + (camel_groupwise_folder_class_init): + Define its own compare function for UIDs. + 2009-04-13 Chenthill Palanisamy diff --git a/camel/providers/groupwise/camel-groupwise-folder.c b/camel/providers/groupwise/camel-groupwise-folder.c index 83164b7..6cb31a5 100644 --- a/camel/providers/groupwise/camel-groupwise-folder.c +++ b/camel/providers/groupwise/camel-groupwise-folder.c @@ -98,7 +98,6 @@ static CamelMimeMessage *groupwise_folder_item_to_msg ( CamelFolder *folder, EGw static char* groupwise_get_filename (CamelFolder *folder, const char *uid, CamelException *ex); static const char *get_from_from_org (EGwItemOrganizer *org); - #define d(x) const char * GET_ITEM_VIEW_WITH_CACHE = "peek default recipient threading attachments subject status priority startDate created delivered size recurrenceKey message notification"; @@ -2516,6 +2515,15 @@ groupwise_expunge (CamelFolder *folder, CamelException *ex) camel_folder_change_info_free (changes); } +static gint +groupwise_cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2) +{ + g_return_val_if_fail (uid1 != NULL, 0); + g_return_val_if_fail (uid2 != NULL, 0); + + return strcmp (uid1, uid2); +} + static void camel_groupwise_folder_class_init (CamelGroupwiseFolderClass *camel_groupwise_folder_class) { @@ -2529,6 +2537,7 @@ camel_groupwise_folder_class_init (CamelGroupwiseFolderClass *camel_groupwise_fo camel_folder_class->rename = groupwise_folder_rename; camel_folder_class->search_by_expression = groupwise_folder_search_by_expression; camel_folder_class->count_by_expression = groupwise_folder_count_by_expression; + camel_folder_class->cmp_uids = groupwise_cmp_uids; camel_folder_class->search_by_uids = groupwise_folder_search_by_uids; camel_folder_class->search_free = groupwise_folder_search_free; camel_folder_class->append_message = groupwise_append_message; diff --git a/camel/providers/local/ChangeLog b/camel/providers/local/ChangeLog index 8da29ab..fdec3d9 100644 --- a/camel/providers/local/ChangeLog +++ b/camel/providers/local/ChangeLog @@ -1,5 +1,19 @@ 2009-04-24 Milan Crha + ** Part of fix for bug #563954 + + * camel-mh-summary.c: (sort_uid_cmp), (camel_mh_summary_new): + Little cleanup. + * camel-mbox-folder.c: (mbox_cmp_uids), (mbox_sort_uids), + (camel_mbox_folder_class_init): + * camel-maildir-folder.c: (maildir_cmp_uids), + (maildir_sort_uids), (camel_maildir_folder_class_init): + Subslass sort and compare uids functions to compare based on the + position in the mbox file or a received date for maildir, instead + of uid values. + +2009-04-24 Milan Crha + ** Fix for bug #571206 * camel-maildir-summary.c: (message_info_new_from_header): diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c index 39eb9be..a290227 100644 --- a/camel/providers/local/camel-maildir-folder.c +++ b/camel/providers/local/camel-maildir-folder.c @@ -57,6 +57,8 @@ static CamelLocalSummary *maildir_create_summary(CamelLocalFolder *lf, const cha static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, char **appended_uid, CamelException * ex); static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex); static char* maildir_get_filename (CamelFolder *folder, const char *uid, CamelException *ex); +static gint maildir_cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2); +static void maildir_sort_uids (CamelFolder *folder, GPtrArray *uids); static void maildir_finalize(CamelObject * object); @@ -104,6 +106,8 @@ static void camel_maildir_folder_class_init(CamelObjectClass * camel_maildir_fol camel_folder_class->append_message = maildir_append_message; camel_folder_class->get_message = maildir_get_message; camel_folder_class->get_filename = maildir_get_filename; + camel_folder_class->cmp_uids = maildir_cmp_uids; + camel_folder_class->sort_uids = maildir_sort_uids; lclass->create_summary = maildir_create_summary; } @@ -307,3 +311,46 @@ maildir_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex return message; } + +static gint +maildir_cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2) +{ + CamelMessageInfo *a, *b; + time_t tma, tmb; + + g_return_val_if_fail (folder != NULL, 0); + g_return_val_if_fail (folder->summary != NULL, 0); + + a = camel_folder_summary_uid (folder->summary, uid1); + b = camel_folder_summary_uid (folder->summary, uid2); + + g_return_val_if_fail (a != NULL, 0); + g_return_val_if_fail (b != NULL, 0); + + tma = camel_message_info_date_received (a); + tmb = camel_message_info_date_received (b); + + return tma < tmb ? -1 : tma == tmb ? 0 : 1; +} + +static void +maildir_sort_uids (CamelFolder *folder, GPtrArray *uids) +{ + g_return_if_fail (parent_class != NULL); + g_return_if_fail (folder != NULL); + + if (uids && uids->len > 1) { + CamelException ex; + + camel_exception_init (&ex); + + camel_folder_summary_ensure_infos_loaded (folder->summary, uids->len, &ex); + + if (camel_exception_is_set (&ex)) + g_warning ("%s: %s", G_STRFUNC, camel_exception_get_description (&ex)); + + camel_exception_clear (&ex); + } + + CAMEL_FOLDER_CLASS (parent_class)->sort_uids (folder, uids); +} diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c index 2eb31a5..005844e 100644 --- a/camel/providers/local/camel-mbox-folder.c +++ b/camel/providers/local/camel-mbox-folder.c @@ -69,6 +69,8 @@ static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex); static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index); static char* mbox_get_filename (CamelFolder *folder, const char *uid, CamelException *ex); +static gint mbox_cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2); +static void mbox_sort_uids (CamelFolder *folder, GPtrArray *uids); static void mbox_finalise(CamelObject * object); @@ -86,6 +88,8 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class) camel_folder_class->append_message = mbox_append_message; camel_folder_class->get_message = mbox_get_message; camel_folder_class->get_filename = mbox_get_filename; + camel_folder_class->cmp_uids = mbox_cmp_uids; + camel_folder_class->sort_uids = mbox_sort_uids; lclass->create_summary = mbox_create_summary; lclass->lock = mbox_lock; @@ -478,3 +482,42 @@ fail: return message; } + +static gint +mbox_cmp_uids (CamelFolder *folder, const char *uid1, const char *uid2) +{ + CamelMboxMessageInfo *a, *b; + + g_return_val_if_fail (folder != NULL, 0); + g_return_val_if_fail (folder->summary != NULL, 0); + + a = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid1); + b = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid2); + + g_return_val_if_fail (a != NULL, 0); + g_return_val_if_fail (b != NULL, 0); + + return a->frompos < b->frompos ? -1 : a->frompos == b->frompos ? 0 : 1; +} + +static void +mbox_sort_uids (CamelFolder *folder, GPtrArray *uids) +{ + g_return_if_fail (parent_class != NULL); + g_return_if_fail (folder != NULL); + + if (uids && uids->len > 1) { + CamelException ex; + + camel_exception_init (&ex); + + camel_folder_summary_ensure_infos_loaded (folder->summary, uids->len, &ex); + + if (camel_exception_is_set (&ex)) + g_warning ("%s: %s", G_STRFUNC, camel_exception_get_description (&ex)); + + camel_exception_clear (&ex); + } + + CAMEL_FOLDER_CLASS (parent_class)->sort_uids (folder, uids); +} diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c index 9154aab..891b38c 100644 --- a/camel/providers/local/camel-mh-summary.c +++ b/camel/providers/local/camel-mh-summary.c @@ -40,6 +40,7 @@ #include "camel-private.h" #include "camel-mh-summary.h" +#include "camel-local-private.h" #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ @@ -115,30 +116,6 @@ camel_mh_summary_finalise(CamelObject *obj) g_free(o->priv); } -static int -sort_uid_cmp (void *enc, int len1, void * data1, int len2, void *data2) -{ - static char *sa1=NULL, *sa2=NULL; - static int l1=0, l2=0; - int a1, a2; - - if (l1 < len1+1) { - sa1 = g_realloc (sa1, len1+1); - l1 = len1+1; - } - if (l2 < len2+1) { - sa2 = g_realloc (sa2, len2+1); - l2 = len2+1; - } - strncpy (sa1, data1, len1);sa1[len1] = 0; - strncpy (sa2, data2, len2);sa2[len2] = 0; - - a1 = strtoul (sa1, NULL, 10); - a2 = strtoul (sa2, NULL, 10); - - return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0; -} - /** * camel_mh_summary_new: * @@ -152,7 +129,7 @@ CamelMhSummary *camel_mh_summary_new(struct _CamelFolder *folder, const char *fi ((CamelFolderSummary *)o)->folder = folder; if (folder) { - camel_db_set_collate (folder->parent_store->cdb_r, "uid", "mh_uid_sort", (CamelDBCollate)sort_uid_cmp); + camel_db_set_collate (folder->parent_store->cdb_r, "uid", "mh_uid_sort", (CamelDBCollate)camel_local_frompos_sort); ((CamelFolderSummary *)o)->sort_by = "uid"; ((CamelFolderSummary *)o)->collate = "mh_uid_sort"; } -- 2.7.4