index 7e2acefd12208c5d276dc73fdef3569a48cc45e2..557b93662f55d0ce4a83329112c98a2382b74a85 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
return (status != INT_MAX) && (status > 0);
} /* match_gt */
+static int
+match_isnull(sdb_store_matcher_t *m, sdb_host_t *host)
+{
+ assert(m->type == MATCHER_ISNULL);
+ return attr_get(host, ISNULL_M(m)->attr_name) == NULL;
+} /* match_isnull */
+
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 */
-static matcher_cb matchers[] = {
+static matcher_cb
+matchers[] = {
match_logical,
match_logical,
match_unary,
match_eq,
match_ge,
match_gt,
+ match_isnull,
};
/*
return buf;
} /* uop_tostring */
+static int
+isnull_matcher_init(sdb_object_t *obj, va_list ap)
+{
+ const char *name;
+
+ M(obj)->type = va_arg(ap, int);
+ if (M(obj)->type != MATCHER_ISNULL)
+ return -1;
+
+ name = va_arg(ap, const char *);
+ if (! name)
+ return -1;
+ ISNULL_M(obj)->attr_name = strdup(name);
+ if (! ISNULL_M(obj)->attr_name)
+ return -1;
+ return 0;
+} /* isnull_matcher_init */
+
+static void
+isnull_matcher_destroy(sdb_object_t *obj)
+{
+ if (ISNULL_M(obj)->attr_name)
+ free(ISNULL_M(obj)->attr_name);
+ ISNULL_M(obj)->attr_name = NULL;
+} /* isnull_matcher_destroy */
+
+static char *
+isnull_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
+{
+ snprintf(buf, buflen, "(IS NULL, attr.%s)", ISNULL_M(m)->attr_name);
+ return buf;
+} /* isnull_tostring */
+
static sdb_type_t name_type = {
/* size = */ sizeof(name_matcher_t),
/* init = */ name_matcher_init,
/* destroy = */ uop_matcher_destroy,
};
+static sdb_type_t isnull_type = {
+ /* size = */ sizeof(isnull_matcher_t),
+ /* init = */ isnull_matcher_init,
+ /* destroy = */ isnull_matcher_destroy,
+};
+
typedef char *(*matcher_tostring_cb)(sdb_store_matcher_t *, char *, size_t);
/* this array needs to be indexable by the matcher types;
* -> update the enum in store-private.h when updating this */
-static matcher_tostring_cb matchers_tostring[] = {
+static matcher_tostring_cb
+matchers_tostring[] = {
op_tostring,
op_tostring,
uop_tostring,
cond_tostring,
cond_tostring,
cond_tostring,
+ isnull_tostring,
};
/*
MATCHER_GT, cond));
} /* sdb_store_gt_matcher */
+sdb_store_matcher_t *
+sdb_store_isnull_matcher(const char *attr_name)
+{
+ return M(sdb_object_create("isnull-matcher", isnull_type,
+ MATCHER_ISNULL, attr_name));
+} /* sdb_store_isnull_matcher */
+
static sdb_store_matcher_t *
parse_attr_cmp(const char *attr, const char *op, const sdb_data_t *value)
{
if (! strcasecmp(attr, "name"))
return NULL;
- if (! strcasecmp(op, "<"))
+ if (! strcasecmp(op, "IS"))
+ return sdb_store_isnull_matcher(attr);
+ else if (! value)
+ return NULL;
+ else if (! strcasecmp(op, "<"))
matcher = sdb_store_lt_matcher;
else if (! strcasecmp(op, "<="))
matcher = sdb_store_le_matcher;