Create new search query parser
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Wed, 13 Mar 2019 10:15:47 +0000 (11:15 +0100)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Wed, 13 Mar 2019 10:15:47 +0000 (11:15 +0100)
Feature #14917

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

src/store/search-bar/search-query/arv-parser.ts [new file with mode: 0644]
src/store/search-bar/search-query/parser.ts [new file with mode: 0644]

diff --git a/src/store/search-bar/search-query/arv-parser.ts b/src/store/search-bar/search-query/arv-parser.ts
new file mode 100644 (file)
index 0000000..3a52be6
--- /dev/null
@@ -0,0 +1,56 @@
+
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as parser from '~/store/search-bar/search-query/parser';
+
+interface Property {
+    key: string;
+    value: string;
+}
+
+export enum Keywords {
+    TYPE = 'type',
+    CLUSTER = 'cluster',
+    PROJECT = 'project',
+    IS = 'is',
+    FROM = 'from',
+    TO = 'to',
+}
+
+const keyValuePattern = (key: string) => new RegExp(`${key}:([^ ]*)`);
+const propertyPattern = /has:"(.*?)":"(.*?)"/;
+
+const patterns = [
+    keyValuePattern(Keywords.TYPE),
+    keyValuePattern(Keywords.CLUSTER),
+    keyValuePattern(Keywords.PROJECT),
+    keyValuePattern(Keywords.IS),
+    keyValuePattern(Keywords.FROM),
+    keyValuePattern(Keywords.TO),
+    propertyPattern
+];
+
+export const parseSearchQuery = parser.parseSearchQuery(patterns);
+
+export const getValue = (tokens: string[]) => (key: string) => {
+    const pattern = keyValuePattern(key);
+    const token = tokens.find(t => pattern.test(t));
+    if (token) {
+        const [, value] = token.split(':');
+        return value;
+    }
+    return undefined;
+};
+
+export const getProperties = (tokens: string[]) =>
+    tokens.reduce((properties, token) => {
+        const match = token.match(propertyPattern);
+        if (match) {
+            const [, key, value] = match;
+            const newProperty = { key, value };
+            return [...properties, newProperty];
+        }
+        return properties;
+    }, [] as Property[]);
diff --git a/src/store/search-bar/search-query/parser.ts b/src/store/search-bar/search-query/parser.ts
new file mode 100644 (file)
index 0000000..5fb82e4
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+export interface ParsedSearchQuery {
+    tokens: string[];
+    searchString: string;
+}
+
+export const findToken = (query: string, patterns: RegExp[]) => {
+    for (const pattern of patterns) {
+        const match = query.match(pattern);
+        if (match) {
+            return match[0];
+        }
+    }
+    return null;
+};
+
+export const findAllTokens = (query: string, patterns: RegExp[]): string[] => {
+    const token = findToken(query, patterns);
+    return token
+        ? [token].concat(findAllTokens(query.replace(token, ''), patterns))
+        : [];
+};
+
+export const findSearchString = (query: string, tokens: string[]) => {
+    return tokens.reduce((q, token) => q.replace(token, ''), query);
+};
+
+export const parseSearchQuery = (patterns: RegExp[]) => (query: string): ParsedSearchQuery => {
+    const tokens = findAllTokens(query, patterns);
+    const searchString = findSearchString(query, tokens);
+    return { tokens, searchString };
+};