dovecot-1.2: Added alias_for setting for namespaces. Fixes names...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Nov 30 02:09:20 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/3efcdc45d111
changeset: 8500:3efcdc45d111
user: Timo Sirainen <tss at iki.fi>
date: Sun Nov 30 02:09:16 2008 +0200
description:
Added alias_for setting for namespaces. Fixes namespace issues with fts.
diffstat:
7 files changed, 126 insertions(+), 38 deletions(-)
src/lib-storage/mail-namespace.c | 25 ++++++++-
src/lib-storage/mail-namespace.h | 10 +++
src/master/mail-process.c | 4 +
src/master/master-settings.c | 28 +++++++++-
src/master/master-settings.h | 1
src/plugins/fts-solr/fts-backend-solr.c | 79 +++++++++++++++++++------------
src/plugins/fts/fts-storage.c | 17 +++++-
diffs (truncated from 366 to 300 lines):
diff -r 252b29ac5f43 -r 3efcdc45d111 src/lib-storage/mail-namespace.c
--- a/src/lib-storage/mail-namespace.c Sun Nov 30 01:27:19 2008 +0200
+++ b/src/lib-storage/mail-namespace.c Sun Nov 30 02:09:16 2008 +0200
@@ -38,10 +38,11 @@ static struct mail_namespace *
static struct mail_namespace *
namespace_add_env(const char *data, unsigned int num,
struct mail_user *user, enum mail_storage_flags flags,
- enum file_lock_method lock_method)
+ enum file_lock_method lock_method,
+ struct mail_namespace *prev_namespaces)
{
struct mail_namespace *ns;
- const char *sep, *type, *prefix, *driver, *error, *list;
+ const char *sep, *type, *prefix, *driver, *error, *list, *alias_for;
ns = i_new(struct mail_namespace, 1);
@@ -49,6 +50,7 @@ namespace_add_env(const char *data, unsi
type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num));
prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num));
list = getenv(t_strdup_printf("NAMESPACE_%u_LIST", num));
+ alias_for = getenv(t_strdup_printf("NAMESPACE_%u_ALIAS", num));
if (getenv(t_strdup_printf("NAMESPACE_%u_INBOX", num)) != NULL)
ns->flags |= NAMESPACE_FLAG_INBOX;
if (getenv(t_strdup_printf("NAMESPACE_%u_HIDDEN", num)) != NULL)
@@ -75,6 +77,23 @@ namespace_add_env(const char *data, unsi
return NULL;
}
+ if (alias_for != NULL) {
+ ns->alias_for = mail_namespace_find_prefix(prev_namespaces,
+ alias_for);
+ if (ns->alias_for == NULL) {
+ i_error("Invalid namespace alias_for: %s", alias_for);
+ mail_namespace_free(ns);
+ return NULL;
+ }
+ if (ns->alias_for->alias_for != NULL) {
+ i_error("Chained namespace alias_for: %s", alias_for);
+ mail_namespace_free(ns);
+ return NULL;
+ }
+ ns->alias_chain_next = ns->alias_for->alias_chain_next;
+ ns->alias_for->alias_chain_next = ns;
+ }
+
if (prefix == NULL)
prefix = "";
@@ -207,7 +226,7 @@ int mail_namespaces_init(struct mail_use
T_BEGIN {
*ns_p = namespace_add_env(data, i, user, flags,
- lock_method);
+ lock_method, namespaces);
} T_END;
if (*ns_p == NULL)
diff -r 252b29ac5f43 -r 3efcdc45d111 src/lib-storage/mail-namespace.h
--- a/src/lib-storage/mail-namespace.h Sun Nov 30 01:27:19 2008 +0200
+++ b/src/lib-storage/mail-namespace.h Sun Nov 30 02:09:16 2008 +0200
@@ -40,6 +40,16 @@ struct mail_namespace {
char *prefix;
size_t prefix_len;
+
+ /* If non-NULL, this points to a namespace with identical mail location
+ and it should be considered as the primary way to access the
+ mailboxes. This allows for example FTS plugin to avoid duplicating
+ indexes for same mailboxes when they're accessed via different
+ namespaces. */
+ struct mail_namespace *alias_for;
+ /* alias_for->alias_chain_next starts each chain. The chain goes
+ through all namespaces that have the same alias_for. */
+ struct mail_namespace *alias_chain_next;
struct mail_user *user, *owner;
struct mailbox_list *list;
diff -r 252b29ac5f43 -r 3efcdc45d111 src/master/mail-process.c
--- a/src/master/mail-process.c Sun Nov 30 01:27:19 2008 +0200
+++ b/src/master/mail-process.c Sun Nov 30 02:09:16 2008 +0200
@@ -267,6 +267,10 @@ env_put_namespace(struct namespace_setti
if (ns->type != NULL) {
env_put(t_strdup_printf("NAMESPACE_%u_TYPE=%s",
i, ns->type));
+ }
+ if (ns->alias_for != NULL) {
+ env_put(t_strdup_printf("NAMESPACE_%u_ALIAS=%s",
+ i, ns->alias_for));
}
if (ns->prefix != NULL) {
/* expand variables, eg. ~%u/ can be useful */
diff -r 252b29ac5f43 -r 3efcdc45d111 src/master/master-settings.c
--- a/src/master/master-settings.c Sun Nov 30 01:27:19 2008 +0200
+++ b/src/master/master-settings.c Sun Nov 30 02:09:16 2008 +0200
@@ -158,6 +158,7 @@ static struct setting_def namespace_sett
DEF_STR(separator),
DEF_STR(prefix),
DEF_STR(location),
+ DEF_STR(alias_for),
DEF_BOOL(inbox),
DEF_BOOL(hidden),
DEF_STR(list),
@@ -359,6 +360,7 @@ struct namespace_settings default_namesp
MEMBER(separator) "",
MEMBER(prefix) "",
MEMBER(location) "",
+ MEMBER(alias_for) NULL,
MEMBER(inbox) FALSE,
MEMBER(hidden) FALSE,
@@ -489,8 +491,10 @@ static bool auth_settings_verify(struct
return TRUE;
}
-static bool namespace_settings_verify(struct namespace_settings *ns)
-{
+static bool namespace_settings_verify(struct server_settings *server,
+ struct namespace_settings *ns)
+{
+ struct namespace_settings *n;
const char *name;
name = ns->prefix != NULL ? ns->prefix : "";
@@ -508,6 +512,24 @@ static bool namespace_settings_verify(st
i_error("Namespace '%s': Invalid list value: %s",
name, ns->list);
return FALSE;
+ }
+
+ if (ns->alias_for != NULL) {
+ for (n = server->namespaces; n != ns; n = n->next) {
+ if (strcmp(n->prefix, ns->alias_for) == 0)
+ break;
+ }
+ if (n == NULL) {
+ i_error("Namespace '%s': alias_for points to "
+ "unknown namespace: %s", name, ns->alias_for);
+ return FALSE;
+ }
+ if (n->alias_for != NULL) {
+ i_error("Namespace '%s': alias_for chaining isn't "
+ "allowed: %s -> %s", name, ns->alias_for,
+ n->alias_for);
+ return FALSE;
+ }
}
return TRUE;
@@ -1559,7 +1581,7 @@ bool master_settings_read(const char *pa
}
ns = server->namespaces;
for (; ns != NULL; ns = ns->next) {
- if (!namespace_settings_verify(ns))
+ if (!namespace_settings_verify(server, ns))
return FALSE;
}
}
diff -r 252b29ac5f43 -r 3efcdc45d111 src/master/master-settings.h
--- a/src/master/master-settings.h Sun Nov 30 01:27:19 2008 +0200
+++ b/src/master/master-settings.h Sun Nov 30 02:09:16 2008 +0200
@@ -240,6 +240,7 @@ struct namespace_settings {
const char *separator;
const char *prefix;
const char *location;
+ const char *alias_for;
bool inbox;
bool hidden;
diff -r 252b29ac5f43 -r 3efcdc45d111 src/plugins/fts-solr/fts-backend-solr.c
--- a/src/plugins/fts-solr/fts-backend-solr.c Sun Nov 30 01:27:19 2008 +0200
+++ b/src/plugins/fts-solr/fts-backend-solr.c Sun Nov 30 02:09:16 2008 +0200
@@ -127,6 +127,9 @@ fts_backend_solr_init(struct mailbox *bo
struct mail_namespace *ns = box->storage->ns;
const char *str;
+ while (ns->alias_for != NULL)
+ ns = ns->alias_for;
+
if (solr_conn == NULL)
solr_conn = solr_connection_init(set->url, set->debug);
@@ -143,9 +146,12 @@ fts_backend_solr_init(struct mailbox *bo
backend->default_ns =
mail_namespace_find_inbox(ns->user->namespaces);
}
+ while (backend->default_ns->alias_for != NULL)
+ backend->default_ns = backend->default_ns->alias_for;
+
str = solr_escape_id_str(ns->user->username);
backend->id_username = i_strdup(str);
- if (box->storage->ns != backend->default_ns) {
+ if (ns != backend->default_ns) {
str = solr_escape_id_str(ns->prefix);
backend->id_namespace = i_strdup(str);
}
@@ -170,6 +176,9 @@ solr_add_ns_query(string_t *str, struct
struct mail_namespace *ns)
{
struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
+
+ while (ns->alias_for != NULL)
+ ns = ns->alias_for;
if (ns == backend->default_ns || *ns->prefix == '\0')
str_append(str, " -ns:[* TO *]");
@@ -268,23 +277,17 @@ static int fts_backend_solr_get_last_uid
return 0;
}
-static const char *
-solr_get_vmailbox(struct fts_backend *_backend,
- struct mailbox *box, const char *ns_prefix,
- const char *mailbox, string_t *dest)
+static struct mail_namespace *
+solr_get_namespaces(struct fts_backend *_backend,
+ struct mailbox *box, const char *ns_prefix)
{
struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
struct mail_namespace *namespaces = box->storage->ns->user->namespaces;
- struct mail_namespace *ns;
if (ns_prefix == NULL)
- ns = backend->default_ns;
- else {
- ns = mail_namespace_find_prefix(namespaces, ns_prefix);
- if (ns == NULL)
- return FALSE;
- }
- return mail_namespace_get_vname(ns, dest, mailbox);
+ return backend->default_ns;
+ else
+ return mail_namespace_find_prefix(namespaces, ns_prefix);
}
static bool
@@ -293,15 +296,17 @@ solr_virtual_get_last_uids(const char *n
{
struct fts_backend_solr_get_last_uids_context *ctx = context;
struct fts_backend_uid_map *map;
+ struct mail_namespace *ns;
const char *vname;
- vname = solr_get_vmailbox(ctx->backend, ctx->box, ns_prefix,
- mailbox, ctx->vname);
-
- map = array_append_space(ctx->last_uids);
- map->mailbox = p_strdup(ctx->pool, vname);
- map->uidvalidity = uidvalidity;
- map->uid = *uid;
+ ns = solr_get_namespaces(ctx->backend, ctx->box, ns_prefix);
+ for (; ns != NULL; ns = ns->alias_chain_next) {
+ vname = mail_namespace_get_vname(ns, ctx->vname, mailbox);
+ map = array_append_space(ctx->last_uids);
+ map->mailbox = p_strdup(ctx->pool, vname);
+ map->uidvalidity = uidvalidity;
+ map->uid = *uid;
+ }
return FALSE;
}
@@ -344,6 +349,7 @@ fts_backend_solr_filter_mailboxes(struct
{
struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
ARRAY_TYPE(mailbox_virtual_patterns) includes_arr, excludes_arr;
+ struct mail_namespace *ns;
const struct mailbox_virtual_pattern *includes, *excludes;
unsigned int i, inc_count, exc_count, len;
string_t *fq;
@@ -386,12 +392,15 @@ fts_backend_solr_filter_mailboxes(struct
str_append_c(fq, '(');
str_append(fq, "-box:");
solr_add_pattern(fq, &excludes[i]);
- if (excludes[i].ns == backend->default_ns) {
+
+ for (ns = excludes[i].ns; ns->alias_for != NULL; )
+ ns = ns->alias_for;
+ if (ns == backend->default_ns) {
str_append(fq, " OR NOT");
- solr_add_ns_query(fq, _backend, excludes[i].ns);
- } else if (*excludes[i].ns->prefix != '\0') {
+ solr_add_ns_query(fq, _backend, ns);
+ } else if (*ns->prefix != '\0') {
str_append(fq, " OR -ns:");
- solr_quote(fq, excludes[i].ns->prefix);
+ solr_quote(fq, ns->prefix);
}
str_append_c(fq, ')');
}
@@ -453,21 +462,25 @@ fts_backend_solr_add_doc_prefix(struct s
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;
str_printfa(ctx->cmd, "<doc>"
"<field name=\"uid\">%u</field>"
"<field name=\"uidv\">%u</field>",
uid, ctx->uid_validity);
More information about the dovecot-cvs
mailing list