fts-storage.c revision fd14806f879f6cd4f023750e0c4cac27a7f94fbb
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "array.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "mail-search.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-storage-private.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "mailbox-list-private.h"
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen#include "../virtual/virtual-storage.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "fts-api-private.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "fts-build.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "fts-search-serialize.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "fts-plugin.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#include "fts-storage.h"
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen#include <stdlib.h>
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#define FTS_CONTEXT(obj) \
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen MODULE_CONTEXT(obj, fts_storage_module)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#define FTS_MAIL_CONTEXT(obj) \
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen MODULE_CONTEXT(obj, fts_mail_module)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#define FTS_LIST_CONTEXT(obj) \
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen MODULE_CONTEXT(obj, fts_mailbox_list_module)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct fts_mailbox_list {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen union mailbox_list_module_context module_ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_backend *backend;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen};
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct fts_mailbox {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen union mailbox_module_context module_ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_backend_update_context *sync_update_ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen};
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct fts_transaction_context {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen union mailbox_transaction_module_context module_ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_scores *scores;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen};
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstruct fts_mail {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen union mail_module_context module_ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen char score[30];
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen};
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_storage_module,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen &mail_storage_module_register);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_mail_module, &mail_module_register);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(fts_mailbox_list_module,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen &mailbox_list_module_register);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void fts_scores_unref(struct fts_scores **_scores)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_scores *scores = *_scores;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen *_scores = NULL;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (--scores->refcount == 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen array_free(&scores->score_map);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_free(scores);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic bool fts_try_build_init(struct mail_search_context *ctx,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_search_context *fctx)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (fts_backend_is_updating(fctx->backend)) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* this process is already building the indexes */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return FALSE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->build_initialized = TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen switch (fts_build_init(fctx->backend, ctx->transaction->box, FALSE,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen &fctx->build_ctx)) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case -1:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case 0:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* the index was up to date */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fts_search_lookup(fctx);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case 1:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* hide "searching" notifications while building index */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ctx->progress_hidden = TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic bool fts_want_build_args(const struct mail_search_arg *args)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* we want to update index only when searching from message body.
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen it's not worth the wait for searching only from headers, which
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen could be in cache file already */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen for (; args != NULL; args = args->next) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen switch (args->type) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case SEARCH_OR:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case SEARCH_SUB:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case SEARCH_INTHREAD:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (fts_want_build_args(args->value.subargs))
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case SEARCH_BODY:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen case SEARCH_TEXT:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen default:
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen break;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return FALSE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic struct mail_search_context *
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenfts_mailbox_search_init(struct mailbox_transaction_context *t,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_search_args *args,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const enum mail_sort_type *sort_program,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen enum mail_fetch_field wanted_fields,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(t->box->list);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct mail_search_context *ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_search_context *fctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ctx = fbox->module_ctx.super.search_init(t, args, sort_program,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen wanted_fields, wanted_headers);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (!fts_backend_can_lookup(flist->backend, args->args))
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx = i_new(struct fts_search_context, 1);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->box = t->box;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->backend = flist->backend;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->t = t;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->args = args;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->result_pool = pool_alloconly_create("fts results", 1024*32);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->orig_matches = buffer_create_dynamic(default_pool, 64);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_array_init(&fctx->levels, 8);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->scores = i_new(struct fts_scores, 1);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->scores->refcount = 1;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_array_init(&fctx->scores->score_map, 64);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen MODULE_CONTEXT_SET(ctx, fts_storage_module, fctx);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->virtual_mailbox =
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen strcmp(t->box->storage->name, VIRTUAL_STORAGE_NAME) == 0;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* transaction contains the last search's scores. they can be
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen queried later with mail_get_special() */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (ft->scores != NULL)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fts_scores_unref(&ft->scores);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ft->scores = fctx->scores;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen ft->scores->refcount++;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (fts_want_build_args(args->args))
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen (void)fts_try_build_init(ctx, fctx);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen else {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fctx->build_initialized = TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen fts_search_lookup(fctx);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen }
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return ctx;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen}
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic bool fts_mailbox_build_continue(struct mail_search_context *ctx)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen{
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen int ret;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (fctx == NULL)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return TRUE;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (!fctx->build_initialized) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* we're still waiting for this process (but another command)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen to finish building the indexes */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!fts_try_build_init(ctx, fctx))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fctx->build_ctx != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* this command is still building the indexes */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = fts_build_more(fctx->build_ctx);
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen if (ret == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->progress_hidden = FALSE;
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen if (fts_build_deinit(&fctx->build_ctx) < 0)
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret > 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fts_search_lookup(fctx);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
2abfef71398a61e5ed97c23a1ceb71461933ccb8Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenfts_mailbox_search_next_nonblock(struct mail_search_context *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail **mail_r, bool *tryagain_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen if (!fts_mailbox_build_continue(ctx)) {
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen *tryagain_r = TRUE;
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen return FALSE;
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen }
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen return fbox->module_ctx.super.
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainen search_next_nonblock(ctx, mail_r, tryagain_r);
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainen}
b9b48aaaebf6f72dfab567cda073cde8a7b26598Timo Sirainen
b9b48aaaebf6f72dfab567cda073cde8a7b26598Timo Sirainenstatic void
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainenfts_search_apply_results_level(struct mail_search_context *ctx,
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen struct mail_search_arg *args, unsigned int *idx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct fts_search_level *level;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainen level = array_idx(&fctx->levels, *idx);
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen if (array_is_created(&level->definite_seqs) &&
d4dcb9c30dba354cff7af6d303ecef7698194c55Timo Sirainen seq_range_exists(&level->definite_seqs, ctx->seq))
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen fts_search_deserialize_add_matches(args, level->args_matches);
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen else if (!array_is_created(&level->maybe_seqs) ||
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen !seq_range_exists(&level->maybe_seqs, ctx->seq))
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen fts_search_deserialize_add_nonmatches(args, level->args_matches);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (; args != NULL; args = args->next) {
9c7e765845357342923e16351181091028e5930fTimo Sirainen if (args->type != SEARCH_OR && args->type != SEARCH_SUB)
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen continue;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen *idx += 1;
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen fts_search_apply_results_level(ctx, args->value.subargs, idx);
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen }
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen}
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainenstatic bool fts_mailbox_search_next_update_seq(struct mail_search_context *ctx)
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen{
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen unsigned int idx;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen if (fctx == NULL || !fctx->fts_lookup_success) {
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen /* fts lookup not done for this search */
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen return fbox->module_ctx.super.search_next_update_seq(ctx);
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen }
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen /* restore original [non]matches */
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen fts_search_deserialize(ctx->args->args, fctx->orig_matches);
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen if (!fbox->module_ctx.super.search_next_update_seq(ctx))
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen return FALSE;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen if (ctx->seq >= fctx->first_unindexed_seq) {
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen /* we've not indexed this far */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainen }
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* apply [non]matches based on the FTS lookup results */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen idx = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fts_search_apply_results_level(ctx, ctx->args->args, &idx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen}
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstatic int fts_mailbox_search_deinit(struct mail_search_context *ctx)
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen{
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
e30b748edcef3cf3352478bf21fa8f785bdc773aTimo Sirainen struct fts_search_context *fctx = FTS_CONTEXT(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fctx != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fctx->build_ctx != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* the search was cancelled */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (void)fts_build_deinit(&fctx->build_ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
e05181d973025627ba08b631c12c07c3bbc99528Timo Sirainen
0b3662995e9fa0d0d857ec5350ce2b1ee6d3b94fTimo Sirainen buffer_free(&fctx->orig_matches);
0b3662995e9fa0d0d857ec5350ce2b1ee6d3b94fTimo Sirainen array_free(&fctx->levels);
0b3662995e9fa0d0d857ec5350ce2b1ee6d3b94fTimo Sirainen pool_unref(&fctx->result_pool);
0b3662995e9fa0d0d857ec5350ce2b1ee6d3b94fTimo Sirainen fts_scores_unref(&fctx->scores);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(fctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen return fbox->module_ctx.super.search_deinit(ctx);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenstatic int fts_score_cmp(const uint32_t *uid, const struct fts_score_map *score)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen{
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen return *uid < score->uid ? -1 :
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (*uid > score->uid ? 1 : 0);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen}
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenstatic int fts_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen const char **value_r)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen{
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen struct fts_mail *fmail = FTS_MAIL_CONTEXT(mail);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen const struct fts_score_map *scores;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen if (field != MAIL_FETCH_SEARCH_RELEVANCY || ft->scores == NULL)
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen scores = NULL;
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen else {
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen scores = array_bsearch(&ft->scores->score_map, &_mail->uid,
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainen fts_score_cmp);
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen }
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen if (scores != NULL) {
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen i_assert(scores->uid == _mail->uid);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen i_snprintf(fmail->score, sizeof(fmail->score),
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen "%f", scores->score);
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen *value_r = fmail->score;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen return 0;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen }
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen return fmail->module_ctx.super.get_special(_mail, field, value_r);
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen}
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainenvoid fts_mail_allocated(struct mail *_mail)
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen{
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen struct mail_vfuncs *v = mail->vlast;
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(_mail->box);
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen struct fts_mail *fmail;
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen if (fbox == NULL)
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen return;
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen fmail = p_new(mail->pool, struct fts_mail, 1);
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen fmail->module_ctx.super = *v;
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen mail->vlast = &fmail->module_ctx.super;
538303a216166f3526c0ae9658c9978275cfa100Timo Sirainen
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen v->get_special = fts_mail_get_special;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MODULE_CONTEXT_SET(mail, fts_mail_module, fmail);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen}
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen
a87e5f15283e057c7dc26dd9db7b616268c95ca7Timo Sirainenstatic struct mailbox_transaction_context *
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenfts_transaction_begin(struct mailbox *box,
c93cd163f9c1d4b0ca29f49cbfdbf474caeef5bfTimo Sirainen enum mailbox_transaction_flags flags)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen{
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox_transaction_context *t;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen struct fts_transaction_context *ft;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ft = i_new(struct fts_transaction_context, 1);
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen t = fbox->module_ctx.super.transaction_begin(box, flags);
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen MODULE_CONTEXT_SET(t, fts_storage_module, ft);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return t;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen}
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainenstatic void fts_transaction_rollback(struct mailbox_transaction_context *t)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen{
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (ft->scores != NULL)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen fts_scores_unref(&ft->scores);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen fbox->module_ctx.super.transaction_rollback(t);
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen}
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainenstatic int
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainenfts_transaction_commit(struct mailbox_transaction_context *t,
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen struct mail_transaction_commit_changes *changes_r)
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen{
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen struct fts_transaction_context *ft = FTS_CONTEXT(t);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen if (ft->scores != NULL)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen fts_scores_unref(&ft->scores);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return fbox->module_ctx.super.transaction_commit(t, changes_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainenstatic void fts_mailbox_sync_notify(struct mailbox *box, uint32_t uid,
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen enum mailbox_sync_type sync_type)
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen{
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d3eff05aaa4c2bc0a7580ee87a54f6693f4a8241Timo Sirainen if (fbox->module_ctx.super.sync_notify != NULL)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen fbox->module_ctx.super.sync_notify(box, uid, sync_type);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (sync_type != MAILBOX_SYNC_TYPE_EXPUNGE) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (uid == 0 && fbox->sync_update_ctx != NULL) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen /* this sync is finished */
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen (void)fts_backend_update_deinit(&fbox->sync_update_ctx);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen if (fbox->sync_update_ctx == NULL) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen fbox->sync_update_ctx = fts_backend_update_init(flist->backend);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen fts_backend_update_set_mailbox(fbox->sync_update_ctx, box);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen fts_backend_update_expunge(fbox->sync_update_ctx, uid);
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen}
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainenstatic int fts_update(struct mailbox *box)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen{
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct fts_storage_build_context *build_ctx;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen int ret = 0;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen if ((ret = fts_build_init(flist->backend, box,
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen TRUE, &build_ctx)) <= 0) {
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen if (box->storage->set->mail_debug)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen i_debug("%s: FTS index is up to date", box->vname);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen if (box->storage->set->mail_debug)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen i_debug("%s: Updating FTS index", box->vname);
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen while ((ret = fts_build_more(build_ctx)) == 0) ;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen if (fts_build_deinit(&build_ctx) < 0)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen ret = -1;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen return ret < 0 ? -1 : 0;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen}
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainenstatic int fts_sync_deinit(struct mailbox_sync_context *ctx,
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct mailbox_sync_status *status_r)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen{
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct mailbox *box = ctx->box;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct fts_mailbox *fbox = FTS_CONTEXT(box);
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen bool precache;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen precache = (ctx->flags & MAILBOX_SYNC_FLAG_PRECACHE) != 0;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen if (fbox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
d77c309fccbc6a7594f8cb08fb01009fa613c568Timo Sirainen ctx = NULL;
d77c309fccbc6a7594f8cb08fb01009fa613c568Timo Sirainen
d77c309fccbc6a7594f8cb08fb01009fa613c568Timo Sirainen if (precache) {
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (fts_update(box) < 0) {
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen mail_storage_set_critical(box->storage,
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen "FTS index update for mailbox %s failed",
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen box->vname);
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen return -1;
7bd6001d84ecc1792ddfd54fe8efa63c509d90b1Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
d3eff05aaa4c2bc0a7580ee87a54f6693f4a8241Timo Sirainen}
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid fts_mailbox_allocated(struct mailbox *box)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox_vfuncs *v = box->vlast;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct fts_mailbox *fbox;
8754bb7a1f24705ffa5434f9e10d57e0b3b88d6eTimo Sirainen
8754bb7a1f24705ffa5434f9e10d57e0b3b88d6eTimo Sirainen if (flist == NULL)
8754bb7a1f24705ffa5434f9e10d57e0b3b88d6eTimo Sirainen return;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen fbox = p_new(box->pool, struct fts_mailbox, 1);
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen fbox->module_ctx.super = *v;
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen box->vlast = &fbox->module_ctx.super;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen v->search_init = fts_mailbox_search_init;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen v->search_next_nonblock = fts_mailbox_search_next_nonblock;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen v->search_next_update_seq = fts_mailbox_search_next_update_seq;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen v->search_deinit = fts_mailbox_search_deinit;
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen v->transaction_begin = fts_transaction_begin;
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen v->transaction_rollback = fts_transaction_rollback;
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen v->transaction_commit = fts_transaction_commit;
9a099a65160987349f441c82ab0e38f32b747adbTimo Sirainen v->sync_notify = fts_mailbox_sync_notify;
9a099a65160987349f441c82ab0e38f32b747adbTimo Sirainen v->sync_deinit = fts_sync_deinit;
9a099a65160987349f441c82ab0e38f32b747adbTimo Sirainen
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen MODULE_CONTEXT_SET(box, fts_storage_module, fbox);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainenstatic void fts_mailbox_list_deinit(struct mailbox_list *list)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(list);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fts_backend_deinit(&flist->backend);
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen flist->module_ctx.super.deinit(list);
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen}
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainenvoid fts_mailbox_list_created(struct mailbox_list *list)
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct fts_backend *backend;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *name, *path, *error;
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen name = mail_user_plugin_getenv(list->ns->user, "fts");
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen if (name == NULL) {
d3eff05aaa4c2bc0a7580ee87a54f6693f4a8241Timo Sirainen if (list->mail_set->mail_debug)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_debug("fts: No fts setting - plugin disabled");
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen path = mailbox_list_get_path(list, NULL,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAILBOX_LIST_PATH_TYPE_INDEX);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (*path == '\0') {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen if (list->mail_set->mail_debug) {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen i_debug("fts: Indexes disabled for namespace '%s'",
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen list->ns->prefix);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen }
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fts_backend_init(name, list->ns, &error, &backend) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("fts: Failed to initialize backend '%s': %s",
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen name, error);
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen } else {
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct fts_mailbox_list *flist;
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen struct mailbox_list_vfuncs *v = list->vlast;
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen flist = p_new(list->pool, struct fts_mailbox_list, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flist->module_ctx.super = *v;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flist->backend = backend;
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen list->vlast = &flist->module_ctx.super;
41264e5dcef8335ab7ba422822b3ab518b7a327aTimo Sirainen v->deinit = fts_mailbox_list_deinit;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MODULE_CONTEXT_SET(list, fts_mailbox_list_module, flist);
d77c309fccbc6a7594f8cb08fb01009fa613c568Timo Sirainen }
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen}
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainenstruct fts_backend *fts_mailbox_backend(struct mailbox *box)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen{
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen return flist->backend;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen}
b60baf6af900a610b2b2ddd24a46f8311acc3386Timo Sirainen