fts-backend-solr-old.c revision e99ffa6abd201ca6ebfdf609bb24e48327a86450
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2006-2015 Dovecot authors, see the included COPYING file */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* Valid characters in XML:
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] |
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen [#x10000-#x10FFFF]
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen This function gets called only for #x80 and higher */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenxml_encode_data(string_t *dest, const unsigned char *data, unsigned int len)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen unsigned int i;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen for (i = 0; i < len; i++) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen switch (data[i]) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* exceptions to the following control char check */
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen /* SOLR doesn't like control characters.
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen replace them with spaces. */
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen /* make sure the character is valid for XML
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen so we don't get XML parser errors */
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen unsigned int char_len =
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainenstatic void xml_encode(string_t *dest, const char *str)
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen xml_encode_data(dest, (const unsigned char *)str, strlen(str));
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainenstatic const char *solr_escape_id_str(const char *str)
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen const char *p;
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen if (*p == '\0')
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainen switch (*p) {
54b51a9c2705a19dfb1639647bc7e9378e37f881Timo Sirainenstatic void solr_quote(string_t *dest, const char *str)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic void solr_quote_http(string_t *dest, const char *str)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic void fts_solr_set_default_ns(struct solr_fts_backend *backend)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_namespace *ns = backend->backend.ns;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT(ns->user);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const struct fts_solr_settings *set = &fuser->set;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const char *str;
2738626e69754ba1278cb351c873f4187787fdfcTimo Sirainen mail_namespace_find_prefix(ns->user->namespaces,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen i_error("fts_solr: default_ns setting points to "
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "nonexistent namespace");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen mail_namespace_find_inbox(ns->user->namespaces);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen while (backend->default_ns->alias_for != NULL)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen backend->default_ns = backend->default_ns->alias_for;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic void fts_box_name_get_root(struct mail_namespace **ns, const char **name)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ((*ns)->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* ugly workaround to allow selecting INBOX from a Maildir/
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen when it's not in the inbox=yes namespace. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic const char *
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenfts_box_get_root(struct mailbox *box, struct mail_namespace **ns_r)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_namespace *ns = mailbox_get_namespace(box);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (t_imap_utf8_to_utf7(box->name, &name) < 0)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic struct fts_backend *fts_backend_solr_alloc(void)
4b6ec040fd7999b8be22aee9c7b4bbd4b11c0a5fTimo Sirainenfts_backend_solr_init(struct fts_backend *_backend, const char **error_r)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT(_backend->ns->user);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const char *str;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (solr_connection_init(fuser->set.url, fuser->set.debug,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen str = solr_escape_id_str(_backend->ns->user->username);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic void fts_backend_solr_deinit(struct fts_backend *_backend)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainensolr_add_ns_query(string_t *str, struct solr_fts_backend *backend,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ns == backend->default_ns || *ns->prefix == '\0') {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainensolr_add_ns_query_http(string_t *str, struct solr_fts_backend *backend,
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenfts_backend_solr_get_last_uid_fallback(struct solr_fts_backend *backend,
4860b8746b3b7846a9fe65b8c2907ba8aebd422fTimo Sirainen unsigned int count;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen str_append(str, "fl=uid&rows=1&sort=uid+desc&q=");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
e20e638805c4bd54e039891a3e92760b1dfa189aTimo Sirainen str_printfa(str, "uidv:%u+AND+box:", status.uidvalidity);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen pool = pool_alloconly_create("solr last uid lookup", 1024);
e20e638805c4bd54e039891a3e92760b1dfa189aTimo Sirainen if (solr_connection_select(backend->solr_conn, str_c(str),
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* no UIDs */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen uidvals = array_get(&results[0]->uids, &count);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (count == 1 && uidvals[0].seq1 == uidvals[0].seq2) {
b346610430690398b8c840006004a2df4aa8ce92Timo Sirainen i_error("fts_solr: Last UID lookup returned multiple rows");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenfts_backend_solr_get_last_uid(struct fts_backend *_backend,
static struct fts_backend_update_context *
if (uid != 0)
const char *box_name;
const char *str;
int ret;
return ret;
T_BEGIN {
} T_END;
i_unreached();
return TRUE;
case SEARCH_TEXT: {
case SEARCH_BODY:
return FALSE;
return TRUE;
bool and_args)
unsigned int last_len;
if (and_args)
return FALSE;
return TRUE;
const char *box_name;
int ret;
&status);
return ret;
const char *box_name;
char *box_id;
unsigned int i, len;
.flags = 0,
NULL,