bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "lib.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "array.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "str.h"
5601c23c0d59376dfda22c7eb807c9e1a0870426Timo Sirainen#include "unichar.h"
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen#include "mail-user.h"
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen#include "mail-namespace.h"
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen#include "mail-storage-private.h"
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen#include "mail-search-build.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "squat-trie.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "fts-squat-plugin.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#define SQUAT_FILE_PREFIX "dovecot.index.search"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainenstruct squat_fts_backend {
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct fts_backend backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *box;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct squat_trie *trie;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int partial_len, full_len;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool refresh;
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen};
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct squat_fts_backend_update_context {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_backend_update_context ctx;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct squat_trie_build_context *build_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen enum squat_index_type squat_type;
12055678401e913f4be130fa41b22fbeb626cc7eTimo Sirainen uint32_t uid;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen string_t *hdr;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen bool failed;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen};
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic struct fts_backend *fts_backend_squat_alloc(void)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend *backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend = i_new(struct squat_fts_backend, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->backend = fts_backend_squat;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return &backend->backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_init(struct fts_backend *_backend, const char **error_r)
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend *backend =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend *)_backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *const *tmp, *env;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen unsigned int len;
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen env = mail_user_plugin_getenv(_backend->ns->user, "fts_squat");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (env == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (tmp = t_strsplit_spaces(env, " "); *tmp != NULL; tmp++) {
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen if (strncmp(*tmp, "partial=", 8) == 0) {
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (str_to_uint(*tmp + 8, &len) < 0 || len == 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *error_r = t_strdup_printf(
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen "Invalid partial length: %s", *tmp + 8);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->partial_len = len;
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen } else if (strncmp(*tmp, "full=", 5) == 0) {
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (str_to_uint(*tmp + 5, &len) < 0 || len == 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *error_r = t_strdup_printf(
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen "Invalid full length: %s", *tmp + 5);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->full_len = len;
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen } else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *error_r = t_strdup_printf("Invalid setting: %s", *tmp);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen }
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen}
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_unset_box(struct squat_fts_backend *backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (backend->trie != NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_trie_deinit(&backend->trie);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->box = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void fts_backend_squat_deinit(struct fts_backend *_backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend *backend =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend *)_backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_unset_box(backend);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_free(backend);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrtstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_set_box(struct squat_fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *box)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
37cd04fc1d01c4a7140ffcb514e15cee1e97986aTimo Sirainen const struct mailbox_permissions *perm;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct mail_storage *storage;
ebfbf5d78dcf95e8b176429f4b5b0694eb4e17d5Timo Sirainen struct mailbox_status status;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *path;
ac383c437b1ccb9420cae6b4c4b03af3c8019e02Timo Sirainen enum squat_index_flags flags = 0;
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt int ret;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (backend->box == box)
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt {
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt if (backend->refresh) {
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt ret = squat_trie_refresh(backend->trie);
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt if (ret < 0)
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt return ret;
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt backend->refresh = FALSE;
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt }
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt return 0;
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_unset_box(backend);
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt backend->refresh = FALSE;
37cd04fc1d01c4a7140ffcb514e15cee1e97986aTimo Sirainen if (box == NULL)
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
37cd04fc1d01c4a7140ffcb514e15cee1e97986aTimo Sirainen perm = mailbox_get_permissions(box);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen storage = mailbox_get_storage(box);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX, &path) <= 0)
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen i_unreached(); /* fts already checked this */
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (storage->set->mmap_disable)
ac383c437b1ccb9420cae6b4c4b03af3c8019e02Timo Sirainen flags |= SQUAT_INDEX_FLAG_MMAP_DISABLE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (storage->set->mail_nfs_index)
ac383c437b1ccb9420cae6b4c4b03af3c8019e02Timo Sirainen flags |= SQUAT_INDEX_FLAG_NFS_FLUSH;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (storage->set->dotlock_use_excl)
ac383c437b1ccb9420cae6b4c4b03af3c8019e02Timo Sirainen flags |= SQUAT_INDEX_FLAG_DOTLOCK_USE_EXCL;
ebfbf5d78dcf95e8b176429f4b5b0694eb4e17d5Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen backend->trie =
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen squat_trie_init(t_strconcat(path, "/"SQUAT_FILE_PREFIX, NULL),
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen status.uidvalidity,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen storage->set->parsed_lock_method,
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen flags, perm->file_create_mode,
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen perm->file_create_gid);
4ae81f8f7aad06aad2f570535cad6e40aaec2b28Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (backend->partial_len != 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_trie_set_partial_len(backend->trie, backend->partial_len);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (backend->full_len != 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_trie_set_full_len(backend->trie, backend->full_len);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->box = box;
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt return squat_trie_open(backend->trie);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_get_last_uid(struct fts_backend *_backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *box, uint32_t *last_uid_r)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct squat_fts_backend *backend =
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen (struct squat_fts_backend *)_backend;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt int ret = fts_backend_squat_set_box(backend, box);
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt if (ret < 0)
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt return -1;
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen return squat_trie_get_last_uid(backend->trie, last_uid_r);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic struct fts_backend_update_context *
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_init(struct fts_backend *_backend)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx = i_new(struct squat_fts_backend_update_context, 1);
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen ctx->ctx.backend = _backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->hdr = str_new(default_pool, 1024*32);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return &ctx->ctx;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainenstatic int get_all_msg_uids(struct mailbox *box, ARRAY_TYPE(seq_range) *uids)
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen{
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen struct mailbox_transaction_context *t;
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen struct mail_search_context *search_ctx;
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen struct mail_search_args *search_args;
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen struct mail *mail;
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen int ret;
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi t = mailbox_transaction_begin(box, 0, __func__);
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen search_args = mail_search_build_init();
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen mail_search_build_add_all(search_args);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen search_ctx = mailbox_search_init(t, search_args, NULL, 0, NULL);
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen mail_search_args_unref(&search_args);
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen while (mailbox_search_next(search_ctx, &mail)) {
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen /* *2 because even/odd is for body/header */
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen seq_range_array_add_range(uids, mail->uid * 2,
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen mail->uid * 2 + 1);
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen }
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen ret = mailbox_search_deinit(&search_ctx);
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen (void)mailbox_transaction_commit(&t);
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen return ret;
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen}
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainenstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_uid_changed(struct squat_fts_backend_update_context *ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int ret = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->uid == 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (squat_trie_build_more(ctx->build_ctx, ctx->uid,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen SQUAT_INDEX_TYPE_HEADER,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen str_data(ctx->hdr), str_len(ctx->hdr)) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen str_truncate(ctx->hdr, 0);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_build_deinit(struct squat_fts_backend_update_context *ctx)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend *backend =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend *)ctx->ctx.backend;
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen ARRAY_TYPE(seq_range) uids;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int ret = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->build_ctx == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_squat_update_uid_changed(ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = -1;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen i_array_init(&uids, 1024);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (get_all_msg_uids(backend->box, &uids) < 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (void)squat_trie_build_deinit(&ctx->build_ctx, NULL);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen seq_range_array_invert(&uids, 2, (uint32_t)-2);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (squat_trie_build_deinit(&ctx->build_ctx, &uids) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = -1;
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen }
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen array_free(&uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_deinit(struct fts_backend_update_context *_ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int ret = ctx->failed ? -1 : 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_squat_build_deinit(ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen str_free(&ctx->hdr);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen i_free(ctx);
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen return ret;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainenstatic void
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_set_mailbox(struct fts_backend_update_context *_ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *box)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend *backend =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend *)ctx->ctx.backend;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_squat_build_deinit(ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->failed = TRUE;
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt if (fts_backend_squat_set_box(backend, box) < 0)
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt ctx->failed = TRUE;
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt else if (box != NULL) {
37cd04fc1d01c4a7140ffcb514e15cee1e97986aTimo Sirainen if (squat_trie_build_init(backend->trie, &ctx->build_ctx) < 0)
37cd04fc1d01c4a7140ffcb514e15cee1e97986aTimo Sirainen ctx->failed = TRUE;
37cd04fc1d01c4a7140ffcb514e15cee1e97986aTimo Sirainen }
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainenstatic void
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_expunge(struct fts_backend_update_context *_ctx ATTR_UNUSED,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uint32_t last_uid ATTR_UNUSED)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* FIXME */
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic bool
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_set_build_key(struct fts_backend_update_context *_ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct fts_backend_build_key *key)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->failed)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (key->uid != ctx->uid) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_squat_update_uid_changed(ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->failed = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (key->type) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case FTS_BACKEND_BUILD_KEY_HDR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case FTS_BACKEND_BUILD_KEY_MIME_HDR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen str_printfa(ctx->hdr, "%s: ", key->hdr_name);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->squat_type = SQUAT_INDEX_TYPE_HEADER;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case FTS_BACKEND_BUILD_KEY_BODY_PART:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->squat_type = SQUAT_INDEX_TYPE_BODY;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case FTS_BACKEND_BUILD_KEY_BODY_PART_BINARY:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_unreached();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->uid = key->uid;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_unset_build_key(struct fts_backend_update_context *_ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->squat_type == SQUAT_INDEX_TYPE_HEADER)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen str_append_c(ctx->hdr, '\n');
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_build_more(struct fts_backend_update_context *_ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const unsigned char *data, size_t size)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->squat_type == SQUAT_INDEX_TYPE_HEADER) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen str_append_n(ctx->hdr, data, size);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return squat_trie_build_more(ctx->build_ctx, ctx->uid, ctx->squat_type,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen data, size);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
de11cf486e0d0448537b1b5d546496ab85e7cda8Timo Sirainenstatic int fts_backend_squat_refresh(struct fts_backend *_backend)
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen{
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen struct squat_fts_backend *backend =
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen (struct squat_fts_backend *)_backend;
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen backend->refresh = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int fts_backend_squat_optimize(struct fts_backend *_backend ATTR_UNUSED)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* FIXME: drop expunged messages */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int squat_lookup_arg(struct squat_fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_arg *arg, bool and_args,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ARRAY_TYPE(seq_range) *definite_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ARRAY_TYPE(seq_range) *maybe_uids)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen enum squat_index_type squat_type;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ARRAY_TYPE(seq_range) tmp_definite_uids, tmp_maybe_uids;
5601c23c0d59376dfda22c7eb807c9e1a0870426Timo Sirainen string_t *dtc;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uint32_t last_uid;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (arg->type) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_TEXT:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_type = SQUAT_INDEX_TYPE_HEADER |
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen SQUAT_INDEX_TYPE_BODY;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_BODY:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_type = SQUAT_INDEX_TYPE_BODY;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER_ADDRESS:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_type = SQUAT_INDEX_TYPE_HEADER;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen default:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_array_init(&tmp_definite_uids, 128);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_array_init(&tmp_maybe_uids, 128);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
5601c23c0d59376dfda22c7eb807c9e1a0870426Timo Sirainen dtc = t_str_new(128);
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen if (backend->backend.ns->user->
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen default_normalizer(arg->value.str, strlen(arg->value.str), dtc) < 0)
5601c23c0d59376dfda22c7eb807c9e1a0870426Timo Sirainen i_panic("squat: search key not utf8");
5601c23c0d59376dfda22c7eb807c9e1a0870426Timo Sirainen
5601c23c0d59376dfda22c7eb807c9e1a0870426Timo Sirainen ret = squat_trie_lookup(backend->trie, str_c(dtc), squat_type,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen &tmp_definite_uids, &tmp_maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (arg->match_not) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* definite -> non-match
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen maybe -> maybe
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen non-match -> maybe */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_clear(&tmp_maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (squat_trie_get_last_uid(backend->trie, &last_uid) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_unreached();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_add_range(&tmp_maybe_uids, 1, last_uid);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_remove_seq_range(&tmp_maybe_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_clear(&tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (and_args) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* AND:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite && definite -> definite
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite && maybe -> maybe
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen maybe && maybe -> maybe */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* put definites among maybies, so they can be intersected */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(maybe_uids, definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(&tmp_maybe_uids, &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_intersect(maybe_uids, &tmp_maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_intersect(definite_uids, &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* remove duplicate maybies that are also definites */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_remove_seq_range(maybe_uids, definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* OR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite || definite -> definite
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite || maybe -> definite
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen maybe || maybe -> maybe */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* remove maybies that are now definites */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_remove_seq_range(&tmp_maybe_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_remove_seq_range(maybe_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(definite_uids, &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(maybe_uids, &tmp_maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_free(&tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_free(&tmp_maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ret < 0 ? -1 : 1;
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen}
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainenstatic int
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_lookup(struct fts_backend *_backend, struct mailbox *box,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen struct mail_search_arg *args,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen enum fts_lookup_flags flags,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_result *result)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct squat_fts_backend *backend =
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen (struct squat_fts_backend *)_backend;
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen bool and_args = (flags & FTS_LOOKUP_FLAG_AND_ARGS) != 0;
0007969c084c671b9f9378706083fad47799c84eTimo Sirainen bool first = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int ret;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt ret = fts_backend_squat_set_box(backend, box);
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt if (ret < 0)
d5db0fd38f7babf6b12c8bcc83dc8b5f32b71cc9nikwrt return -1;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (; args != NULL; args = args->next) {
0007969c084c671b9f9378706083fad47799c84eTimo Sirainen ret = squat_lookup_arg(backend, args, first ? FALSE : and_args,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen &result->definite_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen &result->maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ret < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
0aa8ac8b4c2f1fd539cc3d93358d6c7af8481408Timo Sirainen if (ret > 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen args->match_always = TRUE;
0aa8ac8b4c2f1fd539cc3d93358d6c7af8481408Timo Sirainen first = FALSE;
0aa8ac8b4c2f1fd539cc3d93358d6c7af8481408Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return 0;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainenstruct fts_backend fts_backend_squat = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = "squat",
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen .flags = FTS_BACKEND_FLAG_NORMALIZE_INPUT,
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_alloc,
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fts_backend_squat_init,
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fts_backend_squat_deinit,
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fts_backend_squat_get_last_uid,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_update_init,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_update_deinit,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_update_set_mailbox,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_update_expunge,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_update_set_build_key,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_update_unset_build_key,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_update_build_more,
de11cf486e0d0448537b1b5d546496ab85e7cda8Timo Sirainen fts_backend_squat_refresh,
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainen NULL,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_squat_optimize,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen fts_backend_default_can_lookup,
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fts_backend_squat_lookup,
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainen NULL,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen NULL
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen }
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen};