Code

store: Use a separate type for prepared querys.
authorSebastian Harl <sh@tokkee.org>
Mon, 18 May 2015 19:04:18 +0000 (21:04 +0200)
committerSebastian Harl <sh@tokkee.org>
Mon, 18 May 2015 19:04:18 +0000 (21:04 +0200)
It's sufficiently different from the general matchers/filters approach to not
benefit from sharing a base type.

src/core/store-private.h
src/core/store_exec.c
src/core/store_query.c
src/frontend/query.c
src/include/core/store.h
t/unit/parser/parser_test.c

index 060ec7b..dfa3e84 100644 (file)
@@ -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
index 949f9ff..6c68dc5 100644 (file)
@@ -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) {
index 88b076a..9855063 100644 (file)
@@ -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 : */
index 149750b..7fcdbe2 100644 (file)
@@ -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;
 
index 179b5d0..fb59c7c 100644 (file)
@@ -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);
 
 /*
index f363dc2..cbcbe2c 100644 (file)
@@ -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: <m>",
+       q = sdb_store_query_prepare(node);
+       fail_unless(q != NULL,
+                       "sdb_store_query_prepare(AST<%s>) = NULL; expected: <query>",
                        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);
 }