1
1
const vscode = require ( `vscode` ) ;
2
2
3
+ const { Parser } = require ( `node-sql-parser` ) ;
4
+
3
5
const Store = require ( `./store` ) ;
4
6
7
+ /** @type {{[path: string]: object} } */
8
+ const workingAst = { }
9
+
5
10
/**
6
11
*
7
12
* @param {vscode.ExtensionContext } context
8
13
*/
9
14
exports . initialise = async ( context ) => {
15
+
10
16
context . subscriptions . push (
17
+ vscode . workspace . onDidChangeTextDocument ( async ( editor ) => {
18
+ const document = editor . document ;
19
+ const text = document . getText ( ) ;
20
+
21
+ if ( text . endsWith ( `.` ) ) return ;
22
+
23
+ if ( document . languageId === `sql` ) {
24
+ const parser = new Parser ( ) ;
25
+ try {
26
+ const sqlAst = parser . astify ( document . getText ( ) , {
27
+ database : `DB2` ,
28
+ } ) ;
29
+
30
+ if ( sqlAst ) workingAst [ document . uri . path ] = sqlAst ;
31
+ } catch ( e ) {
32
+ console . log ( e ) ;
33
+ }
34
+ }
35
+ } ) ,
36
+
11
37
vscode . languages . registerCompletionItemProvider ( { language : `sql` } , {
38
+ // @ts -ignore
12
39
provideCompletionItems : async ( document , position ) => {
13
40
///** @type vscode.CompletionItem[] */
14
41
const items = [ ] ;
@@ -21,8 +48,59 @@ exports.initialise = async (context) => {
21
48
items . push ( item ) ;
22
49
} ) ;
23
50
51
+ const ast = workingAst [ document . uri . path ] ;
52
+ if ( ast ) {
53
+ if ( ast . from && ast . from . length > 0 ) {
54
+ ast . from . forEach ( definedAs => {
55
+ const item = new vscode . CompletionItem ( definedAs . as || definedAs . table , vscode . CompletionItemKind . Struct ) ;
56
+ item . detail = `${ definedAs . db } .${ definedAs . table } ` ;
57
+ items . push ( item ) ;
58
+ } ) ;
59
+ }
60
+ } ;
61
+
24
62
return items ;
25
63
}
26
64
} )
27
- )
65
+ ) ,
66
+
67
+ vscode . languages . registerCompletionItemProvider ( { language : `sql` } , {
68
+ // @ts -ignore
69
+ provideCompletionItems : async ( document , position ) => {
70
+ ///** @type vscode.CompletionItem[] */
71
+ const items = [ ] ;
72
+
73
+ const ast = workingAst [ document . uri . path ] ;
74
+ if ( ast ) {
75
+ if ( ast . from && ast . from . length > 0 ) {
76
+ const currentPosition = new vscode . Position ( position . line , position . character - 1 ) ;
77
+ const range = document . getWordRangeAtPosition ( currentPosition ) ;
78
+
79
+ if ( range ) {
80
+ const prefix = document . getText ( range ) ;
81
+
82
+ console . log ( prefix ) ;
83
+
84
+ const definedAs =
85
+ ast . from . find ( f => f . as === prefix ) ||
86
+ ast . from . find ( f => f . table === prefix ) ;
87
+
88
+ if ( definedAs ) {
89
+ const columns = await Store . getTable ( definedAs . db , definedAs . table ) ;
90
+
91
+ columns . forEach ( column => {
92
+ const item = new vscode . CompletionItem ( column . COLUMN_NAME . toLowerCase ( ) , vscode . CompletionItemKind . Field ) ;
93
+ item . insertText = new vscode . SnippetString ( column . COLUMN_NAME . toLowerCase ( ) ) ;
94
+ item . detail = column . DATA_TYPE ;
95
+ item . documentation = new vscode . MarkdownString ( `${ column . COLUMN_TEXT } (\`${ definedAs . db } .${ definedAs . table } \`)` ) ;
96
+ items . push ( item ) ;
97
+ } ) ;
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ return items ;
104
+ }
105
+ } , `.` )
28
106
}
0 commit comments