[Groonga-commit] groonga/groonga at ddb0d09 [master] Support pretty print for JSON output

Zurück zum Archiv-Index

Kouhei Sutou null+****@clear*****
Mon Nov 23 16:44:40 JST 2015


Kouhei Sutou	2015-11-23 16:44:40 +0900 (Mon, 23 Nov 2015)

  New Revision: ddb0d0998b0df06cf44cff2853ce159e4935ef97
  https://github.com/groonga/groonga/commit/ddb0d0998b0df06cf44cff2853ce159e4935ef97

  Message:
    Support pretty print for JSON output
    
    For example: `table_list --pretty yes`

  Modified files:
    lib/ctx.c
    lib/grn_ctx_impl.h
    lib/output.c

  Modified: lib/ctx.c (+23 -0)
===================================================================
--- lib/ctx.c    2015-11-23 15:44:48 +0900 (1be1bd4)
+++ lib/ctx.c    2015-11-23 16:44:40 +0900 (a894215)
@@ -1362,10 +1362,12 @@ get_command_version(grn_ctx *ctx, const char *p, const char *pe)
 #define OUTPUT_TYPE         "output_type"
 #define COMMAND_VERSION     "command_version"
 #define REQUEST_ID          "request_id"
+#define PRETTY              "pretty"
 #define EXPR_MISSING        "expr_missing"
 #define OUTPUT_TYPE_LEN     (sizeof(OUTPUT_TYPE) - 1)
 #define COMMAND_VERSION_LEN (sizeof(COMMAND_VERSION) - 1)
 #define REQUEST_ID_LEN      (sizeof(REQUEST_ID) - 1)
+#define PRETTY_LEN          (sizeof(PRETTY) - 1)
 
 #define HTTP_QUERY_PAIR_DELIMITER   "="
 #define HTTP_QUERY_PAIRS_DELIMITERS "&;"
@@ -1417,6 +1419,16 @@ grn_ctx_qe_exec_uri(grn_ctx *ctx, const char *path, uint32_t path_len)
           p = grn_text_cgidec(ctx, &request_id, p, e,
                               HTTP_QUERY_PAIRS_DELIMITERS);
           if (ctx->rc) { goto exit; }
+        } else if (l == PRETTY_LEN &&
+                   !memcmp(v, PRETTY, PRETTY_LEN)) {
+          GRN_BULK_REWIND(&buf);
+          p = grn_text_cgidec(ctx, &buf, p, e, HTTP_QUERY_PAIRS_DELIMITERS);
+          if (GRN_TEXT_LEN(&buf) == strlen("yes") &&
+              !memcmp(GRN_TEXT_VALUE(&buf), "yes", GRN_TEXT_LEN(&buf))) {
+            ctx->impl->output.is_pretty = GRN_TRUE;
+          } else {
+            ctx->impl->output.is_pretty = GRN_FALSE;
+          }
         } else {
           if (!(val = grn_expr_get_or_add_var(ctx, expr, v, l))) {
             val = &buf;
@@ -1496,6 +1508,16 @@ grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len)
           GRN_BULK_REWIND(&request_id);
           p = grn_text_unesc_tok(ctx, &request_id, p, e, &tok_type);
           if (ctx->rc) { goto exit; }
+        } else if (l == PRETTY_LEN &&
+                   !memcmp(v, PRETTY, PRETTY_LEN)) {
+          GRN_BULK_REWIND(&buf);
+          p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+          if (GRN_TEXT_LEN(&buf) == strlen("yes") &&
+              !memcmp(GRN_TEXT_VALUE(&buf), "yes", GRN_TEXT_LEN(&buf))) {
+            ctx->impl->output.is_pretty = GRN_TRUE;
+          } else {
+            ctx->impl->output.is_pretty = GRN_FALSE;
+          }
         } else if (expr && (val = grn_expr_get_or_add_var(ctx, expr, v, l))) {
           grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
           p = grn_text_unesc_tok(ctx, val, p, e, &tok_type);
@@ -1619,6 +1641,7 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
         if (comment_command_p(str, str_len)) { goto output; };
         ctx->impl->output.type = GRN_CONTENT_JSON;
         ctx->impl->output.mime_type = "application/json";
+        ctx->impl->output.is_pretty = GRN_FALSE;
         grn_timeval_now(ctx, &ctx->impl->tv);
         GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_COMMAND,
                       ">", "%.*s", str_len, str);

  Modified: lib/grn_ctx_impl.h (+1 -0)
===================================================================
--- lib/grn_ctx_impl.h    2015-11-23 15:44:48 +0900 (2f4e7f3)
+++ lib/grn_ctx_impl.h    2015-11-23 16:44:40 +0900 (6670d18)
@@ -166,6 +166,7 @@ struct _grn_ctx_impl {
     } data;
     grn_content_type type;
     const char *mime_type;
+    grn_bool is_pretty;
     grn_obj names;
     grn_obj levels;
 #ifdef GRN_WITH_MESSAGE_PACK

  Modified: lib/output.c (+109 -11)
===================================================================
--- lib/output.c    2015-11-23 15:44:48 +0900 (e398e3e)
+++ lib/output.c    2015-11-23 16:44:40 +0900 (158ea3a)
@@ -32,13 +32,30 @@
 #define INCR_LENGTH (DEPTH ? (GRN_UINT32_VALUE_AT(LEVELS, (DEPTH - 1)) += 2) : 0)
 
 static void
+indent(grn_ctx *ctx, grn_obj *outbuf, int level)
+{
+  int i;
+  for (i = 0; i < level; i++) {
+    GRN_TEXT_PUTS(ctx, outbuf, "  ");
+  }
+}
+
+static void
 put_delimiter(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type)
 {
   uint32_t level = CURR_LEVEL;
   switch (output_type) {
   case GRN_CONTENT_JSON:
     if (level < 2) { return; }
-    GRN_TEXT_PUTC(ctx, outbuf, ((level & 3) == 3) ? ':' : ',');
+    if ((level & 3) == 3) {
+      GRN_TEXT_PUTC(ctx, outbuf, ':');
+    } else {
+      GRN_TEXT_PUTC(ctx, outbuf, ',');
+      if (ctx->impl->output.is_pretty) {
+        GRN_TEXT_PUTC(ctx, outbuf, '\n');
+        indent(ctx, outbuf, DEPTH);
+      }
+    }
     // if (DEPTH == 1 && ((level & 3) != 3)) { GRN_TEXT_PUTC(ctx, outbuf, '\n'); }
     break;
   case GRN_CONTENT_XML:
@@ -70,6 +87,10 @@ grn_output_array_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_typ
   switch (output_type) {
   case GRN_CONTENT_JSON:
     GRN_TEXT_PUTC(ctx, outbuf, '[');
+    if (ctx->impl->output.is_pretty) {
+      GRN_TEXT_PUTC(ctx, outbuf, '\n');
+      indent(ctx, outbuf, DEPTH + 1);
+    }
     break;
   case GRN_CONTENT_XML:
     GRN_TEXT_PUTC(ctx, outbuf, '<');
@@ -107,6 +128,10 @@ grn_output_array_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_ty
 {
   switch (output_type) {
   case GRN_CONTENT_JSON:
+    if (ctx->impl->output.is_pretty) {
+      GRN_TEXT_PUTC(ctx, outbuf, '\n');
+      indent(ctx, outbuf, DEPTH - 1);
+    }
     GRN_TEXT_PUTC(ctx, outbuf, ']');
     break;
   case GRN_CONTENT_TSV:
@@ -1848,39 +1873,112 @@ grn_output_envelope(grn_ctx *ctx,
       GRN_TEXT_PUT(ctx, head, GRN_TEXT_VALUE(jsonp_func), GRN_TEXT_LEN(jsonp_func));
       GRN_TEXT_PUTC(ctx, head, '(');
     }
-    GRN_TEXT_PUTS(ctx, head, "[[");
-    grn_text_itoa(ctx, head, rc);
-    GRN_TEXT_PUTC(ctx, head, ',');
-    grn_text_ftoa(ctx, head, started);
-    GRN_TEXT_PUTC(ctx, head, ',');
-    grn_text_ftoa(ctx, head, elapsed);
+    if (ctx->impl->output.is_pretty) {
+      grn_text_printf(ctx, head,
+                      "[\n"
+                      "[\n"
+                      "  %d,\n"
+                      "  %f,\n"
+                      "  %f",
+                      rc, started, elapsed);
+    } else {
+      grn_text_printf(ctx, head,
+                      "[[%d,%f,%f",
+                      rc, started, elapsed);
+    }
     if (rc != GRN_SUCCESS) {
       GRN_TEXT_PUTC(ctx, head, ',');
+      if (ctx->impl->output.is_pretty) {
+        GRN_TEXT_PUTS(ctx, head,
+                      "\n"
+                      "  ");
+      }
       grn_text_esc(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
       if (ctx->errfunc && ctx->errfile) {
         grn_obj *command;
-        /* TODO: output backtrace */
-        GRN_TEXT_PUTS(ctx, head, ",[[");
+        if (ctx->impl->output.is_pretty) {
+          GRN_TEXT_PUTS(ctx, head,
+                        ",\n"
+                        "  [\n"
+                        "    [\n"
+                        "      ");
+        } else {
+          GRN_TEXT_PUTS(ctx, head, ",[[");
+        }
         grn_text_esc(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
         GRN_TEXT_PUTC(ctx, head, ',');
+        if (ctx->impl->output.is_pretty) {
+          GRN_TEXT_PUTS(ctx, head,
+                        "\n"
+                        "      ");
+        }
         grn_text_esc(ctx, head, ctx->errfile, strlen(ctx->errfile));
         GRN_TEXT_PUTC(ctx, head, ',');
+        if (ctx->impl->output.is_pretty) {
+          GRN_TEXT_PUTS(ctx, head,
+                        "\n"
+                        "      ");
+        }
         grn_text_itoa(ctx, head, ctx->errline);
+        if (ctx->impl->output.is_pretty) {
+          GRN_TEXT_PUTS(ctx, head,
+                        "\n"
+                        "    ");
+        }
         GRN_TEXT_PUTS(ctx, head, "]");
         if (file && (command = GRN_CTX_USER_DATA(ctx)->ptr)) {
-          GRN_TEXT_PUTS(ctx, head, ",[");
+          if (ctx->impl->output.is_pretty) {
+            GRN_TEXT_PUTS(ctx, head,
+                          ",\n"
+                          "    [\n"
+                          "      ");
+          } else {
+            GRN_TEXT_PUTS(ctx, head, ",[");
+          }
           grn_text_esc(ctx, head, file, strlen(file));
           GRN_TEXT_PUTC(ctx, head, ',');
+          if (ctx->impl->output.is_pretty) {
+            GRN_TEXT_PUTS(ctx, head,
+                          "\n"
+                          "      ");
+          }
           grn_text_itoa(ctx, head, line);
           GRN_TEXT_PUTC(ctx, head, ',');
+          if (ctx->impl->output.is_pretty) {
+            GRN_TEXT_PUTS(ctx, head,
+                          "\n"
+                          "      ");
+          }
           grn_text_esc(ctx, head, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command));
+          if (ctx->impl->output.is_pretty) {
+            GRN_TEXT_PUTS(ctx, head,
+                          "\n"
+                          "    ");
+          }
           GRN_TEXT_PUTS(ctx, head, "]");
         }
+        if (ctx->impl->output.is_pretty) {
+          GRN_TEXT_PUTS(ctx, head,
+                        "\n"
+                        "  ");
+        }
         GRN_TEXT_PUTS(ctx, head, "]");
       }
     }
+    if (ctx->impl->output.is_pretty) {
+      GRN_TEXT_PUTC(ctx, head, '\n');
+    }
     GRN_TEXT_PUTC(ctx, head, ']');
-    if (GRN_TEXT_LEN(body)) { GRN_TEXT_PUTC(ctx, head, ','); }
+    if (GRN_TEXT_LEN(body)) {
+      GRN_TEXT_PUTC(ctx, head, ',');
+      if (ctx->impl->output.is_pretty) {
+        GRN_TEXT_PUTC(ctx, head, '\n');
+      }
+    }
+
+    if (ctx->impl->output.is_pretty) {
+      GRN_TEXT_PUTS(ctx, foot, "\n");
+    }
     GRN_TEXT_PUTC(ctx, foot, ']');
     if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) {
       GRN_TEXT_PUTS(ctx, foot, ");");
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index