Code

store: Split store_obj into separate host and service objects.
[sysdb.git] / src / core / store_lookup.c
index dceab19dd7d99feb1e7fb68982d43fe703567e00..66f3f22dcfb9b5ec7a9fd447135ab493c7360f92 100644 (file)
@@ -74,16 +74,14 @@ lookup_iter(sdb_store_base_t *obj, void *user_data)
 } /* lookup_iter */
 
 static sdb_store_base_t *
-attr_get(sdb_store_base_t *host, const char *name)
+attr_get(sdb_host_t *host, const char *name)
 {
        sdb_llist_iter_t *iter = NULL;
        sdb_store_base_t *attr = NULL;
 
-       assert(host->type == SDB_HOST);
-
-       iter = sdb_llist_get_iter(SDB_STORE_OBJ(host)->attributes);
+       iter = sdb_llist_get_iter(host->attributes);
        while (sdb_llist_iter_has_next(iter)) {
-               sdb_attribute_t *a = SDB_ATTR(sdb_llist_iter_get_next(iter));
+               sdb_attribute_t *a = ATTR(sdb_llist_iter_get_next(iter));
 
                if (strcasecmp(name, SDB_OBJ(a)->name))
                        continue;
@@ -103,7 +101,7 @@ attr_cmp(sdb_store_base_t *obj, sdb_store_cond_t *cond)
 {
        sdb_attribute_t *attr;
 
-       attr = SDB_ATTR(attr_get(obj, ATTR_C(cond)->name));
+       attr = ATTR(attr_get(HOST(obj), ATTR_C(cond)->name));
        if (! attr)
                return INT_MAX;
        if (attr->value.type != ATTR_C(cond)->value.type)
@@ -172,10 +170,10 @@ match_name(sdb_store_matcher_t *m, sdb_store_base_t *obj)
                        return match_string(&NAME_M(m)->name, obj->super.name);
                        break;
                case SDB_SERVICE:
-                       iter = sdb_llist_get_iter(SDB_STORE_OBJ(obj)->children);
+                       iter = sdb_llist_get_iter(HOST(obj)->services);
                        break;
                case SDB_ATTRIBUTE:
-                       iter = sdb_llist_get_iter(SDB_STORE_OBJ(obj)->attributes);
+                       iter = sdb_llist_get_iter(HOST(obj)->attributes);
                        break;
        }
 
@@ -198,7 +196,7 @@ match_attr(sdb_store_matcher_t *m, sdb_store_base_t *obj)
        assert(m->type == MATCHER_ATTR);
        assert(ATTR_M(m)->name);
 
-       attr = SDB_ATTR(attr_get(obj, ATTR_M(m)->name));
+       attr = ATTR(attr_get(HOST(obj), ATTR_M(m)->name));
        if (attr) {
                char buf[sdb_data_strlen(&attr->value) + 1];
                if (sdb_data_format(&attr->value, buf, sizeof(buf), SDB_UNQUOTED) <= 0)
@@ -667,9 +665,59 @@ 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 sdb_data_t *value)
+{
+       sdb_store_matcher_t *(*matcher)(sdb_store_cond_t *) = NULL;
+       sdb_store_matcher_t *m;
+       sdb_store_cond_t *cond;
+       _Bool inv = 0;
+
+       /* 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, "="))
+               matcher = sdb_store_eq_matcher;
+       else if (! strcasecmp(op, ">="))
+               matcher = sdb_store_ge_matcher;
+       else if (! strcasecmp(op, ">"))
+               matcher = sdb_store_gt_matcher;
+       else if (! strcasecmp(op, "!=")) {
+               matcher = sdb_store_eq_matcher;
+               inv = 1;
+       }
+       else
+               return NULL;
+
+       cond = sdb_store_attr_cond(attr, value);
+       if (! cond)
+               return NULL;
+
+       m = matcher(cond);
+       /* pass ownership to 'm' or destroy in case of an error */
+       sdb_object_deref(SDB_OBJ(cond));
+       if (! m)
+               return NULL;
+
+       if (inv) {
+               sdb_store_matcher_t *tmp;
+               tmp = sdb_store_inv_matcher(m);
+               /* pass ownership to the inverse matcher */
+               sdb_object_deref(SDB_OBJ(m));
+               m = tmp;
+       }
+       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)
+               const char *op, const sdb_data_t *value)
 {
        int type = -1;
        _Bool inv = 0;
@@ -686,7 +734,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,13 +748,21 @@ 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;
 
+       if (value->type != SDB_TYPE_STRING) {
+               if (type == SDB_ATTRIBUTE)
+                       return parse_attr_cmp(attr, op, value);
+               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;