useAddDefinitions.ts112 lines · main
1import { Monaco } from '@monaco-editor/react'
2import { LOCAL_STORAGE_KEYS } from 'common'
3import type { IDisposable } from 'monaco-editor'
4import { useEffect, useRef } from 'react'
5
6import getPgsqlCompletionProvider from '@/components/ui/CodeEditor/Providers/PgSQLCompletionProvider'
7import getPgsqlSignatureHelpProvider from '@/components/ui/CodeEditor/Providers/PgSQLSignatureHelpProvider'
8import { useDatabaseFunctionsQuery } from '@/data/database-functions/database-functions-query'
9import { useKeywordsQuery } from '@/data/database/keywords-query'
10import { useSchemasQuery } from '@/data/database/schemas-query'
11import { useTableColumnsQuery } from '@/data/database/table-columns-query'
12import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
13import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
14import { formatSql } from '@/lib/formatSql'
15import { useSqlEditorV2StateSnapshot } from '@/state/sql-editor-v2'
16
17export const useAddDefinitions = (id: string, monaco: Monaco | null) => {
18 const { data: project } = useSelectedProjectQuery()
19 const snapV2 = useSqlEditorV2StateSnapshot()
20
21 const [intellisenseEnabled] = useLocalStorageQuery(
22 LOCAL_STORAGE_KEYS.SQL_EDITOR_INTELLISENSE,
23 true
24 )
25
26 const { data: keywords, isSuccess: isKeywordsSuccess } = useKeywordsQuery(
27 {
28 projectRef: project?.ref,
29 connectionString: project?.connectionString,
30 },
31 { enabled: intellisenseEnabled }
32 )
33 const { data: functions, isSuccess: isFunctionsSuccess } = useDatabaseFunctionsQuery(
34 {
35 projectRef: project?.ref,
36 connectionString: project?.connectionString,
37 },
38 { enabled: intellisenseEnabled }
39 )
40 const { data: schemas, isSuccess: isSchemasSuccess } = useSchemasQuery(
41 {
42 projectRef: project?.ref,
43 connectionString: project?.connectionString,
44 },
45 { enabled: intellisenseEnabled }
46 )
47 const { data: tableColumns, isSuccess: isTableColumnsSuccess } = useTableColumnsQuery(
48 {
49 projectRef: project?.ref,
50 connectionString: project?.connectionString,
51 },
52 { enabled: intellisenseEnabled }
53 )
54
55 const pgInfoRef = useRef<any>(null)
56
57 const isPgInfoReady =
58 intellisenseEnabled &&
59 isTableColumnsSuccess &&
60 isSchemasSuccess &&
61 isKeywordsSuccess &&
62 isFunctionsSuccess
63
64 if (isPgInfoReady) {
65 if (pgInfoRef.current === null) {
66 pgInfoRef.current = {}
67 }
68 pgInfoRef.current.tableColumns = tableColumns
69 pgInfoRef.current.schemas = schemas
70 pgInfoRef.current.keywords = keywords
71 pgInfoRef.current.functions = functions
72 }
73
74 // Enable pgsql format
75 useEffect(() => {
76 if (monaco) {
77 const formatProvider = monaco.languages.registerDocumentFormattingEditProvider('pgsql', {
78 async provideDocumentFormattingEdits(model) {
79 const value = model.getValue()
80 const formatted = formatSql(value)
81 if (id) snapV2.setSql({ id, sql: formatted })
82 return [{ range: model.getFullModelRange(), text: formatted }]
83 },
84 })
85 return () => formatProvider.dispose()
86 }
87 // eslint-disable-next-line react-hooks/exhaustive-deps
88 }, [monaco])
89
90 // Register auto completion item provider for pgsql
91 useEffect(() => {
92 let completeProvider: IDisposable | null = null
93 let signatureHelpProvider: IDisposable | null = null
94
95 if (isPgInfoReady) {
96 if (monaco && isPgInfoReady) {
97 completeProvider = monaco.languages.registerCompletionItemProvider(
98 'pgsql',
99 getPgsqlCompletionProvider(monaco, pgInfoRef)
100 )
101 signatureHelpProvider = monaco.languages.registerSignatureHelpProvider(
102 'pgsql',
103 getPgsqlSignatureHelpProvider(monaco, pgInfoRef)
104 )
105 }
106 }
107 return () => {
108 completeProvider?.dispose()
109 signatureHelpProvider?.dispose()
110 }
111 }, [isPgInfoReady, monaco])
112}