From: Sebastian Harl Date: Mon, 18 May 2015 19:04:18 +0000 (+0200) Subject: store: Use a separate type for prepared querys. X-Git-Tag: sysdb-0.8.0~92 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=29aa1f75c4840710671488420208a2e029a308a9;ds=sidebyside store: Use a separate type for prepared querys. It's sufficiently different from the general matchers/filters approach to not benefit from sharing a base type. --- diff --git a/src/core/store-private.h b/src/core/store-private.h index 060ec7b..dfa3e84 100644 --- a/src/core/store-private.h +++ b/src/core/store-private.h @@ -103,6 +103,18 @@ typedef struct { #define _last_update super.last_update #define _interval super.interval +/* + * querying + */ + +struct sdb_store_query { + sdb_object_t super; + sdb_ast_node_t *ast; + sdb_store_matcher_t *matcher; + sdb_store_matcher_t *filter; +}; +#define QUERY(m) ((sdb_store_query_t *)(m)) + /* * expressions */ @@ -240,14 +252,6 @@ typedef struct { } isnull_matcher_t; #define ISNULL_M(m) ((isnull_matcher_t *)(m)) -typedef struct { - sdb_store_matcher_t super; - sdb_ast_node_t *ast; - sdb_store_matcher_t *matcher; - sdb_store_matcher_t *filter; -} query_matcher_t; -#define QUERY_M(m) ((query_matcher_t *)(m)) - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/core/store_exec.c b/src/core/store_exec.c index 949f9ff..6c68dc5 100644 --- a/src/core/store_exec.c +++ b/src/core/store_exec.c @@ -324,36 +324,33 @@ exec_timeseries(sdb_strbuf_t *buf, sdb_strbuf_t *errbuf, */ int -sdb_store_query_execute(sdb_store_matcher_t *m, +sdb_store_query_execute(sdb_store_query_t *m, sdb_strbuf_t *buf, sdb_strbuf_t *errbuf) { sdb_timeseries_opts_t ts_opts; sdb_ast_node_t *ast; - if ((! m) || (m->type != MATCHER_QUERY)) { - int t = m ? m-> type : -1; - sdb_log(SDB_LOG_ERR, "store: Invalid query of type %s", MATCHER_SYM(t)); + if (! m) return -1; - } - if (! QUERY_M(m)->ast) { + if (! QUERY(m)->ast) { sdb_log(SDB_LOG_ERR, "store: Invalid empty query"); return -1; } - ast = QUERY_M(m)->ast; + ast = QUERY(m)->ast; switch (ast->type) { case SDB_AST_TYPE_FETCH: return exec_fetch(buf, errbuf, SDB_AST_FETCH(ast)->obj_type, SDB_AST_FETCH(ast)->hostname, SDB_AST_FETCH(ast)->name, - QUERY_M(m)->filter); + QUERY(m)->filter); case SDB_AST_TYPE_LIST: return exec_list(buf, errbuf, SDB_AST_LIST(ast)->obj_type, - QUERY_M(m)->filter); + QUERY(m)->filter); case SDB_AST_TYPE_LOOKUP: return exec_lookup(buf, errbuf, SDB_AST_LOOKUP(ast)->obj_type, - QUERY_M(m)->matcher, QUERY_M(m)->filter); + QUERY(m)->matcher, QUERY(m)->filter); case SDB_AST_TYPE_STORE: if (ast->type != SDB_AST_TYPE_STORE) { diff --git a/src/core/store_query.c b/src/core/store_query.c index 88b076a..9855063 100644 --- a/src/core/store_query.c +++ b/src/core/store_query.c @@ -265,18 +265,16 @@ node_to_matcher(sdb_ast_node_t *n) } /* node_to_matcher */ /* - * matcher type + * query type */ static int -query_matcher_init(sdb_object_t *obj, va_list ap) +query_init(sdb_object_t *obj, va_list ap) { sdb_ast_node_t *ast = va_arg(ap, sdb_ast_node_t *); sdb_ast_node_t *matcher = NULL, *filter = NULL; - M(obj)->type = MATCHER_QUERY; - - QUERY_M(obj)->ast = ast; + QUERY(obj)->ast = ast; sdb_object_ref(SDB_OBJ(ast)); switch (ast->type) { @@ -302,43 +300,43 @@ query_matcher_init(sdb_object_t *obj, va_list ap) } if (matcher) { - QUERY_M(obj)->matcher = node_to_matcher(matcher); - if (! QUERY_M(obj)->matcher) + QUERY(obj)->matcher = node_to_matcher(matcher); + if (! QUERY(obj)->matcher) return -1; } if (filter) { - QUERY_M(obj)->filter = node_to_matcher(filter); - if (! QUERY_M(obj)->filter) + QUERY(obj)->filter = node_to_matcher(filter); + if (! QUERY(obj)->filter) return -1; } return 0; -} /* query_matcher_init */ +} /* query_init */ static void -query_matcher_destroy(sdb_object_t *obj) +query_destroy(sdb_object_t *obj) { - sdb_object_deref(SDB_OBJ(QUERY_M(obj)->ast)); - sdb_object_deref(SDB_OBJ(QUERY_M(obj)->matcher)); - sdb_object_deref(SDB_OBJ(QUERY_M(obj)->filter)); -} /* query_matcher_destroy */ + sdb_object_deref(SDB_OBJ(QUERY(obj)->ast)); + sdb_object_deref(SDB_OBJ(QUERY(obj)->matcher)); + sdb_object_deref(SDB_OBJ(QUERY(obj)->filter)); +} /* query_destroy */ static sdb_type_t query_type = { - /* size = */ sizeof(query_matcher_t), - /* init = */ query_matcher_init, - /* destroy = */ query_matcher_destroy, + /* size = */ sizeof(sdb_store_query_t), + /* init = */ query_init, + /* destroy = */ query_destroy, }; /* * public API */ -sdb_store_matcher_t * +sdb_store_query_t * sdb_store_query_prepare(sdb_ast_node_t *ast) { if (! ast) return NULL; - return M(sdb_object_create(SDB_AST_TYPE_TO_STRING(ast), query_type, ast)); + return QUERY(sdb_object_create(SDB_AST_TYPE_TO_STRING(ast), query_type, ast)); } /* sdb_store_query_prepare */ /* vim: set tw=78 sw=4 ts=4 noexpandtab : */ diff --git a/src/frontend/query.c b/src/frontend/query.c index 149750b..7fcdbe2 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -69,7 +69,7 @@ sdb_fe_query(sdb_conn_t *conn) sdb_llist_t *parsetree; sdb_ast_node_t *ast = NULL; - sdb_store_matcher_t *q; + sdb_store_query_t *q; sdb_strbuf_t *buf = NULL; int status = 0; diff --git a/src/include/core/store.h b/src/include/core/store.h index 179b5d0..fb59c7c 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -360,15 +360,35 @@ int sdb_store_get_attr(sdb_store_obj_t *obj, const char *name, sdb_data_t *res, sdb_store_matcher_t *filter); +/* + * Querying a store: + * + * - Query interface: A query is a formal description of an interaction with + * the store. It can be used, both, for read and write access. The query is + * described by its abstract syntax tree (AST). The parser package provides + * means to parse a string (SysQL) representation of the query into an AST. + * + * - Matcher / expression interface: This low-level interface provides direct + * control over how to access the store. It is used by the query + * implementation internally and can only be used for read access. + */ + +/* + * sdb_store_query_t: + * A parsed query readily prepared for execution. + */ +struct sdb_store_query; +typedef struct sdb_store_query sdb_store_query_t; + /* * sdb_store_query_prepare: * Prepare the query described by 'ast' for execution in a store. * * Returns: - * - a store matcher on success + * - a store query on success * - NULL else */ -sdb_store_matcher_t * +sdb_store_query_t * sdb_store_query_prepare(sdb_ast_node_t *ast); /* @@ -381,7 +401,7 @@ sdb_store_query_prepare(sdb_ast_node_t *ast); * - a negative value on error */ int -sdb_store_query_execute(sdb_store_matcher_t *m, +sdb_store_query_execute(sdb_store_query_t *m, sdb_strbuf_t *buf, sdb_strbuf_t *errbuf); /* diff --git a/t/unit/parser/parser_test.c b/t/unit/parser/parser_test.c index f363dc2..cbcbe2c 100644 --- a/t/unit/parser/parser_test.c +++ b/t/unit/parser/parser_test.c @@ -635,7 +635,7 @@ START_TEST(test_parse) sdb_strbuf_t *errbuf = sdb_strbuf_create(64); sdb_llist_t *check; sdb_ast_node_t *node; - sdb_store_matcher_t *m; + sdb_store_query_t *q; _Bool ok; check = sdb_parser_parse(parse_data[_i].query, @@ -698,13 +698,13 @@ START_TEST(test_parse) } /* TODO: this should move into front-end specific tests */ - m = sdb_store_query_prepare(node); - fail_unless(m != NULL, - "sdb_store_query_prepare(AST<%s>) = NULL; expected: ", + q = sdb_store_query_prepare(node); + fail_unless(q != NULL, + "sdb_store_query_prepare(AST<%s>) = NULL; expected: ", parse_data[_i].query); sdb_object_deref(SDB_OBJ(node)); - sdb_object_deref(SDB_OBJ(m)); + sdb_object_deref(SDB_OBJ(q)); sdb_llist_destroy(check); sdb_strbuf_destroy(errbuf); }