X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Fcore%2Fstore_lookup.c;h=489dd1ac52c6fa817df40046d5f0725b6fb45386;hp=dceab19dd7d99feb1e7fb68982d43fe703567e00;hb=56b97a180a53aecbfe9f7162b8ece3faae973cf9;hpb=596bcf4487836a640a03ccbad28763694181cab4 diff --git a/src/core/store_lookup.c b/src/core/store_lookup.c index dceab19..489dd1a 100644 --- a/src/core/store_lookup.c +++ b/src/core/store_lookup.c @@ -64,7 +64,7 @@ typedef struct { */ static int -lookup_iter(sdb_store_base_t *obj, void *user_data) +lookup_iter(sdb_store_obj_t *obj, void *user_data) { lookup_iter_data_t *d = user_data; @@ -73,21 +73,21 @@ lookup_iter(sdb_store_base_t *obj, void *user_data) return 0; } /* lookup_iter */ -static sdb_store_base_t * -attr_get(sdb_store_base_t *host, const char *name) +static sdb_attribute_t * +attr_get(sdb_host_t *host, const char *name) { sdb_llist_iter_t *iter = NULL; - sdb_store_base_t *attr = NULL; + sdb_attribute_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; - attr = STORE_BASE(a); + + assert(STORE_OBJ(a)->type == SDB_ATTRIBUTE); + attr = a; break; } sdb_llist_iter_destroy(iter); @@ -99,11 +99,11 @@ attr_get(sdb_store_base_t *host, const char *name) */ static int -attr_cmp(sdb_store_base_t *obj, sdb_store_cond_t *cond) +attr_cmp(sdb_host_t *host, sdb_store_cond_t *cond) { sdb_attribute_t *attr; - attr = SDB_ATTR(attr_get(obj, ATTR_C(cond)->name)); + attr = attr_get(host, ATTR_C(cond)->name); if (! attr) return INT_MAX; if (attr->value.type != ATTR_C(cond)->value.type) @@ -133,34 +133,34 @@ match_string(string_matcher_t *m, const char *name) } /* match_string */ static int -match_logical(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_logical(sdb_store_matcher_t *m, sdb_host_t *host) { int status; assert((m->type == MATCHER_AND) || (m->type == MATCHER_OR)); assert(OP_M(m)->left && OP_M(m)->right); - status = sdb_store_matcher_matches(OP_M(m)->left, obj); + status = sdb_store_matcher_matches(OP_M(m)->left, STORE_OBJ(host)); /* lazy evaluation */ if ((! status) && (m->type == MATCHER_AND)) return status; else if (status && (m->type == MATCHER_OR)) return status; - return sdb_store_matcher_matches(OP_M(m)->right, obj); + return sdb_store_matcher_matches(OP_M(m)->right, STORE_OBJ(host)); } /* match_logical */ static int -match_unary(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_unary(sdb_store_matcher_t *m, sdb_host_t *host) { assert(m->type == MATCHER_NOT); assert(UOP_M(m)->op); - return !sdb_store_matcher_matches(UOP_M(m)->op, obj); + return !sdb_store_matcher_matches(UOP_M(m)->op, STORE_OBJ(host)); } /* match_unary */ static int -match_name(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_name(sdb_store_matcher_t *m, sdb_host_t *host) { sdb_llist_iter_t *iter = NULL; int status = 0; @@ -169,19 +169,19 @@ match_name(sdb_store_matcher_t *m, sdb_store_base_t *obj) switch (NAME_M(m)->obj_type) { case SDB_HOST: - return match_string(&NAME_M(m)->name, obj->super.name); + return match_string(&NAME_M(m)->name, SDB_OBJ(host)->name); break; case SDB_SERVICE: - iter = sdb_llist_get_iter(SDB_STORE_OBJ(obj)->children); + iter = sdb_llist_get_iter(host->services); break; case SDB_ATTRIBUTE: - iter = sdb_llist_get_iter(SDB_STORE_OBJ(obj)->attributes); + iter = sdb_llist_get_iter(host->attributes); break; } while (sdb_llist_iter_has_next(iter)) { - sdb_store_base_t *child = STORE_BASE(sdb_llist_iter_get_next(iter)); - if (match_string(&NAME_M(m)->name, child->super.name)) { + sdb_object_t *child = sdb_llist_iter_get_next(iter); + if (match_string(&NAME_M(m)->name, child->name)) { status = 1; break; } @@ -191,14 +191,14 @@ match_name(sdb_store_matcher_t *m, sdb_store_base_t *obj) } /* match_name */ static int -match_attr(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_attr(sdb_store_matcher_t *m, sdb_host_t *host) { sdb_attribute_t *attr; assert(m->type == MATCHER_ATTR); assert(ATTR_M(m)->name); - attr = SDB_ATTR(attr_get(obj, ATTR_M(m)->name)); + attr = attr_get(host, 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) @@ -210,51 +210,51 @@ match_attr(sdb_store_matcher_t *m, sdb_store_base_t *obj) } /* match_attr */ static int -match_lt(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_lt(sdb_store_matcher_t *m, sdb_host_t *host) { int status; assert(m->type == MATCHER_LT); - status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond); + status = COND_M(m)->cond->cmp(host, COND_M(m)->cond); return (status != INT_MAX) && (status < 0); } /* match_lt */ static int -match_le(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_le(sdb_store_matcher_t *m, sdb_host_t *host) { int status; assert(m->type == MATCHER_LE); - status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond); + status = COND_M(m)->cond->cmp(host, COND_M(m)->cond); return (status != INT_MAX) && (status <= 0); } /* match_le */ static int -match_eq(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_eq(sdb_store_matcher_t *m, sdb_host_t *host) { int status; assert(m->type == MATCHER_EQ); - status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond); + status = COND_M(m)->cond->cmp(host, COND_M(m)->cond); return (status != INT_MAX) && (! status); } /* match_eq */ static int -match_ge(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_ge(sdb_store_matcher_t *m, sdb_host_t *host) { int status; assert(m->type == MATCHER_GE); - status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond); + status = COND_M(m)->cond->cmp(host, COND_M(m)->cond); return (status != INT_MAX) && (status >= 0); } /* match_ge */ static int -match_gt(sdb_store_matcher_t *m, sdb_store_base_t *obj) +match_gt(sdb_store_matcher_t *m, sdb_host_t *host) { int status; assert(m->type == MATCHER_GT); - status = COND_M(m)->cond->cmp(obj, COND_M(m)->cond); + status = COND_M(m)->cond->cmp(host, COND_M(m)->cond); return (status != INT_MAX) && (status > 0); } /* match_gt */ -typedef int (*matcher_cb)(sdb_store_matcher_t *, sdb_store_base_t *); +typedef int (*matcher_cb)(sdb_store_matcher_t *, sdb_host_t *); /* this array needs to be indexable by the matcher types; * -> update the enum in store-private.h when updating this */ @@ -667,9 +667,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 +736,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 +750,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; @@ -742,7 +800,7 @@ sdb_store_inv_matcher(sdb_store_matcher_t *m) } /* sdb_store_inv_matcher */ int -sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_base_t *obj) +sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_obj_t *obj) { if (obj->type != SDB_HOST) return 0; @@ -754,7 +812,7 @@ sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_base_t *obj) if ((m->type < 0) || ((size_t)m->type >= SDB_STATIC_ARRAY_LEN(matchers))) return 0; - return matchers[m->type](m, obj); + return matchers[m->type](m, HOST(obj)); } /* sdb_store_matcher_matches */ char *