clean up some promise use in cms (#7004)

This commit is contained in:
Anthony Dresser
2019-09-06 15:58:47 -07:00
committed by GitHub
parent fda4ba81c3
commit 02f497712d
4 changed files with 261 additions and 334 deletions

View File

@@ -6,7 +6,7 @@
/** /**
* Deferred promise * Deferred promise
*/ */
export class Deferred<T> { export class Deferred<T> implements Promise<T> {
promise: Promise<T>; promise: Promise<T>;
resolve: (value?: T | PromiseLike<T>) => void; resolve: (value?: T | PromiseLike<T>) => void;
reject: (reason?: any) => void; reject: (reason?: any) => void;
@@ -17,9 +17,20 @@ export class Deferred<T> {
}); });
} }
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>; then<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>; then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult> | void): Thenable<TResult> { then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => void): Promise<U>;
return this.promise.then(onfulfilled, onrejected); then(onFulfilled?: any, onRejected?: any) {
return this.promise.then(onFulfilled, onRejected);
}
catch<TResult = never>(onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
catch<U>(onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
catch(onRejected?: any) {
return this.promise.catch(onRejected);
}
finally(onfinally?: () => void): Promise<T> {
return this.promise.finally(onfinally);
} }
} }

View File

@@ -30,14 +30,13 @@ import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHost
import { values, entries } from 'sql/base/common/objects'; import { values, entries } from 'sql/base/common/objects';
import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension'; import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
import { IAccountManagementService, AzureResource } from 'sql/platform/accounts/common/interfaces'; import { IAccountManagementService, AzureResource } from 'sql/platform/accounts/common/interfaces';
import { IServerGroupController, IServerGroupDialogCallbacks } from 'sql/platform/serverGroup/common/serverGroupController';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import * as errors from 'vs/base/common/errors'; import * as errors from 'vs/base/common/errors';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import * as platform from 'vs/platform/registry/common/platform'; import * as platform from 'vs/platform/registry/common/platform';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -55,9 +54,9 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
export class ConnectionManagementService extends Disposable implements IConnectionManagementService { export class ConnectionManagementService extends Disposable implements IConnectionManagementService {
_serviceBrand: any; _serviceBrand!: ServiceIdentifier<IConnectionManagementService>;
private _providers = new Map<string, { onReady: Thenable<azdata.ConnectionProvider>, properties: ConnectionProviderProperties }>(); private _providers = new Map<string, { onReady: Promise<azdata.ConnectionProvider>, properties: ConnectionProviderProperties }>();
private _iconProviders = new Map<string, azdata.IconProvider>(); private _iconProviders = new Map<string, azdata.IconProvider>();
private _uriToProvider: { [uri: string]: string; } = Object.create(null); private _uriToProvider: { [uri: string]: string; } = Object.create(null);
private _onAddConnectionProfile = new Emitter<IConnectionProfile>(); private _onAddConnectionProfile = new Emitter<IConnectionProfile>();
@@ -184,20 +183,15 @@ export class ConnectionManagementService extends Disposable implements IConnecti
* @param model the existing connection profile to create a new one from * @param model the existing connection profile to create a new one from
*/ */
public showConnectionDialog(params?: INewConnectionParams, options?: IConnectionCompletionOptions, model?: IConnectionProfile, connectionResult?: IConnectionResult): Promise<void> { public showConnectionDialog(params?: INewConnectionParams, options?: IConnectionCompletionOptions, model?: IConnectionProfile, connectionResult?: IConnectionResult): Promise<void> {
let self = this;
return new Promise<void>((resolve, reject) => {
if (!params) { if (!params) {
params = { connectionType: ConnectionType.default }; params = { connectionType: ConnectionType.default };
} }
if (!model && params.input && params.input.uri) { if (!model && params.input && params.input.uri) {
model = this._connectionStatusManager.getConnectionProfile(params.input.uri); model = this._connectionStatusManager.getConnectionProfile(params.input.uri);
} }
self._connectionDialogService.showDialog(self, params, model, connectionResult, options).then(() => { return this._connectionDialogService.showDialog(this, params, model, connectionResult, options).catch(dialogError => {
resolve();
}, dialogError => {
this._logService.warn('failed to open the connection dialog. error: ' + dialogError); this._logService.warn('failed to open the connection dialog. error: ' + dialogError);
reject(dialogError); throw dialogError;
});
}); });
} }
@@ -229,16 +223,14 @@ export class ConnectionManagementService extends Disposable implements IConnecti
* @param options to use after the connection is complete * @param options to use after the connection is complete
*/ */
private tryConnect(connection: IConnectionProfile, owner: IConnectableInput, options?: IConnectionCompletionOptions): Promise<IConnectionResult> { private tryConnect(connection: IConnectionProfile, owner: IConnectableInput, options?: IConnectionCompletionOptions): Promise<IConnectionResult> {
let self = this;
return new Promise<IConnectionResult>((resolve, reject) => {
// Load the password if it's not already loaded // Load the password if it's not already loaded
self._connectionStore.addSavedPassword(connection).then(async result => { return this._connectionStore.addSavedPassword(connection).then(async result => {
let newConnection = result.profile; let newConnection = result.profile;
let foundPassword = result.savedCred; let foundPassword = result.savedCred;
// If there is no password, try to load it from an existing connection // If there is no password, try to load it from an existing connection
if (!foundPassword && self._connectionStore.isPasswordRequired(newConnection)) { if (!foundPassword && this._connectionStore.isPasswordRequired(newConnection)) {
let existingConnection = self._connectionStatusManager.findConnectionProfile(connection); let existingConnection = this._connectionStatusManager.findConnectionProfile(connection);
if (existingConnection && existingConnection.connectionProfile) { if (existingConnection && existingConnection.connectionProfile) {
newConnection.password = existingConnection.connectionProfile.password; newConnection.password = existingConnection.connectionProfile.password;
foundPassword = true; foundPassword = true;
@@ -246,28 +238,23 @@ export class ConnectionManagementService extends Disposable implements IConnecti
} }
// Fill in the Azure account token if needed and open the connection dialog if it fails // Fill in the Azure account token if needed and open the connection dialog if it fails
let tokenFillSuccess = await self.fillInOrClearAzureToken(newConnection); let tokenFillSuccess = await this.fillInOrClearAzureToken(newConnection);
// If the password is required and still not loaded show the dialog // If the password is required and still not loaded show the dialog
if ((!foundPassword && self._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) || !tokenFillSuccess) { if ((!foundPassword && this._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) || !tokenFillSuccess) {
resolve(self.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options)); return this.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options);
} else { } else {
// Try to connect // Try to connect
self.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => { return this.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => {
if (!connectionResult.connected && !connectionResult.errorHandled) { if (!connectionResult.connected && !connectionResult.errorHandled) {
// If connection fails show the dialog // If connection fails show the dialog
resolve(self.showConnectionDialogOnError(connection, owner, connectionResult, options)); return this.showConnectionDialogOnError(connection, owner, connectionResult, options);
} else { } else {
//Resolve with the connection result //Resolve with the connection result
resolve(connectionResult); return connectionResult;
} }
}).catch(connectionError => {
reject(connectionError);
}); });
} }
}).catch(err => {
reject(err);
});
}); });
} }
@@ -280,8 +267,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
owner: IConnectableInput, owner: IConnectableInput,
connectionResult: IConnectionResult, connectionResult: IConnectionResult,
options?: IConnectionCompletionOptions): Promise<IConnectionResult> { options?: IConnectionCompletionOptions): Promise<IConnectionResult> {
return new Promise<IConnectionResult>((resolve, reject) => {
if (options && options.showConnectionDialogOnError) { if (options && options.showConnectionDialogOnError) {
let params: INewConnectionParams = options && options.params ? options.params : { let params: INewConnectionParams = options && options.params ? options.params : {
connectionType: this._connectionStatusManager.isDefaultTypeUri(owner.uri) ? ConnectionType.default : ConnectionType.editor, connectionType: this._connectionStatusManager.isDefaultTypeUri(owner.uri) ? ConnectionType.default : ConnectionType.editor,
@@ -289,15 +274,12 @@ export class ConnectionManagementService extends Disposable implements IConnecti
runQueryOnCompletion: RunQueryOnConnectionMode.none, runQueryOnCompletion: RunQueryOnConnectionMode.none,
showDashboard: options.showDashboard showDashboard: options.showDashboard
}; };
this.showConnectionDialog(params, options, connection, connectionResult).then(() => { return this.showConnectionDialog(params, options, connection, connectionResult).then(() => {
resolve(connectionResult); return connectionResult;
}).catch(err => {
reject(err);
}); });
} else { } else {
resolve(connectionResult); return Promise.resolve(connectionResult);
} }
});
} }
/** /**
@@ -337,10 +319,9 @@ export class ConnectionManagementService extends Disposable implements IConnecti
* The purpose is connection by default * The purpose is connection by default
*/ */
public connectIfNotConnected(connection: IConnectionProfile, purpose?: 'dashboard' | 'insights' | 'connection' | 'notebook', saveConnection: boolean = false): Promise<string> { public connectIfNotConnected(connection: IConnectionProfile, purpose?: 'dashboard' | 'insights' | 'connection' | 'notebook', saveConnection: boolean = false): Promise<string> {
return new Promise<string>((resolve, reject) => {
let ownerUri: string = Utils.generateUri(connection, purpose); let ownerUri: string = Utils.generateUri(connection, purpose);
if (this._connectionStatusManager.isConnected(ownerUri)) { if (this._connectionStatusManager.isConnected(ownerUri)) {
resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri)); return Promise.resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri));
} else { } else {
const options: IConnectionCompletionOptions = { const options: IConnectionCompletionOptions = {
saveTheConnection: saveConnection, saveTheConnection: saveConnection,
@@ -349,18 +330,15 @@ export class ConnectionManagementService extends Disposable implements IConnecti
params: undefined, params: undefined,
showFirewallRuleOnError: true, showFirewallRuleOnError: true,
}; };
this.connect(connection, ownerUri, options).then(connectionResult => { return this.connect(connection, ownerUri, options).then(connectionResult => {
if (connectionResult && connectionResult.connected) { if (connectionResult && connectionResult.connected) {
resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri)); return this._connectionStatusManager.getOriginalOwnerUri(ownerUri);
} else { } else {
reject(connectionResult.errorMessage); throw connectionResult.errorMessage;
}
}, error => {
reject(error);
});
} }
}); });
} }
}
/** /**
* Opens a new connection and saves the profile in the settings. * Opens a new connection and saves the profile in the settings.
@@ -384,8 +362,7 @@ export class ConnectionManagementService extends Disposable implements IConnecti
return this.connectWithOptions(connection, uri, options, callbacks); return this.connectWithOptions(connection, uri, options, callbacks);
} }
private connectWithOptions(connection: IConnectionProfile, uri: string, options?: IConnectionCompletionOptions, callbacks?: IConnectionCallbacks): private async connectWithOptions(connection: IConnectionProfile, uri: string, options?: IConnectionCompletionOptions, callbacks?: IConnectionCallbacks): Promise<IConnectionResult> {
Promise<IConnectionResult> {
connection.options['groupId'] = connection.groupId; connection.options['groupId'] = connection.groupId;
connection.options['databaseDisplayName'] = connection.databaseName; connection.options['databaseDisplayName'] = connection.databaseName;
@@ -411,7 +388,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
showFirewallRuleOnError: true showFirewallRuleOnError: true
}; };
} }
return new Promise<IConnectionResult>(async (resolve, reject) => {
if (callbacks.onConnectStart) { if (callbacks.onConnectStart) {
callbacks.onConnectStart(); callbacks.onConnectStart();
} }
@@ -419,7 +395,7 @@ export class ConnectionManagementService extends Disposable implements IConnecti
if (!tokenFillSuccess) { if (!tokenFillSuccess) {
throw new Error(nls.localize('connection.noAzureAccount', "Failed to get Azure account token for connection")); throw new Error(nls.localize('connection.noAzureAccount', "Failed to get Azure account token for connection"));
} }
this.createNewConnection(uri, connection).then(connectionResult => { return this.createNewConnection(uri, connection).then(connectionResult => {
if (connectionResult && connectionResult.connected) { if (connectionResult && connectionResult.connected) {
// The connected succeeded so add it to our active connections now, optionally adding it to the MRU based on // The connected succeeded so add it to our active connections now, optionally adding it to the MRU based on
// the options.saveTheConnection setting // the options.saveTheConnection setting
@@ -439,82 +415,63 @@ export class ConnectionManagementService extends Disposable implements IConnecti
this.doActionsAfterConnectionComplete(uri, options); this.doActionsAfterConnectionComplete(uri, options);
} }
if (connection.savePassword) { if (connection.savePassword) {
this._connectionStore.savePassword(connection).then(() => { return this._connectionStore.savePassword(connection).then(() => {
resolve(connectionResult); return connectionResult;
}); });
} else { } else {
resolve(connectionResult); return connectionResult;
} }
} else if (connectionResult && connectionResult.errorMessage) { } else if (connectionResult && connectionResult.errorMessage) {
this.handleConnectionError(connection, uri, options, callbacks, connectionResult).then(result => { return this.handleConnectionError(connection, uri, options, callbacks, connectionResult).catch(handleConnectionError => {
resolve(result);
}).catch(handleConnectionError => {
if (callbacks.onConnectReject) { if (callbacks.onConnectReject) {
callbacks.onConnectReject(handleConnectionError); callbacks.onConnectReject(handleConnectionError);
} }
reject(handleConnectionError); throw handleConnectionError;
}); });
} else { } else {
if (callbacks.onConnectReject) { if (callbacks.onConnectReject) {
callbacks.onConnectReject(nls.localize('connectionNotAcceptedError', "Connection Not Accepted")); callbacks.onConnectReject(nls.localize('connectionNotAcceptedError', "Connection Not Accepted"));
} }
resolve(connectionResult); return connectionResult;
} }
}).catch(err => { }).catch(err => {
if (callbacks.onConnectReject) { if (callbacks.onConnectReject) {
callbacks.onConnectReject(err); callbacks.onConnectReject(err);
} }
reject(err); throw err;
});
}); });
} }
private handleConnectionError(connection: IConnectionProfile, uri: string, options: IConnectionCompletionOptions, callbacks: IConnectionCallbacks, connectionResult: IConnectionResult) { private handleConnectionError(connection: IConnectionProfile, uri: string, options: IConnectionCompletionOptions, callbacks: IConnectionCallbacks, connectionResult: IConnectionResult) {
return new Promise<IConnectionResult>((resolve, reject) => {
let connectionNotAcceptedError = nls.localize('connectionNotAcceptedError', "Connection Not Accepted"); let connectionNotAcceptedError = nls.localize('connectionNotAcceptedError', "Connection Not Accepted");
if (options.showFirewallRuleOnError && connectionResult.errorCode) { if (options.showFirewallRuleOnError && connectionResult.errorCode) {
this.handleFirewallRuleError(connection, connectionResult).then(success => { return this.handleFirewallRuleError(connection, connectionResult).then(success => {
if (success) { if (success) {
options.showFirewallRuleOnError = false; options.showFirewallRuleOnError = false;
this.connectWithOptions(connection, uri, options, callbacks).then((result) => { return this.connectWithOptions(connection, uri, options, callbacks);
resolve(result); } else {
}).catch(connectionError => { if (callbacks.onConnectReject) {
reject(connectionError); callbacks.onConnectReject(connectionNotAcceptedError);
}
return connectionResult;
}
}); });
} else { } else {
if (callbacks.onConnectReject) { if (callbacks.onConnectReject) {
callbacks.onConnectReject(connectionNotAcceptedError); callbacks.onConnectReject(connectionNotAcceptedError);
} }
resolve(connectionResult); return Promise.resolve(connectionResult);
} }
}).catch(handleFirewallRuleError => {
reject(handleFirewallRuleError);
});
} else {
if (callbacks.onConnectReject) {
callbacks.onConnectReject(connectionNotAcceptedError);
}
resolve(connectionResult);
}
});
} }
private handleFirewallRuleError(connection: IConnectionProfile, connectionResult: IConnectionResult): Promise<boolean> { private handleFirewallRuleError(connection: IConnectionProfile, connectionResult: IConnectionResult): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => { return this._resourceProviderService.handleFirewallRule(connectionResult.errorCode, connectionResult.errorMessage, connection.providerName).then(response => {
this._resourceProviderService.handleFirewallRule(connectionResult.errorCode, connectionResult.errorMessage, connection.providerName).then(response => {
if (response.canHandleFirewallRule) { if (response.canHandleFirewallRule) {
connectionResult.errorHandled = true; connectionResult.errorHandled = true;
this._resourceProviderService.showFirewallRuleDialog(connection, response.ipAddress, response.resourceProviderId).then(success => { return this._resourceProviderService.showFirewallRuleDialog(connection, response.ipAddress, response.resourceProviderId);
resolve(success);
}).catch(showFirewallRuleError => {
reject(showFirewallRuleError);
});
} else { } else {
resolve(false); return false;
} }
}).catch(handleFirewallRuleError => {
reject(handleFirewallRuleError);
});
}); });
} }
@@ -573,12 +530,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
private focusDashboard(profile: IConnectionProfile): boolean { private focusDashboard(profile: IConnectionProfile): boolean {
let found: boolean = false; let found: boolean = false;
let options = {
preserveFocus: false,
revealIfVisible: true,
revealInCenterIfOutsideViewport: true,
pinned: true
};
this._editorService.editors.map(editor => { this._editorService.editors.map(editor => {
if (editor instanceof DashboardInput) { if (editor instanceof DashboardInput) {
@@ -637,13 +588,9 @@ export class ConnectionManagementService extends Disposable implements IConnecti
public saveProfileGroup(profile: IConnectionProfileGroup): Promise<string> { public saveProfileGroup(profile: IConnectionProfileGroup): Promise<string> {
TelemetryUtils.addTelemetry(this._telemetryService, this._logService, TelemetryKeys.AddServerGroup); TelemetryUtils.addTelemetry(this._telemetryService, this._logService, TelemetryKeys.AddServerGroup);
return new Promise<string>((resolve, reject) => { return this._connectionStore.saveProfileGroup(profile).then(groupId => {
this._connectionStore.saveProfileGroup(profile).then(groupId => {
this._onAddConnectionProfile.fire(undefined); this._onAddConnectionProfile.fire(undefined);
resolve(groupId); return groupId;
}).catch(err => {
reject(err);
});
}); });
} }
@@ -815,7 +762,7 @@ export class ConnectionManagementService extends Disposable implements IConnecti
}); });
} }
private sendDisconnectRequest(uri: string): Thenable<boolean> { private sendDisconnectRequest(uri: string): Promise<boolean> {
let providerId: string = this.getProviderIdFromUri(uri); let providerId: string = this.getProviderIdFromUri(uri);
if (!providerId) { if (!providerId) {
return Promise.resolve(false); return Promise.resolve(false);
@@ -827,7 +774,7 @@ export class ConnectionManagementService extends Disposable implements IConnecti
}); });
} }
private sendCancelRequest(uri: string): Thenable<boolean> { private sendCancelRequest(uri: string): Promise<boolean> {
let providerId: string = this.getProviderIdFromUri(uri); let providerId: string = this.getProviderIdFromUri(uri);
if (!providerId) { if (!providerId) {
return Promise.resolve(false); return Promise.resolve(false);
@@ -856,12 +803,9 @@ export class ConnectionManagementService extends Disposable implements IConnecti
} }
private saveToSettings(id: string, connection: IConnectionProfile): Promise<string> { private saveToSettings(id: string, connection: IConnectionProfile): Promise<string> {
return this._connectionStore.saveProfile(connection).then(savedProfile => {
return new Promise<string>((resolve, reject) => {
this._connectionStore.saveProfile(connection).then(savedProfile => {
let newId = this._connectionStatusManager.updateConnectionProfile(savedProfile, id); let newId = this._connectionStatusManager.updateConnectionProfile(savedProfile, id);
return resolve(newId); return newId;
});
}); });
} }
@@ -900,7 +844,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
} }
public onConnectionComplete(handle: number, info: azdata.ConnectionInfoSummary): void { public onConnectionComplete(handle: number, info: azdata.ConnectionInfoSummary): void {
const self = this;
let connection = this._connectionStatusManager.onConnectionComplete(info); let connection = this._connectionStatusManager.onConnectionComplete(info);
if (info.connectionId) { if (info.connectionId) {
@@ -911,10 +854,10 @@ export class ConnectionManagementService extends Disposable implements IConnecti
connection.extensionTimer.stop(); connection.extensionTimer.stop();
connection.connectHandler(true); connection.connectHandler(true);
self.addTelemetryForConnection(connection); this.addTelemetryForConnection(connection);
if (self._connectionStatusManager.isDefaultTypeUri(info.ownerUri)) { if (this._connectionStatusManager.isDefaultTypeUri(info.ownerUri)) {
self._connectionGlobalStatus.setStatusToConnected(info.connectionSummary); this._connectionGlobalStatus.setStatusToConnected(info.connectionSummary);
} }
} else { } else {
connection.connectHandler(false, info.errorMessage, info.errorNumber, info.messages); connection.connectHandler(false, info.errorMessage, info.errorNumber, info.messages);
@@ -967,40 +910,37 @@ export class ConnectionManagementService extends Disposable implements IConnecti
}); });
return (recentConnections.length >= 1); return (recentConnections.length >= 1);
} }
// Disconnect a URI from its current connection // Disconnect a URI from its current connection
// The default editor implementation does not perform UI updates // The default editor implementation does not perform UI updates
// The default force implementation is set to false // The default force implementation is set to false
public disconnectEditor(owner: IConnectableInput, force: boolean = false): Promise<boolean> { public disconnectEditor(owner: IConnectableInput, force: boolean = false): Promise<boolean> {
const self = this;
return new Promise<boolean>((resolve, reject) => {
// If the URI is connected, disconnect it and the editor // If the URI is connected, disconnect it and the editor
if (self.isConnected(owner.uri)) { if (this.isConnected(owner.uri)) {
let connection = self.getConnectionProfile(owner.uri); let connection = this.getConnectionProfile(owner.uri);
owner.onDisconnect(); owner.onDisconnect();
resolve(self.doDisconnect(owner.uri, connection)); return this.doDisconnect(owner.uri, connection);
// If the URI is connecting, prompt the user to cancel connecting // If the URI is connecting, prompt the user to cancel connecting
} else if (self.isConnecting(owner.uri)) { } else if (this.isConnecting(owner.uri)) {
if (!force) { if (!force) {
self.shouldCancelConnect(owner.uri).then((result) => { return this.shouldCancelConnect(owner.uri).then((result) => {
// If the user wants to cancel, then disconnect // If the user wants to cancel, then disconnect
if (result) { if (result) {
owner.onDisconnect(); owner.onDisconnect();
resolve(self.cancelEditorConnection(owner)); return this.cancelEditorConnection(owner);
} }
// If the user does not want to cancel, then ignore // If the user does not want to cancel, then ignore
resolve(false); return false;
}); });
} else { } else {
owner.onDisconnect(); owner.onDisconnect();
resolve(self.cancelEditorConnection(owner)); return this.cancelEditorConnection(owner);
} }
} }
// If the URI is disconnected, ensure the UI state is consistent and resolve true // If the URI is disconnected, ensure the UI state is consistent and resolve true
owner.onDisconnect(); owner.onDisconnect();
resolve(true); return Promise.resolve(true);
});
} }
/** /**
@@ -1036,33 +976,26 @@ export class ConnectionManagementService extends Disposable implements IConnecti
} }
// Ask user if they are sure they want to cancel connection request // Ask user if they are sure they want to cancel connection request
private shouldCancelConnect(fileUri: string): Thenable<boolean> { private shouldCancelConnect(fileUri: string): Promise<boolean> {
const self = this;
// Double check if the user actually wants to cancel their connection request // Double check if the user actually wants to cancel their connection request
return new Promise<boolean>((resolve, reject) => {
// Setup our cancellation choices // Setup our cancellation choices
let choices: { key, value }[] = [ let choices: { key, value }[] = [
{ key: nls.localize('connectionService.yes', "Yes"), value: true }, { key: nls.localize('connectionService.yes', "Yes"), value: true },
{ key: nls.localize('connectionService.no', "No"), value: false } { key: nls.localize('connectionService.no', "No"), value: false }
]; ];
self._quickInputService.pick(choices.map(x => x.key), { placeHolder: nls.localize('cancelConnectionConfirmation', "Are you sure you want to cancel this connection?"), ignoreFocusLost: true }).then((choice) => { return this._quickInputService.pick(choices.map(x => x.key), { placeHolder: nls.localize('cancelConnectionConfirmation', "Are you sure you want to cancel this connection?"), ignoreFocusLost: true }).then((choice) => {
let confirm = choices.find(x => x.key === choice); let confirm = choices.find(x => x.key === choice);
resolve(confirm && confirm.value); return confirm && confirm.value;
});
}); });
} }
private doDisconnect(fileUri: string, connection?: IConnectionProfile): Promise<boolean> { private doDisconnect(fileUri: string, connection?: IConnectionProfile): Promise<boolean> {
const self = this;
return new Promise<boolean>((resolve, reject) => {
let disconnectParams = new ConnectionContracts.DisconnectParams(); let disconnectParams = new ConnectionContracts.DisconnectParams();
disconnectParams.ownerUri = fileUri; disconnectParams.ownerUri = fileUri;
// Send a disconnection request for the input URI // Send a disconnection request for the input URI
self.sendDisconnectRequest(fileUri).then((result) => { return this.sendDisconnectRequest(fileUri).then((result) => {
// If the request was sent // If the request was sent
if (result) { if (result) {
this._connectionStatusManager.deleteConnection(fileUri); this._connectionStatusManager.deleteConnection(fileUri);
@@ -1078,15 +1011,13 @@ export class ConnectionManagementService extends Disposable implements IConnecti
// Telemetry.sendTelemetryEvent('DatabaseDisconnected'); // Telemetry.sendTelemetryEvent('DatabaseDisconnected');
} }
resolve(result); return result;
});
}); });
} }
public disconnect(connection: IConnectionProfile): Promise<void>; public disconnect(connection: IConnectionProfile): Promise<void>;
public disconnect(ownerUri: string): Promise<void>; public disconnect(ownerUri: string): Promise<void>;
public disconnect(input: any): Promise<void> { public disconnect(input: string | IConnectionProfile): Promise<void> {
return new Promise<void>((resolve, reject) => {
let uri: string; let uri: string;
let profile: IConnectionProfile; let profile: IConnectionProfile;
if (typeof input === 'object') { if (typeof input === 'object') {
@@ -1096,16 +1027,14 @@ export class ConnectionManagementService extends Disposable implements IConnecti
profile = this.getConnectionProfile(input); profile = this.getConnectionProfile(input);
uri = input; uri = input;
} }
this.doDisconnect(uri, profile).then(result => { return this.doDisconnect(uri, profile).then(result => {
if (result) { if (result) {
this.addTelemetryForConnectionDisconnected(input); this.addTelemetryForConnectionDisconnected(profile);
this._connectionStatusManager.removeConnection(uri); this._connectionStatusManager.removeConnection(uri);
resolve();
} else { } else {
reject(result); throw result;
} }
}); });
});
} }
public cancelConnection(connection: IConnectionProfile): Thenable<boolean> { public cancelConnection(connection: IConnectionProfile): Thenable<boolean> {
@@ -1113,32 +1042,24 @@ export class ConnectionManagementService extends Disposable implements IConnecti
return this.cancelConnectionForUri(fileUri); return this.cancelConnectionForUri(fileUri);
} }
public cancelConnectionForUri(fileUri: string): Thenable<boolean> { public cancelConnectionForUri(fileUri: string): Promise<boolean> {
const self = this;
return new Promise<boolean>((resolve, reject) => {
// Create a new set of cancel connection params with our file URI // Create a new set of cancel connection params with our file URI
let cancelParams: ConnectionContracts.CancelConnectParams = new ConnectionContracts.CancelConnectParams(); let cancelParams: ConnectionContracts.CancelConnectParams = new ConnectionContracts.CancelConnectParams();
cancelParams.ownerUri = fileUri; cancelParams.ownerUri = fileUri;
this._connectionStatusManager.deleteConnection(fileUri); this._connectionStatusManager.deleteConnection(fileUri);
// Send connection cancellation request // Send connection cancellation request
resolve(self.sendCancelRequest(fileUri)); return this.sendCancelRequest(fileUri);
});
} }
public cancelEditorConnection(owner: IConnectableInput): Thenable<boolean> { public cancelEditorConnection(owner: IConnectableInput): Promise<boolean> {
const self = this; let fileUri = owner.uri;
let fileUri: string = owner.uri; if (this.isConnecting(fileUri)) {
return new Promise<boolean>((resolve, reject) => { return this.cancelConnectionForUri(fileUri);
if (self.isConnecting(fileUri)) {
this.cancelConnectionForUri(fileUri).then(result => {
resolve(result);
});
} else { } else {
// If the editor is connected then there is nothing to cancel // If the editor is connected then there is nothing to cancel
resolve(false); return Promise.resolve(false);
} }
});
} }
// Is a certain file URI connected? // Is a certain file URI connected?
public isConnected(fileUri: string, connectionProfile?: ConnectionProfile): boolean { public isConnected(fileUri: string, connectionProfile?: ConnectionProfile): boolean {
@@ -1211,14 +1132,9 @@ export class ConnectionManagementService extends Disposable implements IConnecti
return Promise.resolve(false); return Promise.resolve(false);
} }
public editGroup(group: ConnectionProfileGroup): Promise<any> { public editGroup(group: ConnectionProfileGroup): Promise<void> {
return new Promise<string>((resolve, reject) => { return this._connectionStore.editGroup(group).then(groupId => {
this._connectionStore.editGroup(group).then(groupId => {
this._onAddConnectionProfile.fire(undefined); this._onAddConnectionProfile.fire(undefined);
resolve(null);
}).catch(err => {
reject(err);
});
}); });
} }

View File

@@ -395,7 +395,7 @@ export class ConnectionDialogService implements IConnectionDialogService {
params?: INewConnectionParams, params?: INewConnectionParams,
model?: IConnectionProfile, model?: IConnectionProfile,
connectionResult?: IConnectionResult, connectionResult?: IConnectionResult,
doConnect: boolean = true): Thenable<IConnectionProfile> { doConnect: boolean = true): Promise<IConnectionProfile> {
if (!doConnect) { if (!doConnect) {
this.ignoreNextConnect = true; this.ignoreNextConnect = true;
@@ -408,7 +408,7 @@ export class ConnectionDialogService implements IConnectionDialogService {
}, error => { }, error => {
this._dialogDeferredPromise.reject(error); this._dialogDeferredPromise.reject(error);
}); });
return this._dialogDeferredPromise; return this._dialogDeferredPromise.promise;
} }
public showDialog( public showDialog(
@@ -416,7 +416,7 @@ export class ConnectionDialogService implements IConnectionDialogService {
params?: INewConnectionParams, params?: INewConnectionParams,
model?: IConnectionProfile, model?: IConnectionProfile,
connectionResult?: IConnectionResult, connectionResult?: IConnectionResult,
connectionOptions?: IConnectionCompletionOptions): Thenable<void> { connectionOptions?: IConnectionCompletionOptions): Promise<void> {
this._connectionManagementService = connectionManagementService; this._connectionManagementService = connectionManagementService;

View File

@@ -13,11 +13,11 @@ export interface IConnectionDialogService {
/** /**
* Opens the connection dialog and returns the promise for successfully opening the dialog * Opens the connection dialog and returns the promise for successfully opening the dialog
*/ */
showDialog(connectionManagementService: IConnectionManagementService, params: INewConnectionParams, model: IConnectionProfile, connectionResult?: IConnectionResult, connectionOptions?: IConnectionCompletionOptions): Thenable<void>; showDialog(connectionManagementService: IConnectionManagementService, params: INewConnectionParams, model: IConnectionProfile, connectionResult?: IConnectionResult, connectionOptions?: IConnectionCompletionOptions): Promise<void>;
/** /**
* Opens the connection dialog and returns the promise when connection is made * Opens the connection dialog and returns the promise when connection is made
* or dialog is closed * or dialog is closed
*/ */
openDialogAndWait(connectionManagementService: IConnectionManagementService, params?: INewConnectionParams, model?: IConnectionProfile, connectionResult?: IConnectionResult, doConnect?: boolean): Thenable<IConnectionProfile>; openDialogAndWait(connectionManagementService: IConnectionManagementService, params?: INewConnectionParams, model?: IConnectionProfile, connectionResult?: IConnectionResult, doConnect?: boolean): Promise<IConnectionProfile>;
} }