fts-storage.c revision a0475b241a56220714d96a41f11a174c11a48bfa
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "array.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "mail-search.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-storage-private.h"
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen#include "mailbox-list-private.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "../virtual/virtual-storage.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "fts-api-private.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "fts-build.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "fts-search-serialize.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "fts-plugin.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "fts-storage.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include <stdlib.h>
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#define FTS_CONTEXT(obj) \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT(obj, fts_storage_module)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#define FTS_MAIL_CONTEXT(obj) \
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT(obj, fts_mail_module)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#define FTS_LIST_CONTEXT(obj) \
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen MODULE_CONTEXT(obj, fts_mailbox_list_module)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct fts_mailbox_list {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen union mailbox_list_module_context module_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_backend *backend;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen};
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct fts_mailbox {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen union mailbox_module_context module_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_backend_update_context *sync_update_ctx;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen};
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstruct fts_transaction_context {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen union mailbox_transaction_module_context module_ctx;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_scores *scores;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen};
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct fts_mail {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen union mail_module_context module_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen char score[30];
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen};
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_storage_module,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen &mail_storage_module_register);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_mail_module, &mail_module_register);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_mailbox_list_module,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen &mailbox_list_module_register);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void fts_scores_unref(struct fts_scores **_scores)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_scores *scores = *_scores;
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *_scores = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (--scores->refcount == 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_free(&scores->score_map);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_free(scores);
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen }
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen}
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainenstatic bool fts_try_build_init(struct mail_search_context *ctx,
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen struct fts_search_context *fctx)
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_is_updating(fctx->backend)) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* this process is already building the indexes */
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen return FALSE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen fctx->build_initialized = TRUE;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (fts_build_init(fctx->backend, ctx->transaction->box, FALSE,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen &fctx->build_ctx)) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case -1:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case 0:
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen /* the index was up to date */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_lookup(fctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case 1:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* hide "searching" notifications while building index */
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainen ctx->progress_hidden = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen }
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen return TRUE;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen}
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic bool fts_want_build_args(const struct mail_search_arg *args)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* we want to update index only when searching from message body.
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen it's not worth the wait for searching only from headers, which
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen could be in cache file already */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (; args != NULL; args = args->next) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (args->type) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_OR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SUB:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_INTHREAD:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_want_build_args(args->value.subargs))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_BODY:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_TEXT:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen default:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstatic struct mail_search_context *
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenfts_mailbox_search_init(struct mailbox_transaction_context *t,
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen struct mail_search_args *args,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen const enum mail_sort_type *sort_program,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen enum mail_fetch_field wanted_fields,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(t->box->list);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_search_context *ctx;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct fts_search_context *fctx;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen ctx = fbox->module_ctx.super.search_init(t, args, sort_program,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen wanted_fields, wanted_headers);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!fts_backend_can_lookup(flist->backend, args->args))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen fctx = i_new(struct fts_search_context, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->box = t->box;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->backend = flist->backend;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen fctx->t = t;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen fctx->args = args;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->result_pool = pool_alloconly_create("fts results", 1024*32);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->orig_matches = buffer_create_dynamic(default_pool, 64);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_array_init(&fctx->levels, 8);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->scores = i_new(struct fts_scores, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->scores->refcount = 1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_array_init(&fctx->scores->score_map, 64);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET(ctx, fts_storage_module, fctx);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->virtual_mailbox =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen strcmp(t->box->storage->name, VIRTUAL_STORAGE_NAME) == 0;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* transaction contains the last search's scores. they can be
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen queried later with mail_get_special() */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ft->scores != NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_scores_unref(&ft->scores);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ft->scores = fctx->scores;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ft->scores->refcount++;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_want_build_args(args->args))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (void)fts_try_build_init(ctx, fctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fctx->build_initialized = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_lookup(fctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic bool fts_mailbox_build_continue(struct mail_search_context *ctx)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int ret;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fctx == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!fctx->build_initialized) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* we're still waiting for this process (but another command)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen to finish building the indexes */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!fts_try_build_init(ctx, fctx))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fctx->build_ctx != NULL) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* this command is still building the indexes */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen ret = fts_build_more(fctx->build_ctx);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (ret == 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainen ctx->progress_hidden = FALSE;
f210ec6b25f80d06419921e9231465bb114ee971Timo Sirainen if (fts_build_deinit(&fctx->build_ctx) < 0)
f210ec6b25f80d06419921e9231465bb114ee971Timo Sirainen ret = -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ret > 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_lookup(fctx);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenstatic bool
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenfts_mailbox_search_next_nonblock(struct mail_search_context *ctx,
437a8b0fe254057b0c1f1723d689bafa91cae2abTimo Sirainen struct mail **mail_r, bool *tryagain_r)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!fts_mailbox_build_continue(ctx)) {
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen *tryagain_r = TRUE;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return FALSE;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return fbox->module_ctx.super.
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen search_next_nonblock(ctx, mail_r, tryagain_r);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenstatic void
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_search_apply_results_level(struct mail_search_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mail_search_arg *args, unsigned int *idx)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct fts_search_level *level;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen level = array_idx(&fctx->levels, *idx);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (array_is_created(&level->definite_seqs) &&
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_exists(&level->definite_seqs, ctx->seq))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_deserialize_add_matches(args, level->args_matches);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen else if (!array_is_created(&level->maybe_seqs) ||
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen !seq_range_exists(&level->maybe_seqs, ctx->seq))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_deserialize_add_nonmatches(args, level->args_matches);
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (; args != NULL; args = args->next) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (args->type != SEARCH_OR && args->type != SEARCH_SUB)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen continue;
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *idx += 1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_apply_results_level(ctx, args->value.subargs, idx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen}
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainenstatic bool fts_mailbox_search_next_update_seq(struct mail_search_context *ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int idx;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fctx == NULL || !fctx->fts_lookup_success) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* fts lookup not done for this search */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return fbox->module_ctx.super.search_next_update_seq(ctx);
c63c3c4d548416914b8c6734fe18dd69bb900775Timo Sirainen }
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* restore original [non]matches */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_deserialize(ctx->args->args, fctx->orig_matches);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!fbox->module_ctx.super.search_next_update_seq(ctx))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->seq >= fctx->first_unindexed_seq) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* we've not indexed this far */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* apply [non]matches based on the FTS lookup results */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen idx = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_search_apply_results_level(ctx, ctx->args->args, &idx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen}
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic int fts_mailbox_search_deinit(struct mail_search_context *ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fctx != NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fctx->build_ctx != NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* the search was cancelled */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (void)fts_build_deinit(&fctx->build_ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen buffer_free(&fctx->orig_matches);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_free(&fctx->levels);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen pool_unref(&fctx->result_pool);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_scores_unref(&fctx->scores);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_free(fctx);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return fbox->module_ctx.super.search_deinit(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainenstatic int fts_score_cmp(const uint32_t *uid, const struct fts_score_map *score)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen{
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen return *uid < score->uid ? -1 :
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen (*uid > score->uid ? 1 : 0);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen}
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainenstatic int fts_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen const char **value_r)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen{
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen struct fts_mail *fmail = FTS_MAIL_CONTEXT(mail);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen const struct fts_score_map *scores;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
fd14806f879f6cd4f023750e0c4cac27a7f94fbbTimo Sirainen if (field != MAIL_FETCH_SEARCH_RELEVANCY || ft->scores == NULL)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen scores = NULL;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen scores = array_bsearch(&ft->scores->score_map, &_mail->uid,
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainen fts_score_cmp);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (scores != NULL) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen i_assert(scores->uid == _mail->uid);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen i_snprintf(fmail->score, sizeof(fmail->score),
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen "%f", scores->score);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen *value_r = fmail->score;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen return 0;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen return fmail->module_ctx.super.get_special(_mail, field, value_r);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen}
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainenvoid fts_mail_allocated(struct mail *_mail)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen{
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mail_vfuncs *v = mail->vlast;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(_mail->box);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen struct fts_mail *fmail;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fbox == NULL)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen fmail = p_new(mail->pool, struct fts_mail, 1);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen fmail->module_ctx.super = *v;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen mail->vlast = &fmail->module_ctx.super;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->get_special = fts_mail_get_special;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen MODULE_CONTEXT_SET(mail, fts_mail_module, fmail);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen}
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstatic struct mailbox_transaction_context *
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenfts_transaction_begin(struct mailbox *box,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen enum mailbox_transaction_flags flags)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct mailbox_transaction_context *t;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_transaction_context *ft;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen ft = i_new(struct fts_transaction_context, 1);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen t = fbox->module_ctx.super.transaction_begin(box, flags);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET(t, fts_storage_module, ft);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen return t;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenstatic void fts_transaction_rollback(struct mailbox_transaction_context *t)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ft->scores != NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_scores_unref(&ft->scores);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen fbox->module_ctx.super.transaction_rollback(t);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainenstatic int
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainenfts_transaction_commit(struct mailbox_transaction_context *t,
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct mail_transaction_commit_changes *changes_r)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ft->scores != NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_scores_unref(&ft->scores);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return fbox->module_ctx.super.transaction_commit(t, changes_r);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void fts_mailbox_sync_notify(struct mailbox *box, uint32_t uid,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen enum mailbox_sync_type sync_type)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fbox->module_ctx.super.sync_notify != NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fbox->module_ctx.super.sync_notify(box, uid, sync_type);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (sync_type != MAILBOX_SYNC_TYPE_EXPUNGE) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (uid == 0 && fbox->sync_update_ctx != NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* this sync is finished */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (void)fts_backend_update_deinit(&fbox->sync_update_ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fbox->sync_update_ctx == NULL) {
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen if (fts_backend_is_updating(flist->backend)) {
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen /* FIXME: maildir workaround - we could get here
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen because we're building an index, which doesn't find
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen some mail and starts syncing the mailbox.. */
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen return;
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fbox->sync_update_ctx = fts_backend_update_init(flist->backend);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_update_set_mailbox(fbox->sync_update_ctx, box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_update_expunge(fbox->sync_update_ctx, uid);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenstatic int fts_update(struct mailbox *box)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_storage_build_context *build_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen int ret = 0;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if ((ret = fts_build_init(flist->backend, box,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen TRUE, &build_ctx)) <= 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (box->storage->set->mail_debug)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_debug("%s: FTS index is up to date", box->vname);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (box->storage->set->mail_debug)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_debug("%s: Updating FTS index", box->vname);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while ((ret = fts_build_more(build_ctx)) == 0) ;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_build_deinit(&build_ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = -1;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return ret < 0 ? -1 : 0;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenstatic int fts_sync_deinit(struct mailbox_sync_context *ctx,
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct mailbox_sync_status *status_r)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct mailbox *box = ctx->box;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen bool precache, force_resync;
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen int ret = 0;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen precache = (ctx->flags & MAILBOX_SYNC_FLAG_PRECACHE) != 0;
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen force_resync = (ctx->flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (fbox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return -1;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen ctx = NULL;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen flist->backend->syncing = TRUE;
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen if (force_resync) {
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen if (fts_backend_optimize(flist->backend) < 0) {
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen mail_storage_set_critical(box->storage,
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen "FTS optimize for mailbox %s failed",
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen box->vname);
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen ret = -1;
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen }
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (precache) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_update(box) < 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_storage_set_critical(box->storage,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen "FTS index update for mailbox %s failed",
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen box->vname);
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen ret = -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen flist->backend->syncing = FALSE;
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen return ret;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_mailbox_allocated(struct mailbox *box)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mailbox_vfuncs *v = box->vlast;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct fts_mailbox *fbox;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (flist == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fbox = p_new(box->pool, struct fts_mailbox, 1);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen fbox->module_ctx.super = *v;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen box->vlast = &fbox->module_ctx.super;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->search_init = fts_mailbox_search_init;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->search_next_nonblock = fts_mailbox_search_next_nonblock;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen v->search_next_update_seq = fts_mailbox_search_next_update_seq;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->search_deinit = fts_mailbox_search_deinit;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->transaction_begin = fts_transaction_begin;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->transaction_rollback = fts_transaction_rollback;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen v->transaction_commit = fts_transaction_commit;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen v->sync_notify = fts_mailbox_sync_notify;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen v->sync_deinit = fts_sync_deinit;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen MODULE_CONTEXT_SET(box, fts_storage_module, fbox);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void fts_mailbox_list_deinit(struct mailbox_list *list)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(list);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_deinit(&flist->backend);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen flist->module_ctx.super.deinit(list);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_mailbox_list_created(struct mailbox_list *list)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_backend *backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *name, *path, *error;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen name = mail_user_plugin_getenv(list->ns->user, "fts");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (name == NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (list->mail_set->mail_debug)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_debug("fts: No fts setting - plugin disabled");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen path = mailbox_list_get_path(list, NULL,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen MAILBOX_LIST_PATH_TYPE_INDEX);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (*path == '\0') {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (list->mail_set->mail_debug) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_debug("fts: Indexes disabled for namespace '%s'",
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen list->ns->prefix);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_init(name, list->ns, &error, &backend) < 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_error("fts: Failed to initialize backend '%s': %s",
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen name, error);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox_list *flist;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox_list_vfuncs *v = list->vlast;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen flist = p_new(list->pool, struct fts_mailbox_list, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen flist->module_ctx.super = *v;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen flist->backend = backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen list->vlast = &flist->module_ctx.super;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen v->deinit = fts_mailbox_list_deinit;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen MODULE_CONTEXT_SET(list, fts_mailbox_list_module, flist);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct fts_backend *fts_mailbox_backend(struct mailbox *box)
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return flist->backend;
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen}