fts-api.c revision 12055678401e913f4be130fa41b22fbeb626cc7e
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2006-2010 Dovecot authors, see the included COPYING file */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "array.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "fts-api-private.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic ARRAY_DEFINE(backends, const struct fts_backend *);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid fts_backend_register(const struct fts_backend *backend)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
3fb1c1f0375ec0a2b00be90b5d61fbc8374e9b90Timo Sirainen if (!array_is_created(&backends))
3fb1c1f0375ec0a2b00be90b5d61fbc8374e9b90Timo Sirainen i_array_init(&backends, 4);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_append(&backends, &backend, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid fts_backend_unregister(const char *name)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct fts_backend *const *be;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen be = array_get(&backends, &count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (i = 0; i < count; i++) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (strcmp(be[i]->name, name) == 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_delete(&backends, i, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (i == count)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_panic("fts_backend_unregister(%s): unknown backend", name);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (count == 1)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_free(&backends);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenstatic const struct fts_backend *
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenfts_backend_class_lookup(const char *backend_name)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct fts_backend *const *be;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen if (array_is_created(&backends)) {
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen be = array_get(&backends, &count);
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen for (i = 0; i < count; i++) {
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen if (strcmp(be[i]->name, backend_name) == 0)
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen return be[i];
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return NULL;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenstruct fts_backend *
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenfts_backend_init(const char *backend_name, struct mailbox *box)
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen{
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen const struct fts_backend *be;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen struct fts_backend *backend;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen be = fts_backend_class_lookup(backend_name);
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen if (be == NULL) {
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen i_error("Unknown FTS backend: %s", backend_name);
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen return NULL;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen }
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen backend = be->v.init(box);
7498c2042724f0ced01bed6cae60ffb4455e0253Timo Sirainen if (backend == NULL)
7498c2042724f0ced01bed6cae60ffb4455e0253Timo Sirainen return NULL;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen backend->box = box;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen return backend;
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen}
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenvoid fts_backend_deinit(struct fts_backend **_backend)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct fts_backend *backend = *_backend;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen *_backend = NULL;
e80307fd7345f60540c7d83c38952603d2df9e9bTimo Sirainen backend->v.deinit(backend);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainenint fts_backend_get_last_uid(struct fts_backend *backend, uint32_t *last_uid_r)
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen{
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen return backend->v.get_last_uid(backend, last_uid_r);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen}
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenint fts_backend_get_all_last_uids(struct fts_backend *backend, pool_t pool,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ARRAY_TYPE(fts_backend_uid_map) *last_uids)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen{
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen return backend->v.get_all_last_uids(backend, pool, last_uids);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen}
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenint fts_backend_build_init(struct fts_backend *backend, uint32_t *last_uid_r,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct fts_backend_build_context **ctx_r)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
1eb887d0fb04c184f56d122dc478b9c7d4a95cc4Timo Sirainen int ret;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
1eb887d0fb04c184f56d122dc478b9c7d4a95cc4Timo Sirainen i_assert(!backend->building);
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
1eb887d0fb04c184f56d122dc478b9c7d4a95cc4Timo Sirainen ret = backend->v.build_init(backend, last_uid_r, ctx_r);
1eb887d0fb04c184f56d122dc478b9c7d4a95cc4Timo Sirainen if (ret == 0)
1eb887d0fb04c184f56d122dc478b9c7d4a95cc4Timo Sirainen backend->building = TRUE;
1eb887d0fb04c184f56d122dc478b9c7d4a95cc4Timo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainenvoid fts_backend_build_hdr(struct fts_backend_build_context *ctx, uint32_t uid)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen ctx->backend->v.build_hdr(ctx, uid);
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainenbool fts_backend_build_body_begin(struct fts_backend_build_context *ctx,
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen uint32_t uid, const char *content_type,
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen const char *content_disposition)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen return ctx->backend->v.build_body_begin(ctx, uid, content_type,
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen content_disposition);
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainenvoid fts_backend_build_body_end(struct fts_backend_build_context *ctx)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen if (ctx->backend->v.build_body_end != NULL)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen ctx->backend->v.build_body_end(ctx);
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainenint fts_backend_build_more(struct fts_backend_build_context *ctx,
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen const unsigned char *data, size_t size)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen return ctx->backend->v.build_more(ctx, data, size);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenint fts_backend_build_deinit(struct fts_backend_build_context **_ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct fts_backend_build_context *ctx = *_ctx;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen *_ctx = NULL;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen ctx->backend->building = FALSE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return ctx->backend->v.build_deinit(ctx);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainenbool fts_backend_is_building(struct fts_backend *backend)
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen{
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen return backend->building;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen}
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainenvoid fts_backend_expunge(struct fts_backend *backend, struct mail *mail)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen{
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen backend->v.expunge(backend, mail);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen}
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenvoid fts_backend_expunge_finish(struct fts_backend *backend,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct mailbox *box, bool committed)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen{
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen backend->v.expunge_finish(backend, box, committed);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainenint fts_backend_lock(struct fts_backend *backend)
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen int ret;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_assert(!backend->locked);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ret = backend->v.lock(backend);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (ret > 0)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen backend->locked = TRUE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen return ret;
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen}
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainenvoid fts_backend_unlock(struct fts_backend *backend)
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_assert(backend->locked);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen backend->locked = FALSE;
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen backend->v.unlock(backend);
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen}
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenstatic void
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenfts_merge_maybies(ARRAY_TYPE(seq_range) *dest_maybe,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const ARRAY_TYPE(seq_range) *dest_definite,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const ARRAY_TYPE(seq_range) *src_maybe,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const ARRAY_TYPE(seq_range) *src_definite)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen{
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen ARRAY_TYPE(seq_range) src_unwanted;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen const struct seq_range *range;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen struct seq_range new_range;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen unsigned int i, count;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen uint32_t seq;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* add/leave to dest_maybe if at least one list has maybe,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen and no lists have none */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen /* create unwanted sequences list from both sources */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen t_array_init(&src_unwanted, 128);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen new_range.seq1 = 0; new_range.seq2 = (uint32_t)-1;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen array_append(&src_unwanted, &new_range, 1);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(&src_unwanted, src_maybe);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(&src_unwanted, src_definite);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* drop unwanted uids */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(dest_maybe, &src_unwanted);
7bc564062f3bef44c61f4e83ccdd9c5eaa433253Timo Sirainen
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen /* add uids that are in dest_definite and src_maybe lists */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen range = array_get(dest_definite, &count);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen for (i = 0; i < count; i++) {
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen for (seq = range[i].seq1; seq <= range[i].seq2; seq++) {
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen if (seq_range_exists(src_maybe, seq))
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen seq_range_array_add(dest_maybe, 0, seq);
7bc564062f3bef44c61f4e83ccdd9c5eaa433253Timo Sirainen }
7bc564062f3bef44c61f4e83ccdd9c5eaa433253Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen}
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenvoid fts_filter_uids(ARRAY_TYPE(seq_range) *definite_dest,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen const ARRAY_TYPE(seq_range) *definite_filter,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *maybe_dest,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen const ARRAY_TYPE(seq_range) *maybe_filter)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen T_BEGIN {
809923ba26218971792182ae8894936f9ac99364Timo Sirainen fts_merge_maybies(maybe_dest, definite_dest,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen maybe_filter, definite_filter);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen } T_END;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen /* keep only what exists in both lists. the rest is in
809923ba26218971792182ae8894936f9ac99364Timo Sirainen maybies or not wanted */
809923ba26218971792182ae8894936f9ac99364Timo Sirainen seq_range_array_intersect(definite_dest, definite_filter);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenstatic void fts_lookup_invert(ARRAY_TYPE(seq_range) *definite_uids,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen const ARRAY_TYPE(seq_range) *maybe_uids)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen /* we'll begin by inverting definite UIDs */
809923ba26218971792182ae8894936f9ac99364Timo Sirainen seq_range_array_invert(definite_uids, 1, (uint32_t)-1);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainen /* from that list remove UIDs in the maybe list.
809923ba26218971792182ae8894936f9ac99364Timo Sirainen the maybe list itself isn't touched. */
809923ba26218971792182ae8894936f9ac99364Timo Sirainen (void)seq_range_array_remove_seq_range(definite_uids, maybe_uids);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenstatic int fts_backend_lookup(struct fts_backend *backend, const char *key,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen enum fts_lookup_flags flags,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *definite_uids,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *maybe_uids)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen int ret;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ret = backend->v.lookup(backend, key, flags & ~FTS_LOOKUP_FLAG_INVERT,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen definite_uids, maybe_uids);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen if (unlikely(ret < 0))
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return -1;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen if ((flags & FTS_LOOKUP_FLAG_INVERT) != 0)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen fts_lookup_invert(definite_uids, maybe_uids);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return 0;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenstatic int fts_backend_filter(struct fts_backend *backend, const char *key,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen enum fts_lookup_flags flags,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *definite_uids,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *maybe_uids)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ARRAY_TYPE(seq_range) tmp_definite, tmp_maybe;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen int ret;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (backend->v.filter != NULL) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen return backend->v.filter(backend, key, flags,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen definite_uids, maybe_uids);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* do this ourself */
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_array_init(&tmp_definite, 64);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_array_init(&tmp_maybe, 64);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ret = fts_backend_lookup(backend, key, flags,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen &tmp_definite, &tmp_maybe);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (ret < 0) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen array_clear(definite_uids);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen array_clear(maybe_uids);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen } else {
809923ba26218971792182ae8894936f9ac99364Timo Sirainen fts_filter_uids(definite_uids, &tmp_definite,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen maybe_uids, &tmp_maybe);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen array_free(&tmp_maybe);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen array_free(&tmp_definite);
7bc564062f3bef44c61f4e83ccdd9c5eaa433253Timo Sirainen return ret;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenstruct fts_backend_lookup_context *
809923ba26218971792182ae8894936f9ac99364Timo Sirainenfts_backend_lookup_init(struct fts_backend *backend)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen struct fts_backend_lookup_context *ctx;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen pool_t pool;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainen pool = pool_alloconly_create("fts backend lookup", 256);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ctx = p_new(pool, struct fts_backend_lookup_context, 1);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ctx->pool = pool;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ctx->backend = backend;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen p_array_init(&ctx->fields, pool, 8);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return ctx;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenvoid fts_backend_lookup_add(struct fts_backend_lookup_context *ctx,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen const char *key, enum fts_lookup_flags flags)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen struct fts_backend_lookup_field *field;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainen field = array_append_space(&ctx->fields);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen field->key = p_strdup(ctx->pool, key);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen field->flags = flags;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenstatic int fts_backend_lookup_old(struct fts_backend_lookup_context *ctx,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *definite_uids,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *maybe_uids)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen const struct fts_backend_lookup_field *fields;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen unsigned int i, count;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainen fields = array_get(&ctx->fields, &count);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen i_assert(count > 0);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainen if (fts_backend_lookup(ctx->backend, fields[0].key, fields[0].flags,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen definite_uids, maybe_uids) < 0)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return -1;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen for (i = 1; i < count; i++) {
809923ba26218971792182ae8894936f9ac99364Timo Sirainen if (fts_backend_filter(ctx->backend,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen fields[i].key, fields[i].flags,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen definite_uids, maybe_uids) < 0)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return -1;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen }
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return 0;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainenint fts_backend_lookup_deinit(struct fts_backend_lookup_context **_ctx,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ARRAY_TYPE(seq_range) *definite_uids,
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen ARRAY_TYPE(seq_range) *maybe_uids,
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen ARRAY_TYPE(fts_score_map) *scores)
809923ba26218971792182ae8894936f9ac99364Timo Sirainen{
809923ba26218971792182ae8894936f9ac99364Timo Sirainen struct fts_backend_lookup_context *ctx = *_ctx;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen int ret;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen
809923ba26218971792182ae8894936f9ac99364Timo Sirainen *_ctx = NULL;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (ctx->backend->v.lookup2 != NULL) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen ret = ctx->backend->v.lookup2(ctx, definite_uids, maybe_uids,
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen scores);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen } else {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen array_clear(scores);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen ret = fts_backend_lookup_old(ctx, definite_uids, maybe_uids);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
809923ba26218971792182ae8894936f9ac99364Timo Sirainen pool_unref(&ctx->pool);
809923ba26218971792182ae8894936f9ac99364Timo Sirainen return ret;
809923ba26218971792182ae8894936f9ac99364Timo Sirainen}
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainenbool fts_backend_default_can_index(const char *content_type)
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen{
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen return strncasecmp(content_type, "text/", 5) == 0 ||
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen strcasecmp(content_type, "message/rfc822") == 0;
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen}