From f16f904e1f266e079ba6f06ae7952a11b29d5dfd Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 23 Jun 2014 18:43:40 +0200 Subject: [PATCH] store_lookup: Pass a data-object to parse_cmp(). That'll allow for comparing attribute values of any type. --- src/core/store_lookup.c | 19 +++--- src/frontend/grammar.y | 3 +- src/include/core/store.h | 2 +- t/unit/core/store_lookup_test.c | 107 +++++++++++++++++--------------- 4 files changed, 69 insertions(+), 62 deletions(-) diff --git a/src/core/store_lookup.c b/src/core/store_lookup.c index 501d7d1..658f931 100644 --- a/src/core/store_lookup.c +++ b/src/core/store_lookup.c @@ -668,12 +668,11 @@ sdb_store_gt_matcher(sdb_store_cond_t *cond) } /* sdb_store_gt_matcher */ static sdb_store_matcher_t * -parse_attr_cmp(const char *attr, const char *op, const char *value) +parse_attr_cmp(const char *attr, const char *op, const sdb_data_t *value) { sdb_store_matcher_t *(*matcher)(sdb_store_cond_t *) = NULL; sdb_store_matcher_t *m; sdb_store_cond_t *cond; - sdb_data_t data; /* TODO: this will reject any attributes called "name"; * use a different syntax for querying objects by name */ @@ -694,12 +693,7 @@ parse_attr_cmp(const char *attr, const char *op, const char *value) else return NULL; - data.type = SDB_TYPE_STRING; - data.data.string = strdup(value); - if (! data.data.string) - return NULL; - cond = sdb_store_attr_cond(attr, &data); - free(data.data.string); + cond = sdb_store_attr_cond(attr, value); if (! cond) return NULL; @@ -711,7 +705,7 @@ parse_attr_cmp(const char *attr, const char *op, const char *value) sdb_store_matcher_t * sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr, - const char *op, const char *value) + const char *op, const sdb_data_t *value) { int type = -1; _Bool inv = 0; @@ -747,10 +741,13 @@ sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr, else return NULL; + if (value->type != SDB_TYPE_STRING) + return NULL; + if (! strcasecmp(attr, "name")) - m = sdb_store_name_matcher(type, value, re); + m = sdb_store_name_matcher(type, value->data.string, re); else if (type == SDB_ATTRIBUTE) - m = sdb_store_attr_matcher(attr, value, re); + m = sdb_store_attr_matcher(attr, value->data.string, re); if (! m) return NULL; diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index 8e5ddf6..402e170 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -292,7 +292,8 @@ matcher: compare_matcher: IDENTIFIER '.' IDENTIFIER op STRING { - $$ = sdb_store_matcher_parse_cmp($1, $3, $4, $5); + sdb_data_t data = { SDB_TYPE_STRING, { .string = $5 } }; + $$ = sdb_store_matcher_parse_cmp($1, $3, $4, &data); free($1); $1 = NULL; free($3); $3 = NULL; free($5); $5 = NULL; diff --git a/src/include/core/store.h b/src/include/core/store.h index ecaf21d..5920081 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -221,7 +221,7 @@ sdb_store_gt_matcher(sdb_store_cond_t *cond); */ sdb_store_matcher_t * sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr, - const char *op, const char *value); + const char *op, const sdb_data_t *value); /* * sdb_store_dis_matcher: diff --git a/t/unit/core/store_lookup_test.c b/t/unit/core/store_lookup_test.c index 4e3e697..b5cb0d2 100644 --- a/t/unit/core/store_lookup_test.c +++ b/t/unit/core/store_lookup_test.c @@ -387,6 +387,10 @@ END_TEST START_TEST(test_parse_cmp) { + sdb_data_t hostname = { SDB_TYPE_STRING, { .string = "hostname" } }; + sdb_data_t srvname = { SDB_TYPE_STRING, { .string = "srvname" } }; + sdb_data_t attrname = { SDB_TYPE_STRING, { .string = "attrname" } }; + sdb_store_matcher_t *check; size_t i; @@ -395,75 +399,80 @@ START_TEST(test_parse_cmp) const char *obj_type; const char *attr; const char *op; - const char *value; + const sdb_data_t value; int expected; } golden_data[] = { - { "host", "name", "=", "hostname", MATCHER_NAME }, - { "host", "name", "!=", "hostname", MATCHER_NOT }, - { "host", "name", "=~", "hostname", MATCHER_NAME }, - { "host", "name", "!~", "hostname", MATCHER_NOT }, - { "host", "attr", "=", "hostname", -1 }, - { "host", "attr", "!=", "hostname", -1 }, - { "host", "name", "&^", "hostname", -1 }, - { "host", "name", "<", "hostname", -1 }, - { "host", "name", "<=", "hostname", -1 }, - { "host", "name", ">=", "hostname", -1 }, - { "host", "name", ">", "hostname", -1 }, - { "service", "name", "=", "srvname", MATCHER_NAME }, - { "service", "name", "!=", "srvname", MATCHER_NOT }, - { "service", "name", "=~", "srvname", MATCHER_NAME }, - { "service", "name", "!~", "srvname", MATCHER_NOT }, - { "service", "attr", "=", "srvname", -1 }, - { "service", "attr", "!=", "srvname", -1 }, - { "service", "name", "&^", "srvname", -1 }, - { "service", "name", "<", "srvname", -1 }, - { "service", "name", "<=", "srvname", -1 }, - { "service", "name", ">=", "srvname", -1 }, - { "service", "name", ">", "srvname", -1 }, - { "attribute", "name", "=", "attrname", MATCHER_NAME }, - { "attribute", "name", "!=", "attrname", MATCHER_NOT }, - { "attribute", "name", "=~", "attrname", MATCHER_NAME }, - { "attribute", "name", "!~", "attrname", MATCHER_NOT }, - { "attribute", "name", "<", "attrname", -1 }, - { "attribute", "name", "<=", "attrname", -1 }, - { "attribute", "name", ">=", "attrname", -1 }, - { "attribute", "name", ">", "attrname", -1 }, - { "attribute", "attr", "=", "attrname", MATCHER_ATTR }, - { "attribute", "attr", "!=", "attrname", MATCHER_NOT }, - { "attribute", "attr", "=~", "attrname", MATCHER_ATTR }, - { "attribute", "attr", "!~", "attrname", MATCHER_NOT }, - { "attribute", "attr", "&^", "attrname", -1 }, - { "attribute", "attr", "<", "attrname", MATCHER_LT }, - { "attribute", "attr", "<=", "attrname", MATCHER_LE }, -/* { "attribute", "attr", "=", "attrname", MATCHER_EQ }, */ - { "attribute", "attr", ">=", "attrname", MATCHER_GE }, - { "attribute", "attr", ">", "attrname", MATCHER_GT }, - { "foo", "name", "=", "bar", -1 }, - { "foo", "attr", "=", "bar", -1 }, + { "host", "name", "=", hostname, MATCHER_NAME }, + { "host", "name", "!=", hostname, MATCHER_NOT }, + { "host", "name", "=~", hostname, MATCHER_NAME }, + { "host", "name", "!~", hostname, MATCHER_NOT }, + { "host", "attr", "=", hostname, -1 }, + { "host", "attr", "!=", hostname, -1 }, + { "host", "name", "&^", hostname, -1 }, + { "host", "name", "<", hostname, -1 }, + { "host", "name", "<=", hostname, -1 }, + { "host", "name", ">=", hostname, -1 }, + { "host", "name", ">", hostname, -1 }, + { "service", "name", "=", srvname, MATCHER_NAME }, + { "service", "name", "!=", srvname, MATCHER_NOT }, + { "service", "name", "=~", srvname, MATCHER_NAME }, + { "service", "name", "!~", srvname, MATCHER_NOT }, + { "service", "attr", "=", srvname, -1 }, + { "service", "attr", "!=", srvname, -1 }, + { "service", "name", "&^", srvname, -1 }, + { "service", "name", "<", srvname, -1 }, + { "service", "name", "<=", srvname, -1 }, + { "service", "name", ">=", srvname, -1 }, + { "service", "name", ">", srvname, -1 }, + { "attribute", "name", "=", attrname, MATCHER_NAME }, + { "attribute", "name", "!=", attrname, MATCHER_NOT }, + { "attribute", "name", "=~", attrname, MATCHER_NAME }, + { "attribute", "name", "!~", attrname, MATCHER_NOT }, + { "attribute", "name", "<", attrname, -1 }, + { "attribute", "name", "<=", attrname, -1 }, + { "attribute", "name", ">=", attrname, -1 }, + { "attribute", "name", ">", attrname, -1 }, + { "attribute", "attr", "=", attrname, MATCHER_ATTR }, + { "attribute", "attr", "!=", attrname, MATCHER_NOT }, + { "attribute", "attr", "=~", attrname, MATCHER_ATTR }, + { "attribute", "attr", "!~", attrname, MATCHER_NOT }, + { "attribute", "attr", "&^", attrname, -1 }, + { "attribute", "attr", "<", attrname, MATCHER_LT }, + { "attribute", "attr", "<=", attrname, MATCHER_LE }, +/* { "attribute", "attr", "=", attrname, MATCHER_EQ }, */ + { "attribute", "attr", ">=", attrname, MATCHER_GE }, + { "attribute", "attr", ">", attrname, MATCHER_GT }, + { "foo", "name", "=", attrname, -1 }, + { "foo", "attr", "=", attrname, -1 }, }; for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) { + char buf[1024]; + check = sdb_store_matcher_parse_cmp(golden_data[i].obj_type, - golden_data[i].attr, golden_data[i].op, golden_data[i].value); + golden_data[i].attr, golden_data[i].op, + &golden_data[i].value); + + if (sdb_data_format(&golden_data[i].value, + buf, sizeof(buf), SDB_UNQUOTED) < 0) + snprintf(buf, sizeof(buf), "ERR"); if (golden_data[i].expected == -1) { fail_unless(check == NULL, "sdb_store_matcher_parse_cmp(%s, %s, %s, %s) = %p; " "expected: NULL", golden_data[i].obj_type, - golden_data[i].attr, golden_data[i].op, - golden_data[i].value, check); + golden_data[i].attr, golden_data[i].op, buf, check); continue; } fail_unless(check != NULL, "sdb_store_matcher_parse_cmp(%s, %s, %s, %s) = %p; " "expected: NULL", golden_data[i].obj_type, - golden_data[i].attr, golden_data[i].op, - golden_data[i].value, check); + golden_data[i].attr, golden_data[i].op, buf, check); fail_unless(M(check)->type == golden_data[i].expected, "sdb_store_matcher_parse_cmp(%s, %s, %s, %s) returned matcher " "of type %d; expected: %d", golden_data[i].obj_type, - golden_data[i].attr, golden_data[i].op, golden_data[i].value, + golden_data[i].attr, golden_data[i].op, buf, M(check)->type, golden_data[i].expected); sdb_object_deref(SDB_OBJ(check)); -- 2.30.2