Code

store: Added field type VALUE for attribute values.
authorSebastian Harl <sh@tokkee.org>
Sun, 15 Mar 2015 02:05:50 +0000 (22:05 -0400)
committerSebastian Harl <sh@tokkee.org>
Sun, 15 Mar 2015 02:05:50 +0000 (22:05 -0400)
src/core/store.c
src/core/store_expr.c
src/core/store_lookup.c
src/include/core/store.h
t/unit/core/store_test.c

index 1eb7ed138435eaa021bd54f1f4f8fca607033e8d..ab37e689641ec52b42f844bb5f1f1d3cd6236d63 100644 (file)
@@ -904,6 +904,12 @@ sdb_store_get_field(sdb_store_obj_t *obj, int field, sdb_data_t *res)
                        tmp.data.array.length = obj->backends_num;
                        tmp.data.array.values = obj->backends;
                        return sdb_data_copy(res, &tmp);
                        tmp.data.array.length = obj->backends_num;
                        tmp.data.array.values = obj->backends;
                        return sdb_data_copy(res, &tmp);
+               case SDB_FIELD_VALUE:
+                       if (obj->type != SDB_ATTRIBUTE)
+                               return -1;
+                       if (! res)
+                               return 0;
+                       return sdb_data_copy(res, &ATTR(obj)->value);
                default:
                        return -1;
        }
                default:
                        return -1;
        }
index 60b0bea130a8c50f85c12b6c1b6d9cf91ebc6a25..6e39305a89ecd18718ad7984a4e7cc85f407728d 100644 (file)
@@ -167,7 +167,7 @@ sdb_store_expr_fieldvalue(int field)
        sdb_data_t value = { SDB_TYPE_INTEGER, { .integer = field } };
        sdb_store_expr_t *e;
 
        sdb_data_t value = { SDB_TYPE_INTEGER, { .integer = field } };
        sdb_store_expr_t *e;
 
-       if ((field < SDB_FIELD_NAME) || (SDB_FIELD_BACKEND < field))
+       if ((field < SDB_FIELD_NAME) || (SDB_FIELD_VALUE < field))
                return NULL;
        e = SDB_STORE_EXPR(sdb_object_create("store-fieldvalue", expr_type,
                                FIELD_VALUE, NULL, NULL, &value));
                return NULL;
        e = SDB_STORE_EXPR(sdb_object_create("store-fieldvalue", expr_type,
                                FIELD_VALUE, NULL, NULL, &value));
@@ -286,7 +286,12 @@ sdb_store_expr_iterable(sdb_store_expr_t *expr, int context)
                if ((context != SDB_HOST) && (context != SDB_SERVICE)
                                && (context != SDB_METRIC) && (context != SDB_ATTRIBUTE))
                        return 0;
                if ((context != SDB_HOST) && (context != SDB_SERVICE)
                                && (context != SDB_METRIC) && (context != SDB_ATTRIBUTE))
                        return 0;
-               return expr->data.data.integer == SDB_FIELD_BACKEND;
+               if (expr->data.data.integer == SDB_FIELD_BACKEND)
+                       return 1;
+               else if (expr->data.data.integer == SDB_FIELD_VALUE)
+                       /* we don't current support this just like when using
+                        * the attribute[<name>] syntax */
+                       return 0;
        }
        else if (! expr->type) {
                return !!(expr->data.type & SDB_TYPE_ARRAY);
        }
        else if (! expr->type) {
                return !!(expr->data.type & SDB_TYPE_ARRAY);
index 9192618dd069442517da83e1461aae06d49e8031..18a0235536e3f154128ff576cbc624c9dfa49a5f 100644 (file)
@@ -705,6 +705,8 @@ sdb_store_parse_field_name(const char *name)
                return SDB_FIELD_INTERVAL;
        else if (! strcasecmp(name, "backend"))
                return SDB_FIELD_BACKEND;
                return SDB_FIELD_INTERVAL;
        else if (! strcasecmp(name, "backend"))
                return SDB_FIELD_BACKEND;
+       else if (! strcasecmp(name, "value"))
+               return SDB_FIELD_VALUE;
        return -1;
 } /* sdb_store_parse_field_name */
 
        return -1;
 } /* sdb_store_parse_field_name */
 
index 3722a7262d6aa773d4f3210e12217e7505d449f1..94a571345852481b89479fd6664f2fc484c103b9 100644 (file)
@@ -60,6 +60,7 @@ enum {
        SDB_FIELD_AGE,           /* type: datetime */
        SDB_FIELD_INTERVAL,      /* type: datetime */
        SDB_FIELD_BACKEND,       /* type: array of strings */
        SDB_FIELD_AGE,           /* type: datetime */
        SDB_FIELD_INTERVAL,      /* type: datetime */
        SDB_FIELD_BACKEND,       /* type: array of strings */
+       SDB_FIELD_VALUE,         /* attributes only;  type: type of the value */
 };
 #define SDB_STORE_TYPE_TO_NAME(t) \
        (((t) == SDB_HOST) ? "host" \
 };
 #define SDB_STORE_TYPE_TO_NAME(t) \
        (((t) == SDB_HOST) ? "host" \
@@ -76,7 +77,9 @@ enum {
                : ((f) == SDB_FIELD_LAST_UPDATE) ? "last-update" \
                : ((f) == SDB_FIELD_AGE) ? "age" \
                : ((f) == SDB_FIELD_INTERVAL) ? "interval" \
                : ((f) == SDB_FIELD_LAST_UPDATE) ? "last-update" \
                : ((f) == SDB_FIELD_AGE) ? "age" \
                : ((f) == SDB_FIELD_INTERVAL) ? "interval" \
-               : ((f) == SDB_FIELD_BACKEND) ? "backend" : "unknown")
+               : ((f) == SDB_FIELD_BACKEND) ? "backend" \
+               : ((f) == SDB_FIELD_VALUE) ? "value" \
+               : "unknown")
 
 #define SDB_FIELD_TYPE(f) \
        (((f) == SDB_FIELD_NAME) ? SDB_TYPE_STRING \
 
 #define SDB_FIELD_TYPE(f) \
        (((f) == SDB_FIELD_NAME) ? SDB_TYPE_STRING \
@@ -84,6 +87,7 @@ enum {
                : ((f) == SDB_FIELD_AGE) ? SDB_TYPE_DATETIME \
                : ((f) == SDB_FIELD_INTERVAL) ? SDB_TYPE_DATETIME \
                : ((f) == SDB_FIELD_BACKEND) ? (SDB_TYPE_ARRAY | SDB_TYPE_STRING) \
                : ((f) == SDB_FIELD_AGE) ? SDB_TYPE_DATETIME \
                : ((f) == SDB_FIELD_INTERVAL) ? SDB_TYPE_DATETIME \
                : ((f) == SDB_FIELD_BACKEND) ? (SDB_TYPE_ARRAY | SDB_TYPE_STRING) \
+               : ((f) == SDB_FIELD_VALUE) ? -1 /* unknown */ \
                : -1)
 
 /*
                : -1)
 
 /*
index 1eb5262ffaa758c2e49be9489ad2b93094acc9d6..dbf220cef4f26d718a505b8a9678812bbd0a1360 100644 (file)
@@ -414,24 +414,53 @@ END_TEST
 
 static struct {
        const char *hostname;
 
 static struct {
        const char *hostname;
+       const char *attr; /* optional */
        int field;
        int expected;
        sdb_data_t value;
 } get_field_data[] = {
        int field;
        int expected;
        sdb_data_t value;
 } get_field_data[] = {
-       { NULL,   0, -1, { SDB_TYPE_NULL, { 0 } } },
-       { NULL,   SDB_FIELD_LAST_UPDATE, -1, { SDB_TYPE_NULL, { 0 } } },
-       { NULL,   SDB_FIELD_NAME,        -1, { SDB_TYPE_NULL, { 0 } } },
-       { "host", SDB_FIELD_LAST_UPDATE,  0, { SDB_TYPE_DATETIME, { .datetime = 20 } } },
-       { "host", SDB_FIELD_INTERVAL,     0, { SDB_TYPE_DATETIME, { .datetime = 10 } } },
+       { NULL,   NULL, 0, -1, { SDB_TYPE_NULL, { 0 } } },
+       { NULL,   NULL,   SDB_FIELD_LAST_UPDATE, -1, { SDB_TYPE_NULL, { 0 } } },
+       { NULL,   NULL,   SDB_FIELD_INTERVAL,    -1, { SDB_TYPE_NULL, { 0 } } },
+       { NULL,   NULL,   SDB_FIELD_AGE,         -1, { SDB_TYPE_NULL, { 0 } } },
+       { NULL,   NULL,   SDB_FIELD_NAME,        -1, { SDB_TYPE_NULL, { 0 } } },
+       { NULL,   NULL,   SDB_FIELD_BACKEND,     -1, { SDB_TYPE_NULL, { 0 } } },
+       { NULL,   NULL,   SDB_FIELD_VALUE,       -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", NULL,   SDB_FIELD_LAST_UPDATE,  0, { SDB_TYPE_DATETIME, { .datetime = 20 } } },
+       { "host", NULL,   SDB_FIELD_INTERVAL,     0, { SDB_TYPE_DATETIME, { .datetime = 10 } } },
        /* the test will handle AGE specially */
        /* the test will handle AGE specially */
-       { "host", SDB_FIELD_AGE,          0, { SDB_TYPE_NULL, { 0 } } },
-       { "host", SDB_FIELD_NAME,         0, { SDB_TYPE_STRING, { .string = "host" } } },
-       { "host", SDB_FIELD_BACKEND,      0, { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } } },
+       { "host", NULL,   SDB_FIELD_AGE,          0, { SDB_TYPE_NULL, { 0 } } },
+       { "host", NULL,   SDB_FIELD_NAME,         0, { SDB_TYPE_STRING, { .string = "host" } } },
+       { "host", NULL,   SDB_FIELD_BACKEND,      0, { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } } },
+       { "host", NULL,   SDB_FIELD_VALUE,       -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "attr", SDB_FIELD_LAST_UPDATE,  0, { SDB_TYPE_DATETIME, { .datetime = 20 } } },
+       { "host", "attr", SDB_FIELD_INTERVAL,     0, { SDB_TYPE_DATETIME, { .datetime = 10 } } },
+       /* the test will handle AGE specially */
+       { "host", "attr", SDB_FIELD_AGE,          0, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "attr", SDB_FIELD_NAME,         0, { SDB_TYPE_STRING, { .string = "attr" } } },
+       { "host", "attr", SDB_FIELD_BACKEND,      0, { SDB_TYPE_ARRAY | SDB_TYPE_STRING, { .array = { 0, NULL } } } },
+       { "host", "attr", SDB_FIELD_VALUE,        0, { SDB_TYPE_INTEGER, { .integer = 1 } } },
+       { "host", "attr", SDB_FIELD_VALUE,        0, { SDB_TYPE_DECIMAL, { .decimal = 2.0 } } },
+       { "host", "attr", SDB_FIELD_VALUE,        0, { SDB_TYPE_STRING, { .string = "foo" } } },
+       { "host", "attr", SDB_FIELD_VALUE,        0, { SDB_TYPE_DATETIME, { .datetime = 1234567890L } } },
+       { "host", "a",    SDB_FIELD_LAST_UPDATE, -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_INTERVAL,    -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_AGE,         -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_NAME,        -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_BACKEND,     -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_VALUE,       -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_VALUE,       -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_VALUE,       -1, { SDB_TYPE_NULL, { 0 } } },
+       { "host", "a",    SDB_FIELD_VALUE,       -1, { SDB_TYPE_NULL, { 0 } } },
 };
 
 };
 
+/* returns a tuple <type> <name> */
+#define OBJ_NAME(obj) \
+       (obj) ? SDB_STORE_TYPE_TO_NAME(obj->type) : "NULL", \
+       (obj) ? SDB_OBJ(obj)->name : ""
 START_TEST(test_get_field)
 {
 START_TEST(test_get_field)
 {
-       sdb_store_obj_t *host = NULL;
+       sdb_store_obj_t *obj = NULL;
        sdb_data_t value = SDB_DATA_INIT;
        char value_str[128], expected_value_str[128];
        sdb_time_t now = sdb_gettime();
        sdb_data_t value = SDB_DATA_INIT;
        char value_str[128], expected_value_str[128];
        sdb_time_t now = sdb_gettime();
@@ -439,25 +468,36 @@ START_TEST(test_get_field)
 
        sdb_store_host("host", 10);
        sdb_store_host("host", 20);
 
        sdb_store_host("host", 10);
        sdb_store_host("host", 20);
+       sdb_store_attribute("host", "attr", &get_field_data[_i].value, 10);
+       sdb_store_attribute("host", "attr", &get_field_data[_i].value, 20);
 
        if (get_field_data[_i].hostname) {
 
        if (get_field_data[_i].hostname) {
-               host = sdb_store_get_host(get_field_data[_i].hostname);
-               ck_assert(host != NULL);
+               obj = sdb_store_get_host(get_field_data[_i].hostname);
+               ck_assert(obj != NULL);
+
+               if (get_field_data[_i].attr) {
+                       sdb_store_obj_t *tmp = sdb_store_get_child(obj,
+                                       SDB_ATTRIBUTE, get_field_data[_i].attr);
+                       sdb_object_deref(SDB_OBJ(obj));
+                       obj = tmp;
+               }
        }
 
        }
 
-       check = sdb_store_get_field(host, get_field_data[_i].field, NULL);
+       check = sdb_store_get_field(obj, get_field_data[_i].field, NULL);
        fail_unless(check == get_field_data[_i].expected,
        fail_unless(check == get_field_data[_i].expected,
-                       "sdb_store_get_field(%s, %s, NULL) = %d; expected: %d",
-                       host ? "<host>" : "NULL", SDB_FIELD_TO_NAME(get_field_data[_i].field),
+                       "sdb_store_get_field(%s %s, %s, NULL) = %d; expected: %d",
+                       OBJ_NAME(obj), SDB_FIELD_TO_NAME(get_field_data[_i].field),
                        check, get_field_data[_i].expected);
                        check, get_field_data[_i].expected);
-       check = sdb_store_get_field(host, get_field_data[_i].field, &value);
+       check = sdb_store_get_field(obj, get_field_data[_i].field, &value);
        fail_unless(check == get_field_data[_i].expected,
        fail_unless(check == get_field_data[_i].expected,
-                       "sdb_store_get_field(%s, %s, <value>) = %d; expected: %d",
-                       host ? "<host>" : "NULL", SDB_FIELD_TO_NAME(get_field_data[_i].field),
+                       "sdb_store_get_field(%s %s, %s, <value>) = %d; expected: %d",
+                       OBJ_NAME(obj), SDB_FIELD_TO_NAME(get_field_data[_i].field),
                        check, get_field_data[_i].expected);
 
                        check, get_field_data[_i].expected);
 
-       if (get_field_data[_i].expected)
+       if (get_field_data[_i].expected) {
+               sdb_object_deref(SDB_OBJ(obj));
                return;
                return;
+       }
 
        if (get_field_data[_i].field == SDB_FIELD_AGE) {
                get_field_data[_i].value.type = SDB_TYPE_DATETIME;
 
        if (get_field_data[_i].field == SDB_FIELD_AGE) {
                get_field_data[_i].value.type = SDB_TYPE_DATETIME;
@@ -471,21 +511,23 @@ START_TEST(test_get_field)
        if (get_field_data[_i].field == SDB_FIELD_AGE) {
                fail_unless((value.type == SDB_TYPE_DATETIME)
                                && (value.data.datetime >= now),
        if (get_field_data[_i].field == SDB_FIELD_AGE) {
                fail_unless((value.type == SDB_TYPE_DATETIME)
                                && (value.data.datetime >= now),
-                               "sdb_store_get_field(<host>, %s, <value>) "
-                               "returned value %s; expected >=%s",
+                               "sdb_store_get_field(%s %s, %s, <value>) "
+                               "returned value %s; expected >=%s", OBJ_NAME(obj),
                                SDB_FIELD_TO_NAME(get_field_data[_i].field),
                                value_str, expected_value_str);
        }
        else {
                fail_unless(! sdb_data_cmp(&value, &get_field_data[_i].value),
                                SDB_FIELD_TO_NAME(get_field_data[_i].field),
                                value_str, expected_value_str);
        }
        else {
                fail_unless(! sdb_data_cmp(&value, &get_field_data[_i].value),
-                               "sdb_store_get_field(<host>, %s, <value>) "
-                               "returned value %s; expected %s",
+                               "sdb_store_get_field(%s %s, %s, <value>) "
+                               "returned value %s; expected %s", OBJ_NAME(obj),
                                SDB_FIELD_TO_NAME(get_field_data[_i].field),
                                value_str, expected_value_str);
        }
        sdb_data_free_datum(&value);
                                SDB_FIELD_TO_NAME(get_field_data[_i].field),
                                value_str, expected_value_str);
        }
        sdb_data_free_datum(&value);
+       sdb_object_deref(SDB_OBJ(obj));
 }
 END_TEST
 }
 END_TEST
+#undef OBJ_NAME
 
 START_TEST(test_get_child)
 {
 
 START_TEST(test_get_child)
 {