mailbox-search-result.c revision 4fb98a31d0e4f67978a98a83a5895472b2da0401
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch#include "lib.h"
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch#include "array.h"
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch#include "mail-storage-private.h"
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch#include "mail-search.h"
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch#include "mailbox-search-result-private.h"
833bed942977673526c72e79bccc09314fc57104Phil Carmody
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschstatic void
38af46387e565053adf6c47f7f6871676d685de8Stephan Boschmailbox_search_result_analyze_args(struct mail_search_result *result,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct mail_search_arg *arg)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (; arg != NULL; arg = arg->next) {
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch switch (arg->type) {
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch case SEARCH_OR:
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch case SEARCH_SUB:
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch mailbox_search_result_analyze_args(result,
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch arg->value.subargs);
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch break;
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch case SEARCH_FLAGS:
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch result->args_have_flags = TRUE;
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch break;
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch case SEARCH_KEYWORDS:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch result->args_have_keywords = TRUE;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch break;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch case SEARCH_MODSEQ:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch result->args_have_modseq = TRUE;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch break;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch default:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch break;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschstruct mail_search_result *
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschmailbox_search_result_alloc(struct mailbox *box, struct mail_search_args *args,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch enum mailbox_search_result_flags flags)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct mail_search_result *result;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch result = i_new(struct mail_search_result, 1);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch result->box = box;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch result->flags = flags;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_array_init(&result->uids, 32);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_array_init(&result->never_uids, 128);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if ((result->flags & MAILBOX_SEARCH_RESULT_FLAG_UPDATE) != 0) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch result->search_args = args;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_search_args_ref(result->search_args);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mailbox_search_result_analyze_args(result, args->args);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch array_append(&result->box->search_results, &result, 1);
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch return result;
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch}
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch
38af46387e565053adf6c47f7f6871676d685de8Stephan Boschvoid mailbox_search_result_free(struct mail_search_result **_result)
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch{
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch struct mail_search_result *result = *_result;
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch struct mail_search_result *const *results;
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch unsigned int i, count;
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch *_result = NULL;
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch results = array_get(&result->box->search_results, &count);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (i = 0; i < count; i++) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (results[i] == result) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch array_delete(&result->box->search_results, i, 1);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch break;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_assert(i != count);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (result->search_args != NULL)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_search_args_unref(&result->search_args);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch array_free(&result->uids);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch array_free(&result->never_uids);
7c7117e542b6a44c1db7fc91c0180bdace6dbce7Stephan Bosch if (array_is_created(&result->removed_uids)) {
7c7117e542b6a44c1db7fc91c0180bdace6dbce7Stephan Bosch array_free(&result->removed_uids);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch array_free(&result->added_uids);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_free(result);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen}
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenstruct mail_search_result *
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenmailbox_search_result_save(struct mail_search_context *ctx,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen enum mailbox_search_result_flags flags)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen{
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct mail_search_result *result;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen result = mailbox_search_result_alloc(ctx->transaction->box,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch ctx->args, flags);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch array_append(&ctx->results, &result, 1);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return result;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mailbox_search_result_initial_done(struct mail_search_result *result)
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch{
dc05b1fb4b7a2b4d91248078311458cb4cbad9a1Stephan Bosch if ((result->flags & MAILBOX_SEARCH_RESULT_FLAG_QUEUE_SYNC) != 0) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_array_init(&result->removed_uids, 32);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_array_init(&result->added_uids, 32);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_search_args_seq2uid(result->search_args);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mailbox_search_results_initial_done(struct mail_search_context *ctx)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
201c3b9375760bafbc180629b4c6ad71ed554aecStephan Bosch struct mail_search_result *const *results;
201c3b9375760bafbc180629b4c6ad71ed554aecStephan Bosch unsigned int i, count;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch results = array_get(&ctx->results, &count);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (i = 0; i < count; i++)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mailbox_search_result_initial_done(results[i]);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenvoid mailbox_search_result_add(struct mail_search_result *result, uint32_t uid)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen{
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen i_assert(uid > 0);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
a5886aec87fbfd767a110e6168ce96411acfe798Stephan Bosch if (seq_range_exists(&result->uids, uid))
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch seq_range_array_add(&result->uids, uid);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (array_is_created(&result->added_uids)) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch seq_range_array_add(&result->added_uids, uid);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch seq_range_array_remove(&result->removed_uids, uid);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mailbox_search_result_remove(struct mail_search_result *result,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch uint32_t uid)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (seq_range_array_try_remove(&result->uids, uid)) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (array_is_created(&result->removed_uids)) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch seq_range_array_add(&result->removed_uids, uid);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch seq_range_array_remove(&result->added_uids, uid);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
38af46387e565053adf6c47f7f6871676d685de8Stephan Boschvoid mailbox_search_results_add(struct mail_search_context *ctx, uint32_t uid)
38af46387e565053adf6c47f7f6871676d685de8Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct mail_search_result *const *results;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch unsigned int i, count;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch results = array_get(&ctx->results, &count);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (i = 0; i < count; i++)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mailbox_search_result_add(results[i], uid);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen}
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenvoid mailbox_search_results_remove(struct mailbox *box, uint32_t uid)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen{
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct mail_search_result *const *results;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen unsigned int i, count;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch results = array_get(&box->search_results, &count);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (i = 0; i < count; i++)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mailbox_search_result_remove(results[i], uid);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mailbox_search_result_never(struct mail_search_result *result,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch uint32_t uid)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch seq_range_array_add(&result->never_uids, uid);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
e1a4ea6ad3e799ef8df7395e765c0ae9218e6c5dStephan Boschvoid mailbox_search_results_never(struct mail_search_context *ctx,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen uint32_t uid)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct mail_search_result *const *results;
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch unsigned int i, count;
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch if (ctx->update_result != NULL)
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch mailbox_search_result_never(ctx->update_result, uid);
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch results = array_get(&ctx->results, &count);
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch for (i = 0; i < count; i++)
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch mailbox_search_result_never(results[i], uid);
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch}
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Boschconst ARRAY_TYPE(seq_range) *
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Boschmailbox_search_result_get(struct mail_search_result *result)
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch{
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch return &result->uids;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mailbox_search_result_sync(struct mail_search_result *result,
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch ARRAY_TYPE(seq_range) *removed_uids,
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch ARRAY_TYPE(seq_range) *added_uids)
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch{
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch array_clear(removed_uids);
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch array_clear(added_uids);
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch array_append_array(removed_uids, &result->removed_uids);
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch array_append_array(added_uids, &result->added_uids);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch array_clear(&result->removed_uids);
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch array_clear(&result->added_uids);
5560e4cd4f5eded857471042fb5485dfa16b7c46Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch