int solr_connection_select(struct solr_connection *conn, const char *query,
pool_t pool, struct solr_result ***box_results_r)
{
- struct solr_lookup_xml_context solr_lookup_context;
+ struct solr_response_parser parser;
struct solr_lookup_context lctx;
struct http_client_request *http_req;
const char *url;
i_zero(&lctx);
lctx.conn = conn;
- i_zero(&solr_lookup_context);
- solr_lookup_context.result_pool = pool;
- hash_table_create(&solr_lookup_context.mailboxes, default_pool, 0,
+ i_zero(&parser);
+ parser.result_pool = pool;
+ hash_table_create(&parser.mailboxes, default_pool, 0,
str_hash, strcmp);
- p_array_init(&solr_lookup_context.results, pool, 32);
+ p_array_init(&parser.results, pool, 32);
i_free_and_null(conn->http_failure);
conn->xml_failed = FALSE;
XML_SetElementHandler(conn->xml_parser,
solr_lookup_xml_start, solr_lookup_xml_end);
XML_SetCharacterDataHandler(conn->xml_parser, solr_lookup_xml_data);
- XML_SetUserData(conn->xml_parser, &solr_lookup_context);
+ XML_SetUserData(conn->xml_parser, &parser);
url = t_strconcat(conn->http_base_url, "select?", query, NULL);
http_client_wait(solr_http_client);
if (lctx.request_status < 0 ||
- solr_lookup_context.content_state == SOLR_XML_CONTENT_STATE_ERROR)
+ parser.content_state == SOLR_XML_CONTENT_STATE_ERROR)
return -1;
parse_ret = solr_xml_parse(conn, "", 0, TRUE);
- hash_table_destroy(&solr_lookup_context.mailboxes);
+ hash_table_destroy(&parser.mailboxes);
- array_append_zero(&solr_lookup_context.results);
- *box_results_r = array_front_modifiable(&solr_lookup_context.results);
+ array_append_zero(&parser.results);
+ *box_results_r = array_front_modifiable(&parser.results);
return parse_ret;
}
SOLR_XML_CONTENT_STATE_ERROR
};
-struct solr_lookup_xml_context {
+struct solr_response_parser {
enum solr_xml_response_state state;
enum solr_xml_content_state content_state;
int depth;
static void
solr_lookup_xml_start(void *context, const char *name, const char **attrs)
{
- struct solr_lookup_xml_context *ctx = context;
+ struct solr_response_parser *parser = context;
const char *name_attr;
- i_assert(ctx->depth >= (int)ctx->state);
+ i_assert(parser->depth >= (int)parser->state);
- ctx->depth++;
- if (ctx->depth - 1 > (int)ctx->state) {
+ parser->depth++;
+ if (parser->depth - 1 > (int)parser->state) {
/* skipping over unwanted elements */
return;
}
/* response -> result -> doc */
- switch (ctx->state) {
+ switch (parser->state) {
case SOLR_XML_RESPONSE_STATE_ROOT:
if (strcmp(name, "response") == 0)
- ctx->state++;
+ parser->state++;
break;
case SOLR_XML_RESPONSE_STATE_RESPONSE:
if (strcmp(name, "result") == 0)
- ctx->state++;
+ parser->state++;
break;
case SOLR_XML_RESPONSE_STATE_RESULT:
if (strcmp(name, "doc") == 0) {
- ctx->state++;
- ctx->uid = 0;
- ctx->score = 0;
- i_free_and_null(ctx->mailbox);
- i_free_and_null(ctx->ns);
- ctx->uidvalidity = 0;
+ parser->state++;
+ parser->uid = 0;
+ parser->score = 0;
+ i_free_and_null(parser->mailbox);
+ i_free_and_null(parser->ns);
+ parser->uidvalidity = 0;
}
break;
case SOLR_XML_RESPONSE_STATE_DOC:
name_attr = attrs_get_name(attrs);
if (strcmp(name_attr, "uid") == 0)
- ctx->content_state = SOLR_XML_CONTENT_STATE_UID;
+ parser->content_state = SOLR_XML_CONTENT_STATE_UID;
else if (strcmp(name_attr, "score") == 0)
- ctx->content_state = SOLR_XML_CONTENT_STATE_SCORE;
+ parser->content_state = SOLR_XML_CONTENT_STATE_SCORE;
else if (strcmp(name_attr, "box") == 0)
- ctx->content_state = SOLR_XML_CONTENT_STATE_MAILBOX;
+ parser->content_state = SOLR_XML_CONTENT_STATE_MAILBOX;
else if (strcmp(name_attr, "ns") == 0)
- ctx->content_state = SOLR_XML_CONTENT_STATE_NAMESPACE;
+ parser->content_state = SOLR_XML_CONTENT_STATE_NAMESPACE;
else if (strcmp(name_attr, "uidv") == 0)
- ctx->content_state = SOLR_XML_CONTENT_STATE_UIDVALIDITY;
+ parser->content_state = SOLR_XML_CONTENT_STATE_UIDVALIDITY;
else
break;
- ctx->state++;
+ parser->state++;
break;
case SOLR_XML_RESPONSE_STATE_CONTENT:
break;
}
static struct solr_result *
-solr_result_get(struct solr_lookup_xml_context *ctx, const char *box_id)
+solr_result_get(struct solr_response_parser *parser, const char *box_id)
{
struct solr_result *result;
char *box_id_dup;
- result = hash_table_lookup(ctx->mailboxes, box_id);
+ result = hash_table_lookup(parser->mailboxes, box_id);
if (result != NULL)
return result;
- box_id_dup = p_strdup(ctx->result_pool, box_id);
- result = p_new(ctx->result_pool, struct solr_result, 1);
+ box_id_dup = p_strdup(parser->result_pool, box_id);
+ result = p_new(parser->result_pool, struct solr_result, 1);
result->box_id = box_id_dup;
- p_array_init(&result->uids, ctx->result_pool, 32);
- p_array_init(&result->scores, ctx->result_pool, 32);
- hash_table_insert(ctx->mailboxes, box_id_dup, result);
- array_push_back(&ctx->results, &result);
+ p_array_init(&result->uids, parser->result_pool, 32);
+ p_array_init(&result->scores, parser->result_pool, 32);
+ hash_table_insert(parser->mailboxes, box_id_dup, result);
+ array_push_back(&parser->results, &result);
return result;
}
-static int solr_lookup_add_doc(struct solr_lookup_xml_context *ctx)
+static int solr_lookup_add_doc(struct solr_response_parser *parser)
{
struct fts_score_map *score;
struct solr_result *result;
const char *box_id;
- if (ctx->uid == 0) {
+ if (parser->uid == 0) {
i_error("fts_solr: uid missing from inside doc");
return -1;
}
- if (ctx->mailbox == NULL) {
+ if (parser->mailbox == NULL) {
/* looking up from a single mailbox only */
box_id = "";
- } else if (ctx->uidvalidity != 0) {
+ } else if (parser->uidvalidity != 0) {
/* old style lookup */
string_t *str = t_str_new(64);
- str_printfa(str, "%u\001", ctx->uidvalidity);
- str_append(str, ctx->mailbox);
- if (ctx->ns != NULL)
- str_printfa(str, "\001%s", ctx->ns);
+ str_printfa(str, "%u\001", parser->uidvalidity);
+ str_append(str, parser->mailbox);
+ if (parser->ns != NULL)
+ str_printfa(str, "\001%s", parser->ns);
box_id = str_c(str);
} else {
/* new style lookup */
- box_id = ctx->mailbox;
+ box_id = parser->mailbox;
}
- result = solr_result_get(ctx, box_id);
+ result = solr_result_get(parser, box_id);
- if (seq_range_array_add(&result->uids, ctx->uid)) {
+ if (seq_range_array_add(&result->uids, parser->uid)) {
/* duplicate result */
- } else if (ctx->score != 0) {
+ } else if (parser->score != 0) {
score = array_append_space(&result->scores);
- score->uid = ctx->uid;
- score->score = ctx->score;
+ score->uid = parser->uid;
+ score->score = parser->score;
}
return 0;
}
static void solr_lookup_xml_end(void *context, const char *name ATTR_UNUSED)
{
- struct solr_lookup_xml_context *ctx = context;
+ struct solr_response_parser *parser = context;
int ret;
- if (ctx->content_state == SOLR_XML_CONTENT_STATE_ERROR)
+ if (parser->content_state == SOLR_XML_CONTENT_STATE_ERROR)
return;
- i_assert(ctx->depth >= (int)ctx->state);
+ i_assert(parser->depth >= (int)parser->state);
- if (ctx->state == SOLR_XML_RESPONSE_STATE_CONTENT &&
- ctx->content_state == SOLR_XML_CONTENT_STATE_MAILBOX &&
- ctx->mailbox == NULL) {
+ if (parser->state == SOLR_XML_RESPONSE_STATE_CONTENT &&
+ parser->content_state == SOLR_XML_CONTENT_STATE_MAILBOX &&
+ parser->mailbox == NULL) {
/* mailbox is namespace prefix */
- ctx->mailbox = i_strdup("");
+ parser->mailbox = i_strdup("");
}
- if (ctx->depth == (int)ctx->state) {
+ if (parser->depth == (int)parser->state) {
ret = 0;
- if (ctx->state == SOLR_XML_RESPONSE_STATE_DOC) {
+ if (parser->state == SOLR_XML_RESPONSE_STATE_DOC) {
T_BEGIN {
- ret = solr_lookup_add_doc(ctx);
+ ret = solr_lookup_add_doc(parser);
} T_END;
}
- ctx->state--;
+ parser->state--;
if (ret < 0)
- ctx->content_state = SOLR_XML_CONTENT_STATE_ERROR;
+ parser->content_state = SOLR_XML_CONTENT_STATE_ERROR;
else
- ctx->content_state = SOLR_XML_CONTENT_STATE_NONE;
+ parser->content_state = SOLR_XML_CONTENT_STATE_NONE;
}
- ctx->depth--;
+ parser->depth--;
}
static int uint32_parse(const char *str, int len, uint32_t *value_r)
static void solr_lookup_xml_data(void *context, const char *str, int len)
{
- struct solr_lookup_xml_context *ctx = context;
+ struct solr_response_parser *parser = context;
char *new_name;
- switch (ctx->content_state) {
+ switch (parser->content_state) {
case SOLR_XML_CONTENT_STATE_NONE:
break;
case SOLR_XML_CONTENT_STATE_UID:
- if (uint32_parse(str, len, &ctx->uid) < 0 || ctx->uid == 0) {
+ if (uint32_parse(str, len, &parser->uid) < 0 ||
+ parser->uid == 0) {
i_error("fts_solr: received invalid uid '%s'",
t_strndup(str, len));
- ctx->content_state = SOLR_XML_CONTENT_STATE_ERROR;
+ parser->content_state = SOLR_XML_CONTENT_STATE_ERROR;
}
break;
case SOLR_XML_CONTENT_STATE_SCORE:
T_BEGIN {
- ctx->score = strtod(t_strndup(str, len), NULL);
+ parser->score = strtod(t_strndup(str, len), NULL);
} T_END;
break;
case SOLR_XML_CONTENT_STATE_MAILBOX:
/* this may be called multiple times, for example if input
contains '&' characters */
- new_name = ctx->mailbox == NULL ? i_strndup(str, len) :
- i_strconcat(ctx->mailbox, t_strndup(str, len), NULL);
- i_free(ctx->mailbox);
- ctx->mailbox = new_name;
+ new_name = parser->mailbox == NULL ? i_strndup(str, len) :
+ i_strconcat(parser->mailbox, t_strndup(str, len), NULL);
+ i_free(parser->mailbox);
+ parser->mailbox = new_name;
break;
case SOLR_XML_CONTENT_STATE_NAMESPACE:
- new_name = ctx->ns == NULL ? i_strndup(str, len) :
- i_strconcat(ctx->ns, t_strndup(str, len), NULL);
- i_free(ctx->ns);
- ctx->ns = new_name;
+ new_name = parser->ns == NULL ? i_strndup(str, len) :
+ i_strconcat(parser->ns, t_strndup(str, len), NULL);
+ i_free(parser->ns);
+ parser->ns = new_name;
break;
case SOLR_XML_CONTENT_STATE_UIDVALIDITY:
- if (uint32_parse(str, len, &ctx->uidvalidity) < 0)
+ if (uint32_parse(str, len, &parser->uidvalidity) < 0)
i_error("fts_solr: received invalid uidvalidity");
break;
case SOLR_XML_CONTENT_STATE_ERROR: