summaryrefslogtreecommitdiffstats
path: root/doc/wiki/Design.Storage.Mailbox.Search.txt
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--doc/wiki/Design.Storage.Mailbox.Search.txt101
1 files changed, 101 insertions, 0 deletions
diff --git a/doc/wiki/Design.Storage.Mailbox.Search.txt b/doc/wiki/Design.Storage.Mailbox.Search.txt
new file mode 100644
index 0000000..d1438ba
--- /dev/null
+++ b/doc/wiki/Design.Storage.Mailbox.Search.txt
@@ -0,0 +1,101 @@
+Mailbox Searching
+=================
+
+'mailbox_search_*()' functions should be used always when you're iterating
+through multiple messages. The search queries can be complex or as simple as
+"all messages". Without searching there's also a way to directly switch to a
+specific message by its sequence number or UID, but this should be avoided
+usually.
+
+Initializing
+------------
+
+Search is initialized with 'mailbox_search_init()' on top of a <transaction>
+[Design.Storage.Mailbox.Transaction.txt]. Although it would appear that a
+search is a read-only operation, it can actually write data to Dovecot's cache
+file. For example if you search for a specific header not yet in cache file,
+the results are saved to cache file so the next search will be fast. This is
+why you should always commit search transactions, even if the rest of your
+operation fails (you should use separate transactions for search and for
+updates if necessary).
+
+You'll need a search query. 'src/lib-storage/mail-search.h' and
+'mail-search-build.h' contain all the functions and structures related to it.
+Usually you should start with 'mail_search_build_init()' and then start adding
+the search parameters, either manually or with one of the existing
+'mail_search_build_add_*()' helper functions. The same search query structures
+can be saved and used for other searches later, but because search state is
+stored inside the structs you need to be careful that multiple searches aren't
+using them at the same time. This is usually more trouble than worth, so avoid
+doing it.
+
+Search results can be sorted by giving a sort program. Dovecot optimizes this
+by keeping sort indexes in the index files.
+
+Reading search results
+----------------------
+
+While 'mailbox_search_next()' returns TRUE, a new search result is found and it
+changes the given <mail> [Design.Storage.Mail.txt] to point to the search
+result. The mail's "wanted fields/headers" parameters don't need to include
+anything needed by the search query, Dovecot optimizes them internally.
+
+If the search needs to parse message bodies and the mailbox is large, this call
+can take a long time. If you want to do other things while searching, you can
+use 'mailbox_search_next_nonblock()' that does only a bit of work and then
+returns either with a result or "try again later" status. Dovecot attempts to
+keep each non-matching call to this function between 200 and 250 milliseconds,
+although the upper bound can't be guaranteed.
+
+It's possible that messages are being expunged while Dovecot is searching them,
+so it can't determine if they would have matched the search rule or not. In
+this case it skips over them, but if you want to know if this has happened, you
+can see if 'mailbox_search_seen_lost_data()' returns TRUE.
+
+Deinitializing
+--------------
+
+'mailbox_search_deinit()' finishes the search. If it returns -1, some error
+occurred and some search results might not have been returned.
+
+Example
+-------
+
+Iterating through all messages in a mailbox goes like:
+
+---%<-------------------------------------------------------------------------
+/* build search query */
+search_args = mail_search_build_init();
+mail_search_build_add_all(search_args);
+
+search_ctx = mailbox_search_init(trans, search_args, NULL);
+/* search context keeps args referenced */
+mail_search_args_unref(&search_args);
+
+mail = mail_alloc(trans, 0, NULL);
+while (mailbox_search_next(ctx, mail)) {
+ printf("matched uid %u\n", mail->uid);
+}
+mail_free(&mail);
+if (mailbox_search_deinit(&search_ctx) < 0)
+ i_error("search failed");
+---%<-------------------------------------------------------------------------
+
+Saving search results
+---------------------
+
+Search results can be saved for future use by calling
+'mailbox_search_result_save()' just after initializing the search. The results
+as returned as UIDs with 'mailbox_search_result_get()' and may contain UIDs
+that are already expunged. Once you're done with the saved result, free it with
+'mailbox_search_result_free()'.
+
+The search result can also be automatically updated whenever mailbox is synced
+if 'MAILBOX_SEARCH_RESULT_FLAG_UPDATE' is set. The update is optimized, so
+Dovecot doesn't do a full re-search, but matches only new and changed messages.
+If 'MAILBOX_SEARCH_RESULT_FLAG_QUEUE_SYNC' is also set, search result additions
+and removals are also tracked and can be retrieved with
+'mailbox_search_result_sync()', i.e. with this you can implement "what changed
+in search results since last time I checked".
+
+(This file was created from the wiki on 2019-06-19 12:42)