summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 99a970f)
raw | patch | inline | side by side (parent: 99a970f)
author | Sebastian Harl <sh@tokkee.org> | |
Tue, 13 Oct 2015 18:27:24 +0000 (20:27 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Tue, 13 Oct 2015 18:27:24 +0000 (20:27 +0200) |
That is, the backend now supports this. The functionality is not yet exposed
via SysQL.
via SysQL.
index ce8f8251dc32851a341013d506d0e748f99d1b5e..a489a665c57ece9d19254611b8ae0832e10b168b 100644 (file)
--- a/src/core/memstore_exec.c
+++ b/src/core/memstore_exec.c
static int
exec_fetch(sdb_memstore_t *store,
sdb_store_writer_t *w, sdb_object_t *wd, sdb_strbuf_t *errbuf,
- int type, const char *hostname, const char *name, bool full,
- sdb_memstore_matcher_t *filter)
+ int type, const char *hostname, int parent_type, const char *parent,
+ const char *name, bool full, sdb_memstore_matcher_t *filter)
{
- sdb_memstore_obj_t *host;
- sdb_memstore_obj_t *obj;
-
+ sdb_memstore_obj_t *host, *p = NULL, *obj;
int status = 0;
- if ((! name) || ((type == SDB_HOST) && hostname)
- || ((type != SDB_HOST) && (! hostname))) {
- /* This is a programming error, not something the client did wrong */
- sdb_strbuf_sprintf(errbuf, "INTERNAL ERROR: invalid "
- "arguments to FETCH(%s, %s, %s)",
- SDB_STORE_TYPE_TO_NAME(type), hostname, name);
- return -1;
- }
if (type == SDB_HOST)
hostname = name;
sdb_object_deref(SDB_OBJ(host));
return -1;
}
- if (type == SDB_HOST) {
- obj = host;
- }
- else {
- obj = sdb_memstore_get_child(host, type, name);
- if ((! obj)
- || (filter && (! sdb_memstore_matcher_matches(filter, obj, NULL)))) {
- sdb_strbuf_sprintf(errbuf, "Failed to fetch %s %s.%s: "
- "%s not found", SDB_STORE_TYPE_TO_NAME(type),
- hostname, name, name);
- if (obj)
- sdb_object_deref(SDB_OBJ(obj));
- sdb_object_deref(SDB_OBJ(host));
- return -1;
+ obj = host;
+ if (type != SDB_HOST) {
+ if (parent) {
+ p = sdb_memstore_get_child(obj, parent_type, parent);
+ if ((! p) || (filter
+ && (! sdb_memstore_matcher_matches(filter, p, NULL)))) {
+ sdb_strbuf_sprintf(errbuf, "Failed to fetch %s %s.%s.%s: "
+ "%s not found", SDB_STORE_TYPE_TO_NAME(type),
+ hostname, parent, name, parent);
+ status = -1;
+ }
+ obj = p;
+ }
+ if (! status) {
+ obj = sdb_memstore_get_child(obj, type, name);
+ if ((! obj) || (filter
+ && (! sdb_memstore_matcher_matches(filter, obj, NULL)))) {
+ sdb_strbuf_sprintf(errbuf, "Failed to fetch %s %s.%s: "
+ "%s not found", SDB_STORE_TYPE_TO_NAME(type),
+ hostname, name, name);
+ status = -1;
+ }
}
- sdb_object_deref(SDB_OBJ(host));
}
- host = NULL;
- if (type != SDB_HOST)
- status = sdb_memstore_emit(obj->parent, w, wd);
if (! status) {
- if (full)
- status = sdb_memstore_emit_full(obj, filter, w, wd);
- else
- status = sdb_memstore_emit(obj, w, wd);
- }
- if (status) {
- sdb_log(SDB_LOG_ERR, "memstore: Failed to serialize "
- "%s %s.%s to JSON", SDB_STORE_TYPE_TO_NAME(type),
- hostname, name);
- sdb_strbuf_sprintf(errbuf, "Out of memory");
- sdb_object_deref(SDB_OBJ(obj));
- return -1;
+ if (type != SDB_HOST)
+ status = sdb_memstore_emit(host, w, wd);
+ if ((! status) && parent)
+ status = sdb_memstore_emit(p, w, wd);
+ if (! status) {
+ if (full)
+ status = sdb_memstore_emit_full(obj, filter, w, wd);
+ else
+ status = sdb_memstore_emit(obj, w, wd);
+ }
+ if (status) {
+ sdb_log(SDB_LOG_ERR, "memstore: Failed to serialize "
+ "%s %s.%s to JSON", SDB_STORE_TYPE_TO_NAME(type),
+ hostname, name);
+ sdb_strbuf_sprintf(errbuf, "Out of memory");
+ status = -1;
+ }
}
+ if (host != obj)
+ sdb_object_deref(SDB_OBJ(host));
+ if (p != obj)
+ sdb_object_deref(SDB_OBJ(p));
sdb_object_deref(SDB_OBJ(obj));
+
+ if (status)
+ return status;
return SDB_CONNECTION_DATA;
} /* exec_fetch */
ast = q->ast;
switch (ast->type) {
case SDB_AST_TYPE_FETCH:
- return exec_fetch(store, w, wd, errbuf, SDB_AST_FETCH(ast)->obj_type,
- SDB_AST_FETCH(ast)->hostname, SDB_AST_FETCH(ast)->name,
- SDB_AST_FETCH(ast)->full, q->filter);
+ return exec_fetch(store, w, wd, errbuf,
+ SDB_AST_FETCH(ast)->obj_type, SDB_AST_FETCH(ast)->hostname,
+ SDB_AST_FETCH(ast)->parent_type, SDB_AST_FETCH(ast)->parent,
+ SDB_AST_FETCH(ast)->name, SDB_AST_FETCH(ast)->full, q->filter);
case SDB_AST_TYPE_LIST:
return exec_list(store, w, wd, errbuf, SDB_AST_LIST(ast)->obj_type,
diff --git a/src/frontend/query.c b/src/frontend/query.c
index 28e1e31c2b006fc7fb947e073456f7c5afa79df3..4ae4f64a5e0a1373f5ff6ddfb416c277aa546f36 100644 (file)
--- a/src/frontend/query.c
+++ b/src/frontend/query.c
ast = sdb_ast_fetch_create((int)type,
hostname[0] ? strdup(hostname) : NULL,
+ -1, NULL,
name[0] ? strdup(name) : NULL,
/* full */ 1, /* filter = */ NULL);
status = exec_cmd(conn, ast);
index 0736876ae1b464d0100958ad04c73b41a08e31b6..01446abbd84b86e4b0395e2715f700fbad04a9dd 100644 (file)
--- a/src/include/parser/ast.h
+++ b/src/include/parser/ast.h
sdb_ast_node_t super;
int obj_type;
char *hostname; /* optional */
+ int parent_type; /* optional */
+ char *parent; /* optional */
char *name;
/* whether to include the full object, that is,
* including all attributes and all children */
} sdb_ast_fetch_t;
#define SDB_AST_FETCH(obj) ((sdb_ast_fetch_t *)(obj))
#define SDB_AST_FETCH_INIT \
- { { SDB_OBJECT_INIT, SDB_AST_TYPE_FETCH, -1 }, -1, NULL, NULL, 0, NULL }
+ { { SDB_OBJECT_INIT, SDB_AST_TYPE_FETCH, -1 }, -1, NULL, -1, NULL, NULL, 0, NULL }
/*
* sdb_ast_list_t represents a LIST command.
* takes ownership of the strings and the filter node.
*/
sdb_ast_node_t *
-sdb_ast_fetch_create(int obj_type, char *hostname, char *name, bool full,
- sdb_ast_node_t *filter);
+sdb_ast_fetch_create(int obj_type, char *hostname,
+ int parent_type, char *parent, char *name,
+ bool full, sdb_ast_node_t *filter);
/*
* sdb_ast_list_create:
diff --git a/src/parser/analyzer.c b/src/parser/analyzer.c
index ecae40f890c2842d82f92d701ab0a8e3137025f9..4adeafc66f02651bbc85c665059503647d792ffb 100644 (file)
--- a/src/parser/analyzer.c
+++ b/src/parser/analyzer.c
r);
} /* iter_error */
+/*
+ * generic checks
+ */
+
+typedef struct {
+ int obj_type;
+ const char *hostname;
+ int parent_type;
+ const char *parent;
+ const char *name;
+} parent_child_t;
+
+static int
+analyze_parent_child(const char *cmd, parent_child_t *pc, sdb_strbuf_t *errbuf)
+{
+ if ((pc->obj_type != SDB_ATTRIBUTE)
+ && (! VALID_OBJ_TYPE(pc->obj_type))) {
+ sdb_strbuf_sprintf(errbuf, "Invalid object type %#x "
+ "in %s command", pc->obj_type, cmd);
+ return -1;
+ }
+ if (! pc->name) {
+ sdb_strbuf_sprintf(errbuf, "Missing object name in "
+ "%s %s command", cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type));
+ return -1;
+ }
+
+ if ((pc->obj_type == SDB_HOST) && pc->hostname) {
+ sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' "
+ "in %s HOST command", pc->hostname, cmd);
+ return -1;
+ }
+ else if ((pc->obj_type != SDB_HOST) && (! pc->hostname)) {
+ sdb_strbuf_sprintf(errbuf, "Missing parent hostname for '%s' "
+ "in %s %s command", pc->name,
+ cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type));
+ return -1;
+ }
+
+ if (pc->obj_type == SDB_ATTRIBUTE) {
+ if ((pc->parent_type <= 0) && pc->parent) {
+ sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' "
+ "in %s %s command", pc->parent,
+ cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type));
+ return -1;
+ }
+ else if (pc->parent_type > 0) {
+ if (! VALID_OBJ_TYPE(pc->parent_type)) {
+ sdb_strbuf_sprintf(errbuf, "Invalid parent type %#x "
+ "in %s %s command", pc->parent_type,
+ cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type));
+ return -1;
+ }
+ if (! pc->parent) {
+ sdb_strbuf_sprintf(errbuf, "Missing %s parent name "
+ "in %s %s command",
+ SDB_STORE_TYPE_TO_NAME(pc->parent_type),
+ cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type));
+ return -1;
+ }
+ }
+ }
+ else if ((pc->parent_type > 0) || pc->parent) {
+ sdb_strbuf_sprintf(errbuf, "Unexpected %s parent name '%s' "
+ "in %s %s command",
+ SDB_STORE_TYPE_TO_NAME(pc->parent_type),
+ pc->parent ? pc->parent : "<unknown>",
+ cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type));
+ return -1;
+ }
+ return 0;
+} /* analyze_parent_child */
+
/*
* expression nodes
*/
static int
analyze_fetch(sdb_ast_fetch_t *fetch, sdb_strbuf_t *errbuf)
{
- if (! VALID_OBJ_TYPE(fetch->obj_type)) {
- sdb_strbuf_sprintf(errbuf, "Invalid object type %#x "
- "in FETCH command", fetch->obj_type);
- return -1;
- }
- if (! fetch->name) {
- sdb_strbuf_sprintf(errbuf, "Missing object name in "
- "FETCH %s command", SDB_STORE_TYPE_TO_NAME(fetch->obj_type));
- return -1;
- }
+ parent_child_t pc = {
+ fetch->obj_type, fetch->hostname,
+ fetch->parent_type, fetch->parent, fetch->name,
+ };
- if ((fetch->obj_type == SDB_HOST) && fetch->hostname) {
- sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' "
- "in FETCH HOST command", fetch->hostname);
+ if (analyze_parent_child("FETCH", &pc, errbuf))
return -1;
- }
- else if ((fetch->obj_type != SDB_HOST) && (! fetch->hostname)) {
- sdb_strbuf_sprintf(errbuf, "Missing parent hostname for '%s' "
- "in FETCH %s command", fetch->name,
- SDB_STORE_TYPE_TO_NAME(fetch->obj_type));
- return -1;
- }
if (fetch->filter)
return analyze_node(FILTER_CTX, fetch->filter, errbuf);
static int
analyze_store(sdb_ast_store_t *st, sdb_strbuf_t *errbuf)
{
- if ((st->obj_type != SDB_ATTRIBUTE)
- && (! VALID_OBJ_TYPE(st->obj_type))) {
- sdb_strbuf_sprintf(errbuf, "Invalid object type %#x "
- "in STORE command", st->obj_type);
- return -1;
- }
- if (! st->name) {
- sdb_strbuf_sprintf(errbuf, "Missing object name in "
- "STORE %s command", SDB_STORE_TYPE_TO_NAME(st->obj_type));
- return -1;
- }
-
- if ((st->obj_type == SDB_HOST) && st->hostname) {
- sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' "
- "in STORE HOST command", st->hostname);
- return -1;
- }
- else if ((st->obj_type != SDB_HOST) && (! st->hostname)) {
- sdb_strbuf_sprintf(errbuf, "Missing parent hostname for '%s' "
- "in STORE %s command", st->name,
- SDB_STORE_TYPE_TO_NAME(st->obj_type));
- return -1;
- }
+ parent_child_t pc = {
+ st->obj_type, st->hostname,
+ st->parent_type, st->parent, st->name,
+ };
- if (st->obj_type == SDB_ATTRIBUTE) {
- if ((st->parent_type <= 0) && st->parent) {
- sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' "
- "in STORE %s command", st->parent,
- SDB_STORE_TYPE_TO_NAME(st->obj_type));
- return -1;
- }
- else if (st->parent_type > 0) {
- if (! VALID_OBJ_TYPE(st->parent_type)) {
- sdb_strbuf_sprintf(errbuf, "Invalid parent type %#x "
- "in STORE %s command", st->parent_type,
- SDB_STORE_TYPE_TO_NAME(st->obj_type));
- return -1;
- }
- if (! st->parent) {
- sdb_strbuf_sprintf(errbuf, "Missing %s parent name "
- "in STORE %s command",
- SDB_STORE_TYPE_TO_NAME(st->parent_type),
- SDB_STORE_TYPE_TO_NAME(st->obj_type));
- return -1;
- }
- }
- }
- else if ((st->parent_type > 0) || st->parent) {
- sdb_strbuf_sprintf(errbuf, "Unexpected %s parent name '%s' "
- "in STORE %s command",
- SDB_STORE_TYPE_TO_NAME(st->parent_type),
- st->parent ? st->parent : "<unknown>",
- SDB_STORE_TYPE_TO_NAME(st->obj_type));
+ if (analyze_parent_child("STORE", &pc, errbuf))
return -1;
- }
if (st->obj_type == SDB_METRIC) {
if ((! st->store_type) != (! st->store_id)) {
diff --git a/src/parser/ast.c b/src/parser/ast.c
index 43fcd41f0464a19c2c7fb559556b736193feb084..dcfe7862bd0b73c891ea017796a28cc626cf0589 100644 (file)
--- a/src/parser/ast.c
+++ b/src/parser/ast.c
sdb_ast_fetch_t *fetch = SDB_AST_FETCH(obj);
if (fetch->hostname)
free(fetch->hostname);
+ if (fetch->parent)
+ free(fetch->parent);
if (fetch->name)
free(fetch->name);
fetch->hostname = fetch->name = NULL;
} /* sdb_ast_value_create */
sdb_ast_node_t *
-sdb_ast_fetch_create(int obj_type, char *hostname, char *name, bool full,
- sdb_ast_node_t *filter)
+sdb_ast_fetch_create(int obj_type, char *hostname,
+ int parent_type, char *parent, char *name,
+ bool full, sdb_ast_node_t *filter)
{
sdb_ast_fetch_t *fetch;
fetch = SDB_AST_FETCH(sdb_object_create("FETCH", fetch_type));
fetch->obj_type = obj_type;
fetch->hostname = hostname;
+ fetch->parent_type = parent_type;
+ fetch->parent = parent;
fetch->name = name;
fetch->full = full;
fetch->filter = filter;
diff --git a/src/parser/grammar.y b/src/parser/grammar.y
index b94300af2d47991b3ca27f5424320e0b1bcc8871..c350d54365a03c5d9d8cb9faaf00234064f4ace5 100644 (file)
--- a/src/parser/grammar.y
+++ b/src/parser/grammar.y
fetch_statement:
FETCH object_type STRING filter_clause
{
- $$ = sdb_ast_fetch_create($2, NULL, $3, 1, $4);
+ $$ = sdb_ast_fetch_create($2, NULL, -1, NULL, $3, 1, $4);
CK_OOM($$);
}
|
FETCH object_type STRING '.' STRING filter_clause
{
- $$ = sdb_ast_fetch_create($2, $3, $5, 1, $6);
+ $$ = sdb_ast_fetch_create($2, $3, -1, NULL, $5, 1, $6);
CK_OOM($$);
}
;