Code

store: Added sdb_store_get_field().
authorSebastian Harl <sh@tokkee.org>
Thu, 31 Jul 2014 21:07:30 +0000 (23:07 +0200)
committerSebastian Harl <sh@tokkee.org>
Thu, 31 Jul 2014 21:07:30 +0000 (23:07 +0200)
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
src/core/store_lookup.c
src/include/core/store.h
t/unit/core/store_test.c

index ee861d33eedafbbce9906b183bf06df3ffc11cfa..5a00b6c3cd49a7bba31cb8755bf4bda73f9564f8 100644 (file)
@@ -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)
index 124c4514c59170a82e2fb575ccc35583bc8d18e1..1ec1dbb68e702f6c5e4a9722e885f1042494cf38 100644 (file)
@@ -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;
 
index bad17a22be0ba523fb5deaf4044727d093c56ccd..533f4080ec17f049051f19a04b97111d226cfc33 100644 (file)
@@ -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.
  *
index 44e9c96c0bd4ad9aea2aa0232c086e028cbc3492..defa6fcfc45d9aaeb021e3ddffdfe9cadd2dc147 100644 (file)
@@ -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(<host>, 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, <value>) = %d; "
+                       "expected: <0");
+
+       check = sdb_store_get_field(host, SDB_FIELD_LAST_UPDATE, &value);
+       fail_unless(check == 0,
+                       "sdb_store_get_field(<host>, SDB_FIELD_LAST_UPDATE, <value>) = "
+                       "%d; expected: 0");
+       fail_unless((value.type == SDB_TYPE_DATETIME)
+                       && (value.data.datetime == 20),
+                       "sdb_store_get_field(<host>, SDB_FIELD_LAST_UPDATE, <value>) "
+                       "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(<host>, SDB_FIELD_AGE, <value>) = "
+                       "%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(<host>, SDB_FIELD_AGE, <value>) "
+                       "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(<host>, SDB_FIELD_INTERVAL, <value>) = "
+                       "%d; expected: 0");
+       fail_unless((value.type == SDB_TYPE_DATETIME)
+                       && (value.data.datetime == 10),
+                       "sdb_store_get_field(<host>, SDB_FIELD_INTERVAL, <value>) "
+                       "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);