diff --git a/src/core/store.c b/src/core/store.c
index e14f27c0e4141482c4edea27f59eca97bc4abdcb..d9ca4c0eb113a7a2824249d92d83fa45f4d4e56c 100644 (file)
--- a/src/core/store.c
+++ b/src/core/store.c
int
sdb_store_get_field(sdb_store_obj_t *obj, int field, sdb_data_t *res)
{
- if ((! obj) || (! res))
+ sdb_data_t tmp;
+
+ if (! obj)
return -1;
switch (field) {
+ case SDB_FIELD_NAME:
+ tmp.type = SDB_TYPE_STRING;
+ tmp.data.string = strdup(SDB_OBJ(obj)->name);
+ if (! tmp.data.string)
+ return -1;
+ break;
case SDB_FIELD_LAST_UPDATE:
- res->type = SDB_TYPE_DATETIME;
- res->data.datetime = obj->last_update;
+ tmp.type = SDB_TYPE_DATETIME;
+ tmp.data.datetime = obj->last_update;
break;
case SDB_FIELD_AGE:
- res->type = SDB_TYPE_DATETIME;
- res->data.datetime = sdb_gettime() - obj->last_update;
+ tmp.type = SDB_TYPE_DATETIME;
+ tmp.data.datetime = sdb_gettime() - obj->last_update;
break;
case SDB_FIELD_INTERVAL:
- res->type = SDB_TYPE_DATETIME;
- res->data.datetime = obj->interval;
+ tmp.type = SDB_TYPE_DATETIME;
+ tmp.data.datetime = obj->interval;
break;
case SDB_FIELD_BACKEND:
- /* TODO: add support for storing array values in a data object
- * for now, fall thru to the error case */
+ {
+ tmp.type = SDB_TYPE_ARRAY | SDB_TYPE_STRING;
+ tmp.data.array.length = obj->backends_num;
+ tmp.data.array.values = obj->backends;
+ return sdb_data_copy(res, &tmp);
+ break;
+ }
default:
return -1;
}
+ if (res)
+ *res = tmp;
+ else
+ sdb_data_free_datum(&tmp);
return 0;
} /* sdb_store_get_field */
+int
+sdb_store_get_attr(sdb_store_obj_t *obj, const char *name, sdb_data_t *res,
+ sdb_store_matcher_t *filter)
+{
+ sdb_avltree_t *tree = NULL;
+ sdb_avltree_iter_t *iter = NULL;
+
+ if ((! obj) || (! name))
+ return -1;
+
+ if (obj->type == SDB_HOST)
+ tree = HOST(obj)->attributes;
+ else if (obj->type == SDB_SERVICE)
+ tree = SVC(obj)->attributes;
+ else if (obj->type == SDB_METRIC)
+ tree = METRIC(obj)->attributes;
+
+ if (! tree)
+ return -1;
+
+ iter = sdb_avltree_get_iter(tree);
+ while (sdb_avltree_iter_has_next(iter)) {
+ sdb_object_t *attr = sdb_avltree_iter_get_next(iter);
+
+ if (strcasecmp(SDB_OBJ(attr)->name, name))
+ continue;
+
+ if (filter&& (! sdb_store_matcher_matches(filter,
+ STORE_OBJ(attr), NULL)))
+ break; /* found it but it's filtered */
+
+ assert(STORE_OBJ(attr)->type == SDB_ATTRIBUTE);
+ if (res)
+ sdb_data_copy(res, &ATTR(attr)->value);
+ sdb_avltree_iter_destroy(iter);
+ return 0;
+ }
+ sdb_avltree_iter_destroy(iter);
+
+ /* not found */
+ return -1;
+} /* sdb_store_get_attr */
+
int
sdb_store_host_tojson(sdb_store_obj_t *h, sdb_strbuf_t *buf,
sdb_store_matcher_t *filter, int flags)
if ((! h) || (h->type != SDB_HOST) || (! buf))
return -1;
+ /* This function ignores SKIP_EMPTY flags given that the current
+ * implementation sucks and it's nut currently used when calling this
+ * function directly. */
+
sdb_strbuf_append(buf, "{\"name\": \"%s\", ", SDB_OBJ(host)->name);
store_common_tojson(h, buf);
return 0;
} /* sdb_store_host_tojson */
+static _Bool
+has_children(sdb_avltree_t *tree, sdb_store_matcher_t *filter)
+{
+ sdb_avltree_iter_t *iter;
+
+ if (! filter)
+ return sdb_avltree_size(tree) > 0;
+
+ iter = sdb_avltree_get_iter(tree);
+ while (sdb_avltree_iter_has_next(iter)) {
+ sdb_store_obj_t *sobj = STORE_OBJ(sdb_avltree_iter_get_next(iter));
+ if (sdb_store_matcher_matches(filter, sobj, NULL)) {
+ sdb_avltree_iter_destroy(iter);
+ return 1;
+ }
+ }
+ sdb_avltree_iter_destroy(iter);
+ return 0;
+} /* has_children */
+
int
sdb_store_tojson(sdb_strbuf_t *buf, sdb_store_matcher_t *filter, int flags)
{
if (filter && (! sdb_store_matcher_matches(filter, host, NULL)))
continue;
+ /*
+ * XXX: This approach sucks but it's the best we can do at the moment.
+ * In the future, all store lookups should be split into multiple
+ * steps instead: first, retrieve all relevant objects and apply all
+ * pre-processing operations and then format it for the wire.
+ */
+ if ((flags & SDB_SKIP_EMPTY_SERVICES)
+ && (! has_children(HOST(host)->services, filter)))
+ continue;
+ if ((flags & SDB_SKIP_EMPTY_METRICS)
+ && (! has_children(HOST(host)->metrics, filter)))
+ continue;
+
if (sdb_strbuf_len(buf) > len)
sdb_strbuf_append(buf, ",");
len = sdb_strbuf_len(buf);