From 140413328384affe3db317256bf64d96bcf722e0 Mon Sep 17 00:00:00 2001 From: Aditya Bist Date: Wed, 3 Jul 2019 17:33:34 -0700 Subject: [PATCH] Data explorer/context (#6242) * fixed context for data explorer * added more files * initial servers and database context menu actions finished * added all actions for servers and databases with correct conditions * added nodetype and nodelabel for subtype actions * added nodeinfo logic to oe shim * fixed context for cms * added all scripting actions to data explorer * review comments * fix import * fix correct context key * removed unused import * fix typo --- .../dataExplorer/common/nodeContextUtils.ts | 159 +++++++++++++ .../nodeActions.contribution.ts | 217 +++++++++++++++++- .../electron-browser/nodeCommands.ts | 79 ++++++- .../objectExplorerViewTreeShimActions.ts | 209 +++++++++++++++++ 4 files changed, 660 insertions(+), 4 deletions(-) create mode 100644 src/sql/workbench/parts/dataExplorer/common/nodeContextUtils.ts create mode 100644 src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions.ts diff --git a/src/sql/workbench/parts/dataExplorer/common/nodeContextUtils.ts b/src/sql/workbench/parts/dataExplorer/common/nodeContextUtils.ts new file mode 100644 index 0000000000..2772c30c54 --- /dev/null +++ b/src/sql/workbench/parts/dataExplorer/common/nodeContextUtils.ts @@ -0,0 +1,159 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as os from 'os'; +import { INodeContextValue } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; +import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; +import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; +import { mssqlProviderName } from 'sql/platform/connection/common/constants'; +import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; +import { ExtensionNodeType } from 'sql/workbench/api/common/sqlExtHostTypes'; + +export class NodeContextUtils extends Disposable { + + static readonly canSelect = new Set([NodeType.Table, NodeType.View]); + static readonly canEditData = new Set([NodeType.Table]); + static readonly canCreateOrDelete = new Set([NodeType.AggregateFunction, NodeType.PartitionFunction, NodeType.ScalarValuedFunction, + NodeType.Schema, NodeType.StoredProcedure, NodeType.Table, NodeType.TableValuedFunction, + NodeType.User, NodeType.UserDefinedTableType, NodeType.View]); + static readonly canExecute = new Set([NodeType.StoredProcedure]); + static readonly canAlter = new Set([NodeType.AggregateFunction, NodeType.PartitionFunction, NodeType.ScalarValuedFunction, + NodeType.StoredProcedure, NodeType.TableValuedFunction, NodeType.View]); + + // General node context keys + static NodeProvider = new RawContextKey('nodeProvider', undefined); + static IsDatabaseOrServer = new RawContextKey('isDatabaseOrServer', false); + static IsWindows = new RawContextKey('isWindows', os.platform() === 'win32'); + static IsCloud = new RawContextKey('isCloud', false); + static NodeType = new RawContextKey('nodeType', undefined); + static NodeLabel = new RawContextKey('nodeLabel', undefined); + + // Scripting context keys + static CanScriptAsSelect = new RawContextKey('canScriptAsSelect', false); + static CanEditData = new RawContextKey('canEditData', false); + static CanScriptAsCreateOrDelete = new RawContextKey('canScriptAsCreateOeDelete', false); + static CanScriptAsExecute = new RawContextKey('canScriptAsExecute', false); + static CanScriptAsAlter = new RawContextKey('canScriptAsAlter', false); + + private nodeProviderKey: IContextKey; + private isCloudKey: IContextKey; + private nodeTypeKey: IContextKey; + private nodeLabelKey: IContextKey; + private isDatabaseOrServerKey: IContextKey; + + private canScriptAsSelectKey: IContextKey; + private canEditDataKey: IContextKey; + private canScriptAsCreateOrDeleteKey: IContextKey; + private canScriptAsExecuteKey: IContextKey; + private canScriptAsAlterKey: IContextKey; + + constructor( + private nodeContextValue: INodeContextValue, + @IContextKeyService private contextKeyService: IContextKeyService, + @IConnectionManagementService private connectionManagementService: IConnectionManagementService, + @ICapabilitiesService private capabilitiesService: ICapabilitiesService + ) { + super(); + this.bindContextKeys(); + + // Set additional node context keys + if (this.nodeContextValue.node) { + const node = this.nodeContextValue.node; + if (node.payload) { + this.setNodeProvider(); + this.setIsCloud(); + if (node.type) { + this.setIsDatabaseOrServer(); + this.nodeTypeKey.set(node.type); + } else if (node.contextValue && node.providerHandle === mssqlProviderName) { + this.setIsDatabaseOrServer(); + this.setScriptingContextKeys(); + this.nodeTypeKey.set(node.contextValue); + } + } + if (node.label) { + this.nodeLabelKey.set(node.label.label); + } + } + } + + private bindContextKeys(): void { + this.isCloudKey = NodeContextUtils.IsCloud.bindTo(this.contextKeyService); + this.nodeTypeKey = NodeContextUtils.NodeType.bindTo(this.contextKeyService); + this.nodeLabelKey = NodeContextUtils.NodeLabel.bindTo(this.contextKeyService); + this.isDatabaseOrServerKey = NodeContextUtils.IsDatabaseOrServer.bindTo(this.contextKeyService); + this.canScriptAsSelectKey = NodeContextUtils.CanScriptAsSelect.bindTo(this.contextKeyService); + this.canEditDataKey = NodeContextUtils.CanEditData.bindTo(this.contextKeyService); + this.canScriptAsCreateOrDeleteKey = NodeContextUtils.CanScriptAsCreateOrDelete.bindTo(this.contextKeyService); + this.canScriptAsExecuteKey = NodeContextUtils.CanScriptAsExecute.bindTo(this.contextKeyService); + this.canScriptAsAlterKey = NodeContextUtils.CanScriptAsAlter.bindTo(this.contextKeyService); + this.nodeProviderKey = NodeContextUtils.NodeProvider.bindTo(this.contextKeyService); + } + + /** + * Helper function to get the node provider + */ + private setNodeProvider(): void { + if (this.nodeContextValue.node.payload.providerName) { + this.nodeProviderKey.set(this.nodeContextValue.node.payload.providerName); + } else if (this.nodeContextValue.node.childProvider) { + this.nodeProviderKey.set(this.nodeContextValue.node.childProvider); + } + } + + /** + * Helper function to tell whether a connected node is cloud or not + */ + private setIsCloud(): void { + const profile = new ConnectionProfile(this.capabilitiesService, + this.nodeContextValue.node.payload); + const connection = this.connectionManagementService.findExistingConnection(profile); + if (connection) { + const serverInfo = this.connectionManagementService.getServerInfo(connection.id); + if (serverInfo.isCloud) { + this.isCloudKey.set(true); + } + } + } + + /** + * Helper function to tell whether a connected node is a database or a + * server or not. Added this key because this is easier to write than + * writing an OR statement in ContextKeyExpr + */ + private setIsDatabaseOrServer(): void { + const isDatabaseOrServer = (this.nodeContextValue.node.contextValue === NodeType.Server || + this.nodeContextValue.node.contextValue === NodeType.Database || + this.nodeContextValue.node.type === ExtensionNodeType.Server || + this.nodeContextValue.node.type === ExtensionNodeType.Database); + this.isDatabaseOrServerKey.set(isDatabaseOrServer); + } + + /** + * Helper function to get the correct context from node for showing + * scripting context menu actions + */ + private setScriptingContextKeys(): void { + const nodeType = this.nodeContextValue.node.contextValue; + if (NodeContextUtils.canCreateOrDelete.has(nodeType)) { + this.canScriptAsCreateOrDeleteKey.set(true); + } + if (NodeContextUtils.canEditData.has(nodeType)) { + this.canEditDataKey.set(true); + } + if (NodeContextUtils.canAlter.has(nodeType)) { + this.canScriptAsAlterKey.set(true); + } + if (NodeContextUtils.canExecute.has(nodeType)) { + this.canScriptAsExecuteKey.set(true); + } + if (NodeContextUtils.canSelect.has(nodeType)) { + this.canScriptAsSelectKey.set(true); + } + } +} diff --git a/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts index df4f764144..191daf3e78 100644 --- a/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts +++ b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeActions.contribution.ts @@ -7,11 +7,19 @@ import { localize } from 'vs/nls'; import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { - DISCONNECT_COMMAND_ID, MANAGE_COMMAND_ID, NEW_QUERY_COMMAND_ID, REFRESH_COMMAND_ID + DISCONNECT_COMMAND_ID, MANAGE_COMMAND_ID, NEW_QUERY_COMMAND_ID, REFRESH_COMMAND_ID, + NEW_NOTEBOOK_COMMAND_ID, SCHEMA_COMPARE_COMMAND_ID, DATA_TIER_WIZARD_COMMAND_ID, + IMPORT_COMMAND_ID, BACKUP_COMMAND_ID, RESTORE_COMMAND_ID } from './nodeCommands'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { + PROFILER_COMMAND_ID, GENERATE_SCRIPTS_COMMAND_ID, PROPERTIES_COMMAND_ID, + SCRIPT_AS_CREATE_COMMAND_ID, SCRIPT_AS_DELETE_COMMAND_ID, SCRIPT_AS_SELECT_COMMAND_ID, + SCRIPT_AS_EXECUTE_COMMAND_ID, SCRIPT_AS_ALTER_COMMAND_ID, EDIT_DATA_COMMAND_ID +} from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions'; +import { ContextKeyExpr, ContextKeyRegexExpr } from 'vs/platform/contextkey/common/contextkey'; import { NodeContextKey } from 'sql/workbench/parts/dataExplorer/common/nodeContext'; import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/common/mssqlNodeContext'; +import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; // Disconnect @@ -69,4 +77,209 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { title: localize('refresh', 'Refresh') }, when: NodeContextKey.IsConnectable +}); + + +// New Notebook +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 3, + command: { + id: NEW_NOTEBOOK_COMMAND_ID, + title: localize('newNotebook', 'New Notebook') + }, + when: ContextKeyExpr.and(NodeContextKey.IsConnectable, + MssqlNodeContext.IsDatabaseOrServer, + MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName)) +}); + +// Data-Tier Application Wizard +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'export', + order: 7, + command: { + id: DATA_TIER_WIZARD_COMMAND_ID, + title: localize('dacFx', 'Data-tier Application Wizard') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.IsDatabaseOrServer) +}); + + +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'export', + order: 7, + command: { + id: DATA_TIER_WIZARD_COMMAND_ID, + title: localize('dacFx', 'Data-tier Application Wizard') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Folder), + MssqlNodeContext.NodeLabel.isEqualTo('Databases')) +}); + +// Profiler +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'profiler', + order: 8, + command: { + id: PROFILER_COMMAND_ID, + title: localize('profiler', 'Launch Profiler') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Server)) +}); + +// Flat File Import +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'import', + order: 10, + command: { + id: IMPORT_COMMAND_ID, + title: localize('flatFileImport', 'Import Wizard') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) +}); + +// Schema Compare +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'export', + order: 9, + command: { + id: SCHEMA_COMPARE_COMMAND_ID, + title: localize('schemaCompare', 'Schema Compare') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) +}); + +// Backup Action +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 4, + command: { + id: BACKUP_COMMAND_ID, + title: localize('backup', 'Backup') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) +}); + +// Restore Action +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 5, + command: { + id: RESTORE_COMMAND_ID, + title: localize('restore', 'Restore') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) +}); + +// Generate Scripts Action +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'z-AdminToolExt@1', + order: 11, + command: { + id: GENERATE_SCRIPTS_COMMAND_ID, + title: localize('generateScripts', 'Generate Scripts...') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), + MssqlNodeContext.IsWindows) +}); + +// Properties Action +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'z-AdminToolExt@2', + order: 12, + command: { + id: PROPERTIES_COMMAND_ID, + title: localize('properties', 'Properties') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.NodeType.isEqualTo(NodeType.Server), ContextKeyExpr.not('isCloud'), + MssqlNodeContext.IsWindows) +}); + +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'z-AdminToolExt@2', + order: 12, + command: { + id: PROPERTIES_COMMAND_ID, + title: localize('properties', 'Properties') + }, + when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), + MssqlNodeContext.IsWindows, + new ContextKeyRegexExpr('nodeType', /^(Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/)) +}); + +//////////////// Scripting Actions ///////////////// + +// Script as Create +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 3, + command: { + id: SCRIPT_AS_CREATE_COMMAND_ID, + title: localize('scriptAsCreate', 'Script as Create') + }, + when: MssqlNodeContext.CanScriptAsCreateOrDelete +}); + +// Script as Delete +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 4, + command: { + id: SCRIPT_AS_DELETE_COMMAND_ID, + title: localize('scriptAsDelete', 'Script as Drop') + }, + when: MssqlNodeContext.CanScriptAsCreateOrDelete +}); + +// Script as Select +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 1, + command: { + id: SCRIPT_AS_SELECT_COMMAND_ID, + title: localize('scriptAsSelect', 'Select Top 1000') + }, + when: MssqlNodeContext.CanScriptAsSelect +}); + +// Script as Execute +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 5, + command: { + id: SCRIPT_AS_EXECUTE_COMMAND_ID, + title: localize('scriptAsExecute', 'Script as Execute') + }, + when: MssqlNodeContext.CanScriptAsExecute +}); + +// Script as Alter +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 5, + command: { + id: SCRIPT_AS_ALTER_COMMAND_ID, + title: localize('scriptAsAlter', 'Script as Alter') + }, + when: MssqlNodeContext.CanScriptAsAlter +}); + +// Edit Data +MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { + group: 'connection', + order: 2, + command: { + id: EDIT_DATA_COMMAND_ID, + title: localize('editData', 'Edit Data') + }, + when: MssqlNodeContext.CanEditData }); \ No newline at end of file diff --git a/src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommands.ts b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommands.ts index 3a4468e9f9..16d5cfff11 100644 --- a/src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommands.ts +++ b/src/sql/workbench/parts/dataExplorer/electron-browser/nodeCommands.ts @@ -3,6 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as azdata from 'azdata'; import { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim'; import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; import { ConnectionType, IConnectableInput, IConnectionCompletionOptions, IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; @@ -14,11 +15,22 @@ import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/c import { IViewsRegistry, Extensions } from 'vs/workbench/common/views'; import { IProgressService2 } from 'vs/platform/progress/common/progress'; import { Registry } from 'vs/platform/registry/common/platform'; +import { NewNotebookAction } from 'sql/workbench/parts/notebook/notebookActions'; +import { BackupAction, RestoreAction } from 'sql/workbench/common/actions'; export const DISCONNECT_COMMAND_ID = 'dataExplorer.disconnect'; export const MANAGE_COMMAND_ID = 'dataExplorer.manage'; export const NEW_QUERY_COMMAND_ID = 'dataExplorer.newQuery'; export const REFRESH_COMMAND_ID = 'dataExplorer.refresh'; +export const NEW_NOTEBOOK_COMMAND_ID = 'dataExplorer.newNotebook'; +export const DATA_TIER_WIZARD_COMMAND_ID = 'dataExplorer.dataTierWizard'; +export const PROFILER_COMMAND_ID = 'dataExplorer.profiler'; +export const IMPORT_COMMAND_ID = 'dataExplorer.flatFileImport'; +export const SCHEMA_COMPARE_COMMAND_ID = 'dataExplorer.schemaCompare'; +export const BACKUP_COMMAND_ID = 'dataExplorer.backup'; +export const RESTORE_COMMAND_ID = 'dataExplorer.restore'; +export const GENERATE_SCRIPTS_COMMAND_ID = 'dataExplorer.generateScripts'; +export const PROPERTIES_COMMAND_ID = 'dataExplorer.properties'; // Disconnect CommandsRegistry.registerCommand({ @@ -86,11 +98,11 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand({ id: REFRESH_COMMAND_ID, handler: (accessor, args: TreeViewItemHandleArg) => { - const progressSerivce = accessor.get(IProgressService2); + const progressService = accessor.get(IProgressService2); if (args.$treeItem) { const { treeView } = (Registry.as(Extensions.ViewsRegistry).getView(args.$treeViewId)); if (args.$treeContainerId) { - return progressSerivce.withProgress({ location: args.$treeContainerId }, () => treeView.refresh([args.$treeItem]).then(() => true)); + return progressService.withProgress({ location: args.$treeContainerId }, () => treeView.refresh([args.$treeItem]).then(() => true)); } else { return treeView.refresh([args.$treeItem]).then(() => true); } @@ -98,4 +110,67 @@ CommandsRegistry.registerCommand({ } return Promise.resolve(true); } +}); + +// New Notebook +CommandsRegistry.registerCommand({ + id: NEW_NOTEBOOK_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const capabilitiesService = accessor.get(ICapabilitiesService); + const commandService = accessor.get(ICommandService); + let profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + const connectedContext: azdata.ConnectedContext = { connectionProfile: profile }; + return commandService.executeCommand(NewNotebookAction.ID, connectedContext); + } +}); + +// Data Tier Wizard +CommandsRegistry.registerCommand({ + id: DATA_TIER_WIZARD_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand('dacFx.start', connectedContext); + } +}); + + +// Flat File Import +CommandsRegistry.registerCommand({ + id: IMPORT_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand('flatFileImport.start', connectedContext); + } +}); + +// Schema Compare +CommandsRegistry.registerCommand({ + id: SCHEMA_COMPARE_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand('schemaCompare.start', connectedContext); + } +}); + +// Backup +CommandsRegistry.registerCommand({ + id: BACKUP_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand(BackupAction.ID, connectedContext); + } +}); + +// Restore +CommandsRegistry.registerCommand({ + id: RESTORE_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + let connectedContext: azdata.ConnectedContext = { connectionProfile: args.$treeItem.payload }; + return commandService.executeCommand(RestoreAction.ID, connectedContext); + } }); \ No newline at end of file diff --git a/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions.ts b/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions.ts new file mode 100644 index 0000000000..4b267c33b3 --- /dev/null +++ b/src/sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShimActions.ts @@ -0,0 +1,209 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as azdata from 'azdata'; +import { IOEShimService } from 'sql/workbench/parts/objectExplorer/common/objectExplorerViewTreeShim'; +import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; +import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; +import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; +import { TreeViewItemHandleArg } from 'sql/workbench/common/views'; +import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; +import { IScriptingService } from 'sql/platform/scripting/common/scriptingService'; +import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; +import { IProgressService2 } from 'vs/platform/progress/common/progress'; +import { ScriptCreateAction, BaseActionContext, ScriptDeleteAction, ScriptSelectAction, ScriptExecuteAction, ScriptAlterAction, EditDataAction } from 'sql/workbench/common/actions'; +import { VIEWLET_ID } from 'sql/workbench/parts/dataExplorer/browser/dataExplorerExtensionPoint'; + +export const PROFILER_COMMAND_ID = 'dataExplorer.profiler'; +export const GENERATE_SCRIPTS_COMMAND_ID = 'dataExplorer.generateScripts'; +export const PROPERTIES_COMMAND_ID = 'dataExplorer.properties'; +export const SCRIPT_AS_CREATE_COMMAND_ID = 'dataExplorer.scriptAsCreate'; +export const SCRIPT_AS_DELETE_COMMAND_ID = 'dataExplorer.scriptAsDelete'; +export const SCRIPT_AS_SELECT_COMMAND_ID = 'dataExplorer.scriptAsSelect'; +export const SCRIPT_AS_EXECUTE_COMMAND_ID = 'dataExplorer.scriptAsExecute'; +export const SCRIPT_AS_ALTER_COMMAND_ID = 'dataExplorer.scriptAsAlter'; +export const EDIT_DATA_COMMAND_ID = 'dataExplorer.scriptAsAlter'; + +// Profiler +CommandsRegistry.registerCommand({ + id: PROFILER_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const oeShimService = accessor.get(IOEShimService); + const objectExplorerContext: azdata.ObjectExplorerContext = { + connectionProfile: args.$treeItem.payload, + isConnectionNode: true, + nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) + }; + return commandService.executeCommand('profiler.newProfiler', objectExplorerContext); + } +}); + +// Generate Scripts +CommandsRegistry.registerCommand({ + id: GENERATE_SCRIPTS_COMMAND_ID, + handler: (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const oeShimService = accessor.get(IOEShimService); + const objectExplorerContext: azdata.ObjectExplorerContext = { + connectionProfile: args.$treeItem.payload, + isConnectionNode: true, + nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) + }; + return commandService.executeCommand('adminToolExtWin.launchSsmsMinGswDialog', objectExplorerContext); + } +}); + +// Properties +CommandsRegistry.registerCommand({ + id: PROPERTIES_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const commandService = accessor.get(ICommandService); + const capabilitiesService = accessor.get(ICapabilitiesService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const oeShimService = accessor.get(IOEShimService); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + await connectionManagementService.connectIfNotConnected(profile); + const objectExplorerContext: azdata.ObjectExplorerContext = { + connectionProfile: args.$treeItem.payload, + isConnectionNode: true, + nodeInfo: oeShimService.getNodeInfoForTreeItem(args.$treeItem) + }; + return commandService.executeCommand('adminToolExtWin.launchSsmsMinPropertiesDialog', objectExplorerContext); + } +}); + +//////////////// Scripting Actions ///////////////// + +// Script as Create +CommandsRegistry.registerCommand({ + id: SCRIPT_AS_CREATE_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const capabilitiesService = accessor.get(ICapabilitiesService); + const oeShimService = accessor.get(IOEShimService); + const queryEditorService = accessor.get(IQueryEditorService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const scriptingService = accessor.get(IScriptingService); + const errorMessageService = accessor.get(IErrorMessageService); + const progressService = accessor.get(IProgressService2); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + const baseContext: BaseActionContext = { + profile: profile, + object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata + }; + const scriptCreateAction = new ScriptCreateAction(ScriptCreateAction.ID, ScriptCreateAction.LABEL, + queryEditorService, connectionManagementService, scriptingService, errorMessageService); + return progressService.withProgress({ location: VIEWLET_ID }, () => scriptCreateAction.run(baseContext)); + } +}); + +// Script as Delete +CommandsRegistry.registerCommand({ + id: SCRIPT_AS_DELETE_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const capabilitiesService = accessor.get(ICapabilitiesService); + const oeShimService = accessor.get(IOEShimService); + const queryEditorService = accessor.get(IQueryEditorService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const scriptingService = accessor.get(IScriptingService); + const errorMessageService = accessor.get(IErrorMessageService); + const progressService = accessor.get(IProgressService2); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + const baseContext: BaseActionContext = { + profile: profile, + object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata + }; + const scriptDeleteAction = new ScriptDeleteAction(ScriptDeleteAction.ID, ScriptDeleteAction.LABEL, + queryEditorService, connectionManagementService, scriptingService, errorMessageService); + return progressService.withProgress({ location: VIEWLET_ID }, () => scriptDeleteAction.run(baseContext)); + } +}); + +// Script as Select +CommandsRegistry.registerCommand({ + id: SCRIPT_AS_SELECT_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const capabilitiesService = accessor.get(ICapabilitiesService); + const oeShimService = accessor.get(IOEShimService); + const queryEditorService = accessor.get(IQueryEditorService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const scriptingService = accessor.get(IScriptingService); + const progressService = accessor.get(IProgressService2); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + const baseContext: BaseActionContext = { + profile: profile, + object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata + }; + const scriptSelectAction = new ScriptSelectAction(ScriptSelectAction.ID, ScriptSelectAction.LABEL, + queryEditorService, connectionManagementService, scriptingService); + return progressService.withProgress({ location: VIEWLET_ID }, () => scriptSelectAction.run(baseContext)); + } +}); + +// Script as Execute +CommandsRegistry.registerCommand({ + id: SCRIPT_AS_EXECUTE_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const capabilitiesService = accessor.get(ICapabilitiesService); + const oeShimService = accessor.get(IOEShimService); + const queryEditorService = accessor.get(IQueryEditorService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const scriptingService = accessor.get(IScriptingService); + const progressService = accessor.get(IProgressService2); + const errorMessageService = accessor.get(IErrorMessageService); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + const baseContext: BaseActionContext = { + profile: profile, + object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata + }; + const scriptExecuteAction = new ScriptExecuteAction(ScriptExecuteAction.ID, ScriptExecuteAction.LABEL, + queryEditorService, connectionManagementService, scriptingService, errorMessageService); + return progressService.withProgress({ location: VIEWLET_ID }, () => scriptExecuteAction.run(baseContext)); + } +}); + +// Script as Alter +CommandsRegistry.registerCommand({ + id: SCRIPT_AS_ALTER_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const capabilitiesService = accessor.get(ICapabilitiesService); + const oeShimService = accessor.get(IOEShimService); + const queryEditorService = accessor.get(IQueryEditorService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const scriptingService = accessor.get(IScriptingService); + const progressService = accessor.get(IProgressService2); + const errorMessageService = accessor.get(IErrorMessageService); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + const baseContext: BaseActionContext = { + profile: profile, + object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata + }; + const scriptAlterAction = new ScriptAlterAction(ScriptAlterAction.ID, ScriptAlterAction.LABEL, + queryEditorService, connectionManagementService, scriptingService, errorMessageService); + return progressService.withProgress({ location: VIEWLET_ID }, () => scriptAlterAction.run(baseContext)); + } +}); + +// Edit Data +CommandsRegistry.registerCommand({ + id: EDIT_DATA_COMMAND_ID, + handler: async (accessor, args: TreeViewItemHandleArg) => { + const capabilitiesService = accessor.get(ICapabilitiesService); + const oeShimService = accessor.get(IOEShimService); + const queryEditorService = accessor.get(IQueryEditorService); + const connectionManagementService = accessor.get(IConnectionManagementService); + const scriptingService = accessor.get(IScriptingService); + const progressService = accessor.get(IProgressService2); + const profile = new ConnectionProfile(capabilitiesService, args.$treeItem.payload); + const baseContext: BaseActionContext = { + profile: profile, + object: oeShimService.getNodeInfoForTreeItem(args.$treeItem).metadata + }; + const editDataAction = new EditDataAction(EditDataAction.ID, EditDataAction.LABEL, + queryEditorService, connectionManagementService, scriptingService); + return progressService.withProgress({ location: VIEWLET_ID }, () => editDataAction.run(baseContext)); + } +}); \ No newline at end of file