null+****@clear*****
null+****@clear*****
2010年 7月 13日 (火) 10:57:11 JST
Kouhei Sutou 2010-07-13 01:57:11 +0000 (Tue, 13 Jul 2010)
New Revision: 32614676ac70826e65f16acf91a5b4a04d80ed9d
Log:
revert select XML format change.
Modified files:
src/groonga.c
Modified: src/groonga.c (+278 -29)
===================================================================
--- src/groonga.c 2010-07-13 01:56:58 +0000 (8bfd1d4)
+++ src/groonga.c 2010-07-13 01:57:11 +0000 (b3c4405)
@@ -21,6 +21,7 @@
#include "lib/ql.h"
#include "lib/proc.h"
#include "lib/db.h"
+#include "lib/util.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>
@@ -207,6 +208,235 @@ typedef enum {
grn_http_request_type_post
} grn_http_request_type;
+typedef enum {
+ XML_START,
+ XML_START_ELEMENT,
+ XML_END_ELEMENT,
+ XML_TEXT
+} xml_status;
+
+typedef enum {
+ XML_PLACE_NONE,
+ XML_PLACE_COLUMN,
+ XML_PLACE_HIT
+} xml_place;
+
+static void
+transform_xml(grn_ctx *ctx, grn_obj *output, grn_obj *transformed)
+{
+ char *s, *e;
+ xml_status status = XML_START;
+ xml_place place = XML_PLACE_NONE;
+ grn_obj buf, name, columns, *expr;
+ unsigned int len;
+ int offset = 0, limit = 0, record_n = 0;
+ int column_n, column_text_n, result_set_n = -1;
+ int in_vector = 0;
+
+ s = GRN_TEXT_VALUE(output);
+ e = GRN_BULK_CURR(output);
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_INIT(&name, 0);
+ GRN_TEXT_INIT(&columns, 0);
+
+ expr = ctx->impl->curr_expr;
+
+#define EQUAL_NAME_P(_name) \
+ (GRN_TEXT_LEN(&name) == strlen(_name) && \
+ !memcmp(GRN_TEXT_VALUE(&name), _name, strlen(_name)))
+
+ while (s < e) {
+ switch (*s) {
+ case '<' :
+ s++;
+ switch (*s) {
+ case '/' :
+ status = XML_END_ELEMENT;
+ s++;
+ break;
+ default :
+ status = XML_START_ELEMENT;
+ break;
+ }
+ GRN_BULK_REWIND(&name);
+ break;
+ case '>' :
+ switch (status) {
+ case XML_START_ELEMENT :
+ if (EQUAL_NAME_P("COLUMN")) {
+ place = XML_PLACE_COLUMN;
+ column_text_n = 0;
+ } else if (EQUAL_NAME_P("HIT")) {
+ place = XML_PLACE_HIT;
+ column_n = 0;
+ if (result_set_n == 0) {
+ GRN_TEXT_PUTS(ctx, transformed, "<HIT NO=\"");
+ grn_text_itoa(ctx, transformed, record_n++);
+ GRN_TEXT_PUTS(ctx, transformed, "\">\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, "<NAVIGATIONELEMENT ");
+ }
+ } else if (EQUAL_NAME_P("RESULTSET")) {
+ GRN_BULK_REWIND(&columns);
+ result_set_n++;
+ if (result_set_n == 0) {
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, "<NAVIGATIONENTRY>");
+ }
+ } else if (EQUAL_NAME_P("VECTOR")) {
+ in_vector = 1;
+ }
+ break;
+ case XML_END_ELEMENT :
+ if (EQUAL_NAME_P("HIT")) {
+ place = XML_PLACE_NONE;
+ if (result_set_n == 0) {
+ GRN_TEXT_PUTS(ctx, transformed, "</HIT>\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, "/>");
+ }
+ } else if (EQUAL_NAME_P("RESULTSET")) {
+ place = XML_PLACE_NONE;
+ if (result_set_n == 0) {
+ GRN_TEXT_PUTS(ctx, transformed, "</RESULTSET>\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed,
+ "</NAVIGATIONELEMENTS>"
+ "</NAVIGATIONENTRY>");
+ }
+ } else if (EQUAL_NAME_P("RESULT")) {
+ GRN_TEXT_PUTS(ctx, transformed,
+ "</RESULTPAGE>\n"
+ "</SEGMENT>\n"
+ "</SEGMENTS>\n");
+ } else if (EQUAL_NAME_P("VECTOR")) {
+ in_vector = 0;
+ } else {
+ switch (place) {
+ case XML_PLACE_HIT :
+ {
+ int i = column_n;
+ char *c = GRN_TEXT_VALUE(&columns);
+ while (i--) {
+ while (*c) {
+ c++;
+ }
+ c++;
+ }
+ if (result_set_n == 0) {
+ GRN_TEXT_PUTS(ctx, transformed, "<FIELD NAME=\"");
+ GRN_TEXT_PUTS(ctx, transformed, c);
+ GRN_TEXT_PUTS(ctx, transformed, "\">");
+ if (!in_vector) {
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ }
+ GRN_TEXT_PUTS(ctx, transformed, "</FIELD>\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, c);
+ GRN_TEXT_PUTS(ctx, transformed, "=\"");
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ GRN_TEXT_PUTS(ctx, transformed, "\" ");
+ }
+ }
+ column_n++;
+ break;
+ default :
+ if (EQUAL_NAME_P("NHITS")) {
+ if (result_set_n == 0) {
+ uint32_t nhits;
+ grn_obj *offset_value, *limit_value;
+
+ nhits = grn_atoui(GRN_TEXT_VALUE(&buf), GRN_BULK_CURR(&buf),
+ NULL);
+ offset_value = grn_expr_get_var(ctx, expr,
+ "offset", strlen("offset"));
+ limit_value = grn_expr_get_var(ctx, expr,
+ "limit", strlen("limit"));
+ if (GRN_TEXT_LEN(offset_value)) {
+ offset = grn_atoi(GRN_TEXT_VALUE(offset_value),
+ GRN_BULK_CURR(offset_value),
+ NULL);
+ } else {
+ offset = 0;
+ }
+ if (GRN_TEXT_LEN(limit_value)) {
+ limit = grn_atoi(GRN_TEXT_VALUE(limit_value),
+ GRN_BULK_CURR(limit_value),
+ NULL);
+ } else {
+#define DEFAULT_LIMIT 10
+ limit = DEFAULT_LIMIT;
+#undef DEFAULT_LIMIT
+ }
+ grn_normalize_offset_and_limit(ctx, nhits, &offset, &limit);
+ record_n = offset + 1;
+ GRN_TEXT_PUTS(ctx, transformed,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<SEGMENTS>\n"
+ "<SEGMENT>\n"
+ "<RESULTPAGE>\n"
+ "<RESULTSET OFFSET=\"");
+ grn_text_lltoa(ctx, transformed, offset);
+ GRN_TEXT_PUTS(ctx, transformed, "\" LIMIT=\"");
+ grn_text_lltoa(ctx, transformed, limit);
+ GRN_TEXT_PUTS(ctx, transformed, "\" NHITS=\"");
+ grn_text_lltoa(ctx, transformed, nhits);
+ GRN_TEXT_PUTS(ctx, transformed, "\">\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed,
+ "<NAVIGATIONELEMENTS COUNT=\"");
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ GRN_TEXT_PUTS(ctx, transformed,
+ "\">");
+ }
+ } else if (EQUAL_NAME_P("TEXT")) {
+ switch (place) {
+ case XML_PLACE_COLUMN :
+ if (column_text_n == 0) {
+ GRN_TEXT_PUT(ctx, &columns,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ GRN_TEXT_PUTC(ctx, &columns, '\0');
+ }
+ column_text_n++;
+ break;
+ default :
+ break;
+ }
+ }
+ }
+ }
+ default :
+ break;
+ }
+ s++;
+ GRN_BULK_REWIND(&buf);
+ status = XML_TEXT;
+ break;
+ default :
+ len = grn_charlen(ctx, s, e);
+ switch (status) {
+ case XML_START_ELEMENT :
+ case XML_END_ELEMENT :
+ GRN_TEXT_PUT(ctx, &name, s, len);
+ break;
+ default :
+ GRN_TEXT_PUT(ctx, &buf, s, len);
+ break;
+ }
+ s += len;
+ break;
+ }
+ }
+#undef EQUAL_NAME_P
+
+ GRN_OBJ_FIN(ctx, &buf);
+ GRN_OBJ_FIN(ctx, &name);
+ GRN_OBJ_FIN(ctx, &columns);
+}
+
static void
print_return_code(grn_ctx *ctx, grn_rc rc, grn_obj *head, grn_obj *body, grn_obj *foot)
{
@@ -277,38 +507,57 @@ print_return_code(grn_ctx *ctx, grn_rc rc, grn_obj *head, grn_obj *body, grn_obj
GRN_TEXT_PUTS(ctx, foot, "\nEND");
break;
case GRN_CONTENT_XML:
- GRN_TEXT_PUTS(ctx, head, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RESULT CODE=\"");
- grn_text_itoa(ctx, head, rc);
- GRN_TEXT_PUTS(ctx, head, "\" UP=\"");
{
- double dv;
- grn_timeval tv;
- grn_timeval_now(ctx, &tv);
- dv = ctx->impl->tv.tv_sec;
- dv += ctx->impl->tv.tv_usec / 1000000.0;
- grn_text_ftoa(ctx, head, dv);
- dv = (tv.tv_sec - ctx->impl->tv.tv_sec);
- dv += (tv.tv_usec - ctx->impl->tv.tv_usec) / 1000000.0;
- GRN_TEXT_PUTS(ctx, head, "\" ELAPSED=\"");
- grn_text_ftoa(ctx, head, dv);
- GRN_TEXT_PUTS(ctx, head, "\">");
- }
- if (rc != GRN_SUCCESS) {
- GRN_TEXT_PUTS(ctx, head, "<ERROR>");
- grn_text_escape_xml(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
- if (ctx->errfunc && ctx->errfile) {
- /* TODO: output backtrace */
- GRN_TEXT_PUTS(ctx, head, "<INFO FUNC=\"");
- grn_text_escape_xml(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
- GRN_TEXT_PUTS(ctx, head, "\" FILE=\"");
- grn_text_escape_xml(ctx, head, ctx->errfile, strlen(ctx->errfile));
- GRN_TEXT_PUTS(ctx, head, "\" LINE=\"");
- grn_text_itoa(ctx, head, ctx->errline);
- GRN_TEXT_PUTS(ctx, head, "\">");
+ char buf[GRN_TABLE_MAX_KEY_SIZE];
+ int is_select = 0;
+ if (!rc && ctx->impl->curr_expr) {
+ int len = grn_obj_name(ctx, ctx->impl->curr_expr,
+ buf, GRN_TABLE_MAX_KEY_SIZE);
+ buf[len] = '\0';
+ is_select = strcmp(buf, "select") == 0;
+ }
+ if (is_select) {
+ grn_obj transformed;
+ GRN_TEXT_INIT(&transformed, 0);
+ transform_xml(ctx, body, &transformed);
+ GRN_TEXT_SET(ctx, body,
+ GRN_TEXT_VALUE(&transformed), GRN_TEXT_LEN(&transformed));
+ GRN_OBJ_FIN(ctx, &transformed);
+ } else {
+ GRN_TEXT_PUTS(ctx, head, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RESULT CODE=\"");
+ grn_text_itoa(ctx, head, rc);
+ GRN_TEXT_PUTS(ctx, head, "\" UP=\"");
+ {
+ double dv;
+ grn_timeval tv;
+ grn_timeval_now(ctx, &tv);
+ dv = ctx->impl->tv.tv_sec;
+ dv += ctx->impl->tv.tv_usec / 1000000.0;
+ grn_text_ftoa(ctx, head, dv);
+ dv = (tv.tv_sec - ctx->impl->tv.tv_sec);
+ dv += (tv.tv_usec - ctx->impl->tv.tv_usec) / 1000000.0;
+ GRN_TEXT_PUTS(ctx, head, "\" ELAPSED=\"");
+ grn_text_ftoa(ctx, head, dv);
+ GRN_TEXT_PUTS(ctx, head, "\">");
+ }
+ if (rc != GRN_SUCCESS) {
+ GRN_TEXT_PUTS(ctx, head, "<ERROR>");
+ grn_text_escape_xml(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
+ if (ctx->errfunc && ctx->errfile) {
+ /* TODO: output backtrace */
+ GRN_TEXT_PUTS(ctx, head, "<INFO FUNC=\"");
+ grn_text_escape_xml(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
+ GRN_TEXT_PUTS(ctx, head, "\" FILE=\"");
+ grn_text_escape_xml(ctx, head, ctx->errfile, strlen(ctx->errfile));
+ GRN_TEXT_PUTS(ctx, head, "\" LINE=\"");
+ grn_text_itoa(ctx, head, ctx->errline);
+ GRN_TEXT_PUTS(ctx, head, "\">");
+ }
+ GRN_TEXT_PUTS(ctx, head, "</ERROR>");
+ }
+ GRN_TEXT_PUTS(ctx, foot, "</RESULT>");
}
- GRN_TEXT_PUTS(ctx, head, "</ERROR>");
}
- GRN_TEXT_PUTS(ctx, foot, "</RESULT>");
break;
case GRN_CONTENT_MSGPACK:
// todo