From: Sebastian Harl Date: Fri, 3 Jan 2014 13:20:30 +0000 (+0100) Subject: store: Added flags to JSON functions indicating information to leave out. X-Git-Tag: sysdb-0.1.0~255 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=40b40eda60b517297089a209f3681c8ec064cd68 store: Added flags to JSON functions indicating information to leave out. This may be used to leave out services or attributes from the serialized object. For this purpose, the serialization function has been simplified to handle attributes and services mostly alike. --- diff --git a/src/core/store.c b/src/core/store.c index 50b39d5..5a36e29 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -376,7 +376,57 @@ store_obj(int parent_type, const char *parent_name, free(parent_cname); free(cname); return status; -} /* sdb_store_obj */ +} /* store_obj */ + +/* + * store_obj_tojson serializes attribute / service objects to JSON. + * + * The function never returns an error. Rather, an error message will be part + * of the serialized data. + */ +static void +store_obj_tojson(sdb_llist_t *list, int type, sdb_strbuf_t *buf) +{ + sdb_llist_iter_t *iter; + char time_str[64]; + + assert((type == SDB_ATTRIBUTE) || (type == SDB_SERVICE)); + + sdb_strbuf_append(buf, "["); + + iter = sdb_llist_get_iter(list); + if (! iter) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "store: Failed to retrieve %ss: %s\n", + TYPE_TO_NAME(type), + sdb_strerror(errno, errbuf, sizeof(errbuf))); + sdb_strbuf_append(buf, "{\"error\": \"failed to retrieve %ss: %s\"}", + TYPE_TO_NAME(type), errbuf); + } + + /* has_next returns false if the iterator is NULL */ + while (sdb_llist_iter_has_next(iter)) { + sdb_store_base_t *sobj = STORE_BASE(sdb_llist_iter_get_next(iter)); + assert(sobj); + + if (! sdb_strftime(time_str, sizeof(time_str), + "%F %T %z", sobj->last_update)) + snprintf(time_str, sizeof(time_str), ""); + time_str[sizeof(time_str) - 1] = '\0'; + + sdb_strbuf_append(buf, "{\"name\": \"%s\", ", SDB_OBJ(sobj)->name); + if (type == SDB_ATTRIBUTE) + sdb_strbuf_append(buf, "\"value\": \"%s\", ", + SDB_ATTR(sobj)->value); + sdb_strbuf_append(buf, "\"last_update\": \"%s\"}", time_str); + + if (sdb_llist_iter_has_next(iter)) + sdb_strbuf_append(buf, ","); + } + + sdb_llist_iter_destroy(iter); + sdb_strbuf_append(buf, "]"); +} /* store_obj_tojson */ /* * public API @@ -457,13 +507,9 @@ sdb_store_service(const char *hostname, const char *name, } /* sdb_store_service */ int -sdb_store_host_tojson(sdb_store_base_t *h, sdb_strbuf_t *buf) +sdb_store_host_tojson(sdb_store_base_t *h, sdb_strbuf_t *buf, int flags) { sdb_store_obj_t *host; - - sdb_llist_iter_t *svc_iter; - sdb_llist_iter_t *attr_iter; - char time_str[64]; if ((! h) || (h->type != SDB_HOST) || (! buf)) @@ -477,68 +523,26 @@ sdb_store_host_tojson(sdb_store_base_t *h, sdb_strbuf_t *buf) time_str[sizeof(time_str) - 1] = '\0'; sdb_strbuf_append(buf, "{\"name\": \"%s\", " - "\"last_update\": \"%s\", " - "\"attributes\": [", + "\"last_update\": \"%s\"", SDB_OBJ(host)->name, time_str); - attr_iter = sdb_llist_get_iter(host->attributes); - if (! attr_iter) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "store: Failed to retrieve attributes: %s\n", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - sdb_strbuf_append(buf, "{\"error\": \"failed to retrieve " - "attributes: %s\"}", errbuf); - } - - /* has_next returns false if the iterator is NULL */ - while (sdb_llist_iter_has_next(attr_iter)) { - sdb_attribute_t *attr = SDB_ATTR(sdb_llist_iter_get_next(attr_iter)); - assert(attr); - - if (! sdb_strftime(time_str, sizeof(time_str), - "%F %T %z", attr->_last_update)) - snprintf(time_str, sizeof(time_str), ""); - time_str[sizeof(time_str) - 1] = '\0'; - - sdb_strbuf_append(buf, "{\"name\": \"%s\", " - "\"value\": \"%s\", \"last_update\": \"%s\"},", - SDB_OBJ(attr)->name, attr->value, time_str); + if (! (flags & SDB_SKIP_ATTRIBUTES)) { + sdb_strbuf_append(buf, ", \"attributes\": "); + store_obj_tojson(host->attributes, SDB_ATTRIBUTE, buf); } - sdb_llist_iter_destroy(attr_iter); - sdb_strbuf_append(buf, "], \"services\": ["); - - svc_iter = sdb_llist_get_iter(host->children); - if (! svc_iter) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "store: Failed to retrieve services: %s\n", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - sdb_strbuf_append(buf, "{\"error\": \"failed to retrieve " - "services: %s\"}", errbuf); + if (! (flags & SDB_SKIP_SERVICES)) { + sdb_strbuf_append(buf, ", \"services\": "); + store_obj_tojson(host->children, SDB_SERVICE, buf); } - while (sdb_llist_iter_has_next(svc_iter)) { - sdb_store_obj_t *svc = SDB_STORE_OBJ(sdb_llist_iter_get_next(svc_iter)); - assert(svc); - - if (! sdb_strftime(time_str, sizeof(time_str), - "%F %T %z", svc->_last_update)) - snprintf(time_str, sizeof(time_str), ""); - time_str[sizeof(time_str) - 1] = '\0'; - - sdb_strbuf_append(buf, "{\"name\": \"%s\", " - "\"last_update\": \"%s\"},", - SDB_OBJ(svc)->name, time_str); - } - - sdb_llist_iter_destroy(svc_iter); - sdb_strbuf_append(buf, "]}"); + sdb_strbuf_append(buf, "}"); return 0; } /* sdb_store_host_tojson */ /* TODO: actually support hierarchical data */ int -sdb_store_tojson(sdb_strbuf_t *buf) +sdb_store_tojson(sdb_strbuf_t *buf, int flags) { sdb_llist_iter_t *host_iter; @@ -559,7 +563,7 @@ sdb_store_tojson(sdb_strbuf_t *buf) sdb_store_base_t *host = STORE_BASE(sdb_llist_iter_get_next(host_iter)); assert(host); - if (sdb_store_host_tojson(host, buf)) + if (sdb_store_host_tojson(host, buf, flags)) return -1; if (sdb_llist_iter_has_next(host_iter)) diff --git a/src/frontend/query.c b/src/frontend/query.c index 65ff290..675a002 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -55,7 +55,7 @@ sdb_fe_list(sdb_conn_t *conn) return -1; } - if (sdb_store_tojson(buf)) { + if (sdb_store_tojson(buf, /* flags = */ 0)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to serialize " "store to JSON"); sdb_strbuf_sprintf(conn->errbuf, "Out of memory"); diff --git a/src/include/core/store.h b/src/include/core/store.h index 99b2ead..cf4ecbb 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -107,6 +107,18 @@ int sdb_store_service(const char *hostname, const char *name, sdb_time_t last_update); +/* + * Flags for serialization functions. + * + * By default, the full object will be included in the serialized output. When + * specifying any of the flags, the respective information will be left out. + */ +enum { + SDB_SKIP_ATTRIBUTES = 1 << 0, + SDB_SKIP_SERVICES = 1 << 1, + SDB_SKIP_SERVICE_ATTRIBUTES = 1 << 2, +}; + /* * sdb_store_tojson: * Serialize the entire store to JSON and append the result to the specified @@ -117,7 +129,7 @@ sdb_store_service(const char *hostname, const char *name, * - a negative value on error */ int -sdb_store_tojson(sdb_strbuf_t *buf); +sdb_store_tojson(sdb_strbuf_t *buf, int flags); /* * sdb_store_host_tojson: @@ -129,7 +141,7 @@ sdb_store_tojson(sdb_strbuf_t *buf); * - a negative value on error */ int -sdb_store_host_tojson(sdb_store_base_t *host, sdb_strbuf_t *buf); +sdb_store_host_tojson(sdb_store_base_t *host, sdb_strbuf_t *buf, int flags); #ifdef __cplusplus } /* extern "C" */ diff --git a/t/core/store_test.c b/t/core/store_test.c index c27310d..9a5b7e5 100644 --- a/t/core/store_test.c +++ b/t/core/store_test.c @@ -166,14 +166,14 @@ START_TEST(test_store_tojson) "\"attributes\": [" "{\"name\": \"k1\", \"value\": \"v1\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}," "{\"name\": \"k2\", \"value\": \"v2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}," - "{\"name\": \"k3\", \"value\": \"v3\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}," + "{\"name\": \"k3\", \"value\": \"v3\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}" "], " "\"services\": []}," "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " "\"attributes\": [], " "\"services\": [" "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}," - "{\"name\": \"s2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}," + "{\"name\": \"s2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}" "]}" "]}"; @@ -188,7 +188,7 @@ START_TEST(test_store_tojson) sdb_store_service("h2", "s2", 1); buf = sdb_strbuf_create(0); - status = sdb_store_tojson(buf); + status = sdb_store_tojson(buf, /* flags = */ 0); fail_unless(status == 0, "sdb_store_tojson() = %d; expected: 0", status);