Code

store_expr: Added support to include field values in an expression.
authorSebastian Harl <sh@tokkee.org>
Thu, 31 Jul 2014 21:09:29 +0000 (23:09 +0200)
committerSebastian Harl <sh@tokkee.org>
Thu, 31 Jul 2014 21:09:29 +0000 (23:09 +0200)
Added sdb_store_expr_fieldvalue() to create such an expression object and pass
a stored object to sdb_store_expr_eval() to be able to extract the field value
when evaluation the expression.

src/core/store_expr.c
src/core/store_lookup.c
src/include/core/store.h

index 4d1fccb47399b540777d1729977fb8473be37316..7d674bc2f6b8e77bd87432b81532b34313da17ad 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "sysdb.h"
 #include "core/store-private.h"
+#include "core/data.h"
 #include "core/object.h"
 
 #include <assert.h>
 struct sdb_store_expr {
        sdb_object_t super;
 
+       /*
+        * type:
+        * -1: field value (field type store in data.data.integer)
+        *  0: const value (stored in data)
+        * >0: operator id
+        */
        int type;
+
        sdb_store_expr_t *left;
        sdb_store_expr_t *right;
 
@@ -67,7 +75,7 @@ expr_init(sdb_object_t *obj, va_list ap)
 
        sdb_store_expr_t *expr = SDB_STORE_EXPR(obj);
 
-       if (! type) {
+       if (type <= 0) {
                if (! value)
                        return -1;
        } else {
@@ -114,10 +122,22 @@ static sdb_type_t expr_type = {
 sdb_store_expr_t *
 sdb_store_expr_create(int op, sdb_store_expr_t *left, sdb_store_expr_t *right)
 {
+       if ((op < 0) || (SDB_DATA_CONCAT < op))
+               return NULL;
        return SDB_STORE_EXPR(sdb_object_create("store-expr", expr_type,
                                op, left, right, NULL));
 } /* sdb_store_expr_create */
 
+sdb_store_expr_t *
+sdb_store_expr_fieldvalue(int field)
+{
+       sdb_data_t value = { SDB_TYPE_INTEGER, { .integer = field } };
+       if ((field < 0) || (SDB_FIELD_BACKEND < field))
+               return NULL;
+       return SDB_STORE_EXPR(sdb_object_create("store-fieldvalue", expr_type,
+                               -1, NULL, NULL, &value));
+} /* sdb_store_expr_fieldvalue */
+
 sdb_store_expr_t *
 sdb_store_expr_constvalue(const sdb_data_t *value)
 {
@@ -126,7 +146,8 @@ sdb_store_expr_constvalue(const sdb_data_t *value)
 } /* sdb_store_expr_constvalue */
 
 int
-sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_data_t *res)
+sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
+               sdb_data_t *res)
 {
        sdb_data_t v1 = SDB_DATA_INIT, v2 = SDB_DATA_INIT;
 
@@ -135,10 +156,12 @@ sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_data_t *res)
 
        if (! expr->type)
                return sdb_data_copy(res, &expr->data);
+       else if (expr->type < 0)
+               return sdb_store_get_field(obj, (int)expr->data.data.integer, res);
 
-       if (sdb_store_expr_eval(expr->left, &v1))
+       if (sdb_store_expr_eval(expr->left, obj, &v1))
                return -1;
-       if (sdb_store_expr_eval(expr->right, &v2)) {
+       if (sdb_store_expr_eval(expr->right, obj, &v2)) {
                sdb_data_free_datum(&v1);
                return -1;
        }
index 1ec1dbb68e702f6c5e4a9722e885f1042494cf38..0ef5f462a4ea4e759b99a5807de4507d45d4046e 100644 (file)
@@ -114,7 +114,7 @@ attr_cmp(sdb_store_obj_t *obj, sdb_store_cond_t *cond,
        if (obj->type != SDB_HOST)
                return INT_MAX;
 
-       if (sdb_store_expr_eval(ATTR_C(cond)->expr, &value))
+       if (sdb_store_expr_eval(ATTR_C(cond)->expr, obj, &value))
                return INT_MAX;
 
        attr = attr_get(HOST(obj), ATTR_C(cond)->name, filter);
@@ -138,7 +138,7 @@ obj_cmp(sdb_store_obj_t *obj, sdb_store_cond_t *cond,
 
        if (sdb_store_get_field(obj, OBJ_C(cond)->field, &obj_value))
                return INT_MAX;
-       if (sdb_store_expr_eval(OBJ_C(cond)->expr, &value))
+       if (sdb_store_expr_eval(OBJ_C(cond)->expr, obj, &value))
                return INT_MAX;
 
        if (obj_value.type != value.type) {
@@ -577,7 +577,7 @@ cond_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
                return buf;
        }
 
-       if (sdb_store_expr_eval(expr, &value))
+       if (sdb_store_expr_eval(expr, NULL, &value))
                snprintf(value_str, sizeof(value_str), "ERR");
        else if (sdb_data_format(&value, value_str, sizeof(value_str),
                                SDB_SINGLE_QUOTED) < 0)
@@ -966,7 +966,7 @@ sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr,
        if (! expr)
                return NULL;
 
-       if (sdb_store_expr_eval(expr, &value))
+       if (sdb_store_expr_eval(expr, NULL, &value))
                return NULL;
        if (value.type != SDB_TYPE_STRING) {
                sdb_data_free_datum(&value);
index 533f4080ec17f049051f19a04b97111d226cfc33..760c23d9fa89f7151b0e33267ebcaff0e37936c1 100644 (file)
@@ -210,6 +210,18 @@ typedef struct sdb_store_expr sdb_store_expr_t;
 sdb_store_expr_t *
 sdb_store_expr_create(int op, sdb_store_expr_t *left, sdb_store_expr_t *right);
 
+/*
+ * sdb_store_expr_fieldvalue:
+ * Creates an expression which evaluates to the value of the specified
+ * queryable field of a stored object.
+ *
+ * Returns:
+ *  - an expression object on success
+ *  - NULL else
+ */
+sdb_store_expr_t *
+sdb_store_expr_fieldvalue(int field);
+
 /*
  * sdb_store_expr_constvalue:
  * Creates an expression which evaluates to the specified constant value.
@@ -223,16 +235,19 @@ sdb_store_expr_constvalue(const sdb_data_t *value);
 
 /*
  * sdb_store_expr_eval:
- * Evaluate an expression and stores the result in 'res'. The result's value
- * will be allocated dynamically if necessary and, thus, should be free'd by
- * the caller (e.g. using sdb_data_free_datum);
+ * Evaluate an expression for the specified stored object and stores the
+ * result in 'res'. The result's value will be allocated dynamically if
+ * necessary and, thus, should be free'd by the caller (e.g. using
+ * sdb_data_free_datum). The object may be NULL, in which case the expression
+ * needs to evaluate to a constant value.
  *
  * Returns:
  *  - 0 on success
  *  - a negative value else
  */
 int
-sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_data_t *res);
+sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
+               sdb_data_t *res);
 
 /*
  * Conditionals may be used to lookup hosts from the store based on a