Code

store: Added sdb_store_expr_typed.
authorSebastian Harl <sh@tokkee.org>
Mon, 1 Dec 2014 16:34:59 +0000 (17:34 +0100)
committerSebastian Harl <sh@tokkee.org>
Mon, 1 Dec 2014 16:34:59 +0000 (17:34 +0100)
This function creates an expression which evaluates another expression in the
context of an object's sibling. The sibling is specified by type and refers to
a parent or child node of the specified type.

src/core/store-private.h
src/core/store_expr.c
src/include/core/store.h

index d2ea3f9a08c9f443584a4d021df97e02d1638111..3ae6c437d20f6b63a4376e610ac086bc576fd5f5 100644 (file)
@@ -108,6 +108,7 @@ typedef struct {
  */
 
 enum {
+       TYPED_EXPR  = -3, /* obj type stored in data.data.integer */
        ATTR_VALUE  = -2, /* attr name stored in data.data.string */
        FIELD_VALUE = -1, /* field type stored in data.data.integer */
        /*  0: const value (stored in data) */
index d5b22c7e89b8c645c1da9f130e1435d90d023122..a0047a1f12e1fa8498ef0ed5255373478f98a070 100644 (file)
@@ -59,6 +59,8 @@ expr_init(sdb_object_t *obj, va_list ap)
        if (type <= 0) {
                if (! value)
                        return -1;
+               if ((type == TYPED_EXPR) && (! left))
+                       return -1;
        } else {
                if (value)
                        return -1;
@@ -127,13 +129,28 @@ sdb_store_expr_create(int op, sdb_store_expr_t *left, sdb_store_expr_t *right)
        return e;
 } /* sdb_store_expr_create */
 
+sdb_store_expr_t *
+sdb_store_expr_typed(int typ, sdb_store_expr_t *expr)
+{
+       sdb_data_t value = { SDB_TYPE_INTEGER, { .integer = typ } };
+       sdb_store_expr_t *e;
+
+       if ((typ < SDB_HOST) || (SDB_ATTRIBUTE < typ))
+               return NULL;
+
+       e = SDB_STORE_EXPR(sdb_object_create("store-typedexpr", expr_type,
+                               TYPED_EXPR, expr, NULL, &value));
+       e->data_type = expr->data_type;
+       return e;
+} /* sdb_store_expr_typed */
+
 sdb_store_expr_t *
 sdb_store_expr_fieldvalue(int field)
 {
        sdb_data_t value = { SDB_TYPE_INTEGER, { .integer = field } };
        sdb_store_expr_t *e;
 
-       if ((field < 0) || (SDB_FIELD_BACKEND < field))
+       if ((field < SDB_FIELD_NAME) || (SDB_FIELD_BACKEND < field))
                return NULL;
        e = SDB_STORE_EXPR(sdb_object_create("store-fieldvalue", expr_type,
                                FIELD_VALUE, NULL, NULL, &value));
@@ -200,6 +217,18 @@ sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
                }
                return status;
        }
+       else if (expr->type == TYPED_EXPR) {
+               int typ = (int)expr->data.data.integer;
+               if (typ != obj->type) {
+                       /* we support self-references and { service, metric } -> host */
+                       if ((typ != SDB_HOST)
+                                       || ((obj->type != SDB_SERVICE)
+                                               && (obj->type != SDB_METRIC)))
+                               return -1;
+                       obj = obj->parent;
+               }
+               return sdb_store_expr_eval(expr->left, obj, res, filter);
+       }
 
        if (sdb_store_expr_eval(expr->left, obj, &v1, filter))
                return -1;
index d3862b4e5c05d51bf3b6d50d75129238104d0c5e..5507436742a79bc6d8cde34496c70dd87c61d4cf 100644 (file)
@@ -332,6 +332,18 @@ sdb_store_get_attr(sdb_store_obj_t *obj, const char *name, sdb_data_t *res,
 sdb_store_expr_t *
 sdb_store_expr_create(int op, sdb_store_expr_t *left, sdb_store_expr_t *right);
 
+/*
+ * sdb_store_expr_typed:
+ * Creates an expression which evaluates in the context of an object's sibling
+ * as specified by the given type.
+ *
+ * Returns:
+ *  - an expression object on success
+ *  - NULL else
+ */
+sdb_store_expr_t *
+sdb_store_expr_typed(int typ, sdb_store_expr_t *expr);
+
 /*
  * sdb_store_expr_fieldvalue:
  * Creates an expression which evaluates to the value of the specified