From 4dc515a84e889641a7cf93171ac60bee2d5b370c Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 23 Jun 2014 09:29:20 +0200 Subject: [PATCH] store_lookup: Added support for <, <=, >=, > when comparing attribute values. --- src/core/store_lookup.c | 46 ++++++++++++++++++++++++++++++++- t/unit/core/store_lookup_test.c | 17 ++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/core/store_lookup.c b/src/core/store_lookup.c index dceab19..501d7d1 100644 --- a/src/core/store_lookup.c +++ b/src/core/store_lookup.c @@ -667,6 +667,48 @@ sdb_store_gt_matcher(sdb_store_cond_t *cond) MATCHER_GT, cond)); } /* sdb_store_gt_matcher */ +static sdb_store_matcher_t * +parse_attr_cmp(const char *attr, const char *op, const char *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 */ + if (! strcasecmp(attr, "name")) + return NULL; + + if (! strcasecmp(op, "<")) + matcher = sdb_store_lt_matcher; + else if (! strcasecmp(op, "<=")) + matcher = sdb_store_le_matcher; + else if (! strcasecmp(op, "=")) + /* XXX: this is still handled by sdb_store_matcher_parse_cmp */ + matcher = sdb_store_eq_matcher; + else if (! strcasecmp(op, ">=")) + matcher = sdb_store_ge_matcher; + else if (! strcasecmp(op, ">")) + matcher = sdb_store_gt_matcher; + 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); + if (! cond) + return NULL; + + m = matcher(cond); + /* pass ownership to 'm' or destroy in case of an error */ + sdb_object_deref(SDB_OBJ(cond)); + return m; +} /* parse_attr_cmp */ + sdb_store_matcher_t * sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr, const char *op, const char *value) @@ -686,7 +728,7 @@ sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr, else return NULL; - /* TODO: support other operators */ + /* XXX: this code sucks! */ if (! strcasecmp(op, "=")) { /* nothing to do */ } @@ -700,6 +742,8 @@ sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr, inv = 1; re = 1; } + else if (type == SDB_ATTRIBUTE) + return parse_attr_cmp(attr, op, value); else return NULL; diff --git a/t/unit/core/store_lookup_test.c b/t/unit/core/store_lookup_test.c index 67f2e05..4e3e697 100644 --- a/t/unit/core/store_lookup_test.c +++ b/t/unit/core/store_lookup_test.c @@ -405,6 +405,10 @@ START_TEST(test_parse_cmp) { "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 }, @@ -412,15 +416,28 @@ START_TEST(test_parse_cmp) { "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 }, }; -- 2.30.2