Code

store_lookup: Added support for <, <=, >=, > when comparing attribute values.
authorSebastian Harl <sh@tokkee.org>
Mon, 23 Jun 2014 07:29:20 +0000 (09:29 +0200)
committerSebastian Harl <sh@tokkee.org>
Mon, 23 Jun 2014 07:29:20 +0000 (09:29 +0200)
src/core/store_lookup.c
t/unit/core/store_lookup_test.c

index dceab19dd7d99feb1e7fb68982d43fe703567e00..501d7d198b5129c2de51b7bfa9d2a65c649b75e9 100644 (file)
@@ -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;
 
index 67f2e05cbeff6bf31f301fd938a7b1202bbb92da..4e3e6971b4b7ad07529c74c1fc652a0fd51ca768 100644 (file)
@@ -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 },
        };