Mercurial > dovecot > original-hg > dovecot-1.2
diff src/plugins/fts-solr/fts-backend-solr.c @ 8950:ec1ae90af21a HEAD
fts: Fixes to how virtual mailboxes are searched.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 15 Apr 2009 19:48:55 -0400 |
parents | 7e639229c2c8 |
children | d21bd1a1710a |
line wrap: on
line diff
--- a/src/plugins/fts-solr/fts-backend-solr.c Wed Apr 15 19:48:17 2009 -0400 +++ b/src/plugins/fts-solr/fts-backend-solr.c Wed Apr 15 19:48:55 2009 -0400 @@ -18,7 +18,7 @@ struct solr_fts_backend { struct fts_backend backend; - char *id_username, *id_namespace; + char *id_username, *id_namespace, *id_box_name; struct mail_namespace *default_ns; }; @@ -48,6 +48,32 @@ static struct solr_connection *solr_conn = NULL; +static void fts_box_name_get_root(struct mail_namespace **ns, const char **name) +{ + struct mail_namespace *orig_ns = *ns; + + while ((*ns)->alias_for != NULL) + *ns = (*ns)->alias_for; + + if (**name == '\0' && *ns != orig_ns && + ((*ns)->flags & NAMESPACE_FLAG_INBOX) != 0) { + /* ugly workaround to allow selecting INBOX from a Maildir/ + when it's not in the inbox=yes namespace. */ + *name = "INBOX"; + } +} + +static const char * +fts_box_get_root(struct mailbox *box, struct mail_namespace **ns_r) +{ + struct mail_namespace *ns = box->storage->ns; + const char *name = box->name; + + fts_box_name_get_root(&ns, &name); + *ns_r = ns; + return name; +} + static void xml_encode_data(string_t *dest, const unsigned char *data, unsigned int len) { @@ -136,11 +162,12 @@ { const struct fts_solr_settings *set = &fts_solr_settings; struct solr_fts_backend *backend; - struct mail_namespace *ns = box->storage->ns; - const char *str; + struct mail_namespace *ns; + const char *str, *box_name; - while (ns->alias_for != NULL) - ns = ns->alias_for; + + box_name = fts_box_get_root(box, &ns); + i_assert(*box_name != '\0'); if (solr_conn == NULL) solr_conn = solr_connection_init(set->url, set->debug); @@ -167,6 +194,7 @@ str = solr_escape_id_str(ns->prefix); backend->id_namespace = i_strdup(str); } + backend->id_box_name = i_strdup(box_name); backend->backend = fts_backend_solr; if (set->substring_search) @@ -178,6 +206,7 @@ { struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; + i_free(backend->id_box_name); i_free(backend->id_namespace); i_free(backend->id_username); i_free(backend); @@ -221,21 +250,25 @@ uint32_t *last_uid_r) { struct mailbox *box = backend->box; + struct mail_namespace *ns; struct mailbox_status status; ARRAY_TYPE(seq_range) uids; const struct seq_range *uidvals; + const char *box_name; unsigned int count; string_t *str; str = t_str_new(256); str_append(str, "fl=uid&rows=1&sort=uid+desc&q="); + box_name = fts_box_get_root(box, &ns); + mailbox_get_status(box, STATUS_UIDVALIDITY, &status); str_printfa(str, "uidv:%u+box:", status.uidvalidity); - solr_quote_http(str, box->name); - solr_add_ns_query_http(str, backend, box->storage->ns); + solr_quote_http(str, box_name); + solr_add_ns_query_http(str, backend, ns); str_append(str, "+user:"); - solr_quote_http(str, box->storage->ns->user->username); + solr_quote_http(str, ns->user->username); t_array_init(&uids, 1); if (solr_connection_select(solr_conn, str_c(str), @@ -259,21 +292,25 @@ uint32_t *last_uid_r) { struct mailbox *box = backend->box; + struct mail_namespace *ns; struct mailbox_status status; ARRAY_TYPE(seq_range) uids; const struct seq_range *uidvals; + const char *box_name; unsigned int count; string_t *str; str = t_str_new(256); str_append(str, "fl=uid&rows=1&q=last_uid:TRUE+"); + box_name = fts_box_get_root(box, &ns); + mailbox_get_status(box, STATUS_UIDVALIDITY, &status); str_printfa(str, "uidv:%u+box:", status.uidvalidity); - solr_quote_http(str, box->name); - solr_add_ns_query_http(str, backend, box->storage->ns); + solr_quote_http(str, box_name); + solr_add_ns_query_http(str, backend, ns); str_append(str, "+user:"); - solr_quote_http(str, box->storage->ns->user->username); + solr_quote_http(str, ns->user->username); t_array_init(&uids, 1); if (solr_connection_select(solr_conn, str_c(str), @@ -331,12 +368,15 @@ static void solr_add_pattern(string_t *str, const struct mailbox_virtual_pattern *pattern) { + struct mail_namespace *ns = pattern->ns; const char *name, *p; name = pattern->pattern; if (!mail_namespace_update_name(pattern->ns, &name)) name = mail_namespace_fix_sep(pattern->ns, name); + fts_box_name_get_root(&ns, &name); + if (strcmp(name, "*") == 0) { str_append(str, "[* TO *]"); return; @@ -478,15 +518,15 @@ struct solr_fts_backend *backend = (struct solr_fts_backend *)ctx->ctx.backend; struct mailbox *box = ctx->ctx.backend->box; - struct mail_namespace *ns = box->storage->ns; + struct mail_namespace *ns; + const char *box_name; str_printfa(ctx->cmd, "<doc>" "<field name=\"uid\">%u</field>" "<field name=\"uidv\">%u</field>", uid, ctx->uid_validity); - while (ns->alias_for != NULL) - ns = ns->alias_for; + box_name = fts_box_get_root(box, &ns); if (ns != backend->default_ns) { str_append(ctx->cmd, "<field name=\"ns\">"); @@ -494,15 +534,14 @@ str_append(ctx->cmd, "</field>"); } str_append(ctx->cmd, "<field name=\"box\">"); - xml_encode(ctx->cmd, box->name); + xml_encode(ctx->cmd, box_name); str_append(ctx->cmd, "</field><field name=\"user\">"); xml_encode(ctx->cmd, ns->user->username); str_append(ctx->cmd, "</field>"); } static void xml_encode_id(string_t *str, struct fts_backend *_backend, - uint32_t uid, uint32_t uid_validity, - const char *mailbox) + uint32_t uid, uint32_t uid_validity) { struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; @@ -517,7 +556,7 @@ str_printfa(str, "%u/", uid_validity); xml_encode(str, backend->id_username); str_append_c(str, '/'); - xml_encode(str, mailbox); + xml_encode(str, backend->id_box_name); } static int @@ -527,7 +566,6 @@ { struct solr_fts_backend_build_context *ctx = (struct solr_fts_backend_build_context *)_ctx; - struct mailbox *box = _ctx->backend->box; string_t *cmd = ctx->cmd; /* body comes first, then headers */ @@ -543,8 +581,7 @@ fts_backend_solr_add_doc_prefix(ctx, uid); str_printfa(cmd, "<field name=\"id\">"); - xml_encode_id(cmd, _ctx->backend, uid, ctx->uid_validity, - box->name); + xml_encode_id(cmd, _ctx->backend, uid, ctx->uid_validity); str_append(cmd, "</field>"); ctx->headers = headers; @@ -571,7 +608,6 @@ static int fts_backed_solr_build_commit(struct solr_fts_backend_build_context *ctx) { - struct mailbox *box = ctx->ctx.backend->box; int ret; if (ctx->post == NULL) @@ -587,8 +623,7 @@ fts_backend_solr_add_doc_prefix(ctx, ctx->prev_uid); str_printfa(ctx->cmd, "<field name=\"last_uid\">TRUE</field>" "<field name=\"id\">"); - xml_encode_id(ctx->cmd, ctx->ctx.backend, 0, ctx->uid_validity, - box->name); + xml_encode_id(ctx->cmd, ctx->ctx.backend, 0, ctx->uid_validity); str_append(ctx->cmd, "</field></doc></add>"); solr_connection_post_more(ctx->post, str_data(ctx->cmd), @@ -627,8 +662,7 @@ cmd = t_str_new(256); str_append(cmd, "<delete><id>"); - xml_encode_id(cmd, backend, mail->uid, status.uidvalidity, - mail->box->name); + xml_encode_id(cmd, backend, mail->uid, status.uidvalidity); str_append(cmd, "</id></delete>"); (void)solr_connection_post(solr_conn, str_c(cmd)); @@ -660,10 +694,14 @@ struct solr_virtual_uid_map_context *ctx = context; struct mail_namespace *ns; const char *vname; + bool convert_inbox; ns = solr_get_namespaces(ctx->backend, ctx->box, ns_prefix); + convert_inbox = (ns->flags & NAMESPACE_FLAG_INBOX) != 0 && + strcmp(mailbox, "INBOX") == 0; for (; ns != NULL; ns = ns->alias_chain_next) { - vname = mail_namespace_get_vname(ns, ctx->vname, mailbox); + vname = convert_inbox ? ns->prefix : + mail_namespace_get_vname(ns, ctx->vname, mailbox); if (mailbox_get_virtual_uid(ctx->box, vname, uidvalidity, *uid, uid)) return TRUE; @@ -677,8 +715,10 @@ ARRAY_TYPE(fts_score_map) *scores) { struct mailbox *box = ctx->backend->box; + struct mail_namespace *ns; struct solr_virtual_uid_map_context uid_map_ctx; const struct fts_backend_lookup_field *fields; + const char *box_name; unsigned int i, count; struct mailbox_status status; string_t *str; @@ -727,9 +767,10 @@ if (virtual) fts_backend_solr_filter_mailboxes(ctx->backend, str, box); else { + box_name = fts_box_get_root(box, &ns); str_printfa(str, "+%%2Buidv:%u+%%2Bbox:", status.uidvalidity); - solr_quote_http(str, box->name); - solr_add_ns_query_http(str, ctx->backend, box->storage->ns); + solr_quote_http(str, box_name); + solr_add_ns_query_http(str, ctx->backend, ns); } array_clear(maybe_uids);