a45cfac
From 16562adadd9e7534852d29b365aaecce0dd43b84 Mon Sep 17 00:00:00 2001
a45cfac
From: Milan Crha <mcrha@redhat.com>
a45cfac
Date: Thu, 11 Jun 2020 19:07:38 +0200
a45cfac
Subject: [PATCH 2/4] evo-I#982 - 'Message contains'-search broken in 3.36.3
a45cfac
a45cfac
Related to https://gitlab.gnome.org/GNOME/evolution/-/issues/982
a45cfac
---
a45cfac
 .../providers/imapx/camel-imapx-folder.c      |   6 +
a45cfac
 .../providers/imapx/camel-imapx-search.c      | 223 +++++++++---------
a45cfac
 .../providers/imapx/camel-imapx-search.h      |   2 +
a45cfac
 3 files changed, 114 insertions(+), 117 deletions(-)
a45cfac
a45cfac
diff --git a/src/camel/providers/imapx/camel-imapx-folder.c b/src/camel/providers/imapx/camel-imapx-folder.c
a45cfac
index 0df26f1e9..1ef5750fc 100644
a45cfac
--- a/src/camel/providers/imapx/camel-imapx-folder.c
a45cfac
+++ b/src/camel/providers/imapx/camel-imapx-folder.c
a45cfac
@@ -347,12 +347,14 @@ imapx_search_by_uids (CamelFolder *folder,
a45cfac
 	imapx_search = CAMEL_IMAPX_SEARCH (imapx_folder->search);
a45cfac
 
a45cfac
 	camel_folder_search_set_folder (imapx_folder->search, folder);
a45cfac
+	camel_imapx_search_clear_cached_results (imapx_search);
a45cfac
 	camel_imapx_search_set_cancellable_and_error (imapx_search, cancellable, error);
a45cfac
 
a45cfac
 	matches = camel_folder_search_search (
a45cfac
 		imapx_folder->search, expression, uids, cancellable, error);
a45cfac
 
a45cfac
 	camel_imapx_search_set_cancellable_and_error (imapx_search, NULL, NULL);
a45cfac
+	camel_imapx_search_clear_cached_results (imapx_search);
a45cfac
 
a45cfac
 	g_mutex_unlock (&imapx_folder->search_lock);
a45cfac
 
a45cfac
@@ -376,12 +378,14 @@ imapx_count_by_expression (CamelFolder *folder,
a45cfac
 	imapx_search = CAMEL_IMAPX_SEARCH (imapx_folder->search);
a45cfac
 
a45cfac
 	camel_folder_search_set_folder (imapx_folder->search, folder);
a45cfac
+	camel_imapx_search_clear_cached_results (imapx_search);
a45cfac
 	camel_imapx_search_set_cancellable_and_error (imapx_search, cancellable, error);
a45cfac
 
a45cfac
 	matches = camel_folder_search_count (
a45cfac
 		imapx_folder->search, expression, cancellable, error);
a45cfac
 
a45cfac
 	camel_imapx_search_set_cancellable_and_error (imapx_search, NULL, NULL);
a45cfac
+	camel_imapx_search_clear_cached_results (imapx_search);
a45cfac
 
a45cfac
 	g_mutex_unlock (&imapx_folder->search_lock);
a45cfac
 
a45cfac
@@ -405,12 +409,14 @@ imapx_search_by_expression (CamelFolder *folder,
a45cfac
 	imapx_search = CAMEL_IMAPX_SEARCH (imapx_folder->search);
a45cfac
 
a45cfac
 	camel_folder_search_set_folder (imapx_folder->search, folder);
a45cfac
+	camel_imapx_search_clear_cached_results (imapx_search);
a45cfac
 	camel_imapx_search_set_cancellable_and_error (imapx_search, cancellable, error);
a45cfac
 
a45cfac
 	matches = camel_folder_search_search (
a45cfac
 		imapx_folder->search, expression, NULL, cancellable, error);
a45cfac
 
a45cfac
 	camel_imapx_search_set_cancellable_and_error (imapx_search, NULL, NULL);
a45cfac
+	camel_imapx_search_clear_cached_results (imapx_search);
a45cfac
 
a45cfac
 	g_mutex_unlock (&imapx_folder->search_lock);
a45cfac
 
a45cfac
diff --git a/src/camel/providers/imapx/camel-imapx-search.c b/src/camel/providers/imapx/camel-imapx-search.c
a45cfac
index 6d68f700e..7c62443b8 100644
a45cfac
--- a/src/camel/providers/imapx/camel-imapx-search.c
a45cfac
+++ b/src/camel/providers/imapx/camel-imapx-search.c
a45cfac
@@ -29,6 +29,7 @@ struct _CamelIMAPXSearchPrivate {
a45cfac
 	GWeakRef imapx_store;
a45cfac
 	gint *local_data_search; /* not NULL, if testing whether all used headers are all locally available */
a45cfac
 
a45cfac
+	GHashTable *cached_results; /* gchar * (search description) ~> GHashTable { gchar * (uid {from string pool}) ~> NULL } */
a45cfac
 	GCancellable *cancellable; /* not referenced */
a45cfac
 	GError **error; /* not referenced */
a45cfac
 };
a45cfac
@@ -99,6 +100,7 @@ imapx_search_finalize (GObject *object)
a45cfac
 	priv = CAMEL_IMAPX_SEARCH (object)->priv;
a45cfac
 
a45cfac
 	g_weak_ref_clear (&priv->imapx_store);
a45cfac
+	g_hash_table_destroy (priv->cached_results);
a45cfac
 
a45cfac
 	/* Chain up to parent's finalize() method. */
a45cfac
 	G_OBJECT_CLASS (camel_imapx_search_parent_class)->finalize (object);
a45cfac
@@ -153,6 +155,43 @@ imapx_search_result_match_none (CamelSExp *sexp,
a45cfac
 	return result;
a45cfac
 }
a45cfac
 
a45cfac
+static gchar *
a45cfac
+imapx_search_describe_criteria (const GString *criteria_prefix,
a45cfac
+				const gchar *search_key,
a45cfac
+				const GPtrArray *words)
a45cfac
+{
a45cfac
+	GString *desc;
a45cfac
+
a45cfac
+	desc = g_string_sized_new (64);
a45cfac
+
a45cfac
+	if (criteria_prefix && criteria_prefix->len)
a45cfac
+		g_string_append (desc, criteria_prefix->str);
a45cfac
+
a45cfac
+	g_string_append_c (desc, '\n');
a45cfac
+
a45cfac
+	if (search_key && *search_key)
a45cfac
+		g_string_append (desc, search_key);
a45cfac
+
a45cfac
+	g_string_append_c (desc, '\n');
a45cfac
+
a45cfac
+	if (words && words->len) {
a45cfac
+		guint ii;
a45cfac
+
a45cfac
+		for (ii = 0; ii < words->len; ii++) {
a45cfac
+			const gchar *word = words->pdata[ii];
a45cfac
+
a45cfac
+			if (word) {
a45cfac
+				g_string_append (desc, word);
a45cfac
+				g_string_append_c (desc, '\n');
a45cfac
+			}
a45cfac
+		}
a45cfac
+	}
a45cfac
+
a45cfac
+	g_string_append_c (desc, '\n');
a45cfac
+
a45cfac
+	return g_string_free (desc, FALSE);
a45cfac
+}
a45cfac
+
a45cfac
 static CamelSExpResult *
a45cfac
 imapx_search_process_criteria (CamelSExp *sexp,
a45cfac
                                CamelFolderSearch *search,
a45cfac
@@ -165,114 +204,89 @@ imapx_search_process_criteria (CamelSExp *sexp,
a45cfac
 	CamelSExpResult *result;
a45cfac
 	CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
a45cfac
 	CamelIMAPXMailbox *mailbox;
a45cfac
+	CamelMessageInfo *info;
a45cfac
+	GHashTable *cached_results;
a45cfac
+	gchar *criteria_desc;
a45cfac
 	GPtrArray *uids = NULL;
a45cfac
 	GError *local_error = NULL;
a45cfac
 
a45cfac
-	mailbox = camel_imapx_folder_list_mailbox (
a45cfac
-		CAMEL_IMAPX_FOLDER (camel_folder_search_get_folder (search)), imapx_search->priv->cancellable, &local_error);
a45cfac
+	criteria_desc = imapx_search_describe_criteria (criteria_prefix, search_key, words);
a45cfac
+	cached_results = g_hash_table_lookup (imapx_search->priv->cached_results, criteria_desc);
a45cfac
 
a45cfac
-	/* Sanity check. */
a45cfac
-	g_return_val_if_fail (
a45cfac
-		((mailbox != NULL) && (local_error == NULL)) ||
a45cfac
-		((mailbox == NULL) && (local_error != NULL)), NULL);
a45cfac
+	if (!cached_results) {
a45cfac
+		mailbox = camel_imapx_folder_list_mailbox (
a45cfac
+			CAMEL_IMAPX_FOLDER (camel_folder_search_get_folder (search)), imapx_search->priv->cancellable, &local_error);
a45cfac
 
a45cfac
-	if (mailbox != NULL) {
a45cfac
-		CamelIMAPXConnManager *conn_man;
a45cfac
+		/* Sanity check. */
a45cfac
+		g_return_val_if_fail (
a45cfac
+			((mailbox != NULL) && (local_error == NULL)) ||
a45cfac
+			((mailbox == NULL) && (local_error != NULL)), NULL);
a45cfac
 
a45cfac
-		conn_man = camel_imapx_store_get_conn_manager (imapx_store);
a45cfac
-		uids = camel_imapx_conn_manager_uid_search_sync (conn_man, mailbox, criteria_prefix->str, search_key,
a45cfac
-			words ? (const gchar * const *) words->pdata : NULL, imapx_search->priv->cancellable, &local_error);
a45cfac
+		if (mailbox != NULL) {
a45cfac
+			CamelIMAPXConnManager *conn_man;
a45cfac
 
a45cfac
-		g_object_unref (mailbox);
a45cfac
-	}
a45cfac
+			conn_man = camel_imapx_store_get_conn_manager (imapx_store);
a45cfac
+			uids = camel_imapx_conn_manager_uid_search_sync (conn_man, mailbox, criteria_prefix ? criteria_prefix->str : "", search_key,
a45cfac
+				words ? (const gchar * const *) words->pdata : NULL, imapx_search->priv->cancellable, &local_error);
a45cfac
+			g_object_unref (mailbox);
a45cfac
+		}
a45cfac
 
a45cfac
-	/* Sanity check. */
a45cfac
-	g_return_val_if_fail (
a45cfac
-		((uids != NULL) && (local_error == NULL)) ||
a45cfac
-		((uids == NULL) && (local_error != NULL)), NULL);
a45cfac
+		/* Sanity check. */
a45cfac
+		g_return_val_if_fail (
a45cfac
+			((uids != NULL) && (local_error == NULL)) ||
a45cfac
+			((uids == NULL) && (local_error != NULL)), NULL);
a45cfac
 
a45cfac
-	if (local_error != NULL) {
a45cfac
-		g_propagate_error (imapx_search->priv->error, local_error);
a45cfac
+		if (local_error != NULL) {
a45cfac
+			g_propagate_error (imapx_search->priv->error, local_error);
a45cfac
 
a45cfac
-		/* Make like we've got an empty result */
a45cfac
-		uids = g_ptr_array_new ();
a45cfac
+			/* Make like we've got an empty result */
a45cfac
+			uids = g_ptr_array_new ();
a45cfac
+		}
a45cfac
 	}
a45cfac
 
a45cfac
-	if (camel_folder_search_get_current_message_info (search)) {
a45cfac
+	info = camel_folder_search_get_current_message_info (search);
a45cfac
+
a45cfac
+	if (info) {
a45cfac
 		result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
a45cfac
-		result->value.boolean = (uids && uids->len > 0);
a45cfac
+		result->value.boolean = cached_results ? g_hash_table_contains (cached_results, camel_message_info_get_uid (info)) : (uids && uids->len > 0);
a45cfac
 	} else {
a45cfac
-		result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
a45cfac
-		result->value.ptrarray = g_ptr_array_ref (uids);
a45cfac
-	}
a45cfac
+		if (cached_results) {
a45cfac
+			GHashTableIter iter;
a45cfac
+			gpointer key;
a45cfac
 
a45cfac
-	g_ptr_array_unref (uids);
a45cfac
+			g_warn_if_fail (uids == NULL);
a45cfac
 
a45cfac
-	return result;
a45cfac
-}
a45cfac
+			uids = g_ptr_array_sized_new (g_hash_table_size (cached_results));
a45cfac
 
a45cfac
-static CamelSExpResult *
a45cfac
-imapx_search_match_all (CamelSExp *sexp,
a45cfac
-                        gint argc,
a45cfac
-                        CamelSExpTerm **argv,
a45cfac
-                        CamelFolderSearch *search)
a45cfac
-{
a45cfac
-	CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
a45cfac
-	CamelIMAPXStore *imapx_store;
a45cfac
-	CamelSExpResult *result;
a45cfac
-	GPtrArray *summary;
a45cfac
-	gint local_data_search = 0, *prev_local_data_search, ii;
a45cfac
+			g_hash_table_iter_init (&iter, cached_results);
a45cfac
 
a45cfac
-	if (argc != 1)
a45cfac
-		return imapx_search_result_match_none (sexp, search);
a45cfac
-
a45cfac
-	imapx_store = camel_imapx_search_ref_store (CAMEL_IMAPX_SEARCH (search));
a45cfac
-	if (!imapx_store || camel_folder_search_get_current_message_info (search) || !camel_folder_search_get_summary (search)) {
a45cfac
-		g_clear_object (&imapx_store);
a45cfac
+			while (g_hash_table_iter_next (&iter, &key, NULL)) {
a45cfac
+				g_ptr_array_add (uids, (gpointer) camel_pstring_strdup (key));
a45cfac
+			}
a45cfac
+		}
a45cfac
 
a45cfac
-		/* Chain up to parent's method. */
a45cfac
-		return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
a45cfac
-			match_all (sexp, argc, argv, search);
a45cfac
+		result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
a45cfac
+		result->value.ptrarray = g_ptr_array_ref (uids);
a45cfac
 	}
a45cfac
 
a45cfac
-	/* First try to see whether all used headers are available locally - if
a45cfac
-	 * they are, then do not use server-side filtering at all. */
a45cfac
-	prev_local_data_search = imapx_search->priv->local_data_search;
a45cfac
-	imapx_search->priv->local_data_search = &local_data_search;
a45cfac
+	if (!cached_results) {
a45cfac
+		cached_results = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
a45cfac
 
a45cfac
-	summary = camel_folder_search_get_current_summary (search);
a45cfac
+		if (uids) {
a45cfac
+			guint ii;
a45cfac
 
a45cfac
-	if (!CAMEL_IS_VEE_FOLDER (camel_folder_search_get_folder (search))) {
a45cfac
-		camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary (camel_folder_search_get_folder (search)), NULL);
a45cfac
-	}
a45cfac
-
a45cfac
-	for (ii = 0; ii < summary->len; ii++) {
a45cfac
-		camel_folder_search_take_current_message_info (search, camel_folder_summary_get (camel_folder_get_folder_summary (camel_folder_search_get_folder (search)), summary->pdata[ii]));
a45cfac
-		if (camel_folder_search_get_current_message_info (search)) {
a45cfac
-			result = camel_sexp_term_eval (sexp, argv[0]);
a45cfac
-			camel_sexp_result_free (sexp, result);
a45cfac
-			camel_folder_search_set_current_message_info (search, NULL);
a45cfac
-			break;
a45cfac
+			for (ii = 0; ii < uids->len; ii++) {
a45cfac
+				g_hash_table_insert (cached_results, (gpointer) camel_pstring_strdup (uids->pdata[ii]), NULL);
a45cfac
+			}
a45cfac
 		}
a45cfac
-	}
a45cfac
-	imapx_search->priv->local_data_search = prev_local_data_search;
a45cfac
-
a45cfac
-	if (local_data_search >= 0) {
a45cfac
-		g_clear_object (&imapx_store);
a45cfac
 
a45cfac
-		/* Chain up to parent's method. */
a45cfac
-		return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
a45cfac
-			match_all (sexp, argc, argv, search);
a45cfac
+		g_hash_table_insert (imapx_search->priv->cached_results, criteria_desc, cached_results);
a45cfac
+	} else {
a45cfac
+		g_free (criteria_desc);
a45cfac
 	}
a45cfac
 
a45cfac
-	/* let's change the requirements a bit, the parent class expects as a result boolean,
a45cfac
-	 * but here is expected GPtrArray of matched UIDs */
a45cfac
-	result = camel_sexp_term_eval (sexp, argv[0]);
a45cfac
-
a45cfac
-	g_object_unref (imapx_store);
a45cfac
-
a45cfac
-	g_return_val_if_fail (result != NULL, result);
a45cfac
-	g_return_val_if_fail (result->type == CAMEL_SEXP_RES_ARRAY_PTR, result);
a45cfac
+	if (uids)
a45cfac
+		g_ptr_array_unref (uids);
a45cfac
 
a45cfac
 	return result;
a45cfac
 }
a45cfac
@@ -338,7 +352,6 @@ imapx_search_body_contains (CamelSExp *sexp,
a45cfac
 	CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
a45cfac
 	CamelIMAPXStore *imapx_store;
a45cfac
 	CamelSExpResult *result;
a45cfac
-	GString *criteria;
a45cfac
 	GPtrArray *words;
a45cfac
 	gboolean is_gmail;
a45cfac
 
a45cfac
@@ -367,23 +380,12 @@ imapx_search_body_contains (CamelSExp *sexp,
a45cfac
 
a45cfac
 	/* Build the IMAP search criteria. */
a45cfac
 
a45cfac
-	criteria = g_string_sized_new (128);
a45cfac
-
a45cfac
-	if (camel_folder_search_get_current_message_info (search)) {
a45cfac
-		const gchar *uid;
a45cfac
-
a45cfac
-		/* Limit the search to a single UID. */
a45cfac
-		uid = camel_message_info_get_uid (camel_folder_search_get_current_message_info (search));
a45cfac
-		g_string_append_printf (criteria, "UID %s", uid);
a45cfac
-	}
a45cfac
-
a45cfac
 	words = imapx_search_gather_words (argv, 0, argc);
a45cfac
 
a45cfac
-	result = imapx_search_process_criteria (sexp, search, imapx_store, criteria, "BODY", words, G_STRFUNC);
a45cfac
+	result = imapx_search_process_criteria (sexp, search, imapx_store, NULL, "BODY", words, G_STRFUNC);
a45cfac
 
a45cfac
 	is_gmail = camel_imapx_store_is_gmail_server (imapx_store);
a45cfac
 
a45cfac
-	g_string_free (criteria, TRUE);
a45cfac
 	g_ptr_array_free (words, TRUE);
a45cfac
 	g_object_unref (imapx_store);
a45cfac
 
a45cfac
@@ -470,7 +472,6 @@ imapx_search_header_contains (CamelSExp *sexp,
a45cfac
 	CamelIMAPXStore *imapx_store;
a45cfac
 	CamelSExpResult *result;
a45cfac
 	const gchar *headername, *command = NULL;
a45cfac
-	GString *criteria;
a45cfac
 	gchar *search_key = NULL;
a45cfac
 	GPtrArray *words;
a45cfac
 
a45cfac
@@ -508,16 +509,6 @@ imapx_search_header_contains (CamelSExp *sexp,
a45cfac
 
a45cfac
 	/* Build the IMAP search criteria. */
a45cfac
 
a45cfac
-	criteria = g_string_sized_new (128);
a45cfac
-
a45cfac
-	if (camel_folder_search_get_current_message_info (search)) {
a45cfac
-		const gchar *uid;
a45cfac
-
a45cfac
-		/* Limit the search to a single UID. */
a45cfac
-		uid = camel_message_info_get_uid (camel_folder_search_get_current_message_info (search));
a45cfac
-		g_string_append_printf (criteria, "UID %s", uid);
a45cfac
-	}
a45cfac
-
a45cfac
 	if (g_ascii_strcasecmp (headername, "From") == 0)
a45cfac
 		command = "FROM";
a45cfac
 	else if (g_ascii_strcasecmp (headername, "To") == 0)
a45cfac
@@ -534,9 +525,8 @@ imapx_search_header_contains (CamelSExp *sexp,
a45cfac
 	if (!command)
a45cfac
 		search_key = g_strdup_printf ("HEADER \"%s\"", headername);
a45cfac
 
a45cfac
-	result = imapx_search_process_criteria (sexp, search, imapx_store, criteria, command ? command : search_key, words, G_STRFUNC);
a45cfac
+	result = imapx_search_process_criteria (sexp, search, imapx_store, NULL, command ? command : search_key, words, G_STRFUNC);
a45cfac
 
a45cfac
-	g_string_free (criteria, TRUE);
a45cfac
 	g_ptr_array_free (words, TRUE);
a45cfac
 	g_object_unref (imapx_store);
a45cfac
 	g_free (search_key);
a45cfac
@@ -599,14 +589,6 @@ imapx_search_header_exists (CamelSExp *sexp,
a45cfac
 
a45cfac
 	criteria = g_string_sized_new (128);
a45cfac
 
a45cfac
-	if (camel_folder_search_get_current_message_info (search)) {
a45cfac
-		const gchar *uid;
a45cfac
-
a45cfac
-		/* Limit the search to a single UID. */
a45cfac
-		uid = camel_message_info_get_uid (camel_folder_search_get_current_message_info (search));
a45cfac
-		g_string_append_printf (criteria, "UID %s", uid);
a45cfac
-	}
a45cfac
-
a45cfac
 	for (ii = 0; ii < argc; ii++) {
a45cfac
 		const gchar *headername;
a45cfac
 
a45cfac
@@ -623,7 +605,6 @@ imapx_search_header_exists (CamelSExp *sexp,
a45cfac
 
a45cfac
 	result = imapx_search_process_criteria (sexp, search, imapx_store, criteria, NULL, NULL, G_STRFUNC);
a45cfac
 
a45cfac
-	g_string_free (criteria, TRUE);
a45cfac
 	g_object_unref (imapx_store);
a45cfac
 
a45cfac
 	return result;
a45cfac
@@ -642,7 +623,6 @@ camel_imapx_search_class_init (CamelIMAPXSearchClass *class)
a45cfac
 	object_class->finalize = imapx_search_finalize;
a45cfac
 
a45cfac
 	search_class = CAMEL_FOLDER_SEARCH_CLASS (class);
a45cfac
-	search_class->match_all = imapx_search_match_all;
a45cfac
 	search_class->body_contains = imapx_search_body_contains;
a45cfac
 	search_class->header_contains = imapx_search_header_contains;
a45cfac
 	search_class->header_exists = imapx_search_header_exists;
a45cfac
@@ -665,6 +645,7 @@ camel_imapx_search_init (CamelIMAPXSearch *search)
a45cfac
 {
a45cfac
 	search->priv = camel_imapx_search_get_instance_private (search);
a45cfac
 	search->priv->local_data_search = NULL;
a45cfac
+	search->priv->cached_results = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy);
a45cfac
 
a45cfac
 	g_weak_ref_init (&search->priv->imapx_store, NULL);
a45cfac
 }
a45cfac
@@ -764,6 +745,14 @@ camel_imapx_search_set_store (CamelIMAPXSearch *search,
a45cfac
 	g_object_notify (G_OBJECT (search), "store");
a45cfac
 }
a45cfac
 
a45cfac
+void
a45cfac
+camel_imapx_search_clear_cached_results (CamelIMAPXSearch *search)
a45cfac
+{
a45cfac
+	g_return_if_fail (CAMEL_IS_IMAPX_SEARCH (search));
a45cfac
+
a45cfac
+	g_hash_table_remove_all (search->priv->cached_results);
a45cfac
+}
a45cfac
+
a45cfac
 /**
a45cfac
  * camel_imapx_search_set_cancellable_and_error:
a45cfac
  * @search: a #CamelIMAPXSearch
a45cfac
diff --git a/src/camel/providers/imapx/camel-imapx-search.h b/src/camel/providers/imapx/camel-imapx-search.h
a45cfac
index 98959a5b0..75d816941 100644
a45cfac
--- a/src/camel/providers/imapx/camel-imapx-search.h
a45cfac
+++ b/src/camel/providers/imapx/camel-imapx-search.h
a45cfac
@@ -75,6 +75,8 @@ CamelIMAPXStore *
a45cfac
 		camel_imapx_search_ref_store	(CamelIMAPXSearch *search);
a45cfac
 void		camel_imapx_search_set_store	(CamelIMAPXSearch *search,
a45cfac
 						 CamelIMAPXStore *imapx_store);
a45cfac
+void		camel_imapx_search_clear_cached_results
a45cfac
+						(CamelIMAPXSearch *search);
a45cfac
 void		camel_imapx_search_set_cancellable_and_error
a45cfac
 						(CamelIMAPXSearch *search,
a45cfac
 						 GCancellable *cancellable,
a45cfac
-- 
a45cfac
2.27.0
a45cfac