summaryrefslogtreecommitdiff
path: root/camel/camel-folder-summary.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-folder-summary.c')
-rw-r--r--camel/camel-folder-summary.c166
1 files changed, 102 insertions, 64 deletions
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 879b185aa..83977815a 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -66,6 +66,7 @@
/* Make 5 minutes as default cache drop */
#define SUMMARY_CACHE_DROP 300
+#define log_time(x) if(camel_debug("logtime")) x;
static pthread_mutex_t info_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -128,7 +129,7 @@ static int content_info_save(CamelFolderSummary *, FILE *, CamelMessag
static void content_info_free(CamelFolderSummary *, CamelMessageContentInfo *);
static int save_message_infos_to_db (CamelFolderSummary *s, CamelException *ex);
-static int camel_read_mir_callback (void * ref, int ncol, char ** cols, char ** name);
+int camel_read_mir_callback (void * ref, int ncol, char ** cols, char ** name);
static char *next_uid_string(CamelFolderSummary *s);
@@ -183,6 +184,9 @@ camel_folder_summary_init (CamelFolderSummary *s)
s->meta_summary->uid_len = 20;
s->cache_load_time = 0;
s->timeout_handle = 0;
+
+ s->sort_col = NULL;
+ s->collate = NULL;
}
static void free_o_name(void *key, void *value, void *data)
@@ -492,12 +496,38 @@ camel_folder_summary_array(CamelFolderSummary *s)
return res;
}
+CamelMessageInfo *
+camel_folder_summary_peek_info (CamelFolderSummary *s, const char *uid)
+{
+ CamelMessageInfo *info = g_hash_table_lookup(s->loaded_infos, uid);
+
+ if (info)
+ camel_message_info_ref(info);
+ return info;
+}
+
struct _db_pass_data {
CamelFolderSummary *summary;
gboolean double_ref;
gboolean add; /* or just insert to hashtable */
};
+int
+camel_folder_summary_load_info_from_db(CamelFolderSummary *s, char *folder_key, const char *uid, gboolean vuid, CamelException *ex)
+{
+ struct _db_pass_data data;
+ int ret;
+ CamelDB *cdb = s->folder->parent_store->cdb;
+
+ data.summary = s;
+ data.double_ref = TRUE;
+ data.add = FALSE;
+
+ ret = camel_db_read_message_info_record_with_uid (cdb, folder_key, uid, &data, camel_read_mir_callback, vuid, &ex);
+
+ return ret;
+}
+
static CamelMessageInfo *
message_info_from_uid (CamelFolderSummary *s, const char *uid)
{
@@ -510,33 +540,20 @@ message_info_from_uid (CamelFolderSummary *s, const char *uid)
info = g_hash_table_lookup (s->loaded_infos, uid);
if (!info) {
- CamelDB *cdb;
CamelException ex;// May be this should come from the caller
char *folder_name;
- struct _db_pass_data data;
d(printf ("\ncamel_folder_summary_uid called \n"));
camel_exception_init (&ex);
s->flags &= ~CAMEL_SUMMARY_DIRTY;
- folder_name = s->folder->full_name;
- cdb = s->folder->cdb;
+ folder_name = s->folder->folder_key;
CAMEL_SUMMARY_UNLOCK(s, ref_lock);
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
- data.summary = s;
- data.double_ref = TRUE;
- data.add = FALSE;
+ camel_folder_summary_load_info_from_db (s, folder_name, uid, FALSE, &ex);
-
- ret = camel_db_read_message_info_record_with_uid (cdb, folder_name, uid, &data, camel_read_mir_callback, &ex);
- if (ret != 0) {
- // if (strcmp (folder_name, "UNMATCHED"))
- //g_warning ("Unable to read uid %s from folder %s: %s", uid, folder_name, camel_exception_get_description(&ex));
-
- return NULL;
- }
CAMEL_SUMMARY_LOCK(s, summary_lock);
CAMEL_SUMMARY_LOCK(s, ref_lock);
@@ -842,10 +859,23 @@ int
camel_folder_summary_cache_size (CamelFolderSummary *s)
{
/* FIXME[disk-summary] this is a timely hack. fix it well */
- if (!CAMEL_IS_VEE_FOLDER(s->folder))
- return g_hash_table_size (s->loaded_infos);
- else
- return s->uids->len;
+ return g_hash_table_size (s->loaded_infos);
+}
+
+int
+reload_from_db (CamelFolderSummary *s, CamelException *ex)
+{
+ int ret;
+ struct _db_pass_data data;
+ CamelDB *cdb = s->folder->parent_store->cdb;
+ char *folder_name = s->folder->folder_key;
+
+ data.summary = s;
+ data.double_ref = FALSE;
+ data.add = FALSE;
+ ret = camel_db_read_message_info_records (cdb, folder_name, (gpointer)&data, camel_read_mir_callback, NULL, ex);
+
+ return ret;
}
int
@@ -858,23 +888,19 @@ camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex)
/* FIXME[disk-summary] baseclass this, and vfolders we may have to
* load better. */
+ gboolean virtual = CAMEL_IS_VEE_SUMMARY(s);
d(printf ("\ncamel_folder_summary_reload_from_db called \n"));
- folder_name = s->folder->full_name;
- cdb = s->folder->cdb;
- /* FIXME FOR SANKAR: No need to pass the address of summary here. */
- data.summary = s;
- data.double_ref = FALSE;
- data.add = FALSE;
- ret = camel_db_read_message_info_records (cdb, folder_name, (gpointer)&data, camel_read_mir_callback, NULL);
+
+ ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->reload_from_db(s, ex);
s->cache_load_time = time (NULL);
/* FIXME[disk-summary] LRU please and not timeouts */
if (!g_getenv("CAMEL_FREE_INFOS") && !s->timeout_handle)
s->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
- printf("Triggering summary_reloaded on %s %p\n", s->folder->full_name, s);
+ d(printf("Triggering summary_reloaded on %s %p\n", s->folder->full_name, s));
camel_object_trigger_event(s, "summary_reloaded", s);
return ret == 0 ? 0 : -1;
}
@@ -906,19 +932,12 @@ camel_folder_summary_load_from_db (CamelFolderSummary *s, CamelException *ex)
if (ret)
return ret;
- folder_name = s->folder->full_name;
- cdb = s->folder->cdb;
+ folder_name = s->folder->folder_key;
+ cdb = s->folder->parent_store->cdb;
- ret = camel_db_get_folder_uids (cdb, folder_name, s->uids, ex);
+ ret = camel_db_get_folder_uids (cdb, folder_name, s->sort_col, s->collate, s->uids, ex);
/* camel_folder_summary_dump (s); */
-#if 0
- data.summary = s;
- data.add = TRUE;
- data.double_ref = FALSE;
- ret = camel_db_read_message_info_records (cdb, folder_name, (gpointer) &data, camel_read_mir_callback, ex);
-#endif
-
return ret == 0 ? 0 : -1;
}
@@ -931,6 +950,10 @@ mir_from_cols (CamelMIRecord *mir, CamelFolderSummary *s, int ncol, char ** cols
if ( !strcmp (name [i], "uid") )
mir->uid = (char *) camel_pstring_strdup (cols [i]);
+ if ( !strcmp (name [i], "vuid") )
+ mir->uid = (char *) camel_pstring_strdup (cols [i]);
+ else if ( !strcmp (name [i], "uid") )
+ mir->folder_key = (char *) camel_pstring_strdup (cols [i]);
else if ( !strcmp (name [i], "flags") )
mir->flags = cols [i] ? strtoul (cols [i], NULL, 10) : 0;
else if ( !strcmp (name [i], "read") )
@@ -981,7 +1004,7 @@ mir_from_cols (CamelMIRecord *mir, CamelFolderSummary *s, int ncol, char ** cols
}
}
-static int
+int
camel_read_mir_callback (void * ref, int ncol, char ** cols, char ** name)
{
struct _db_pass_data *data = (struct _db_pass_data *) ref;
@@ -1115,7 +1138,6 @@ error:
}
-
int
camel_folder_summary_migrate_infos(CamelFolderSummary *s)
{
@@ -1124,7 +1146,7 @@ camel_folder_summary_migrate_infos(CamelFolderSummary *s)
CamelMessageInfo *mi;
CamelMessageInfoBase *info;
int ret = 0;
- CamelDB *cdb = s->folder->cdb;
+ CamelDB *cdb = s->folder->parent_store->cdb_write;
CamelFIRecord *record;
CamelException ex;
@@ -1198,12 +1220,14 @@ camel_folder_summary_migrate_infos(CamelFolderSummary *s)
if (!record) {
return -1;
}
-
+ record->account_url = camel_service_get_url((CamelService *)s->folder->parent_store);
+ record->folder_key = camel_folder_get_hash (s->folder);
ret = camel_db_write_folder_info_record (cdb, record, &ex);
g_free (record->bdata);
+ g_free (record->account_url);
g_free (record);
-
+
if (ret != 0) {
return -1;
}
@@ -1272,8 +1296,8 @@ save_to_db_cb (gpointer key, gpointer value, gpointer data)
CamelException *ex = (CamelException *)data;
CamelMessageInfoBase *mi = (CamelMessageInfoBase *)value;
CamelFolderSummary *s = (CamelFolderSummary *)mi->summary;
- char *folder_name = s->folder->full_name;
- CamelDB *cdb = s->folder->cdb;
+ char *folder_name = s->folder->folder_key;
+ CamelDB *cdb = s->folder->parent_store->cdb_write;
CamelMIRecord *mir;
if (!mi->dirty)
@@ -1304,10 +1328,10 @@ save_to_db_cb (gpointer key, gpointer value, gpointer data)
static int
save_message_infos_to_db (CamelFolderSummary *s, CamelException *ex)
{
- CamelDB *cdb = s->folder->cdb;
+ CamelDB *cdb = s->folder->parent_store->cdb_write;
char *folder_name;
- folder_name = s->folder->full_name;
+ folder_name = s->folder->folder_key;
if (camel_db_prepare_message_info_table (cdb, folder_name, ex) != 0) {
return -1;
}
@@ -1324,7 +1348,7 @@ save_message_infos_to_db (CamelFolderSummary *s, CamelException *ex)
int
camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex)
{
- CamelDB *cdb = s->folder->cdb;
+ CamelDB *cdb = s->folder->parent_store->cdb_write;
CamelFIRecord *record;
int ret, count;
@@ -1340,6 +1364,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex)
return camel_folder_summary_header_save_to_db (s, ex);
printf("Saving %d/%d dirty records of %s\n", count, g_hash_table_size (s->loaded_infos), s->folder->full_name);
+ log_time(printf("Summary save to db for %s: start %ld\n", s->folder ? s->folder->full_name : "NULL", time(NULL)));
camel_db_begin_transaction (cdb, ex);
@@ -1352,16 +1377,19 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex)
}
camel_db_end_transaction (cdb, ex);
+ log_time(printf("Summary save to db for %s: end-summary %ld\n", s->folder ? s->folder->full_name : "NULL", time(NULL)));
record = (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_to_db (s, ex));
if (!record) {
s->flags |= CAMEL_SUMMARY_DIRTY;
return -1;
}
-
+ record->account_url = camel_service_get_url((CamelService *)s->folder->parent_store);
+ record->folder_key = camel_folder_get_hash (s->folder);
camel_db_begin_transaction (cdb, ex);
ret = camel_db_write_folder_info_record (cdb, record, ex);
g_free (record->bdata);
+ g_free (record->account_url);
g_free (record);
if (ret != 0) {
@@ -1371,6 +1399,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex)
}
camel_db_end_transaction (cdb, ex);
+ log_time(printf("Summary save to db for %s: end-header %ld\n", s->folder ? s->folder->full_name : "NULL", time(NULL)));
return ret;
}
@@ -1378,7 +1407,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex)
int
camel_folder_summary_header_save_to_db (CamelFolderSummary *s, CamelException *ex)
{
- CamelDB *cdb = s->folder->cdb;
+ CamelDB *cdb = s->folder->parent_store->cdb_write;
CamelFIRecord *record;
int ret;
@@ -1388,10 +1417,12 @@ camel_folder_summary_header_save_to_db (CamelFolderSummary *s, CamelException *e
if (!record) {
return -1;
}
-
+ record->account_url = camel_service_get_url((CamelService *)s->folder->parent_store);
+ record->folder_key = camel_folder_get_hash (s->folder);
camel_db_begin_transaction (cdb, ex);
ret = camel_db_write_folder_info_record (cdb, record, ex);
g_free (record->bdata);
+ g_free (record->account_url);
g_free (record);
if (ret != 0) {
@@ -1553,6 +1584,7 @@ camel_folder_summary_header_load_from_db (CamelFolderSummary *s, CamelStore *sto
CamelDB *cdb;
CamelFIRecord *record;
int ret = 0;
+ char *url = camel_service_get_url((CamelService *)store);
d(printf ("\ncamel_folder_summary_load_from_db called \n"));
s->flags &= ~CAMEL_SUMMARY_DIRTY;
@@ -1560,7 +1592,7 @@ camel_folder_summary_header_load_from_db (CamelFolderSummary *s, CamelStore *sto
cdb = store->cdb;
record = g_new0 (CamelFIRecord, 1);
- camel_db_read_folder_info_record (cdb, folder_name, &record, ex);
+ camel_db_read_folder_info_record (cdb, url, folder_name, &record, ex);
if (record) {
if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_from_db (s, record) == -1)
@@ -1572,6 +1604,7 @@ camel_folder_summary_header_load_from_db (CamelFolderSummary *s, CamelStore *sto
g_free (record->folder_name);
g_free (record->bdata);
g_free (record);
+ g_free (url);
return ret;
}
@@ -2065,12 +2098,13 @@ camel_folder_summary_clear_db (CamelFolderSummary *s)
{
CamelDB *cdb;
char *folder_name;
+ char *url = camel_service_get_url(s->folder->parent_store);
d(printf ("\ncamel_folder_summary_load_from_db called \n"));
s->flags &= ~CAMEL_SUMMARY_DIRTY;
- folder_name = s->folder->full_name;
- cdb = s->folder->cdb;
+ folder_name = s->folder->folder_key;
+ cdb = s->folder->parent_store->cdb_write;
CAMEL_SUMMARY_LOCK(s, summary_lock);
if (camel_folder_summary_count(s) == 0) {
@@ -2087,7 +2121,8 @@ camel_folder_summary_clear_db (CamelFolderSummary *s)
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
- camel_db_clear_folder_summary (cdb, folder_name, NULL);
+ camel_db_clear_folder_summary (cdb, url, s->folder->full_name, folder_name, NULL);
+ g_free (url);
}
@@ -2137,7 +2172,7 @@ camel_folder_summary_remove (CamelFolderSummary *s, CamelMessageInfo *info)
s->meta_summary->msg_expunged = TRUE;
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
- if (!ret && camel_db_delete_uid (s->folder->cdb, s->folder->full_name, camel_message_info_uid(info), NULL) != 0)
+ if (!ret && camel_db_delete_uid (s->folder->parent_store->cdb_write, s->folder->folder_key, camel_message_info_uid(info), NULL) != 0)
return ;
camel_message_info_free(info);
@@ -2174,7 +2209,7 @@ camel_folder_summary_remove_uid(CamelFolderSummary *s, const char *uid)
CAMEL_SUMMARY_UNLOCK(s, ref_lock);
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
- if (!ret && camel_db_delete_uid (s->folder->cdb, s->folder->full_name, tmpid, NULL) != 0) {
+ if (!ret && camel_db_delete_uid (s->folder->parent_store->cdb_write, s->folder->folder_key, tmpid, NULL) != 0) {
g_free(tmpid);
return ;
}
@@ -2298,8 +2333,8 @@ camel_folder_summary_remove_range (CamelFolderSummary *s, int start, int end)
}
camel_exception_init (&ex);
- folder_name = s->folder->full_name;
- cdb = s->folder->cdb;
+ folder_name = s->folder->folder_key;
+ cdb = s->folder->parent_store->cdb_write;
/* FIXME[disk-summary] lifecycle of infos should be checked.
* Add should add to db and del should del to db. Sync only
@@ -2615,13 +2650,14 @@ summary_header_to_db (CamelFolderSummary *s, CamelException *ex)
CamelDB *db;
char *table_name;
- db = s->folder->cdb;
+ /* Though we gonna read, we would do it while saving. Lets not block the thread. */
+ db = s->folder->parent_store->cdb_write;
//table_name = safe_table (camel_file_util_safe_filename (s->folder->full_name));
- table_name = s->folder->full_name;
+ table_name = s->folder->folder_key;
io(printf("Savining header to db\n"));
- record->folder_name = table_name;
+ record->folder_name = s->folder->full_name;
/* we always write out the current version */
record->version = CAMEL_FOLDER_SUMMARY_VERSION;
@@ -2999,7 +3035,7 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
/* Extract User flags/labels */
part = record->labels;
- if (part) {
+ if (part && *part) {
label = part;
for (i=0;part[i];i++) {
@@ -3147,6 +3183,7 @@ message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info)
record->replied = mi->flags & CAMEL_MESSAGE_ANSWERED ? 1 : 0;
record->important = mi->flags & CAMEL_MESSAGE_FLAGGED ? 1 : 0;
record->junk = mi->flags & CAMEL_MESSAGE_JUNK ? 1 : 0;
+ record->dirty = mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED ? 1 : 0;
record->attachment = mi->flags & CAMEL_MESSAGE_ATTACHMENTS ? 1 : 0;
record->size = mi->size;
@@ -4789,7 +4826,8 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *klass)
klass->message_info_free = message_info_free;
klass->message_info_clone = message_info_clone;
klass->message_info_from_uid = message_info_from_uid;
-
+ klass->reload_from_db = reload_from_db;
+
klass->content_info_new_from_header = content_info_new_from_header;
klass->content_info_new_from_parser = content_info_new_from_parser;
klass->content_info_new_from_message = content_info_new_from_message;