X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Fcore%2Fmemstore_exec.c;h=a489a665c57ece9d19254611b8ae0832e10b168b;hp=ce8f8251dc32851a341013d506d0e748f99d1b5e;hb=07dada8e5c614f0ef90fed8e86183ba7acd0e6e8;hpb=99a970fdf911d6885750508044153c920620423f diff --git a/src/core/memstore_exec.c b/src/core/memstore_exec.c index ce8f825..a489a66 100644 --- a/src/core/memstore_exec.c +++ b/src/core/memstore_exec.c @@ -86,22 +86,12 @@ lookup_tojson(sdb_memstore_obj_t *obj, sdb_memstore_matcher_t *filter, 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; @@ -114,43 +104,59 @@ exec_fetch(sdb_memstore_t *store, 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 */ @@ -209,9 +215,10 @@ sdb_memstore_query_execute(sdb_memstore_t *store, sdb_memstore_query_t *q, 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,