Code

store: Added flags to JSON functions indicating information to leave out.
authorSebastian Harl <sh@tokkee.org>
Fri, 3 Jan 2014 13:20:30 +0000 (14:20 +0100)
committerSebastian Harl <sh@tokkee.org>
Fri, 3 Jan 2014 13:20:30 +0000 (14:20 +0100)
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.

src/core/store.c
src/frontend/query.c
src/include/core/store.h
t/core/store_test.c

index 50b39d52f1160791cee05ecb5b3a44867380eece..5a36e29eef5817e2988d445accd19b352fbe6f61 100644 (file)
@@ -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), "<error>");
+               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), "<error>");
-               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), "<error>");
-               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))
index 65ff290cb26f1cd123f444649dc1ad4b18d66423..675a002eaea897ece7dc4301c5fcd00f2660081a 100644 (file)
@@ -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");
index 99b2ead200cce151cc6775882903b6235fe042fc..cf4ecbbb6f1155444a451bf57535bf536704098e 100644 (file)
@@ -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" */
index c27310d4e6720dd5819483e00af7668f3e498287..9a5b7e563200dfeae84872d29278bf7065ad2376 100644 (file)
@@ -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);