Code

frontend: Added simple 'LOOKUP <type> WHERE <expression>' query.
[sysdb.git] / src / frontend / grammar.y
index 876f48a04a2d718864020473304e30d34ca0848a..50bb00e7f632fa35abb283ca7025b0c02a80a908 100644 (file)
 
 %{
 
-#include "frontend/connection.h"
+#include "frontend/connection-private.h"
 #include "frontend/parser.h"
 #include "frontend/grammar.h"
 
+#include "core/store.h"
+
 #include "utils/error.h"
 #include "utils/llist.h"
 
 #include <stdio.h>
+#include <string.h>
+
+int
+sdb_fe_yylex(YYSTYPE *yylval, YYLTYPE *yylloc, sdb_fe_yyscan_t yyscanner);
 
 sdb_fe_yyextra_t *
 sdb_fe_yyget_extra(sdb_fe_yyscan_t scanner);
@@ -45,6 +51,9 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
 /* quick access to the current parse tree */
 #define pt sdb_fe_yyget_extra(scanner)->parsetree
 
+/* quick access to the parser mode */
+#define parser_mode sdb_fe_yyget_extra(scanner)->mode
+
 %}
 
 %pure-parser
@@ -56,6 +65,8 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
 %name-prefix="sdb_fe_yy"
 
 %union {
+       char *str;
+
        sdb_llist_t     *list;
        sdb_conn_node_t *node;
 }
@@ -64,18 +75,31 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
 
 %token SCANNER_ERROR
 
-%token IDENTIFIER
-%token <node> LIST
+%token WHERE
+
+%token <str> IDENTIFIER STRING
+%token <node> FETCH LIST LOOKUP
 
 %type <list> statements
 %type <node> statement
+       fetch_statement
        list_statement
+       lookup_statement
+       expression
 
 %%
 
 statements:
        statements ';' statement
                {
+                       /* only accept this in default parse mode */
+                       if (parser_mode != SDB_PARSE_DEFAULT) {
+                               sdb_fe_yyerror(&yylloc, scanner,
+                                               YY_("syntax error, unexpected statement, "
+                                                       "expecting expression"));
+                               YYABORT;
+                       }
+
                        if ($3) {
                                sdb_llist_append(pt, SDB_OBJ($3));
                                sdb_object_deref(SDB_OBJ($3));
@@ -84,6 +108,30 @@ statements:
        |
        statement
                {
+                       /* only accept this in default parse mode */
+                       if (parser_mode != SDB_PARSE_DEFAULT) {
+                               sdb_fe_yyerror(&yylloc, scanner,
+                                               YY_("syntax error, unexpected statement, "
+                                                       "expecting expression"));
+                               YYABORT;
+                       }
+
+                       if ($1) {
+                               sdb_llist_append(pt, SDB_OBJ($1));
+                               sdb_object_deref(SDB_OBJ($1));
+                       }
+               }
+       |
+       expression
+               {
+                       /* only accept this in expression parse mode */
+                       if (! (parser_mode & SDB_PARSE_EXPR)) {
+                               sdb_fe_yyerror(&yylloc, scanner,
+                                               YY_("syntax error, unexpected expression, "
+                                                       "expecting statement"));
+                               YYABORT;
+                       }
+
                        if ($1) {
                                sdb_llist_append(pt, SDB_OBJ($1));
                                sdb_object_deref(SDB_OBJ($1));
@@ -92,19 +140,87 @@ statements:
        ;
 
 statement:
+       fetch_statement
+       |
        list_statement
        |
+       lookup_statement
+       |
        /* empty */
                {
                        $$ = NULL;
                }
        ;
 
+/*
+ * FETCH <hostname>;
+ *
+ * Retrieve detailed information about a single host.
+ */
+fetch_statement:
+       FETCH STRING
+               {
+                       $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
+                                               conn_fetch_t, conn_fetch_destroy));
+                       CONN_FETCH($$)->name = strdup($2);
+                       $$->cmd = CONNECTION_FETCH;
+                       free($2);
+                       $2 = NULL;
+               }
+       ;
+
+/*
+ * LIST;
+ *
+ * Returns a list of all hosts in the store.
+ */
 list_statement:
        LIST
                {
-                       $$ = sdb_object_create_T(/* name = */ NULL, sdb_conn_node_t);
-                       ((sdb_conn_node_t *)$$)->cmd = CONNECTION_LIST;
+                       $$ = SDB_CONN_NODE(sdb_object_create_T(/* name = */ NULL,
+                                               sdb_conn_node_t));
+                       $$->cmd = CONNECTION_LIST;
+               }
+       ;
+
+/*
+ * LOOKUP <type> WHERE <expression>;
+ *
+ * Returns detailed information about <type> matching expression.
+ */
+lookup_statement:
+       LOOKUP IDENTIFIER WHERE expression
+               {
+                       /* TODO: support other types as well */
+                       if (strcasecmp($2, "hosts")) {
+                               char errmsg[strlen($2) + 32];
+                               snprintf(errmsg, sizeof(errmsg),
+                                               YY_("unknown table %s"), $2);
+                               sdb_fe_yyerror(&yylloc, scanner, errmsg);
+                               YYABORT;
+                       }
+
+                       $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
+                                               conn_lookup_t, conn_lookup_destroy));
+                       CONN_LOOKUP($$)->matcher = CONN_MATCHER($4);
+                       $$->cmd = CONNECTION_LOOKUP;
+                       free($2);
+                       $2 = NULL;
+               }
+       ;
+
+expression:
+       STRING
+               {
+                       $$ = SDB_CONN_NODE(sdb_object_create_T(/* name = */ NULL,
+                                               conn_node_matcher_t));
+                       $$->cmd = CONNECTION_EXPR;
+                       /* XXX: this is just a placeholder for now */
+                       CONN_MATCHER($$)->matcher = sdb_store_host_matcher($1,
+                                       /* name_re = */ NULL, /* service = */ NULL,
+                                       /* attr = */ NULL);
+                       free($1);
+                       $1 = NULL;
                }
        ;