Skip to content

Commit 6c44afe

Browse files
committed
Support use of named host variables
Signed-off-by: worksofliam <mrliamallan@live.co.uk>
1 parent 5ca79b0 commit 6c44afe

File tree

5 files changed

+77
-8
lines changed

5 files changed

+77
-8
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { CodeAction, CodeActionKind, languages, TextDocument, Uri, WorkspaceEdit } from "vscode";
2+
import { remoteAssistIsEnabled } from "./logic/available";
3+
import { getSqlDocument } from "./logic/parse";
4+
5+
class SqlCodeAction extends CodeAction {
6+
constructor(title: string, kind: CodeActionKind, public file: {document: TextDocument, statementOffset: number, bindCount: number}) {
7+
super(title, kind);
8+
}
9+
}
10+
11+
const invalidBindingLabels = [`bind`, `cl`];
12+
13+
export const actionProvider = languages.registerCodeActionsProvider({ language: `sql` }, {
14+
provideCodeActions(document, range, context, token) {
15+
if (range.isEmpty) {
16+
const offset = document.offsetAt(range.start);
17+
18+
const enabled = remoteAssistIsEnabled();
19+
if (!enabled) return;
20+
21+
const sqlDoc = getSqlDocument(document);
22+
if (!sqlDoc) return;
23+
24+
const currentStatement = sqlDoc.getStatementByOffset(offset);
25+
const label = currentStatement.getLabel()?.toLowerCase() || ``;
26+
27+
if (currentStatement && !invalidBindingLabels.includes(label)) {
28+
const markers = currentStatement.getEmbeddedStatementAreas().filter(a => a.type === `marker`);
29+
const codeActions: SqlCodeAction[] = [];
30+
31+
if (markers.length > 0) {
32+
const action = new SqlCodeAction(`Generate bind statement`, CodeActionKind.QuickFix, {
33+
document,
34+
statementOffset: currentStatement.range.end,
35+
bindCount: markers.length
36+
});
37+
38+
codeActions.push(action);
39+
40+
return codeActions;
41+
}
42+
}
43+
44+
return [];
45+
}
46+
},
47+
resolveCodeAction(codeAction: SqlCodeAction, token) {
48+
if (!(codeAction instanceof SqlCodeAction)) return codeAction;
49+
codeAction.edit = new WorkspaceEdit();
50+
const document = codeAction.file.document;
51+
52+
const endOfStatementPos = document.positionAt(codeAction.file.statementOffset);
53+
const lineOfStatement = document.lineAt(endOfStatementPos.line);
54+
55+
let statement = `bind: ${new Array(codeAction.file.bindCount).fill(`v`).join(`, `)}`;
56+
57+
codeAction.edit.insert(document.uri, lineOfStatement.range.end, `\n${statement};`);
58+
return codeAction;
59+
}
60+
});

src/language/providers/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { actionProvider } from "./actionProvider";
12
import { completionProvider } from "./completionProvider";
23
import { formatProvider } from "./formatProvider";
34
import { hoverProvider, openProvider } from "./hoverProvider";
@@ -20,7 +21,8 @@ export function languageInit() {
2021
// peekProvider,
2122
...problemProvider,
2223
checkDocumentDefintion,
23-
sqlLanguageStatus
24+
sqlLanguageStatus,
25+
actionProvider
2426
);
2527

2628
return functionality;

src/language/sql/document.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ export default class Document {
223223
})
224224
}
225225

226-
removeEmbeddedAreas(statement: Statement, snippetString?: boolean): ParsedEmbeddedStatement {
226+
removeEmbeddedAreas(statement: Statement, replacement: `snippet`|`?`): ParsedEmbeddedStatement {
227227
const areas = statement.getEmbeddedStatementAreas();
228228

229229
const totalParameters = areas.filter(a => a.type === `marker`).length;
@@ -242,7 +242,14 @@ export default class Document {
242242
case `marker`:
243243
const markerContent = newContent.substring(start, end);
244244

245-
newContent = newContent.substring(0, start) + (snippetString ? `\${${totalParameters-parameterCount}:${markerContent}}` : `?`) + newContent.substring(end) + (snippetString ? `$0` : ``);
245+
switch (replacement) {
246+
case `snippet`:
247+
newContent = newContent.substring(0, start) + `\${${totalParameters-parameterCount}:${markerContent}}` + newContent.substring(end) + `$0`;
248+
break;
249+
case `?`:
250+
newContent = newContent.substring(0, start) + `?` + newContent.substring(end);
251+
break;
252+
}
246253

247254
parameterCount++;
248255
break;

src/views/results/binding.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ export function getPriorBindableStatement(editor: TextEditor, offset: number): {
1818
if (group.statements.length === 1) {
1919
const statement = group.statements[0];
2020
if (!statement.getLabel()) {
21-
const markers = statement.getEmbeddedStatementAreas().filter(a => a.type === `marker`);
21+
const newStatement = sqlDocument.removeEmbeddedAreas(statement, `?`);
2222
return {
23-
statement: sqlDocument.content.substring(group.range.start, group.range.end),
24-
parameters: markers.length
23+
statement: newStatement.content,
24+
parameters: newStatement.parameterCount
2525
};
2626
}
2727
}
@@ -40,7 +40,7 @@ export function getLiteralsFromStatement(group: StatementGroup): SqlParameter[]
4040
literals.push(token.value.substring(1, token.value.length - 1)); // Remove quotes
4141
} else if (token.type === `number`) {
4242
// Handle decimal numbers
43-
if (tokenIs(tokens[i+1], `number`) && tokenIs(tokens[i+2], `number`)) {
43+
if (tokenIs(tokens[i+1], `dot`) && tokenIs(tokens[i+2], `number`)) {
4444
literals.push(Number(`${token.value}.${tokens[i+2].value}`));
4545
i += 2; // Skip the next two tokens as they are part of the decimal number
4646
} else {

src/views/results/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ export function parseStatement(editor?: vscode.TextEditor, existingInfo?: Statem
600600

601601
if (sqlDocument) {
602602
if (statementInfo.qualifier !== `cl`) {
603-
statementInfo.embeddedInfo = sqlDocument.removeEmbeddedAreas(statementInfo.statement, true);
603+
statementInfo.embeddedInfo = sqlDocument.removeEmbeddedAreas(statementInfo.statement, `snippet`);
604604
}
605605
}
606606

0 commit comments

Comments
 (0)