From 6fbccd38ba921b0f08b4a38ef3568bd9ca12fcd5 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Thu, 31 Jul 2014 23:07:30 +0200 Subject: [PATCH] store: Added sdb_store_get_field(). This function may be used to retrieve the value of queryable fields of objects in the store. For now, all fields except the backend(s) are supported. --- src/core/store.c | 28 ++++++++++++++++++ src/core/store_lookup.c | 23 ++------------- src/include/core/store.h | 15 ++++++++++ t/unit/core/store_test.c | 64 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 21 deletions(-) diff --git a/src/core/store.c b/src/core/store.c index ee861d3..5a00b6c 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -620,6 +620,34 @@ sdb_store_service_attr(const char *hostname, const char *service, return status; } /* sdb_store_service_attr */ +int +sdb_store_get_field(sdb_store_obj_t *obj, int field, sdb_data_t *res) +{ + if ((! obj) || (! res)) + return -1; + + switch (field) { + case SDB_FIELD_LAST_UPDATE: + res->type = SDB_TYPE_DATETIME; + res->data.datetime = obj->last_update; + break; + case SDB_FIELD_AGE: + res->type = SDB_TYPE_DATETIME; + res->data.datetime = sdb_gettime() - obj->last_update; + break; + case SDB_FIELD_INTERVAL: + res->type = SDB_TYPE_DATETIME; + res->data.datetime = obj->interval; + break; + case SDB_FIELD_BACKEND: + /* TODO: add support for storing array values in a data object + * for now, fall thru to the error case */ + default: + return -1; + } + return 0; +} /* sdb_store_get_field */ + int sdb_store_host_tojson(sdb_store_obj_t *h, sdb_strbuf_t *buf, sdb_store_matcher_t *filter, int flags) diff --git a/src/core/store_lookup.c b/src/core/store_lookup.c index 124c451..1ec1dbb 100644 --- a/src/core/store_lookup.c +++ b/src/core/store_lookup.c @@ -136,27 +136,8 @@ obj_cmp(sdb_store_obj_t *obj, sdb_store_cond_t *cond, sdb_data_t value = SDB_DATA_INIT; int status; - switch (OBJ_C(cond)->field) { - case SDB_FIELD_LAST_UPDATE: - obj_value.type = SDB_TYPE_DATETIME; - obj_value.data.datetime = obj->last_update; - break; - case SDB_FIELD_AGE: - obj_value.type = SDB_TYPE_DATETIME; - obj_value.data.datetime = sdb_gettime() - obj->last_update; - break; - case SDB_FIELD_INTERVAL: - obj_value.type = SDB_TYPE_DATETIME; - obj_value.data.datetime = obj->interval; - break; - case SDB_FIELD_BACKEND: - obj_value.type = SDB_TYPE_STRING; - obj_value.data.string = NULL; /* handled separately */ - break; - default: - return INT_MAX; - } - + if (sdb_store_get_field(obj, OBJ_C(cond)->field, &obj_value)) + return INT_MAX; if (sdb_store_expr_eval(OBJ_C(cond)->expr, &value)) return INT_MAX; diff --git a/src/include/core/store.h b/src/include/core/store.h index bad17a2..533f408 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -173,6 +173,21 @@ int sdb_store_service_attr(const char *hostname, const char *service, const char *key, const sdb_data_t *value, sdb_time_t last_update); +/* + * sdb_store_get_field: + * Get the value of a stored object's queryable field. The caller is + * responsible for freeing any dynamically allocated memory possibly stored in + * the returned value. + * + * Note: Retrieving the backend this way is not currently supported. + * + * Returns: + * - 0 on success + * - a negative value else + */ +int +sdb_store_get_field(sdb_store_obj_t *obj, int field, sdb_data_t *res); + /* * Expressions specify arithmetic expressions. * diff --git a/t/unit/core/store_test.c b/t/unit/core/store_test.c index 44e9c96..defa6fc 100644 --- a/t/unit/core/store_test.c +++ b/t/unit/core/store_test.c @@ -501,6 +501,69 @@ START_TEST(test_store_tojson) } END_TEST +START_TEST(test_get_field) +{ + sdb_store_obj_t *host; + sdb_data_t value = SDB_DATA_INIT; + int check; + + sdb_store_host("host", 10); + sdb_store_host("host", 20); + + host = sdb_store_get_host("host"); + fail_unless(host != NULL, + "INTERNAL ERROR: store doesn't have host after adding it"); + + check = sdb_store_get_field(NULL, 0, NULL); + fail_unless(check < 0, + "sdb_store_get_field(NULL, 0, NULL) = %d; expected: <0"); + check = sdb_store_get_field(NULL, SDB_FIELD_LAST_UPDATE, NULL); + fail_unless(check < 0, + "sdb_store_get_field(NULL, SDB_FIELD_LAST_UPDATE, NULL) = %d; " + "expected: <0"); + check = sdb_store_get_field(host, SDB_FIELD_LAST_UPDATE, NULL); + fail_unless(check < 0, + "sdb_store_get_field(, SDB_FIELD_LAST_UPDATE, NULL) = %d; " + "expected: <0"); + check = sdb_store_get_field(NULL, SDB_FIELD_LAST_UPDATE, &value); + fail_unless(check < 0, + "sdb_store_get_field(NULL, SDB_FIELD_LAST_UPDATE, ) = %d; " + "expected: <0"); + + check = sdb_store_get_field(host, SDB_FIELD_LAST_UPDATE, &value); + fail_unless(check == 0, + "sdb_store_get_field(, SDB_FIELD_LAST_UPDATE, ) = " + "%d; expected: 0"); + fail_unless((value.type == SDB_TYPE_DATETIME) + && (value.data.datetime == 20), + "sdb_store_get_field(, SDB_FIELD_LAST_UPDATE, ) " + "returned value {%d, %lu}; expected {%d, 20}", + value.type, value.data.datetime, SDB_TYPE_DATETIME); + + check = sdb_store_get_field(host, SDB_FIELD_AGE, &value); + fail_unless(check == 0, + "sdb_store_get_field(, SDB_FIELD_AGE, ) = " + "%d; expected: 0"); + /* let's assume we're at least in year 1980 ;-) */ + fail_unless((value.type == SDB_TYPE_DATETIME) + && (value.data.datetime > 10L * SDB_INTERVAL_YEAR), + "sdb_store_get_field(, SDB_FIELD_AGE, ) " + "returned value {%d, %lu}; expected {%d, >%lu}", + value.type, value.data.datetime, + SDB_TYPE_DATETIME, 10L * SDB_INTERVAL_YEAR); + + check = sdb_store_get_field(host, SDB_FIELD_INTERVAL, &value); + fail_unless(check == 0, + "sdb_store_get_field(, SDB_FIELD_INTERVAL, ) = " + "%d; expected: 0"); + fail_unless((value.type == SDB_TYPE_DATETIME) + && (value.data.datetime == 10), + "sdb_store_get_field(, SDB_FIELD_INTERVAL, ) " + "returned value {%d, %lu}; expected {%d, 10}", + value.type, value.data.datetime, SDB_TYPE_DATETIME); +} +END_TEST + START_TEST(test_interval) { sdb_store_obj_t *host; @@ -632,6 +695,7 @@ core_store_suite(void) tcase_add_test(tc, test_store_attr); tcase_add_test(tc, test_store_service); tcase_add_test(tc, test_store_service_attr); + tcase_add_test(tc, test_get_field); tcase_add_test(tc, test_interval); tcase_add_test(tc, test_iterate); tcase_add_unchecked_fixture(tc, NULL, sdb_store_clear); -- 2.30.2