mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-29 09:35:38 -05:00
window reuse for connections (#4049)
* window reuse for connections * space after colon * use undefined instead of null
This commit is contained in:
@@ -5,13 +5,15 @@
|
||||
|
||||
'use strict';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
|
||||
export interface ICommandLineProcessing {
|
||||
_serviceBrand: any;
|
||||
/**
|
||||
* Interprets the various Azure Data Studio-specific command line switches and
|
||||
* performs the requisite tasks such as connecting to a server
|
||||
*/
|
||||
processCommandLine(): Promise<void>;
|
||||
processCommandLine(args: ParsedArgs): Promise<void>;
|
||||
}
|
||||
|
||||
export const ICommandLineProcessing = createDecorator<ICommandLineProcessing>('commandLineService');
|
||||
@@ -7,7 +7,7 @@ import { ConnectionProfile } from 'sql/platform/connection/common/connectionProf
|
||||
import { ICommandLineProcessing } from 'sql/workbench/services/commandLine/common/commandLine';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
|
||||
import * as platform from 'vs/platform/registry/common/platform';
|
||||
@@ -18,14 +18,12 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
||||
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { warn } from 'sql/base/common/log';
|
||||
import { ipcRenderer as ipc} from 'electron';
|
||||
|
||||
export class CommandLineService implements ICommandLineProcessing {
|
||||
private _connectionProfile: ConnectionProfile;
|
||||
private _showConnectionDialog: boolean;
|
||||
private _commandName: string;
|
||||
|
||||
constructor(
|
||||
@ICapabilitiesService _capabilitiesService: ICapabilitiesService,
|
||||
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IEnvironmentService private _environmentService: IEnvironmentService,
|
||||
@IQueryEditorService private _queryEditorService: IQueryEditorService,
|
||||
@@ -34,52 +32,62 @@ export class CommandLineService implements ICommandLineProcessing {
|
||||
@ICommandService private _commandService: ICommandService,
|
||||
@IWorkspaceConfigurationService private _configurationService: IWorkspaceConfigurationService
|
||||
) {
|
||||
let profile = null;
|
||||
if (this._environmentService) {
|
||||
if (this._commandService) {
|
||||
this._commandName = this._environmentService.args.command;
|
||||
}
|
||||
if (this._environmentService.args.server) {
|
||||
profile = new ConnectionProfile(_capabilitiesService, null);
|
||||
// We want connection store to use any matching password it finds
|
||||
profile.savePassword = true;
|
||||
profile.providerName = Constants.mssqlProviderName;
|
||||
profile.serverName = _environmentService.args.server;
|
||||
profile.databaseName = _environmentService.args.database ? _environmentService.args.database : '';
|
||||
profile.userName = _environmentService.args.user ? _environmentService.args.user : '';
|
||||
profile.authenticationType = _environmentService.args.integrated ? 'Integrated' : 'SqlLogin';
|
||||
profile.connectionName = '';
|
||||
profile.setOptionValue('applicationName', Constants.applicationName);
|
||||
profile.setOptionValue('databaseDisplayName', profile.databaseName);
|
||||
profile.setOptionValue('groupId', profile.groupId);
|
||||
}
|
||||
if (ipc) {
|
||||
ipc.on('ads:processCommandLine', (event: any, args: ParsedArgs) => this.onLaunched(args));
|
||||
}
|
||||
this._connectionProfile = profile;
|
||||
// we only get the ipc from main during window reuse
|
||||
this.onLaunched(_environmentService.args);
|
||||
}
|
||||
|
||||
private onLaunched(args: ParsedArgs)
|
||||
{
|
||||
const registry = platform.Registry.as<IConnectionProviderRegistry>(ConnectionProviderExtensions.ConnectionProviderContributions);
|
||||
let sqlProvider = registry.getProperties(Constants.mssqlProviderName);
|
||||
// We can't connect to object explorer until the MSSQL connection provider is registered
|
||||
if (sqlProvider) {
|
||||
this.processCommandLine().catch(reason => { warn('processCommandLine failed: ' + reason); });
|
||||
this.processCommandLine(args).catch(reason => { warn('processCommandLine failed: ' + reason); });
|
||||
} else {
|
||||
registry.onNewProvider(e => {
|
||||
if (e.id === Constants.mssqlProviderName) {
|
||||
this.processCommandLine().catch(reason => { warn('processCommandLine failed: ' + reason); });
|
||||
this.processCommandLine(args).catch(reason => { warn('processCommandLine failed: ' + reason); });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public _serviceBrand: any;
|
||||
// We base our logic on the combination of (server, command) values.
|
||||
// (serverName, commandName) => Connect object explorer and execute the command, passing the connection profile to the command. Do not load query editor.
|
||||
// (null, commandName) => Launch the command with a null connection. If the command implementation needs a connection, it will need to create it.
|
||||
// (serverName, null) => Connect object explorer and open a new query editor
|
||||
// (null, null) => Prompt for a connection unless there are registered servers
|
||||
public processCommandLine(): Promise<void> {
|
||||
public processCommandLine(args: ParsedArgs): Promise<void> {
|
||||
let profile = undefined;
|
||||
let commandName = undefined;
|
||||
if (args) {
|
||||
if (this._commandService) {
|
||||
commandName = args.command;
|
||||
}
|
||||
|
||||
if (args.server) {
|
||||
profile = new ConnectionProfile(this._capabilitiesService, null);
|
||||
// We want connection store to use any matching password it finds
|
||||
profile.savePassword = true;
|
||||
profile.providerName = Constants.mssqlProviderName;
|
||||
profile.serverName = args.server;
|
||||
profile.databaseName = args.database ? args.database : '';
|
||||
profile.userName = args.user ? args.user : '';
|
||||
profile.authenticationType = args.integrated ? 'Integrated' : 'SqlLogin';
|
||||
profile.connectionName = '';
|
||||
profile.setOptionValue('applicationName', Constants.applicationName);
|
||||
profile.setOptionValue('databaseDisplayName', profile.databaseName);
|
||||
profile.setOptionValue('groupId', profile.groupId);
|
||||
}
|
||||
}
|
||||
let self = this;
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
let showConnectDialogOnStartup: boolean = this._configurationService.getValue('workbench.showConnectDialogOnStartup');
|
||||
if (showConnectDialogOnStartup && !self._commandName && !self._connectionProfile && !self._connectionManagementService.hasRegisteredServers()) {
|
||||
let showConnectDialogOnStartup: boolean = self._configurationService.getValue('workbench.showConnectDialogOnStartup');
|
||||
if (showConnectDialogOnStartup && !commandName && !profile && !self._connectionManagementService.hasRegisteredServers()) {
|
||||
// prompt the user for a new connection on startup if no profiles are registered
|
||||
self._connectionManagementService.showConnectionDialog()
|
||||
.then(() => {
|
||||
@@ -88,11 +96,11 @@ export class CommandLineService implements ICommandLineProcessing {
|
||||
error => {
|
||||
reject(error);
|
||||
});
|
||||
} else if (self._connectionProfile) {
|
||||
if (!self._commandName) {
|
||||
self._connectionManagementService.connectIfNotConnected(self._connectionProfile, 'connection', true)
|
||||
} else if (profile) {
|
||||
if (!commandName) {
|
||||
self._connectionManagementService.connectIfNotConnected(profile, 'connection', true)
|
||||
.then(() => {
|
||||
TaskUtilities.newQuery(self._connectionProfile,
|
||||
TaskUtilities.newQuery(profile,
|
||||
self._connectionManagementService,
|
||||
self._queryEditorService,
|
||||
self._objectExplorerService,
|
||||
@@ -109,15 +117,15 @@ export class CommandLineService implements ICommandLineProcessing {
|
||||
reject(error);
|
||||
});
|
||||
} else {
|
||||
self._connectionManagementService.connectIfNotConnected(self._connectionProfile, 'connection', true)
|
||||
self._connectionManagementService.connectIfNotConnected(profile, 'connection', true)
|
||||
.then(() => {
|
||||
self._commandService.executeCommand(self._commandName, self._connectionProfile.id).then(() => resolve(), error => reject(error));
|
||||
self._commandService.executeCommand(commandName, profile.id).then(() => resolve(), error => reject(error));
|
||||
}, error => {
|
||||
reject(error);
|
||||
});
|
||||
}
|
||||
} else if (self._commandName) {
|
||||
self._commandService.executeCommand(self._commandName).then(() => resolve(), error => reject(error));
|
||||
} else if (commandName) {
|
||||
self._commandService.executeCommand(commandName).then(() => resolve(), error => reject(error));
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/* Disabled pending next vscode merge which allows electron module to be imported during test runs
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -106,14 +107,13 @@ suite('commandLineService tests', () => {
|
||||
|
||||
function getCommandLineService(connectionManagementService: IConnectionManagementService,
|
||||
configurationService: IWorkspaceConfigurationService,
|
||||
environmentService?: IEnvironmentService,
|
||||
capabilitiesService?: ICapabilitiesService,
|
||||
commandService?: ICommandService
|
||||
): CommandLineService {
|
||||
let service = new CommandLineService(
|
||||
capabilitiesService,
|
||||
connectionManagementService,
|
||||
environmentService,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -142,7 +142,7 @@ suite('commandLineService tests', () => {
|
||||
.verifiable(TypeMoq.Times.never());
|
||||
const configurationService = getConfigurationServiceMock(true);
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object);
|
||||
service.processCommandLine().then(() => {
|
||||
service.processCommandLine(new TestParsedArgs()).then(() => {
|
||||
connectionManagementService.verifyAll();
|
||||
done();
|
||||
}, error => { assert.fail(error, null, 'processCommandLine rejected ' + error); done(); });
|
||||
@@ -159,7 +159,7 @@ suite('commandLineService tests', () => {
|
||||
const configurationService = getConfigurationServiceMock(false);
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object);
|
||||
|
||||
service.processCommandLine();
|
||||
service.processCommandLine(new TestParsedArgs());
|
||||
connectionManagementService.verifyAll();
|
||||
done();
|
||||
});
|
||||
@@ -175,7 +175,7 @@ suite('commandLineService tests', () => {
|
||||
.verifiable(TypeMoq.Times.never());
|
||||
const configurationService = getConfigurationServiceMock(true);
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object);
|
||||
service.processCommandLine().then(() => {
|
||||
service.processCommandLine(new TestParsedArgs()).then(() => {
|
||||
connectionManagementService.verifyAll();
|
||||
done();
|
||||
}, error => { assert.fail(error, null, 'processCommandLine rejected ' + error); done(); });
|
||||
@@ -185,20 +185,17 @@ suite('commandLineService tests', () => {
|
||||
const connectionManagementService: TypeMoq.Mock<IConnectionManagementService>
|
||||
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
|
||||
|
||||
const environmentService: TypeMoq.Mock<IEnvironmentService> = TypeMoq.Mock.ofType<IEnvironmentService>(EnvironmentService);
|
||||
const args: TestParsedArgs = new TestParsedArgs();
|
||||
args.server = 'myserver';
|
||||
args.database = 'mydatabase';
|
||||
environmentService.setup(e => e.args).returns(() => args).verifiable(TypeMoq.Times.atLeastOnce());
|
||||
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never());
|
||||
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true).verifiable(TypeMoq.Times.atMostOnce());
|
||||
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), 'connection', true))
|
||||
.returns(() => new Promise<string>((resolve, reject) => { resolve('unused'); }))
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
const configurationService = getConfigurationServiceMock(true);
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, environmentService.object, capabilitiesService);
|
||||
service.processCommandLine().then(() => {
|
||||
environmentService.verifyAll();
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, capabilitiesService);
|
||||
service.processCommandLine(args).then(() => {
|
||||
connectionManagementService.verifyAll();
|
||||
done();
|
||||
}, error => { assert.fail(error, null, 'processCommandLine rejected ' + error); done(); });
|
||||
@@ -207,12 +204,10 @@ suite('commandLineService tests', () => {
|
||||
test('processCommandLine invokes a command without a profile parameter when no server is passed', done => {
|
||||
const connectionManagementService: TypeMoq.Mock<IConnectionManagementService>
|
||||
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
|
||||
const environmentService: TypeMoq.Mock<IEnvironmentService> = TypeMoq.Mock.ofType<IEnvironmentService>(EnvironmentService);
|
||||
const commandService: TypeMoq.Mock<ICommandService> = TypeMoq.Mock.ofType<ICommandService>(TestCommandService);
|
||||
const args: TestParsedArgs = new TestParsedArgs();
|
||||
|
||||
args.command = 'mycommand';
|
||||
environmentService.setup(e => e.args).returns(() => args);
|
||||
connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never());
|
||||
connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true).verifiable(TypeMoq.Times.atMostOnce());
|
||||
connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
|
||||
@@ -221,8 +216,8 @@ suite('commandLineService tests', () => {
|
||||
.returns(() => TPromise.wrap(1))
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
const configurationService = getConfigurationServiceMock(true);
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, environmentService.object, capabilitiesService, commandService.object);
|
||||
service.processCommandLine().then(() => {
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, capabilitiesService, commandService.object);
|
||||
service.processCommandLine(args).then(() => {
|
||||
connectionManagementService.verifyAll();
|
||||
commandService.verifyAll();
|
||||
done();
|
||||
@@ -235,7 +230,6 @@ suite('commandLineService tests', () => {
|
||||
const connectionManagementService: TypeMoq.Mock<IConnectionManagementService>
|
||||
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
|
||||
|
||||
const environmentService: TypeMoq.Mock<IEnvironmentService> = TypeMoq.Mock.ofType<IEnvironmentService>(EnvironmentService);
|
||||
const commandService: TypeMoq.Mock<ICommandService> = TypeMoq.Mock.ofType<ICommandService>(TestCommandService);
|
||||
const args: TestParsedArgs = new TestParsedArgs();
|
||||
args.command = 'mycommand';
|
||||
@@ -250,8 +244,8 @@ suite('commandLineService tests', () => {
|
||||
.returns(() => TPromise.wrap(1))
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
const configurationService = getConfigurationServiceMock(true);
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, environmentService.object, capabilitiesService, commandService.object);
|
||||
service.processCommandLine().then(() => {
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, capabilitiesService, commandService.object);
|
||||
service.processCommandLine(args).then(() => {
|
||||
connectionManagementService.verifyAll();
|
||||
commandService.verifyAll();
|
||||
done();
|
||||
@@ -261,7 +255,6 @@ suite('commandLineService tests', () => {
|
||||
test('processCommandLine rejects unknown commands', done => {
|
||||
const connectionManagementService: TypeMoq.Mock<IConnectionManagementService>
|
||||
= TypeMoq.Mock.ofType<IConnectionManagementService>(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
|
||||
const environmentService: TypeMoq.Mock<IEnvironmentService> = TypeMoq.Mock.ofType<IEnvironmentService>(EnvironmentService);
|
||||
const commandService: TypeMoq.Mock<ICommandService> = TypeMoq.Mock.ofType<ICommandService>(TestCommandService);
|
||||
const args: TestParsedArgs = new TestParsedArgs();
|
||||
|
||||
@@ -272,8 +265,8 @@ suite('commandLineService tests', () => {
|
||||
.returns(() => TPromise.wrapError(new Error('myerror')))
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
const configurationService = getConfigurationServiceMock(true);
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, environmentService.object, capabilitiesService, commandService.object);
|
||||
service.processCommandLine().then(() => {
|
||||
let service = getCommandLineService(connectionManagementService.object, configurationService.object, capabilitiesService, commandService.object);
|
||||
service.processCommandLine(args).then(() => {
|
||||
assert.fail(1, null, 'processCommandLine should reject when executeCommand errors out');
|
||||
done();
|
||||
}, error => {
|
||||
@@ -282,3 +275,5 @@ suite('commandLineService tests', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
*/
|
||||
@@ -228,6 +228,15 @@ export class LaunchService implements ILaunchService {
|
||||
});
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
// give the first used window a chance to process the other command line arguments
|
||||
if (args['reuse-window'] && usedWindows.length > 0 && usedWindows[0])
|
||||
{
|
||||
let window = usedWindows[0];
|
||||
usedWindows[0].ready().then(() => window.send('ads:processCommandLine', args));
|
||||
}
|
||||
// {{SQL CARBON EDIT}}
|
||||
|
||||
// If the other instance is waiting to be killed, we hook up a window listener if one window
|
||||
// is being used and only then resolve the startup promise which will kill this second instance.
|
||||
// In addition, we poll for the wait marker file to be deleted to return.
|
||||
|
||||
Reference in New Issue
Block a user