diff --git a/src/sql/workbench/parts/objectExplorer/browser/serverTreeDataSource.ts b/src/sql/workbench/parts/objectExplorer/browser/serverTreeDataSource.ts index 9389ab01b9..75f8442b5f 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/serverTreeDataSource.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/serverTreeDataSource.ts @@ -56,40 +56,31 @@ export class ServerTreeDataSource implements IDataSource { /** * Returns the element's children as an array in a promise. */ - public getChildren(tree: ITree, element: any): Promise { - return new Promise((resolve) => { - if (element instanceof ConnectionProfile) { - TreeUpdateUtils.getObjectExplorerNode(element, this._connectionManagementService, this._objectExplorerService).then(nodes => { - resolve(nodes); - }, error => { - resolve([]); - }); - } else if (element instanceof ConnectionProfileGroup) { - resolve((element).getChildren()); - } else if (element instanceof TreeNode) { - let node = element; - if (node.children) { - resolve(node.children); - } else { - // These similar changes are probably needed for a ConnectionProfile group element as well. However, we do not have a repro of a failiure in that scenario so they will be tackled in a future checkin. - // It has been tested for connecting to the server in profile itself and things work fine there. - this._objectExplorerService.resolveTreeNodeChildren(node.getSession(), node).then(() => { - resolve(node.children); - }, async expandError => { - await node.setExpandedState(TreeItemCollapsibleState.Collapsed); - node.errorStateMessage = expandError; - this.showError(expandError); - // collapse node and refresh in case of error so remove tree cache - setTimeout(() => { - tree.collapse(element).then(() => tree.refresh(element)); - }); - resolve([]); - }); - } + public async getChildren(tree: ITree, element: any): Promise<(ConnectionProfile | ConnectionProfileGroup | TreeNode)[]> { + if (element instanceof ConnectionProfile) { + return TreeUpdateUtils.getObjectExplorerNode(element, this._connectionManagementService, this._objectExplorerService); + } else if (element instanceof ConnectionProfileGroup) { + return (element as ConnectionProfileGroup).getChildren(); + } else if (element instanceof TreeNode) { + let node = element; + if (node.children) { + return node.children; } else { - resolve([]); + try { + return this._objectExplorerService.resolveTreeNodeChildren(node.getSession(), node); + } catch (expandError) { + await node.setExpandedState(TreeItemCollapsibleState.Collapsed); + node.errorStateMessage = expandError; + this.showError(expandError); + // collapse node and refresh in case of error so remove tree cache + setTimeout(() => { + tree.collapse(element).then(() => tree.refresh(element)); + }); + return []; + } } - }); + } + return []; } /** diff --git a/src/sql/workbench/parts/objectExplorer/browser/serverTreeView.ts b/src/sql/workbench/parts/objectExplorer/browser/serverTreeView.ts index 89687bd9e9..dd4c321506 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/serverTreeView.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/serverTreeView.ts @@ -172,7 +172,7 @@ export class ServerTreeView extends Disposable { } return new Promise(async (resolve, reject) => { - this.refreshTree(); + await this.refreshTree(); const root = this._tree.getInput(); const expandGroups: boolean = this._configurationService.getValue(SERVER_GROUP_CONFIG)[SERVER_GROUP_AUTOEXPAND_CONFIG]; @@ -216,7 +216,7 @@ export class ServerTreeView extends Disposable { } await this.refreshTree(); if (newProfile && !newProfileIsSelected) { - this._tree.reveal(newProfile); + await this._tree.reveal(newProfile); this._tree.select(newProfile); } } diff --git a/src/sql/workbench/parts/objectExplorer/browser/treeUpdateUtils.ts b/src/sql/workbench/parts/objectExplorer/browser/treeUpdateUtils.ts index e6aa760ec3..5f871483f4 100644 --- a/src/sql/workbench/parts/objectExplorer/browser/treeUpdateUtils.ts +++ b/src/sql/workbench/parts/objectExplorer/browser/treeUpdateUtils.ts @@ -151,57 +151,49 @@ export class TreeUpdateUtils { return isConnected; } - public static connectIfNotConnected( + public static async connectIfNotConnected( connection: IConnectionProfile, options: IConnectionCompletionOptions, connectionManagementService: IConnectionManagementService, - tree: ITree): Promise { - return new Promise((resolve, reject) => { - if (!connectionManagementService.isProfileConnected(connection)) { - // don't try to reconnect if currently connecting - if (connectionManagementService.isProfileConnecting(connection)) { - resolve(undefined); + tree: ITree): Promise { + if (!connectionManagementService.isProfileConnected(connection)) { + // don't try to reconnect if currently connecting + if (connectionManagementService.isProfileConnecting(connection)) { + return undefined; - // else if we aren't connected or connecting then try to connect - } else { - let callbacks: IConnectionCallbacks = undefined; - if (tree) { - // Show the spinner in OE by adding the 'loading' trait to the connection, and set up callbacks to hide the spinner - tree.addTraits('loading', [connection]); - let rejectOrCancelCallback = () => { - tree.collapse(connection); - tree.removeTraits('loading', [connection]); - }; - callbacks = { - onConnectStart: undefined, - onConnectReject: rejectOrCancelCallback, - onConnectSuccess: () => tree.removeTraits('loading', [connection]), - onDisconnect: undefined, - onConnectCanceled: rejectOrCancelCallback, - }; - } - connectionManagementService.connect(connection, undefined, options, callbacks).then(result => { - if (result.connected) { - let existingConnection = connectionManagementService.findExistingConnection(connection); - resolve(existingConnection); - } else { - reject('connection failed'); - } - }, connectionError => { - reject(connectionError); - }); - } + // else if we aren't connected or connecting then try to connect } else { - let existingConnection = connectionManagementService.findExistingConnection(connection); - if (options && options.showDashboard) { - connectionManagementService.showDashboard(connection).then((value) => { - resolve(existingConnection); - }); + let callbacks: IConnectionCallbacks = undefined; + if (tree) { + // Show the spinner in OE by adding the 'loading' trait to the connection, and set up callbacks to hide the spinner + tree.addTraits('loading', [connection]); + let rejectOrCancelCallback = () => { + tree.collapse(connection); + tree.removeTraits('loading', [connection]); + }; + callbacks = { + onConnectStart: undefined, + onConnectReject: rejectOrCancelCallback, + onConnectSuccess: () => tree.removeTraits('loading', [connection]), + onDisconnect: undefined, + onConnectCanceled: rejectOrCancelCallback, + }; + } + const result = await connectionManagementService.connect(connection, undefined, options, callbacks); + if (result.connected) { + let existingConnection = connectionManagementService.findExistingConnection(connection); + return existingConnection; } else { - resolve(existingConnection); + throw new Error('connection failed'); } } - }); + } else { + let existingConnection = connectionManagementService.findExistingConnection(connection); + if (options && options.showDashboard) { + await connectionManagementService.showDashboard(connection); + } + return existingConnection; + } } /** @@ -213,34 +205,26 @@ export class TreeUpdateUtils { * @param connectionManagementService Connection management service instance * @param objectExplorerService Object explorer service instance */ - public static connectAndCreateOeSession(connection: IConnectionProfile, options: IConnectionCompletionOptions, + public static async connectAndCreateOeSession(connection: IConnectionProfile, options: IConnectionCompletionOptions, connectionManagementService: IConnectionManagementService, objectExplorerService: IObjectExplorerService, tree: ITree): Promise { - return new Promise((resolve, reject) => { - TreeUpdateUtils.connectIfNotConnected(connection, options, connectionManagementService, tree).then(connectedConnection => { - if (connectedConnection) { - // append group ID and original display name to build unique OE session ID - connectedConnection.options['groupId'] = connection.groupId; - connectedConnection.options['databaseDisplayName'] = connection.databaseName; + const connectedConnection = await TreeUpdateUtils.connectIfNotConnected(connection, options, connectionManagementService, tree); + if (connectedConnection) { + // append group ID and original display name to build unique OE session ID + connectedConnection.options['groupId'] = connection.groupId; + connectedConnection.options['databaseDisplayName'] = connection.databaseName; - let rootNode: TreeNode = objectExplorerService.getObjectExplorerNode(connectedConnection); - if (!rootNode) { - objectExplorerService.updateObjectExplorerNodes(connectedConnection).then(() => { - rootNode = objectExplorerService.getObjectExplorerNode(connectedConnection); - resolve(true); - // The oe request is sent. an event will be raised when the session is created - }, error => { - reject('session failed'); - }); - } else { - resolve(false); - } - } else { - resolve(false); - } - }, connectionError => { - reject(connectionError); - }); - }); + let rootNode: TreeNode = objectExplorerService.getObjectExplorerNode(connectedConnection); + if (!rootNode) { + await objectExplorerService.updateObjectExplorerNodes(connectedConnection); + rootNode = objectExplorerService.getObjectExplorerNode(connectedConnection); + return true; + // The oe request is sent. an event will be raised when the session is created + } else { + return false; + } + } else { + return false; + } } public static getObjectExplorerNode(connection: ConnectionProfile, connectionManagementService: IConnectionManagementService, objectExplorerService: IObjectExplorerService): Promise {