Code

frontend/parser: Let ‘LIST’ and ‘FETCH’ accept optional filters as well.
authorSebastian Harl <sh@tokkee.org>
Sat, 2 Aug 2014 20:16:59 +0000 (22:16 +0200)
committerSebastian Harl <sh@tokkee.org>
Sat, 2 Aug 2014 20:16:59 +0000 (22:16 +0200)
This allows for more consistent results across different types of queries.

src/frontend/connection-private.h
src/frontend/grammar.y
src/frontend/query.c
t/unit/frontend/parser_test.c

index 1d4e019a01fe45db4d464c9bd387a2258d04b83d..0126e892b1774f2071f255a0362ebb9404d77ef3 100644 (file)
@@ -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
index a444423b409ce6854190b5d9e9ef7812fe702a5a..a2ae448cc744166875afd8e0f4904b5a186ad5cf 100644 (file)
@@ -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;
                }
        ;
index 50f0fed6bb4997856e8692e2a994ab185ee94734..a30bee3e4b8f274730ff650d2ca84cc168fee58d 100644 (file)
@@ -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);
index 1b5cb242e9c94b3bc4c45eb3e4e638f6f5702d44..bca86452dffc44afe22f2fb5b3418eaa7e6f42f3 100644 (file)
@@ -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 },