Skip to content

Commit 0f29fa6

Browse files
author
jialan
committed
feat: support built-in sql snippets
1 parent a8f6ea8 commit 0f29fa6

15 files changed

Lines changed: 321 additions & 13 deletions

src/baseSQLWorker.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { BasicSQL } from 'dt-sql-parser/dist/parser/common/basicSQL';
22
import { worker } from './fillers/monaco-editor-core';
33
import { Suggestions, ParseError, EntityContext } from 'dt-sql-parser';
44
import { Position } from './fillers/monaco-editor-core';
5+
import { SemanticContext } from 'dt-sql-parser/dist/parser/common/types';
56

67
export interface ICreateData {
78
languageId: string;
@@ -45,17 +46,32 @@ export abstract class BaseSQLWorker {
4546
async doCompletionWithEntities(
4647
code: string,
4748
position: Position
48-
): Promise<[Suggestions | null, EntityContext[] | null]> {
49+
): Promise<{
50+
suggestions: Suggestions | null;
51+
allEntities: EntityContext[] | null;
52+
context: SemanticContext | null;
53+
}> {
4954
code = code || this.getTextDocument();
5055
if (code) {
5156
const suggestions = this.parser.getSuggestionAtCaretPosition(code, position);
5257
let allEntities = null;
5358
if (suggestions?.syntax?.length) {
5459
allEntities = this.parser.getAllEntities(code, position);
5560
}
56-
return Promise.resolve([suggestions, allEntities]);
61+
const semanticContext = this.parser.getSemanticContextAtCaretPosition(code, position);
62+
63+
return Promise.resolve({
64+
suggestions,
65+
allEntities,
66+
context: semanticContext
67+
});
5768
}
58-
return Promise.resolve([null, null]);
69+
70+
return Promise.resolve({
71+
suggestions: null,
72+
allEntities: null,
73+
context: null
74+
});
5975
}
6076

6177
async getAllEntities(code: string, position?: Position): Promise<EntityContext[] | null> {

src/languageFeatures.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import { debounce } from './common/utils';
1212
import { BaseSQLWorker } from './baseSQLWorker';
1313
import type { ParseError } from 'dt-sql-parser';
14-
import type { LanguageServiceDefaults } from './monaco.contribution';
14+
import type { CompletionSnippet, LanguageServiceDefaults } from './monaco.contribution';
1515

1616
export interface WorkerAccessor<T extends BaseSQLWorker> {
1717
(...uris: Uri[]): Promise<T>;
@@ -159,13 +159,22 @@ export class CompletionAdapter<T extends BaseSQLWorker>
159159
}
160160
return worker.doCompletionWithEntities(code, position);
161161
})
162-
.then(([suggestions, allEntities]) => {
162+
.then(async ({ suggestions, allEntities, context: semanticContext }) => {
163+
let snippets: CompletionSnippet[] = [];
164+
if (semanticContext?.isNewStatement) {
165+
snippets = this._defaults.completionSnippets.map((item) => ({
166+
...item,
167+
insertText: typeof item.body === 'string' ? item.body : item.body.join('\n')
168+
}));
169+
}
170+
163171
return this._defaults.completionService(
164172
model,
165173
position,
166174
context,
167175
suggestions,
168-
allEntities
176+
allEntities,
177+
snippets
169178
);
170179
})
171180
.then((completions) => {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { CompletionSnippetOption } from 'src/monaco.contribution';
2+
3+
export const flinkSnippets: CompletionSnippetOption[] = [
4+
{
5+
prefix: 'INSERT',
6+
label: 'INSERT代码片段',
7+
body: ['insert', 'into', '\t`${1:table1}`', 'values', '\t(`$2`);', '${3}']
8+
},
9+
{
10+
prefix: 'SELECT',
11+
label: 'SELECT 通用模板',
12+
body: ['select', '\t${1:id}', 'from', '\t${2:table1};', '${3}']
13+
}
14+
];

src/languages/hive/hive.snippet.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import type { CompletionSnippetOption } from 'src/monaco.contribution';
2+
3+
export const hiveSnippets: CompletionSnippetOption[] = [
4+
{
5+
label: 'select',
6+
prefix: 'SELECT',
7+
body: ['SELECT ${2:column1}, ${3:column2} FROM ${1:table_name};\n$4']
8+
},
9+
{
10+
label: 'select join',
11+
prefix: 'SELECT-JOIN',
12+
body: [
13+
'SELECT ${8:column1} FROM ${1:table_name} ${2:t1}',
14+
'${3:LEFT} JOIN ${4:table2} ${5:t2} ON ${2:t1}.${6:column1} = ${5:t2}.${7:column2};\n$9'
15+
]
16+
},
17+
{
18+
label: 'select order-by',
19+
prefix: 'SELECT-ORDERBY',
20+
body: [
21+
'SELECT ${2:column1}, ${3:column2} FROM ${1:table_name} ORDER BY ${4:column1} ${5:desc};\n$6'
22+
]
23+
},
24+
{
25+
label: 'insert',
26+
prefix: 'INSERT',
27+
body: [
28+
'INSERT INTO ${1:table_name} (${2:column1}, ${3:column2}) VALUES (${4:value1}, ${5:value2});\n$6'
29+
]
30+
},
31+
{
32+
label: 'insert into select',
33+
prefix: 'INSERT',
34+
body: [
35+
'INSERT INTO TABLE ${1:table_name}',
36+
'SELECT ${2:column1}, ${3:column3}',
37+
'FROM ${4:source_table}',
38+
'WHERE ${5:conditions};\n$6'
39+
]
40+
},
41+
{
42+
label: 'update',
43+
prefix: 'UPDATE',
44+
body: [
45+
'UPDATE ${1:table_name} SET ${2:column1} = ${3:value1} WHERE ${4:column2} = ${5:value2};\n$6'
46+
]
47+
},
48+
{
49+
label: 'delete',
50+
prefix: 'DELETE',
51+
body: ['DELETE FROM ${1:table_name} WHERE ${2:column1} = ${3:value1};\n$4']
52+
},
53+
{
54+
label: 'create table',
55+
prefix: 'CREATE-TABLE',
56+
body: [
57+
'CREATE TABLE IF NOT EXISTS ${1:table_name} (',
58+
'\t${2:column1} ${3:STRING},',
59+
'\t${4:column2} ${5:STRING}',
60+
')',
61+
"COMMENT '${6:table_alias}'",
62+
'ROW FORMAT ${7:DELIMITE}',
63+
"FIELDS TERMINATED BY '${8:\\t}'",
64+
'STORED AS ${9:TEXTFILE};\n$10'
65+
]
66+
},
67+
{
68+
label: 'create table as select',
69+
prefix: 'CREATE-TABLE-AS-SELECT',
70+
body: [
71+
'CREATE TABLE ${1:table_name} AS',
72+
'SELECT ${2:column1}, ${3:column2}',
73+
'FROM ${4:source_table}',
74+
'WHERE ${5:conditions};\n$6'
75+
]
76+
},
77+
{
78+
label: 'create partition table',
79+
prefix: 'CREATE-PARTITION-TABLE',
80+
body: [
81+
'CREATE TABLE IF NOT EXISTS ${1:table_name} (',
82+
'\t${2:column1} ${3:STRING},',
83+
'\t${4:column2} ${5:STRING}',
84+
')',
85+
"COMMENT '${6:table_alias}'",
86+
'PARTITIONED BY (${7:part_column_name} STRING)',
87+
'ROW FORMAT ${8:DELIMITED}',
88+
"FIELDS TERMINATED BY '${9:\\t}'",
89+
'STORED AS ${10:TEXTFILE};\n$11'
90+
]
91+
},
92+
{
93+
label: 'create bucket table',
94+
prefix: 'CREATE-BUCKET-TABLE',
95+
body: [
96+
'CREATE TABLE IF NOT EXISTS ${1:table_name} (',
97+
'\t${2:column1} ${3:STRING},',
98+
'\t${4:column2} ${5:STRING}',
99+
')',
100+
"COMMENT '${6:table_alias}'",
101+
'PARTITIONED BY (${7:part_column_name} STRING)',
102+
'CLUSTERED BY (${8:bucket_column_name})',
103+
'INTO ${9:1} BUCKETS',
104+
'ROW FORMAT ${10:DELIMITED}',
105+
"FIELDS TERMINATED BY '${11:\\t}'",
106+
'STORED AS ${12:TEXTFILE};\n$13'
107+
]
108+
},
109+
{
110+
label: 'alter table partition',
111+
prefix: 'ALTER-TABLE-PARTITION',
112+
body: [
113+
'ALTER TABLE ${1:table_name}',
114+
"${2:ADD} PARTITION (${3:partition_column}='${4:partition_value}');\n$5"
115+
]
116+
}
117+
];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { CompletionSnippetOption } from 'src/monaco.contribution';
2+
3+
export const impalaSnippets: CompletionSnippetOption[] = [
4+
{
5+
prefix: 'INSERT',
6+
label: 'INSERT代码片段',
7+
body: ['insert', 'into', '\t`${1:table1}`', 'values', '\t(`$2`);', '${3}']
8+
},
9+
{
10+
prefix: 'SELECT',
11+
label: 'SELECT 通用模板',
12+
body: ['select', '\t${1:id}', 'from', '\t${2:table1};', '${3}']
13+
}
14+
];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { CompletionSnippetOption } from 'src/monaco.contribution';
2+
3+
export const mysqlSnippets: CompletionSnippetOption[] = [
4+
{
5+
prefix: 'INSERT',
6+
label: 'INSERT代码片段',
7+
body: ['insert', 'into', '\t`${1:table1}`', 'values', '\t(`$2`);', '${3}']
8+
},
9+
{
10+
prefix: 'SELECT',
11+
label: 'SELECT 通用模板',
12+
body: ['select', '\t${1:id}', 'from', '\t${2:table1};', '${3}']
13+
}
14+
];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { CompletionSnippetOption } from 'src/monaco.contribution';
2+
3+
export const pgsqlSnippets: CompletionSnippetOption[] = [
4+
{
5+
prefix: 'INSERT',
6+
label: 'INSERT代码片段',
7+
body: ['insert', 'into', '\t`${1:table1}`', 'values', '\t(`$2`);', '${3}']
8+
},
9+
{
10+
prefix: 'SELECT',
11+
label: 'SELECT 通用模板',
12+
body: ['select', '\t${1:id}', 'from', '\t${2:table1};', '${3}']
13+
}
14+
];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { CompletionSnippetOption } from 'src/monaco.contribution';
2+
3+
export const sparkSnippets: CompletionSnippetOption[] = [
4+
{
5+
prefix: 'INSERT',
6+
label: 'INSERT代码片段',
7+
body: ['insert', 'into', '\t`${1:table1}`', 'values', '\t(`$2`);', '${3}']
8+
},
9+
{
10+
prefix: 'SELECT',
11+
label: 'SELECT 通用模板',
12+
body: ['select', '\t${1:id}', 'from', '\t${2:table1};', '${3}']
13+
}
14+
];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { CompletionSnippetOption } from 'src/monaco.contribution';
2+
3+
export const trinoSnippets: CompletionSnippetOption[] = [
4+
{
5+
prefix: 'INSERT',
6+
label: 'INSERT代码片段',
7+
body: ['insert', 'into', '\t`${1:table1}`', 'values', '\t(`$2`);', '${3}']
8+
},
9+
{
10+
prefix: 'SELECT',
11+
label: 'SELECT 通用模板',
12+
body: ['select', '\t${1:id}', 'from', '\t${2:table1};', '${3}']
13+
}
14+
];

src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from './languageService';
44
export * from './setupLanguageFeatures';
55
export * from './common/constants';
66
export * from './theme';
7+
export * as snippets from './snippets';
78

89
export { EntityContextType, StmtContextType } from 'dt-sql-parser';
910

0 commit comments

Comments
 (0)