Exemple #1
0
static int fts_mailbox_search_deinit(struct mail_search_context *ctx)
{
	struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
	struct fts_transaction_context *ft = FTS_CONTEXT(ctx->transaction);
	struct fts_search_context *fctx = FTS_CONTEXT(ctx);
	int ret = 0;

	if (fctx != NULL) {
		if (fctx->indexer_ctx != NULL) {
			if (fts_indexer_deinit(&fctx->indexer_ctx) < 0)
				ft->failed = TRUE;
		}
		if (fctx->indexing_timed_out)
			ret = -1;
		if (!fctx->fts_lookup_success && fctx->enforced) {
			/* FTS lookup failed and we didn't want to fallback to
			   opening all the mails and searching manually */
			mail_storage_set_internal_error(ctx->transaction->box->storage);
			ret = -1;
		}

		buffer_free(&fctx->orig_matches);
		array_free(&fctx->levels);
		pool_unref(&fctx->result_pool);
		fts_scores_unref(&fctx->scores);
		i_free(fctx);
	} else {
		if (ft->failed)
			ret = -1;
	}
	if (fbox->module_ctx.super.search_deinit(ctx) < 0)
		ret = -1;
	return ret;
}
Exemple #2
0
static int fts_transaction_end(struct mailbox_transaction_context *t, const char **error_r)
{
	struct fts_transaction_context *ft = FTS_CONTEXT(t);
	struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(t->box->list);
	int ret = ft->failed ? -1 : 0;

	if (ft->failed)
		*error_r = "transaction context";

	if (ft->precached) {
		i_assert(flist->update_ctx_refcount > 0);
		if (--flist->update_ctx_refcount == 0) {
			if (fts_backend_update_deinit(&flist->update_ctx) < 0) {
				ret = -1;
				*error_r = "backend deinit";
			}
		}
	} else if (ft->highest_virtual_uid > 0) {
		if (fts_index_set_last_uid(t->box, ft->highest_virtual_uid) < 0) {
			ret = -1;
			*error_r = "index last uid setting";
		}
	}
	if (ft->scores != NULL)
		fts_scores_unref(&ft->scores);
	i_free(ft);
	return ret;
}
Exemple #3
0
static struct mail_search_context *
fts_mailbox_search_init(struct mailbox_transaction_context *t,
			struct mail_search_args *args,
			const enum mail_sort_type *sort_program,
			enum mail_fetch_field wanted_fields,
			struct mailbox_header_lookup_ctx *wanted_headers)
{
	struct fts_transaction_context *ft = FTS_CONTEXT(t);
	struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
	struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(t->box->list);
	struct mail_search_context *ctx;
	struct fts_search_context *fctx;

	ctx = fbox->module_ctx.super.search_init(t, args, sort_program,
						 wanted_fields, wanted_headers);

	if (!fts_backend_can_lookup(flist->backend, args->args))
		return ctx;

	fctx = i_new(struct fts_search_context, 1);
	fctx->box = t->box;
	fctx->backend = flist->backend;
	fctx->t = t;
	fctx->args = args;
	fctx->result_pool = pool_alloconly_create("fts results", 1024*64);
	fctx->orig_matches = buffer_create_dynamic(default_pool, 64);
	fctx->virtual_mailbox =
		strcmp(t->box->storage->name, VIRTUAL_STORAGE_NAME) == 0;
	fctx->enforced =
		mail_user_plugin_getenv(t->box->storage->user,
					"fts_enforced") != NULL;
	i_array_init(&fctx->levels, 8);
	fctx->scores = i_new(struct fts_scores, 1);
	fctx->scores->refcount = 1;
	i_array_init(&fctx->scores->score_map, 64);
	MODULE_CONTEXT_SET(ctx, fts_storage_module, fctx);

	/* FIXME: we'll assume that all the args are fuzzy. not good,
	   but would require much more work to fix it. */
	if (!fts_args_have_fuzzy(args->args) &&
	    mail_user_plugin_getenv(t->box->storage->user,
				    "fts_no_autofuzzy") != NULL)
		fctx->flags |= FTS_LOOKUP_FLAG_NO_AUTO_FUZZY;
	/* transaction contains the last search's scores. they can be
	   queried later with mail_get_special() */
	if (ft->scores != NULL)
		fts_scores_unref(&ft->scores);
	ft->scores = fctx->scores;
	ft->scores->refcount++;

	if (fctx->enforced || fts_want_build_args(args->args))
		fts_try_build_init(ctx, fctx);
	else
		fts_search_lookup(fctx);
	return ctx;
}