[PATCH 6/8] Support maildir folder search.

Austin Clements amdragon at MIT.EDU
Sun Jan 16 00:10:56 PST 2011


This implements a folder: query prefix by constructing a wildcard
query that matches all files within the specified folder, folder/new,
or folder/cur.  This works with hierarchical folder names, and accepts
both absolute and relative paths.
---
 lib/database.cc |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index 3af82b0..20fd412 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -582,6 +582,57 @@ transform_type_mail (_notmuch_token_t *root, unused (void *opaque))
     return _notmuch_token_create_op (root, TOK_AND, mail_ast, root);
 }
 
+static _notmuch_token_t *
+transform_folder_one (const void *ctx, notmuch_database_t *notmuch,
+		      const char *relpath, const char *rest)
+{
+    const char *db_path;
+    notmuch_private_status_t status;
+    unsigned int doc_id;
+    _notmuch_token_t *tok;
+
+    /* Get the docid for (relpath + rest). */
+    if (*rest)
+	relpath = talloc_asprintf (ctx, "%s%s", relpath, rest);
+    db_path = _notmuch_database_get_directory_db_path (relpath);
+    status = _notmuch_database_find_unique_doc_id (notmuch, "directory",
+						   db_path, &doc_id);
+    if (db_path != relpath)
+	free ((char*) db_path);
+
+    /* Construct a wildcard query that matches files in this directory. */
+    if (status)
+	/* Directory doesn't exist.  Perhaps this should be an error? */
+	doc_id = 0;
+    tok = _notmuch_token_create_term (ctx, TOK_LIT,
+				      talloc_asprintf (ctx, "%u:", doc_id));
+    tok->prefix = _find_prefix ("file-direntry");
+    return tok;
+}
+
+static _notmuch_token_t *
+transform_folder (_notmuch_token_t *root, void *opaque)
+{
+    if (!root)
+	return NULL;
+    if (root->type == TOK_PREFIX && strcmp (root->text, "folder") == 0) {
+	notmuch_database_t *notmuch = (notmuch_database_t *)opaque;
+	_notmuch_token_t *lit = root->left, *subs[3], *tok;
+	const char *relpath;
+	assert (lit && lit->type == TOK_LIT);
+	relpath = _notmuch_database_relative_path (notmuch, lit->text);
+	subs[0] = transform_folder_one (root, notmuch, relpath, "");
+	subs[1] = transform_folder_one (root, notmuch, relpath, "/new");
+	subs[2] = transform_folder_one (root, notmuch, relpath, "/cur");
+	tok = _notmuch_token_create_op (root, TOK_OR, subs[1], subs[2]);
+	return _notmuch_token_create_op (root, TOK_OR, subs[0], tok);
+    }
+
+    root->left = transform_folder (root->left, opaque);
+    root->right = transform_folder (root->right, opaque);
+    return root;
+}
+
 notmuch_database_t *
 notmuch_database_open (const char *path,
 		       notmuch_database_mode_t mode)
@@ -690,6 +741,11 @@ notmuch_database_open (const char *path,
 
 	_notmuch_qparser_add_transform (notmuch->query_parser,
 					transform_type_mail, NULL);
+
+	_notmuch_qparser_add_prefix (notmuch->query_parser, "folder",
+				     TRUE, TRUE);
+	_notmuch_qparser_add_transform (notmuch->query_parser,
+					transform_folder, notmuch);
     } catch (const Xapian::Error &error) {
 	fprintf (stderr, "A Xapian exception occurred opening database: %s\n",
 		 error.get_msg().c_str());
-- 
1.7.2.3



More information about the notmuch mailing list