summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 88281ca)
raw | patch | inline | side by side (parent: 88281ca)
author | Sebastian Harl <sh@tokkee.org> | |
Mon, 28 Jul 2014 21:36:05 +0000 (23:36 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Mon, 28 Jul 2014 21:36:05 +0000 (23:36 +0200) |
Most of the matchers are actually not specific to hosts and may be re-used for
different purposes (e.g. filters). Make them applicable to arbitrary object
types (again) and only check for the right object type when actually needed.
Added simple unit-tests covering filters applied to all types of objects.
different purposes (e.g. filters). Make them applicable to arbitrary object
types (again) and only check for the right object type when actually needed.
Added simple unit-tests covering filters applied to all types of objects.
src/core/store-private.h | patch | blob | history | |
src/core/store_lookup.c | patch | blob | history | |
t/unit/core/store_lookup_test.c | patch | blob | history |
index 703bc55e476c0b3ef2663ec28ac63098a0d2399b..0df3c7ba041c5eae961e116231c87605e46b0a47 100644 (file)
--- a/src/core/store-private.h
+++ b/src/core/store-private.h
* conditionals
*/
-/* compares a host using the specified conditional and taking the specified
+/* compares an object using the specified conditional and taking the specified
* filter into account */
-typedef int (*cmp_cb)(sdb_host_t *, sdb_store_cond_t *,
+typedef int (*cmp_cb)(sdb_store_obj_t *, sdb_store_cond_t *,
sdb_store_matcher_t *);
struct sdb_store_cond {
index ac0f2e8c794c61c36a9d0aa34cff47deb2a9c939..ed585914cd38bee517d0dddfd84e47bfcbb6b980 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
*/
static int
-attr_cmp(sdb_host_t *host, sdb_store_cond_t *cond,
+attr_cmp(sdb_store_obj_t *obj, sdb_store_cond_t *cond,
sdb_store_matcher_t *filter)
{
sdb_attribute_t *attr;
sdb_data_t value = SDB_DATA_INIT;
int status;
+ if (obj->type != SDB_HOST)
+ return INT_MAX;
+
if (sdb_store_expr_eval(ATTR_C(cond)->expr, &value))
return INT_MAX;
- attr = attr_get(host, ATTR_C(cond)->name, filter);
+ attr = attr_get(HOST(obj), ATTR_C(cond)->name, filter);
if (! attr)
status = INT_MAX;
else if (attr->value.type != value.type)
} /* match_string */
static int
-match_logical(sdb_store_matcher_t *m, sdb_host_t *host,
+match_logical(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
int status;
assert((m->type == MATCHER_AND) || (m->type == MATCHER_OR));
assert(OP_M(m)->left && OP_M(m)->right);
- status = sdb_store_matcher_matches(OP_M(m)->left, STORE_OBJ(host),
- filter);
+ status = sdb_store_matcher_matches(OP_M(m)->left, obj, filter);
/* lazy evaluation */
if ((! status) && (m->type == MATCHER_AND))
else if (status && (m->type == MATCHER_OR))
return status;
- return sdb_store_matcher_matches(OP_M(m)->right, STORE_OBJ(host), filter);
+ return sdb_store_matcher_matches(OP_M(m)->right, obj, filter);
} /* match_logical */
static int
-match_unary(sdb_store_matcher_t *m, sdb_host_t *host,
+match_unary(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
assert(m->type == MATCHER_NOT);
assert(UOP_M(m)->op);
- return !sdb_store_matcher_matches(UOP_M(m)->op, STORE_OBJ(host), filter);
+ return !sdb_store_matcher_matches(UOP_M(m)->op, obj, filter);
} /* match_unary */
static int
-match_name(sdb_store_matcher_t *m, sdb_host_t *host,
+match_name(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
sdb_avltree_iter_t *iter = NULL;
assert(m->type == MATCHER_NAME);
+ if (obj->type == NAME_M(m)->obj_type)
+ return match_string(&NAME_M(m)->name, SDB_OBJ(obj)->name);
+ else if (obj->type != SDB_HOST)
+ return 0;
+
switch (NAME_M(m)->obj_type) {
- case SDB_HOST:
- return match_string(&NAME_M(m)->name, SDB_OBJ(host)->name);
- break;
case SDB_SERVICE:
- iter = sdb_avltree_get_iter(host->services);
+ iter = sdb_avltree_get_iter(HOST(obj)->services);
break;
case SDB_ATTRIBUTE:
- iter = sdb_avltree_get_iter(host->attributes);
+ iter = sdb_avltree_get_iter(HOST(obj)->attributes);
break;
}
} /* match_name */
static int
-match_attr(sdb_store_matcher_t *m, sdb_host_t *host,
+match_attr(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
sdb_attribute_t *attr;
assert(m->type == MATCHER_ATTR);
assert(ATTR_M(m)->name);
- attr = attr_get(host, ATTR_M(m)->name, filter);
+ if (obj->type != SDB_HOST)
+ return 0;
+
+ attr = attr_get(HOST(obj), ATTR_M(m)->name, filter);
if (attr) {
char buf[sdb_data_strlen(&attr->value) + 1];
if (sdb_data_format(&attr->value, buf, sizeof(buf), SDB_UNQUOTED) <= 0)
} /* match_attr */
static int
-match_lt(sdb_store_matcher_t *m, sdb_host_t *host,
+match_lt(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
int status;
assert(m->type == MATCHER_LT);
- status = COND_M(m)->cond->cmp(host, COND_M(m)->cond, filter);
+ status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond, filter);
return (status != INT_MAX) && (status < 0);
} /* match_lt */
static int
-match_le(sdb_store_matcher_t *m, sdb_host_t *host,
+match_le(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
int status;
assert(m->type == MATCHER_LE);
- status = COND_M(m)->cond->cmp(host, COND_M(m)->cond, filter);
+ status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond, filter);
return (status != INT_MAX) && (status <= 0);
} /* match_le */
static int
-match_eq(sdb_store_matcher_t *m, sdb_host_t *host,
+match_eq(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
int status;
assert(m->type == MATCHER_EQ);
- status = COND_M(m)->cond->cmp(host, COND_M(m)->cond, filter);
+ status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond, filter);
return (status != INT_MAX) && (! status);
} /* match_eq */
static int
-match_ge(sdb_store_matcher_t *m, sdb_host_t *host,
+match_ge(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
int status;
assert(m->type == MATCHER_GE);
- status = COND_M(m)->cond->cmp(host, COND_M(m)->cond, filter);
+ status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond, filter);
return (status != INT_MAX) && (status >= 0);
} /* match_ge */
static int
-match_gt(sdb_store_matcher_t *m, sdb_host_t *host,
+match_gt(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
int status;
assert(m->type == MATCHER_GT);
- status = COND_M(m)->cond->cmp(host, COND_M(m)->cond, filter);
+ status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond, filter);
return (status != INT_MAX) && (status > 0);
} /* match_gt */
static int
-match_isnull(sdb_store_matcher_t *m, sdb_host_t *host,
+match_isnull(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
assert(m->type == MATCHER_ISNULL);
- return attr_get(host, ISNULL_M(m)->attr_name, filter) == NULL;
+ if (obj->type != SDB_HOST)
+ return 0;
+ return attr_get(HOST(obj), ISNULL_M(m)->attr_name, filter) == NULL;
} /* match_isnull */
-typedef int (*matcher_cb)(sdb_store_matcher_t *, sdb_host_t *,
+typedef int (*matcher_cb)(sdb_store_matcher_t *, sdb_store_obj_t *,
sdb_store_matcher_t *);
/* this array needs to be indexable by the matcher types;
sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
- if (obj->type != SDB_HOST)
- return 0;
-
if (filter && (! sdb_store_matcher_matches(filter, obj, NULL)))
return 0;
if ((m->type < 0) || ((size_t)m->type >= SDB_STATIC_ARRAY_LEN(matchers)))
return 0;
- return matchers[m->type](m, HOST(obj), filter);
+ return matchers[m->type](m, obj, filter);
} /* sdb_store_matcher_matches */
char *
index c6eeb6bc3ae4d83b2cc6c323063795c5fe04083d..1adece554b031c6f94712b2a4977aa6ed2715e63 100644 (file)
} golden_data[] = {
{ "host = 'a'", NULL, 1,
"OBJ\\[host\\]\\{ NAME\\{ 'a', \\(nil\\) \\} \\}" },
- { "host = 'a'", "host = 'b'", 0,
+ { "host = 'a'", "host = 'x'", 0, /* filter never matches */
"OBJ\\[host\\]\\{ NAME\\{ 'a', \\(nil\\) \\} \\}" },
{ "host = 'a'",
- "attribute.x IS NULL", 1,
+ "NOT attribute.x = ''", 1, /* filter always matches */
"OBJ\\[host\\]\\{ NAME\\{ 'a', \\(nil\\) \\} \\}" },
{ "host =~ 'a|b'", NULL, 2,
"OBJ\\[host\\]\\{ NAME\\{ NULL, "PTR_RE" \\} \\}" },
"OBJ\\[host\\]\\{ NAME\\{ NULL, "PTR_RE" \\} \\}" },
{ "service = 's1'", NULL, 2,
"OBJ\\[service\\]\\{ NAME\\{ 's1', \\(nil\\) } \\}" },
+ { "service = 's1'", "host = 'x'", 0, /* filter never matches */
+ "OBJ\\[service\\]\\{ NAME\\{ 's1', \\(nil\\) } \\}" },
+ { "service = 's1'",
+ "NOT attribute.x = ''", 2, /* filter always matches */
+ "OBJ\\[service\\]\\{ NAME\\{ 's1', \\(nil\\) } \\}" },
{ "service =~ 's'", NULL, 2,
"OBJ\\[service\\]\\{ NAME\\{ NULL, "PTR_RE" } \\}" },
{ "service !~ 's'", NULL, 1,
"\\(NOT, OBJ\\[service\\]\\{ NAME\\{ NULL, "PTR_RE" } \\}\\)" },
{ "attribute = 'k1'", NULL, 1,
"OBJ\\[attribute\\]\\{ NAME\\{ 'k1', \\(nil\\) \\} " },
+ { "attribute = 'k1'", "host = 'x'", 0, /* filter never matches */
+ "OBJ\\[attribute\\]\\{ NAME\\{ 'k1', \\(nil\\) \\} " },
+ { "attribute = 'k1'",
+ "NOT attribute.x = ''", 1, /* filter always matches */
+ "OBJ\\[attribute\\]\\{ NAME\\{ 'k1', \\(nil\\) \\} " },
{ "attribute = 'x'", NULL, 0,
"OBJ\\[attribute\\]\\{ NAME\\{ 'x', \\(nil\\) \\}" },
{ "attribute.k1 = 'v1'", NULL, 1,
n = 0;
sdb_store_scan(m, filter, scan_cb, &n);
fail_unless(n == golden_data[i].expected,
- "sdb_store_scan(matcher{%s}, filter{NULL}) found %d hosts; "
- "expected: %d", golden_data[i].query, n,
- golden_data[i].expected);
+ "sdb_store_scan(matcher{%s}, filter{%s}) found %d hosts; "
+ "expected: %d", golden_data[i].query, golden_data[i].filter,
+ n, golden_data[i].expected);
sdb_object_deref(SDB_OBJ(filter));
sdb_object_deref(SDB_OBJ(m));
}