comparison src/plugins/fts-solr/fts-backend-solr.c @ 8500:3efcdc45d111 HEAD

Added alias_for setting for namespaces. Fixes namespace issues with fts.
author Timo Sirainen <tss@iki.fi>
date Sun, 30 Nov 2008 02:09:16 +0200
parents 252b29ac5f43
children 5cc1c4f3d38b
comparison
equal deleted inserted replaced
8499:252b29ac5f43 8500:3efcdc45d111
125 const struct fts_solr_settings *set = &fts_solr_settings; 125 const struct fts_solr_settings *set = &fts_solr_settings;
126 struct solr_fts_backend *backend; 126 struct solr_fts_backend *backend;
127 struct mail_namespace *ns = box->storage->ns; 127 struct mail_namespace *ns = box->storage->ns;
128 const char *str; 128 const char *str;
129 129
130 while (ns->alias_for != NULL)
131 ns = ns->alias_for;
132
130 if (solr_conn == NULL) 133 if (solr_conn == NULL)
131 solr_conn = solr_connection_init(set->url, set->debug); 134 solr_conn = solr_connection_init(set->url, set->debug);
132 135
133 backend = i_new(struct solr_fts_backend, 1); 136 backend = i_new(struct solr_fts_backend, 1);
134 str = fts_solr_settings.default_ns_prefix; 137 str = fts_solr_settings.default_ns_prefix;
141 } 144 }
142 } else { 145 } else {
143 backend->default_ns = 146 backend->default_ns =
144 mail_namespace_find_inbox(ns->user->namespaces); 147 mail_namespace_find_inbox(ns->user->namespaces);
145 } 148 }
149 while (backend->default_ns->alias_for != NULL)
150 backend->default_ns = backend->default_ns->alias_for;
151
146 str = solr_escape_id_str(ns->user->username); 152 str = solr_escape_id_str(ns->user->username);
147 backend->id_username = i_strdup(str); 153 backend->id_username = i_strdup(str);
148 if (box->storage->ns != backend->default_ns) { 154 if (ns != backend->default_ns) {
149 str = solr_escape_id_str(ns->prefix); 155 str = solr_escape_id_str(ns->prefix);
150 backend->id_namespace = i_strdup(str); 156 backend->id_namespace = i_strdup(str);
151 } 157 }
152 backend->backend = fts_backend_solr; 158 backend->backend = fts_backend_solr;
153 159
168 static void 174 static void
169 solr_add_ns_query(string_t *str, struct fts_backend *_backend, 175 solr_add_ns_query(string_t *str, struct fts_backend *_backend,
170 struct mail_namespace *ns) 176 struct mail_namespace *ns)
171 { 177 {
172 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; 178 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
179
180 while (ns->alias_for != NULL)
181 ns = ns->alias_for;
173 182
174 if (ns == backend->default_ns || *ns->prefix == '\0') 183 if (ns == backend->default_ns || *ns->prefix == '\0')
175 str_append(str, " -ns:[* TO *]"); 184 str_append(str, " -ns:[* TO *]");
176 else { 185 else {
177 str_append(str, " ns:"); 186 str_append(str, " ns:");
266 return -1; 275 return -1;
267 } 276 }
268 return 0; 277 return 0;
269 } 278 }
270 279
271 static const char * 280 static struct mail_namespace *
272 solr_get_vmailbox(struct fts_backend *_backend, 281 solr_get_namespaces(struct fts_backend *_backend,
273 struct mailbox *box, const char *ns_prefix, 282 struct mailbox *box, const char *ns_prefix)
274 const char *mailbox, string_t *dest)
275 { 283 {
276 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; 284 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
277 struct mail_namespace *namespaces = box->storage->ns->user->namespaces; 285 struct mail_namespace *namespaces = box->storage->ns->user->namespaces;
278 struct mail_namespace *ns;
279 286
280 if (ns_prefix == NULL) 287 if (ns_prefix == NULL)
281 ns = backend->default_ns; 288 return backend->default_ns;
282 else { 289 else
283 ns = mail_namespace_find_prefix(namespaces, ns_prefix); 290 return mail_namespace_find_prefix(namespaces, ns_prefix);
284 if (ns == NULL)
285 return FALSE;
286 }
287 return mail_namespace_get_vname(ns, dest, mailbox);
288 } 291 }
289 292
290 static bool 293 static bool
291 solr_virtual_get_last_uids(const char *ns_prefix, const char *mailbox, 294 solr_virtual_get_last_uids(const char *ns_prefix, const char *mailbox,
292 uint32_t uidvalidity, uint32_t *uid, void *context) 295 uint32_t uidvalidity, uint32_t *uid, void *context)
293 { 296 {
294 struct fts_backend_solr_get_last_uids_context *ctx = context; 297 struct fts_backend_solr_get_last_uids_context *ctx = context;
295 struct fts_backend_uid_map *map; 298 struct fts_backend_uid_map *map;
299 struct mail_namespace *ns;
296 const char *vname; 300 const char *vname;
297 301
298 vname = solr_get_vmailbox(ctx->backend, ctx->box, ns_prefix, 302 ns = solr_get_namespaces(ctx->backend, ctx->box, ns_prefix);
299 mailbox, ctx->vname); 303 for (; ns != NULL; ns = ns->alias_chain_next) {
300 304 vname = mail_namespace_get_vname(ns, ctx->vname, mailbox);
301 map = array_append_space(ctx->last_uids); 305 map = array_append_space(ctx->last_uids);
302 map->mailbox = p_strdup(ctx->pool, vname); 306 map->mailbox = p_strdup(ctx->pool, vname);
303 map->uidvalidity = uidvalidity; 307 map->uidvalidity = uidvalidity;
304 map->uid = *uid; 308 map->uid = *uid;
309 }
305 return FALSE; 310 return FALSE;
306 } 311 }
307 312
308 static void 313 static void
309 solr_add_pattern(string_t *str, const struct mailbox_virtual_pattern *pattern) 314 solr_add_pattern(string_t *str, const struct mailbox_virtual_pattern *pattern)
342 fts_backend_solr_filter_mailboxes(struct fts_backend *_backend, 347 fts_backend_solr_filter_mailboxes(struct fts_backend *_backend,
343 string_t *str, struct mailbox *box) 348 string_t *str, struct mailbox *box)
344 { 349 {
345 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; 350 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
346 ARRAY_TYPE(mailbox_virtual_patterns) includes_arr, excludes_arr; 351 ARRAY_TYPE(mailbox_virtual_patterns) includes_arr, excludes_arr;
352 struct mail_namespace *ns;
347 const struct mailbox_virtual_pattern *includes, *excludes; 353 const struct mailbox_virtual_pattern *includes, *excludes;
348 unsigned int i, inc_count, exc_count, len; 354 unsigned int i, inc_count, exc_count, len;
349 string_t *fq; 355 string_t *fq;
350 356
351 t_array_init(&includes_arr, 16); 357 t_array_init(&includes_arr, 16);
384 if (str_len(fq) > len) 390 if (str_len(fq) > len)
385 str_append_c(fq, ' '); 391 str_append_c(fq, ' ');
386 str_append_c(fq, '('); 392 str_append_c(fq, '(');
387 str_append(fq, "-box:"); 393 str_append(fq, "-box:");
388 solr_add_pattern(fq, &excludes[i]); 394 solr_add_pattern(fq, &excludes[i]);
389 if (excludes[i].ns == backend->default_ns) { 395
396 for (ns = excludes[i].ns; ns->alias_for != NULL; )
397 ns = ns->alias_for;
398 if (ns == backend->default_ns) {
390 str_append(fq, " OR NOT"); 399 str_append(fq, " OR NOT");
391 solr_add_ns_query(fq, _backend, excludes[i].ns); 400 solr_add_ns_query(fq, _backend, ns);
392 } else if (*excludes[i].ns->prefix != '\0') { 401 } else if (*ns->prefix != '\0') {
393 str_append(fq, " OR -ns:"); 402 str_append(fq, " OR -ns:");
394 solr_quote(fq, excludes[i].ns->prefix); 403 solr_quote(fq, ns->prefix);
395 } 404 }
396 str_append_c(fq, ')'); 405 str_append_c(fq, ')');
397 } 406 }
398 if (str_len(fq) > 0) { 407 if (str_len(fq) > 0) {
399 str_append(str, "&fq="); 408 str_append(str, "&fq=");
451 uint32_t uid) 460 uint32_t uid)
452 { 461 {
453 struct solr_fts_backend *backend = 462 struct solr_fts_backend *backend =
454 (struct solr_fts_backend *)ctx->ctx.backend; 463 (struct solr_fts_backend *)ctx->ctx.backend;
455 struct mailbox *box = ctx->ctx.backend->box; 464 struct mailbox *box = ctx->ctx.backend->box;
465 struct mail_namespace *ns = box->storage->ns;
456 466
457 str_printfa(ctx->cmd, "<doc>" 467 str_printfa(ctx->cmd, "<doc>"
458 "<field name=\"uid\">%u</field>" 468 "<field name=\"uid\">%u</field>"
459 "<field name=\"uidv\">%u</field>", 469 "<field name=\"uidv\">%u</field>",
460 uid, ctx->uid_validity); 470 uid, ctx->uid_validity);
461 471
462 if (box->storage->ns != backend->default_ns) { 472 while (ns->alias_for != NULL)
473 ns = ns->alias_for;
474
475 if (ns != backend->default_ns) {
463 str_append(ctx->cmd, "<field name=\"ns\">"); 476 str_append(ctx->cmd, "<field name=\"ns\">");
464 xml_encode(ctx->cmd, box->storage->ns->prefix); 477 xml_encode(ctx->cmd, ns->prefix);
465 str_append(ctx->cmd, "</field>"); 478 str_append(ctx->cmd, "</field>");
466 } 479 }
467 str_append(ctx->cmd, "<field name=\"box\">"); 480 str_append(ctx->cmd, "<field name=\"box\">");
468 xml_encode(ctx->cmd, box->name); 481 xml_encode(ctx->cmd, box->name);
469 str_append(ctx->cmd, "</field><field name=\"user\">"); 482 str_append(ctx->cmd, "</field><field name=\"user\">");
470 xml_encode(ctx->cmd, box->storage->ns->user->username); 483 xml_encode(ctx->cmd, ns->user->username);
471 str_append(ctx->cmd, "</field>"); 484 str_append(ctx->cmd, "</field>");
472 } 485 }
473 486
474 static void xml_encode_id(string_t *str, struct fts_backend *_backend, 487 static void xml_encode_id(string_t *str, struct fts_backend *_backend,
475 uint32_t uid, uint32_t uid_validity, 488 uint32_t uid, uint32_t uid_validity,
627 static bool solr_virtual_uid_map(const char *ns_prefix, const char *mailbox, 640 static bool solr_virtual_uid_map(const char *ns_prefix, const char *mailbox,
628 uint32_t uidvalidity, uint32_t *uid, 641 uint32_t uidvalidity, uint32_t *uid,
629 void *context) 642 void *context)
630 { 643 {
631 struct solr_virtual_uid_map_context *ctx = context; 644 struct solr_virtual_uid_map_context *ctx = context;
645 struct mail_namespace *ns;
632 const char *vname; 646 const char *vname;
633 647
634 vname = solr_get_vmailbox(ctx->backend, ctx->box, ns_prefix, 648 ns = solr_get_namespaces(ctx->backend, ctx->box, ns_prefix);
635 mailbox, ctx->vname); 649 for (; ns != NULL; ns = ns->alias_chain_next) {
636 return mailbox_get_virtual_uid(ctx->box, vname, uidvalidity, *uid, uid); 650 vname = mail_namespace_get_vname(ns, ctx->vname, mailbox);
651 if (mailbox_get_virtual_uid(ctx->box, vname, uidvalidity,
652 *uid, uid))
653 return TRUE;
654 }
655 return FALSE;
637 } 656 }
638 657
639 static int fts_backend_solr_lookup(struct fts_backend_lookup_context *ctx, 658 static int fts_backend_solr_lookup(struct fts_backend_lookup_context *ctx,
640 ARRAY_TYPE(seq_range) *definite_uids, 659 ARRAY_TYPE(seq_range) *definite_uids,
641 ARRAY_TYPE(seq_range) *maybe_uids, 660 ARRAY_TYPE(seq_range) *maybe_uids,