diff --git a/package.json b/package.json index 4db1133b..c29c599d 100644 --- a/package.json +++ b/package.json @@ -213,6 +213,15 @@ "light": "./resources/light/add-scratchpad-python.svg" } }, + { + "category": "KX", + "command": "kdb.scratchpad.sql.create", + "title": "New Workbook (SQL)", + "icon": { + "dark": "./resources/dark/sql.svg", + "light": "./resources/light/sql.svg" + } + }, { "category": "KX", "command": "kdb.connections.content.selectView", @@ -686,6 +695,10 @@ "command": "kdb.scratchpad.python.create", "when": "true" }, + { + "command": "kdb.scratchpad.sql.create", + "when": "true" + }, { "command": "kdb.connections.content.selectView", "when": "false" @@ -915,10 +928,15 @@ "group": "navigation@2" }, { - "command": "kdb.scratchpad.explorer.refresh", + "command": "kdb.scratchpad.sql.create", "when": "view == kdb-scratchpad-explorer", "group": "navigation@3" }, + { + "command": "kdb.scratchpad.explorer.refresh", + "when": "view == kdb-scratchpad-explorer", + "group": "navigation@4" + }, { "command": "kdb.queryHistory.clear", "when": "view == kdb-query-history", diff --git a/ref_card.md b/ref_card.md index 814ac75c..e194c631 100644 --- a/ref_card.md +++ b/ref_card.md @@ -6,7 +6,8 @@ | KX: Install KDB-X | KX: New Notebook | KX: Focus on Datasources view | | KX: Start REPL | KX: New Workbook (q) | KX: Focus on Workbooks view | | KX: Import Connections | KX: New Workbook (Python) | KX: Focus on Query History view | -| KX: Export Connections | KX: New Datasource | KX: Focus on Help and Feedback view | +| KX: Export Connections | KX: New Workbook (SQL) | KX: Focus on Help and Feedback view | +| | KX: New Datasource | | ## Keybindings @@ -60,10 +61,10 @@ | :--------- | :--: | :--: | :---: | :------: | :----: | :----: | :------------: | | File `q` | ✓ | ✓ | ✓ | ✓ | | | ✓ | | File `py` | ✓ | ✓ | ✓ | ✓ | | | ✓ | -| File `sql` | ✓ | | | ✓ | | | ✓ | +| File `sql` | ✓ | ✓ | | ✓ | | | ✓ | | Cell `q` | ✓ | ✓ | ✓ | ✓ | | | ✓ | | Cell `py` | ✓ | ✓ | ✓ | ✓ | | | ✓ | -| Cell `sql` | ✓ | | | ✓ | | | ✓ | +| Cell `sql` | ✓ | ✓ | | ✓ | | | ✓ | | Datasource | | | | ✓ | ✓ | ✓ | ✓ | `REPL` and `My q` requires [PyKX](https://github.com/KxSystems/kx-vscode/wiki/Use-PyKX-Within-REPL) for Python support. diff --git a/resources/dark/sql-active.svg b/resources/dark/sql-active.svg new file mode 100644 index 00000000..6e640319 --- /dev/null +++ b/resources/dark/sql-active.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/dark/sql-connected.svg b/resources/dark/sql-connected.svg new file mode 100644 index 00000000..78ae8b57 --- /dev/null +++ b/resources/dark/sql-connected.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/dark/sql.svg b/resources/dark/sql.svg new file mode 100644 index 00000000..d322be1c --- /dev/null +++ b/resources/dark/sql.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/light/sql-active.svg b/resources/light/sql-active.svg new file mode 100644 index 00000000..9ad1b138 --- /dev/null +++ b/resources/light/sql-active.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/light/sql-connected.svg b/resources/light/sql-connected.svg new file mode 100644 index 00000000..78ae8b57 --- /dev/null +++ b/resources/light/sql-connected.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/light/sql.svg b/resources/light/sql.svg new file mode 100644 index 00000000..b946a91c --- /dev/null +++ b/resources/light/sql.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/commands/serverCommand.ts b/src/commands/serverCommand.ts index 1f468580..a2b45fe8 100644 --- a/src/commands/serverCommand.ts +++ b/src/commands/serverCommand.ts @@ -78,6 +78,7 @@ import { formatScratchpadStacktrace, resultToBase64, needsScratchpad, + getSQLWrapper, } from "../utils/queryUtils"; import { openUrl } from "../utils/uriUtils"; import { @@ -1126,8 +1127,12 @@ export async function runQuery( variable = await inputVariable(); } + if (isSql && !isInsights) { + query = getSQLWrapper(query); + } + const runner = Runner.create((_, token) => { - return target || isSql + return target || (isSql && isInsights) ? variable ? populateScratchpad( getPartialDatasourceFile(query, target, isSql, isPython), diff --git a/src/commands/workspaceCommand.ts b/src/commands/workspaceCommand.ts index 91561560..d595a095 100644 --- a/src/commands/workspaceCommand.ts +++ b/src/commands/workspaceCommand.ts @@ -449,7 +449,14 @@ function isPython(uri: Uri | undefined) { } function isWorkbook(uri: Uri | undefined) { - return uri && (uri.path.endsWith(".kdb.q") || uri.path.endsWith(".kdb.py")); + /* c8 ignore start */ + return ( + uri && + (uri.path.endsWith(".kdb.q") || + uri.path.endsWith(".kdb.py") || + uri.path.endsWith(".kdb.sql")) + ); + /* c8 ignore stop */ } function isDataSource(uri: Uri | undefined) { @@ -538,15 +545,6 @@ export async function runActiveEditor(type?: ExecutionTypes) { const target = isInsights ? getTargetForUri(uri) : undefined; const isSql = executorName.endsWith(".sql"); - if (isSql && !isInsights) { - notify( - `SQL execution is not supported on ${conn.connLabel}.`, - MessageKind.ERROR, - { logger }, - ); - return; - } - if (type === ExecutionTypes.PopulateScratchpad && !isInsights) { notify( `Populating scratchpad is not supported on ${conn.connLabel}.`, diff --git a/src/extension.ts b/src/extension.ts index bd97a93c..74a4b8e2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -145,7 +145,7 @@ export async function activate(context: vscode.ExtensionContext) { ext.context.extensionUri, ); ext.scratchpadTreeProvider = new WorkspaceTreeProvider( - "**/*.kdb.{q,py}", + "**/*.kdb.{q,py,sql}", "scratchpad", ); ext.dataSourceTreeProvider = new WorkspaceTreeProvider( @@ -561,6 +561,25 @@ function registerScratchpadCommands(): CommandRegistration[] { } }, }, + { + command: "kdb.scratchpad.sql.create", + callback: async (item: FileTreeItem) => { + if (hasWorkspaceOrShowOption("adding workbooks")) { + const uri = await addWorkspaceFile( + item ? item.resourceUri : undefined, + "workbook", + ".kdb.sql", + ); + await vscode.workspace.openTextDocument(uri); + await vscode.window.showTextDocument(uri); + await vscode.commands.executeCommand( + "workbench.action.files.save", + uri, + ); + await setServerForUri(uri, undefined); + } + }, + }, { command: "kdb.scratchpad.explorer.refresh", callback: () => { diff --git a/src/services/notebookController.ts b/src/services/notebookController.ts index 2c509f0b..6f614e75 100644 --- a/src/services/notebookController.ts +++ b/src/services/notebookController.ts @@ -225,9 +225,6 @@ export class KxNotebookController { const variable = cell.metadata?.variable; if (!isInsights) { - if (kind === CellKind.SQL) { - throw new Error(`SQL is not supported on ${conn.connLabel}`); - } if (target) { throw new Error( `Setting execution target (${target}) is not supported on ${conn.connLabel}.`, @@ -253,7 +250,10 @@ export class KxNotebookController { ): Promise { const executorName = getBasename(cell.notebook.uri); - if (target || kind === CellKind.SQL) { + if ( + target || + (kind === CellKind.SQL && conn instanceof InsightsConnection) + ) { const params = getPartialDatasourceFile( cell.document.getText(), target, @@ -265,7 +265,9 @@ export class KxNotebookController { : runDataSource(params, conn.connLabel, executorName); } else { return executeQuery( - cell.document.getText(), + kind === CellKind.SQL + ? getSQLWrapper(cell.document.getText()) + : cell.document.getText(), conn.connLabel, executorName, ".", diff --git a/src/services/workspaceTreeProvider.ts b/src/services/workspaceTreeProvider.ts index ca54edf1..6b4c94bd 100644 --- a/src/services/workspaceTreeProvider.ts +++ b/src/services/workspaceTreeProvider.ts @@ -101,13 +101,17 @@ export class FileTreeItem extends TreeItem { } private getFileIconType(fileName: string) { + /* c8 ignore start */ if (fileName.endsWith(".kdb.json")) { this.baseIcon = "datasource"; } else if (fileName.endsWith(".kdb.q")) { this.baseIcon = "scratchpad"; - } else { + } else if (fileName.endsWith(".kdb.py")) { this.baseIcon = "python"; + } else { + this.baseIcon = "sql"; } + /* c8 ignore stop */ } async getChildren(): Promise { diff --git a/test/suite/commands/commands.test.ts b/test/suite/commands/commands.test.ts index a520d99c..a0dd3ca6 100644 --- a/test/suite/commands/commands.test.ts +++ b/test/suite/commands/commands.test.ts @@ -49,6 +49,7 @@ describe("Commands", () => { "kdb.datasource.create", "kdb.scratchpad.create", "kdb.scratchpad.python.create", + "kdb.scratchpad.sql.create", "kdb.connections.add", "kdb.repl.start", "kdb.createNotebook",