From b4d485cde96751e1ec832d0e75a3e6081006a1a4 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sat, 2 Aug 2014 22:16:59 +0200 Subject: [PATCH] =?utf8?q?frontend/parser:=20Let=20=E2=80=98LIST=E2=80=99?= =?utf8?q?=20and=20=E2=80=98FETCH=E2=80=99=20accept=20optional=20filters?= =?utf8?q?=20as=20well.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This allows for more consistent results across different types of queries. --- src/frontend/connection-private.h | 46 +++++++++++++++++++------------ src/frontend/grammar.y | 10 ++++--- src/frontend/query.c | 14 ++++++---- t/unit/frontend/parser_test.c | 10 +++++++ 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/frontend/connection-private.h b/src/frontend/connection-private.h index 1d4e019..0126e89 100644 --- a/src/frontend/connection-private.h +++ b/src/frontend/connection-private.h @@ -79,18 +79,25 @@ struct sdb_conn { * node types */ -typedef struct { - sdb_conn_node_t super; - char *name; -} conn_fetch_t; -#define CONN_FETCH(obj) ((conn_fetch_t *)(obj)) - typedef struct { sdb_conn_node_t super; sdb_store_matcher_t *matcher; } conn_matcher_t; #define CONN_MATCHER(obj) ((conn_matcher_t *)(obj)) +typedef struct { + sdb_conn_node_t super; + conn_matcher_t *filter; +} conn_list_t; +#define CONN_LIST(obj) ((conn_list_t *)(obj)) + +typedef struct { + sdb_conn_node_t super; + char *name; + conn_matcher_t *filter; +} conn_fetch_t; +#define CONN_FETCH(obj) ((conn_fetch_t *)(obj)) + typedef struct { sdb_conn_node_t super; conn_matcher_t *matcher; @@ -101,27 +108,32 @@ typedef struct { /* * type helper functions */ + +static void __attribute__((unused)) +conn_matcher_destroy(sdb_object_t *obj) +{ + sdb_object_deref(SDB_OBJ(CONN_MATCHER(obj)->matcher)); +} /* conn_matcher_destroy */ + +static void __attribute__((unused)) +conn_list_destroy(sdb_object_t *obj) +{ + sdb_object_deref(SDB_OBJ(CONN_LIST(obj)->filter)); +} /* conn_list_destroy */ + static void __attribute__((unused)) conn_fetch_destroy(sdb_object_t *obj) { if (CONN_FETCH(obj)->name) free(CONN_FETCH(obj)->name); + sdb_object_deref(SDB_OBJ(CONN_FETCH(obj)->filter)); } /* conn_fetch_destroy */ -static void __attribute__((unused)) -conn_matcher_destroy(sdb_object_t *obj) -{ - if (CONN_MATCHER(obj)->matcher) - sdb_object_deref(SDB_OBJ(CONN_MATCHER(obj)->matcher)); -} /* conn_matcher_destroy */ - static void __attribute__((unused)) conn_lookup_destroy(sdb_object_t *obj) { - if (CONN_LOOKUP(obj)->matcher) - sdb_object_deref(SDB_OBJ(CONN_LOOKUP(obj)->matcher)); - if (CONN_LOOKUP(obj)->filter) - sdb_object_deref(SDB_OBJ(CONN_LOOKUP(obj)->filter)); + sdb_object_deref(SDB_OBJ(CONN_LOOKUP(obj)->matcher)); + sdb_object_deref(SDB_OBJ(CONN_LOOKUP(obj)->filter)); } /* conn_lookup_destroy */ #ifdef __cplusplus diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index a444423..a2ae448 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -206,11 +206,12 @@ statement: * Retrieve detailed information about a single host. */ fetch_statement: - FETCH STRING + FETCH STRING filter_clause { $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_fetch_t, conn_fetch_destroy)); CONN_FETCH($$)->name = strdup($2); + CONN_FETCH($$)->filter = CONN_MATCHER($3); $$->cmd = CONNECTION_FETCH; free($2); $2 = NULL; } @@ -222,10 +223,11 @@ fetch_statement: * Returns a list of all hosts in the store. */ list_statement: - LIST + LIST filter_clause { - $$ = SDB_CONN_NODE(sdb_object_create_T(/* name = */ NULL, - sdb_conn_node_t)); + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_list_t, conn_list_destroy)); + CONN_LIST($$)->filter = CONN_MATCHER($2); $$->cmd = CONNECTION_LIST; } ; diff --git a/src/frontend/query.c b/src/frontend/query.c index 50f0fed..a30bee3 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -167,24 +167,26 @@ sdb_fe_lookup(sdb_conn_t *conn) int sdb_fe_exec(sdb_conn_t *conn, sdb_conn_node_t *node) { + sdb_store_matcher_t *m = NULL, *filter = NULL; + if (! node) return -1; switch (node->cmd) { case CONNECTION_FETCH: - return sdb_fe_exec_fetch(conn, CONN_FETCH(node)->name, - /* filter = */ NULL); + if (CONN_FETCH(node)->filter) + filter = CONN_FETCH(node)->filter->matcher; + return sdb_fe_exec_fetch(conn, CONN_FETCH(node)->name, filter); case CONNECTION_LIST: - return sdb_fe_exec_list(conn, /* filter = */ NULL); + if (CONN_LIST(node)->filter) + filter = CONN_LIST(node)->filter->matcher; + return sdb_fe_exec_list(conn, filter); case CONNECTION_LOOKUP: - { - sdb_store_matcher_t *m = NULL, *filter = NULL; if (CONN_LOOKUP(node)->matcher) m = CONN_LOOKUP(node)->matcher->matcher; if (CONN_LOOKUP(node)->filter) filter = CONN_LOOKUP(node)->filter->matcher; return sdb_fe_exec_lookup(conn, m, filter); - } default: sdb_log(SDB_LOG_ERR, "frontend: Unknown command %i", node->cmd); diff --git a/t/unit/frontend/parser_test.c b/t/unit/frontend/parser_test.c index 1b5cb24..bca8645 100644 --- a/t/unit/frontend/parser_test.c +++ b/t/unit/frontend/parser_test.c @@ -53,10 +53,15 @@ START_TEST(test_parse) /* valid commands */ { "FETCH 'host'", -1, 1, CONNECTION_FETCH }, + { "FETCH 'host' FILTER " + "host = 'host'", -1, 1, CONNECTION_FETCH }, + { "LIST", -1, 1, CONNECTION_LIST }, { "LIST -- comment", -1, 1, CONNECTION_LIST }, { "LIST;", -1, 1, CONNECTION_LIST }, { "LIST; INVALID", 5, 1, CONNECTION_LIST }, + { "LIST FILTER " + "host = 'host'", -1, 1, CONNECTION_LIST }, { "LOOKUP hosts", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " @@ -185,6 +190,11 @@ START_TEST(test_parse) { "LIST; INVALID", 8, -1, 0 }, { "/* some incomplete", -1, -1, 0 }, + { "LIST MATCHING " + "host = 'host'", -1, -1, 0 }, + { "FETCH 'host' MATCHING " + "host = 'host'", -1, -1, 0 }, + { "LOOKUP foo", -1, -1, 0 }, { "LOOKUP foo MATCHING " "host = 'host'", -1, -1, 0 }, -- 2.30.2