Code

store: Added sdb_store_matcher_parse_cmp().
authorSebastian Harl <sh@tokkee.org>
Sat, 5 Apr 2014 16:42:06 +0000 (18:42 +0200)
committerSebastian Harl <sh@tokkee.org>
Sat, 5 Apr 2014 16:42:06 +0000 (18:42 +0200)
This function parses simple matcher compare expressions (<obj_type>.<attr>
<op> <value>).

src/core/store_lookup.c
src/include/core/store.h
t/core/store_lookup_test.c

index 45e7839b2debfe2365c93a51f17a1d17a5564afb..b73068486cf69811a85d7487b27ad7f41f741c5a 100644 (file)
@@ -469,6 +469,47 @@ sdb_store_host_matcher(const char *host_name, const char *host_name_re,
                                host_name, host_name_re, service_matcher, attr_matcher));
 } /* sdb_store_host_matcher */
 
+sdb_store_matcher_t *
+sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr,
+               const char *op, const char *value)
+{
+       int typ = -1;
+
+       const char *matcher = NULL;
+       const char *matcher_re = NULL;
+
+       if (! strcasecmp(obj_type, "host"))
+               typ = SDB_HOST;
+       else if (! strcasecmp(obj_type, "service"))
+               typ = SDB_SERVICE;
+       else if (! strcasecmp(obj_type, "attribute"))
+               typ = SDB_ATTRIBUTE;
+
+       /* TODO: support other operators */
+       if (! strcasecmp(op, "="))
+               matcher = value;
+       else if (! strcasecmp(op, "=~"))
+               matcher_re = value;
+       else
+               return NULL;
+
+       if (! strcasecmp(attr, "name")) {
+               /* accept */
+       }
+       else if (typ == SDB_ATTRIBUTE)
+               return sdb_store_attr_matcher(attr, NULL, matcher, matcher_re);
+       else
+               return NULL;
+
+       if (typ == SDB_HOST)
+               return sdb_store_host_matcher(matcher, matcher_re, NULL, NULL);
+       else if (typ == SDB_SERVICE)
+               return sdb_store_service_matcher(matcher, matcher_re, NULL);
+       else if (typ == SDB_ATTRIBUTE)
+               return sdb_store_attr_matcher(matcher, matcher_re, NULL, NULL);
+       return NULL;
+} /* sdb_store_matcher_parse_cmp */
+
 sdb_store_matcher_t *
 sdb_store_dis_matcher(sdb_store_matcher_t *left, sdb_store_matcher_t *right)
 {
index 1dfa9ab51005f3b116ce18332b9f6124c95cd833..9f232758b6e1a99b337c959b4174206fbb1080ed 100644 (file)
@@ -169,6 +169,18 @@ sdb_store_host_matcher(const char *host_name, const char *host_name_re,
                sdb_store_matcher_t *service_matcher,
                sdb_store_matcher_t *attr_matcher);
 
+/*
+ * sdb_store_matcher_parse_cmp:
+ * Parse a simple compare expression (<obj_type>.<attr> <op> <value>).
+ *
+ * Returns:
+ *  - a matcher object on success
+ *  - NULL else
+ */
+sdb_store_matcher_t *
+sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr,
+               const char *op, const char *value);
+
 /*
  * sdb_store_dis_matcher:
  * Creates a matcher matching the disjunction (logical OR) of two matchers.
index f95598e27dcf222be6ef0dfe42f80e3e9f137d7c..15a67b10a7809ac5f92d4a534a99f3600fd1cf65 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include "core/store.h"
+#include "core/store-private.h"
 #include "libsysdb_test.h"
 
 #include <check.h>
@@ -317,6 +318,63 @@ START_TEST(test_store_match_op)
 }
 END_TEST
 
+START_TEST(test_parse_cmp)
+{
+       sdb_store_matcher_t *check;
+
+       size_t i;
+
+       struct {
+               const char *obj_type;
+               const char *attr;
+               const char *op;
+               const char *value;
+               int expected;
+       } golden_data[] = {
+               { "host",      "name", "=",  "hostname", MATCHER_HOST },
+               { "host",      "name", "=~", "hostname", MATCHER_HOST },
+               { "host",      "attr", "=",  "hostname", -1 },
+               { "host",      "name", "&^", "hostname", -1 },
+               { "service",   "name", "=",  "srvname",  MATCHER_SERVICE },
+               { "service",   "name", "=",  "srvname",  MATCHER_SERVICE },
+               { "service",   "attr", "=",  "srvname",  -1 },
+               { "service",   "name", "&^", "srvname",  -1 },
+               { "attribute", "name", "=",  "attrname", MATCHER_ATTR },
+               { "attribute", "name", "=~", "attrname", MATCHER_ATTR },
+               { "attribute", "attr", "=",  "attrname", MATCHER_ATTR },
+               { "attribute", "attr", "=~", "attrname", MATCHER_ATTR },
+               { "attribute", "attr", "&^", "attrname", -1 },
+       };
+
+       for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
+               check = sdb_store_matcher_parse_cmp(golden_data[i].obj_type,
+                               golden_data[i].attr, golden_data[i].op, golden_data[i].value);
+
+               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);
+                       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);
+               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,
+                               M(check)->type, golden_data[i].expected);
+
+               sdb_object_deref(SDB_OBJ(check));
+       }
+}
+END_TEST
+
 static int
 lookup_cb(sdb_store_base_t *obj, void *user_data)
 {
@@ -356,6 +414,7 @@ core_store_lookup_suite(void)
        tcase_add_checked_fixture(tc, populate, sdb_store_clear);
        tcase_add_test(tc, test_store_match);
        tcase_add_test(tc, test_store_match_op);
+       tcase_add_test(tc, test_parse_cmp);
        tcase_add_test(tc, test_lookup);
        suite_add_tcase(s, tc);