[evolution-data-server] Camel: Special-case search for the match of the MESSAGE-ID headers
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Camel: Special-case search for the match of the MESSAGE-ID headers
- Date: Thu, 29 Oct 2020 11:57:49 +0000 (UTC)
commit f302e70f991d9d351ef27ecc552d8a506d2f9524
Author: Milan Crha <mcrha redhat com>
Date: Thu Oct 29 12:55:00 2020 +0100
Camel: Special-case search for the match of the MESSAGE-ID headers
This helps to search for it quickly, by using the local summary data.
Related to https://bugzilla.gnome.org/show_bug.cgi?id=788192
docs/reference/camel/camel-docs.sgml.in | 4 +++
src/camel/camel-folder-search.c | 49 +++++++++++++++++++++++++++++++++
src/camel/camel-folder-search.h | 3 ++
src/camel/camel-folder-summary.c | 38 +++++--------------------
src/camel/camel-search-sql-sexp.c | 15 +++++++++-
5 files changed, 77 insertions(+), 32 deletions(-)
---
diff --git a/docs/reference/camel/camel-docs.sgml.in b/docs/reference/camel/camel-docs.sgml.in
index 25dd20102..f72214645 100644
--- a/docs/reference/camel/camel-docs.sgml.in
+++ b/docs/reference/camel/camel-docs.sgml.in
@@ -297,6 +297,10 @@
<title>Index of deprecated symbols</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-3-40" role="3.40">
+ <title>Index of new symbols in 3.40</title>
+ <xi:include href="xml/api-index-3.40.xml"><xi:fallback /></xi:include>
+ </index>
<index id="api-index-3-38" role="3.38">
<title>Index of new symbols in 3.38</title>
<xi:include href="xml/api-index-3.38.xml"><xi:fallback /></xi:include>
diff --git a/src/camel/camel-folder-search.c b/src/camel/camel-folder-search.c
index 858ff79f4..b5db023b2 100644
--- a/src/camel/camel-folder-search.c
+++ b/src/camel/camel-folder-search.c
@@ -342,6 +342,7 @@ check_header (CamelSExp *sexp,
const gchar *header = NULL, *charset = NULL;
gchar strbuf[32];
gint i, j;
+ gboolean is_message_id = FALSE;
camel_search_t type = CAMEL_SEARCH_TYPE_ASIS;
struct _camel_search_words *words;
CamelMimeMessage *message = NULL;
@@ -368,6 +369,8 @@ check_header (CamelSExp *sexp,
} else if (!g_ascii_strcasecmp (headername, "x-camel-mlist")) {
header = camel_message_info_get_mlist (search->priv->current);
type = CAMEL_SEARCH_TYPE_MLIST;
+ } else if (how == CAMEL_SEARCH_MATCH_EXACT && !g_ascii_strcasecmp (headername, "MESSAGE-ID"))
{
+ is_message_id = TRUE;
} else {
message = ref_current_message (search);
if (message) {
@@ -417,6 +420,11 @@ check_header (CamelSExp *sexp,
how, type, charset);
}
camel_search_words_free (words);
+ } else if (is_message_id) {
+ guint64 message_id;
+
+ message_id = camel_folder_search_util_hash_message_id
(argv[i]->value.string, TRUE);
+ truth = camel_message_info_get_message_id (search->priv->current) ==
message_id;
} else {
if (message) {
const CamelNameValueArray *headers = NULL;
@@ -2629,3 +2637,44 @@ camel_folder_search_util_compare_date (gint64 datetime1,
return dt1 - dt2;
}
+
+/**
+ * camel_folder_search_util_hash_message_id:
+ * @message_id: a raw Message-ID header value
+ * @needs_decode: whether the @message_id requires camel_header_msgid_decode() first
+ *
+ * Calculates a hash of the Message-ID header value @message_id.
+ *
+ * Returns: hash of the @message_id, or 0 on any error.
+ *
+ * Since: 3.40
+ **/
+guint64
+camel_folder_search_util_hash_message_id (const gchar *message_id,
+ gboolean needs_decode)
+{
+ GChecksum *checksum;
+ CamelSummaryMessageID message_id_struct;
+ gchar *msgid = NULL;
+ guint8 *digest;
+ gsize length;
+
+ if (!message_id)
+ return 0;
+
+ if (needs_decode)
+ msgid = camel_header_msgid_decode (message_id);
+
+ length = g_checksum_type_get_length (G_CHECKSUM_MD5);
+ digest = g_alloca (length);
+
+ checksum = g_checksum_new (G_CHECKSUM_MD5);
+ g_checksum_update (checksum, (guchar *) (msgid ? msgid : message_id), -1);
+ g_checksum_get_digest (checksum, digest, &length);
+ g_checksum_free (checksum);
+
+ memcpy (message_id_struct.id.hash, digest, sizeof (message_id_struct.id.hash));
+ g_free (msgid);
+
+ return message_id_struct.id.id;
+}
diff --git a/src/camel/camel-folder-search.h b/src/camel/camel-folder-search.h
index fc95bf8c1..be6d6f05f 100644
--- a/src/camel/camel-folder-search.h
+++ b/src/camel/camel-folder-search.h
@@ -331,6 +331,9 @@ time_t camel_folder_search_util_make_time
gint camel_folder_search_util_compare_date
(gint64 datetime1,
gint64 datetime2);
+guint64 camel_folder_search_util_hash_message_id
+ (const gchar *message_id,
+ gboolean needs_decode);
G_END_DECLS
#endif /* CAMEL_FOLDER_SEARCH_H */
diff --git a/src/camel/camel-folder-summary.c b/src/camel/camel-folder-summary.c
index 0b33bb5ec..af80a658e 100644
--- a/src/camel/camel-folder-summary.c
+++ b/src/camel/camel-folder-summary.c
@@ -2944,19 +2944,13 @@ static CamelMessageInfo *
message_info_new_from_headers (CamelFolderSummary *summary,
const CamelNameValueArray *headers)
{
- const gchar *received, *date, *content, *charset = NULL;
+ const gchar *received, *date, *content, *charset = NULL, *msgid;
GSList *refs, *irt, *scan;
gchar *subject, *from, *to, *cc, *mlist;
CamelContentType *ct = NULL;
CamelMessageInfo *mi;
- guint8 *digest;
- gsize length;
- gchar *msgid;
guint count;
- length = g_checksum_type_get_length (G_CHECKSUM_MD5);
- digest = g_alloca (length);
-
mi = camel_message_info_new (summary);
camel_message_info_set_abort_notifications (mi, TRUE);
@@ -3008,28 +3002,15 @@ message_info_new_from_headers (CamelFolderSummary *summary,
if (!camel_message_info_get_date_sent (mi))
camel_message_info_set_date_sent (mi, (gint64) time (NULL));
- msgid = camel_header_msgid_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "Message-ID"));
- if (msgid) {
- GChecksum *checksum;
- CamelSummaryMessageID message_id;
-
- checksum = g_checksum_new (G_CHECKSUM_MD5);
- g_checksum_update (checksum, (guchar *) msgid, -1);
- g_checksum_get_digest (checksum, digest, &length);
- g_checksum_free (checksum);
-
- memcpy (message_id.id.hash, digest, sizeof (message_id.id.hash));
- g_free (msgid);
-
- camel_message_info_set_message_id (mi, message_id.id.id);
- }
+ msgid = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Message-ID");
+ if (msgid)
+ camel_message_info_set_message_id (mi, camel_folder_search_util_hash_message_id (msgid,
TRUE));
/* decode our references and in-reply-to headers */
refs = camel_header_references_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "References"));
irt = camel_header_references_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "In-Reply-To"));
if (refs || irt) {
GArray *references;
- CamelSummaryMessageID message_id;
if (irt) {
/* The References field is populated from the "References" and/or "In-Reply-To"
@@ -3046,16 +3027,11 @@ message_info_new_from_headers (CamelFolderSummary *summary,
references = g_array_sized_new (FALSE, FALSE, sizeof (guint64), count);
for (scan = refs; scan != NULL; scan = g_slist_next (scan)) {
- GChecksum *checksum;
-
- checksum = g_checksum_new (G_CHECKSUM_MD5);
- g_checksum_update (checksum, (guchar *) scan->data, -1);
- g_checksum_get_digest (checksum, digest, &length);
- g_checksum_free (checksum);
+ guint64 msgid_hash;
- memcpy (message_id.id.hash, digest, sizeof (message_id.id.hash));
+ msgid_hash = camel_folder_search_util_hash_message_id (scan->data, FALSE);
- g_array_append_val (references, message_id.id.id);
+ g_array_append_val (references, msgid_hash);
}
g_slist_free_full (refs, g_free);
diff --git a/src/camel/camel-search-sql-sexp.c b/src/camel/camel-search-sql-sexp.c
index 59e99435a..d2bfb66fe 100644
--- a/src/camel/camel-search-sql-sexp.c
+++ b/src/camel/camel-search-sql-sexp.c
@@ -391,6 +391,10 @@ check_header (struct _CamelSExp *f,
/* only a subset of headers are supported .. */
headername = camel_db_get_column_name (argv[0]->value.string);
+ if (!headername && how == CAMEL_SEARCH_MATCH_EXACT &&
+ g_ascii_strcasecmp (argv[0]->value.string ? argv[0]->value.string : "", "MESSAGE-ID") ==
0) {
+ headername = g_strdup ("part");
+ }
if (!headername) {
gboolean *pcontains_unknown_column = (gboolean *) data;
*pcontains_unknown_column = TRUE;
@@ -417,7 +421,16 @@ check_header (struct _CamelSExp *f,
value = get_db_safe_string (tstr);
g_free (tstr);
} else if (how == CAMEL_SEARCH_MATCH_EXACT) {
- tstr = g_strdup_printf ("%c%s%c", '%', argv[i]->value.string, '%');
+ if (g_ascii_strcasecmp (headername, "part") == 0) {
+ CamelSummaryMessageID message_id;
+
+ message_id.id.id = camel_folder_search_util_hash_message_id
(argv[i]->value.string, TRUE);
+
+ tstr = g_strdup_printf ("%lu %lu %%", (gulong)
message_id.id.part.hi, (gulong) message_id.id.part.lo);
+ } else {
+ tstr = g_strdup_printf ("%c%s%c", '%', argv[i]->value.string,
'%');
+ }
+
value = get_db_safe_string (tstr);
g_free (tstr);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]