From 45e97a5c2c641995c7a6fd036ca11a6341f227c8 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Thu, 31 Jul 2014 23:09:29 +0200 Subject: [PATCH] store_expr: Added support to include field values in an expression. 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 | 31 +++++++++++++++++++++++++++---- src/core/store_lookup.c | 8 ++++---- src/include/core/store.h | 23 +++++++++++++++++++---- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/core/store_expr.c b/src/core/store_expr.c index 4d1fccb..7d674bc 100644 --- a/src/core/store_expr.c +++ b/src/core/store_expr.c @@ -35,6 +35,7 @@ #include "sysdb.h" #include "core/store-private.h" +#include "core/data.h" #include "core/object.h" #include @@ -46,7 +47,14 @@ 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; } diff --git a/src/core/store_lookup.c b/src/core/store_lookup.c index 1ec1dbb..0ef5f46 100644 --- a/src/core/store_lookup.c +++ b/src/core/store_lookup.c @@ -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); diff --git a/src/include/core/store.h b/src/include/core/store.h index 533f408..760c23d 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -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 -- 2.30.2