Skip to content

Commit

Permalink
Refactoring, file split
Browse files Browse the repository at this point in the history
  • Loading branch information
insmac committed Nov 29, 2023
1 parent a90a76f commit 2cc4772
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -1,93 +1,12 @@
import { Table, uniq } from "../../../../utils"
import * as monaco from "monaco-editor"
import { InformationSchemaColumn } from "./types"
import { editor, IRange } from "monaco-editor"
import { languages } from "monaco-editor"
import { CompletionItemPriority, InformationSchemaColumn } from "./types"
import { editor } from "monaco-editor"
import IStandaloneCodeEditor = editor.IStandaloneCodeEditor
import { findMatches, getQueryFromCursor } from "../utils"
import { operators } from "./operators"
import { dataTypes, functions, keywords } from "@questdb/sql-grammar"

const getLanguageCompletions = (range: IRange) => [
...functions.map((qdbFunction) => {
return {
label: qdbFunction,
kind: languages.CompletionItemKind.Function,
insertText: qdbFunction,
range,
}
}),
...dataTypes.map((item) => {
return {
label: item,
kind: languages.CompletionItemKind.Keyword,
insertText: item,
range,
}
}),
...keywords.map((item) => {
const keyword = item.toUpperCase()
return {
label: keyword,
kind: languages.CompletionItemKind.Keyword,
insertText: keyword,
range,
}
}),
...operators.map((item) => {
const operator = item.toUpperCase()
return {
label: operator,
kind: languages.CompletionItemKind.Operator,
insertText: operator.toUpperCase(),
range,
}
}),
]

export const getColumnCompletions = (
columns: InformationSchemaColumn[],
range: IRange,
withTableName?: boolean,
) => {
// For JOIN ON ... completions, return `table.column` text
if (withTableName) {
return columns.map((item) => ({
label: {
label: `${item.table_name}.${item.column_name}`,
detail: "",
description: item.data_type,
},
kind: languages.CompletionItemKind.Enum,
insertText: `${item.table_name}.${item.column_name}`,
sortText: "1",
range,
}))
// For everything else, return a list of unique column names.
} else {
return uniq(columns.map((item) => item.column_name)).map((columnName) => {
const tableNames = columns
.filter((item) => item.column_name === columnName)
.map((item) => item.table_name)
return {
label: {
label: columnName,
detail: ` (${tableNames.sort().join(", ")})`,
// If the column is present in multiple tables, show their list here, otherwise return the column type.
description:
tableNames.length > 1
? ""
: columns.find((item) => item.column_name === columnName)
?.data_type,
},
kind: languages.CompletionItemKind.Enum,
insertText: columnName,
sortText: "1",
range,
}
})
}
}
import { getTableCompletions } from "./getTableCompletions"
import { getColumnCompletions } from "./getColumnCompletions"
import { getLanguageCompletions } from "./getLanguageCompletions"

export const createSchemaCompletionProvider = (
editor: IStandaloneCodeEditor,
Expand Down Expand Up @@ -149,20 +68,6 @@ export const createSchemaCompletionProvider = (
const openQuote = textUntilPosition.substr(-1) === '"'
const nextCharQuote = nextChar == '"'

const tableSuggestions = tables.map((item) => {
return {
label: item.table_name,
kind: languages.CompletionItemKind.Class,
insertText: openQuote
? item.table_name + (nextCharQuote ? "" : '"')
: /^[a-z0-9_]+$/i.test(item.table_name)
? item.table_name
: `"${item.table_name}"`,
sortText: "1",
range,
}
})

if (
/(FROM|INTO|(ALTER|BACKUP|DROP|REINDEX|RENAME|TRUNCATE|VACUUM) TABLE|JOIN|UPDATE)\s$/gim.test(
textUntilPosition,
Expand All @@ -171,7 +76,13 @@ export const createSchemaCompletionProvider = (
!textUntilPosition.endsWith("= '"))
) {
return {
suggestions: tableSuggestions,
suggestions: getTableCompletions({
tables,
range,
priority: CompletionItemPriority.High,
openQuote,
nextCharQuote,
}),
}
}

Expand All @@ -186,21 +97,33 @@ export const createSchemaCompletionProvider = (
textUntilPosition.match(/\sON\s/gim) !== null
return {
suggestions: [
...getColumnCompletions(
informationSchemaColumns.filter((item) =>
...getColumnCompletions({
columns: informationSchemaColumns.filter((item) =>
tableContext.includes(item.table_name),
),
range,
withTableName,
),
priority: CompletionItemPriority.High,
}),
...getLanguageCompletions(range),
],
}
} else {
return {
suggestions: [
...getColumnCompletions(informationSchemaColumns, range),
...tableSuggestions,
...getColumnCompletions({
columns: informationSchemaColumns,
range,
withTableName: false,
priority: CompletionItemPriority.High,
}),
...getTableCompletions({
tables,
range,
priority: CompletionItemPriority.MediumHigh,
openQuote,
nextCharQuote,
}),
...getLanguageCompletions(range),
],
}
Expand All @@ -210,7 +133,13 @@ export const createSchemaCompletionProvider = (
if (word.word) {
return {
suggestions: [
...tableSuggestions,
...getTableCompletions({
tables,
range,
priority: CompletionItemPriority.High,
openQuote,
nextCharQuote,
}),
...getLanguageCompletions(range),
],
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { uniq } from "../../../../utils"
import { CompletionItemPriority, InformationSchemaColumn } from "./types"
import { IRange } from "monaco-editor"
import { languages } from "monaco-editor"

export const getColumnCompletions = ({
columns,
range,
withTableName,
priority,
}: {
columns: InformationSchemaColumn[]
range: IRange
withTableName: boolean
priority: CompletionItemPriority
}) => {
// For JOIN ON ... completions, return `table.column` text
if (withTableName) {
return columns.map((item) => ({
label: {
label: `${item.table_name}.${item.column_name}`,
detail: "",
description: item.data_type,
},
kind: languages.CompletionItemKind.Enum,
insertText: `${item.table_name}.${item.column_name}`,
sortText: priority,
range,
}))
// For everything else, return a list of unique column names.
} else {
return uniq(columns.map((item) => item.column_name)).map((columnName) => {
const tableNames = columns
.filter((item) => item.column_name === columnName)
.map((item) => item.table_name)
return {
label: {
label: columnName,
detail: ` (${tableNames.sort().join(", ")})`,
// If the column is present in multiple tables, show their list here, otherwise return the column type.
description:
tableNames.length > 1
? ""
: columns.find((item) => item.column_name === columnName)
?.data_type,
},
kind: languages.CompletionItemKind.Enum,
insertText: columnName,
sortText: priority,
range,
}
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { IRange } from "monaco-editor"
import { languages } from "monaco-editor"
import { operators } from "./operators"
import { dataTypes, functions, keywords } from "@questdb/sql-grammar"

export const getLanguageCompletions = (range: IRange) => [
...functions.map((qdbFunction) => {
return {
label: qdbFunction,
kind: languages.CompletionItemKind.Function,
insertText: qdbFunction,
range,
}
}),
...dataTypes.map((item) => {
return {
label: item,
kind: languages.CompletionItemKind.Keyword,
insertText: item,
range,
}
}),
...keywords.map((item) => {
const keyword = item.toUpperCase()
return {
label: keyword,
kind: languages.CompletionItemKind.Keyword,
insertText: keyword,
range,
}
}),
...operators.map((item) => {
const operator = item.toUpperCase()
return {
label: operator,
kind: languages.CompletionItemKind.Operator,
insertText: operator.toUpperCase(),
range,
}
}),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Table } from "../../../../utils"
import { CompletionItemPriority } from "./types"
import { IRange } from "monaco-editor"
import { languages } from "monaco-editor"

export const getTableCompletions = ({
tables,
range,
priority,
openQuote,
nextCharQuote,
}: {
tables: Table[]
range: IRange
priority: CompletionItemPriority
openQuote: boolean
nextCharQuote: boolean
}) => {
return tables.map((item) => {
return {
label: item.table_name,
kind: languages.CompletionItemKind.Class,
insertText: openQuote
? item.table_name + (nextCharQuote ? "" : '"')
: /^[a-z0-9_]+$/i.test(item.table_name)
? item.table_name
: `"${item.table_name}"`,
sortText: priority,
range,
}
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ export type InformationSchemaColumn = {
column_name: string
data_type: string
}

export enum CompletionItemPriority {
High = "1",
MediumHigh = "2",
Medium = "3",
MediumLow = "4",
Low = "5",
}

0 comments on commit 2cc4772

Please sign in to comment.