From bf5bf5faa1f61a2b78ff6153daff70a7bb08e939 Mon Sep 17 00:00:00 2001 From: Michal Klobukowski Date: Wed, 13 Mar 2019 11:15:47 +0100 Subject: [PATCH] Create new search query parser Feature #14917 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- .../search-bar/search-query/arv-parser.ts | 56 +++++++++++++++++++ src/store/search-bar/search-query/parser.ts | 35 ++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/store/search-bar/search-query/arv-parser.ts create mode 100644 src/store/search-bar/search-query/parser.ts 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 index 0000000000..3a52be6c82 --- /dev/null +++ b/src/store/search-bar/search-query/arv-parser.ts @@ -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 index 0000000000..5fb82e4d0f --- /dev/null +++ b/src/store/search-bar/search-query/parser.ts @@ -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 }; +}; -- 2.30.2