From fe7add0bc657d55dfdb21524aa681e0f4e421e16 Mon Sep 17 00:00:00 2001 From: Scott Lepper Date: Tue, 2 Aug 2022 11:44:06 -0400 Subject: [PATCH] ref experimental query editor (#53061) * ref experimental query editor --- .betterer.results | 28 - package.json | 1 + .../features/plugins/sql/components/index.ts | 1 - .../query-editor-raw/QueryEditorRaw.tsx | 4 +- .../components/query-editor-raw/SQLEditor.tsx | 405 -------- .../sql/components/query-editor-raw/index.ts | 1 - public/app/features/plugins/sql/index.ts | 22 +- .../app/features/plugins/sql/mocks/Monaco.ts | 26 - .../features/plugins/sql/mocks/TextModel.ts | 21 - .../sql/mocks/queries/multiLineFullQuery.ts | 214 ----- .../multiLineFullQueryWithAggregation.ts | 229 ----- .../mocks/queries/multiLineMultipleColumns.ts | 269 ------ .../sql/mocks/queries/singleLineEmptyQuery.ts | 6 - .../sql/mocks/queries/singleLineFullQuery.ts | 196 ---- .../singleLineFullQueryWithAggregation.ts | 209 ----- .../queries/singleLineMultipleColumns.ts | 250 ----- .../sql/mocks/queries/singleLineTwoQueries.ts | 385 -------- .../singleLineTwoQueriesWithAggregation.ts | 415 --------- .../features/plugins/sql/mocks/testData.ts | 9 - .../plugins/sql/standardSql/definition.ts | 24 - .../getStandardSuggestions.test.ts | 273 ------ .../sql/standardSql/getStandardSuggestions.ts | 34 - .../standardSql/getStatementPosition.test.ts | 184 ---- .../sql/standardSql/getStatementPosition.ts | 31 - .../plugins/sql/standardSql/language.ts | 880 ------------------ .../plugins/sql/standardSql/macros.ts | 67 -- .../standardSuggestionsRegistry.ts | 425 --------- .../statementPositionResolversRegistry.ts | 244 ----- .../standardSql/suggestionsKindRegistry.ts | 146 --- .../features/plugins/sql/standardSql/types.ts | 52 -- .../features/plugins/sql/test-utils/index.ts | 11 - .../sql/test-utils/statementPosition.ts | 63 -- .../plugins/sql/test-utils/testQueries.txt | 21 - .../features/plugins/sql/test-utils/types.ts | 11 - public/app/features/plugins/sql/types.ts | 264 +----- .../features/plugins/sql/utils/LinkedToken.ts | 176 ---- .../features/plugins/sql/utils/commands.ts | 4 - .../features/plugins/sql/utils/debugger.ts | 12 - .../sql/utils/getSuggestionKind.test.ts | 31 - .../plugins/sql/utils/getSuggestionKind.ts | 22 - .../sql/utils/linkedTokenBuilder.test.ts | 72 -- .../plugins/sql/utils/linkedTokenBuilder.ts | 56 -- .../plugins/sql/utils/toCompletionItem.ts | 19 - .../features/plugins/sql/utils/tokenUtils.ts | 57 -- .../app/features/plugins/sql/utils/types.ts | 14 - .../datasource/mssql/sqlCompletionProvider.ts | 2 +- .../datasource/mysql/sqlCompletionProvider.ts | 2 +- yarn.lock | 17 +- 48 files changed, 37 insertions(+), 5868 deletions(-) delete mode 100644 public/app/features/plugins/sql/components/query-editor-raw/SQLEditor.tsx delete mode 100644 public/app/features/plugins/sql/components/query-editor-raw/index.ts delete mode 100644 public/app/features/plugins/sql/mocks/Monaco.ts delete mode 100644 public/app/features/plugins/sql/mocks/TextModel.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/multiLineFullQuery.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/multiLineFullQueryWithAggregation.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/multiLineMultipleColumns.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/singleLineEmptyQuery.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/singleLineFullQuery.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/singleLineFullQueryWithAggregation.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/singleLineMultipleColumns.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/singleLineTwoQueries.ts delete mode 100644 public/app/features/plugins/sql/mocks/queries/singleLineTwoQueriesWithAggregation.ts delete mode 100644 public/app/features/plugins/sql/mocks/testData.ts delete mode 100644 public/app/features/plugins/sql/standardSql/definition.ts delete mode 100644 public/app/features/plugins/sql/standardSql/getStandardSuggestions.test.ts delete mode 100644 public/app/features/plugins/sql/standardSql/getStandardSuggestions.ts delete mode 100644 public/app/features/plugins/sql/standardSql/getStatementPosition.test.ts delete mode 100644 public/app/features/plugins/sql/standardSql/getStatementPosition.ts delete mode 100644 public/app/features/plugins/sql/standardSql/language.ts delete mode 100644 public/app/features/plugins/sql/standardSql/macros.ts delete mode 100644 public/app/features/plugins/sql/standardSql/standardSuggestionsRegistry.ts delete mode 100644 public/app/features/plugins/sql/standardSql/statementPositionResolversRegistry.ts delete mode 100644 public/app/features/plugins/sql/standardSql/suggestionsKindRegistry.ts delete mode 100644 public/app/features/plugins/sql/standardSql/types.ts delete mode 100644 public/app/features/plugins/sql/test-utils/index.ts delete mode 100644 public/app/features/plugins/sql/test-utils/statementPosition.ts delete mode 100644 public/app/features/plugins/sql/test-utils/testQueries.txt delete mode 100644 public/app/features/plugins/sql/test-utils/types.ts delete mode 100644 public/app/features/plugins/sql/utils/LinkedToken.ts delete mode 100644 public/app/features/plugins/sql/utils/commands.ts delete mode 100644 public/app/features/plugins/sql/utils/debugger.ts delete mode 100644 public/app/features/plugins/sql/utils/getSuggestionKind.test.ts delete mode 100644 public/app/features/plugins/sql/utils/getSuggestionKind.ts delete mode 100644 public/app/features/plugins/sql/utils/linkedTokenBuilder.test.ts delete mode 100644 public/app/features/plugins/sql/utils/linkedTokenBuilder.ts delete mode 100644 public/app/features/plugins/sql/utils/toCompletionItem.ts delete mode 100644 public/app/features/plugins/sql/utils/tokenUtils.ts delete mode 100644 public/app/features/plugins/sql/utils/types.ts diff --git a/.betterer.results b/.betterer.results index b1d89314506..46861281fda 100644 --- a/.betterer.results +++ b/.betterer.results @@ -5377,39 +5377,11 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "7"], [0, 0, 0, "Do not use any type assertions.", "8"] ], - "public/app/features/plugins/sql/components/query-editor-raw/SQLEditor.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"] - ], "public/app/features/plugins/sql/components/visual-query-builder/AwesomeQueryBuilder.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], - "public/app/features/plugins/sql/mocks/Monaco.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/plugins/sql/mocks/queries/singleLineFullQuery.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], - "public/app/features/plugins/sql/standardSql/definition.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/plugins/sql/test-utils/statementPosition.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"] - ], - "public/app/features/plugins/sql/utils/debugger.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], "public/app/features/plugins/tests/datasource_srv.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], diff --git a/package.json b/package.json index cb5ec96a821..ea2497707f3 100644 --- a/package.json +++ b/package.json @@ -254,6 +254,7 @@ "@grafana/aws-sdk": "0.0.37", "@grafana/data": "workspace:*", "@grafana/e2e-selectors": "workspace:*", + "@grafana/experimental": "^0.0.2-canary.36", "@grafana/google-sdk": "0.0.3", "@grafana/lezer-logql": "0.0.14", "@grafana/runtime": "workspace:*", diff --git a/public/app/features/plugins/sql/components/index.ts b/public/app/features/plugins/sql/components/index.ts index b78eb8e5982..f7bbd027106 100644 --- a/public/app/features/plugins/sql/components/index.ts +++ b/public/app/features/plugins/sql/components/index.ts @@ -1,2 +1 @@ -export * from './query-editor-raw'; export * from './visual-query-builder'; diff --git a/public/app/features/plugins/sql/components/query-editor-raw/QueryEditorRaw.tsx b/public/app/features/plugins/sql/components/query-editor-raw/QueryEditorRaw.tsx index 37d609f2044..74265916ab0 100644 --- a/public/app/features/plugins/sql/components/query-editor-raw/QueryEditorRaw.tsx +++ b/public/app/features/plugins/sql/components/query-editor-raw/QueryEditorRaw.tsx @@ -1,10 +1,10 @@ import React, { useCallback, useEffect, useRef } from 'react'; +import { SQLEditor } from '@grafana/experimental'; + import { LanguageCompletionProvider, SQLQuery } from '../../types'; import { formatSQL } from '../../utils/formatSQL'; -import { SQLEditor } from './SQLEditor'; - type Props = { query: SQLQuery; onChange: (value: SQLQuery, processQuery: boolean) => void; diff --git a/public/app/features/plugins/sql/components/query-editor-raw/SQLEditor.tsx b/public/app/features/plugins/sql/components/query-editor-raw/SQLEditor.tsx deleted file mode 100644 index b6a0217fffe..00000000000 --- a/public/app/features/plugins/sql/components/query-editor-raw/SQLEditor.tsx +++ /dev/null @@ -1,405 +0,0 @@ -import React, { useCallback, useEffect, useMemo, useRef } from 'react'; -import { v4 } from 'uuid'; - -import { Registry } from '@grafana/data'; -import { CodeEditor, Monaco, monacoTypes } from '@grafana/ui'; - -import standardSQLLanguageDefinition from '../../standardSql/definition'; -import { getStandardSuggestions } from '../../standardSql/getStandardSuggestions'; -import { getStatementPosition } from '../../standardSql/getStatementPosition'; -import { - initFunctionsRegistry, - initMacrosRegistry, - initOperatorsRegistry, - initStandardSuggestions, -} from '../../standardSql/standardSuggestionsRegistry'; -import { initStatementPositionResolvers } from '../../standardSql/statementPositionResolversRegistry'; -import { initSuggestionsKindRegistry, SuggestionKindRegistryItem } from '../../standardSql/suggestionsKindRegistry'; -import { - FunctionsRegistryItem, - MacrosRegistryItem, - OperatorsRegistryItem, - SQLMonarchLanguage, - StatementPositionResolversRegistryItem, - SuggestionsRegistryItem, -} from '../../standardSql/types'; -import { - CompletionItemKind, - CompletionItemPriority, - CustomSuggestion, - PositionContext, - SQLCompletionItemProvider, - StatementPosition, - SuggestionKind, -} from '../../types'; -import { LinkedToken } from '../../utils/LinkedToken'; -import { TRIGGER_SUGGEST } from '../../utils/commands'; -import { sqlEditorLog } from '../../utils/debugger'; -import { getSuggestionKinds } from '../../utils/getSuggestionKind'; -import { linkedTokenBuilder } from '../../utils/linkedTokenBuilder'; -import { getTableToken } from '../../utils/tokenUtils'; - -const STANDARD_SQL_LANGUAGE = 'sql'; - -export interface LanguageDefinition extends monacoTypes.languages.ILanguageExtensionPoint { - loader?: (module: any) => Promise<{ - language: SQLMonarchLanguage; - conf: monacoTypes.languages.LanguageConfiguration; - }>; - // Provides API for customizing the autocomplete - completionProvider?: (m: Monaco) => SQLCompletionItemProvider; - // Function that returns a formatted query - formatter?: (q: string) => string; -} - -interface SQLEditorProps { - query: string; - /** - * Use for inspecting the query as it changes. I.e. for validation. - */ - onChange?: (q: string, processQuery: boolean) => void; - language?: LanguageDefinition; - children?: (props: { formatQuery: () => void }) => React.ReactNode; - width?: number; - height?: number; -} - -const defaultTableNameParser = (t: LinkedToken) => t.value; - -interface LanguageRegistries { - functions: Registry; - operators: Registry; - suggestionKinds: Registry; - positionResolvers: Registry; - macros: Registry; -} - -const LANGUAGES_CACHE = new Map(); -const INSTANCE_CACHE = new Map>(); - -export const SQLEditor: React.FC = ({ - children, - onChange, - query, - language = { id: STANDARD_SQL_LANGUAGE }, - width, - height, -}) => { - const monacoRef = useRef(null); - const langUid = useRef(); - // create unique language id for each SQLEditor instance - const id = useMemo(() => { - const uid = v4(); - const id = `${language.id}-${uid}`; - langUid.current = id; - return id; - }, [language.id]); - - useEffect(() => { - return () => { - INSTANCE_CACHE.delete(langUid.current!); - sqlEditorLog(`Removing instance cache ${langUid.current}`, false, INSTANCE_CACHE); - }; - }, []); - - const formatQuery = useCallback(() => { - if (monacoRef.current) { - monacoRef.current.getAction('editor.action.formatDocument').run(); - } - }, []); - - return ( -
- onChange && onChange(v, false)} - showMiniMap={false} - showLineNumbers={true} - // Using onEditorDidMount instead of onBeforeEditorMount to support Grafana < 8.2.x - onEditorDidMount={(editor, m) => { - // TODO - says its read only but this worked in experimental - // monacoRef.current = editor; - editor.onDidChangeModelContent((e) => { - const text = editor.getValue(); - if (onChange) { - onChange(text, false); - } - }); - - editor.addCommand(m.KeyMod.CtrlCmd | m.KeyCode.Enter, () => { - const text = editor.getValue(); - if (onChange) { - onChange(text, true); - } - }); - registerLanguageAndSuggestions(m, language, id); - }} - /> - {children && children({ formatQuery })} -
- ); -}; - -// There's three ways to define Monaco language: -// 1. Leave language.id empty or set it to 'sql'. This will load a standard sql language definition, including syntax highlighting and tokenization for -// common Grafana entities such as macros and template variables -// 2. Provide a custom language and load it via the async LanguageDefinition.loader callback -// 3. Specify a language.id that exists in the Monaco language registry. See available languages here: https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages -// If a custom language is specified, its LanguageDefinition will be merged with the LanguageDefinition for standard SQL. This allows the consumer to only -// override parts of the LanguageDefinition, such as for example the completion item provider. -const resolveLanguage = (monaco: Monaco, languageDefinitionProp: LanguageDefinition): LanguageDefinition => { - if (languageDefinitionProp?.id !== STANDARD_SQL_LANGUAGE && !languageDefinitionProp.loader) { - sqlEditorLog(`Loading language '${languageDefinitionProp?.id}' from Monaco registry`, false); - const allLangs = monaco.languages.getLanguages(); - const custom = allLangs.find(({ id }) => id === languageDefinitionProp?.id); - if (!custom) { - throw Error(`Unknown Monaco language ${languageDefinitionProp?.id}`); - } - return custom; - } - - return { - ...standardSQLLanguageDefinition, - ...languageDefinitionProp, - }; -}; - -export const registerLanguageAndSuggestions = async (monaco: Monaco, l: LanguageDefinition, lid: string) => { - const languageDefinition = resolveLanguage(monaco, l); - const { language, conf } = await languageDefinition.loader!(monaco); - monaco.languages.register({ id: lid }); - monaco.languages.setMonarchTokensProvider(lid, { ...language }); - monaco.languages.setLanguageConfiguration(lid, { ...conf }); - - if (languageDefinition.formatter) { - monaco.languages.registerDocumentFormattingEditProvider(lid, { - provideDocumentFormattingEdits: (model) => { - var formatted = l.formatter!(model.getValue()); - return [ - { - range: model.getFullModelRange(), - text: formatted, - }, - ]; - }, - }); - } - - if (languageDefinition.completionProvider) { - const customProvider = l.completionProvider!(monaco); - extendStandardRegistries(l.id, lid, customProvider); - const languageSuggestionsRegistries = LANGUAGES_CACHE.get(l.id)!; - const instanceSuggestionsRegistry = INSTANCE_CACHE.get(lid)!; - - const completionProvider: monacoTypes.languages.CompletionItemProvider['provideCompletionItems'] = async ( - model, - position, - context, - token - ) => { - const currentToken = linkedTokenBuilder(monaco, model, position, 'sql'); - const statementPosition = getStatementPosition(currentToken, languageSuggestionsRegistries.positionResolvers); - const kind = getSuggestionKinds(statementPosition, languageSuggestionsRegistries.suggestionKinds); - - sqlEditorLog('Statement position', false, statementPosition); - sqlEditorLog('Suggestion kinds', false, kind); - - const ctx: PositionContext = { - position, - currentToken, - statementPosition, - kind, - range: monaco.Range.fromPositions(position), - }; - - // // Completely custom suggestions - hope this won't we needed - // let ci; - // if (customProvider.provideCompletionItems) { - // ci = customProvider.provideCompletionItems(model, position, context, token, ctx); - // } - - const stdSuggestions = await getStandardSuggestions(monaco, currentToken, kind, ctx, instanceSuggestionsRegistry); - - return { - // ...ci, - suggestions: stdSuggestions, - }; - }; - - monaco.languages.registerCompletionItemProvider(lid, { - ...customProvider, - provideCompletionItems: completionProvider, - }); - } -}; - -function extendStandardRegistries(id: string, lid: string, customProvider: SQLCompletionItemProvider) { - if (!LANGUAGES_CACHE.has(id)) { - initializeLanguageRegistries(id); - } - - const languageRegistries = LANGUAGES_CACHE.get(id)!; - - if (!INSTANCE_CACHE.has(lid)) { - INSTANCE_CACHE.set( - lid, - new Registry( - initStandardSuggestions(languageRegistries.functions, languageRegistries.operators, languageRegistries.macros) - ) - ); - } - - const instanceSuggestionsRegistry = INSTANCE_CACHE.get(lid)!; - - if (customProvider.supportedFunctions) { - for (const func of customProvider.supportedFunctions()) { - const exists = languageRegistries.functions.getIfExists(func.id); - if (!exists) { - languageRegistries.functions.register(func); - } - } - } - - if (customProvider.supportedOperators) { - for (const op of customProvider.supportedOperators()) { - const exists = languageRegistries.operators.getIfExists(op.id); - if (!exists) { - languageRegistries.operators.register({ ...op, name: op.id }); - } - } - } - - if (customProvider.supportedMacros) { - for (const macro of customProvider.supportedMacros()) { - const exists = languageRegistries.macros.getIfExists(macro.id); - if (!exists) { - languageRegistries.macros.register({ ...macro, name: macro.id }); - } - } - } - - if (customProvider.customStatementPlacement) { - for (const placement of customProvider.customStatementPlacement()) { - const exists = languageRegistries.positionResolvers.getIfExists(placement.id); - if (!exists) { - languageRegistries.positionResolvers.register({ - ...placement, - id: placement.id as StatementPosition, - name: placement.id, - }); - languageRegistries.suggestionKinds.register({ - id: placement.id as StatementPosition, - name: placement.id, - kind: [], - }); - } else { - // Allow extension to the built-in placement resolvers - const origResolve = exists.resolve; - exists.resolve = (...args) => { - const ext = placement.resolve(...args); - if (placement.overrideDefault) { - return ext; - } - const orig = origResolve(...args); - return orig || ext; - }; - } - } - } - - if (customProvider.customSuggestionKinds) { - for (const kind of customProvider.customSuggestionKinds()) { - kind.applyTo?.forEach((applyTo) => { - const exists = languageRegistries.suggestionKinds.getIfExists(applyTo); - if (exists) { - // avoid duplicates - if (exists.kind.indexOf(kind.id as SuggestionKind) === -1) { - exists.kind.push(kind.id as SuggestionKind); - } - } - }); - - if (kind.overrideDefault) { - const stbBehaviour = instanceSuggestionsRegistry.get(kind.id); - if (stbBehaviour !== undefined) { - stbBehaviour.suggestions = kind.suggestionsResolver; - continue; - } - } - - instanceSuggestionsRegistry.register({ - id: kind.id as SuggestionKind, - name: kind.id, - suggestions: kind.suggestionsResolver, - }); - } - } - - if (customProvider.tables) { - const stbBehaviour = instanceSuggestionsRegistry.get(SuggestionKind.Tables); - const s = stbBehaviour!.suggestions; - stbBehaviour!.suggestions = async (ctx, m) => { - const o = await s(ctx, m); - const oo = (await customProvider.tables!.resolve!()).map((x) => ({ - label: x.name, - insertText: x.completion ?? x.name, - command: TRIGGER_SUGGEST, - kind: CompletionItemKind.Field, - sortText: CompletionItemPriority.High, - })); - return [...o, ...oo]; - }; - } - - if (customProvider.columns) { - const stbBehaviour = instanceSuggestionsRegistry.get(SuggestionKind.Columns); - const s = stbBehaviour!.suggestions; - stbBehaviour!.suggestions = async (ctx, m) => { - const o = await s(ctx, m); - const tableToken = getTableToken(ctx.currentToken); - let table = ''; - const tableNameParser = customProvider.tables?.parseName ?? defaultTableNameParser; - - if (tableToken && tableToken.value) { - table = tableNameParser(tableToken).trim(); - } - - let oo: CustomSuggestion[] = []; - if (table) { - const columns = await customProvider.columns?.resolve!(table); - oo = columns - ? columns.map((x) => ({ - label: x.name, - insertText: x.completion ?? x.name, - kind: CompletionItemKind.Field, - sortText: CompletionItemPriority.High, - detail: x.type, - documentation: x.description, - })) - : []; - } - return [...o, ...oo]; - }; - } -} - -/** - * Initializes language specific registries that are treated as singletons - */ -function initializeLanguageRegistries(id: string) { - if (!LANGUAGES_CACHE.has(id)) { - LANGUAGES_CACHE.set(id, { - functions: new Registry(initFunctionsRegistry), - operators: new Registry(initOperatorsRegistry), - suggestionKinds: new Registry(initSuggestionsKindRegistry), - positionResolvers: new Registry(initStatementPositionResolvers), - macros: new Registry(initMacrosRegistry), - }); - } - - return LANGUAGES_CACHE.get(id)!; -} diff --git a/public/app/features/plugins/sql/components/query-editor-raw/index.ts b/public/app/features/plugins/sql/components/query-editor-raw/index.ts deleted file mode 100644 index b1abf960d03..00000000000 --- a/public/app/features/plugins/sql/components/query-editor-raw/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SQLEditor, LanguageDefinition } from './SQLEditor'; diff --git a/public/app/features/plugins/sql/index.ts b/public/app/features/plugins/sql/index.ts index a3861bddaae..195d95f598d 100644 --- a/public/app/features/plugins/sql/index.ts +++ b/public/app/features/plugins/sql/index.ts @@ -1,22 +1,2 @@ -export { SQLEditorTestUtils, TestQueryModel } from './test-utils'; -export { LinkedToken } from './utils/LinkedToken'; -export { language as grafanaStandardSQLLanguage, conf as grafanaStandardSQLLanguageConf } from './standardSql/language'; -export { SQLMonarchLanguage } from './standardSql/types'; - -export { - TableDefinition, - ColumnDefinition, - StatementPlacementProvider, - SuggestionKindProvider, - LanguageCompletionProvider, - OperatorType, - MacroType, - TokenType, - StatementPosition, - SuggestionKind, - CompletionItemKind, - CompletionItemPriority, - CompletionItemInsertTextRule, -} from './types'; - export * from './components'; +export * from './types'; diff --git a/public/app/features/plugins/sql/mocks/Monaco.ts b/public/app/features/plugins/sql/mocks/Monaco.ts deleted file mode 100644 index 190cafe56b5..00000000000 --- a/public/app/features/plugins/sql/mocks/Monaco.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -// Stub for the Monaco instance. Only implements the parts that are used in cloudwatch sql -const getMonacoMock: ( - testData: Map>>> -) => any = (testData) => ({ - editor: { - tokenize: (value: string, languageId: string) => testData.get(value), - }, - Range: { - containsPosition: (range: monacoTypes.IRange, position: monacoTypes.IPosition) => { - return ( - position.lineNumber >= range.startLineNumber && - position.lineNumber <= range.endLineNumber && - position.column >= range.startColumn && - position.column <= range.endColumn - ); - }, - }, - languages: { - CompletionItemKind: { Snippet: 2, Function: 1, Keyword: 3 }, - CompletionItemInsertTextRule: { InsertAsSnippet: 2 }, - }, -}); - -export { getMonacoMock }; diff --git a/public/app/features/plugins/sql/mocks/TextModel.ts b/public/app/features/plugins/sql/mocks/TextModel.ts deleted file mode 100644 index 22f3f73780e..00000000000 --- a/public/app/features/plugins/sql/mocks/TextModel.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -// Stub for monacoTypes.editor.ITextModel -function TextModel(value: string) { - return { - getValue: function (eol?: monacoTypes.editor.EndOfLinePreference, preserveBOM?: boolean): string { - return value; - }, - getValueInRange: function (range: monacoTypes.IRange, eol?: monacoTypes.editor.EndOfLinePreference): string { - const lines = value.split('\n'); - const line = lines[range.startLineNumber - 1]; - return line.trim().slice(range.startColumn === 0 ? 0 : range.startColumn - 1, range.endColumn - 1); - }, - getLineLength: function (lineNumber: number): number { - const lines = value.split('\n'); - return lines[lineNumber - 1].trim().length; - }, - }; -} - -export { TextModel }; diff --git a/public/app/features/plugins/sql/mocks/queries/multiLineFullQuery.ts b/public/app/features/plugins/sql/mocks/queries/multiLineFullQuery.ts deleted file mode 100644 index 2cc92ea02aa..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/multiLineFullQuery.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const multiLineFullQuery: TestQueryModel = { - query: `SELECT column1, - FROM table1 - - WHERE column1 = "value1" - GROUP BY column1 ORDER BY column1 DESC - LIMIT 10;`, - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 14, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 15, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 4, - type: 'white.sql', - language: 'sql', - }, - { - offset: 5, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 11, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 13, - type: 'white.sql', - language: 'sql', - }, - { - offset: 14, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 15, - type: 'white.sql', - language: 'sql', - }, - { - offset: 16, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 17, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 23, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 24, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 8, - type: 'white.sql', - language: 'sql', - }, - { - offset: 9, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 16, - type: 'white.sql', - language: 'sql', - }, - { - offset: 17, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - { - offset: 23, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 25, - type: 'white.sql', - language: 'sql', - }, - { - offset: 26, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 33, - type: 'white.sql', - language: 'sql', - }, - { - offset: 34, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 38, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'number.sql', - language: 'sql', - }, - { - offset: 8, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/multiLineFullQueryWithAggregation.ts b/public/app/features/plugins/sql/mocks/queries/multiLineFullQueryWithAggregation.ts deleted file mode 100644 index 1f8d54c4da6..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/multiLineFullQueryWithAggregation.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const multiLineFullQueryWithAggregation: TestQueryModel = { - query: `SELECT count(column1), - FROM table1 - - WHERE column1 = "value1" - GROUP BY column1 ORDER BY column1 DESC - LIMIT 10;`, - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 12, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 13, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 20, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 21, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 4, - type: 'white.sql', - language: 'sql', - }, - { - offset: 5, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 11, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 13, - type: 'white.sql', - language: 'sql', - }, - { - offset: 14, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 15, - type: 'white.sql', - language: 'sql', - }, - { - offset: 16, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 17, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 23, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 24, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 8, - type: 'white.sql', - language: 'sql', - }, - { - offset: 9, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 16, - type: 'white.sql', - language: 'sql', - }, - { - offset: 17, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - { - offset: 23, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 25, - type: 'white.sql', - language: 'sql', - }, - { - offset: 26, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 33, - type: 'white.sql', - language: 'sql', - }, - { - offset: 34, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 38, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'number.sql', - language: 'sql', - }, - { - offset: 8, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/multiLineMultipleColumns.ts b/public/app/features/plugins/sql/mocks/queries/multiLineMultipleColumns.ts deleted file mode 100644 index 359896e43d3..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/multiLineMultipleColumns.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const multiLineMultipleColumns: TestQueryModel = { - query: `SELECT count(column1), column2 - FROM table1 - - WHERE column1 = "value1" - GROUP BY column1 ORDER BY column1, avg(column2) DESC - LIMIT 10;`, - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 12, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 13, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 20, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 21, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - { - offset: 23, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 30, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 4, - type: 'white.sql', - language: 'sql', - }, - { - offset: 5, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 11, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 13, - type: 'white.sql', - language: 'sql', - }, - { - offset: 14, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 15, - type: 'white.sql', - language: 'sql', - }, - { - offset: 16, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 17, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 23, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 24, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 8, - type: 'white.sql', - language: 'sql', - }, - { - offset: 9, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 16, - type: 'white.sql', - language: 'sql', - }, - { - offset: 17, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - { - offset: 23, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 25, - type: 'white.sql', - language: 'sql', - }, - { - offset: 26, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 33, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 34, - type: 'white.sql', - language: 'sql', - }, - { - offset: 35, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 38, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 39, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 46, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 47, - type: 'white.sql', - language: 'sql', - }, - { - offset: 48, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 52, - type: 'white.sql', - language: 'sql', - }, - ], - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 5, - type: 'white.sql', - language: 'sql', - }, - { - offset: 6, - type: 'number.sql', - language: 'sql', - }, - { - offset: 8, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/singleLineEmptyQuery.ts b/public/app/features/plugins/sql/mocks/queries/singleLineEmptyQuery.ts deleted file mode 100644 index 123fc2d331e..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/singleLineEmptyQuery.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const singleLineEmptyQuery: TestQueryModel = { - query: '', - tokens: [], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/singleLineFullQuery.ts b/public/app/features/plugins/sql/mocks/queries/singleLineFullQuery.ts deleted file mode 100644 index 690465678c8..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/singleLineFullQuery.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -import { TestQueryModel } from '../../test-utils/types'; - -export const singleLineFullQuery: TestQueryModel = { - query: `SELECT column1, FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10`, - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 14, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 15, - type: 'white.sql', - language: 'sql', - }, - { - offset: 16, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 20, - type: 'white.sql', - language: 'sql', - }, - { - offset: 21, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 27, - type: 'white.sql', - language: 'sql', - }, - { - offset: 28, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 33, - type: 'white.sql', - language: 'sql', - }, - { - offset: 34, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 41, - type: 'white.sql', - language: 'sql', - }, - { - offset: 42, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 43, - type: 'white.sql', - language: 'sql', - }, - { - offset: 44, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 45, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 51, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 52, - type: 'white.sql', - language: 'sql', - }, - { - offset: 53, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 58, - type: 'white.sql', - language: 'sql', - }, - { - offset: 59, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 61, - type: 'white.sql', - language: 'sql', - }, - { - offset: 62, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 69, - type: 'white.sql', - language: 'sql', - }, - { - offset: 70, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 75, - type: 'white.sql', - language: 'sql', - }, - { - offset: 76, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 78, - type: 'white.sql', - language: 'sql', - }, - { - offset: 79, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 86, - type: 'white.sql', - language: 'sql', - }, - { - offset: 87, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 91, - type: 'white.sql', - language: 'sql', - }, - { - offset: 92, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 97, - type: 'white.sql', - language: 'sql', - }, - { - offset: 98, - type: 'number.sql', - language: 'sql', - }, - { - offset: 100, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ] as monacoTypes.Token[][], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/singleLineFullQueryWithAggregation.ts b/public/app/features/plugins/sql/mocks/queries/singleLineFullQueryWithAggregation.ts deleted file mode 100644 index 0f76f78258c..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/singleLineFullQueryWithAggregation.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const singleLineFullQueryWithAggregation: TestQueryModel = { - query: 'SELECT count(column1), FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10;', - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 12, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 13, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 20, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 21, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - { - offset: 23, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 27, - type: 'white.sql', - language: 'sql', - }, - { - offset: 28, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 34, - type: 'white.sql', - language: 'sql', - }, - { - offset: 35, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 40, - type: 'white.sql', - language: 'sql', - }, - { - offset: 41, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 48, - type: 'white.sql', - language: 'sql', - }, - { - offset: 49, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 50, - type: 'white.sql', - language: 'sql', - }, - { - offset: 51, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 52, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 58, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 59, - type: 'white.sql', - language: 'sql', - }, - { - offset: 60, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 65, - type: 'white.sql', - language: 'sql', - }, - { - offset: 66, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 68, - type: 'white.sql', - language: 'sql', - }, - { - offset: 69, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 76, - type: 'white.sql', - language: 'sql', - }, - { - offset: 77, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 82, - type: 'white.sql', - language: 'sql', - }, - { - offset: 83, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 85, - type: 'white.sql', - language: 'sql', - }, - { - offset: 86, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 93, - type: 'white.sql', - language: 'sql', - }, - { - offset: 94, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 98, - type: 'white.sql', - language: 'sql', - }, - { - offset: 99, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 104, - type: 'white.sql', - language: 'sql', - }, - { - offset: 105, - type: 'number.sql', - language: 'sql', - }, - { - offset: 107, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/singleLineMultipleColumns.ts b/public/app/features/plugins/sql/mocks/queries/singleLineMultipleColumns.ts deleted file mode 100644 index ced9a273474..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/singleLineMultipleColumns.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const singleLineMultipleColumns: TestQueryModel = { - query: - 'SELECT count(column1), column2 FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1, avg(column2) DESC LIMIT 10;', - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 12, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 13, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 20, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 21, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - { - offset: 23, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 30, - type: 'white.sql', - language: 'sql', - }, - { - offset: 31, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 35, - type: 'white.sql', - language: 'sql', - }, - { - offset: 36, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 42, - type: 'white.sql', - language: 'sql', - }, - { - offset: 43, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 48, - type: 'white.sql', - language: 'sql', - }, - { - offset: 49, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 56, - type: 'white.sql', - language: 'sql', - }, - { - offset: 57, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 58, - type: 'white.sql', - language: 'sql', - }, - { - offset: 59, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 60, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 66, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 67, - type: 'white.sql', - language: 'sql', - }, - { - offset: 68, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 73, - type: 'white.sql', - language: 'sql', - }, - { - offset: 74, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 76, - type: 'white.sql', - language: 'sql', - }, - { - offset: 77, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 84, - type: 'white.sql', - language: 'sql', - }, - { - offset: 85, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 90, - type: 'white.sql', - language: 'sql', - }, - { - offset: 91, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 93, - type: 'white.sql', - language: 'sql', - }, - { - offset: 94, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 101, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 102, - type: 'white.sql', - language: 'sql', - }, - { - offset: 103, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 106, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 107, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 114, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 115, - type: 'white.sql', - language: 'sql', - }, - { - offset: 116, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 120, - type: 'white.sql', - language: 'sql', - }, - { - offset: 121, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 126, - type: 'white.sql', - language: 'sql', - }, - { - offset: 127, - type: 'number.sql', - language: 'sql', - }, - { - offset: 129, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/singleLineTwoQueries.ts b/public/app/features/plugins/sql/mocks/queries/singleLineTwoQueries.ts deleted file mode 100644 index 141f797ed30..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/singleLineTwoQueries.ts +++ /dev/null @@ -1,385 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const singleLineTwoQueries: TestQueryModel = { - query: - 'SELECT column1, FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10; SELECT column2, FROM table2 WHERE column2 = "value2" GROUP BY column1 ORDER BY column2 DESC LIMIT 10;', - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 14, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 15, - type: 'white.sql', - language: 'sql', - }, - { - offset: 16, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 20, - type: 'white.sql', - language: 'sql', - }, - { - offset: 21, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 27, - type: 'white.sql', - language: 'sql', - }, - { - offset: 28, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 33, - type: 'white.sql', - language: 'sql', - }, - { - offset: 34, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 41, - type: 'white.sql', - language: 'sql', - }, - { - offset: 42, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 43, - type: 'white.sql', - language: 'sql', - }, - { - offset: 44, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 45, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 51, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 52, - type: 'white.sql', - language: 'sql', - }, - { - offset: 53, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 58, - type: 'white.sql', - language: 'sql', - }, - { - offset: 59, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 61, - type: 'white.sql', - language: 'sql', - }, - { - offset: 62, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 69, - type: 'white.sql', - language: 'sql', - }, - { - offset: 70, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 75, - type: 'white.sql', - language: 'sql', - }, - { - offset: 76, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 78, - type: 'white.sql', - language: 'sql', - }, - { - offset: 79, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 86, - type: 'white.sql', - language: 'sql', - }, - { - offset: 87, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 91, - type: 'white.sql', - language: 'sql', - }, - { - offset: 92, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 97, - type: 'white.sql', - language: 'sql', - }, - { - offset: 98, - type: 'number.sql', - language: 'sql', - }, - { - offset: 100, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 101, - type: 'white.sql', - language: 'sql', - }, - { - offset: 102, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 108, - type: 'white.sql', - language: 'sql', - }, - { - offset: 109, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 116, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 117, - type: 'white.sql', - language: 'sql', - }, - { - offset: 118, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 122, - type: 'white.sql', - language: 'sql', - }, - { - offset: 123, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 129, - type: 'white.sql', - language: 'sql', - }, - { - offset: 130, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 135, - type: 'white.sql', - language: 'sql', - }, - { - offset: 136, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 143, - type: 'white.sql', - language: 'sql', - }, - { - offset: 144, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 145, - type: 'white.sql', - language: 'sql', - }, - { - offset: 146, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 147, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 153, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 154, - type: 'white.sql', - language: 'sql', - }, - { - offset: 155, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 160, - type: 'white.sql', - language: 'sql', - }, - { - offset: 161, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 163, - type: 'white.sql', - language: 'sql', - }, - { - offset: 164, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 171, - type: 'white.sql', - language: 'sql', - }, - { - offset: 172, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 177, - type: 'white.sql', - language: 'sql', - }, - { - offset: 178, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 180, - type: 'white.sql', - language: 'sql', - }, - { - offset: 181, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 188, - type: 'white.sql', - language: 'sql', - }, - { - offset: 189, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 193, - type: 'white.sql', - language: 'sql', - }, - { - offset: 194, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 199, - type: 'white.sql', - language: 'sql', - }, - { - offset: 200, - type: 'number.sql', - language: 'sql', - }, - { - offset: 202, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ], -}; diff --git a/public/app/features/plugins/sql/mocks/queries/singleLineTwoQueriesWithAggregation.ts b/public/app/features/plugins/sql/mocks/queries/singleLineTwoQueriesWithAggregation.ts deleted file mode 100644 index 371bc9a7588..00000000000 --- a/public/app/features/plugins/sql/mocks/queries/singleLineTwoQueriesWithAggregation.ts +++ /dev/null @@ -1,415 +0,0 @@ -import { TestQueryModel } from '../../test-utils/types'; - -export const singleLineTwoQueriesWithAggregation: TestQueryModel = { - query: - 'SELECT count(column1), FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10; SELECT count(column2), FROM table2 WHERE column2 = "value2" GROUP BY column1 ORDER BY column2 DESC LIMIT 10;', - tokens: [ - [ - { - offset: 0, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 6, - type: 'white.sql', - language: 'sql', - }, - { - offset: 7, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 12, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 13, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 20, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 21, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 22, - type: 'white.sql', - language: 'sql', - }, - { - offset: 23, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 27, - type: 'white.sql', - language: 'sql', - }, - { - offset: 28, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 34, - type: 'white.sql', - language: 'sql', - }, - { - offset: 35, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 40, - type: 'white.sql', - language: 'sql', - }, - { - offset: 41, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 48, - type: 'white.sql', - language: 'sql', - }, - { - offset: 49, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 50, - type: 'white.sql', - language: 'sql', - }, - { - offset: 51, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 52, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 58, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 59, - type: 'white.sql', - language: 'sql', - }, - { - offset: 60, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 65, - type: 'white.sql', - language: 'sql', - }, - { - offset: 66, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 68, - type: 'white.sql', - language: 'sql', - }, - { - offset: 69, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 76, - type: 'white.sql', - language: 'sql', - }, - { - offset: 77, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 82, - type: 'white.sql', - language: 'sql', - }, - { - offset: 83, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 85, - type: 'white.sql', - language: 'sql', - }, - { - offset: 86, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 93, - type: 'white.sql', - language: 'sql', - }, - { - offset: 94, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 98, - type: 'white.sql', - language: 'sql', - }, - { - offset: 99, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 104, - type: 'white.sql', - language: 'sql', - }, - { - offset: 105, - type: 'number.sql', - language: 'sql', - }, - { - offset: 107, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 108, - type: 'white.sql', - language: 'sql', - }, - { - offset: 109, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 115, - type: 'white.sql', - language: 'sql', - }, - { - offset: 116, - type: 'predefined.sql', - language: 'sql', - }, - { - offset: 121, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 122, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 129, - type: 'delimiter.parenthesis.sql', - language: 'sql', - }, - { - offset: 130, - type: 'delimiter.sql', - language: 'sql', - }, - { - offset: 131, - type: 'white.sql', - language: 'sql', - }, - { - offset: 132, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 136, - type: 'white.sql', - language: 'sql', - }, - { - offset: 137, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 143, - type: 'white.sql', - language: 'sql', - }, - { - offset: 144, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 149, - type: 'white.sql', - language: 'sql', - }, - { - offset: 150, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 157, - type: 'white.sql', - language: 'sql', - }, - { - offset: 158, - type: 'operator.sql', - language: 'sql', - }, - { - offset: 159, - type: 'white.sql', - language: 'sql', - }, - { - offset: 160, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 161, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 167, - type: 'identifier.quote.sql', - language: 'sql', - }, - { - offset: 168, - type: 'white.sql', - language: 'sql', - }, - { - offset: 169, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 174, - type: 'white.sql', - language: 'sql', - }, - { - offset: 175, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 177, - type: 'white.sql', - language: 'sql', - }, - { - offset: 178, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 185, - type: 'white.sql', - language: 'sql', - }, - { - offset: 186, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 191, - type: 'white.sql', - language: 'sql', - }, - { - offset: 192, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 194, - type: 'white.sql', - language: 'sql', - }, - { - offset: 195, - type: 'identifier.sql', - language: 'sql', - }, - { - offset: 202, - type: 'white.sql', - language: 'sql', - }, - { - offset: 203, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 207, - type: 'white.sql', - language: 'sql', - }, - { - offset: 208, - type: 'keyword.sql', - language: 'sql', - }, - { - offset: 213, - type: 'white.sql', - language: 'sql', - }, - { - offset: 214, - type: 'number.sql', - language: 'sql', - }, - { - offset: 216, - type: 'delimiter.sql', - language: 'sql', - }, - ], - ], -}; diff --git a/public/app/features/plugins/sql/mocks/testData.ts b/public/app/features/plugins/sql/mocks/testData.ts deleted file mode 100644 index 5903ae8e055..00000000000 --- a/public/app/features/plugins/sql/mocks/testData.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { singleLineFullQuery } from './queries/singleLineFullQuery'; -export { singleLineFullQueryWithAggregation } from './queries/singleLineFullQueryWithAggregation'; -export { multiLineFullQuery } from './queries/multiLineFullQuery'; -export { multiLineFullQueryWithAggregation } from './queries/multiLineFullQueryWithAggregation'; -export { singleLineEmptyQuery } from './queries/singleLineEmptyQuery'; -export { singleLineTwoQueries } from './queries/singleLineTwoQueries'; -export { singleLineTwoQueriesWithAggregation } from './queries/singleLineTwoQueriesWithAggregation'; -export { singleLineMultipleColumns } from './queries/singleLineMultipleColumns'; -export { multiLineMultipleColumns } from './queries/multiLineMultipleColumns'; diff --git a/public/app/features/plugins/sql/standardSql/definition.ts b/public/app/features/plugins/sql/standardSql/definition.ts deleted file mode 100644 index c7cc7c77dd5..00000000000 --- a/public/app/features/plugins/sql/standardSql/definition.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -import { SQLMonarchLanguage } from './types'; - -export type LanguageDefinition = { - id: string; - extensions: string[]; - aliases: string[]; - mimetypes: string[]; - loader: (monaco: any) => Promise<{ - language: SQLMonarchLanguage; - conf: monacoTypes.languages.LanguageConfiguration; - }>; -}; - -const standardSQLLanguageDefinition: LanguageDefinition = { - id: 'standardSql', - extensions: ['.sql'], - aliases: ['sql'], - mimetypes: [], - loader: () => import('./language'), -}; - -export default standardSQLLanguageDefinition; diff --git a/public/app/features/plugins/sql/standardSql/getStandardSuggestions.test.ts b/public/app/features/plugins/sql/standardSql/getStandardSuggestions.test.ts deleted file mode 100644 index 5ec9e346f5f..00000000000 --- a/public/app/features/plugins/sql/standardSql/getStandardSuggestions.test.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { Registry } from '@grafana/data'; -import { monacoTypes } from '@grafana/ui'; - -import { getMonacoMock } from '../mocks/Monaco'; -import { TextModel } from '../mocks/TextModel'; -import { singleLineFullQuery } from '../mocks/testData'; -import { OperatorType, SuggestionKind, CustomSuggestion, PositionContext, MacroType } from '../types'; -import { linkedTokenBuilder } from '../utils/linkedTokenBuilder'; - -import { getStandardSuggestions } from './getStandardSuggestions'; -import { initStandardSuggestions } from './standardSuggestionsRegistry'; -import { FunctionsRegistryItem, MacrosRegistryItem, OperatorsRegistryItem, SuggestionsRegistryItem } from './types'; - -describe('getStandardSuggestions', () => { - const mockQueries = new Map>>>(); - const cases = [{ query: singleLineFullQuery, position: { line: 1, column: 0 } }]; - cases.forEach((c) => mockQueries.set(c.query.query, c.query.tokens)); - const MonacoMock = getMonacoMock(mockQueries); - const token = linkedTokenBuilder(MonacoMock, TextModel(singleLineFullQuery.query) as monacoTypes.editor.ITextModel, { - lineNumber: 1, - column: 0, - }); - const posContextMock = {}; - - it('calls the resolvers', async () => { - const suggestionMock: CustomSuggestion = { label: 'customSuggest' }; - const resolveFunctionSpy = jest.fn().mockReturnValue([suggestionMock]); - const kind = 'customSuggestionItemKind' as SuggestionKind; - const suggestionsRegistry = new Registry(() => { - return [ - { - id: kind, - name: 'customSuggestionItemKind', - suggestions: resolveFunctionSpy, - }, - ]; - }); - const result = await getStandardSuggestions( - MonacoMock, - token, - [kind], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(resolveFunctionSpy).toBeCalledTimes(1); - expect(resolveFunctionSpy).toBeCalledWith({ range: token!.range }, MonacoMock); - - expect(result).toHaveLength(1); - expect(result[0].label).toEqual(suggestionMock.label); - }); - - it('suggests custom functions with arguments from the registry', async () => { - const customFunction = { - name: 'customFunction', - id: 'customFunction', - }; - - const suggestionsRegistry = new Registry( - initStandardSuggestions( - new Registry(() => [customFunction]), - new Registry(() => []), - new Registry(() => []) - ) - ); - - const result = await getStandardSuggestions( - MonacoMock, - token, - [SuggestionKind.FunctionsWithArguments], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(result).toHaveLength(1); - expect(result[0].label).toEqual(customFunction.name); - }); - - it('suggests custom functions without arguments from the registry', async () => { - const customFunction = { - name: 'customFunction', - id: 'customFunction', - }; - - const suggestionsRegistry = new Registry( - initStandardSuggestions( - new Registry(() => [customFunction]), - new Registry(() => []), - new Registry(() => []) - ) - ); - - const result = await getStandardSuggestions( - MonacoMock, - token, - [SuggestionKind.FunctionsWithoutArguments], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(result).toHaveLength(1); - expect(result[0].label).toEqual(customFunction.name); - }); - - it('suggests custom logical operators from the registry', async () => { - const customLogicalOperator = { - type: OperatorType.Logical, - name: 'customOperator', - id: 'customOperator', - operator: '½', - }; - - const suggestionsRegistry = new Registry( - initStandardSuggestions( - new Registry(() => []), - new Registry(() => [customLogicalOperator]), - new Registry(() => []) - ) - ); - - const result = await getStandardSuggestions( - MonacoMock, - token, - [SuggestionKind.LogicalOperators], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(result).toHaveLength(1); - expect(result[0].label).toEqual(customLogicalOperator.operator); - }); - - it('suggests custom comparison operators from the registry', async () => { - const customComparisonOperator = { - type: OperatorType.Comparison, - name: 'customOperator', - id: 'customOperator', - operator: '§', - }; - - const suggestionsRegistry = new Registry( - initStandardSuggestions( - new Registry(() => []), - new Registry(() => [customComparisonOperator]), - new Registry(() => []) - ) - ); - - const result = await getStandardSuggestions( - MonacoMock, - token, - [SuggestionKind.ComparisonOperators], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(result).toHaveLength(5); - expect(result[0].label).toEqual(customComparisonOperator.operator); - }); - - it('does not suggest logical operators when asked for comparison operators', async () => { - const customLogicalOperator = { - type: OperatorType.Logical, - name: 'customOperator', - id: 'customOperator', - operator: '§', - }; - - const suggestionsRegistry = new Registry( - initStandardSuggestions( - new Registry(() => []), - new Registry(() => [customLogicalOperator]), - new Registry(() => []) - ) - ); - - const result = await getStandardSuggestions( - MonacoMock, - token, - [SuggestionKind.ComparisonOperators], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(result).toHaveLength(4); - }); - - it('suggests $__time(dateColumn) macro when in column position', async () => { - const customMacro: MacrosRegistryItem = { - name: '$__time', - id: '$__time', - text: '$__time', - type: MacroType.Value, - }; - - const suggestionsRegistry = new Registry( - initStandardSuggestions( - new Registry(() => []), - new Registry(() => []), - new Registry(() => [customMacro]) - ) - ); - - const result = await getStandardSuggestions( - MonacoMock, - token, - [SuggestionKind.SelectMacro], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(result).toHaveLength(1); - expect(result[0].label).toEqual('$__time'); - }); - - it('suggests SELECT and SELECT FROM from the standard registry', async () => { - const suggestionsRegistry = new Registry( - initStandardSuggestions( - new Registry(() => []), - new Registry(() => []), - new Registry(() => []) - ) - ); - - const result = await getStandardSuggestions( - MonacoMock, - token, - [SuggestionKind.SelectKeyword], - posContextMock as PositionContext, - suggestionsRegistry - ); - - expect(result).toHaveLength(2); - expect(result).toMatchInlineSnapshot(` - Array [ - Object { - "command": Object { - "id": "editor.action.triggerSuggest", - "title": "", - }, - "insertText": "SELECT $0", - "insertTextRules": 4, - "kind": 27, - "label": "SELECT ", - "range": Object { - "endColumn": 7, - "endLineNumber": 1, - "startColumn": 0, - "startLineNumber": 1, - }, - "sortText": "g", - }, - Object { - "command": Object { - "id": "editor.action.triggerSuggest", - "title": "", - }, - "insertText": "SELECT $2 FROM $1", - "insertTextRules": 4, - "kind": 27, - "label": "SELECT FROM ", - "range": Object { - "endColumn": 7, - "endLineNumber": 1, - "startColumn": 0, - "startLineNumber": 1, - }, - "sortText": "g", - }, - ] - `); - }); -}); diff --git a/public/app/features/plugins/sql/standardSql/getStandardSuggestions.ts b/public/app/features/plugins/sql/standardSql/getStandardSuggestions.ts deleted file mode 100644 index deff3e04679..00000000000 --- a/public/app/features/plugins/sql/standardSql/getStandardSuggestions.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Registry } from '@grafana/data'; -import { Monaco, monacoTypes } from '@grafana/ui'; - -import { PositionContext, SuggestionKind } from '../types'; -import { LinkedToken } from '../utils/LinkedToken'; -import { toCompletionItem } from '../utils/toCompletionItem'; - -import { SuggestionsRegistryItem } from './types'; - -// Given standard and custom registered suggestions and kinds of suggestion expected, return a list of completion items -export const getStandardSuggestions = async ( - monaco: Monaco, - currentToken: LinkedToken | null, - suggestionKinds: SuggestionKind[], - positionContext: PositionContext, - suggestionsRegistry: Registry -): Promise => { - let suggestions: monacoTypes.languages.CompletionItem[] = []; - const invalidRangeToken = currentToken?.isWhiteSpace() || currentToken?.isParenthesis(); - const range = - invalidRangeToken || !currentToken?.range - ? monaco.Range.fromPositions(positionContext.position) - : currentToken?.range; - - // iterating over Set to deduplicate - for (const suggestion of [...new Set(suggestionKinds)]) { - const registeredSuggestions = suggestionsRegistry.getIfExists(suggestion); - if (registeredSuggestions) { - const su = await registeredSuggestions.suggestions({ ...positionContext, range }, monaco); - suggestions = [...suggestions, ...su.map((s) => toCompletionItem(s.label, range, { kind: s.kind, ...s }))]; - } - } - return Promise.resolve(suggestions); -}; diff --git a/public/app/features/plugins/sql/standardSql/getStatementPosition.test.ts b/public/app/features/plugins/sql/standardSql/getStatementPosition.test.ts deleted file mode 100644 index 5f6646f4e52..00000000000 --- a/public/app/features/plugins/sql/standardSql/getStatementPosition.test.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { - multiLineFullQuery, - multiLineFullQueryWithAggregation, - multiLineMultipleColumns, - singleLineEmptyQuery, - singleLineFullQuery, - singleLineFullQueryWithAggregation, - singleLineMultipleColumns, - singleLineTwoQueries, - singleLineTwoQueriesWithAggregation, -} from '../mocks/testData'; -import { testStatementPosition } from '../test-utils/statementPosition'; -import { StatementPosition } from '../types'; - -import { initStatementPositionResolvers } from './statementPositionResolversRegistry'; - -const templateSrvMock = { replace: jest.fn(), getVariables: () => [], getAdhocFilters: jest.fn() }; -jest.mock('@grafana/runtime', () => ({ - ...(jest.requireActual('@grafana/runtime') as unknown as object), - getTemplateSrv: () => templateSrvMock, -})); - -describe('statementPosition', () => { - testStatementPosition( - StatementPosition.SelectKeyword, - [ - { query: singleLineEmptyQuery, position: { line: 1, column: 0 } }, - { query: singleLineFullQuery, position: { line: 1, column: 0 } }, - { query: multiLineFullQuery, position: { line: 1, column: 0 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 103 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterSelectKeyword, - [ - { query: singleLineFullQuery, position: { line: 1, column: 7 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 109 } }, - { query: multiLineFullQuery, position: { line: 1, column: 7 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterSelectArguments, - [ - { query: singleLineFullQuery, position: { line: 1, column: 16 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 16 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 118 } }, - { query: multiLineFullQuery, position: { line: 1, column: 16 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterSelectFuncFirstArgument, - [ - { query: singleLineFullQueryWithAggregation, position: { line: 1, column: 14 } }, - { query: multiLineFullQueryWithAggregation, position: { line: 1, column: 14 } }, - { query: singleLineTwoQueriesWithAggregation, position: { line: 1, column: 128 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.FromKeyword, - [ - { query: singleLineFullQuery, position: { line: 1, column: 17 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 119 } }, - { query: multiLineFullQuery, position: { line: 2, column: 0 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterFromKeyword, - [ - { query: singleLineFullQuery, position: { line: 1, column: 21 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 123 } }, - { query: multiLineFullQuery, position: { line: 2, column: 5 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterFrom, - [ - { query: singleLineFullQuery, position: { line: 1, column: 28 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 130 } }, - { query: multiLineFullQuery, position: { line: 2, column: 12 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.WhereKeyword, - [ - { query: singleLineFullQuery, position: { line: 1, column: 34 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 136 } }, - { query: multiLineFullQuery, position: { line: 4, column: 6 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.WhereComparisonOperator, - [ - { query: singleLineFullQuery, position: { line: 1, column: 43 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 145 } }, - { query: multiLineFullQuery, position: { line: 4, column: 15 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.WhereValue, - [ - { query: singleLineFullQuery, position: { line: 1, column: 44 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 146 } }, - { query: multiLineFullQuery, position: { line: 4, column: 16 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterWhereValue, - [ - { query: singleLineFullQuery, position: { line: 1, column: 53 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 155 } }, - { query: multiLineFullQuery, position: { line: 4, column: 25 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterGroupByKeywords, - [ - { query: singleLineFullQuery, position: { line: 1, column: 63 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 167 } }, - { query: multiLineFullQuery, position: { line: 5, column: 11 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterGroupBy, - [ - { query: singleLineFullQuery, position: { line: 1, column: 71 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 173 } }, - { query: multiLineFullQuery, position: { line: 5, column: 18 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterOrderByKeywords, - [ - { query: singleLineFullQuery, position: { line: 1, column: 80 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 181 } }, - { query: multiLineFullQuery, position: { line: 5, column: 26 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterOrderByFunction, - [ - { query: singleLineMultipleColumns, position: { line: 1, column: 108 } }, - { query: multiLineMultipleColumns, position: { line: 5, column: 40 } }, - ], - initStatementPositionResolvers - ); - - testStatementPosition( - StatementPosition.AfterOrderByDirection, - [ - { query: singleLineFullQuery, position: { line: 1, column: 92 } }, - { query: singleLineTwoQueries, position: { line: 1, column: 196 } }, - { query: multiLineFullQuery, position: { line: 5, column: 39 } }, - ], - initStatementPositionResolvers - ); -}); diff --git a/public/app/features/plugins/sql/standardSql/getStatementPosition.ts b/public/app/features/plugins/sql/standardSql/getStatementPosition.ts deleted file mode 100644 index a6c75e84715..00000000000 --- a/public/app/features/plugins/sql/standardSql/getStatementPosition.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Registry } from '@grafana/data'; - -import { StatementPosition, TokenType } from '../types'; -import { LinkedToken } from '../utils/LinkedToken'; - -import { StatementPositionResolversRegistryItem } from './types'; - -// Given current cursor position in the SQL editor, returns the statement position. -export function getStatementPosition( - currentToken: LinkedToken | null, - statementPositionResolversRegistry: Registry -): StatementPosition[] { - const previousNonWhiteSpace = currentToken?.getPreviousNonWhiteSpaceToken(); - const previousKeyword = currentToken?.getPreviousKeyword(); - const previousIsSlash = currentToken?.getPreviousNonWhiteSpaceToken()?.is(TokenType.Operator, '/'); - const resolvers = statementPositionResolversRegistry.list(); - const positions = []; - - for (const resolver of resolvers) { - if ( - resolver.resolve(currentToken, previousKeyword ?? null, previousNonWhiteSpace ?? null, Boolean(previousIsSlash)) - ) { - positions.push(resolver.id); - } - } - - if (positions.length === 0) { - return [StatementPosition.Unknown]; - } - return positions; -} diff --git a/public/app/features/plugins/sql/standardSql/language.ts b/public/app/features/plugins/sql/standardSql/language.ts deleted file mode 100644 index 70d6707f49c..00000000000 --- a/public/app/features/plugins/sql/standardSql/language.ts +++ /dev/null @@ -1,880 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -import { SQLMonarchLanguage } from './types'; - -// STD basic SQL -export const SELECT = 'select'; -export const FROM = 'from'; -export const WHERE = 'where'; -export const GROUP = 'group'; -export const ORDER = 'order'; -export const BY = 'by'; -export const DESC = 'desc'; -export const ASC = 'asc'; -export const LIMIT = 'limit'; -export const WITH = 'with'; -export const AS = 'as'; -export const SCHEMA = 'schema'; - -export const STD_STATS = ['AVG', 'COUNT', 'MAX', 'MIN', 'SUM']; - -export const AND = 'AND'; -export const OR = 'OR'; -export const LOGICAL_OPERATORS = [AND, OR]; - -export const EQUALS = '='; -export const NOT_EQUALS = '!='; -export const COMPARISON_OPERATORS = [EQUALS, NOT_EQUALS]; - -export const STD_OPERATORS = [...COMPARISON_OPERATORS]; - -export const conf: monacoTypes.languages.LanguageConfiguration = { - comments: { - lineComment: '--', - blockComment: ['/*', '*/'], - }, - brackets: [ - ['{', '}'], - ['[', ']'], - ['(', ')'], - ], - autoClosingPairs: [ - { open: '{', close: '}' }, - { open: '[', close: ']' }, - { open: '(', close: ')' }, - { open: '"', close: '"' }, - { open: "'", close: "'" }, - ], - surroundingPairs: [ - { open: '{', close: '}' }, - { open: '[', close: ']' }, - { open: '(', close: ')' }, - { open: '"', close: '"' }, - { open: "'", close: "'" }, - ], -}; - -// based on https://github.com/microsoft/monaco-editor/blob/main/src/basic-languages/sql/sql.ts -export const language: SQLMonarchLanguage = { - defaultToken: '', - tokenPostfix: '.sql', - ignoreCase: true, - - brackets: [ - { open: '[', close: ']', token: 'delimiter.square' }, - { open: '(', close: ')', token: 'delimiter.parenthesis' }, - ], - - keywords: [ - 'ABORT', - 'ABSOLUTE', - 'ACTION', - 'ADA', - 'ADD', - 'AFTER', - 'ALL', - 'ALLOCATE', - 'ALTER', - 'ALWAYS', - 'ANALYZE', - 'AND', - 'ANY', - 'ARE', - 'AS', - 'ASC', - 'ASSERTION', - 'AT', - 'ATTACH', - 'AUTHORIZATION', - 'AUTOINCREMENT', - 'AVG', - 'BACKUP', - 'BEFORE', - 'BEGIN', - 'BETWEEN', - 'BIT', - 'BIT_LENGTH', - 'BOTH', - 'BREAK', - 'BROWSE', - 'BULK', - 'BY', - 'CASCADE', - 'CASCADED', - 'CASE', - 'CAST', - 'CATALOG', - 'CHAR', - 'CHARACTER', - 'CHARACTER_LENGTH', - 'CHAR_LENGTH', - 'CHECK', - 'CHECKPOINT', - 'CLOSE', - 'CLUSTERED', - 'COALESCE', - 'COLLATE', - 'COLLATION', - 'COLUMN', - 'COMMIT', - 'COMPUTE', - 'CONFLICT', - 'CONNECT', - 'CONNECTION', - 'CONSTRAINT', - 'CONSTRAINTS', - 'CONTAINS', - 'CONTAINSTABLE', - 'CONTINUE', - 'CONVERT', - 'CORRESPONDING', - 'COUNT', - 'CREATE', - 'CROSS', - 'CURRENT', - 'CURRENT_DATE', - 'CURRENT_TIME', - 'CURRENT_TIMESTAMP', - 'CURRENT_USER', - 'CURSOR', - 'DATABASE', - 'DATE', - 'DAY', - 'DBCC', - 'DEALLOCATE', - 'DEC', - 'DECIMAL', - 'DECLARE', - 'DEFAULT', - 'DEFERRABLE', - 'DEFERRED', - 'DELETE', - 'DENY', - 'DESC', - 'DESCRIBE', - 'DESCRIPTOR', - 'DETACH', - 'DIAGNOSTICS', - 'DISCONNECT', - 'DISK', - 'DISTINCT', - 'DISTRIBUTED', - 'DO', - 'DOMAIN', - 'DOUBLE', - 'DROP', - 'DUMP', - 'EACH', - 'ELSE', - 'END', - 'END-EXEC', - 'ERRLVL', - 'ESCAPE', - 'EXCEPT', - 'EXCEPTION', - 'EXCLUDE', - 'EXCLUSIVE', - 'EXEC', - 'EXECUTE', - 'EXISTS', - 'EXIT', - 'EXPLAIN', - 'EXTERNAL', - 'EXTRACT', - 'FAIL', - 'FALSE', - 'FETCH', - 'FILE', - 'FILLFACTOR', - 'FILTER', - 'FIRST', - 'FLOAT', - 'FOLLOWING', - 'FOR', - 'FOREIGN', - 'FORTRAN', - 'FOUND', - 'FREETEXT', - 'FREETEXTTABLE', - 'FROM', - 'FULL', - 'FUNCTION', - 'GENERATED', - 'GET', - 'GLOB', - 'GLOBAL', - 'GO', - 'GOTO', - 'GRANT', - 'GROUP', - 'GROUPS', - 'HAVING', - 'HOLDLOCK', - 'HOUR', - 'IDENTITY', - 'IDENTITYCOL', - 'IDENTITY_INSERT', - 'IF', - 'IGNORE', - 'IMMEDIATE', - 'IN', - 'INCLUDE', - 'INDEX', - 'INDEXED', - 'INDICATOR', - 'INITIALLY', - 'INNER', - 'INPUT', - 'INSENSITIVE', - 'INSERT', - 'INSTEAD', - 'INT', - 'INTEGER', - 'INTERSECT', - 'INTERVAL', - 'INTO', - 'IS', - 'ISNULL', - 'ISOLATION', - 'JOIN', - 'KEY', - 'KILL', - 'LANGUAGE', - 'LAST', - 'LEADING', - 'LEFT', - 'LEVEL', - 'LIKE', - 'LIMIT', - 'LINENO', - 'LOAD', - 'LOCAL', - 'LOWER', - 'MATCH', - 'MATERIALIZED', - 'MAX', - 'MERGE', - 'MIN', - 'MINUTE', - 'MODULE', - 'MONTH', - 'NAMES', - 'NATIONAL', - 'NATURAL', - 'NCHAR', - 'NEXT', - 'NO', - 'NOCHECK', - 'NONCLUSTERED', - 'NONE', - 'NOT', - 'NOTHING', - 'NOTNULL', - 'NULL', - 'NULLIF', - 'NULLS', - 'NUMERIC', - 'OCTET_LENGTH', - 'OF', - 'OFF', - 'OFFSET', - 'OFFSETS', - 'ON', - 'ONLY', - 'OPEN', - 'OPENDATASOURCE', - 'OPENQUERY', - 'OPENROWSET', - 'OPENXML', - 'OPTION', - 'OR', - 'ORDER', - 'OTHERS', - 'OUTER', - 'OUTPUT', - 'OVER', - 'OVERLAPS', - 'PAD', - 'PARTIAL', - 'PARTITION', - 'PASCAL', - 'PERCENT', - 'PIVOT', - 'PLAN', - 'POSITION', - 'PRAGMA', - 'PRECEDING', - 'PRECISION', - 'PREPARE', - 'PRESERVE', - 'PRIMARY', - 'PRINT', - 'PRIOR', - 'PRIVILEGES', - 'PROC', - 'PROCEDURE', - 'PUBLIC', - 'QUERY', - 'RAISE', - 'RAISERROR', - 'RANGE', - 'READ', - 'READTEXT', - 'REAL', - 'RECONFIGURE', - 'RECURSIVE', - 'REFERENCES', - 'REGEXP', - 'REINDEX', - 'RELATIVE', - 'RELEASE', - 'RENAME', - 'REPLACE', - 'REPLICATION', - 'RESTORE', - 'RESTRICT', - 'RETURN', - 'RETURNING', - 'REVERT', - 'REVOKE', - 'RIGHT', - 'ROLLBACK', - 'ROW', - 'ROWCOUNT', - 'ROWGUIDCOL', - 'ROWS', - 'RULE', - 'SAVE', - 'SAVEPOINT', - 'SCHEMA', - 'SCROLL', - 'SECOND', - 'SECTION', - 'SECURITYAUDIT', - 'SELECT', - 'SEMANTICKEYPHRASETABLE', - 'SEMANTICSIMILARITYDETAILSTABLE', - 'SEMANTICSIMILARITYTABLE', - 'SESSION', - 'SESSION_USER', - 'SET', - 'SETUSER', - 'SHUTDOWN', - 'SIZE', - 'SMALLINT', - 'SOME', - 'SPACE', - 'SQL', - 'SQLCA', - 'SQLCODE', - 'SQLERROR', - 'SQLSTATE', - 'SQLWARNING', - 'STATISTICS', - 'SUBSTRING', - 'SUM', - 'SYSTEM_USER', - 'TABLE', - 'TABLESAMPLE', - 'TEMP', - 'TEMPORARY', - 'TEXTSIZE', - 'THEN', - 'TIES', - 'TIME', - 'TIMESTAMP', - 'TIMEZONE_HOUR', - 'TIMEZONE_MINUTE', - 'TO', - 'TOP', - 'TRAILING', - 'TRAN', - 'TRANSACTION', - 'TRANSLATE', - 'TRANSLATION', - 'TRIGGER', - 'TRIM', - 'TRUE', - 'TRUNCATE', - 'TRY_CONVERT', - 'TSEQUAL', - 'UNBOUNDED', - 'UNION', - 'UNIQUE', - 'UNKNOWN', - 'UNPIVOT', - 'UPDATE', - 'UPDATETEXT', - 'UPPER', - 'USAGE', - 'USE', - 'USER', - 'USING', - 'VACUUM', - 'VALUE', - 'VALUES', - 'VARCHAR', - 'VARYING', - 'VIEW', - 'VIRTUAL', - 'WAITFOR', - 'WHEN', - 'WHENEVER', - 'WHERE', - 'WHILE', - 'WINDOW', - 'WITH', - 'WITHIN GROUP', - 'WITHOUT', - 'WORK', - 'WRITE', - 'WRITETEXT', - 'YEAR', - 'ZONE', - ], - operators: [ - // Set - 'EXCEPT', - 'INTERSECT', - 'UNION', - // Join - 'APPLY', - 'CROSS', - 'FULL', - 'INNER', - 'JOIN', - 'LEFT', - 'OUTER', - 'RIGHT', - // Predicates - 'CONTAINS', - 'FREETEXT', - 'IS', - 'NULL', - // Pivoting - 'PIVOT', - 'UNPIVOT', - // Merging - 'MATCHED', - ], - logicalOperators: ['ALL', 'AND', 'ANY', 'BETWEEN', 'EXISTS', 'IN', 'LIKE', 'NOT', 'OR', 'SOME'], - comparisonOperators: ['<>', '>', '<', '>=', '<=', '=', '!=', '&', '~', '^', '%'], - - builtinFunctions: [ - // Aggregate - 'AVG', - 'CHECKSUM_AGG', - 'COUNT', - 'COUNT_BIG', - 'GROUPING', - 'GROUPING_ID', - 'MAX', - 'MIN', - 'SUM', - 'STDEV', - 'STDEVP', - 'VAR', - 'VARP', - // Analytic - 'CUME_DIST', - 'FIRST_VALUE', - 'LAG', - 'LAST_VALUE', - 'LEAD', - 'PERCENTILE_CONT', - 'PERCENTILE_DISC', - 'PERCENT_RANK', - // Collation - 'COLLATE', - 'COLLATIONPROPERTY', - 'TERTIARY_WEIGHTS', - // Azure - 'FEDERATION_FILTERING_VALUE', - // Conversion - 'CAST', - 'CONVERT', - 'PARSE', - 'TRY_CAST', - 'TRY_CONVERT', - 'TRY_PARSE', - // Cryptographic - 'ASYMKEY_ID', - 'ASYMKEYPROPERTY', - 'CERTPROPERTY', - 'CERT_ID', - 'CRYPT_GEN_RANDOM', - 'DECRYPTBYASYMKEY', - 'DECRYPTBYCERT', - 'DECRYPTBYKEY', - 'DECRYPTBYKEYAUTOASYMKEY', - 'DECRYPTBYKEYAUTOCERT', - 'DECRYPTBYPASSPHRASE', - 'ENCRYPTBYASYMKEY', - 'ENCRYPTBYCERT', - 'ENCRYPTBYKEY', - 'ENCRYPTBYPASSPHRASE', - 'HASHBYTES', - 'IS_OBJECTSIGNED', - 'KEY_GUID', - 'KEY_ID', - 'KEY_NAME', - 'SIGNBYASYMKEY', - 'SIGNBYCERT', - 'SYMKEYPROPERTY', - 'VERIFYSIGNEDBYCERT', - 'VERIFYSIGNEDBYASYMKEY', - // Cursor - 'CURSOR_STATUS', - // Datatype - 'DATALENGTH', - 'IDENT_CURRENT', - 'IDENT_INCR', - 'IDENT_SEED', - 'IDENTITY', - 'SQL_VARIANT_PROPERTY', - // Datetime - 'CURRENT_TIMESTAMP', - 'DATEADD', - 'DATEDIFF', - 'DATEFROMPARTS', - 'DATENAME', - 'DATEPART', - 'DATETIME2FROMPARTS', - 'DATETIMEFROMPARTS', - 'DATETIMEOFFSETFROMPARTS', - 'DAY', - 'EOMONTH', - 'GETDATE', - 'GETUTCDATE', - 'ISDATE', - 'MONTH', - 'SMALLDATETIMEFROMPARTS', - 'SWITCHOFFSET', - 'SYSDATETIME', - 'SYSDATETIMEOFFSET', - 'SYSUTCDATETIME', - 'TIMEFROMPARTS', - 'TODATETIMEOFFSET', - 'YEAR', - // Logical - 'CHOOSE', - 'COALESCE', - 'IIF', - 'NULLIF', - // Mathematical - 'ABS', - 'ACOS', - 'ASIN', - 'ATAN', - 'ATN2', - 'CEILING', - 'COS', - 'COT', - 'DEGREES', - 'EXP', - 'FLOOR', - 'LOG', - 'LOG10', - 'PI', - 'POWER', - 'RADIANS', - 'RAND', - 'ROUND', - 'SIGN', - 'SIN', - 'SQRT', - 'SQUARE', - 'TAN', - // Metadata - 'APP_NAME', - 'APPLOCK_MODE', - 'APPLOCK_TEST', - 'ASSEMBLYPROPERTY', - 'COL_LENGTH', - 'COL_NAME', - 'COLUMNPROPERTY', - 'DATABASE_PRINCIPAL_ID', - 'DATABASEPROPERTYEX', - 'DB_ID', - 'DB_NAME', - 'FILE_ID', - 'FILE_IDEX', - 'FILE_NAME', - 'FILEGROUP_ID', - 'FILEGROUP_NAME', - 'FILEGROUPPROPERTY', - 'FILEPROPERTY', - 'FULLTEXTCATALOGPROPERTY', - 'FULLTEXTSERVICEPROPERTY', - 'INDEX_COL', - 'INDEXKEY_PROPERTY', - 'INDEXPROPERTY', - 'OBJECT_DEFINITION', - 'OBJECT_ID', - 'OBJECT_NAME', - 'OBJECT_SCHEMA_NAME', - 'OBJECTPROPERTY', - 'OBJECTPROPERTYEX', - 'ORIGINAL_DB_NAME', - 'PARSENAME', - 'SCHEMA_ID', - 'SCHEMA_NAME', - 'SCOPE_IDENTITY', - 'SERVERPROPERTY', - 'STATS_DATE', - 'TYPE_ID', - 'TYPE_NAME', - 'TYPEPROPERTY', - // Ranking - 'DENSE_RANK', - 'NTILE', - 'RANK', - 'ROW_NUMBER', - // Replication - 'PUBLISHINGSERVERNAME', - // Rowset - 'OPENDATASOURCE', - 'OPENQUERY', - 'OPENROWSET', - 'OPENXML', - // Security - 'CERTENCODED', - 'CERTPRIVATEKEY', - 'CURRENT_USER', - 'HAS_DBACCESS', - 'HAS_PERMS_BY_NAME', - 'IS_MEMBER', - 'IS_ROLEMEMBER', - 'IS_SRVROLEMEMBER', - 'LOGINPROPERTY', - 'ORIGINAL_LOGIN', - 'PERMISSIONS', - 'PWDENCRYPT', - 'PWDCOMPARE', - 'SESSION_USER', - 'SESSIONPROPERTY', - 'SUSER_ID', - 'SUSER_NAME', - 'SUSER_SID', - 'SUSER_SNAME', - 'SYSTEM_USER', - 'USER', - 'USER_ID', - 'USER_NAME', - // String - 'ASCII', - 'CHAR', - 'CHARINDEX', - 'CONCAT', - 'DIFFERENCE', - 'FORMAT', - 'LEFT', - 'LEN', - 'LOWER', - 'LTRIM', - 'NCHAR', - 'PATINDEX', - 'QUOTENAME', - 'REPLACE', - 'REPLICATE', - 'REVERSE', - 'RIGHT', - 'RTRIM', - 'SOUNDEX', - 'SPACE', - 'STR', - 'STUFF', - 'SUBSTRING', - 'UNICODE', - 'UPPER', - // System - 'BINARY_CHECKSUM', - 'CHECKSUM', - 'CONNECTIONPROPERTY', - 'CONTEXT_INFO', - 'CURRENT_REQUEST_ID', - 'ERROR_LINE', - 'ERROR_NUMBER', - 'ERROR_MESSAGE', - 'ERROR_PROCEDURE', - 'ERROR_SEVERITY', - 'ERROR_STATE', - 'FORMATMESSAGE', - 'GETANSINULL', - 'GET_FILESTREAM_TRANSACTION_CONTEXT', - 'HOST_ID', - 'HOST_NAME', - 'ISNULL', - 'ISNUMERIC', - 'MIN_ACTIVE_ROWVERSION', - 'NEWID', - 'NEWSEQUENTIALID', - 'ROWCOUNT_BIG', - 'XACT_STATE', - // TextImage - 'TEXTPTR', - 'TEXTVALID', - // Trigger - 'COLUMNS_UPDATED', - 'EVENTDATA', - 'TRIGGER_NESTLEVEL', - 'UPDATE', - // ChangeTracking - 'CHANGETABLE', - 'CHANGE_TRACKING_CONTEXT', - 'CHANGE_TRACKING_CURRENT_VERSION', - 'CHANGE_TRACKING_IS_COLUMN_IN_MASK', - 'CHANGE_TRACKING_MIN_VALID_VERSION', - // FullTextSearch - 'CONTAINSTABLE', - 'FREETEXTTABLE', - // SemanticTextSearch - 'SEMANTICKEYPHRASETABLE', - 'SEMANTICSIMILARITYDETAILSTABLE', - 'SEMANTICSIMILARITYTABLE', - // FileStream - 'FILETABLEROOTPATH', - 'GETFILENAMESPACEPATH', - 'GETPATHLOCATOR', - 'PATHNAME', - // ServiceBroker - 'GET_TRANSMISSION_STATUS', - ], - builtinVariables: [ - // Configuration - '@@DATEFIRST', - '@@DBTS', - '@@LANGID', - '@@LANGUAGE', - '@@LOCK_TIMEOUT', - '@@MAX_CONNECTIONS', - '@@MAX_PRECISION', - '@@NESTLEVEL', - '@@OPTIONS', - '@@REMSERVER', - '@@SERVERNAME', - '@@SERVICENAME', - '@@SPID', - '@@TEXTSIZE', - '@@VERSION', - // Cursor - '@@CURSOR_ROWS', - '@@FETCH_STATUS', - // Datetime - '@@DATEFIRST', - // Metadata - '@@PROCID', - // System - '@@ERROR', - '@@IDENTITY', - '@@ROWCOUNT', - '@@TRANCOUNT', - // Stats - '@@CONNECTIONS', - '@@CPU_BUSY', - '@@IDLE', - '@@IO_BUSY', - '@@PACKET_ERRORS', - '@@PACK_RECEIVED', - '@@PACK_SENT', - '@@TIMETICKS', - '@@TOTAL_ERRORS', - '@@TOTAL_READ', - '@@TOTAL_WRITE', - ], - pseudoColumns: ['$ACTION', '$IDENTITY', '$ROWGUID', '$PARTITION'], - tokenizer: { - root: [ - { include: '@templateVariables' }, - { include: '@macros' }, - { include: '@comments' }, - { include: '@whitespace' }, - { include: '@pseudoColumns' }, - { include: '@numbers' }, - { include: '@strings' }, - { include: '@complexIdentifiers' }, - { include: '@scopes' }, - [/[;,.]/, 'delimiter'], - [/[()]/, '@brackets'], - [ - /[\w@#$|<|>|=|!|%|&|+|\|-|*|/|~|^]+/, - { - cases: { - '@operators': 'operator', - '@comparisonOperators': 'operator', - '@logicalOperators': 'operator', - '@builtinVariables': 'predefined', - '@builtinFunctions': 'predefined', - '@keywords': 'keyword', - '@default': 'identifier', - }, - }, - ], - ], - templateVariables: [[/\$[a-zA-Z0-9]+/, 'variable']], - macros: [[/\$__[a-zA-Z0-9-_]+/, 'type']], - whitespace: [[/\s+/, 'white']], - comments: [ - [/--+.*/, 'comment'], - [/\/\*/, { token: 'comment.quote', next: '@comment' }], - ], - comment: [ - [/[^*/]+/, 'comment'], - // Not supporting nested comments, as nested comments seem to not be standard? - // i.e. http://stackoverflow.com/questions/728172/are-there-multiline-comment-delimiters-in-sql-that-are-vendor-agnostic - // [/\/\*/, { token: 'comment.quote', next: '@push' }], // nested comment not allowed :-( - [/\*\//, { token: 'comment.quote', next: '@pop' }], - [/./, 'comment'], - ], - pseudoColumns: [ - [ - /[$][A-Za-z_][\w@#$]*/, - { - cases: { - '@pseudoColumns': 'predefined', - '@default': 'identifier', - }, - }, - ], - ], - numbers: [ - [/0[xX][0-9a-fA-F]*/, 'number'], - [/[$][+-]*\d*(\.\d*)?/, 'number'], - [/((\d+(\.\d*)?)|(\.\d+))([eE][\-+]?\d+)?/, 'number'], - ], - strings: [ - [/N'/, { token: 'string', next: '@string' }], - [/'/, { token: 'string', next: '@string' }], - ], - string: [ - [/[^']+/, 'string'], - [/''/, 'string'], - [/'/, { token: 'string', next: '@pop' }], - ], - complexIdentifiers: [ - [/\[/, { token: 'identifier.quote', next: '@bracketedIdentifier' }], - [/"/, { token: 'identifier.quote', next: '@quotedIdentifier' }], - ], - bracketedIdentifier: [ - [/[^\]]+/, 'identifier'], - [/]]/, 'identifier'], - [/]/, { token: 'identifier.quote', next: '@pop' }], - ], - quotedIdentifier: [ - [/[^"]+/, 'identifier'], - [/""/, 'identifier'], - [/"/, { token: 'identifier.quote', next: '@pop' }], - ], - scopes: [ - [/BEGIN\s+(DISTRIBUTED\s+)?TRAN(SACTION)?\b/i, 'keyword'], - [/BEGIN\s+TRY\b/i, { token: 'keyword.try' }], - [/END\s+TRY\b/i, { token: 'keyword.try' }], - [/BEGIN\s+CATCH\b/i, { token: 'keyword.catch' }], - [/END\s+CATCH\b/i, { token: 'keyword.catch' }], - [/(BEGIN|CASE)\b/i, { token: 'keyword.block' }], - [/END\b/i, { token: 'keyword.block' }], - [/WHEN\b/i, { token: 'keyword.choice' }], - [/THEN\b/i, { token: 'keyword.choice' }], - ], - }, -}; diff --git a/public/app/features/plugins/sql/standardSql/macros.ts b/public/app/features/plugins/sql/standardSql/macros.ts deleted file mode 100644 index 28ab605382a..00000000000 --- a/public/app/features/plugins/sql/standardSql/macros.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { MacrosRegistryItem } from './types'; - -const COLUMN = 'column', - RELATIVE_TIME_STRING = "'5m'"; - -export enum MacroType { - Value, - Filter, - Group, - Column, - Table, -} - -export const MACROS: MacrosRegistryItem[] = [ - { - id: '$__timeFilter(dateColumn)', - name: '$__timeFilter(dateColumn)', - text: '$__timeFilter', - args: [COLUMN], - type: MacroType.Filter, - description: - 'Will be replaced by a time range filter using the specified column name. For example, dateColumn BETWEEN FROM_UNIXTIME(1494410783) AND FROM_UNIXTIME(1494410983)', - }, - { - id: '$__timeFrom()', - name: '$__timeFrom()', - text: '$__timeFrom', - args: [], - type: MacroType.Filter, - description: - 'Will be replaced by the start of the currently active time selection. For example, FROM_UNIXTIME(1494410783)', - }, - { - id: '$__timeTo()', - name: '$__timeTo()', - text: '$__timeTo', - args: [], - type: MacroType.Filter, - description: - 'Will be replaced by the end of the currently active time selection. For example, FROM_UNIXTIME(1494410983)', - }, - { - id: "$__timeGroup(dateColumn, '5m')", - name: "$__timeGroup(dateColumn, '5m')", - text: '$__timeGroup', - args: [COLUMN, RELATIVE_TIME_STRING], - type: MacroType.Value, - description: - 'Will be replaced by an expression usable in GROUP BY clause. For example, *cast(cast(UNIX_TIMESTAMP(dateColumn)/(300) as signed)*300 as signed),*', - }, - { - id: '$__table', - name: '$__table', - text: '$__table', - args: [], - type: MacroType.Table, - description: 'Will be replaced by the query table.', - }, - { - id: '$__column', - name: '$__column', - text: '$__column', - args: [], - type: MacroType.Column, - description: 'Will be replaced by the query column.', - }, -]; diff --git a/public/app/features/plugins/sql/standardSql/standardSuggestionsRegistry.ts b/public/app/features/plugins/sql/standardSql/standardSuggestionsRegistry.ts deleted file mode 100644 index 40283c4797d..00000000000 --- a/public/app/features/plugins/sql/standardSql/standardSuggestionsRegistry.ts +++ /dev/null @@ -1,425 +0,0 @@ -import { Registry } from '@grafana/data'; -import { getTemplateSrv } from '@grafana/runtime'; - -import { - CompletionItemInsertTextRule, - CompletionItemKind, - CompletionItemPriority, - MacroType, - OperatorType, - SuggestionKind, -} from '../types'; -import { TRIGGER_SUGGEST } from '../utils/commands'; - -import { ASC, DESC, LOGICAL_OPERATORS, STD_OPERATORS, STD_STATS } from './language'; -import { MACROS } from './macros'; -import { FunctionsRegistryItem, MacrosRegistryItem, OperatorsRegistryItem, SuggestionsRegistryItem } from './types'; - -/** - * This registry glues particular SuggestionKind with an async function that provides completion items for it. - * To add a new suggestion kind, SQLEditor should be configured with a provider that implements customSuggestionKinds. - */ - -export const initStandardSuggestions = - ( - functions: Registry, - operators: Registry, - macros: Registry - ) => - (): SuggestionsRegistryItem[] => - [ - { - id: SuggestionKind.SelectKeyword, - name: SuggestionKind.SelectKeyword, - suggestions: (_, m) => - Promise.resolve([ - { - label: `SELECT `, - insertText: `SELECT $0`, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - kind: CompletionItemKind.Snippet, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - }, - { - label: `SELECT FROM
`, - insertText: `SELECT $2 FROM $1`, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - kind: CompletionItemKind.Snippet, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - }, - ]), - }, - { - id: SuggestionKind.TemplateVariables, - name: SuggestionKind.TemplateVariables, - suggestions: (_, m) => { - const templateSrv = getTemplateSrv(); - if (!templateSrv) { - return Promise.resolve([]); - } - - return Promise.resolve( - templateSrv.getVariables().map((variable) => { - const label = `\$${variable.name}`; - const val = templateSrv.replace(label); - return { - label, - detail: `(Template Variable) ${val}`, - kind: CompletionItemKind.Snippet, - documentation: `(Template Variable) ${val}`, - insertText: `\\$${variable.name} `, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - command: TRIGGER_SUGGEST, - }; - }) - ); - }, - }, - { - id: SuggestionKind.SelectMacro, - name: SuggestionKind.SelectMacro, - suggestions: (_, m) => - Promise.resolve([ - ...macros - .list() - .filter((m) => m.type === MacroType.Value || m.type === MacroType.Column) - .map(createMacroSuggestionItem), - ]), - }, - { - id: SuggestionKind.TableMacro, - name: SuggestionKind.TableMacro, - suggestions: (_, m) => - Promise.resolve([ - ...macros - .list() - .filter((m) => m.type === MacroType.Table) - .map(createMacroSuggestionItem), - ]), - }, - { - id: SuggestionKind.GroupMacro, - name: SuggestionKind.GroupMacro, - suggestions: (_, m) => - Promise.resolve([ - ...macros - .list() - .filter((m) => m.type === MacroType.Group) - .map(createMacroSuggestionItem), - ]), - }, - { - id: SuggestionKind.FilterMacro, - name: SuggestionKind.FilterMacro, - suggestions: (_, m) => - Promise.resolve([ - ...macros - .list() - .filter((m) => m.type === MacroType.Filter) - .map(createMacroSuggestionItem), - ]), - }, - { - id: SuggestionKind.WithKeyword, - name: SuggestionKind.WithKeyword, - suggestions: (_, m) => - Promise.resolve([ - { - label: `WITH AS ( ... )`, - insertText: `WITH $1 AS ( $2 )`, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - kind: CompletionItemKind.Snippet, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - }, - ]), - }, - { - id: SuggestionKind.FunctionsWithArguments, - name: SuggestionKind.FunctionsWithArguments, - suggestions: (_, m) => - Promise.resolve([ - ...functions.list().map((f) => ({ - label: f.name, - insertText: `${f.name}($0)`, - documentation: f.description, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - kind: CompletionItemKind.Function, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumHigh, - })), - ]), - }, - { - id: SuggestionKind.FunctionsWithoutArguments, - name: SuggestionKind.FunctionsWithoutArguments, - suggestions: (_, m) => - Promise.resolve([ - ...functions.list().map((f) => ({ - label: f.name, - insertText: `${f.name}()`, - documentation: f.description, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - kind: CompletionItemKind.Function, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumHigh, - })), - ]), - }, - { - id: SuggestionKind.FromKeyword, - name: SuggestionKind.FromKeyword, - suggestions: (_, m) => - Promise.resolve([ - { - label: 'FROM', - insertText: `FROM $0`, - command: TRIGGER_SUGGEST, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - kind: CompletionItemKind.Keyword, - }, - ]), - }, - { - id: SuggestionKind.Tables, - name: SuggestionKind.Tables, - suggestions: (_, m) => Promise.resolve([]), - }, - { - id: SuggestionKind.Columns, - name: SuggestionKind.Columns, - suggestions: (_, m) => Promise.resolve([]), - }, - { - id: SuggestionKind.LogicalOperators, - name: SuggestionKind.LogicalOperators, - suggestions: (_, m) => - Promise.resolve( - operators - .list() - .filter((o) => o.type === OperatorType.Logical) - .map((o) => ({ - label: o.operator, - insertText: `${o.operator} `, - documentation: o.description, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumHigh, - kind: CompletionItemKind.Operator, - })) - ), - }, - { - id: SuggestionKind.WhereKeyword, - name: SuggestionKind.WhereKeyword, - suggestions: (_, m) => - Promise.resolve([ - { - label: 'WHERE', - insertText: `WHERE `, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumHigh, - kind: CompletionItemKind.Keyword, - }, - ]), - }, - { - id: SuggestionKind.ComparisonOperators, - name: SuggestionKind.ComparisonOperators, - suggestions: (_, m) => - Promise.resolve([ - ...operators - .list() - .filter((o) => o.type === OperatorType.Comparison) - .map((o) => ({ - label: o.operator, - insertText: `${o.operator} `, - documentation: o.description, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumHigh, - kind: CompletionItemKind.Operator, - })), - { - label: 'IN (...)', - insertText: `IN ( $0 )`, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - kind: CompletionItemKind.Operator, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - }, - { - label: 'NOT IN (...)', - insertText: `NOT IN ( $0 )`, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - kind: CompletionItemKind.Operator, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - }, - { - label: 'IS', - insertText: `IS`, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - kind: CompletionItemKind.Operator, - }, - { - label: 'IS NOT', - insertText: `IS NOT`, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - kind: CompletionItemKind.Operator, - }, - ]), - }, - { - id: SuggestionKind.GroupByKeywords, - name: SuggestionKind.GroupByKeywords, - suggestions: (_, m) => - Promise.resolve([ - { - label: 'GROUP BY', - insertText: `GROUP BY `, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumHigh, - kind: CompletionItemKind.Keyword, - }, - ]), - }, - { - id: SuggestionKind.OrderByKeywords, - name: SuggestionKind.OrderByKeywords, - suggestions: (_, m) => - Promise.resolve([ - { - label: 'ORDER BY', - insertText: `ORDER BY `, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.Medium, - kind: CompletionItemKind.Keyword, - }, - { - label: 'ORDER BY(ascending)', - insertText: `ORDER BY $1 ASC `, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumLow, - kind: CompletionItemKind.Snippet, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - }, - { - label: 'ORDER BY(descending)', - insertText: `ORDER BY $1 DESC`, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumLow, - kind: CompletionItemKind.Snippet, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - }, - ]), - }, - { - id: SuggestionKind.LimitKeyword, - name: SuggestionKind.LimitKeyword, - suggestions: (_, m) => - Promise.resolve([ - { - label: 'LIMIT', - insertText: `LIMIT `, - command: TRIGGER_SUGGEST, - sortText: CompletionItemPriority.MediumLow, - kind: CompletionItemKind.Keyword, - }, - ]), - }, - { - id: SuggestionKind.SortOrderDirectionKeyword, - name: SuggestionKind.SortOrderDirectionKeyword, - suggestions: (_, m) => - Promise.resolve( - [ASC, DESC].map((o) => ({ - label: o, - insertText: `${o} `, - command: TRIGGER_SUGGEST, - kind: CompletionItemKind.Keyword, - })) - ), - }, - { - id: SuggestionKind.NotKeyword, - name: SuggestionKind.NotKeyword, - suggestions: () => - Promise.resolve([ - { - label: 'NOT', - insertText: 'NOT', - command: TRIGGER_SUGGEST, - kind: CompletionItemKind.Keyword, - sortText: CompletionItemPriority.High, - }, - ]), - }, - { - id: SuggestionKind.BoolValues, - name: SuggestionKind.BoolValues, - suggestions: () => - Promise.resolve( - ['TRUE', 'FALSE'].map((o) => ({ - label: o, - insertText: `${o}`, - command: TRIGGER_SUGGEST, - kind: CompletionItemKind.Keyword, - sortText: CompletionItemPriority.Medium, - })) - ), - }, - { - id: SuggestionKind.NullValue, - name: SuggestionKind.NullValue, - suggestions: () => - Promise.resolve( - ['NULL'].map((o) => ({ - label: o, - insertText: `${o}`, - command: TRIGGER_SUGGEST, - kind: CompletionItemKind.Keyword, - sortText: CompletionItemPriority.Low, - })) - ), - }, - ]; - -export const initFunctionsRegistry = (): FunctionsRegistryItem[] => [ - ...STD_STATS.map((s) => ({ - id: s, - name: s, - })), -]; - -export const initMacrosRegistry = (): MacrosRegistryItem[] => [...MACROS]; - -export const initOperatorsRegistry = (): OperatorsRegistryItem[] => [ - ...STD_OPERATORS.map((o) => ({ - id: o, - name: o, - operator: o, - type: OperatorType.Comparison, - })), - ...LOGICAL_OPERATORS.map((o) => ({ id: o, name: o.toUpperCase(), operator: o, type: OperatorType.Logical })), -]; - -function createMacroSuggestionItem(m: MacrosRegistryItem) { - return { - label: m.name, - insertText: `${'\\' + m.text}${argsString(m.args)} `, - insertTextRules: CompletionItemInsertTextRule.InsertAsSnippet, - kind: CompletionItemKind.Snippet, - documentation: m.description, - command: TRIGGER_SUGGEST, - }; -} - -function argsString(args?: string[]): string { - if (!args) { - return '()'; - } - return '('.concat(args.map((t, i) => `\${${i}:${t}}`).join(', ')).concat(')'); -} diff --git a/public/app/features/plugins/sql/standardSql/statementPositionResolversRegistry.ts b/public/app/features/plugins/sql/standardSql/statementPositionResolversRegistry.ts deleted file mode 100644 index aa6a440f4a2..00000000000 --- a/public/app/features/plugins/sql/standardSql/statementPositionResolversRegistry.ts +++ /dev/null @@ -1,244 +0,0 @@ -import { StatementPosition, TokenType } from '../types'; - -import { AND, AS, ASC, BY, DESC, FROM, GROUP, ORDER, SELECT, WHERE, WITH } from './language'; -import { StatementPositionResolversRegistryItem } from './types'; - -export function initStatementPositionResolvers(): StatementPositionResolversRegistryItem[] { - return [ - { - id: StatementPosition.SelectKeyword, - name: StatementPosition.SelectKeyword, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - currentToken === null || - (currentToken.isWhiteSpace() && currentToken.previous === null) || - currentToken.is(TokenType.Keyword, SELECT) || - (currentToken.is(TokenType.Keyword, SELECT) && currentToken.previous === null) || - previousIsSlash || - (currentToken.isIdentifier() && (previousIsSlash || currentToken?.previous === null)) || - (currentToken.isIdentifier() && SELECT.startsWith(currentToken.value.toLowerCase())) - ), - }, - { - id: StatementPosition.WithKeyword, - name: StatementPosition.WithKeyword, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - currentToken === null || - (currentToken.isWhiteSpace() && currentToken.previous === null) || - (currentToken.is(TokenType.Keyword, WITH) && currentToken.previous === null) || - (currentToken.isIdentifier() && WITH.toLowerCase().startsWith(currentToken.value.toLowerCase())) - ), - }, - { - id: StatementPosition.AfterSelectKeyword, - name: StatementPosition.AfterSelectKeyword, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean(previousNonWhiteSpace?.value.toLowerCase() === SELECT), - }, - { - id: StatementPosition.AfterSelectArguments, - name: StatementPosition.AfterSelectArguments, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean(previousKeyword?.value.toLowerCase() === SELECT && previousNonWhiteSpace?.value === ','); - }, - }, - { - id: StatementPosition.AfterSelectFuncFirstArgument, - name: StatementPosition.AfterSelectFuncFirstArgument, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean( - (previousKeyword?.value.toLowerCase() === SELECT || previousKeyword?.value.toLowerCase() === AS) && - (previousNonWhiteSpace?.is(TokenType.Parenthesis, '(') || currentToken?.is(TokenType.Parenthesis, '()')) - ); - }, - }, - { - id: StatementPosition.AfterWhereFunctionArgument, - name: StatementPosition.AfterWhereFunctionArgument, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean( - previousKeyword?.is(TokenType.Keyword, WHERE) && - (previousNonWhiteSpace?.is(TokenType.Parenthesis, '(') || currentToken?.is(TokenType.Parenthesis, '()')) - ); - }, - }, - { - id: StatementPosition.AfterGroupBy, - name: StatementPosition.AfterGroupBy, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - previousKeyword?.is(TokenType.Keyword, BY) && - previousKeyword?.getPreviousKeyword()?.is(TokenType.Keyword, GROUP) && - (previousNonWhiteSpace?.isIdentifier() || - previousNonWhiteSpace?.isDoubleQuotedString() || - previousNonWhiteSpace?.is(TokenType.Parenthesis, ')') || - previousNonWhiteSpace?.is(TokenType.Parenthesis, '()')) - ), - }, - { - id: StatementPosition.SelectAlias, - name: StatementPosition.SelectAlias, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - if (previousNonWhiteSpace?.value === ',' && previousKeyword?.value.toLowerCase() === AS) { - return true; - } - - return false; - }, - }, - - { - id: StatementPosition.FromKeyword, - name: StatementPosition.FromKeyword, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean( - (previousKeyword?.value.toLowerCase() === SELECT && previousNonWhiteSpace?.value !== ',') || - ((currentToken?.isKeyword() || currentToken?.isIdentifier()) && - FROM.toLowerCase().startsWith(currentToken.value.toLowerCase())) - ); - }, - }, - { - id: StatementPosition.AfterFromKeyword, - name: StatementPosition.AfterFromKeyword, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean(previousNonWhiteSpace?.value.toLowerCase() === FROM), - }, - { - id: StatementPosition.AfterFrom, - name: StatementPosition.AfterFrom, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - (previousKeyword?.value.toLowerCase() === FROM && previousNonWhiteSpace?.isDoubleQuotedString()) || - (previousKeyword?.value.toLowerCase() === FROM && previousNonWhiteSpace?.isIdentifier()) || - (previousKeyword?.value.toLowerCase() === FROM && previousNonWhiteSpace?.isVariable()) - ), - }, - { - id: StatementPosition.AfterTable, - name: StatementPosition.AfterTable, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean( - previousKeyword?.value.toLowerCase() === FROM && - (previousNonWhiteSpace?.isVariable() || previousNonWhiteSpace?.value !== '') - ); - }, - }, - { - id: StatementPosition.WhereKeyword, - name: StatementPosition.WhereKeyword, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - previousKeyword?.value.toLowerCase() === WHERE && - (previousNonWhiteSpace?.isKeyword() || - previousNonWhiteSpace?.is(TokenType.Parenthesis, '(') || - previousNonWhiteSpace?.is(TokenType.Operator, AND)) - ), - }, - { - id: StatementPosition.WhereComparisonOperator, - name: StatementPosition.WhereComparisonOperator, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - previousKeyword?.value.toLowerCase() === WHERE && - !previousNonWhiteSpace?.getPreviousNonWhiteSpaceToken()?.isOperator() && - !currentToken?.is(TokenType.Delimiter, '.') && - !currentToken?.isParenthesis() && - (previousNonWhiteSpace?.isIdentifier() || previousNonWhiteSpace?.isDoubleQuotedString()) - ), - }, - { - id: StatementPosition.WhereValue, - name: StatementPosition.WhereValue, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean(previousKeyword?.value.toLowerCase() === WHERE && previousNonWhiteSpace?.isOperator()), - }, - { - id: StatementPosition.AfterWhereValue, - name: StatementPosition.AfterWhereValue, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean( - previousKeyword?.value.toLowerCase() === WHERE && - (previousNonWhiteSpace?.is(TokenType.Operator, 'and') || - previousNonWhiteSpace?.is(TokenType.Operator, 'or') || - previousNonWhiteSpace?.isString() || - previousNonWhiteSpace?.isNumber() || - previousNonWhiteSpace?.is(TokenType.Parenthesis, ')') || - previousNonWhiteSpace?.is(TokenType.Parenthesis, '()') || - previousNonWhiteSpace?.isTemplateVariable() || - (previousNonWhiteSpace?.is(TokenType.IdentifierQuote) && - previousNonWhiteSpace.getPreviousNonWhiteSpaceToken()?.is(TokenType.Identifier) && - previousNonWhiteSpace - ?.getPreviousNonWhiteSpaceToken() - ?.getPreviousNonWhiteSpaceToken() - ?.is(TokenType.IdentifierQuote))) - ); - }, - }, - { - id: StatementPosition.AfterGroupByKeywords, - name: StatementPosition.AfterGroupByKeywords, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - previousKeyword?.is(TokenType.Keyword, BY) && - previousKeyword?.getPreviousKeyword()?.is(TokenType.Keyword, GROUP) && - (previousNonWhiteSpace?.is(TokenType.Keyword, BY) || previousNonWhiteSpace?.is(TokenType.Delimiter, ',')) - ), - }, - { - id: StatementPosition.AfterGroupByFunctionArgument, - name: StatementPosition.AfterGroupByFunctionArgument, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean( - previousKeyword?.is(TokenType.Keyword, BY) && - previousKeyword?.getPreviousKeyword()?.is(TokenType.Keyword, GROUP) && - (previousNonWhiteSpace?.is(TokenType.Parenthesis, '(') || currentToken?.is(TokenType.Parenthesis, '()')) - ); - }, - }, - { - id: StatementPosition.AfterOrderByKeywords, - name: StatementPosition.AfterOrderByKeywords, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - previousNonWhiteSpace?.is(TokenType.Keyword, BY) && - previousNonWhiteSpace?.getPreviousKeyword()?.is(TokenType.Keyword, ORDER) - ), - }, - { - id: StatementPosition.AfterOrderByFunction, - name: StatementPosition.AfterOrderByFunction, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean( - previousKeyword?.is(TokenType.Keyword, BY) && - previousKeyword?.getPreviousKeyword()?.is(TokenType.Keyword, ORDER) && - previousNonWhiteSpace?.is(TokenType.Parenthesis) && - previousNonWhiteSpace?.getPreviousNonWhiteSpaceToken()?.is(TokenType.Function) - ), - }, - { - id: StatementPosition.AfterOrderByDirection, - name: StatementPosition.AfterOrderByDirection, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => - Boolean(previousKeyword?.is(TokenType.Keyword, DESC) || previousKeyword?.is(TokenType.Keyword, ASC)), - }, - { - id: StatementPosition.AfterIsOperator, - name: StatementPosition.AfterIsOperator, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean(previousNonWhiteSpace?.is(TokenType.Operator, 'IS')); - }, - }, - { - id: StatementPosition.AfterIsNotOperator, - name: StatementPosition.AfterIsNotOperator, - resolve: (currentToken, previousKeyword, previousNonWhiteSpace, previousIsSlash) => { - return Boolean( - previousNonWhiteSpace?.is(TokenType.Operator, 'NOT') && - previousNonWhiteSpace.getPreviousNonWhiteSpaceToken()?.is(TokenType.Operator, 'IS') - ); - }, - }, - ]; -} diff --git a/public/app/features/plugins/sql/standardSql/suggestionsKindRegistry.ts b/public/app/features/plugins/sql/standardSql/suggestionsKindRegistry.ts deleted file mode 100644 index c09f2b7aff7..00000000000 --- a/public/app/features/plugins/sql/standardSql/suggestionsKindRegistry.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { RegistryItem } from '@grafana/data'; - -import { StatementPosition, SuggestionKind } from '../types'; - -export interface SuggestionKindRegistryItem extends RegistryItem { - id: StatementPosition; - kind: SuggestionKind[]; -} - -// Registry of possible suggestions for the given statement position -export const initSuggestionsKindRegistry = (): SuggestionKindRegistryItem[] => { - return [ - { - id: StatementPosition.SelectKeyword, - name: StatementPosition.SelectKeyword, - kind: [SuggestionKind.SelectKeyword], - }, - { - id: StatementPosition.WithKeyword, - name: StatementPosition.WithKeyword, - kind: [SuggestionKind.WithKeyword], - }, - { - id: StatementPosition.AfterSelectKeyword, - name: StatementPosition.AfterSelectKeyword, - kind: [SuggestionKind.FunctionsWithArguments, SuggestionKind.Columns, SuggestionKind.SelectMacro], - }, - { - id: StatementPosition.AfterSelectFuncFirstArgument, - name: StatementPosition.AfterSelectFuncFirstArgument, - kind: [SuggestionKind.Columns], - }, - { - id: StatementPosition.AfterGroupByFunctionArgument, - name: StatementPosition.AfterGroupByFunctionArgument, - kind: [SuggestionKind.Columns], - }, - { - id: StatementPosition.AfterWhereFunctionArgument, - name: StatementPosition.AfterWhereFunctionArgument, - kind: [SuggestionKind.Columns], - }, - { - id: StatementPosition.AfterSelectArguments, - name: StatementPosition.AfterSelectArguments, - kind: [SuggestionKind.Columns], - }, - { - id: StatementPosition.AfterFromKeyword, - name: StatementPosition.AfterFromKeyword, - kind: [SuggestionKind.Tables, SuggestionKind.TableMacro], - }, - { - id: StatementPosition.SelectAlias, - name: StatementPosition.SelectAlias, - kind: [SuggestionKind.Columns, SuggestionKind.FunctionsWithArguments], - }, - { - id: StatementPosition.FromKeyword, - name: StatementPosition.FromKeyword, - kind: [SuggestionKind.FromKeyword], - }, - { - id: StatementPosition.AfterFrom, - name: StatementPosition.AfterFrom, - kind: [ - SuggestionKind.WhereKeyword, - SuggestionKind.GroupByKeywords, - SuggestionKind.OrderByKeywords, - SuggestionKind.LimitKeyword, - ], - }, - { - id: StatementPosition.AfterTable, - name: StatementPosition.AfterTable, - kind: [ - SuggestionKind.WhereKeyword, - SuggestionKind.GroupByKeywords, - SuggestionKind.OrderByKeywords, - SuggestionKind.LimitKeyword, - ], - }, - { - id: StatementPosition.WhereKeyword, - name: StatementPosition.WhereKeyword, - kind: [SuggestionKind.Columns, SuggestionKind.FilterMacro, SuggestionKind.TemplateVariables], - }, - { - id: StatementPosition.WhereComparisonOperator, - name: StatementPosition.WhereComparisonOperator, - kind: [SuggestionKind.ComparisonOperators], - }, - { - id: StatementPosition.WhereValue, - name: StatementPosition.WhereValue, - kind: [SuggestionKind.Columns, SuggestionKind.FilterMacro, SuggestionKind.TemplateVariables], - }, - { - id: StatementPosition.AfterWhereValue, - name: StatementPosition.AfterWhereValue, - kind: [ - SuggestionKind.LogicalOperators, - SuggestionKind.GroupByKeywords, - SuggestionKind.OrderByKeywords, - SuggestionKind.LimitKeyword, - SuggestionKind.Columns, - SuggestionKind.TemplateVariables, - ], - }, - { - id: StatementPosition.AfterGroupByKeywords, - name: StatementPosition.AfterGroupByKeywords, - kind: [SuggestionKind.GroupMacro], - }, - { - id: StatementPosition.AfterGroupBy, - name: StatementPosition.AfterGroupBy, - kind: [SuggestionKind.OrderByKeywords, SuggestionKind.LimitKeyword], - }, - { - id: StatementPosition.AfterOrderByKeywords, - name: StatementPosition.AfterOrderByKeywords, - kind: [SuggestionKind.Columns], - }, - { - id: StatementPosition.AfterOrderByFunction, - name: StatementPosition.AfterOrderByFunction, - kind: [SuggestionKind.SortOrderDirectionKeyword, SuggestionKind.LimitKeyword], - }, - { - id: StatementPosition.AfterOrderByDirection, - name: StatementPosition.AfterOrderByDirection, - kind: [SuggestionKind.LimitKeyword], - }, - { - id: StatementPosition.AfterIsOperator, - name: StatementPosition.AfterOrderByDirection, - kind: [SuggestionKind.NotKeyword, SuggestionKind.NullValue, SuggestionKind.BoolValues], - }, - { - id: StatementPosition.AfterIsNotOperator, - name: StatementPosition.AfterOrderByDirection, - kind: [SuggestionKind.NullValue, SuggestionKind.BoolValues], - }, - ]; -}; diff --git a/public/app/features/plugins/sql/standardSql/types.ts b/public/app/features/plugins/sql/standardSql/types.ts deleted file mode 100644 index 20d692cb86c..00000000000 --- a/public/app/features/plugins/sql/standardSql/types.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { RegistryItem } from '@grafana/data'; -import { monacoTypes } from '@grafana/ui'; - -import { - CustomSuggestion, - MacroType, - OperatorType, - PositionContext, - StatementPosition, - SuggestionKind, -} from '../types'; -import { LinkedToken } from '../utils/LinkedToken'; - -export interface SuggestionsRegistryItem extends RegistryItem { - id: SuggestionKind; - suggestions: (position: PositionContext, m: typeof monacoTypes) => Promise; -} - -export interface MacrosRegistryItem extends RegistryItem { - type: MacroType; - text: string; - args?: string[]; -} - -export interface FunctionsRegistryItem extends RegistryItem {} -export interface OperatorsRegistryItem extends RegistryItem { - operator: string; - type: OperatorType; -} - -export type StatementPositionResolver = ( - currentToken: LinkedToken | null, - previousKeyword: LinkedToken | null, - previousNonWhiteSpace: LinkedToken | null, - previousIsSlash: Boolean -) => Boolean; - -export interface StatementPositionResolversRegistryItem extends RegistryItem { - id: StatementPosition; - resolve: StatementPositionResolver; -} - -export type SuggestionsResolver = ( - positionContext: T -) => Promise; - -export interface SQLMonarchLanguage extends monacoTypes.languages.IMonarchLanguage { - keywords?: string[]; - builtinFunctions?: string[]; - logicalOperators?: string[]; - comparisonOperators?: string[]; -} diff --git a/public/app/features/plugins/sql/test-utils/index.ts b/public/app/features/plugins/sql/test-utils/index.ts deleted file mode 100644 index 452538a2c42..00000000000 --- a/public/app/features/plugins/sql/test-utils/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as testData from '../mocks/testData'; - -import { testStatementPosition } from './statementPosition'; -import { TestQueryModel } from './types'; - -export const SQLEditorTestUtils = { - testData, - testStatementPosition, -}; - -export { TestQueryModel }; diff --git a/public/app/features/plugins/sql/test-utils/statementPosition.ts b/public/app/features/plugins/sql/test-utils/statementPosition.ts deleted file mode 100644 index 047b30515d7..00000000000 --- a/public/app/features/plugins/sql/test-utils/statementPosition.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Registry } from '@grafana/data'; -import { monacoTypes } from '@grafana/ui'; - -import { getMonacoMock } from '../mocks/Monaco'; -import { TextModel } from '../mocks/TextModel'; -import { getStatementPosition } from '../standardSql/getStatementPosition'; -import { StatementPositionResolversRegistryItem } from '../standardSql/types'; -import { CustomStatementPlacement, StatementPosition } from '../types'; -import { linkedTokenBuilder } from '../utils/linkedTokenBuilder'; - -import { StatementPositionResolverTestCase } from './types'; - -function assertPosition( - query: string, - position: monacoTypes.IPosition, - expected: StatementPosition | string, - monacoMock: any, - resolversRegistry: Registry -) { - const testModel = TextModel(query); - const current = linkedTokenBuilder(monacoMock, testModel as monacoTypes.editor.ITextModel, position); - const statementPosition = getStatementPosition(current, resolversRegistry); - - expect(statementPosition).toContain(expected); -} - -export const testStatementPosition = ( - expected: StatementPosition | string, - cases: StatementPositionResolverTestCase[], - resolvers: () => CustomStatementPlacement[] -) => { - describe(`${expected}`, () => { - let MonacoMock: any; - let statementPositionResolversRegistry: Registry; - - beforeEach(() => { - const mockQueries = new Map>>>(); - cases.forEach((c) => mockQueries.set(c.query.query, c.query.tokens)); - - MonacoMock = getMonacoMock(mockQueries); - statementPositionResolversRegistry = new Registry(() => { - return resolvers().map((r) => ({ - id: r.id as StatementPosition, - name: r.name || r.id, - resolve: r.resolve, - })); - }); - }); - - // using forEach here rather than test.each as been struggling to get the arguments intepolated in test name string - cases.forEach((c) => { - test(`${c.query.query}`, () => { - assertPosition( - c.query.query, - { lineNumber: c.position.line, column: c.position.column }, - expected, - MonacoMock, - statementPositionResolversRegistry - ); - }); - }); - }); -}; diff --git a/public/app/features/plugins/sql/test-utils/testQueries.txt b/public/app/features/plugins/sql/test-utils/testQueries.txt deleted file mode 100644 index a588073f7ab..00000000000 --- a/public/app/features/plugins/sql/test-utils/testQueries.txt +++ /dev/null @@ -1,21 +0,0 @@ -SELECT column1, FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10 -SELECT column1, FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10; SELECT column2, FROM table2 WHERE column2 = "value2" GROUP BY column1 ORDER BY column2 DESC LIMIT 10; -SELECT count(column1), FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10; -SELECT count(column1), FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1 DESC LIMIT 10; SELECT count(column2), FROM table2 WHERE column2 = "value2" GROUP BY column1 ORDER BY column2 DESC LIMIT 10; - - -SELECT column1, -FROM table1 - -WHERE column1 = "value1" -GROUP BY column1 ORDER BY column1 DESC -LIMIT 10; - -SELECT count(column1), column2 FROM table1 WHERE column1 = "value1" GROUP BY column1 ORDER BY column1, avg(column2) DESC LIMIT 10; - -SELECT count(column1), column2 -FROM table1 - -WHERE column1 = "value1" -GROUP BY column1 ORDER BY column1, avg(column2) DESC -LIMIT 10; \ No newline at end of file diff --git a/public/app/features/plugins/sql/test-utils/types.ts b/public/app/features/plugins/sql/test-utils/types.ts deleted file mode 100644 index a5ce5ad5551..00000000000 --- a/public/app/features/plugins/sql/test-utils/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -export interface TestQueryModel { - query: string; - tokens: Array>>; -} - -export interface StatementPositionResolverTestCase { - query: TestQueryModel; - position: { line: number; column: number }; -} diff --git a/public/app/features/plugins/sql/types.ts b/public/app/features/plugins/sql/types.ts index 3c261743c2f..ad649fe03e4 100644 --- a/public/app/features/plugins/sql/types.ts +++ b/public/app/features/plugins/sql/types.ts @@ -9,7 +9,7 @@ import { TimeRange, toOption as toOptionFromData, } from '@grafana/data'; -import { Monaco, monacoTypes } from '@grafana/ui'; +import { CompletionItemKind, LanguageCompletionProvider } from '@grafana/experimental'; import { QueryWithDefaults } from './defaults'; import { @@ -17,8 +17,6 @@ import { QueryEditorGroupByExpression, QueryEditorPropertyExpression, } from './expressions'; -import { StatementPositionResolver, SuggestionsResolver } from './standardSql/types'; -import { LinkedToken } from './utils/LinkedToken'; export interface SqlQueryForInterpolation { dataset?: string; @@ -182,249 +180,17 @@ export interface MetaDefinition { kind: CompletionItemKind; } -/** - * Provides a context for suggestions resolver - * @alpha - */ -export interface PositionContext { - position: monacoTypes.IPosition; - kind: SuggestionKind[]; - statementPosition: StatementPosition[]; - currentToken: LinkedToken | null; - range: monacoTypes.IRange; -} - -export type CustomSuggestion = Partial & { label: string }; - -export interface CustomSuggestionKind { - id: string; - suggestionsResolver: SuggestionsResolver; - applyTo?: Array; - overrideDefault?: boolean; -} - -export interface CustomStatementPlacement { - id: string; - name?: string; - resolve: StatementPositionResolver; - overrideDefault?: boolean; -} -export type StatementPlacementProvider = () => CustomStatementPlacement[]; -export type SuggestionKindProvider = () => CustomSuggestionKind[]; - -export interface ColumnDefinition { - name: string; - type?: string; - description?: string; - // Text used for automplete. If not provided name is used. - completion?: string; -} -export interface TableDefinition { - name: string; - // Text used for automplete. If not provided name is used. - completion?: string; -} - -export interface SQLCompletionItemProvider - extends Omit { - /** - * Allows dialect specific functions to be added to the completion list. - * @alpha - */ - supportedFunctions?: () => Array<{ - id: string; - name: string; - description?: string; - }>; - - /** - * Allows dialect specific operators to be added to the completion list. - * @alpha - */ - supportedOperators?: () => Array<{ - id: string; - operator: string; - type: OperatorType; - description?: string; - }>; - - supportedMacros?: () => Array<{ - id: string; - text: string; - type: MacroType; - args: string[]; - description?: string; - }>; - - /** - * Allows custom suggestion kinds to be defined and correlate them with StatementPosition. - * @alpha - */ - customSuggestionKinds?: SuggestionKindProvider; - - /** - * Allows custom statement placement definition. - * @alpha - */ - customStatementPlacement?: StatementPlacementProvider; - - /** - * Allows providing a custom function for resolving db tables. - * It's up to the consumer to decide whether the columns are resolved via API calls or preloaded in the query editor(i.e. full db schema is preloades loaded). - * @alpha - */ - tables?: { - resolve: () => Promise; - // Allows providing a custom function for calculating the table name from the query. If not specified a default implemnentation is used. - parseName?: (t: LinkedToken) => string; - }; - /** - * Allows providing a custom function for resolving table. - * It's up to the consumer to decide whether the columns are resolved via API calls or preloaded in the query editor(i.e. full db schema is preloades loaded). - * @alpha - */ - columns?: { - resolve: (table: string) => Promise; - }; - - /** - * TODO: Not sure whether or not we need this. Would like to avoid this kind of flexibility. - * @alpha - */ - provideCompletionItems?: ( - model: monacoTypes.editor.ITextModel, - position: monacoTypes.Position, - context: monacoTypes.languages.CompletionContext, - token: monacoTypes.CancellationToken, - positionContext: PositionContext // Decorates original provideCompletionItems function with our custom statement position context - ) => monacoTypes.languages.CompletionList; -} - -export type LanguageCompletionProvider = (m: Monaco) => SQLCompletionItemProvider; - -export enum OperatorType { - Comparison, - Logical, -} - -export enum MacroType { - Value, - Filter, - Group, - Column, - Table, -} - -export enum TokenType { - Parenthesis = 'delimiter.parenthesis.sql', - Whitespace = 'white.sql', - Keyword = 'keyword.sql', - Delimiter = 'delimiter.sql', - Operator = 'operator.sql', - Identifier = 'identifier.sql', - IdentifierQuote = 'identifier.quote.sql', - Type = 'type.sql', - Function = 'predefined.sql', - Number = 'number.sql', - String = 'string.sql', - Variable = 'variable.sql', -} - -export enum StatementPosition { - Unknown = 'unknown', - SelectKeyword = 'selectKeyword', - WithKeyword = 'withKeyword', - AfterSelectKeyword = 'afterSelectKeyword', - AfterSelectArguments = 'afterSelectArguments', - AfterSelectFuncFirstArgument = 'afterSelectFuncFirstArgument', - SelectAlias = 'selectAlias', - AfterFromKeyword = 'afterFromKeyword', - AfterTable = 'afterTable', - SchemaFuncFirstArgument = 'schemaFuncFirstArgument', - SchemaFuncExtraArgument = 'schemaFuncExtraArgument', - FromKeyword = 'fromKeyword', - AfterFrom = 'afterFrom', - WhereKeyword = 'whereKeyword', - WhereComparisonOperator = 'whereComparisonOperator', - WhereValue = 'whereValue', - AfterWhereFunctionArgument = 'afterWhereFunctionArgument', - AfterGroupByFunctionArgument = 'afterGroupByFunctionArgument', - AfterWhereValue = 'afterWhereValue', - AfterGroupByKeywords = 'afterGroupByKeywords', - AfterGroupBy = 'afterGroupBy', - AfterOrderByKeywords = 'afterOrderByKeywords', - AfterOrderByFunction = 'afterOrderByFunction', - AfterOrderByDirection = 'afterOrderByDirection', - AfterIsOperator = 'afterIsOperator', - AfterIsNotOperator = 'afterIsNotOperator', -} - -export enum SuggestionKind { - Tables = 'tables', - Columns = 'columns', - SelectKeyword = 'selectKeyword', - WithKeyword = 'withKeyword', - FunctionsWithArguments = 'functionsWithArguments', - FromKeyword = 'fromKeyword', - WhereKeyword = 'whereKeyword', - GroupByKeywords = 'groupByKeywords', - OrderByKeywords = 'orderByKeywords', - FunctionsWithoutArguments = 'functionsWithoutArguments', - LimitKeyword = 'limitKeyword', - SortOrderDirectionKeyword = 'sortOrderDirectionKeyword', - ComparisonOperators = 'comparisonOperators', - LogicalOperators = 'logicalOperators', - SelectMacro = 'selectMacro', - TableMacro = 'tableMacro', - FilterMacro = 'filterMacro', - GroupMacro = 'groupMacro', - BoolValues = 'boolValues', - NullValue = 'nullValue', - NotKeyword = 'notKeyword', - TemplateVariables = 'templateVariables', -} - -// TODO: export from grafana/ui -export enum CompletionItemPriority { - High = 'a', - MediumHigh = 'd', - Medium = 'g', - MediumLow = 'k', - Low = 'q', -} - -export enum CompletionItemKind { - Method = 0, - Function = 1, - Constructor = 2, - Field = 3, - Variable = 4, - Class = 5, - Struct = 6, - Interface = 7, - Module = 8, - Property = 9, - Event = 10, - Operator = 11, - Unit = 12, - Value = 13, - Constant = 14, - Enum = 15, - EnumMember = 16, - Keyword = 17, - Text = 18, - Color = 19, - File = 20, - Reference = 21, - Customcolor = 22, - Folder = 23, - TypeParameter = 24, - User = 25, - Issue = 26, - Snippet = 27, -} - -export enum CompletionItemInsertTextRule { - KeepWhitespace = 1, - InsertAsSnippet = 4, -} +export { + CompletionItemKind, + LanguageCompletionProvider, + LinkedToken, + ColumnDefinition, + CompletionItemPriority, + StatementPlacementProvider, + SuggestionKindProvider, + TableDefinition, + TokenType, + OperatorType, + StatementPosition, + PositionContext, +} from '@grafana/experimental'; diff --git a/public/app/features/plugins/sql/utils/LinkedToken.ts b/public/app/features/plugins/sql/utils/LinkedToken.ts deleted file mode 100644 index 27acd1e7905..00000000000 --- a/public/app/features/plugins/sql/utils/LinkedToken.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { getTemplateSrv } from '@grafana/runtime'; -import { monacoTypes } from '@grafana/ui'; - -import { TokenType } from '../types'; - -export class LinkedToken { - constructor( - public type: string, - public value: string, - public range: monacoTypes.IRange, - public previous: LinkedToken | null, - public next: LinkedToken | null - ) {} - - isKeyword(): boolean { - return this.type === TokenType.Keyword; - } - - isWhiteSpace(): boolean { - return this.type === TokenType.Whitespace; - } - - isParenthesis(): boolean { - return this.type === TokenType.Parenthesis; - } - - isIdentifier(): boolean { - return this.type === TokenType.Identifier; - } - - isString(): boolean { - return this.type === TokenType.String; - } - - isNumber(): boolean { - return this.type === TokenType.Number; - } - - isDoubleQuotedString(): boolean { - return this.type === TokenType.Type; - } - - isVariable(): boolean { - return this.type === TokenType.Variable; - } - - isFunction(): boolean { - return this.type === TokenType.Function; - } - - isOperator(): boolean { - return this.type === TokenType.Operator; - } - - isTemplateVariable(): boolean { - const variables = getTemplateSrv()?.getVariables(); - return variables.find((v) => '$' + v.name === this.value) !== undefined; - } - - is(type: TokenType, value?: string | number | boolean): boolean { - const isType = this.type === type; - - return value !== undefined ? isType && compareTokenWithValue(type, this, value) : isType; - } - - getPreviousNonWhiteSpaceToken(): LinkedToken | null { - let curr = this.previous; - while (curr != null) { - if (!curr.isWhiteSpace()) { - return curr; - } - curr = curr.previous; - } - return null; - } - - getPreviousOfType(type: TokenType, value?: string): LinkedToken | null { - let curr = this.previous; - while (curr != null) { - const isType = curr.type === type; - - if (value !== undefined ? isType && compareTokenWithValue(type, curr, value) : isType) { - return curr; - } - curr = curr.previous; - } - return null; - } - - getPreviousUntil(type: TokenType, ignoreTypes: TokenType[], value?: string): LinkedToken[] | null { - let tokens: LinkedToken[] = []; - let curr = this.previous; - while (curr != null) { - if (ignoreTypes.some((t) => t === curr?.type)) { - curr = curr.previous; - continue; - } - - const isType = curr.type === type; - - if (value !== undefined ? isType && compareTokenWithValue(type, curr, value) : isType) { - return tokens; - } - if (!curr.isWhiteSpace()) { - tokens.push(curr); - } - curr = curr.previous; - } - - return tokens; - } - - getNextUntil(type: TokenType, ignoreTypes: TokenType[], value?: string): LinkedToken[] | null { - let tokens: LinkedToken[] = []; - let curr = this.next; - while (curr != null) { - if (ignoreTypes.some((t) => t === curr?.type)) { - curr = curr.next; - continue; - } - - const isType = curr.type === type; - - if (value !== undefined ? isType && compareTokenWithValue(type, curr, value) : isType) { - return tokens; - } - if (!curr.isWhiteSpace()) { - tokens.push(curr); - } - curr = curr.next; - } - - return tokens; - } - - getPreviousKeyword(): LinkedToken | null { - let curr = this.previous; - while (curr != null) { - if (curr.isKeyword()) { - return curr; - } - curr = curr.previous; - } - return null; - } - - getNextNonWhiteSpaceToken(): LinkedToken | null { - let curr = this.next; - while (curr != null) { - if (!curr.isWhiteSpace()) { - return curr; - } - curr = curr.next; - } - return null; - } - - getNextOfType(type: TokenType, value?: string): LinkedToken | null { - let curr = this.next; - while (curr != null) { - const isType = curr.type === type; - - if (value !== undefined ? isType && compareTokenWithValue(type, curr, value) : isType) { - return curr; - } - curr = curr.next; - } - return null; - } -} - -function compareTokenWithValue(type: TokenType, token: LinkedToken, value: string | number | boolean) { - return type === TokenType.Keyword || type === TokenType.Operator - ? token.value.toLowerCase() === value.toString().toLowerCase() - : token.value === value; -} diff --git a/public/app/features/plugins/sql/utils/commands.ts b/public/app/features/plugins/sql/utils/commands.ts deleted file mode 100644 index 3c3f507dc2f..00000000000 --- a/public/app/features/plugins/sql/utils/commands.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const TRIGGER_SUGGEST = { - id: 'editor.action.triggerSuggest', - title: '', -}; diff --git a/public/app/features/plugins/sql/utils/debugger.ts b/public/app/features/plugins/sql/utils/debugger.ts deleted file mode 100644 index 6fa7908f876..00000000000 --- a/public/app/features/plugins/sql/utils/debugger.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { attachDebugger, createLogger } from '@grafana/ui'; - -let sqlEditorLogger = { logger: () => {} }; -let sqlEditorLog: (...t: any[]) => void = () => {}; - -if (attachDebugger) { - sqlEditorLogger = createLogger('SQLEditor'); - sqlEditorLog = sqlEditorLogger.logger; - attachDebugger('sqleditor', undefined, sqlEditorLogger as any); -} - -export { sqlEditorLog, sqlEditorLogger }; diff --git a/public/app/features/plugins/sql/utils/getSuggestionKind.test.ts b/public/app/features/plugins/sql/utils/getSuggestionKind.test.ts deleted file mode 100644 index 25982457bc9..00000000000 --- a/public/app/features/plugins/sql/utils/getSuggestionKind.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Registry } from '@grafana/data'; - -import { SuggestionKindRegistryItem } from '../standardSql/suggestionsKindRegistry'; -import { StatementPosition, SuggestionKind } from '../types'; - -import { getSuggestionKinds } from './getSuggestionKind'; - -describe('getSuggestionKind', () => { - const registry = new Registry((): SuggestionKindRegistryItem[] => { - return [ - { - id: StatementPosition.SelectKeyword, - name: StatementPosition.SelectKeyword, - kind: [SuggestionKind.SelectKeyword], - }, - { - id: StatementPosition.AfterSelectArguments, - name: StatementPosition.AfterSelectArguments, - kind: [SuggestionKind.Columns], - }, - ]; - }); - it('should return select kind when given select keyword as position', () => { - const pos = [StatementPosition.SelectKeyword]; - expect([SuggestionKind.SelectKeyword]).toEqual(getSuggestionKinds(pos, registry)); - }); - it('should return column kind when given AfterSelectArguments as position', () => { - const pos = [StatementPosition.AfterSelectArguments]; - expect([SuggestionKind.Columns]).toEqual(getSuggestionKinds(pos, registry)); - }); -}); diff --git a/public/app/features/plugins/sql/utils/getSuggestionKind.ts b/public/app/features/plugins/sql/utils/getSuggestionKind.ts deleted file mode 100644 index 47819055b2a..00000000000 --- a/public/app/features/plugins/sql/utils/getSuggestionKind.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Registry } from '@grafana/data'; - -import { SuggestionKindRegistryItem } from '../standardSql/suggestionsKindRegistry'; -import { StatementPosition, SuggestionKind } from '../types'; - -/** - * Given statement positions, returns list of suggestion kinds that apply to those positions. - */ -export function getSuggestionKinds( - statementPosition: StatementPosition[], - suggestionsKindRegistry: Registry -): SuggestionKind[] { - let result: SuggestionKind[] = []; - for (let i = 0; i < statementPosition.length; i++) { - const exists = suggestionsKindRegistry.getIfExists(statementPosition[i]); - if (exists) { - result = result.concat(exists.kind); - } - } - - return result; -} diff --git a/public/app/features/plugins/sql/utils/linkedTokenBuilder.test.ts b/public/app/features/plugins/sql/utils/linkedTokenBuilder.test.ts deleted file mode 100644 index ab93f5a6f28..00000000000 --- a/public/app/features/plugins/sql/utils/linkedTokenBuilder.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -import { getMonacoMock } from '../mocks/Monaco'; -import { TextModel } from '../mocks/TextModel'; -import { multiLineFullQuery, singleLineFullQuery } from '../mocks/testData'; -import { DESC, LIMIT, SELECT } from '../standardSql/language'; -import { TokenType } from '../types'; - -import { linkedTokenBuilder } from './linkedTokenBuilder'; - -describe('linkedTokenBuilder', () => { - describe('singleLineFullQuery', () => { - const testModel = TextModel(singleLineFullQuery.query); - const queriesMock = new Map(); - queriesMock.set(singleLineFullQuery.query, singleLineFullQuery.tokens); - - const MonacoMock = getMonacoMock(queriesMock); - - it('should add correct references to next LinkedToken', () => { - const position: monacoTypes.IPosition = { lineNumber: 1, column: 0 }; - const current = linkedTokenBuilder(MonacoMock, testModel as monacoTypes.editor.ITextModel, position); - - expect(current?.is(TokenType.Keyword, SELECT)).toBeTruthy(); - expect(current?.getNextNonWhiteSpaceToken()?.is(TokenType.Identifier, 'column1')).toBeTruthy(); - }); - - it('should add correct references to previous LinkedToken', () => { - const position: monacoTypes.IPosition = { lineNumber: 1, column: singleLineFullQuery.query.length }; - const current = linkedTokenBuilder(MonacoMock, testModel as monacoTypes.editor.ITextModel, position); - expect(current?.is(TokenType.Number, '10')).toBeTruthy(); - expect(current?.getPreviousNonWhiteSpaceToken()?.is(TokenType.Keyword, 'LIMIT')).toBeTruthy(); - expect( - current?.getPreviousNonWhiteSpaceToken()?.getPreviousNonWhiteSpaceToken()?.is(TokenType.Keyword, DESC) - ).toBeTruthy(); - }); - }); - - describe('multiLineFullQuery', () => { - const testModel = TextModel(multiLineFullQuery.query); - const queriesMock = new Map(); - queriesMock.set(multiLineFullQuery.query, multiLineFullQuery.tokens); - - const MonacoMock = getMonacoMock(queriesMock); - - it('should add LinkedToken with whitespace in case empty lines', () => { - const position: monacoTypes.IPosition = { lineNumber: 3, column: 0 }; - const current = linkedTokenBuilder(MonacoMock, testModel as monacoTypes.editor.ITextModel, position); - - expect(current).not.toBeNull(); - expect(current?.isWhiteSpace()).toBeTruthy(); - }); - - it('should add correct references to next LinkedToken', () => { - const position: monacoTypes.IPosition = { lineNumber: 1, column: 0 }; - const current = linkedTokenBuilder(MonacoMock, testModel as monacoTypes.editor.ITextModel, position); - - expect(current?.is(TokenType.Keyword, SELECT)).toBeTruthy(); - expect(current?.getNextNonWhiteSpaceToken()?.is(TokenType.Identifier, 'column1')).toBeTruthy(); - }); - - it('should add correct references to previous LinkedToken even when references spans over multiple lines', () => { - const position: monacoTypes.IPosition = { lineNumber: 6, column: 7 }; - const current = linkedTokenBuilder(MonacoMock, testModel as monacoTypes.editor.ITextModel, position); - - expect(current?.is(TokenType.Number, '10')).toBeTruthy(); - expect(current?.getPreviousNonWhiteSpaceToken()?.is(TokenType.Keyword, LIMIT)).toBeTruthy(); - expect( - current?.getPreviousNonWhiteSpaceToken()?.getPreviousNonWhiteSpaceToken()?.is(TokenType.Keyword, DESC) - ).toBeTruthy(); - }); - }); -}); diff --git a/public/app/features/plugins/sql/utils/linkedTokenBuilder.ts b/public/app/features/plugins/sql/utils/linkedTokenBuilder.ts deleted file mode 100644 index dfc67472a37..00000000000 --- a/public/app/features/plugins/sql/utils/linkedTokenBuilder.ts +++ /dev/null @@ -1,56 +0,0 @@ -import type { monacoTypes } from '@grafana/ui'; - -import { TokenType } from '../types'; - -import { LinkedToken } from './LinkedToken'; -import { Monaco } from './types'; - -export function linkedTokenBuilder( - monaco: Monaco, - model: monacoTypes.editor.ITextModel, - position: monacoTypes.IPosition, - languageId = 'sql' -) { - let current: LinkedToken | null = null; - let previous: LinkedToken | null = null; - const tokensPerLine = monaco.editor.tokenize(model.getValue() ?? '', languageId); - for (let lineIndex = 0; lineIndex < tokensPerLine.length; lineIndex++) { - const tokens = tokensPerLine[lineIndex]; - // In case position is first column in new line, add empty whitespace token so that links are not broken - if (!tokens.length && previous) { - const token: monacoTypes.Token = { - offset: 0, - type: TokenType.Whitespace, - language: languageId, - _tokenBrand: undefined, - }; - tokens.push(token); - } - - for (let columnIndex = 0; columnIndex < tokens.length; columnIndex++) { - const token = tokens[columnIndex]; - let endColumn = - tokens.length > columnIndex + 1 ? tokens[columnIndex + 1].offset + 1 : model.getLineLength(lineIndex + 1) + 1; - - const range: monacoTypes.IRange = { - startLineNumber: lineIndex + 1, - startColumn: token.offset === 0 ? 0 : token.offset + 1, - endLineNumber: lineIndex + 1, - endColumn, - }; - - const value = model.getValueInRange(range); - const sqlToken: LinkedToken = new LinkedToken(token.type, value, range, previous, null); - - if (monaco.Range.containsPosition(range, position)) { - current = sqlToken; - } - - if (previous) { - previous.next = sqlToken; - } - previous = sqlToken; - } - } - return current; -} diff --git a/public/app/features/plugins/sql/utils/toCompletionItem.ts b/public/app/features/plugins/sql/utils/toCompletionItem.ts deleted file mode 100644 index 3315d6b6dd6..00000000000 --- a/public/app/features/plugins/sql/utils/toCompletionItem.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -import { CompletionItemKind, CompletionItemPriority } from '../types'; - -export const toCompletionItem = ( - value: string, - range: monacoTypes.IRange, - rest: Partial = {} -) => { - const item: monacoTypes.languages.CompletionItem = { - label: value, - insertText: value, - kind: CompletionItemKind.Field, - sortText: CompletionItemPriority.Medium, - range, - ...rest, - }; - return item; -}; diff --git a/public/app/features/plugins/sql/utils/tokenUtils.ts b/public/app/features/plugins/sql/utils/tokenUtils.ts deleted file mode 100644 index aa503c7d77e..00000000000 --- a/public/app/features/plugins/sql/utils/tokenUtils.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { FROM, SCHEMA, SELECT } from '../standardSql/language'; -import { TokenType } from '../types'; - -import { LinkedToken } from './LinkedToken'; - -export const getSelectToken = (currentToken: LinkedToken | null) => - currentToken?.getPreviousOfType(TokenType.Keyword, SELECT) ?? null; - -export const getSelectStatisticToken = (currentToken: LinkedToken | null) => { - const assumedStatisticToken = getSelectToken(currentToken)?.getNextNonWhiteSpaceToken(); - return assumedStatisticToken?.isVariable() || assumedStatisticToken?.isFunction() ? assumedStatisticToken : null; -}; - -export const getMetricNameToken = (currentToken: LinkedToken | null) => { - // statistic function is followed by `(` and then an argument - const assumedMetricNameToken = getSelectStatisticToken(currentToken)?.next?.next; - return assumedMetricNameToken?.isVariable() || assumedMetricNameToken?.isIdentifier() ? assumedMetricNameToken : null; -}; - -export const getFromKeywordToken = (currentToken: LinkedToken | null) => { - const selectToken = getSelectToken(currentToken); - return selectToken?.getNextOfType(TokenType.Keyword, FROM); -}; - -export const getNamespaceToken = (currentToken: LinkedToken | null) => { - const fromToken = getFromKeywordToken(currentToken); - const nextNonWhiteSpace = fromToken?.getNextNonWhiteSpaceToken(); - - if ( - nextNonWhiteSpace?.isDoubleQuotedString() || - (nextNonWhiteSpace?.isVariable() && nextNonWhiteSpace?.value.toUpperCase() !== SCHEMA) - ) { - // schema is not used - return nextNonWhiteSpace; - } else if (nextNonWhiteSpace?.isKeyword() && nextNonWhiteSpace.next?.is(TokenType.Parenthesis, '(')) { - // schema is specified - const assumedNamespaceToken = nextNonWhiteSpace.next?.next; - if (assumedNamespaceToken?.isDoubleQuotedString() || assumedNamespaceToken?.isVariable()) { - return assumedNamespaceToken; - } - } - return null; -}; - -export const getTableToken = (currentToken: LinkedToken | null) => { - const fromToken = getFromKeywordToken(currentToken); - const nextNonWhiteSpace = fromToken?.getNextNonWhiteSpaceToken(); - if (nextNonWhiteSpace?.isVariable()) { - // TODO: resolve column from variable? - return null; - } else if (nextNonWhiteSpace?.isKeyword() && nextNonWhiteSpace.next?.is(TokenType.Parenthesis, '(')) { - return null; - } else { - return nextNonWhiteSpace; - } - return null; -}; diff --git a/public/app/features/plugins/sql/utils/types.ts b/public/app/features/plugins/sql/utils/types.ts deleted file mode 100644 index e87c24bd04c..00000000000 --- a/public/app/features/plugins/sql/utils/types.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { monacoTypes } from '@grafana/ui'; - -export interface Editor { - tokenize: (value: string, languageId: string) => monacoTypes.Token[][]; -} - -export interface Range { - containsPosition: (range: monacoTypes.IRange, position: monacoTypes.IPosition) => boolean; -} - -export interface Monaco { - editor: Editor; - Range: Range; -} diff --git a/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts b/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts index 5cd0f1ffcaf..d3c7e0556a5 100644 --- a/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts +++ b/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts @@ -1,4 +1,3 @@ -import { LinkedToken } from 'app/features/plugins/sql'; import { AGGREGATE_FNS, OPERATORS } from 'app/features/plugins/sql/constants'; import { ColumnDefinition, @@ -6,6 +5,7 @@ import { CompletionItemPriority, DB, LanguageCompletionProvider, + LinkedToken, SQLQuery, StatementPlacementProvider, SuggestionKindProvider, diff --git a/public/app/plugins/datasource/mysql/sqlCompletionProvider.ts b/public/app/plugins/datasource/mysql/sqlCompletionProvider.ts index b147cc2358c..6025456c4e5 100644 --- a/public/app/plugins/datasource/mysql/sqlCompletionProvider.ts +++ b/public/app/plugins/datasource/mysql/sqlCompletionProvider.ts @@ -1,4 +1,3 @@ -import { LinkedToken } from 'app/features/plugins/sql'; import { AGGREGATE_FNS, OPERATORS } from 'app/features/plugins/sql/constants'; import { Aggregate, @@ -7,6 +6,7 @@ import { CompletionItemPriority, DB, LanguageCompletionProvider, + LinkedToken, MetaDefinition, PositionContext, SQLQuery, diff --git a/yarn.lock b/yarn.lock index 865c08ddfe8..d36f6722dc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3799,6 +3799,20 @@ __metadata: languageName: node linkType: hard +"@grafana/experimental@npm:^0.0.2-canary.36": + version: 0.0.2-canary.36 + resolution: "@grafana/experimental@npm:0.0.2-canary.36" + dependencies: + "@types/uuid": ^8.3.3 + uuid: ^8.3.2 + peerDependencies: + "@emotion/css": 11.1.3 + react: 17.0.1 + react-select: 5.2.1 + checksum: 2aea6c2cbed323f7212c82df1b529897296c5c2938345dc0e7866cc4576c763f731f4f89803e6344ec7a3eb3940e0e8bdc4a01739b67833a5513913434130aba + languageName: node + linkType: hard + "@grafana/google-sdk@npm:0.0.3": version: 0.0.3 resolution: "@grafana/google-sdk@npm:0.0.3" @@ -10983,7 +10997,7 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:8.3.4": +"@types/uuid@npm:8.3.4, @types/uuid@npm:^8.3.3": version: 8.3.4 resolution: "@types/uuid@npm:8.3.4" checksum: 6f11f3ff70f30210edaa8071422d405e9c1d4e53abbe50fdce365150d3c698fe7bbff65c1e71ae080cbfb8fded860dbb5e174da96fdbbdfcaa3fb3daa474d20f @@ -20233,6 +20247,7 @@ __metadata: "@grafana/e2e": "workspace:*" "@grafana/e2e-selectors": "workspace:*" "@grafana/eslint-config": 4.0.0 + "@grafana/experimental": ^0.0.2-canary.36 "@grafana/google-sdk": 0.0.3 "@grafana/lezer-logql": 0.0.14 "@grafana/runtime": "workspace:*"