From f5cc6c740a52a3ad6a047a60fd6b1621fde7c4c4 Mon Sep 17 00:00:00 2001 From: David Matejka Date: Wed, 8 Nov 2023 15:21:37 +0100 Subject: [PATCH] feat(binding): support double quoted string in query language --- build/api/binding.api.md | 2 ++ .../binding/src/queryLanguage/CacheStore.ts | 1 + packages/binding/src/queryLanguage/Parser.ts | 5 +++++ packages/binding/src/queryLanguage/tokenList.ts | 2 +- .../cases/unit/queryLanguage/general.spec.tsx | 17 +++++++++++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/build/api/binding.api.md b/build/api/binding.api.md index 0fbf51cafb..d11a82430c 100644 --- a/build/api/binding.api.md +++ b/build/api/binding.api.md @@ -1285,6 +1285,8 @@ export namespace Parser { export type EntryPoint = keyof ParserResult; // (undocumented) export interface ParserResult { + // (undocumented) + columnValue: AST.ColumnValue; // (undocumented) filter: Filter; // (undocumented) diff --git a/packages/binding/src/queryLanguage/CacheStore.ts b/packages/binding/src/queryLanguage/CacheStore.ts index c8ace0ba8e..3caa4c72a4 100644 --- a/packages/binding/src/queryLanguage/CacheStore.ts +++ b/packages/binding/src/queryLanguage/CacheStore.ts @@ -51,6 +51,7 @@ export class CacheStore { filter: new LRUCache(100), orderBy: new LRUCache(50), taggedMap: new LRUCache(50), + columnValue: new LRUCache(500), } } } diff --git a/packages/binding/src/queryLanguage/Parser.ts b/packages/binding/src/queryLanguage/Parser.ts index 3d73755430..cf079868fe 100644 --- a/packages/binding/src/queryLanguage/Parser.ts +++ b/packages/binding/src/queryLanguage/Parser.ts @@ -744,6 +744,7 @@ class Parser extends EmbeddedActionsParser { return image .substring(1, image.length - 1) .replace("\\'", "'") + .replace(`\\"`, `"`) .replace('\\b', '\b') .replace('\\f', '\f') .replace('\\n', '\n') @@ -863,6 +864,9 @@ class Parser extends EmbeddedActionsParser { case 'taggedMap': expression = Parser.parser.taggedMap() break + case 'columnValue': + expression = Parser.parser.columnValue() + break default: throw new QueryLanguageError(`Not implemented entry point '${entry}'`) } @@ -903,6 +907,7 @@ namespace Parser { filter: Filter // E.g. [author.son.age < 123] orderBy: OrderBy // E.g. items.order asc, items.content.name asc taggedMap: ParsedTaggedMap // E.g editUser(id: $entity.id, foo: 'bar') + columnValue: AST.ColumnValue } export type EntryPoint = keyof ParserResult diff --git a/packages/binding/src/queryLanguage/tokenList.ts b/packages/binding/src/queryLanguage/tokenList.ts index a518600d37..2026f7deeb 100644 --- a/packages/binding/src/queryLanguage/tokenList.ts +++ b/packages/binding/src/queryLanguage/tokenList.ts @@ -56,7 +56,7 @@ export const tokens = { StringLiteral: createToken({ name: 'StringLiteral', - pattern: /'(:?[^\\']|\\(:?[bfnrtv'\\/]|u[0-9a-fA-F]{4}))*'/, + pattern: /'(:?[^\\']|\\(:?[bfnrtv"'\\/]|u[0-9a-fA-F]{4}))*'|"(:?[^\\"]|\\(:?[bfnrtv"'\\/]|u[0-9a-fA-F]{4}))*"/, }), LeftParenthesis: createToken({ diff --git a/packages/binding/tests/cases/unit/queryLanguage/general.spec.tsx b/packages/binding/tests/cases/unit/queryLanguage/general.spec.tsx index 6440e5832e..6bd6c80bfb 100644 --- a/packages/binding/tests/cases/unit/queryLanguage/general.spec.tsx +++ b/packages/binding/tests/cases/unit/queryLanguage/general.spec.tsx @@ -4,6 +4,23 @@ import { Environment } from '../../../../src/dao' import { Parser } from '../../../../src/queryLanguage' describe('query language parser', () => { + it('shoud parse column value', () => { + const env = Environment.create() + expect(Parser.parseQueryLanguageExpression('123', 'columnValue', env)).toEqual(123) + expect(Parser.parseQueryLanguageExpression('123.456', 'columnValue', env)).toEqual(123.456) + expect(Parser.parseQueryLanguageExpression('true', 'columnValue', env)).toEqual(true) + expect(Parser.parseQueryLanguageExpression('false', 'columnValue', env)).toEqual(false) + expect(Parser.parseQueryLanguageExpression('null', 'columnValue', env)).toEqual(null) + expect(Parser.parseQueryLanguageExpression("'foo'", 'columnValue', env)).toEqual('foo') + expect(Parser.parseQueryLanguageExpression(`'foo\\'bar'`, 'columnValue', env)).toEqual("foo'bar") + expect(Parser.parseQueryLanguageExpression(`'foo"bar'`, 'columnValue', env)).toEqual(`foo"bar`) + expect(Parser.parseQueryLanguageExpression(`'foo\\"bar'`, 'columnValue', env)).toEqual(`foo"bar`) + expect(Parser.parseQueryLanguageExpression('"foo"', 'columnValue', env)).toEqual('foo') + expect(Parser.parseQueryLanguageExpression(`"foo\\"bar"`, 'columnValue', env)).toEqual('foo"bar') + expect(Parser.parseQueryLanguageExpression(`"foo\\'bar"`, 'columnValue', env)).toEqual("foo'bar") + expect(Parser.parseQueryLanguageExpression(`"foo'bar"`, 'columnValue', env)).toEqual("foo'bar") + }) + it('should resolve variables adhering to the principle maximal munch', () => { const environment = Environment.create().withVariables({ ab: 456,