[evolution-data-server] Retrieving and storing bodystructure from IMAP servers



commit e41c2f1e84a15db63d8c292190148b57f1d37f2b
Author: Philip Van Hoof <philip codeminded be>
Date:   Mon Aug 17 15:51:55 2009 +0200

    Retrieving and storing bodystructure from IMAP servers

 camel/camel-db.c                                   |   33 +++++++++++++++++--
 camel/camel-db.h                                   |    1 +
 camel/camel-digest-folder.c                        |    2 +-
 camel/camel-folder-summary.c                       |   21 +++++++++---
 camel/camel-folder-summary.h                       |    6 ++--
 .../providers/groupwise/camel-groupwise-journal.c  |    2 +-
 .../providers/groupwise/camel-groupwise-summary.c  |    2 +-
 camel/providers/imap/camel-imap-folder.c           |    9 +++--
 camel/providers/imap/camel-imap-summary.c          |    2 +-
 9 files changed, 59 insertions(+), 19 deletions(-)
---
diff --git a/camel/camel-db.c b/camel/camel-db.c
index 0c19e7c..5e7ce51 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -1140,7 +1140,11 @@ camel_db_create_message_info_table (CamelDB *cdb, const gchar *folder_name, Came
 	gchar *table_creation_query, *safe_index;
 
 	/* README: It is possible to compress all system flags into a single column and use just as userflags but that makes querying for other applications difficult an d bloats the parsing code. Instead, it is better to bloat the tables. Sqlite should have some optimizations for sparse columns etc. */
-	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS %Q (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , dirty INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT, created TEXT, modified TEXT )", folder_name);
+	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS %Q (  uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , dirty INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT, created TEXT, modified TEXT)", folder_name);
+	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
+	sqlite3_free (table_creation_query);
+
+	table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%s_bodystructure' (  uid TEXT PRIMARY KEY , bodystructure TEXT )", folder_name);
 	ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
 	sqlite3_free (table_creation_query);
 
@@ -1196,6 +1200,7 @@ camel_db_migrate_folder_prepare (CamelDB *cdb, const gchar *folder_name, gint ve
 	/* Migration stage one: storing the old data */
 
 	if (version < 1) {
+
 		/* Between version 0-1 the following things are changed
 		 * ADDED: created: time
 		 * ADDED: modified: time
@@ -1235,7 +1240,7 @@ camel_db_migrate_folder_recreate (CamelDB *cdb, const gchar *folder_name, gint v
 
 	/* Migration stage two: writing back the old data */
 
-	if (version < 1) {
+	if (version < 2) {
 		table_creation_query = sqlite3_mprintf ("INSERT INTO %Q SELECT uid , flags , msg_type , read , deleted , replied , important , junk , attachment , dirty , size , dsent , dreceived , subject , mail_from , mail_to , mail_cc , mlist , followup_flag , followup_completed_on , followup_due_by , part , labels , usertags , cinfo , bdata, created, modified FROM 'mem.%q'", folder_name, folder_name);
 		ret = camel_db_add_to_transaction (cdb, table_creation_query, ex);
 		sqlite3_free (table_creation_query);
@@ -1285,9 +1290,9 @@ camel_db_write_folder_version (CamelDB *cdb, const gchar *folder_name, gint old_
 	version_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%q_version' ( version TEXT )", folder_name);
 
 	if (old_version == -1)
-		version_insert_query = sqlite3_mprintf ("INSERT INTO '%q_version' VALUES ('1')", folder_name);
+		version_insert_query = sqlite3_mprintf ("INSERT INTO '%q_version' VALUES ('2')", folder_name);
 	else
-		version_insert_query = sqlite3_mprintf ("UPDATE '%q_version' SET version='1'", folder_name);
+		version_insert_query = sqlite3_mprintf ("UPDATE '%q_version' SET version='2'", folder_name);
 
 	ret = camel_db_add_to_transaction (cdb, version_creation_query, ex);
 	ret = camel_db_add_to_transaction (cdb, version_insert_query, ex);
@@ -1399,6 +1404,13 @@ write_mir (CamelDB *cdb, const gchar *folder_name, CamelMIRecord *record, CamelE
 			sqlite3_free (del_query); */
 	sqlite3_free (ins_query);
 
+	if (ret == 0) {
+		ins_query = sqlite3_mprintf ("INSERT OR REPLACE INTO '%s_bodystructure' VALUES (%Q, %Q )",
+				folder_name, record->uid, record->bodystructure);
+		ret = camel_db_add_to_transaction (cdb, ins_query, ex);
+		sqlite3_free (ins_query);
+	}
+
 	return ret;
 }
 
@@ -1568,6 +1580,10 @@ camel_db_delete_uid (CamelDB *cdb, const gchar *folder, const gchar *uid, CamelE
 
 	ret = camel_db_trim_deleted_table (cdb, ex);
 
+	tab = sqlite3_mprintf ("DELETE FROM '%s_bodystructure' WHERE uid = %Q", folder, uid);
+	ret = camel_db_add_to_transaction (cdb, tab, ex);
+	sqlite3_free (tab);
+
 	tab = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder, uid);
 	ret = camel_db_add_to_transaction (cdb, tab, ex);
 	sqlite3_free (tab);
@@ -1671,10 +1687,12 @@ camel_db_clear_folder_summary (CamelDB *cdb, gchar *folder, CamelException *ex)
 
 	gchar *folders_del;
 	gchar *msginfo_del;
+	gchar *bstruct_del;
 	gchar *tab;
 
 	folders_del = sqlite3_mprintf ("DELETE FROM folders WHERE folder_name = %Q", folder);
 	msginfo_del = sqlite3_mprintf ("DELETE FROM %Q ", folder);
+	bstruct_del = sqlite3_mprintf ("DELETE FROM '%s_bodystructure' ", folder);
 
 	camel_db_begin_transaction (cdb, ex);
 
@@ -1688,11 +1706,13 @@ camel_db_clear_folder_summary (CamelDB *cdb, gchar *folder, CamelException *ex)
 
 	camel_db_add_to_transaction (cdb, msginfo_del, ex);
 	camel_db_add_to_transaction (cdb, folders_del, ex);
+	camel_db_add_to_transaction (cdb, bstruct_del, ex);
 
 	ret = camel_db_end_transaction (cdb, ex);
 
 	sqlite3_free (folders_del);
 	sqlite3_free (msginfo_del);
+	sqlite3_free (bstruct_del);
 
 	return ret;
 }
@@ -1722,6 +1742,10 @@ camel_db_delete_folder (CamelDB *cdb, const gchar *folder, CamelException *ex)
 	ret = camel_db_add_to_transaction (cdb, del, ex);
 	sqlite3_free (del);
 
+	del = sqlite3_mprintf ("DROP TABLE '%s_bodystructure' ", folder);
+	ret = camel_db_add_to_transaction (cdb, del, ex);
+	sqlite3_free (del);
+
 	ret = camel_db_end_transaction (cdb, ex);
 
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
@@ -1784,6 +1808,7 @@ camel_db_camel_mir_free (CamelMIRecord *record)
 		g_free (record->usertags);
 		g_free (record->cinfo);
 		g_free (record->bdata);
+		g_free (record->bodystructure);
 
 		g_free (record);
 	}
diff --git a/camel/camel-db.h b/camel/camel-db.h
index 540f5da..dfd3a73 100644
--- a/camel/camel-db.h
+++ b/camel/camel-db.h
@@ -84,6 +84,7 @@ typedef struct _CamelMIRecord {
 	gchar *usertags;
 	gchar *cinfo;
 	gchar *bdata;
+	gchar *bodystructure;
 } CamelMIRecord;
 
 typedef struct _CamelFIRecord {
diff --git a/camel/camel-digest-folder.c b/camel/camel-digest-folder.c
index 94f8f22..6886312 100644
--- a/camel/camel-digest-folder.c
+++ b/camel/camel-digest-folder.c
@@ -196,7 +196,7 @@ digest_add_multipart (CamelFolder *folder, CamelMultipart *multipart, const gcha
 			continue;
 		}
 
-		info = camel_folder_summary_info_new_from_message (folder->summary, CAMEL_MIME_MESSAGE (wrapper));
+		info = camel_folder_summary_info_new_from_message (folder->summary, CAMEL_MIME_MESSAGE (wrapper), NULL);
 		camel_pstring_free(info->uid);
 		tmp = g_strdup_printf ("%s%d", preuid, i);
 		info->uid = camel_pstring_strdup (tmp);
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 1d4a791..b0e9ed0 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -116,7 +116,7 @@ static gint summary_meta_header_save(CamelFolderSummary *, FILE *);
 
 static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
-static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg);
+static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg, const gchar *bodystructure);
 static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
 static gint		  message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *);
 static gint		  meta_message_info_save(CamelFolderSummary *s, FILE *out_meta, FILE *out, CamelMessageInfo *info);
@@ -1168,6 +1168,9 @@ mir_from_cols (CamelMIRecord *mir, CamelFolderSummary *s, gint ncol, gchar ** co
 			mir->cinfo = g_strdup(cols [i]);
 		else if ( !strcmp (name [i], "bdata") )
 			mir->bdata = g_strdup(cols [i]);
+		/* Evolution itself doesn't yet use this, ignoring
+		else if ( !strcmp (name [i], "bodystructure") )
+			mir->bodystructure = g_strdup(cols [i]); */
 
 	}
 }
@@ -2084,7 +2087,7 @@ camel_folder_summary_add_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
 CamelMessageInfo *
 camel_folder_summary_add_from_message (CamelFolderSummary *s, CamelMimeMessage *msg)
 {
-	CamelMessageInfo *info = camel_folder_summary_info_new_from_message(s, msg);
+	CamelMessageInfo *info = camel_folder_summary_info_new_from_message(s, msg, NULL);
 
 	camel_folder_summary_add (s, info);
 	update_summary (s, (CamelMessageInfoBase *) info);
@@ -2181,6 +2184,7 @@ camel_folder_summary_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser
  * camel_folder_summary_info_new_from_message:
  * @summary: a #CamelFodlerSummary object
  * @message: a #CamelMimeMessage object
+ * @boydstructure: a bodystructure or NULL
  *
  * Create a summary item from a message.
  *
@@ -2188,13 +2192,13 @@ camel_folder_summary_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser
  * #camel_message_info_free
  **/
 CamelMessageInfo *
-camel_folder_summary_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg)
+camel_folder_summary_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg, const gchar *bodystructure)
 {
 	CamelMessageInfo *info;
 	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
 	CamelIndexName *name = NULL;
 
-	info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_message(s, msg);
+	info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_message(s, msg, bodystructure);
 
 	/* assign a unique uid, this is slightly 'wrong' as we do not really
 	 * know if we are going to store this in the summary, but we need it set for indexing */
@@ -2996,11 +3000,12 @@ content_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
 }
 
 static CamelMessageInfo *
-message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg)
+message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg, const gchar *bodystructure)
 {
 	CamelMessageInfo *mi;
 
 	mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
+	((CamelMessageInfoBase *)mi)->bodystructure = g_strdup (bodystructure);
 
 	return mi;
 }
@@ -3222,6 +3227,9 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
 	mi->cc = (gchar *) camel_pstring_add (record->cc, FALSE);
 	mi->mlist = (gchar *) camel_pstring_add (record->mlist, FALSE);
 
+	/* Evolution itself doesn't yet use this, so we ignore it (saving some memory) */
+	mi->bodystructure = NULL;
+
 	/* Extract Message id & References */
 	mi->content = NULL;
 	part = record->part;
@@ -3408,6 +3416,8 @@ message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info)
 	record->followup_completed_on = (gchar *) camel_pstring_strdup(camel_message_info_user_tag(info, "completed-on"));
 	record->followup_due_by = (gchar *) camel_pstring_strdup(camel_message_info_user_tag(info, "due-by"));
 
+	record->bodystructure = mi->bodystructure ? g_strdup (mi->bodystructure) : NULL;
+
 	tmp = g_string_new (NULL);
 	if (mi->references) {
 		g_string_append_printf (tmp, "%lu %lu %lu", (gulong)mi->message_id.id.part.hi, (gulong)mi->message_id.id.part.lo, (gulong)mi->references->size);
@@ -3519,6 +3529,7 @@ message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
 	camel_pstring_free(mi->to);
 	camel_pstring_free(mi->cc);
 	camel_pstring_free(mi->mlist);
+	g_free (mi->bodystructure);
 	g_free(mi->references);
 	g_free (mi->preview);
 	camel_flag_list_free(&mi->user_flags);
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index 6281d18..560a882 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -188,7 +188,7 @@ struct _CamelMessageInfoBase {
 	CamelMessageContentInfo *content;
 	struct _camel_header_param *headers;
 	gchar *preview;
-
+	gchar *bodystructure;
 };
 
 /* probably do this as well, removing CamelFolderChangeInfo and interfaces
@@ -275,7 +275,7 @@ struct _CamelFolderSummaryClass {
 	/* create/save/load an individual message info */
 	CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
 	CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
-	CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *);
+	CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *, const gchar *);
 	CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *);
 	gint		   (*message_info_save)(CamelFolderSummary *, FILE *, CamelMessageInfo *);
 	gint		   (*meta_message_info_save)(CamelFolderSummary *, FILE *, FILE *, CamelMessageInfo *);
@@ -380,7 +380,7 @@ CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *summ
 /* Just build raw summary items */
 CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *summary, struct _camel_header_raw *headers);
 CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *summary, CamelMimeParser *parser);
-CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary *summary, CamelMimeMessage *message);
+CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary *summary, CamelMimeMessage *message, const gchar *bodystructure);
 
 CamelMessageContentInfo *camel_folder_summary_content_info_new(CamelFolderSummary *summary);
 void camel_folder_summary_content_info_free(CamelFolderSummary *summary, CamelMessageContentInfo *ci);
diff --git a/camel/providers/groupwise/camel-groupwise-journal.c b/camel/providers/groupwise/camel-groupwise-journal.c
index 6e34e36..1068b34 100644
--- a/camel/providers/groupwise/camel-groupwise-journal.c
+++ b/camel/providers/groupwise/camel-groupwise-journal.c
@@ -367,7 +367,7 @@ update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *messag
 
 	camel_object_unref (cache);
 
-	info = camel_folder_summary_info_new_from_message (folder->summary, message);
+	info = camel_folder_summary_info_new_from_message (folder->summary, message, NULL);
 	camel_pstring_free(info->uid);
 	info->uid = camel_pstring_strdup (uid);
 
diff --git a/camel/providers/groupwise/camel-groupwise-summary.c b/camel/providers/groupwise/camel-groupwise-summary.c
index fe1273e..b765645 100644
--- a/camel/providers/groupwise/camel-groupwise-summary.c
+++ b/camel/providers/groupwise/camel-groupwise-summary.c
@@ -427,7 +427,7 @@ camel_gw_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, Cam
 	const CamelTag *tag;
 
 	/* Create summary entry */
-	mi = (CamelGroupwiseMessageInfo *)camel_folder_summary_info_new_from_message (summary, message);
+	mi = (CamelGroupwiseMessageInfo *)camel_folder_summary_info_new_from_message (summary, message, NULL);
 
 	/* Copy flags 'n' tags */
 	mi->info.flags = camel_message_info_flags(info);
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index f34d313..69e2d9d 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -3239,6 +3239,7 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
 	CamelStream *stream;
 	CamelImapMessageInfo *mi;
 	const gchar *idate;
+	const gchar *bodystructure;
 	gint seq;
 
 	seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
@@ -3257,7 +3258,9 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
 		return;
 	}
 
-	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg);
+	bodystructure = g_datalist_get_data (&data, "BODY");
+
+	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg, bodystructure);
 	camel_object_unref (CAMEL_OBJECT (msg));
 
 	if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
@@ -3413,7 +3416,7 @@ imap_update_summary (CamelFolder *folder, gint exists,
 	size = (exists - seq) * (IMAP_PRETEND_SIZEOF_FLAGS + IMAP_PRETEND_SIZEOF_SIZE + IMAP_PRETEND_SIZEOF_HEADERS);
 	got = 0;
 	if (!camel_imap_command_start (store, folder, ex,
-				       "UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[%s])",
+				       "UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODYSTRUCTURE BODY.PEEK[%s])",
 				       uidval + 1, header_spec->str)) {
 		g_string_free (header_spec, TRUE);
 		return;
@@ -3499,7 +3502,7 @@ imap_update_summary (CamelFolder *folder, gint exists,
 		while (uid < needheaders->len && !camel_application_is_exiting) {
 			uidset = imap_uid_array_to_set (folder->summary, needheaders, uid, UID_SET_LIMIT, &uid);
 			if (!camel_imap_command_start (store, folder, ex,
-						       "UID FETCH %s BODY.PEEK[%s]",
+						       "UID FETCH %s BODYSTRUCTURE BODY.PEEK[%s]",
 						       uidset, header_spec->str)) {
 				g_ptr_array_free (needheaders, TRUE);
 				camel_operation_end (NULL);
diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c
index 3a30530..a8c2328 100644
--- a/camel/providers/imap/camel-imap-summary.c
+++ b/camel/providers/imap/camel-imap-summary.c
@@ -454,7 +454,7 @@ camel_imap_summary_add_offline (CamelFolderSummary *summary, const gchar *uid,
 	const CamelTag *tag;
 
 	/* Create summary entry */
-	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message);
+	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message, NULL);
 
 	/* Copy flags 'n' tags */
 	mi->info.flags = camel_message_info_flags(info);



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