Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/plugins/fts-solr/fts-backend-solr.c @ 8493:149c6ccc3df4 HEAD
fts-solr: Use '!' as escape character in usernames. Escape '/' and '!'.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 29 Nov 2008 19:24:59 +0200 |
parents | ee1ecdda8a6b |
children | ffb37c392166 |
comparison
equal
deleted
inserted
replaced
8492:ee1ecdda8a6b | 8493:149c6ccc3df4 |
---|---|
11 #include <curl/curl.h> | 11 #include <curl/curl.h> |
12 | 12 |
13 #define SOLR_CMDBUF_SIZE (1024*64) | 13 #define SOLR_CMDBUF_SIZE (1024*64) |
14 #define SOLR_MAX_ROWS 100000 | 14 #define SOLR_MAX_ROWS 100000 |
15 | 15 |
16 struct solr_fts_backend { | |
17 struct fts_backend backend; | |
18 char *id_username; | |
19 }; | |
20 | |
16 struct solr_fts_backend_build_context { | 21 struct solr_fts_backend_build_context { |
17 struct fts_backend_build_context ctx; | 22 struct fts_backend_build_context ctx; |
18 | 23 |
19 struct solr_connection_post *post; | 24 struct solr_connection_post *post; |
20 uint32_t prev_uid, uid_validity; | 25 uint32_t prev_uid, uid_validity; |
55 static void xml_encode(string_t *dest, const char *str) | 60 static void xml_encode(string_t *dest, const char *str) |
56 { | 61 { |
57 xml_encode_data(dest, (const unsigned char *)str, strlen(str)); | 62 xml_encode_data(dest, (const unsigned char *)str, strlen(str)); |
58 } | 63 } |
59 | 64 |
65 static const char *solr_escape_id_str(const char *str) | |
66 { | |
67 string_t *tmp; | |
68 const char *p; | |
69 | |
70 for (p = str; *p != '\0'; p++) { | |
71 if (*p == '/' || *p == '!') | |
72 break; | |
73 } | |
74 if (*p == '\0') | |
75 return str; | |
76 | |
77 tmp = t_str_new(64); | |
78 for (p = str; *p != '\0'; p++) { | |
79 switch (*p) { | |
80 case '/': | |
81 str_append(tmp, "!\\"); | |
82 break; | |
83 case '!': | |
84 str_append(tmp, "!!"); | |
85 break; | |
86 default: | |
87 str_append_c(tmp, *p); | |
88 break; | |
89 } | |
90 } | |
91 return str_c(tmp); | |
92 } | |
93 | |
60 static struct fts_backend * | 94 static struct fts_backend * |
61 fts_backend_solr_init(struct mailbox *box ATTR_UNUSED) | 95 fts_backend_solr_init(struct mailbox *box) |
62 { | 96 { |
63 const struct fts_solr_settings *set = &fts_solr_settings; | 97 const struct fts_solr_settings *set = &fts_solr_settings; |
64 struct fts_backend *backend; | 98 struct solr_fts_backend *backend; |
99 const char *username = box->storage->ns->user->username; | |
65 | 100 |
66 if (solr_conn == NULL) | 101 if (solr_conn == NULL) |
67 solr_conn = solr_connection_init(set->url, set->debug); | 102 solr_conn = solr_connection_init(set->url, set->debug); |
68 | 103 |
69 backend = i_new(struct fts_backend, 1); | 104 backend = i_new(struct solr_fts_backend, 1); |
70 *backend = fts_backend_solr; | 105 backend->id_username = i_strdup(solr_escape_id_str(username)); |
106 backend->backend = fts_backend_solr; | |
71 | 107 |
72 if (set->substring_search) | 108 if (set->substring_search) |
73 backend->flags |= FTS_BACKEND_FLAG_SUBSTRING_LOOKUPS; | 109 backend->backend.flags |= FTS_BACKEND_FLAG_SUBSTRING_LOOKUPS; |
74 return backend; | 110 return &backend->backend; |
75 } | 111 } |
76 | 112 |
77 static void fts_backend_solr_deinit(struct fts_backend *backend) | 113 static void fts_backend_solr_deinit(struct fts_backend *_backend) |
78 { | 114 { |
115 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; | |
116 | |
117 i_free(backend->id_username); | |
79 i_free(backend); | 118 i_free(backend); |
119 } | |
120 | |
121 static const char *fts_backend_solr_username(struct fts_backend *_backend) | |
122 { | |
123 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend; | |
124 | |
125 return backend->id_username; | |
80 } | 126 } |
81 | 127 |
82 static int fts_backend_solr_get_last_uid_fallback(struct fts_backend *backend, | 128 static int fts_backend_solr_get_last_uid_fallback(struct fts_backend *backend, |
83 uint32_t *last_uid_r) | 129 uint32_t *last_uid_r) |
84 { | 130 { |
212 ctx->prev_uid = uid; | 258 ctx->prev_uid = uid; |
213 | 259 |
214 fts_backend_solr_add_doc_prefix(ctx, uid); | 260 fts_backend_solr_add_doc_prefix(ctx, uid); |
215 str_printfa(cmd, "<field name=\"id\">%u/%u/", | 261 str_printfa(cmd, "<field name=\"id\">%u/%u/", |
216 uid, ctx->uid_validity); | 262 uid, ctx->uid_validity); |
217 xml_encode(cmd, box->storage->ns->user->username); | 263 xml_encode(cmd, fts_backend_solr_username(ctx->ctx.backend)); |
218 str_append_c(cmd, '/'); | 264 str_append_c(cmd, '/'); |
219 xml_encode(cmd, box->name); | 265 xml_encode(cmd, box->name); |
220 str_append(cmd, "</field>"); | 266 str_append(cmd, "</field>"); |
221 | 267 |
222 ctx->headers = headers; | 268 ctx->headers = headers; |
257 may shrink. This doesn't really matter, we'll simply do more work | 303 may shrink. This doesn't really matter, we'll simply do more work |
258 in future by reindexing some messages. */ | 304 in future by reindexing some messages. */ |
259 fts_backend_solr_add_doc_prefix(ctx, ctx->prev_uid); | 305 fts_backend_solr_add_doc_prefix(ctx, ctx->prev_uid); |
260 str_printfa(ctx->cmd, "<field name=\"last_uid\">TRUE</field>" | 306 str_printfa(ctx->cmd, "<field name=\"last_uid\">TRUE</field>" |
261 "<field name=\"id\">L/%u/", ctx->uid_validity); | 307 "<field name=\"id\">L/%u/", ctx->uid_validity); |
262 xml_encode(ctx->cmd, box->storage->ns->user->username); | 308 xml_encode(ctx->cmd, fts_backend_solr_username(ctx->ctx.backend)); |
263 str_append_c(ctx->cmd, '/'); | 309 str_append_c(ctx->cmd, '/'); |
264 xml_encode(ctx->cmd, box->name); | 310 xml_encode(ctx->cmd, box->name); |
265 str_append(ctx->cmd, "</field></doc></add>"); | 311 str_append(ctx->cmd, "</field></doc></add>"); |
266 | 312 |
267 solr_connection_post_more(ctx->post, str_data(ctx->cmd), | 313 solr_connection_post_more(ctx->post, str_data(ctx->cmd), |
287 i_free(ctx); | 333 i_free(ctx); |
288 return ret; | 334 return ret; |
289 } | 335 } |
290 | 336 |
291 static void | 337 static void |
292 fts_backend_solr_expunge(struct fts_backend *backend ATTR_UNUSED, | 338 fts_backend_solr_expunge(struct fts_backend *backend, struct mail *mail) |
293 struct mail *mail) | |
294 { | 339 { |
295 struct mailbox_status status; | 340 struct mailbox_status status; |
296 | 341 |
297 mailbox_get_status(mail->box, STATUS_UIDVALIDITY, &status); | 342 mailbox_get_status(mail->box, STATUS_UIDVALIDITY, &status); |
298 | 343 |
300 string_t *cmd; | 345 string_t *cmd; |
301 | 346 |
302 cmd = t_str_new(256); | 347 cmd = t_str_new(256); |
303 str_printfa(cmd, "<delete><id>%u/%u/", | 348 str_printfa(cmd, "<delete><id>%u/%u/", |
304 mail->uid, status.uidvalidity); | 349 mail->uid, status.uidvalidity); |
305 xml_encode(cmd, mail->box->storage->ns->user->username); | 350 xml_encode(cmd, fts_backend_solr_username(backend)); |
306 str_append_c(cmd, '/'); | 351 str_append_c(cmd, '/'); |
307 xml_encode(cmd, mail->box->name); | 352 xml_encode(cmd, mail->box->name); |
308 str_append(cmd, "</id></delete>"); | 353 str_append(cmd, "</id></delete>"); |
309 | 354 |
310 (void)solr_connection_post(solr_conn, str_c(cmd)); | 355 (void)solr_connection_post(solr_conn, str_c(cmd)); |