summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8b3cabc)
raw | patch | inline | side by side (parent: 8b3cabc)
author | Sebastian Harl <sh@tokkee.org> | |
Sun, 8 Mar 2015 10:56:33 +0000 (11:56 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sun, 8 Mar 2015 10:56:33 +0000 (11:56 +0100) |
For now, the same restrictions apply as before (iterate child objects or the
backends field). This is in preparation for more generic iterators.
backends field). This is in preparation for more generic iterators.
index 4ef11f917ac22eb875a912c7839868c99c9d54dd..cde2216327582968966d6f053adc62174ee0de99 100644 (file)
--- a/src/core/store-private.h
+++ b/src/core/store-private.h
/* iter matcher */
typedef struct {
sdb_store_matcher_t super;
- int type;
+ sdb_store_expr_t *iter;
sdb_store_matcher_t *m;
} iter_matcher_t;
#define ITER_M(m) ((iter_matcher_t *)(m))
index 2e73780fbf8da67f51c7e040470d051668b20621..94f95cc5188f4c03d146bd1b7157adab3f62f76f 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
#include "sysdb.h"
#include "core/store-private.h"
#include "core/object.h"
+#include "utils/error.h"
#include <assert.h>
sdb_store_matcher_t *filter)
{
sdb_avltree_iter_t *iter = NULL;
- int status;
+ int type, status;
int all = (int)(m->type == MATCHER_ALL);
assert((m->type == MATCHER_ANY) || (m->type == MATCHER_ALL));
- if (ITER_M(m)->type == SDB_FIELD_BACKEND)
+ if (ITER_M(m)->iter->type == FIELD_VALUE) {
+ if (ITER_M(m)->iter->data.data.integer != SDB_FIELD_BACKEND)
+ return 0;
return match_iter_array(m, obj, filter);
+ }
+ assert(ITER_M(m)->iter->type == TYPED_EXPR);
+
+ type = (int)ITER_M(m)->iter->data.data.integer;
if (obj->type == SDB_HOST) {
- if (ITER_M(m)->type == SDB_SERVICE)
+ if (type == SDB_SERVICE)
iter = sdb_avltree_get_iter(HOST(obj)->services);
- else if (ITER_M(m)->type == SDB_METRIC)
+ else if (type == SDB_METRIC)
iter = sdb_avltree_get_iter(HOST(obj)->metrics);
- else if (ITER_M(m)->type == SDB_ATTRIBUTE)
+ else if (type == SDB_ATTRIBUTE)
iter = sdb_avltree_get_iter(HOST(obj)->attributes);
} else if (obj->type == SDB_SERVICE) {
- if (ITER_M(m)->type == SDB_ATTRIBUTE)
+ if (type == SDB_ATTRIBUTE)
iter = sdb_avltree_get_iter(SVC(obj)->attributes);
} else if (obj->type == SDB_METRIC) {
- if (ITER_M(m)->type == SDB_ATTRIBUTE)
+ if (type == SDB_ATTRIBUTE)
iter = sdb_avltree_get_iter(METRIC(obj)->attributes);
}
iter_matcher_init(sdb_object_t *obj, va_list ap)
{
M(obj)->type = va_arg(ap, int);
- ITER_M(obj)->type = va_arg(ap, int);
+ ITER_M(obj)->iter = va_arg(ap, sdb_store_expr_t *);
ITER_M(obj)->m = va_arg(ap, sdb_store_matcher_t *);
- if (! ITER_M(obj)->m)
- return -1;
-
+ sdb_object_ref(SDB_OBJ(ITER_M(obj)->iter));
sdb_object_ref(SDB_OBJ(ITER_M(obj)->m));
+
+ if ((! ITER_M(obj)->iter) || (! ITER_M(obj)->m))
+ return -1;
return 0;
} /* iter_matcher_init */
static void
iter_matcher_destroy(sdb_object_t *obj)
{
+ sdb_object_deref(SDB_OBJ(ITER_M(obj)->iter));
sdb_object_deref(SDB_OBJ(ITER_M(obj)->m));
} /* iter_matcher_destroy */
*/
sdb_store_matcher_t *
-sdb_store_any_matcher(int type, sdb_store_matcher_t *m)
+sdb_store_any_matcher(sdb_store_expr_t *iter, sdb_store_matcher_t *m)
{
- if ((type != SDB_SERVICE) && (type != SDB_METRIC)
- && (type != SDB_ATTRIBUTE) && (type != SDB_FIELD_BACKEND))
+ if ((m->type < MATCHER_LT) || (MATCHER_NREGEX < m->type)) {
+ sdb_log(SDB_LOG_ERR, "store: Invalid ANY -> %s matcher "
+ "(invalid operator)", MATCHER_SYM(m->type));
return NULL;
+ }
return M(sdb_object_create("any-matcher", iter_type,
- MATCHER_ANY, type, m));
+ MATCHER_ANY, iter, m));
} /* sdb_store_any_matcher */
sdb_store_matcher_t *
-sdb_store_all_matcher(int type, sdb_store_matcher_t *m)
+sdb_store_all_matcher(sdb_store_expr_t *iter, sdb_store_matcher_t *m)
{
- if ((type != SDB_SERVICE) && (type != SDB_METRIC)
- && (type != SDB_ATTRIBUTE) && (type != SDB_FIELD_BACKEND))
+ if ((m->type < MATCHER_LT) || (MATCHER_NREGEX < m->type)) {
+ sdb_log(SDB_LOG_ERR, "store: Invalid ALL -> %s matcher "
+ "(invalid operator)", MATCHER_SYM(m->type));
return NULL;
+ }
return M(sdb_object_create("all-matcher", iter_type,
- MATCHER_ALL, type, m));
+ MATCHER_ALL, iter, m));
} /* sdb_store_all_matcher */
sdb_store_matcher_t *
index 62bae1c134904af8a84ede0d7906912fe3704f3e..b5d0e0825ce785dd09468d2474676bd7888749b8 100644 (file)
--- a/src/frontend/analyzer.c
+++ b/src/frontend/analyzer.c
case MATCHER_ANY:
case MATCHER_ALL:
+ {
+ int type;
assert(ITER_M(m)->m);
+ if ((ITER_M(m)->iter->type == TYPED_EXPR)
+ || (ITER_M(m)->iter->type == FIELD_VALUE)) {
+ type = (int)ITER_M(m)->iter->data.data.integer;
+ }
+ else {
+ iter_error(errbuf, m->type, -1, context);
+ return -1;
+ }
if ((context != SDB_HOST)
&& (context != SDB_SERVICE)
&& (context != SDB_METRIC)) {
- iter_error(errbuf, m->type, ITER_M(m)->type, context);
+ iter_error(errbuf, m->type, type, context);
return -1;
}
- if (ITER_M(m)->type == context) {
- iter_error(errbuf, m->type, ITER_M(m)->type, context);
+ if (type == context) {
+ iter_error(errbuf, m->type, type, context);
return -1;
}
- if ((ITER_M(m)->type != SDB_SERVICE)
- && (ITER_M(m)->type != SDB_METRIC)
- && (ITER_M(m)->type != SDB_ATTRIBUTE)
- && (ITER_M(m)->type != SDB_FIELD_BACKEND)) {
- iter_error(errbuf, m->type, ITER_M(m)->type, context);
+ if ((type != SDB_SERVICE)
+ && (type != SDB_METRIC)
+ && (type != SDB_ATTRIBUTE)
+ && (type != SDB_FIELD_BACKEND)) {
+ iter_error(errbuf, m->type, type, context);
return -1;
}
- if ((context == SDB_SERVICE)
- && (ITER_M(m)->type == SDB_METRIC)) {
- iter_error(errbuf, m->type, ITER_M(m)->type, context);
+ if ((context == SDB_SERVICE) && (type == SDB_METRIC)) {
+ iter_error(errbuf, m->type, type, context);
return -1;
}
- else if ((context == SDB_METRIC)
- && (ITER_M(m)->type == SDB_SERVICE)) {
- iter_error(errbuf, m->type, ITER_M(m)->type, context);
+ else if ((context == SDB_METRIC) && (type == SDB_SERVICE)) {
+ iter_error(errbuf, m->type, type, context);
return -1;
}
/* any ary operator will do but these are the once
CMP_M(ITER_M(m)->m)->right->data_type);
return -1;
}
- if (ITER_M(m)->type == SDB_FIELD_BACKEND) {
+ if (type == SDB_FIELD_BACKEND) {
if (CMP_M(ITER_M(m)->m)->right->data_type < 0)
return 0; /* skip further type checks */
if (CMP_M(ITER_M(m)->m)->right->data_type & SDB_TYPE_ARRAY) {
return -1;
}
}
- else if (analyze_matcher(ITER_M(m)->type, m->type,
- ITER_M(m)->m, errbuf))
+ else if (analyze_matcher(type, m->type, ITER_M(m)->m, errbuf))
return -1;
break;
+ }
case MATCHER_LT:
case MATCHER_LE:
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 4021031d4e8f3dd29e39e03634decfe98e1b22cc..ac899e3708212fe78b928fe6977fb86c6d5cfb2b 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
*/
static sdb_store_matcher_t *
-name_iter_matcher(int m_type, int type, const char *cmp,
+name_iter_matcher(int m_type, sdb_store_expr_t *iter, const char *cmp,
sdb_store_expr_t *expr);
/*
%type <expr> expression arithmetic_expression object_expression
%type <integer> object_type object_type_plural
-%type <integer> iterable
%type <integer> field
%type <sstr> cmp
sdb_object_deref(SDB_OBJ($3));
}
|
- ANY iterable cmp expression
+ ANY expression cmp expression
{
$$ = name_iter_matcher(MATCHER_ANY, $2, $3, $4);
+ sdb_object_deref(SDB_OBJ($2));
sdb_object_deref(SDB_OBJ($4));
}
|
- ALL iterable cmp expression
+ ALL expression cmp expression
{
$$ = name_iter_matcher(MATCHER_ALL, $2, $3, $4);
+ sdb_object_deref(SDB_OBJ($2));
sdb_object_deref(SDB_OBJ($4));
}
|
sdb_object_deref(SDB_OBJ($3));
}
|
+ ATTRIBUTE_T '.' object_expression
+ {
+ $$ = sdb_store_expr_typed(SDB_ATTRIBUTE, $3);
+ sdb_object_deref(SDB_OBJ($3));
+ }
+ |
field
{
$$ = sdb_store_expr_fieldvalue($1);
METRICS_T { $$ = SDB_METRIC; }
;
-iterable:
- SERVICE_T '.' NAME_T { $$ = SDB_SERVICE; }
- |
- METRIC_T '.' NAME_T { $$ = SDB_METRIC; }
- |
- ATTRIBUTE_T '.' NAME_T { $$ = SDB_ATTRIBUTE; }
- |
- BACKEND_T { $$ = SDB_FIELD_BACKEND; }
- ;
-
field:
NAME_T { $$ = SDB_FIELD_NAME; }
|
} /* sdb_fe_yyerrorf */
static sdb_store_matcher_t *
-name_iter_matcher(int m_type, int type, const char *cmp,
+name_iter_matcher(int type, sdb_store_expr_t *iter, const char *cmp,
sdb_store_expr_t *expr)
{
sdb_store_matcher_op_cb cb = sdb_store_parse_matcher_op(cmp);
- sdb_store_expr_t *e;
sdb_store_matcher_t *m, *tmp = NULL;
assert(cb);
- /* hosts are never iterable */
- if (type == SDB_HOST) {
- return NULL;
- }
-
- if (type == SDB_FIELD_BACKEND)
- e = sdb_store_expr_fieldvalue(type);
- else
- e = sdb_store_expr_fieldvalue(SDB_FIELD_NAME);
- m = cb(e, expr);
- if (m_type == MATCHER_ANY)
- tmp = sdb_store_any_matcher(type, m);
- else if (m_type == MATCHER_ALL)
- tmp = sdb_store_all_matcher(type, m);
+ m = cb(iter, expr);
+ if (type == MATCHER_ANY)
+ tmp = sdb_store_any_matcher(iter, m);
+ else if (type == MATCHER_ALL)
+ tmp = sdb_store_all_matcher(iter, m);
sdb_object_deref(SDB_OBJ(m));
- sdb_object_deref(SDB_OBJ(e));
return tmp;
} /* name_iter_matcher */
index e83ff8486ebcf2a8d21a49a9c8da87ddeceba9ec..3722a7262d6aa773d4f3210e12217e7505d449f1 100644 (file)
--- a/src/include/core/store.h
+++ b/src/include/core/store.h
/*
* sdb_store_any_matcher:
- * Creates a matcher iterating over objects of the specified type. It matches
- * if *any* of those objects match 'm'.
+ * Creates a matcher iterating over values of the first expression (which has
+ * to be iterable). It matches if *any* of those elements match 'm'. 'm' has
+ * to be an ary operation with the left operand unset.
*/
sdb_store_matcher_t *
-sdb_store_any_matcher(int type, sdb_store_matcher_t *m);
+sdb_store_any_matcher(sdb_store_expr_t *iter, sdb_store_matcher_t *m);
/*
* sdb_store_all_matcher:
- * Creates a matcher iterating over objects of the specified type. It matches
- * if *all* of those objects match 'm'.
+ * Creates a matcher iterating over values of the first expression (which has
+ * to be iterable). It matches if *all* of those elements match 'm'. 'm' has
+ * to be an ary operation with the left operand unset.
*/
sdb_store_matcher_t *
-sdb_store_all_matcher(int type, sdb_store_matcher_t *m);
+sdb_store_all_matcher(sdb_store_expr_t *iter, sdb_store_matcher_t *m);
/*
* sdb_store_in_matcher:
index f202c6ba463ffd291f8da2b6a95071b6ca2a6c07..642af72d92bffed59364085e6556d673cddcdf6c 100644 (file)
else
m = sdb_store_eq_matcher(obj, value);
if (cmp_name_data[_i].type != SDB_HOST) {
+ sdb_store_expr_t *iter;
sdb_store_matcher_t *tmp;
- tmp = sdb_store_any_matcher(cmp_name_data[_i].type, m);
+ iter = sdb_store_expr_typed(cmp_name_data[_i].type, obj);
+ tmp = sdb_store_any_matcher(iter, m);
+ sdb_object_deref(SDB_OBJ(iter));
sdb_object_deref(SDB_OBJ(m));
m = tmp;
}
index e64da004450359056136f61d79ae8351f2da3200..b67b133c367c045506576be9de50ce96aeb0919b 100644 (file)
"name + 1 IS NULL", -1, -1, 0 },
{ "LOOKUP hosts FILTER "
"name + 1 IS NULL", -1, -1, 0 },
+ { "LOOKUP hosts MATCHING "
+ "ANY 'patt' =~ 'p'", -1, -1, 0 },
/* comments */
{ "/* some comment */", -1, 0, 0 },