From: Sebastian Harl Date: Sun, 2 Nov 2014 17:02:25 +0000 (+0100) Subject: store: Let the JSON formatter know about arrays at top level. X-Git-Tag: sysdb-0.6.0~41 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=fa16153fd58a0a5c36037c81119072f1a0623e48 store: Let the JSON formatter know about arrays at top level. There's no reason to require this to be handled separately. --- diff --git a/src/core/store_json.c b/src/core/store_json.c index d9fc37c..b4b7b6a 100644 --- a/src/core/store_json.c +++ b/src/core/store_json.c @@ -52,6 +52,8 @@ struct sdb_store_json_formatter { * the path pointing to the current object */ int context[8]; size_t current; + + int flags; }; /* @@ -105,7 +107,7 @@ json_emit(sdb_store_json_formatter_t *f, sdb_store_obj_t *obj) */ sdb_store_json_formatter_t * -sdb_store_json_formatter(sdb_strbuf_t *buf) +sdb_store_json_formatter(sdb_strbuf_t *buf, int flags) { sdb_store_json_formatter_t *f; @@ -119,6 +121,7 @@ sdb_store_json_formatter(sdb_strbuf_t *buf) f->buf = buf; f->context[0] = 0; f->current = 0; + f->flags = flags; return f; } /* sdb_store_json_formatter */ @@ -130,6 +133,8 @@ sdb_store_json_emit(sdb_store_json_formatter_t *f, sdb_store_obj_t *obj) /* first host */ if (! f->context[0]) { + if (f->flags & SDB_WANT_ARRAY) + sdb_strbuf_append(f->buf, "["); assert(f->current == 0); f->context[0] = SDB_HOST; return json_emit(f, obj); @@ -228,12 +233,21 @@ sdb_store_json_finish(sdb_store_json_formatter_t *f) if (! f) return -1; + if (! f->context[0]) { + /* no content */ + if (f->flags & SDB_WANT_ARRAY) + sdb_strbuf_append(f->buf, "[]"); + return 0; + } + while (f->current > 0) { sdb_strbuf_append(f->buf, "}]"); --f->current; } - if (f->context[0]) - sdb_strbuf_append(f->buf, "}"); + + sdb_strbuf_append(f->buf, "}"); + if (f->flags & SDB_WANT_ARRAY) + sdb_strbuf_append(f->buf, "]"); return 0; } /* sdb_store_json_finish */ diff --git a/src/frontend/query.c b/src/frontend/query.c index dddf842..1ef36b3 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -390,7 +390,7 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, int type, sdb_strbuf_sprintf(conn->errbuf, "Out of memory"); return -1; } - f = sdb_store_json_formatter(buf); + f = sdb_store_json_formatter(buf, SDB_WANT_ARRAY); if (! f) { char errbuf[1024]; sdb_log(SDB_LOG_ERR, "frontend: Failed to create " @@ -403,7 +403,6 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, int type, } sdb_strbuf_memcpy(buf, &res_type, sizeof(uint32_t)); - sdb_strbuf_append(buf, "["); if (sdb_store_scan(SDB_HOST, m, filter, lookup_tojson, f)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to lookup hosts"); @@ -414,8 +413,6 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, int type, } sdb_store_json_finish(f); - sdb_strbuf_append(buf, "]"); - sdb_connection_send(conn, CONNECTION_DATA, (uint32_t)sdb_strbuf_len(buf), sdb_strbuf_string(buf)); sdb_strbuf_destroy(buf); diff --git a/src/include/core/store.h b/src/include/core/store.h index 6dd7d1a..df959ea 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -89,7 +89,7 @@ typedef struct sdb_store_matcher sdb_store_matcher_t; #define SDB_STORE_MATCHER(obj) ((sdb_store_matcher_t *)(obj)) /* - * A JSON formatter converts a stored object into the JSON format. + * A JSON formatter converts stored objects into the JSON format. * See http://www.ietf.org/rfc/rfc4627.txt */ struct sdb_store_json_formatter; @@ -577,6 +577,8 @@ sdb_store_scan(int type, sdb_store_matcher_t *m, sdb_store_matcher_t *filter, * out. The SKIP_EMPTY flags may be used to skip host objects entirely. */ enum { + SDB_WANT_ARRAY = 1 << 0, + SDB_SKIP_ATTRIBUTES = 1 << 0, SDB_SKIP_SERVICES = 1 << 1, SDB_SKIP_METRICS = 1 << 2, @@ -624,7 +626,7 @@ sdb_store_host_tojson(sdb_store_obj_t *host, sdb_strbuf_t *buf, * Create a JSON formatter writing to the specified buffer. */ sdb_store_json_formatter_t * -sdb_store_json_formatter(sdb_strbuf_t *buf); +sdb_store_json_formatter(sdb_strbuf_t *buf, int flags); /* * sdb_store_json_emit: diff --git a/t/unit/core/store_json_test.c b/t/unit/core/store_json_test.c index ee0db2f..c544633 100644 --- a/t/unit/core/store_json_test.c +++ b/t/unit/core/store_json_test.c @@ -236,6 +236,9 @@ START_TEST(test_store_tojson) "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]" }, + { { sdb_store_lt_matcher, SDB_FIELD_LAST_UPDATE, + { SDB_TYPE_DATETIME, { .datetime = 0 } } }, scan_tojson_full, + "[]" }, }; buf = sdb_strbuf_create(0); @@ -269,17 +272,15 @@ START_TEST(test_store_tojson) } sdb_strbuf_clear(buf); - f = sdb_store_json_formatter(buf); + f = sdb_store_json_formatter(buf, SDB_WANT_ARRAY); assert(f); - sdb_strbuf_append(buf, "["); status = sdb_store_scan(SDB_HOST, /* m = */ NULL, filter, golden_data[i].f, f); fail_unless(status == 0, "sdb_store_scan(HOST, ..., tojson) = %d; expected: 0", status); sdb_store_json_finish(f); - sdb_strbuf_append(buf, "]"); verify_json_output(buf, golden_data[i].expected); free(f);