summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 14319a3)
raw | patch | inline | side by side (parent: 14319a3)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 30 Jul 2014 19:02:35 +0000 (21:02 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 30 Jul 2014 19:02:35 +0000 (21:02 +0200) |
The new syntax is 'LOOKUP <obj> MATCHING <cond> [FILTER <cond>]'.
index ae9cbbc91ba0cfa2dd532cb55795de95164a96fe..1d4e019a01fe45db4d464c9bd387a2258d04b83d 100644 (file)
typedef struct {
sdb_conn_node_t super;
sdb_store_matcher_t *matcher;
-} conn_node_matcher_t;
-#define CONN_MATCHER(obj) ((conn_node_matcher_t *)(obj))
+} conn_matcher_t;
+#define CONN_MATCHER(obj) ((conn_matcher_t *)(obj))
typedef struct {
sdb_conn_node_t super;
- conn_node_matcher_t *matcher;
+ conn_matcher_t *matcher;
+ conn_matcher_t *filter;
} conn_lookup_t;
#define CONN_LOOKUP(obj) ((conn_lookup_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));
} /* conn_lookup_destroy */
#ifdef __cplusplus
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 57174290b00dc97c00aa50d9e1d6841ff45f3dad..92bfd1f5c60d2ab24d5e0b6f82b90e7e4ce73c71 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
%token SCANNER_ERROR
-%token AND OR IS NOT MATCHING
+%token AND OR IS NOT MATCHING FILTER
%token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX
%token CMP_LT CMP_LE CMP_GE CMP_GT
%token CONCAT
;
/*
- * LOOKUP <type> MATCHING <condition>;
+ * LOOKUP <type> MATCHING <condition> [FILTER <condition>];
*
* Returns detailed information about <type> matching condition.
*/
$$->cmd = CONNECTION_LOOKUP;
free($2); $2 = NULL;
}
+ |
+ LOOKUP IDENTIFIER MATCHING condition FILTER condition
+ {
+ /* 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);
+ free($2); $2 = NULL;
+ sdb_object_deref(SDB_OBJ($4));
+ YYABORT;
+ }
+
+ $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
+ conn_lookup_t, conn_lookup_destroy));
+ CONN_LOOKUP($$)->matcher = CONN_MATCHER($4);
+ CONN_LOOKUP($$)->filter = CONN_MATCHER($6);
+ $$->cmd = CONNECTION_LOOKUP;
+ free($2); $2 = NULL;
+ }
;
condition:
}
$$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
- conn_node_matcher_t, conn_matcher_destroy));
+ conn_matcher_t, conn_matcher_destroy));
$$->cmd = CONNECTION_EXPR;
CONN_MATCHER($$)->matcher = $1;
}
diff --git a/src/frontend/query.c b/src/frontend/query.c
index d83ffd82ca76ab34bd03d0a18359baeaab194c1c..6fa2a619dcaa3d635dc3201b5cbe85f6698c0139 100644 (file)
--- a/src/frontend/query.c
+++ b/src/frontend/query.c
case CONNECTION_LIST:
return sdb_fe_list(conn, /* filter = */ NULL);
case CONNECTION_LOOKUP:
- return sdb_fe_lookup(conn, CONN_LOOKUP(node)->matcher->matcher,
- /* filter = */ NULL);
+ {
+ 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_lookup(conn, m, filter);
+ }
default:
sdb_log(SDB_LOG_ERR, "frontend: Unknown command %i", node->cmd);
diff --git a/src/frontend/scanner.l b/src/frontend/scanner.l
index f70f60f84dab33618a7ae84a67771ec33e0a022f..4bd5655e04bd9d870ccadcafa5da15d9c7c3ba74 100644 (file)
--- a/src/frontend/scanner.l
+++ b/src/frontend/scanner.l
} reserved_words[] = {
{ "AND", AND },
{ "FETCH", FETCH },
+ { "FILTER", FILTER },
{ "IS", IS },
{ "LIST", LIST },
{ "LOOKUP", LOOKUP },
index 8f9e3753fa7924d4cae67127a098201ee3d02269..86ac03fd80962dae080dc08c7425ee4319f172c3 100755 (executable)
echo "$output" | grep -F 'host1.example.com' && exit 1
echo "$output" | grep -F 'host2.example.com' && exit 1
+output="$( run_sysdb -H "$SOCKET_FILE" \
+ -c "LOOKUP hosts MATCHING attribute != 'architecture'
+ FILTER :age >= 0s" )"
+echo "$output" \
+ | grep -F '"some.host.name"' \
+ | grep -F '"localhost"'
+echo "$output" | grep -F 'other.host.name' && exit 1
+echo "$output" | grep -F 'host1.example.com' && exit 1
+echo "$output" | grep -F 'host2.example.com' && exit 1
+
+output="$( run_sysdb -H "$SOCKET_FILE" \
+ -c "LOOKUP hosts MATCHING attribute != 'architecture'
+ FILTER :last_update < 2Y" )"
+echo $output | grep -E '^\[\]$'
+
output="$( run_sysdb -H "$SOCKET_FILE" \
-c "LOOKUP hosts MATCHING service = 'sysdbd'" )"
echo "$output" | grep -F '"localhost"'
index a0826070ed958a6e864998af1eecf3890e944906..a10185469f2397accd253425025dbf9fe097c62c 100644 (file)
"host =~ 'p' AND "
"service =~ 'p' OR "
"service =~ 'r'", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts MATCHING "
+ "host =~ 'p' "
+ "FILTER :age > 1D", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts MATCHING "
+ "host =~ 'p' "
+ "FILTER :age > 1D AND "
+ ":interval < 240s" , -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts MATCHING "
+ "host =~ 'p' "
+ "FILTER NOT :age>1D", -1, 1, CONNECTION_LOOKUP },
/* numeric constants */
{ "LOOKUP hosts MATCHING "
{ "attribute.foo IS NULL", -1, MATCHER_ISNULL },
{ "attribute.foo IS NOT NULL", -1, MATCHER_NOT },
+ /* object field matchers */
+ { ":last_update < 10s", -1, MATCHER_LT },
+ { ":AGE <= 1m", -1, MATCHER_LE },
+ { ":interval = 10h", -1, MATCHER_EQ },
+ { ":Last_Update >= 24D", -1, MATCHER_GE },
+ { ":age > 1M", -1, MATCHER_GT },
+ { ":age != 20Y", -1, MATCHER_NOT },
+ { ":backend != 'be'", -1, MATCHER_NOT },
+
/* check operator precedence */
{ "host = 'name' OR "
"service = 'name' AND "