Kouhei Sutou
null+****@clear*****
Fri May 20 12:31:12 JST 2016
Kouhei Sutou 2016-05-20 12:31:12 +0900 (Fri, 20 May 2016) New Revision: da2e1608c05eb49f79adf17795e912dfc5948c91 https://github.com/groonga/groonga/commit/da2e1608c05eb49f79adf17795e912dfc5948c91 Message: Add command version 3 It used object literal based envelope: { "header": { "return_code": 0, "start_time": 0.0, "elapsed_time": 0.0, }, "body": ... } Added files: test/command/suite/command_version/3/envelope/json.expected test/command/suite/command_version/3/envelope/json.test Modified files: include/groonga/groonga.h lib/ctx.c lib/output.c Modified: include/groonga/groonga.h (+3 -2) =================================================================== --- include/groonga/groonga.h 2016-05-20 11:33:11 +0900 (fdd15fe) +++ include/groonga/groonga.h 2016-05-20 12:31:12 +0900 (9889456) @@ -147,12 +147,13 @@ typedef enum { typedef enum { GRN_COMMAND_VERSION_DEFAULT = 0, GRN_COMMAND_VERSION_1, - GRN_COMMAND_VERSION_2 + GRN_COMMAND_VERSION_2, + GRN_COMMAND_VERSION_3 } grn_command_version; #define GRN_COMMAND_VERSION_MIN GRN_COMMAND_VERSION_1 #define GRN_COMMAND_VERSION_STABLE GRN_COMMAND_VERSION_1 -#define GRN_COMMAND_VERSION_MAX GRN_COMMAND_VERSION_2 +#define GRN_COMMAND_VERSION_MAX GRN_COMMAND_VERSION_3 typedef enum { GRN_LOG_NONE = 0, Modified: lib/ctx.c (+4 -8) =================================================================== --- lib/ctx.c 2016-05-20 11:33:11 +0900 (42b1324) +++ lib/ctx.c 2016-05-20 12:31:12 +0900 (f9946db) @@ -1013,13 +1013,11 @@ command_proc_p(grn_obj *expr) grn_obj * grn_ctx_qe_exec_uri(grn_ctx *ctx, const char *path, uint32_t path_len) { - grn_command_version command_version; grn_obj buf, *expr, *val; grn_obj request_id; double request_timeout; const char *p = path, *e = path + path_len, *v, *key_end, *filename_end; - command_version = grn_ctx_get_command_version(ctx); request_timeout = grn_get_default_request_timeout(); GRN_TEXT_INIT(&buf, 0); @@ -1115,15 +1113,12 @@ exit : GRN_OBJ_FIN(ctx, &request_id); GRN_OBJ_FIN(ctx, &buf); - grn_ctx_set_command_version(ctx, command_version); - return expr; } grn_obj * grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len) { - grn_command_version command_version; char tok_type; int offset = 0; grn_obj buf, *expr = NULL, *val = NULL; @@ -1131,7 +1126,6 @@ grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len) double request_timeout; const char *p = str, *e = str + str_len, *v; - command_version = grn_ctx_get_command_version(ctx); request_timeout = grn_get_default_request_timeout(); GRN_TEXT_INIT(&buf, 0); @@ -1233,8 +1227,6 @@ exit : GRN_OBJ_FIN(ctx, &request_id); GRN_OBJ_FIN(ctx, &buf); - grn_ctx_set_command_version(ctx, command_version); - return expr; } @@ -1300,7 +1292,10 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags) } goto exit; } else { + grn_command_version command_version; grn_obj *expr = NULL; + + command_version = grn_ctx_get_command_version(ctx); if (ctx->impl->qe_next) { grn_obj *val; expr = ctx->impl->qe_next; @@ -1350,6 +1345,7 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags) } } if (expr) { grn_expr_clear_vars(ctx, expr); } + grn_ctx_set_command_version(ctx, command_version); goto exit; } } Modified: lib/output.c (+177 -28) =================================================================== --- lib/output.c 2016-05-20 11:33:11 +0900 (ed2805f) +++ lib/output.c 2016-05-20 12:31:12 +0900 (3f30d2d) @@ -73,6 +73,54 @@ json_element_end(grn_ctx *ctx, grn_obj *outbuf, size_t indent_level) } static void +json_map_open(grn_ctx *ctx, grn_obj *outbuf, size_t *indent_level) +{ + GRN_TEXT_PUTC(ctx, outbuf, '{'); + if (ctx->impl->output.is_pretty) { + GRN_TEXT_PUTC(ctx, outbuf, '\n'); + (*indent_level)++; + indent(ctx, outbuf, *indent_level); + } +} + +static void +json_map_close(grn_ctx *ctx, grn_obj *outbuf, size_t *indent_level) +{ + if (ctx->impl->output.is_pretty) { + GRN_TEXT_PUTC(ctx, outbuf, '\n'); + (*indent_level)--; + indent(ctx, outbuf, *indent_level); + } + GRN_TEXT_PUTC(ctx, outbuf, '}'); +} + +static void +json_key_end(grn_ctx *ctx, grn_obj *outbuf) +{ + GRN_TEXT_PUTC(ctx, outbuf, ':'); + if (ctx->impl->output.is_pretty) { + GRN_TEXT_PUTC(ctx, outbuf, ' '); + } +} + +static void +json_key(grn_ctx *ctx, grn_obj *outbuf, const char *key) +{ + grn_text_esc(ctx, outbuf, key, strlen(key)); + json_key_end(ctx, outbuf); +} + +static void +json_value_end(grn_ctx *ctx, grn_obj *outbuf, size_t indent_level) +{ + GRN_TEXT_PUTC(ctx, outbuf, ','); + if (ctx->impl->output.is_pretty) { + GRN_TEXT_PUTC(ctx, outbuf, '\n'); + indent(ctx, outbuf, indent_level); + } +} + +static void put_delimiter(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type) { uint32_t level = CURR_LEVEL; @@ -1926,30 +1974,17 @@ msgpack_buffer_writer(void* data, const char* buf, msgpack_size_t len) #define JSON_CALLBACK_PARAM "callback" static void -grn_output_envelope_json(grn_ctx *ctx, - grn_rc rc, - grn_obj *head, - grn_obj *body, - grn_obj *foot, - double started, - double elapsed, - const char *file, - int line) +grn_output_envelope_json_v1(grn_ctx *ctx, + grn_rc rc, + grn_obj *head, + grn_obj *body, + grn_obj *foot, + double started, + double elapsed, + const char *file, + int line) { size_t indent_level = 0; - grn_obj *expr; - grn_obj *jsonp_func = NULL; - - expr = ctx->impl->curr_expr; - if (expr) { - jsonp_func = grn_expr_get_var(ctx, expr, JSON_CALLBACK_PARAM, - strlen(JSON_CALLBACK_PARAM)); - } - if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) { - GRN_TEXT_PUT(ctx, head, - GRN_TEXT_VALUE(jsonp_func), GRN_TEXT_LEN(jsonp_func)); - GRN_TEXT_PUTC(ctx, head, '('); - } json_array_open(ctx, head, &indent_level); { @@ -2013,8 +2048,95 @@ grn_output_envelope_json(grn_ctx *ctx, } json_array_close(ctx, foot, &indent_level); - if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) { - GRN_TEXT_PUTS(ctx, foot, ");"); +} + +static void +grn_output_envelope_json(grn_ctx *ctx, + grn_rc rc, + grn_obj *head, + grn_obj *body, + grn_obj *foot, + double started, + double elapsed, + const char *file, + int line) +{ + size_t indent_level = 0; + + json_map_open(ctx, head, &indent_level); + { + json_key(ctx, head, "header"); + json_map_open(ctx, head, &indent_level); + { + json_key(ctx, head, "return_code"); + grn_text_itoa(ctx, head, rc); + + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "start_time"); + grn_text_ftoa(ctx, head, started); + + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "elapsed_time"); + grn_text_ftoa(ctx, head, elapsed); + + if (rc != GRN_SUCCESS) { + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "error"); + json_map_open(ctx, head, &indent_level); + { + json_key(ctx, head, "message"); + grn_text_esc(ctx, head, ctx->errbuf, strlen(ctx->errbuf)); + + if (ctx->errfunc && ctx->errfile) { + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "function"); + grn_text_esc(ctx, head, ctx->errfunc, strlen(ctx->errfunc)); + + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "file"); + grn_text_esc(ctx, head, ctx->errfile, strlen(ctx->errfile)); + + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "line"); + grn_text_itoa(ctx, head, ctx->errline); + } + + if (file) { + grn_obj *command; + + command = GRN_CTX_USER_DATA(ctx)->ptr; + if (command) { + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "input"); + json_map_open(ctx, head, &indent_level); + { + json_key(ctx, head, "file"); + grn_text_esc(ctx, head, file, strlen(file)); + + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "line"); + grn_text_itoa(ctx, head, line); + + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "command"); + grn_text_esc(ctx, head, + GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command)); + } + json_map_close(ctx, head, &indent_level); + } + } + } + json_map_close(ctx, head, &indent_level); + } + } + json_map_close(ctx, head, &indent_level); + + if (GRN_TEXT_LEN(body)) { + json_value_end(ctx, head, indent_level); + json_key(ctx, head, "body"); + } + + json_map_close(ctx, foot, &indent_level); } } @@ -2039,10 +2161,37 @@ grn_output_envelope(grn_ctx *ctx, switch (ctx->impl->output.type) { case GRN_CONTENT_JSON: - grn_output_envelope_json(ctx, rc, - head, body, foot, - started, elapsed, - file, line); + { + grn_obj *expr; + grn_obj *jsonp_func = NULL; + + expr = ctx->impl->curr_expr; + if (expr) { + jsonp_func = grn_expr_get_var(ctx, expr, JSON_CALLBACK_PARAM, + strlen(JSON_CALLBACK_PARAM)); + } + if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) { + GRN_TEXT_PUT(ctx, head, + GRN_TEXT_VALUE(jsonp_func), GRN_TEXT_LEN(jsonp_func)); + GRN_TEXT_PUTC(ctx, head, '('); + } + + if (grn_ctx_get_command_version(ctx) <= GRN_COMMAND_VERSION_2) { + grn_output_envelope_json_v1(ctx, rc, + head, body, foot, + started, elapsed, + file, line); + } else { + grn_output_envelope_json(ctx, rc, + head, body, foot, + started, elapsed, + file, line); + } + + if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) { + GRN_TEXT_PUTS(ctx, foot, ");"); + } + } break; case GRN_CONTENT_TSV: grn_text_itoa(ctx, head, rc); Added: test/command/suite/command_version/3/envelope/json.expected (+2 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/command_version/3/envelope/json.expected 2016-05-20 12:31:12 +0900 (53fb9f8) @@ -0,0 +1,2 @@ +cache_limit --command_version 3 +{"header":{"return_code":0,"start_time":0.0,"elapsed_time":0.0},"body":100} Added: test/command/suite/command_version/3/envelope/json.test (+1 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/command_version/3/envelope/json.test 2016-05-20 12:31:12 +0900 (90eaaa2) @@ -0,0 +1 @@ +cache_limit --command_version 3 -------------- next part -------------- HTML����������������������������...下载