evolution-data-server r9643 - in branches/gnome-2-24/camel: . providers/groupwise providers/imap providers/local providers/nntp



Author: sragavan
Date: Mon Oct  6 10:46:16 2008
New Revision: 9643
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9643&view=rev

Log:
2008-10-06  Srinivasa Ragavan  <sragavan novell com>

	** Fixes lots of bugs and breaks ABI

	* camel/camel-db.c: Added new APIs and support for cloning handles.
	* camel/camel-db.h:
	* camel/camel-folder-search.c:
	* camel/camel-folder-search.h:
	* camel/camel-folder-summary.c:
	* camel/camel-folder-summary.h:
	* camel/camel-folder.c:
	* camel/camel-folder.h:
	* camel/camel-search-sql-sexp.c:
	* camel/camel-store.c: Adds two handles to sqlite
	* camel/camel-store.h:
	* camel/camel-vee-folder.c:
	* camel/camel-vee-summary.c:
	* camel/camel-vtrash-folder.c:
	* camel/providers/groupwise/camel-groupwise-folder.c:
	* camel/providers/imap/camel-imap-folder.c:
	* camel/providers/imap/camel-imap-store.c:
	* camel/providers/imap/camel-imap-summary.c:
	* camel/providers/local/camel-local-folder.c:
	* camel/providers/local/camel-local-store.c:
	* camel/providers/local/camel-maildir-summary.c:
	* camel/providers/local/camel-mbox-summary.c:
	* camel/providers/local/camel-mh-summary.c:
	* camel/providers/local/camel-spool-summary.c:
	* camel/providers/nntp/camel-nntp-folder.c:



Modified:
   branches/gnome-2-24/camel/ChangeLog
   branches/gnome-2-24/camel/camel-db.c
   branches/gnome-2-24/camel/camel-db.h
   branches/gnome-2-24/camel/camel-folder-search.c
   branches/gnome-2-24/camel/camel-folder-search.h
   branches/gnome-2-24/camel/camel-folder-summary.c
   branches/gnome-2-24/camel/camel-folder-summary.h
   branches/gnome-2-24/camel/camel-folder.c
   branches/gnome-2-24/camel/camel-folder.h
   branches/gnome-2-24/camel/camel-search-sql-sexp.c
   branches/gnome-2-24/camel/camel-store.c
   branches/gnome-2-24/camel/camel-store.h
   branches/gnome-2-24/camel/camel-vee-folder.c
   branches/gnome-2-24/camel/camel-vee-summary.c
   branches/gnome-2-24/camel/camel-vtrash-folder.c
   branches/gnome-2-24/camel/providers/groupwise/camel-groupwise-folder.c
   branches/gnome-2-24/camel/providers/imap/camel-imap-folder.c
   branches/gnome-2-24/camel/providers/imap/camel-imap-store.c
   branches/gnome-2-24/camel/providers/imap/camel-imap-summary.c
   branches/gnome-2-24/camel/providers/local/camel-local-folder.c
   branches/gnome-2-24/camel/providers/local/camel-local-store.c
   branches/gnome-2-24/camel/providers/local/camel-maildir-summary.c
   branches/gnome-2-24/camel/providers/local/camel-mbox-summary.c
   branches/gnome-2-24/camel/providers/local/camel-mh-summary.c
   branches/gnome-2-24/camel/providers/local/camel-spool-summary.c
   branches/gnome-2-24/camel/providers/nntp/camel-nntp-folder.c

Modified: branches/gnome-2-24/camel/camel-db.c
==============================================================================
--- branches/gnome-2-24/camel/camel-db.c	(original)
+++ branches/gnome-2-24/camel/camel-db.c	Mon Oct  6 10:46:16 2008
@@ -36,17 +36,14 @@
 
 #include "camel-debug.h"
 
-#ifdef CAMEL_DB_DEBUG
-/* Enable d(x) if you want */
-#define d(x)
-/* Yeah it leaks, so fix it while debugging */
-#define START(stmt) 	g_print ("\n===========\nDB SQL operation [%s] started\n", stmt); cdb->timer = g_timer_new ();
-#define END 	g_timer_stop (cdb->timer); g_print ("DB Operation ended. Time Taken : %f\n###########\n", g_timer_elapsed (cdb->timer, NULL));
-#else
 #define d(x) if (camel_debug("sqlite")) x
-#define START(x)
-#define END
-#endif
+#define START(stmt) 	if (camel_debug("dbtime")) { g_print ("\n===========\nDB SQL operation [%s] started\n", stmt); if (!cdb->priv->timer) { cdb->priv->timer = g_timer_new (); } else { g_timer_reset(cdb->priv->timer);} }
+#define END 	if (camel_debug("dbtime")) { g_timer_stop (cdb->priv->timer); g_print ("DB Operation ended. Time Taken : %f\n###########\n", g_timer_elapsed (cdb->priv->timer, NULL)); }
+
+struct _CamelDBPrivate {
+	GTimer *timer;
+	char *file_name;
+};
 
 static GStaticRecMutex trans_lock = G_STATIC_REC_MUTEX_INIT;	
 
@@ -115,9 +112,9 @@
 	cdb = g_new (CamelDB, 1);
 	cdb->db = db;
 	cdb->lock = g_mutex_new ();
-	/* These will be written once the Summary takes control of the CDB. */
-	cdb->sort_by = NULL;
-	cdb->collate = NULL;
+	cdb->priv = g_new(CamelDBPrivate, 1);
+	cdb->priv->file_name = g_strdup(path);
+	cdb->priv->timer = NULL;
 	d(g_print ("\nDatabase succesfully opened  \n"));
 
 	/* Which is big / costlier ? A Stack frame or a pointer */
@@ -135,6 +132,12 @@
 	return cdb;
 }
 
+CamelDB *
+camel_db_clone (CamelDB *cdb, CamelException *ex)
+{
+	return camel_db_open(cdb->priv->file_name, ex);
+}
+
 void
 camel_db_close (CamelDB *cdb)
 {
@@ -155,9 +158,6 @@
 			return 0;
 
 		g_mutex_lock (cdb->lock);
-		cdb->sort_by = col;
-		cdb->collate = collate;
-		cdb->collate_cb = func;
 		d(g_print("Creating Collation %s on %s with %p\n", collate, col, func));
 		if (collate && func)
 			ret = sqlite3_create_collation(cdb->db, collate, SQLITE_UTF8,  NULL, func);
@@ -192,7 +192,6 @@
 		return -1;
 	g_static_rec_mutex_lock (&trans_lock);
 
-	d(g_print ("\n\aBEGIN TRANSACTION \n\a"));
 	g_mutex_lock (cdb->lock);
 	return (cdb_sql_exec (cdb->db, "BEGIN", ex));
 }
@@ -204,7 +203,6 @@
 	if (!cdb)
 		return -1;
 
-	d(g_print ("\nCOMMIT TRANSACTION \n"));
 	START("COMMIT");
 	ret = cdb_sql_exec (cdb->db, "COMMIT", ex);
 	END;
@@ -221,7 +219,6 @@
 {
 	int ret;
 	
-	d(g_print ("\nABORT TRANSACTION \n"));
 	ret = cdb_sql_exec (cdb->db, "ROLLBACK", ex);
 	g_mutex_unlock (cdb->lock);
 	g_static_rec_mutex_unlock (&trans_lock);	
@@ -236,8 +233,6 @@
 	if (!cdb)
 		return -1;
 
-	d(g_print("Adding the following query to transaction: %s\n", stmt));
-
 	return (cdb_sql_exec (cdb->db, stmt, ex));
 }
 
@@ -256,11 +251,9 @@
 	if (ret)
 		goto end;
 
-	d(g_print ("\nBEGIN Transaction\n"));
 
 	while (qry_list) {
 		query = qry_list->data;
-		d(g_print ("\nInside Transaction: [%s] \n", query));
 		ret = cdb_sql_exec (cdb->db, query, ex);
 		if (ret)
 			goto end;
@@ -271,7 +264,6 @@
 	END;
 end:
 	g_mutex_unlock (cdb->lock);
-	d(g_print ("\nTransaction Result: [%d] \n", ret));
 	return ret;
 }
 
@@ -289,7 +281,7 @@
   	return 0;
 }
 
-static int
+int
 camel_db_count_message_info (CamelDB *cdb, const char *query, guint32 *count, CamelException *ex)
 {
 	int ret = -1;
@@ -583,12 +575,12 @@
 }
 
 int
-camel_db_get_folder_uids (CamelDB *db, char *folder_name, GPtrArray *array, CamelException *ex)
+camel_db_get_folder_uids (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *array, CamelException *ex)
 {
 	 char *sel_query;
 	 int ret;
 
-	 sel_query = sqlite3_mprintf("SELECT uid FROM %Q%s%s%s%s", folder_name, db->sort_by ? " order by " : "", db->sort_by ? db->sort_by: "", (db->sort_by && db->collate) ? " collate " : "", (db->sort_by && db->collate) ? db->collate : "");
+	 sel_query = sqlite3_mprintf("SELECT uid FROM %Q%s%s%s%s", folder_name, sort_by ? " order by " : "", sort_by ? sort_by: "", (sort_by && collate) ? " collate " : "", (sort_by && collate) ? collate : "");
 
 	 ret = camel_db_select (db, sel_query, read_uids_callback, array, ex);
 	 sqlite3_free (sel_query);
@@ -754,10 +746,12 @@
 	char *del_query;
 	char *ins_query;
 
+	/* NB: UGLIEST Hack. We can't modify the schema now. We are using msg_security (an unsed one to notify of FLAGGED/Dirty infos */
+
 	ins_query = sqlite3_mprintf ("INSERT INTO %Q VALUES (%Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %ld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q )", 
 			folder_name, record->uid, record->flags,
 			record->msg_type, record->read, record->deleted, record->replied,
-			record->important, record->junk, record->attachment, record->msg_security,
+			record->important, record->junk, record->attachment, record->dirty,
 			record->size, record->dsent, record->dreceived,
 			record->subject, record->from, record->to,
 			record->cc, record->mlist, record->followup_flag,

Modified: branches/gnome-2-24/camel/camel-db.h
==============================================================================
--- branches/gnome-2-24/camel/camel-db.h	(original)
+++ branches/gnome-2-24/camel/camel-db.h	Mon Oct  6 10:46:16 2008
@@ -8,17 +8,14 @@
 
 #include "camel-exception.h"
 
+typedef struct _CamelDBPrivate CamelDBPrivate;
+
 typedef int(*CamelDBCollate)(void*,int,const void*,int,const void*);
 
 struct _CamelDB {
 	sqlite3 *db;
 	GMutex *lock;
-	const char *sort_by;
-	const char *collate;
-	CamelDBCollate collate_cb;
-#ifdef CAMEL_DB_DEBUG 	
-	GTimer *timer;
-#endif	
+	CamelDBPrivate *priv;
 };
 
 #define CAMEL_DB_FREE_CACHE_SIZE 2 * 1024 * 1024
@@ -59,7 +56,7 @@
 	char *uid;
 	guint32 flags;
 	guint32 msg_type;
-	guint32 msg_security;
+	guint32 dirty;
 	gboolean read;
 	gboolean deleted;
 	gboolean replied;
@@ -107,6 +104,7 @@
 
 
 CamelDB * camel_db_open (const char *path, CamelException *ex);
+CamelDB * camel_db_clone (CamelDB *cdb, CamelException *ex);
 void camel_db_close (CamelDB *cdb);
 int camel_db_command (CamelDB *cdb, const char *stmt, CamelException *ex);
 
@@ -145,7 +143,7 @@
 int camel_db_count_visible_unread_message_info (CamelDB *cdb, const char *table_name, guint32 *count, CamelException *ex);
 
 int camel_db_count_junk_not_deleted_message_info (CamelDB *cdb, const char *table_name, guint32 *count, CamelException *ex);
-
+int camel_db_count_message_info (CamelDB *cdb, const char *query, guint32 *count, CamelException *ex);
 void camel_db_camel_mir_free (CamelMIRecord *record);
 
 int camel_db_create_vfolder (CamelDB *db, const char *folder_name, CamelException *ex);
@@ -156,7 +154,7 @@
 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, GPtrArray *array, CamelException *ex);
+int camel_db_get_folder_uids (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *array, 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);

Modified: branches/gnome-2-24/camel/camel-folder-search.c
==============================================================================
--- branches/gnome-2-24/camel/camel-folder-search.c	(original)
+++ branches/gnome-2-24/camel/camel-folder-search.c	Mon Oct  6 10:46:16 2008
@@ -393,6 +393,133 @@
 }
 
 /**
+ * camel_folder_search_count:
+ * @search: 
+ * @expr: 
+ * @uids: to search against, NULL for all uid's.
+ * @ex: 
+ * 
+ * Run a search.  Search must have had Folder already set on it, and
+ * it must implement summaries.
+ * 
+ * Return value: Number of messages that match the query.
+ **/
+
+guint32
+camel_folder_search_count(CamelFolderSearch *search, const char *expr, CamelException *ex)
+{
+	ESExpResult *r;
+	GPtrArray *summary_set;
+	int i;
+	CamelDB *cdb;
+	char *sql_query, *tmp, *tmp1;
+	GHashTable *results;
+	guint32 count = 0;
+
+	struct _CamelFolderSearchPrivate *p = _PRIVATE(search);
+
+	g_assert(search->folder);
+	
+	p->ex = ex;
+
+	/* We route body-contains search and uid search through memory and not via db. */
+	if (strstr((const char *) expr, "body-contains")) {
+		/* setup our search list only contains those we're interested in */
+		search->summary = camel_folder_get_summary(search->folder);
+
+		summary_set = search->summary;
+
+		/* only re-parse if the search has changed */
+		if (search->last_search == NULL
+		    || strcmp(search->last_search, expr)) {
+			e_sexp_input_text(search->sexp, expr, strlen(expr));
+			if (e_sexp_parse(search->sexp) == -1) {
+				camel_exception_setv(ex, 1, _("Cannot parse search expression: %s:\n%s"), e_sexp_error(search->sexp), expr);
+				goto fail;
+			}
+
+			g_free(search->last_search);
+			search->last_search = g_strdup(expr);
+		}
+		r = e_sexp_eval(search->sexp);
+		if (r == NULL) {
+			if (!camel_exception_is_set(ex))
+				camel_exception_setv(ex, 1, _("Error executing search expression: %s:\n%s"), e_sexp_error(search->sexp), expr);
+			goto fail;
+		}
+
+		/* now create a folder summary to return?? */
+		if (r->type == ESEXP_RES_ARRAY_PTR) {
+			d(printf("got result\n"));
+	
+			/* reorder result in summary order */
+			results = g_hash_table_new(g_str_hash, g_str_equal);
+			for (i=0;i<r->value.ptrarray->len;i++) {
+				d(printf("adding match: %s\n", (char *)g_ptr_array_index(r->value.ptrarray, i)));
+				g_hash_table_insert(results, g_ptr_array_index(r->value.ptrarray, i), GINT_TO_POINTER (1));
+			}
+	
+			for (i=0;i<summary_set->len;i++) {
+				char *uid = g_ptr_array_index(summary_set, i);
+				if (g_hash_table_lookup(results, uid))
+					count++;
+			}
+			g_hash_table_destroy(results);
+		}
+
+		e_sexp_result_free(search->sexp, r);
+
+	} else {
+		/* Sync the db, so that we search the db for changes */
+		camel_folder_summary_save_to_db (search->folder->summary, ex);
+	
+		dd(printf ("sexp is : [%s]\n", expr));
+		if (g_getenv("SQL_SEARCH_OLD"))
+			sql_query = camel_sexp_to_sql (expr);
+		else
+			sql_query = camel_sexp_to_sql_sexp (expr);
+		tmp1 = camel_db_sqlize_string(search->folder->full_name);
+		tmp = g_strdup_printf ("SELECT COUNT (*) FROM %s %s %s", tmp1, sql_query ? "WHERE":"", sql_query?sql_query:"");
+		camel_db_free_sqlized_string (tmp1);
+		g_free (sql_query);
+		dd(printf("Equivalent sql %s\n", tmp));
+	
+		cdb = (CamelDB *) (search->folder->parent_store->cdb_r);
+		camel_db_count_message_info  (cdb, tmp, &count, ex);
+		if (ex && camel_exception_is_set(ex)) {
+			const char *exception = camel_exception_get_description (ex);
+			if (strncmp(exception, "no such table", 13) == 0) {
+				g_warning ("Error during searching %s: %s\n", tmp, exception);
+				camel_exception_clear (ex); /* Suppress no such table */
+			}
+		}
+		g_free (tmp);
+
+	}
+
+fail:
+	/* these might be allocated by match-threads */
+	if (p->threads)
+		camel_folder_thread_messages_unref(p->threads);
+	if (p->threads_hash)
+		g_hash_table_destroy(p->threads_hash);
+	if (search->summary_set)
+		g_ptr_array_free(search->summary_set, TRUE);
+	if (search->summary)
+		camel_folder_free_summary(search->folder, search->summary);
+
+	p->threads = NULL;
+	p->threads_hash = NULL;
+	search->folder = NULL;
+	search->summary = NULL;
+	search->summary_set = NULL;
+	search->current = NULL;
+	search->body_index = NULL;
+
+	return count;
+}
+
+/**
  * camel_folder_search_search:
  * @search: 
  * @expr: 
@@ -497,7 +624,7 @@
 		dd(printf("Equivalent sql %s\n", tmp));
 	
 		matches = g_ptr_array_new();
-		cdb = (CamelDB *) (search->folder->cdb);
+		cdb = (CamelDB *) (search->folder->parent_store->cdb_r);
 		camel_db_select (cdb, tmp, (CamelDBSelectCB) read_uid_callback, matches, ex);
 		if (ex && camel_exception_is_set(ex)) {
 			const char *exception = camel_exception_get_description (ex);

Modified: branches/gnome-2-24/camel/camel-folder-search.h
==============================================================================
--- branches/gnome-2-24/camel/camel-folder-search.h	(original)
+++ branches/gnome-2-24/camel/camel-folder-search.h	Mon Oct  6 10:46:16 2008
@@ -126,6 +126,7 @@
 GPtrArray *camel_folder_search_execute_expression(CamelFolderSearch *search, const char *expr, CamelException *ex);
 
 GPtrArray *camel_folder_search_search(CamelFolderSearch *search, const char *expr, GPtrArray *uids, CamelException *ex);
+guint32 camel_folder_search_count(CamelFolderSearch *search, const char *expr, CamelException *ex);
 void camel_folder_search_free_result(CamelFolderSearch *search, GPtrArray *);
 
 G_END_DECLS

Modified: branches/gnome-2-24/camel/camel-folder-summary.c
==============================================================================
--- branches/gnome-2-24/camel/camel-folder-summary.c	(original)
+++ branches/gnome-2-24/camel/camel-folder-summary.c	Mon Oct  6 10:46:16 2008
@@ -491,6 +491,16 @@
 	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;
@@ -510,7 +520,7 @@
 
 	if (!info) {
 		CamelDB *cdb;
-		CamelException ex;// May be this should come from the caller 
+		CamelException ex;
 		char *folder_name;
 		struct _db_pass_data data;
 		
@@ -519,7 +529,7 @@
 		s->flags &= ~CAMEL_SUMMARY_DIRTY;
 
 		folder_name = s->folder->full_name;
-		cdb = s->folder->cdb;
+		cdb = s->folder->parent_store->cdb_r;
 		
 		CAMEL_SUMMARY_UNLOCK(s, ref_lock);
 		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
@@ -530,12 +540,9 @@
 
 	
 		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));
-			
+		if (ret != 0)
 			return NULL;
-		}
+		
 		CAMEL_SUMMARY_LOCK(s, summary_lock);
 		CAMEL_SUMMARY_LOCK(s, ref_lock);
 
@@ -547,8 +554,7 @@
 
 			/* Makes no sense now as the exception is local as of now. FIXME: Pass exception from caller */
 			camel_exception_set (&ex, CAMEL_EXCEPTION_SYSTEM, _(errmsg));
-			// if (strcmp (folder_name, "UNMATCHED"))			
-			g_warning ("No uid[%s] exists in %s\n", uid, folder_name);
+			d(g_warning ("No uid[%s] exists in %s\n", uid, folder_name));
 			camel_exception_clear (&ex);
 			g_free (errmsg);
 		}
@@ -858,7 +864,7 @@
 	d(printf ("\ncamel_folder_summary_reload_from_db called \n"));
 
 	folder_name = s->folder->full_name;
-	cdb = s->folder->cdb;
+	cdb = s->folder->parent_store->cdb_r;
 
 	/* FIXME FOR SANKAR: No need to pass the address of summary here. */
 	data.summary = s;
@@ -871,7 +877,7 @@
 	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;
 }
@@ -904,9 +910,9 @@
 		return ret;
 
 	folder_name = s->folder->full_name;
-	cdb = s->folder->cdb;
+	cdb = s->folder->parent_store->cdb_r;
 
-	ret = camel_db_get_folder_uids (cdb, folder_name, s->uids, ex);
+	ret = camel_db_get_folder_uids (cdb, folder_name, (char *)s->sort_by, (char *)s->collate, s->uids, ex);
 	/* camel_folder_summary_dump (s); */
 
 #if 0
@@ -1121,7 +1127,7 @@
 	CamelMessageInfo *mi;
 	CamelMessageInfoBase *info;
 	int ret = 0;
-	CamelDB *cdb = s->folder->cdb;
+	CamelDB *cdb = s->folder->parent_store->cdb_w;
 	CamelFIRecord *record;
 	CamelException ex;
 
@@ -1270,7 +1276,7 @@
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)value;	
 	CamelFolderSummary *s = (CamelFolderSummary *)mi->summary;
 	char *folder_name = s->folder->full_name;
-	CamelDB *cdb = s->folder->cdb;
+	CamelDB *cdb = s->folder->parent_store->cdb_w;
 	CamelMIRecord *mir;
 
 	if (!mi->dirty)
@@ -1301,7 +1307,7 @@
 static int
 save_message_infos_to_db (CamelFolderSummary *s, CamelException *ex)
 {
-	CamelDB *cdb = s->folder->cdb;
+	CamelDB *cdb = s->folder->parent_store->cdb_w;
 	char *folder_name;
 
 	folder_name = s->folder->full_name;
@@ -1320,7 +1326,7 @@
 int
 camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex)
 {
-	CamelDB *cdb = s->folder->cdb;
+	CamelDB *cdb = s->folder->parent_store->cdb_w;
 	CamelFIRecord *record;
 	int ret, count;
 
@@ -1374,7 +1380,7 @@
 int
 camel_folder_summary_header_save_to_db (CamelFolderSummary *s, CamelException *ex)
 {
-	CamelDB *cdb = s->folder->cdb;
+	CamelDB *cdb = s->folder->parent_store->cdb_w;
 	CamelFIRecord *record;
 	int ret;
 
@@ -1553,7 +1559,7 @@
 	d(printf ("\ncamel_folder_summary_load_from_db called \n"));
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 
-	cdb = store->cdb;
+	cdb = store->cdb_r;
 
 	record = g_new0 (CamelFIRecord, 1);
 	camel_db_read_folder_info_record (cdb, folder_name, &record, ex);
@@ -2066,7 +2072,7 @@
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 
 	folder_name = s->folder->full_name;
-	cdb = s->folder->cdb;
+	cdb = s->folder->parent_store->cdb_w;
 
 	CAMEL_SUMMARY_LOCK(s, summary_lock);
 	if (camel_folder_summary_count(s) == 0) {
@@ -2133,7 +2139,7 @@
 	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_w, s->folder->full_name, camel_message_info_uid(info), NULL) != 0)
 		return ;
 	
 	camel_message_info_free(info);
@@ -2170,7 +2176,7 @@
 				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_w, s->folder->full_name, tmpid, NULL) != 0) {
 						g_free(tmpid);
 						return ;
 				}
@@ -2295,7 +2301,7 @@
 		camel_exception_init (&ex);
 
 		folder_name = s->folder->full_name;
-		cdb = s->folder->cdb;
+		cdb = s->folder->parent_store->cdb_w;
 
 		#warning "lifecycle of infos should be checked. Add should add to db and del should del to db. Sync only the changes at interval and remove those full sync on folder switch"
 		camel_db_delete_uids (cdb, folder_name, uids, &ex);
@@ -2608,8 +2614,8 @@
 	CamelDB *db;
 	char *table_name;
 
-	db = s->folder->cdb;
-	//table_name = safe_table (camel_file_util_safe_filename (s->folder->full_name));
+	/* Though we are going to read, we do this during write, so lets use it that way */
+	db = s->folder->parent_store->cdb_w;
 	table_name = s->folder->full_name;
 
 	io(printf("Savining header to db\n"));
@@ -3140,6 +3146,7 @@
 	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;

Modified: branches/gnome-2-24/camel/camel-folder-summary.h
==============================================================================
--- branches/gnome-2-24/camel/camel-folder-summary.h	(original)
+++ branches/gnome-2-24/camel/camel-folder-summary.h	Mon Oct  6 10:46:16 2008
@@ -247,6 +247,12 @@
 	struct _CamelFolderMetaSummary *meta_summary; /* Meta summary */
 	time_t cache_load_time;
 	guint timeout_handle;
+	
+	const char *collate;
+	const char *sort_by;
+
+	/* Future ABI expansion */
+	gpointer later[4];
 };
 
 struct _CamelFolderSummaryClass {
@@ -348,6 +354,9 @@
 /* add a new raw summary item */
 void camel_folder_summary_add (CamelFolderSummary *summary, CamelMessageInfo *info);
 
+/* Peek from mem only */
+CamelMessageInfo * camel_folder_summary_peek_info (CamelFolderSummary *s, const char *uid);
+
 /* Get only the uids of dirty/changed things to sync to server/db */
 GPtrArray * camel_folder_summary_get_changed (CamelFolderSummary *s);
 /* Gets the size of loaded mi's */

Modified: branches/gnome-2-24/camel/camel-folder.c
==============================================================================
--- branches/gnome-2-24/camel/camel-folder.c	(original)
+++ branches/gnome-2-24/camel/camel-folder.c	Mon Oct  6 10:46:16 2008
@@ -102,6 +102,8 @@
 static void		 ref_message_info    (CamelFolder *folder, CamelMessageInfo *info);
 
 static GPtrArray      *search_by_expression  (CamelFolder *folder, const char *exp, CamelException *ex);
+static guint32	       count_by_expression  (CamelFolder *folder, const char *exp, CamelException *ex);
+
 static GPtrArray      *search_by_uids	     (CamelFolder *folder, const char *exp, GPtrArray *uids, CamelException *ex);
 static void            search_free           (CamelFolder * folder, GPtrArray *result);
 
@@ -150,6 +152,7 @@
 	camel_folder_class->get_summary = get_summary;
 	camel_folder_class->free_summary = free_summary;
 	camel_folder_class->search_by_expression = search_by_expression;
+	camel_folder_class->count_by_expression = count_by_expression;
 	camel_folder_class->search_by_uids = search_by_uids;
 	camel_folder_class->search_free = search_free;
 	camel_folder_class->get_message_info = get_message_info;
@@ -205,11 +208,6 @@
 
 	camel_folder_change_info_free(p->changed_frozen);
 
-	if (camel_folder->cdb) {
-		camel_db_close (camel_folder->cdb);
-		camel_folder->cdb = NULL;
-	}
-
 	g_static_rec_mutex_free(&p->lock);
 	g_static_mutex_free(&p->change_lock);
 	
@@ -273,27 +271,6 @@
 		store_db_path = g_build_filename (store_path, CAMEL_DB_FILE, NULL);
 		g_free (store_path);
 	}
-
-	folder->cdb = camel_db_open (store_db_path, &ex);
-	if (camel_exception_is_set (&ex)) {
-		char *store_path;
-		
-		g_print ("Failure for store_db_path : [%s]\n", store_db_path);
-		g_free (store_db_path);		
-
-		store_path =   camel_session_get_storage_path ((CamelSession *)camel_service_get_session (service), service, &ex);
-		store_db_path = g_build_filename (store_path, CAMEL_DB_FILE, NULL);
-		g_free (store_path);
-		camel_exception_clear(&ex);
-		folder->cdb = camel_db_open (store_db_path, &ex);
-		if (camel_exception_is_set (&ex)) {
-			g_print("Retry with %s failed\n", store_db_path);
-			g_free(store_db_path);
-			camel_exception_clear(&ex);
-			return;
-		}
-	}
-	g_free (store_db_path);
 }
 
 
@@ -1383,6 +1360,47 @@
 	return ret;
 }
 
+static guint32
+count_by_expression (CamelFolder *folder, const char *expression,
+		      CamelException *ex)
+{
+	camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
+			      _("Unsupported operation: count by expression: for %s"),
+			      camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
+	
+	w(g_warning ("CamelFolder::count_by_expression not implemented for "
+		     "'%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))));
+	
+	return 0;
+}
+
+
+/**
+ * camel_folder_count_by_expression:
+ * @folder: a #CamelFolder object
+ * @expr: a search expression
+ * @ex: a #CamelException
+ *
+ * Searches the folder for count of messages matching the given search expression.
+ *
+ * Returns: an interger
+ **/
+guint32
+camel_folder_count_by_expression (CamelFolder *folder, const char *expression,
+				   CamelException *ex)
+{
+	guint32 ret;
+
+	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
+	g_return_val_if_fail (folder->folder_flags & CAMEL_FOLDER_HAS_SEARCH_CAPABILITY, 0);
+
+	/* NOTE: that it is upto the callee to lock */
+
+	ret = CF_CLASS (folder)->count_by_expression (folder, expression, ex);
+
+	return ret;
+}
+
 static GPtrArray *
 search_by_uids(CamelFolder *folder, const char *exp, GPtrArray *uids, CamelException *ex)
 {
@@ -1599,7 +1617,7 @@
 	CAMEL_FOLDER_REC_UNLOCK (folder, lock);
 
 	/* Delete the references of the folder from the DB.*/
-	camel_db_delete_folder (folder->cdb, folder->full_name, NULL);
+	camel_db_delete_folder (folder->parent_store->cdb_w, folder->full_name, NULL);
 	
 	camel_object_trigger_event (folder, "deleted", NULL);
 }
@@ -1637,7 +1655,7 @@
 	old = g_strdup(folder->full_name);
 
 	CF_CLASS (folder)->rename(folder, new);
-	camel_db_rename_folder (folder->cdb, old, new, NULL);
+	camel_db_rename_folder (folder->parent_store->cdb_w, old, new, NULL);
 	camel_object_trigger_event (folder, "renamed", old);
 	g_free(old);
 }

Modified: branches/gnome-2-24/camel/camel-folder.h
==============================================================================
--- branches/gnome-2-24/camel/camel-folder.h	(original)
+++ branches/gnome-2-24/camel/camel-folder.h	Mon Oct  6 10:46:16 2008
@@ -109,7 +109,9 @@
 
 	guint32 folder_flags;
 	guint32 permanent_flags;
-	CamelDB *cdb;
+
+	/* Future ABI expansion */
+	gpointer later[4];
 };
 
 #define CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY (1<<0)
@@ -208,6 +210,7 @@
 	gboolean (*is_frozen) (CamelFolder *folder);
 	
 	CamelFolderQuotaInfo * (*get_quota_info) (CamelFolder *folder);
+	guint32	(*count_by_expression) (CamelFolder *, const char *, CamelException *);
 } CamelFolderClass;
 
 /* Standard Camel function */
@@ -314,6 +317,7 @@
 GPtrArray *	   camel_folder_search_by_expression  (CamelFolder *folder, const char *expr, CamelException *ex);
 GPtrArray *	   camel_folder_search_by_uids	      (CamelFolder *folder, const char *expr, GPtrArray *uids, CamelException *ex);
 void		   camel_folder_search_free	      (CamelFolder *folder, GPtrArray *result);
+guint32		   camel_folder_count_by_expression   (CamelFolder *folder, const char *expression, CamelException *ex);
 
 /* summary info */
 CamelMessageInfo *camel_folder_get_message_info		(CamelFolder *folder, const char *uid);

Modified: branches/gnome-2-24/camel/camel-search-sql-sexp.c
==============================================================================
--- branches/gnome-2-24/camel/camel-search-sql-sexp.c	(original)
+++ branches/gnome-2-24/camel/camel-search-sql-sexp.c	Mon Oct  6 10:46:16 2008
@@ -534,6 +534,26 @@
 	return r;
 }
 
+static ESExpResult *
+sql_exp (struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+	ESExpResult *r;
+	int i;
+	GString *str = g_string_new (NULL);
+
+	d(printf("executing sql-exp\n"));
+
+	r = e_sexp_result_new(f, ESEXP_RES_STRING);
+	for (i=0;i<argc;i++) {
+		if (argv[i]->type == ESEXP_RES_STRING && argv[i]->value.string)
+			g_string_append (str, argv[i]->value.string);
+	}
+	r->value.string = str->str;
+	g_string_free (str, FALSE);
+	
+	return r;
+}
+
 /* 'builtin' functions */
 static struct {
 	char *name;
@@ -562,6 +582,8 @@
 	{ "get-received-date", get_received_date, 0},
 	{ "get-current-date", get_current_date, 0},
 	{ "get-size", get_size, 0},
+	{ "sql-exp", sql_exp, 0},
+	
 /*	{ "uid", CAMEL_STRUCT_OFFSET(CamelFolderSearchClass, uid), 1 },	*/
 };
 
@@ -585,6 +607,8 @@
 	e_sexp_parse (sexp);
 
 	r = e_sexp_eval (sexp);
+	if (!r)
+		return NULL;
 	if (r->type == ESEXP_RES_STRING) {
 		res = g_strdup (r->value.string);
 	} else 
@@ -664,6 +688,7 @@
 
 	int i=0;
 	char *txt[] = {
+#if 0		
 	"(match-all (header-contains \"From\"  \"org\"))",
 	"(and (match-all (and (not (system-flag \"deleted\")) (not (system-flag \"junk\")))) (and   (or (match-all (or (header-ends-with \"To\"  \"novell.com\") (header-ends-with \"Cc\"  \"novell.com\"))) (match-all (or (= (user-tag \"label\")  \"work\")  (user-flag  \"work\"))) )))", 
 
@@ -704,7 +729,10 @@
 	"(not (or (header-matches \"from\" \"bugzilla-daemon bugzilla ximian com\") (header-matches \"from\" \"bugzilla-daemon bugzilla gnome org\") (header-matches \"from\" \"bugzilla_noreply novell com\") (header-matches \"from\" \"bugzilla-daemon mozilla org\") (header-matches \"from\" \"root dist suse de\") (header-matches \"from\" \"root hilbert3 suse de\") (header-matches \"from\" \"root hilbert4 suse de\") (header-matches \"from\" \"root hilbert5 suse de\") (header-matches \"from\" \"root hilbert6 suse de\") (header-matches \"from\" \"root suse de\") (header-matches \"from\" \"swamp_noreply suse de\") (and (header-matches \"from\" \"hermes opensuse org\") (header-starts-with \"subject\" \"submit-Request\"))))",
 	"(and (match-threads \"replies_parents\" (and (match-all (or (header-matches \"to\" \"maw ximian com\") (header-matches \"to\" \"mw ximian com\")   (header-matches \"to\" \"maw novell com\")   (header-matches \"to\" \"maw AMERICAS3 AMERICAS novell com\") (header-matches \"cc\" \"maw ximian com\") (header-matches \"cc\" \"mw ximian com\")     (header-matches \"cc\" \"maw novell com\")   (header-matches \"cc\" \"maw AMERICAS3 AMERICAS novell com\"))) (match-all (not (or (header-matches \"from\" \"bugzilla-daemon bugzilla ximian com\") (header-matches \"from\" \"bugzilla-daemon bugzilla gnome org\") (header-matches \"from\" \"bugzilla_noreply novell com\") (header-matches \"from\" \"bugzilla-daemon mozilla org\") (header-matches \"from\" \"root dist suse de\") (header-matches \"from\" \"root hilbert3 suse de\") (header-matches \"from\" \"root hilbert4 suse de\") (header-matches \"from\" \"root hilbert5 suse de\") (header-matches \"from\" \"root hilbert6 suse de\") (header-matc
 hes \"from\" \"root suse de\") (header-matches \"from\" \"swamp_noreply suse de\") (and (header-matches \"from\" \"hermes opensuse org\") (header-starts-with \"subject\" \"submit-Request\"))))) (match-all (> (get-sent-date) (- (get-current-date) 1209600))) )) (match-all (and (not (system-flag \"deleted\")) (not (system-flag \"junk\")))))",
 	"and ((match-all (system-flag \"Deleted\")) (match-all (system-flag  \"junk\")))",
-	"(and (match-threads \"replies_parents\" (and (match-all (or (header-matches \"to\" \"maw ximian com\")))))))"
+	"(and (match-threads \"replies_parents\" (and (match-all (or (header-matches \"to\" \"maw ximian com\")))))))",
+	"(and (sql-exp \"folder_key = 'ASDGASd' AND folder_key = 'DSFWEA'\") (match-threads \"replies_parents\" (and (match-all (or (header-matches \"to\" \"maw ximian com\")))))))"
+#endif	
+	"(and (match-all (and (not (system-flag \"deleted\")) (not (system-flag \"junk\")))) (and   (or  (match-all list-post.*zypp-devel)  ) ))"
 	};
 
 	for (i=0; i < G_N_ELEMENTS(txt); i++) {

Modified: branches/gnome-2-24/camel/camel-store.c
==============================================================================
--- branches/gnome-2-24/camel/camel-store.c	(original)
+++ branches/gnome-2-24/camel/camel-store.c	Mon Oct  6 10:46:16 2008
@@ -159,9 +159,14 @@
 	
 	g_static_rec_mutex_free (&store->priv->folder_lock);
 
-	if (store->cdb) {
-		camel_db_close (store->cdb);
-		store->cdb = NULL;
+	if (store->cdb_r) {
+		camel_db_close (store->cdb_r);
+		store->cdb_r = NULL;
+	}
+
+	if (store->cdb_w) {
+		camel_db_close (store->cdb_w);
+		store->cdb_w = NULL;
 	}
 
 	g_free (store->priv);
@@ -228,7 +233,8 @@
 
 	g_free (store_path);
 
-	store->cdb = camel_db_open (store_db_path, ex);
+	/* This is for reading from the store */
+	store->cdb_r = camel_db_open (store_db_path, ex);
 	printf("store_db_path %s\n", store_db_path);
 	if (camel_exception_is_set (ex)) {
 		char *store_path;
@@ -240,7 +246,7 @@
 		store_db_path = g_build_filename (store_path, CAMEL_DB_FILE, NULL);
 		g_free (store_path);
 		camel_exception_clear(ex);
-		store->cdb = camel_db_open (store_db_path, ex);
+		store->cdb_r = camel_db_open (store_db_path, ex);
 		if (camel_exception_is_set (ex)) {
 			g_print("Retry with %s failed\n", store_db_path);
 			g_free(store_db_path);
@@ -250,13 +256,15 @@
 	}
 	g_free (store_db_path);
 
-	if (camel_db_create_folders_table (store->cdb, ex))
-		printf ("something went wrong terribly\n");
+	if (camel_db_create_folders_table (store->cdb_r, ex))
+		g_warning ("something went wrong terribly during db creation \n");
 	else
-		printf ("folders table successfully created \n");
+		d(printf ("folders table successfully created \n"));
 
 	if (camel_exception_is_set (ex))
 		return;
+	/* This is for writing to the store */
+	store->cdb_w = camel_db_clone (store->cdb_r, ex);
 
 	if (camel_url_get_param(url, "filter"))
 		store->flags |= CAMEL_STORE_FILTER_INBOX;

Modified: branches/gnome-2-24/camel/camel-store.h
==============================================================================
--- branches/gnome-2-24/camel/camel-store.h	(original)
+++ branches/gnome-2-24/camel/camel-store.h	Mon Oct  6 10:46:16 2008
@@ -122,10 +122,14 @@
 	struct _CamelStorePrivate *priv;
 	
 	CamelObjectBag *folders;
-	CamelDB *cdb;
+	CamelDB *cdb_r;
+	CamelDB *cdb_w;
 
 	guint32 flags;
 	guint32 mode;
+
+	/* Future ABI expansion */
+	gpointer later[4];
 };
 
 /* open mode for folder */

Modified: branches/gnome-2-24/camel/camel-vee-folder.c
==============================================================================
--- branches/gnome-2-24/camel/camel-vee-folder.c	(original)
+++ branches/gnome-2-24/camel/camel-vee-folder.c	Mon Oct  6 10:46:16 2008
@@ -64,6 +64,7 @@
 static void vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex);
 static void vee_transfer_messages_to(CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex);
 
+static guint32 vee_count_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
 static GPtrArray *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
 static GPtrArray *vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
 
@@ -482,27 +483,17 @@
 	g_list_free(list);
 }
 
-static int
+static guint32
 count_folder (CamelFolder *f, char *expr, CamelException *ex)
 {
-	GPtrArray *match;
-	int count = 0;
-
-	/* FIXME: Why don't we write a count_search_by_expression. It can be just fast. */
-	match = camel_folder_search_by_expression(f, expr, ex);
-	if (match) {
-		count = match->len;
-		camel_folder_search_free (f, match);
-	}
-
-	return count;
+	return camel_folder_count_by_expression(f, expr, ex);
 }
 static int 
 count_result (CamelFolderSummary *summary, char *query, CamelException *ex)
 {
 	CamelFolder *folder = summary->folder;
 	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
-	int count=0; 
+	guint32 count=0; 
 	char *expr = g_strdup_printf ("(and %s %s)", vf->expression ? vf->expression : "", query);
 	GList *node;
 	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
@@ -525,7 +516,8 @@
 	CamelDB *db;
 	char *table_name;
 
-	db = s->folder->parent_store->cdb;
+	/* We do this during write, so lets use write handle, though we gonna read */
+	db = s->folder->parent_store->cdb_w;
 	table_name = s->folder->full_name;
 
 	record->folder_name = table_name;
@@ -641,6 +633,40 @@
 	return msg;
 }
 
+static guint32
+vee_count_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
+{
+	GList *node;
+	char *expr;
+	guint32 count = 0;
+	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
+	struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
+	GHashTable *searched = g_hash_table_new(NULL, NULL);
+	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+	
+	if (vf != folder_unmatched)
+		expr = g_strdup_printf ("(and %s %s)", vf->expression ? vf->expression : "", expression);
+	else
+		expr = g_strdup (expression);
+	
+	node = p->folders;
+	while (node) {
+		CamelFolder *f = node->data;
+		
+		/* make sure we only search each folder once - for unmatched folder to work right */
+		if (g_hash_table_lookup(searched, f) == NULL) {
+			count += camel_folder_count_by_expression(f, expr, ex);
+			g_hash_table_insert(searched, f, f);
+		}
+		node = g_list_next(node);
+	}
+
+	
+	g_free(expr);
+
+	g_hash_table_destroy(searched);
+	return count;
+}
 static GPtrArray *
 vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
 {
@@ -1005,7 +1031,7 @@
 		#warning "Handle exceptions"
 		#warning "Make all these as transactions, just testing atm"
 		if (u->rebuilt)
-			camel_db_add_to_vfolder_transaction (((CamelFolder *) u->vf)->parent_store->cdb, ((CamelFolder *) u->vf)->full_name, (char *) camel_message_info_uid(mi), NULL);
+			camel_db_add_to_vfolder_transaction (((CamelFolder *) u->vf)->parent_store->cdb_w, ((CamelFolder *) u->vf)->full_name, (char *) camel_message_info_uid(mi), NULL);
 		if (!CAMEL_IS_VEE_FOLDER(u->source) && u->unmatched_uids != NULL) {
 			if (g_hash_table_lookup_extended(u->unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
 				n = GPOINTER_TO_INT (oldval);
@@ -1135,13 +1161,13 @@
 
 	/* now matchhash contains any new uid's, add them, etc */
 	if (rebuilded) {
-		camel_db_begin_transaction (folder->parent_store->cdb, NULL);
+		camel_db_begin_transaction (folder->parent_store->cdb_w, NULL);
 
 	}
 	g_hash_table_foreach(matchhash, (GHFunc)folder_added_uid, &u);
 
 	if (rebuilded)
-		camel_db_end_transaction (folder->parent_store->cdb, NULL);
+		camel_db_end_transaction (folder->parent_store->cdb_w, NULL);
 	
 	if (folder_unmatched != NULL) {
 		/* scan unmatched, remove any that have vanished, etc */
@@ -1312,7 +1338,7 @@
 		return;
 	
 	vuid = camel_message_info_uid(vinfo);
-	camel_db_add_to_vfolder_transaction (folder->parent_store->cdb, folder->full_name, (char *)vuid, NULL);
+	camel_db_add_to_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, (char *)vuid, NULL);
 	camel_folder_change_info_add_uid(vf->changes,  vuid);
 	/* old flags and new flags should  be same, since we sync all times  */
 	update_summary (vinfo, camel_message_info_flags(vinfo), 0, TRUE, FALSE);
@@ -1353,9 +1379,9 @@
 		camel_message_info_free((CamelMessageInfo *)vinfo);
 	}
 	camel_folder_change_info_remove_uid(vf->changes, vuid);
-        #warning "Handle exception"
-	camel_db_delete_uid_from_vfolder_transaction (folder->parent_store->cdb, folder->full_name, vuid, NULL);
-	camel_folder_summary_remove_uid(folder->summary, vuid);
+        /* FIXME[disk-summary] Handle exception */
+	camel_db_delete_uid_from_vfolder_transaction (folder->parent_store->cdb_w, folder->full_name, vuid, NULL);
+	camel_folder_summary_remove_uid_fast(folder->summary, vuid);
 
 	if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
 		if (keep) {
@@ -1521,7 +1547,7 @@
 
 	CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
 	if (matches_changed || matches_added || changes->uid_removed->len||present)
-		camel_db_begin_transaction (folder->parent_store->cdb, NULL);
+		camel_db_begin_transaction (folder->parent_store->cdb_w, NULL);
 
 	if (folder_unmatched != NULL)
 		CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
@@ -1654,7 +1680,7 @@
 	}
 
 	if (matches_changed || matches_added || changes->uid_removed->len || present)
-		camel_db_end_transaction (folder->parent_store->cdb, NULL);
+		camel_db_end_transaction (folder->parent_store->cdb_w, NULL);
 	CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
 
 	/* Cleanup stuff on our folder */
@@ -1999,7 +2025,7 @@
 
 	/* Recreate the table when the query changes, only if we are not setting it first */
 	if (vf->expression)
-		camel_db_recreate_vfolder (((CamelFolder *) vf)->parent_store->cdb, ((CamelFolder *) vf)->full_name, NULL);
+		camel_db_recreate_vfolder (((CamelFolder *) vf)->parent_store->cdb_w, ((CamelFolder *) vf)->full_name, NULL);
 
 
 	g_free(vf->expression);
@@ -2041,6 +2067,7 @@
 
 	folder_class->search_by_expression = vee_search_by_expression;
 	folder_class->search_by_uids = vee_search_by_uids;
+	folder_class->count_by_expression = vee_count_by_expression;
 
 	folder_class->rename = vee_rename;
 	folder_class->delete = vee_delete;
@@ -2165,7 +2192,7 @@
 
 	/* Save the counts to DB */
 	record = summary_header_to_db (vf->summary, ex);
-	camel_db_write_folder_info_record (vf->parent_store->cdb, record, ex);
+	camel_db_write_folder_info_record (vf->parent_store->cdb_w, record, ex);
 	g_free (record);
 }
 
@@ -2183,7 +2210,7 @@
 	/* Save the counts to DB */
 	if (!vf->deleted) {
 		record = summary_header_to_db (((CamelFolder *)vf)->summary, NULL);
-		camel_db_write_folder_info_record (((CamelFolder *) vf)->parent_store->cdb, record, NULL);
+		camel_db_write_folder_info_record (((CamelFolder *) vf)->parent_store->cdb_w, record, NULL);
 		g_free (record);
 	}
 	

Modified: branches/gnome-2-24/camel/camel-vee-summary.c
==============================================================================
--- branches/gnome-2-24/camel/camel-vee-summary.c	(original)
+++ branches/gnome-2-24/camel/camel-vee-summary.c	Mon Oct  6 10:46:16 2008
@@ -65,7 +65,7 @@
 	return (CamelMessageInfo *)to;
 }
 
-#define HANDLE_NULL_INFO(value) if (!rmi) { g_warning (G_STRLOC ": real info is NULL for %s, safeguarding\n", mi->uid); return value; }
+#define HANDLE_NULL_INFO(value) if (!rmi) { d(g_warning (G_STRLOC ": real info is NULL for %s, safeguarding\n", mi->uid)); return value; }
 
 static const void *
 vee_info_ptr (const CamelMessageInfo *mi, int id)
@@ -329,9 +329,10 @@
 	s->summary.folder = parent;
 	s->force_counts = FALSE;
 
-        #warning "fix exceptions and note return values"
-	#warning "if Evo's junk/trash vfolders make it VJunk VTrash instead of .#evolution/Junk-or-whatever"		
-	camel_db_create_vfolder (parent->cdb, parent->full_name, NULL);
+        /* FIXME[disk-summary] fix exceptions and note return values */
+	/* FIXME[disk-summary] if Evo's junk/trash vfolders make it VJunk
+	 * VTrash instead of .#evolution/Junk-or-whatever */
+	camel_db_create_vfolder (parent->parent_store->cdb_w, parent->full_name, NULL);
 
 	#warning "handle excep and ret"
 	camel_folder_summary_header_load_from_db ((CamelFolderSummary *)s, parent->parent_store, parent->full_name, NULL);
@@ -345,8 +346,8 @@
 	CamelFolderSummary *cfs = (CamelFolderSummary *)summary;
 	GPtrArray *array;
 
-	#warning "fix exception passing"
-	array = camel_db_get_vuids_from_vfolder(cfs->folder->cdb, cfs->folder->full_name, shash, NULL);
+	/* FIXME[disk-summary] fix exception passing */
+	array = camel_db_get_vuids_from_vfolder(cfs->folder->parent_store->cdb_r, cfs->folder->full_name, shash, NULL);
 	
 	g_free(shash);
 

Modified: branches/gnome-2-24/camel/camel-vtrash-folder.c
==============================================================================
--- branches/gnome-2-24/camel/camel-vtrash-folder.c	(original)
+++ branches/gnome-2-24/camel/camel-vtrash-folder.c	Mon Oct  6 10:46:16 2008
@@ -521,14 +521,14 @@
 	CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
 
 	if (((CamelVTrashFolder *)vf)->bit == CAMEL_MESSAGE_DELETED) {
-		infos = camel_db_get_folder_deleted_uids (sub->cdb, sub->full_name, NULL);
+		infos = camel_db_get_folder_deleted_uids (sub->parent_store->cdb_w, sub->full_name, NULL);
 		if (infos) {
 			((CamelFolder *)vf)->summary->saved_count += infos->len;
 			((CamelFolder *)vf)->summary->deleted_count += infos->len;
 		}
 	}
 	else if (((CamelVTrashFolder *)vf)->bit == CAMEL_MESSAGE_JUNK)
-		infos = camel_db_get_folder_junk_uids (sub->cdb, sub->full_name, NULL);
+		infos = camel_db_get_folder_junk_uids (sub->parent_store->cdb_w, sub->full_name, NULL);
 
 	if (!infos) {
 		CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);

Modified: branches/gnome-2-24/camel/providers/groupwise/camel-groupwise-folder.c
==============================================================================
--- branches/gnome-2-24/camel/providers/groupwise/camel-groupwise-folder.c	(original)
+++ branches/gnome-2-24/camel/providers/groupwise/camel-groupwise-folder.c	Mon Oct  6 10:46:16 2008
@@ -451,6 +451,20 @@
 	return matches;
 }
 
+static guint32
+groupwise_folder_count_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
+{
+	CamelGroupwiseFolder *gw_folder = CAMEL_GROUPWISE_FOLDER(folder);
+	guint32 matches;
+
+	CAMEL_GROUPWISE_FOLDER_LOCK(gw_folder, search_lock);
+	camel_folder_search_set_folder (gw_folder->search, folder);
+	matches = camel_folder_search_count (gw_folder->search, expression, ex);
+	CAMEL_GROUPWISE_FOLDER_UNLOCK(gw_folder, search_lock);
+
+	return matches;
+}
+
 static GPtrArray *
 groupwise_folder_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
 {
@@ -2396,6 +2410,7 @@
 	camel_folder_class->get_message = groupwise_folder_get_message;
 	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->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;

Modified: branches/gnome-2-24/camel/providers/imap/camel-imap-folder.c
==============================================================================
--- branches/gnome-2-24/camel/providers/imap/camel-imap-folder.c	(original)
+++ branches/gnome-2-24/camel/providers/imap/camel-imap-folder.c	Mon Oct  6 10:46:16 2008
@@ -123,6 +123,7 @@
 
 /* searching */
 static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
+static guint32 imap_count_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
 static GPtrArray *imap_search_by_uids	    (CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
 static void       imap_search_free          (CamelFolder *folder, GPtrArray *uids);
 
@@ -155,6 +156,7 @@
 	camel_folder_class->get_message = imap_get_message;
 	camel_folder_class->rename = imap_rename;
 	camel_folder_class->search_by_expression = imap_search_by_expression;
+	camel_folder_class->count_by_expression = imap_count_by_expression;
 	camel_folder_class->search_by_uids = imap_search_by_uids;
 	camel_folder_class->search_free = imap_search_free;
 	camel_folder_class->thaw = imap_thaw;
@@ -1483,7 +1485,7 @@
 		 * the cached data may be useful in replaying a COPY later.
 		 */
 	}
-	camel_db_delete_uids (folder->cdb, folder->full_name, list, ex);
+	camel_db_delete_uids (folder->parent_store->cdb_w, folder->full_name, list, ex);
 	g_slist_free(list);
 	camel_folder_summary_save_to_db (folder->summary, ex);
 
@@ -1568,7 +1570,7 @@
 		 * the cached data may be useful in replaying a COPY later.
 		 */
 	}
-	camel_db_delete_uids (folder->cdb, folder->full_name, list, ex);
+	camel_db_delete_uids (folder->parent_store->cdb_w, folder->full_name, list, ex);
 	g_slist_free (list);
 	camel_folder_summary_save_to_db (folder->summary, ex);
 	camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
@@ -2399,6 +2401,24 @@
 	return matches;
 }
 
+static guint32
+imap_count_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
+{
+	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+	guint32 matches;
+
+	/* we could get around this by creating a new search object each time,
+	   but i doubt its worth it since any long operation would lock the
+	   command channel too */
+	CAMEL_IMAP_FOLDER_LOCK(folder, search_lock);
+
+	camel_folder_search_set_folder (imap_folder->search, folder);
+	matches = camel_folder_search_count(imap_folder->search, expression, ex);
+
+	CAMEL_IMAP_FOLDER_UNLOCK(folder, search_lock);
+
+	return matches;
+}
 static GPtrArray *
 imap_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
 {
@@ -3506,7 +3526,7 @@
 		}
 		
 		/* Delete all in one transaction */
-		camel_db_delete_uids (folder->cdb, folder->full_name, deleted, ex);
+		camel_db_delete_uids (folder->parent_store->cdb_w, folder->full_name, deleted, ex);
 		g_slist_foreach (deleted, (GFunc) g_free, NULL);
 		g_slist_free (deleted);
 	}

Modified: branches/gnome-2-24/camel/providers/imap/camel-imap-store.c
==============================================================================
--- branches/gnome-2-24/camel/providers/imap/camel-imap-store.c	(original)
+++ branches/gnome-2-24/camel/providers/imap/camel-imap-store.c	Mon Oct  6 10:46:16 2008
@@ -1126,7 +1126,7 @@
 	g_unlink (state_file);
 	g_free (state_file);
 	
-	camel_db_delete_folder (((CamelStore *)imap_store)->cdb, folder_name, ex);
+	camel_db_delete_folder (((CamelStore *)imap_store)->cdb_w, folder_name, ex);
 	camel_imap_message_cache_delete (folder_dir, ex);
 
 	state_file = g_strdup_printf("%s/subfolders", folder_dir);
@@ -1378,6 +1378,7 @@
 			}
 		}
 		if (!authenticated) {
+			printf("EXCEP %d %d %d\n", camel_exception_get_id(ex), CAMEL_EXCEPTION_USER_CANCEL, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE);
 			if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL ||
 			    camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE)
 				return FALSE;

Modified: branches/gnome-2-24/camel/providers/imap/camel-imap-summary.c
==============================================================================
--- branches/gnome-2-24/camel/providers/imap/camel-imap-summary.c	(original)
+++ branches/gnome-2-24/camel/providers/imap/camel-imap-summary.c	Mon Oct  6 10:46:16 2008
@@ -34,6 +34,7 @@
 #include "camel-folder.h"
 #include "camel-file-utils.h"
 #include "camel-string-utils.h"
+#include "camel-store.h"
 
 #include "camel-imap-summary.h"
 #include "camel-imap-utils.h"
@@ -140,12 +141,23 @@
 static int 
 sort_uid_cmp (void *enc, int len1, void * data1, int len2, void *data2)
 {
-	char *sa1 = (char*)g_utf8_normalize (data1, len1, G_NORMALIZE_DEFAULT);
-	char *sa2 = (char*)g_utf8_normalize (data2, len2, G_NORMALIZE_DEFAULT);
-	int a1 = strtoul (sa1, NULL, 10);
-	int a2 = strtoul (sa2, NULL, 10);
+	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;	
 
-	g_free(sa1); g_free(sa2);
+	a1 = strtoul (sa1, NULL, 10);
+	a2 = strtoul (sa2, NULL, 10);
 
 	return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
 }
@@ -168,8 +180,11 @@
 	camel_exception_init (&ex);
 
 	summary->folder = folder;
-	if (folder)
-		camel_db_set_collate (folder->cdb, "uid", "uid_sort", (CamelDBCollate)sort_uid_cmp);
+	if (folder) {
+		camel_db_set_collate (folder->parent_store->cdb_r, "uid", "imap_uid_sort", (CamelDBCollate)sort_uid_cmp);
+		summary->sort_by = "uid";
+		summary->collate = "imap_uid_sort";
+	}
 
 	camel_folder_summary_set_build_content (summary, TRUE);
 	camel_folder_summary_set_filename (summary, filename);

Modified: branches/gnome-2-24/camel/providers/local/camel-local-folder.c
==============================================================================
--- branches/gnome-2-24/camel/providers/local/camel-local-folder.c	(original)
+++ branches/gnome-2-24/camel/providers/local/camel-local-folder.c	Mon Oct  6 10:46:16 2008
@@ -81,6 +81,7 @@
 static void local_expunge(CamelFolder *folder, CamelException *ex);
 
 static GPtrArray *local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
+static guint32 local_count_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
 static GPtrArray *local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
 static void local_search_free(CamelFolder *folder, GPtrArray * result);
 
@@ -106,6 +107,7 @@
 	camel_folder_class->expunge = local_expunge;
 
 	camel_folder_class->search_by_expression = local_search_by_expression;
+	camel_folder_class->count_by_expression = local_count_by_expression;
 	camel_folder_class->search_by_uids = local_search_by_uids;
 	camel_folder_class->search_free = local_search_free;
 
@@ -590,6 +592,26 @@
 	return matches;
 }
 
+static guint32
+local_count_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
+{
+	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder);
+	gint matches;
+
+	CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock);
+
+	if (local_folder->search == NULL)
+		local_folder->search = camel_folder_search_new();
+
+	camel_folder_search_set_folder(local_folder->search, folder);
+	camel_folder_search_set_body_index(local_folder->search, local_folder->index);
+	matches = camel_folder_search_count (local_folder->search, expression, ex);
+
+	CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock);
+
+	return matches;
+}
+
 static GPtrArray *
 local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
 {

Modified: branches/gnome-2-24/camel/providers/local/camel-local-store.c
==============================================================================
--- branches/gnome-2-24/camel/providers/local/camel-local-store.c	(original)
+++ branches/gnome-2-24/camel/providers/local/camel-local-store.c	Mon Oct  6 10:46:16 2008
@@ -106,12 +106,6 @@
 	store = ((CamelStore *)local_store); 
 	d(printf ("\n\aLocal Store Finalize \n\a"));
 
-	if (store && store->cdb) {
-	d(printf ("\n\aClosing Store DB for hte local provider \n\a"));
-		camel_db_close (store->cdb);
-		store->cdb = NULL;
-	}
-
 }
 
 CamelType

Modified: branches/gnome-2-24/camel/providers/local/camel-maildir-summary.c
==============================================================================
--- branches/gnome-2-24/camel/providers/local/camel-maildir-summary.c	(original)
+++ branches/gnome-2-24/camel/providers/local/camel-maildir-summary.c	Mon Oct  6 10:46:16 2008
@@ -41,6 +41,7 @@
 #include "camel-mime-message.h"
 #include "camel-operation.h"
 #include "camel-private.h"
+#include "camel-store.h"
 #include "camel-string-utils.h"
 #include "camel-maildir-summary.h"
 
@@ -168,8 +169,11 @@
 	CamelMaildirSummary *o = (CamelMaildirSummary *)camel_object_new(camel_maildir_summary_get_type ());
 
 	((CamelFolderSummary *)o)->folder = folder;
-	if (folder)
-		camel_db_set_collate (folder->cdb, "dreceived", NULL, NULL);
+	if (folder) {
+		camel_db_set_collate (folder->parent_store->cdb_r, "dreceived", NULL, NULL);
+		((CamelFolderSummary *)o)->sort_by = "dreceived";
+		((CamelFolderSummary *)o)->collate = NULL;
+	}
 	camel_local_summary_construct((CamelLocalSummary *)o, filename, maildirdir, index);
 	return o;
 }

Modified: branches/gnome-2-24/camel/providers/local/camel-mbox-summary.c
==============================================================================
--- branches/gnome-2-24/camel/providers/local/camel-mbox-summary.c	(original)
+++ branches/gnome-2-24/camel/providers/local/camel-mbox-summary.c	Mon Oct  6 10:46:16 2008
@@ -213,14 +213,25 @@
 static int 
 frompos_sort (void *enc, int len1, void * data1, int len2, void *data2)
 {
-	char *sa1 = (char*)g_utf8_normalize (data1, len1, G_NORMALIZE_DEFAULT);
-	char *sa2 = (char*)g_utf8_normalize (data2, len2, G_NORMALIZE_DEFAULT);
-	int a1 = strtoul (sa1, NULL, 10);
-	int a2 = strtoul (sa2, NULL, 10);
+	static char *sa1=NULL, *sa2=NULL;
+	static int l1=0, l2=0;
+	int a1, a2;
 
-	g_free(sa1); g_free(sa2);
+	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;
 
-	return a1 > a2;
+	a1 = strtoul (sa1, NULL, 10);
+	a2 = strtoul (sa2, NULL, 10);
+
+	return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
 }
 
 /**
@@ -237,9 +248,13 @@
 
 	((CamelFolderSummary *)new)->folder = folder;
 	if (folder) {
+		CamelFolderSummary *summary = (CamelFolderSummary *)new;
+
 		/* Set the functions for db sorting */
-		/* FIXME: Add column names though a #define */
-		camel_db_set_collate (folder->cdb, "bdata", "frompos_sort", (CamelDBCollate)frompos_sort);
+		camel_db_set_collate (folder->parent_store->cdb_r, "bdata", "mbox_frompos_sort", (CamelDBCollate)frompos_sort);
+		summary->sort_by = "bdata";
+		summary->collate = "mbox_frompos_sort";
+
 	}
 	camel_local_summary_construct((CamelLocalSummary *)new, filename, mbox_name, index);
 	return new;
@@ -367,7 +382,8 @@
 		    && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, &mi->info) == 0) {
 			uid = camel_message_info_uid(mi);
 			d(printf("found valid x-evolution: %s\n", uid));
-			info = (CamelMboxMessageInfo *)camel_folder_summary_uid(s, uid);
+			/* If one is there, it should be there already */
+			info = (CamelMboxMessageInfo *) camel_folder_summary_peek_info (s, uid);
 			if (info) {
 				if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
 					info->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
@@ -567,6 +583,8 @@
 	   If we're not starting from the start, we must be starting
 	   from the old end, so everything must be treated as new */
 	count = camel_folder_summary_count(s);
+	if (count != camel_folder_summary_cache_size(s)) /* It makes sense to load summary, if it isn't there. */
+		camel_folder_summary_reload_from_db (s, ex);	
 	for (i=0;i<count;i++) {
 		mi = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
 		if (offset == 0)
@@ -613,7 +631,7 @@
 	}
 	
 	/* Delete all in one transaction */
-	camel_db_delete_uids (s->folder->cdb, s->folder->full_name, del, ex);
+	camel_db_delete_uids (s->folder->parent_store->cdb_w, s->folder->full_name, del, ex);
 	g_slist_foreach (del, (GFunc) camel_pstring_free, NULL);
 	g_slist_free (del);	
 
@@ -789,6 +807,30 @@
 	return -1;
 }
 
+static gint
+cms_sort_frompos (gpointer a, gpointer b, gpointer data)
+{
+	CamelFolderSummary *summary = (CamelFolderSummary *)data;
+	CamelMboxMessageInfo *info1, *info2;
+	int ret = 0;
+
+	/* Things are in memory already. Sorting speeds up syncing, if things are sorted by from pos. */
+	info1 = (CamelMboxMessageInfo *)camel_folder_summary_uid (summary, *(char **)a);
+	info2 = (CamelMboxMessageInfo *)camel_folder_summary_uid (summary, *(char **)b);
+
+	if (info1->frompos > info2->frompos)
+		ret = 1;
+	else if  (info1->frompos < info2->frompos)
+		ret = -1;
+	else 
+		ret = 0;
+	camel_message_info_free (info1);
+	camel_message_info_free (info2);
+
+	return ret;
+
+}
+
 /* perform a quick sync - only system flags have changed */
 static int
 mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex)
@@ -836,6 +878,9 @@
 
 	/* Sync only the changes */
 	summary = camel_folder_summary_get_changed ((CamelFolderSummary *)mbs);
+	if (summary->len)
+		g_ptr_array_sort_with_data (summary, (GCompareDataFunc)cms_sort_frompos, (gpointer) mbs);
+	
 	for (i = 0; i < summary->len; i++) {
 		int xevoffset;
 		int pc = (i+1)*100/summary->len;
@@ -909,6 +954,7 @@
 		camel_mime_parser_drop_step(mp);
 
 		info->info.info.flags &= 0xffff;
+		info->info.info.dirty = TRUE;
 		camel_message_info_free((CamelMessageInfo *)info);
 	}
 
@@ -979,10 +1025,10 @@
 	g_ptr_array_free (summary, TRUE);
 	
 	if (quick && expunge) {
-		int dcount =0;
+		guint32 dcount =0;
 
 	
-		if (camel_db_count_deleted_message_info (s->folder->cdb, s->folder->full_name, &dcount, ex) == -1)
+		if (camel_db_count_deleted_message_info (s->folder->parent_store->cdb_w, s->folder->full_name, &dcount, ex) == -1)
 			return -1;
 		if (dcount)
 			quick = FALSE;
@@ -1191,7 +1237,7 @@
 			info = NULL;
 		}
 	}
-	camel_db_delete_uids (s->folder->cdb, s->folder->full_name, del, ex);
+	camel_db_delete_uids (s->folder->parent_store->cdb_w, s->folder->full_name, del, ex);
 	g_slist_foreach (del, (GFunc) camel_pstring_free, NULL);
 	g_slist_free (del);
 
@@ -1211,6 +1257,7 @@
 				info->info.info.flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV
 							   |CAMEL_MESSAGE_FOLDER_FLAGGED
 							   |CAMEL_MESSAGE_FOLDER_XEVCHANGE);
+				((CamelMessageInfo *)info)->dirty = TRUE;
 				camel_folder_summary_touch(s);
 			}
 			camel_message_info_free((CamelMessageInfo *)info);

Modified: branches/gnome-2-24/camel/providers/local/camel-mh-summary.c
==============================================================================
--- branches/gnome-2-24/camel/providers/local/camel-mh-summary.c	(original)
+++ branches/gnome-2-24/camel/providers/local/camel-mh-summary.c	Mon Oct  6 10:46:16 2008
@@ -34,6 +34,7 @@
 
 #include <glib/gi18n-lib.h>
 
+#include "camel-store.h"
 #include "camel-mime-message.h"
 #include "camel-private.h"
 
@@ -116,12 +117,23 @@
 static int 
 sort_uid_cmp (void *enc, int len1, void * data1, int len2, void *data2)
 {
-	char *sa1 = (char*)g_utf8_normalize (data1, len1, G_NORMALIZE_DEFAULT);
-	char *sa2 = (char*)g_utf8_normalize (data2, len2, G_NORMALIZE_DEFAULT);
-	int a1 = strtoul (sa1, NULL, 10);
-	int a2 = strtoul (sa2, NULL, 10);
+	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;	
 
-	g_free(sa1); g_free(sa2);
+	a1 = strtoul (sa1, NULL, 10);
+	a2 = strtoul (sa2, NULL, 10);
 
 	return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
 }
@@ -139,8 +151,11 @@
 
 	((CamelFolderSummary *)o)->folder = folder;
 	if (folder) {
-		camel_db_set_collate (folder->cdb, "uid", "uid_sort", (CamelDBCollate)sort_uid_cmp);
+		camel_db_set_collate (folder->parent_store->cdb_r, "uid", "mh_uid_sort", (CamelDBCollate)sort_uid_cmp);
+		((CamelFolderSummary *)o)->sort_by = "uid";
+		((CamelFolderSummary *)o)->collate = "mh_uid_sort";
 	}
+
 	camel_local_summary_construct((CamelLocalSummary *)o, filename, mhdir, index);
 	return o;
 }

Modified: branches/gnome-2-24/camel/providers/local/camel-spool-summary.c
==============================================================================
--- branches/gnome-2-24/camel/providers/local/camel-spool-summary.c	(original)
+++ branches/gnome-2-24/camel/providers/local/camel-spool-summary.c	Mon Oct  6 10:46:16 2008
@@ -37,6 +37,7 @@
 #include "camel-file-utils.h"
 #include "camel-mime-message.h"
 #include "camel-operation.h"
+#include "camel-store.h"
 
 #include "camel-spool-summary.h"
 
@@ -108,14 +109,25 @@
 static int 
 frompos_sort (void *enc, int len1, void * data1, int len2, void *data2)
 {
-	char *sa1 = (char*)g_utf8_normalize (data1, len1, G_NORMALIZE_DEFAULT);
-	char *sa2 = (char*)g_utf8_normalize (data2, len2, G_NORMALIZE_DEFAULT);
-	int a1 = strtoul (sa1, NULL, 10);
-	int a2 = strtoul (sa2, NULL, 10);
+	static char *sa1=NULL, *sa2=NULL;
+	static int l1=0, l2=0;
+	int a1, a2;
 
-	g_free(sa1); g_free(sa2);
+	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 > a2;
+	return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
 }
 
 CamelSpoolSummary *
@@ -125,9 +137,9 @@
 
 	((CamelFolderSummary *)new)->folder = folder;
 	if (folder) {
-		/* Set the functions for db sorting */
-		/* FIXME: Add column names though a #define */
-		camel_db_set_collate (folder->cdb, "bdata", "frompos_sort", (CamelDBCollate)frompos_sort);
+		camel_db_set_collate (folder->parent_store->cdb_r, "bdata", "spool_frompos_sort", (CamelDBCollate)frompos_sort);
+		((CamelFolderSummary *)new)->sort_by = "bdata";
+		((CamelFolderSummary *)new)->collate = "spool_frompos_sort";
 	}
 	camel_local_summary_construct((CamelLocalSummary *)new, NULL, mbox_name, NULL);
 	camel_folder_summary_load_from_db ((CamelFolderSummary *)new, NULL);

Modified: branches/gnome-2-24/camel/providers/nntp/camel-nntp-folder.c
==============================================================================
--- branches/gnome-2-24/camel/providers/nntp/camel-nntp-folder.c	(original)
+++ branches/gnome-2-24/camel/providers/nntp/camel-nntp-folder.c	Mon Oct  6 10:46:16 2008
@@ -274,6 +274,25 @@
 	return matches;
 }
 
+static guint32
+nntp_folder_count_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
+{
+	CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
+	guint32 count;
+	
+	CAMEL_NNTP_FOLDER_LOCK(nntp_folder, search_lock);
+	
+	if (nntp_folder->search == NULL)
+		nntp_folder->search = camel_folder_search_new ();
+	
+	camel_folder_search_set_folder (nntp_folder->search, folder);
+	count = camel_folder_search_count(nntp_folder->search, expression, ex);
+	
+	CAMEL_NNTP_FOLDER_UNLOCK(nntp_folder, search_lock);
+	
+	return count;
+}
+
 static GPtrArray *
 nntp_folder_search_by_uids (CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
 {
@@ -461,6 +480,7 @@
 	camel_folder_class->set_message_flags = nntp_folder_set_message_flags;
 	camel_folder_class->get_message = nntp_folder_get_message;
 	camel_folder_class->search_by_expression = nntp_folder_search_by_expression;
+	camel_folder_class->count_by_expression = nntp_folder_count_by_expression;
 	camel_folder_class->search_by_uids = nntp_folder_search_by_uids;
 	camel_folder_class->search_free = nntp_folder_search_free;
 }



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