From c9ed4d2a7a92ef589809a7df9b04c061afa4ef64 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 29 Jan 2014 21:55:58 +0100 Subject: [PATCH] store: Added support for different data-types for attributes. An attribute value is now stored as sdb_data_t, supporting all data-types which are supported by that type. JSON-serialization does not fully support that yet, though. --- src/backend/puppet/store-configs.c | 7 ++++--- src/core/store.c | 28 +++++++++++++--------------- src/include/core/store.h | 4 +++- t/core/store_test.c | 20 +++++++++++++++----- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/backend/puppet/store-configs.c b/src/backend/puppet/store-configs.c index a9a0ff7..e109b30 100644 --- a/src/backend/puppet/store-configs.c +++ b/src/backend/puppet/store-configs.c @@ -87,7 +87,7 @@ sdb_puppet_stcfg_get_attrs(sdb_dbi_client_t __attribute__((unused)) *client, const char *hostname; const char *key; - const char *value; + sdb_data_t value; sdb_time_t last_update; assert(n == 4); @@ -98,10 +98,11 @@ sdb_puppet_stcfg_get_attrs(sdb_dbi_client_t __attribute__((unused)) *client, hostname = data[0].data.string; key = data[1].data.string; - value = data[2].data.string; + value.type = SDB_TYPE_STRING; + value.data.string = data[2].data.string; last_update = data[3].data.datetime; - status = sdb_store_attribute(hostname, key, value, last_update); + status = sdb_store_attribute(hostname, key, &value, last_update); if (status < 0) { sdb_log(SDB_LOG_ERR, "puppet::store-configs backend: Failed to " diff --git a/src/core/store.c b/src/core/store.c index e8d14a0..2522233 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -71,7 +71,7 @@ struct sdb_store_base { typedef struct { sdb_store_base_t super; - char *value; + sdb_data_t value; } sdb_attribute_t; #define SDB_ATTR(obj) ((sdb_attribute_t *)(obj)) #define SDB_CONST_ATTR(obj) ((const sdb_attribute_t *)(obj)) @@ -158,20 +158,19 @@ sdb_store_obj_destroy(sdb_object_t *obj) static int sdb_attr_init(sdb_object_t *obj, va_list ap) { - const char *value; + const sdb_data_t *value; int ret; - /* this will consume the first argument (type) of ap */ + /* this will consume the first two arguments + * (type and last_update) of ap */ ret = store_base_init(obj, ap); if (ret) return ret; - value = va_arg(ap, const char *); + value = va_arg(ap, const sdb_data_t *); - if (value) { - SDB_ATTR(obj)->value = strdup(value); - if (! SDB_ATTR(obj)->value) + if (value) + if (sdb_data_copy(&SDB_ATTR(obj)->value, value)) return -1; - } return 0; } /* sdb_attr_init */ @@ -181,9 +180,7 @@ sdb_attr_destroy(sdb_object_t *obj) assert(obj); store_base_destroy(obj); - - if (SDB_ATTR(obj)->value) - free(SDB_ATTR(obj)->value); + sdb_data_free_datum(&SDB_ATTR(obj)->value); } /* sdb_attr_destroy */ static sdb_type_t sdb_store_obj_type = { @@ -416,8 +413,9 @@ store_obj_tojson(sdb_llist_t *list, int type, sdb_strbuf_t *buf) sdb_strbuf_append(buf, "{\"name\": \"%s\", ", SDB_OBJ(sobj)->name); if (type == SDB_ATTRIBUTE) + /* XXX: this needs to be type-dependent */ sdb_strbuf_append(buf, "\"value\": \"%s\", ", - SDB_ATTR(sobj)->value); + SDB_ATTR(sobj)->value.data.string); sdb_strbuf_append(buf, "\"last_update\": \"%s\"}", time_str); if (sdb_llist_iter_has_next(iter)) @@ -477,7 +475,8 @@ sdb_store_get_host(const char *name) } /* sdb_store_get_host */ int -sdb_store_attribute(const char *hostname, const char *key, const char *value, +sdb_store_attribute(const char *hostname, + const char *key, const sdb_data_t *value, sdb_time_t last_update) { int status; @@ -494,8 +493,7 @@ sdb_store_attribute(const char *hostname, const char *key, const char *value, if (status >= 0) { assert(updated_attr); - SDB_ATTR(updated_attr)->value = strdup(value); - if (! SDB_ATTR(updated_attr)->value) { + if (sdb_data_copy(&SDB_ATTR(updated_attr)->value, value)) { sdb_object_deref(SDB_OBJ(updated_attr)); status = -1; } diff --git a/src/include/core/store.h b/src/include/core/store.h index ab11a21..100aadf 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -30,6 +30,7 @@ #include "sysdb.h" #include "core/object.h" +#include "core/data.h" #include "core/time.h" #include "utils/llist.h" #include "utils/strbuf.h" @@ -95,7 +96,8 @@ sdb_store_get_host(const char *name); * - a negative value on error */ int -sdb_store_attribute(const char *hostname, const char *key, const char *value, +sdb_store_attribute(const char *hostname, + const char *key, const sdb_data_t *value, sdb_time_t last_update); /* diff --git a/t/core/store_test.c b/t/core/store_test.c index effd05a..855c8c0 100644 --- a/t/core/store_test.c +++ b/t/core/store_test.c @@ -147,7 +147,7 @@ START_TEST(test_store_attr) struct { const char *host; const char *key; - const char *value; + char *value; sdb_time_t last_update; int expected; } golden_data[] = { @@ -166,10 +166,15 @@ START_TEST(test_store_attr) sdb_store_host("l", 1); sdb_store_host("m", 1); for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) { + sdb_data_t datum; int status; + /* XXX: test other types as well */ + datum.type = SDB_TYPE_STRING; + datum.data.string = golden_data[i].value; + status = sdb_store_attribute(golden_data[i].host, - golden_data[i].key, golden_data[i].value, + golden_data[i].key, &datum, golden_data[i].last_update); fail_unless(status == golden_data[i].expected, "sdb_store_attribute(%s, %s, %s, %d) = %d; expected: %d", @@ -244,6 +249,7 @@ verify_json_output(sdb_strbuf_t *buf, const char *expected, int flags) START_TEST(test_store_tojson) { sdb_strbuf_t *buf; + sdb_data_t datum; size_t i; struct { @@ -296,9 +302,13 @@ START_TEST(test_store_tojson) sdb_store_host("h1", 1); sdb_store_host("h2", 1); - sdb_store_attribute("h1", "k1", "v1", 1); - sdb_store_attribute("h1", "k2", "v2", 1); - sdb_store_attribute("h1", "k3", "v3", 1); + datum.type = SDB_TYPE_STRING; + datum.data.string = "v1"; + sdb_store_attribute("h1", "k1", &datum, 1); + datum.data.string = "v2"; + sdb_store_attribute("h1", "k2", &datum, 1); + datum.data.string = "v3"; + sdb_store_attribute("h1", "k3", &datum, 1); sdb_store_service("h2", "s1", 1); sdb_store_service("h2", "s2", 1); -- 2.30.2