summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7f29e5a)
raw | patch | inline | side by side (parent: 7f29e5a)
author | Sebastian Harl <sh@tokkee.org> | |
Tue, 1 Apr 2014 20:45:19 +0000 (22:45 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Tue, 1 Apr 2014 20:45:19 +0000 (22:45 +0200) |
This query command may be used to retrieve a list of detailed host information
for each host matching the specified expression. For now, querying hosts is
supported only.
for each host matching the specified expression. For now, querying hosts is
supported only.
index 534d3cbd3978d3ca43707aba0a071ad9bdd9281d..f2d85f2ccdfd177e461032421a90eb181f870fdc 100644 (file)
} conn_node_matcher_t;
#define CONN_MATCHER(obj) ((conn_node_matcher_t *)(obj))
+typedef struct {
+ sdb_conn_node_t super;
+ conn_node_matcher_t *matcher;
+} conn_lookup_t;
+#define CONN_LOOKUP(obj) ((conn_lookup_t *)(obj))
+
/*
* type helper functions
*/
free(CONN_FETCH(obj)->name);
} /* conn_fetch_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));
+} /* conn_fetch_destroy */
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 3802c9c97de1aa70c8d387acd99df728c70ed0bb..50bb00e7f632fa35abb283ca7025b0c02a80a908 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
%token SCANNER_ERROR
+%token WHERE
+
%token <str> IDENTIFIER STRING
-%token <node> FETCH LIST
+%token <node> FETCH LIST LOOKUP
%type <list> statements
%type <node> statement
fetch_statement
list_statement
+ lookup_statement
expression
%%
|
list_statement
|
+ lookup_statement
+ |
/* empty */
{
$$ = NULL;
}
;
+/*
+ * 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
{
diff --git a/src/frontend/query.c b/src/frontend/query.c
index 96c46d28db6f2b3425d90cd1079a363882779983..759b9c9795ebbe86da1c9ab4308c0c641f7e10aa 100644 (file)
--- a/src/frontend/query.c
+++ b/src/frontend/query.c
#include <errno.h>
+/*
+ * private helper functions
+ */
+
+static int
+lookup_tojson(sdb_store_base_t *obj, void *user_data)
+{
+ sdb_strbuf_t *buf = user_data;
+ if (sdb_strbuf_len(buf) > 1)
+ sdb_strbuf_append(buf, ",");
+ return sdb_store_host_tojson(obj, buf, /* flags = */ 0);
+} /* lookup_tojson */
+
/*
* public API
*/
return sdb_fe_fetch(conn, CONN_FETCH(node)->name);
case CONNECTION_LIST:
return sdb_fe_list(conn);
+ case CONNECTION_LOOKUP:
+ return sdb_fe_lookup(conn, CONN_LOOKUP(node)->matcher->matcher);
default:
sdb_log(SDB_LOG_ERR, "frontend: Unknown command %i", node->cmd);
return 0;
} /* sdb_fe_list */
+int
+sdb_fe_lookup(sdb_conn_t *conn, sdb_store_matcher_t *m)
+{
+ sdb_strbuf_t *buf;
+
+ buf = sdb_strbuf_create(1024);
+ if (! buf) {
+ char errbuf[1024];
+ sdb_log(SDB_LOG_ERR, "frontend: Failed to create "
+ "buffer to handle LOOKUP command: %s",
+ sdb_strerror(errno, errbuf, sizeof(errbuf)));
+
+ sdb_strbuf_sprintf(conn->errbuf, "Out of memory");
+ sdb_strbuf_destroy(buf);
+ return -1;
+ }
+
+ sdb_strbuf_append(buf, "[");
+
+ if (sdb_store_lookup(m, lookup_tojson, buf)) {
+ sdb_log(SDB_LOG_ERR, "frontend: Failed to lookup hosts");
+ sdb_strbuf_sprintf(conn->errbuf, "Failed to lookup hosts");
+ sdb_strbuf_destroy(buf);
+ return -1;
+ }
+
+ sdb_strbuf_append(buf, "]");
+
+ sdb_connection_send(conn, CONNECTION_OK,
+ (uint32_t)sdb_strbuf_len(buf), sdb_strbuf_string(buf));
+ sdb_strbuf_destroy(buf);
+ return 0;
+} /* sdb_fe_lookup */
+
/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
diff --git a/src/frontend/scanner.l b/src/frontend/scanner.l
index c0d167c00c0df1da371d8762098acd57c7ce5abc..61f1743fa60560c69f2cf5835f9c49827e760b17 100644 (file)
--- a/src/frontend/scanner.l
+++ b/src/frontend/scanner.l
}
{identifier} {
- /* XXX */
- if (! strcasecmp(yytext, "LIST"))
- return LIST;
- else if (! strcasecmp(yytext, "FETCH"))
+ /* XXX: simplify handling of reserved words */
+ if (! strcasecmp(yytext, "FETCH"))
return FETCH;
+ else if (! strcasecmp(yytext, "LIST"))
+ return LIST;
+ else if (! strcasecmp(yytext, "LOOKUP"))
+ return LOOKUP;
+ else if (! strcasecmp(yytext, "WHERE"))
+ return WHERE;
yylval->str = strdup(yytext);
return IDENTIFIER;
index bf902ddc1761b78c5b56f7b3c4903c8614639c3d..4791a5e4523c61f1d76d56f88c113d1c4ae26382 100644 (file)
#define SDB_FRONTEND_CONNECTION_H 1
#include "frontend/proto.h"
+#include "core/store.h"
#include "utils/llist.h"
#include "utils/strbuf.h"
int
sdb_fe_list(sdb_conn_t *conn);
+/*
+ * sdb_fe_lookup:
+ * Send a list of hosts matching 'm', serialized as JSON, to the client.
+ *
+ * Returns:
+ * - 0 on success
+ * - a negative value else
+ */
+int
+sdb_fe_lookup(sdb_conn_t *conn, sdb_store_matcher_t *m);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
index 132e10c17058d972f4b893ec37cbb6a972c011aa..0f55a7c71d13b5ec80b2d57d5c98db6b2c8af154 100644 (file)
/* query commands */
CONNECTION_FETCH,
CONNECTION_LIST,
+ CONNECTION_LOOKUP,
/* command elements */
CONNECTION_EXPR,