fts-backend-solr.c revision a7af27522004d1d520072c80883aa2a5c440ea6a
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2006-2010 Dovecot authors, see the included COPYING file */
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen char *id_username, *id_namespace, *id_box_name;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstruct fts_backend_solr_get_last_uids_context {
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainenstatic struct solr_connection *solr_conn = NULL;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainenstatic void fts_box_name_get_root(struct mail_namespace **ns, const char **name)
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen /* ugly workaround to allow selecting INBOX from a Maildir/
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen when it's not in the inbox=yes namespace. */
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainenstatic const char *
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainenfts_box_get_root(struct mailbox *box, struct mail_namespace **ns_r)
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen struct mail_namespace *ns = mailbox_get_namespace(box);
ce6c2809b8a1673372a683716566d973efd2f6eeTimo Sirainenxml_encode_data(string_t *dest, const unsigned char *data, unsigned int len)
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen unsigned int i;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen for (i = 0; i < len; i++) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen switch (data[i]) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen /* exceptions to the following control char check */
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen /* SOLR doesn't like control characters.
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen replace them with spaces. */
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainenstatic void xml_encode(string_t *dest, const char *str)
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen xml_encode_data(dest, (const unsigned char *)str, strlen(str));
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainenstatic const char *solr_escape_id_str(const char *str)
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen const char *p;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (*p == '\0')
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen switch (*p) {
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainenstatic void solr_quote(string_t *dest, const char *str)
b24ffea8baa472d9b542e54ed3f9939eefd020adTimo Sirainenstatic void solr_quote_http(string_t *dest, const char *str)
7d26aee0c0b6c0ce227ef4ae4f20fc86e2c423f2Timo Sirainen solr_connection_http_escape(solr_conn, dest, str);
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainenstatic struct fts_backend *
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const struct fts_solr_settings *set = &fuser->set;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen solr_conn = solr_connection_init(set->url, set->debug);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen mail_namespace_find_prefix(ns->user->namespaces,
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen i_fatal("fts_solr: default_ns setting points to "
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen "nonexisting namespace");
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen mail_namespace_find_inbox(ns->user->namespaces);
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen while (backend->default_ns->alias_for != NULL)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen backend->default_ns = backend->default_ns->alias_for;
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen backend->backend.flags |= FTS_BACKEND_FLAG_SUBSTRING_LOOKUPS;
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainenstatic void fts_backend_solr_deinit(struct fts_backend *_backend)
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainensolr_add_ns_query(string_t *str, struct fts_backend *_backend,
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen if (ns == backend->default_ns || *ns->prefix == '\0') {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainensolr_add_ns_query_http(string_t *str, struct fts_backend *backend,
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen solr_connection_http_escape(solr_conn, str, str_c(tmp));
9d75363d3fbabc2fbc2d80f06672e3ed8965804aTimo Sirainenstatic int fts_backend_solr_get_last_uid_fallback(struct fts_backend *backend,
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen unsigned int count;
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen str_append(str, "fl=uid&rows=1&sort=uid+desc&q=");
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen mailbox_get_status(box, STATUS_UIDVALIDITY, &status);
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen str_printfa(str, "uidv:%u+box:", status.uidvalidity);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen if (solr_connection_select(solr_conn, str_c(str),
1a669829132a4b68aaba32400e28bb2a4e19bcaaTimo Sirainen /* nothing indexed yet for this mailbox */
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen } else if (count == 1 && uidvals[0].seq1 == uidvals[0].seq2) {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen i_error("fts_solr: Last UID lookup returned multiple rows");
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic int fts_backend_solr_get_last_uid(struct fts_backend *backend,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen unsigned int count;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen str_append(str, "fl=uid&rows=1&q=last_uid:TRUE+");
if (count == 0) {
static struct mail_namespace *
const char *vname;
return FALSE;
const char *name, *p;
if (!i_isalnum(*p))
for (i = 0; i < inc_count; i++) {
for (i = 0; i < inc_count; i++) {
for (i = 0; i < exc_count; i++) {
const char *box_name;
if (uid != 0)
return FALSE;
return TRUE;
int ret;
return ret;
int ret;
return ret;
T_BEGIN {
} T_END;
void *context)
const char *vname;
bool convert_inbox;
return TRUE;
return FALSE;
const char *box_name;
unsigned int i, count;
bool virtual;
if (!virtual) {
for (i = 0; i < count; i++) {
if (virtual)
if (!virtual) {
NULL,
NULL,
NULL,