evolution-data-server r9641 - in trunk/camel: . providers/groupwise providers/imap providers/local providers/nntp



Author: sragavan
Date: Mon Oct  6 10:27:15 2008
New Revision: 9641
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9641&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:
   trunk/camel/ChangeLog
   trunk/camel/camel-db.c
   trunk/camel/camel-db.h
   trunk/camel/camel-folder-search.c
   trunk/camel/camel-folder-search.h
   trunk/camel/camel-folder-summary.c
   trunk/camel/camel-folder-summary.h
   trunk/camel/camel-folder.c
   trunk/camel/camel-folder.h
   trunk/camel/camel-search-sql-sexp.c
   trunk/camel/camel-store.c
   trunk/camel/camel-store.h
   trunk/camel/camel-vee-folder.c
   trunk/camel/camel-vee-summary.c
   trunk/camel/camel-vtrash-folder.c
   trunk/camel/providers/groupwise/camel-groupwise-folder.c
   trunk/camel/providers/imap/camel-imap-folder.c
   trunk/camel/providers/imap/camel-imap-store.c
   trunk/camel/providers/imap/camel-imap-summary.c
   trunk/camel/providers/local/camel-local-folder.c
   trunk/camel/providers/local/camel-local-store.c
   trunk/camel/providers/local/camel-maildir-summary.c
   trunk/camel/providers/local/camel-mbox-summary.c
   trunk/camel/providers/local/camel-mh-summary.c
   trunk/camel/providers/local/camel-spool-summary.c
   trunk/camel/providers/nntp/camel-nntp-folder.c

Modified: trunk/camel/camel-db.c
==============================================================================
--- trunk/camel/camel-db.c	(original)
+++ trunk/camel/camel-db.c	Mon Oct  6 10:27:15 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);
@@ -755,10 +747,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: trunk/camel/camel-db.h
==============================================================================
--- trunk/camel/camel-db.h	(original)
+++ trunk/camel/camel-db.h	Mon Oct  6 10:27:15 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: trunk/camel/camel-folder-search.c
==============================================================================
--- trunk/camel/camel-folder-search.c	(original)
+++ trunk/camel/camel-folder-search.c	Mon Oct  6 10:27:15 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: trunk/camel/camel-folder-search.h
==============================================================================
--- trunk/camel/camel-folder-search.h	(original)
+++ trunk/camel/camel-folder-search.h	Mon Oct  6 10:27:15 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: trunk/camel/camel-folder-summary.c
==============================================================================
--- trunk/camel/camel-folder-summary.c	(original)
+++ trunk/camel/camel-folder-summary.c	Mon Oct  6 10:27:15 2008
@@ -492,6 +492,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;
@@ -511,7 +521,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;
 		
@@ -520,7 +530,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);
@@ -531,12 +541,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);
 
@@ -548,8 +555,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);
 		}
@@ -861,7 +867,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;
@@ -874,7 +880,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;
 }
@@ -907,9 +913,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
@@ -1124,7 +1130,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;
 
@@ -1273,7 +1279,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)
@@ -1304,7 +1310,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;
@@ -1324,7 +1330,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;
 
@@ -1378,7 +1384,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;
 
@@ -1557,7 +1563,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);
@@ -2070,7 +2076,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) {
@@ -2137,7 +2143,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);
@@ -2174,7 +2180,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 ;
 				}
@@ -2299,7 +2305,7 @@
 		camel_exception_init (&ex);
 
 		folder_name = s->folder->full_name;
-		cdb = s->folder->cdb;
+		cdb = s->folder->parent_store->cdb_w;
 
 		/* FIXME[disk-summary] lifecycle of infos should be checked.
 		 * Add should add to db and del should del to db. Sync only
@@ -2615,8 +2621,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"));
@@ -3147,6 +3153,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: trunk/camel/camel-folder-summary.h
==============================================================================
--- trunk/camel/camel-folder-summary.h	(original)
+++ trunk/camel/camel-folder-summary.h	Mon Oct  6 10:27:15 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: trunk/camel/camel-folder.c
==============================================================================
--- trunk/camel/camel-folder.c	(original)
+++ trunk/camel/camel-folder.c	Mon Oct  6 10:27:15 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);
 }
 
 
@@ -1387,6 +1364,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)
 {
@@ -1603,7 +1621,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);
 }
@@ -1641,7 +1659,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: trunk/camel/camel-folder.h
==============================================================================
--- trunk/camel/camel-folder.h	(original)
+++ trunk/camel/camel-folder.h	Mon Oct  6 10:27:15 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: trunk/camel/camel-search-sql-sexp.c
==============================================================================
--- trunk/camel/camel-search-sql-sexp.c	(original)
+++ trunk/camel/camel-search-sql-sexp.c	Mon Oct  6 10:27:15 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: trunk/camel/camel-store.c
==============================================================================
--- trunk/camel/camel-store.c	(original)
+++ trunk/camel/camel-store.c	Mon Oct  6 10:27:15 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: trunk/camel/camel-store.h
==============================================================================
--- trunk/camel/camel-store.h	(original)
+++ trunk/camel/camel-store.h	Mon Oct  6 10:27:15 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: trunk/camel/camel-vee-folder.c
==============================================================================
--- trunk/camel/camel-vee-folder.c	(original)
+++ trunk/camel/camel-vee-folder.c	Mon Oct  6 10:27:15 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)
 {
@@ -1006,7 +1032,7 @@
 		/* FIXME[disk-summary] 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);
@@ -1136,13 +1162,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 */
@@ -1313,7 +1339,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);
@@ -1355,8 +1381,8 @@
 	}
 	camel_folder_change_info_remove_uid(vf->changes, vuid);
         /* FIXME[disk-summary] 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);
+	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) {
@@ -1522,7 +1548,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);
@@ -1655,7 +1681,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 */
@@ -2000,7 +2026,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);
@@ -2042,6 +2068,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;
@@ -2166,7 +2193,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);
 }
 
@@ -2184,7 +2211,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: trunk/camel/camel-vee-summary.c
==============================================================================
--- trunk/camel/camel-vee-summary.c	(original)
+++ trunk/camel/camel-vee-summary.c	Mon Oct  6 10:27:15 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)
@@ -333,7 +333,7 @@
         /* 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->cdb, parent->full_name, NULL);
+	camel_db_create_vfolder (parent->parent_store->cdb_w, parent->full_name, NULL);
 
 	/* FIXME[disk-summary] handle excep and ret */
 	camel_folder_summary_header_load_from_db ((CamelFolderSummary *)s, parent->parent_store, parent->full_name, NULL);
@@ -348,7 +348,7 @@
 	GPtrArray *array;
 
 	/* FIXME[disk-summary] fix exception passing */
-	array = camel_db_get_vuids_from_vfolder(cfs->folder->cdb, cfs->folder->full_name, shash, NULL);
+	array = camel_db_get_vuids_from_vfolder(cfs->folder->parent_store->cdb_r, cfs->folder->full_name, shash, NULL);
 	
 	g_free(shash);
 

Modified: trunk/camel/camel-vtrash-folder.c
==============================================================================
--- trunk/camel/camel-vtrash-folder.c	(original)
+++ trunk/camel/camel-vtrash-folder.c	Mon Oct  6 10:27:15 2008
@@ -523,14 +523,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: trunk/camel/providers/groupwise/camel-groupwise-folder.c
==============================================================================
--- trunk/camel/providers/groupwise/camel-groupwise-folder.c	(original)
+++ trunk/camel/providers/groupwise/camel-groupwise-folder.c	Mon Oct  6 10:27:15 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)
 {
@@ -2402,6 +2416,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: trunk/camel/providers/imap/camel-imap-folder.c
==============================================================================
--- trunk/camel/providers/imap/camel-imap-folder.c	(original)
+++ trunk/camel/providers/imap/camel-imap-folder.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/imap/camel-imap-store.c
==============================================================================
--- trunk/camel/providers/imap/camel-imap-store.c	(original)
+++ trunk/camel/providers/imap/camel-imap-store.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/imap/camel-imap-summary.c
==============================================================================
--- trunk/camel/providers/imap/camel-imap-summary.c	(original)
+++ trunk/camel/providers/imap/camel-imap-summary.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/local/camel-local-folder.c
==============================================================================
--- trunk/camel/providers/local/camel-local-folder.c	(original)
+++ trunk/camel/providers/local/camel-local-folder.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/local/camel-local-store.c
==============================================================================
--- trunk/camel/providers/local/camel-local-store.c	(original)
+++ trunk/camel/providers/local/camel-local-store.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/local/camel-maildir-summary.c
==============================================================================
--- trunk/camel/providers/local/camel-maildir-summary.c	(original)
+++ trunk/camel/providers/local/camel-maildir-summary.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/local/camel-mbox-summary.c
==============================================================================
--- trunk/camel/providers/local/camel-mbox-summary.c	(original)
+++ trunk/camel/providers/local/camel-mbox-summary.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/local/camel-mh-summary.c
==============================================================================
--- trunk/camel/providers/local/camel-mh-summary.c	(original)
+++ trunk/camel/providers/local/camel-mh-summary.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/local/camel-spool-summary.c
==============================================================================
--- trunk/camel/providers/local/camel-spool-summary.c	(original)
+++ trunk/camel/providers/local/camel-spool-summary.c	Mon Oct  6 10:27:15 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: trunk/camel/providers/nntp/camel-nntp-folder.c
==============================================================================
--- trunk/camel/providers/nntp/camel-nntp-folder.c	(original)
+++ trunk/camel/providers/nntp/camel-nntp-folder.c	Mon Oct  6 10:27:15 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]