ovsdb-client: Add JSON output format.
authorBen Pfaff <blp@nicira.com>
Thu, 4 Nov 2010 00:12:59 +0000 (17:12 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 4 Nov 2010 00:12:59 +0000 (17:12 -0700)
Requested-by: DK Moon <dkmoon@nicira.com>
CC: DK Moon <dkmoon@nicira.com>
AUTHORS
ovsdb/ovsdb-client.1.in
ovsdb/ovsdb-client.c

diff --git a/AUTHORS b/AUTHORS
index 6a8166878f392af73b70f75078cbcb167f8e4ce9..0cbd468177bef76160d35d05f1625d103ff8dde3 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -40,6 +40,7 @@ Brandon Heller          brandonh@stanford.edu
 Bryan Fulton            bryan@nicira.com
 Cedric Hobbs            cedric@nicira.com
 Derek Cormier           derek.cormier@lab.ntt.co.jp
+DK Moon                 dkmoon@nicira.com
 Ghanem Bahri            bahri.ghanem@gmail.com
 Henrik Amren            henrik@nicira.com
 Jad Naous               jnaous@gmail.com
index 8bd1c12ee8d5e1039f28c11e4ddfa83b782072e6..22b4e232214177ccc6a27db363f76949ad8888e3 100644 (file)
@@ -123,6 +123,25 @@ Text-based tables with aligned columns.
 HTML tables.
 .IP "\fBcvs\fR"
 Comma-separated values as defined in RFC 4180.
+.IP "\fBjson\fR"
+JSON format as defined in RFC 4627.  The output is a sequence of JSON
+objects, each of which corresponds to one table.  Each JSON object has
+the following members with the noted values:
+.RS
+.IP "\fBcaption\fR"
+The table's caption.  This member is omitted if the table has no
+caption.
+.IP "\fBheadings\fR"
+An array with one element per table column.  Each array element is a
+string giving the corresponding column's heading.
+.IP "\fBdata\fR"
+An array with one element per table row.  Each element is also an
+array with one element per table column.  The elements of this
+second-level array are the cells that constitute the table.  Cells
+that represent OVSDB data or data types are expressed in the format
+described in the OVSDB specification; other cells are simply expressed
+as text strings.
+.RE
 .RE
 .
 .IP "\fB\-d \fIformat\fR"
@@ -135,6 +154,9 @@ The simple format described in \fBovs\-vsctl\fR(8).
 .IP "\fBjson\fR"
 JSON.
 .RE
+.IP
+The \fBjson\fR output format always outputs cells in JSON format,
+ignoring this option.
 .
 .IP "\fB\-\-no\-heading\fR"
 This option suppresses the heading row that otherwise appears in the
index 8502f19bec14464ffc9c6996a404036bfdae5fe3..6d19e5df2a49a42e872fe89e87d0c255e6f97517 100644 (file)
@@ -49,7 +49,8 @@ VLOG_DEFINE_THIS_MODULE(ovsdb_client);
 static enum {
     FMT_TABLE,                  /* Textual table. */
     FMT_HTML,                   /* HTML table. */
-    FMT_CSV                     /* Comma-separated lines. */
+    FMT_CSV,                    /* Comma-separated lines. */
+    FMT_JSON                    /* JSON. */
 } output_format;
 
 /* --no-headings: Whether table output should include headings. */
@@ -119,6 +120,8 @@ parse_options(int argc, char *argv[])
                 output_format = FMT_HTML;
             } else if (!strcmp(optarg, "csv")) {
                 output_format = FMT_CSV;
+            } else if (!strcmp(optarg, "json")) {
+                output_format = FMT_JSON;
             } else {
                 ovs_fatal(0, "unknown output format \"%s\"", optarg);
             }
@@ -196,7 +199,8 @@ usage(void)
     stream_usage("SERVER", true, true, true);
     printf("\nOutput formatting options:\n"
            "  -f, --format=FORMAT         set output formatting to FORMAT\n"
-           "                              (\"table\", \"html\", or \"csv\"\n"
+           "                              (\"table\", \"html\", \"csv\", "
+           "or \"json\")\n"
            "  --no-headings               omit table heading row\n"
            "  --pretty                    pretty-print JSON in output");
     daemon_usage();
@@ -676,6 +680,46 @@ table_print_csv__(const struct table *table)
     }
 }
 
+static void
+table_print_json__(const struct table *table)
+{
+    struct json *json, *headings, *data;
+    size_t x, y;
+    char *s;
+
+    json = json_object_create();
+    if (table->caption) {
+        json_object_put_string(json, "caption", table->caption);
+    }
+
+    headings = json_array_create_empty();
+    for (x = 0; x < table->n_columns; x++) {
+        const struct column *column = &table->columns[x];
+        json_array_add(headings, json_string_create(column->heading));
+    }
+    json_object_put(json, "headings", headings);
+
+    data = json_array_create_empty();
+    for (y = 0; y < table->n_rows; y++) {
+        struct json *row = json_array_create_empty();
+        for (x = 0; x < table->n_columns; x++) {
+            const struct cell *cell = table_cell__(table, y, x);
+            if (cell->text) {
+                json_array_add(row, json_string_create(cell->text));
+            } else {
+                json_array_add(row, json_clone(cell->json));
+            }
+        }
+        json_array_add(data, row);
+    }
+    json_object_put(json, "data", data);
+
+    s = json_to_string(json, json_flags);
+    json_destroy(json);
+    puts(s);
+    free(s);
+}
+
 static void
 table_print(const struct table *table)
 {
@@ -691,6 +735,10 @@ table_print(const struct table *table)
     case FMT_CSV:
         table_print_csv__(table);
         break;
+
+    case FMT_JSON:
+        table_print_json__(table);
+        break;
     }
 }
 \f