fts-storage.c revision bc93929cdd9000ca560a5f42a27f50ab307f1efb
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (C) 2006 Timo Sirainen */
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen *((void **)array_idx_modifiable(&(obj)->module_contexts, \
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const char *env;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen struct timeval search_start_time, last_notify;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainenstatic unsigned int fts_storage_module_id = 0;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainenstatic int fts_mailbox_close(struct mailbox *box)
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainenstatic int uid_range_to_seq(struct mailbox *box,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen unsigned int i, count;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen for (i = 0; i < count; i++) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (mailbox_get_uids(box, range[i].seq1, range[i].seq2,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainenstatic int fts_build_mail_flush(struct fts_storage_build_context *ctx)
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (fts_backend_build_more(ctx->build, ctx->uid, str_data(ctx->headers),
009217abb57a24a4076092e8e4e165545747839eStephan Boschstatic bool fts_build_update_save_part(struct fts_storage_build_context *ctx,
009217abb57a24a4076092e8e4e165545747839eStephan Bosch /* we'll index only text/xxx and message/rfc822 parts for now */
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainenstatic int fts_build_mail_header(struct fts_storage_build_context *ctx,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const struct message_header_line *hdr = block->hdr;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen /* hdr->full_value is always set because we get the block from
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen message_decoder */
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_append_n(ctx->headers, hdr->middle, hdr->middle_len);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_append_n(ctx->headers, hdr->full_value, hdr->full_value_len);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (strcasecmp(hdr->name, "Content-Type") == 0) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainenstatic int fts_build_mail(struct fts_storage_build_context *ctx)
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen input = mail_get_stream(ctx->mail, NULL, NULL);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen parser = message_parser_init(pool_datastack_create(), input);
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen ret = message_parser_parse_next_block(parser, &raw_block);
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen if (!message_decoder_decode_next_block(decoder, &raw_block,
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen /* end of headers */
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen if (fts_build_update_save_part(ctx, &block)) {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (fts_backend_build_more(ctx->build, ctx->mail->uid,
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainenstatic int fts_build_init(struct fts_search_context *fctx)
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen struct mailbox_transaction_context *t = fctx->t;
6899af0c40f5e1ef80bd18961cea3a192134a4a4Timo Sirainen if (fts_backend_get_last_uid(backend, &last_uid) < 0)
6899af0c40f5e1ef80bd18961cea3a192134a4a4Timo Sirainen if (last_uid == 0 && fctx->best_arg->type == SEARCH_HEADER) {
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen /* index doesn't exist. we're not creating it just for
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen header lookups. */
396999508030c8498cb538eb8943e6b61394994cTimo Sirainen if (mailbox_get_uids(t->box, last_uid+1, (uint32_t)-1,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen /* no new messages */
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen build = fts_backend_build_init(backend, &last_uid_locked);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen /* changed, need to get again the sequences */
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (mailbox_get_uids(t->box, last_uid+1, (uint32_t)-1,
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen /* no new messages */
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen ctx = i_new(struct fts_storage_build_context, 1);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen ctx->search_ctx = mailbox_search_init(t, NULL, &ctx->search_arg, NULL);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainenstatic int fts_build_deinit(struct fts_storage_build_context *ctx)
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen struct mailbox *box = ctx->mail->transaction->box;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (mailbox_search_deinit(&ctx->search_ctx) < 0)
c84c0d4cb7f16aedbcb3d5db6b2d41851cc572c9Timo Sirainen if (ioloop_time - ctx->search_start_time.tv_sec >=
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen /* we notified at least once */
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainenstatic void fts_build_notify(struct fts_storage_build_context *ctx)
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen struct mailbox *box = ctx->mail->transaction->box;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen /* set the search time in here, in case a plugin
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen already spent some time indexing the mailbox */
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen } else if (box->storage->callbacks->notify_ok != NULL) {
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen percentage = (ctx->mail->seq - ctx->seqset.seq1) * 100.0 /
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen secs = (msecs / (percentage / 100.0) - msecs) / 1000;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen text = t_strdup_printf("Indexed %d%% of the mailbox, "
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen notify_ok(box, text, box->storage->callback_context);
d84c270231a617298088f597474a73f4a14921aeTimo Sirainenstatic int fts_build_more(struct fts_storage_build_context *ctx)
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen unsigned int count = 0;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen while (mailbox_search_next(ctx->search_ctx, ctx->mail) > 0) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenstatic void fts_search_filter_args(struct fts_search_context *fctx,
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen const char *key;
633a3da9d3e9a5befd3405f6651043a6bdd327cbTimo Sirainen /* fall through */
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen /* already handled this one */
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen /* we're only checking the existence
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen of the header. */
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (fts_backend_filter(fctx->backend, flags, key,
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen /* failed, but we already have limited
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen the search, so just ignore this */
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen fts_search_filter_args(fctx, args->value.subargs,
633a3da9d3e9a5befd3405f6651043a6bdd327cbTimo Sirainenstatic void fts_search_init(struct mailbox *box,
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen const char *key;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen i_assert(fctx->best_arg->type == SEARCH_HEADER);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen /* we're only checking the existence
4383941ed43d004f34f77334a06ad14e6a305607Timo Sirainen of the header. */
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen if (fctx->best_arg->type == SEARCH_TEXT_FAST ||
return TRUE;
return TRUE;
return FALSE;
case SEARCH_BODY_FAST:
case SEARCH_TEXT_FAST:
case SEARCH_BODY:
case SEARCH_TEXT:
case SEARCH_HEADER:
case SEARCH_OR:
case SEARCH_SUB:
return TRUE;
return FALSE;
return TRUE;
static struct mail_search_context *
fctx->t = t;
return ctx;
return ctx;
int ret;
if (ret == 0) {
if (ret > 0)
unsigned int count;
int ret;
return ret;
static struct mail *
return _mail;
const char *const *tmp;
FTS_BACKEND_FLAG_EXACT_LOOKUPS) != 0) {
*tmp);
*tmp);
static struct mailbox_transaction_context *
struct mailbox_transaction_context *t;
bool committed)
int ret;
return ret;
const char *env;
if (!fts_storage_module_id_set) {