Feature: Ability to add connection name (#2332)

This commit is contained in:
AlexFsmn
2018-09-04 20:05:09 +02:00
committed by Matt Irvine
parent 8600dbb04e
commit 3763278366
19 changed files with 161 additions and 6 deletions

View File

@@ -201,6 +201,20 @@
"providerId": "MSSQL",
"displayName": "Microsoft SQL Server",
"connectionOptions": [
{
"specialValueType": "connectionName",
"isIdentity": true,
"name": "connectionName",
"displayName": "Name (optional)",
"description": "Custom name of the connection",
"groupName": "Source",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": "serverName",
"isIdentity": true,

View File

@@ -145,6 +145,7 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
public toIConnectionProfile(): interfaces.IConnectionProfile {
let result: interfaces.IConnectionProfile = {
connectionName: this.connectionName,
serverName: this.serverName,
databaseName: this.databaseName,
authenticationType: this.authenticationType,

View File

@@ -45,6 +45,7 @@ export class ProviderConnectionInfo extends Disposable implements sqlops.Connect
this.databaseName = model.databaseName;
this.password = model.password;
this.userName = model.userName;
this.connectionName = model.connectionName;
}
}
}
@@ -78,6 +79,10 @@ export class ProviderConnectionInfo extends Disposable implements sqlops.Connect
return this._serverCapabilities;
}
public get connectionName(): string {
return this.getSpecialTypeOptionValue(ConnectionOptionSpecialType.connectionName);
}
public get serverName(): string {
return this.getSpecialTypeOptionValue(ConnectionOptionSpecialType.serverName);
}
@@ -98,6 +103,10 @@ export class ProviderConnectionInfo extends Disposable implements sqlops.Connect
return this.getSpecialTypeOptionValue(ConnectionOptionSpecialType.authType);
}
public set connectionName(value: string) {
this.setSpecialTypeOptionName(ConnectionOptionSpecialType.connectionName, value);
}
public set serverName(value: string) {
this.setSpecialTypeOptionName(ConnectionOptionSpecialType.serverName, value);
}
@@ -127,16 +136,30 @@ export class ProviderConnectionInfo extends Disposable implements sqlops.Connect
this.options[name] = value;
}
private getServerInfo() {
let databaseName = this.databaseName ? this.databaseName : '<default>';
let userName = this.userName ? this.userName : 'Windows Authentication';
return this.serverName + ', ' + databaseName + ' (' + userName + ')';
}
/**
* Returns the title of the connection
*/
public get title(): string {
let databaseName = this.databaseName ? this.databaseName : '<default>';
let userName = this.userName ? this.userName : 'Windows Authentication';
let label = this.serverName + ', ' + databaseName + ' (' + userName + ')';
let label = '';
if (this.connectionName) {
label = this.connectionName;
} else {
label = this.getServerInfo();
}
return label;
}
public get serverInfo(): string {
return this.getServerInfo();
}
/**
* Returns true if the capabilities and options are loaded correctly
*/
@@ -171,7 +194,9 @@ export class ProviderConnectionInfo extends Disposable implements sqlops.Connect
let idNames = [];
if (this._serverCapabilities) {
idNames = this._serverCapabilities.connectionOptions.map(o => {
if ((o.specialValueType || o.isIdentity) && o.specialValueType !== ConnectionOptionSpecialType.password) {
if ((o.specialValueType || o.isIdentity)
&& o.specialValueType !== ConnectionOptionSpecialType.password
&& o.specialValueType !== ConnectionOptionSpecialType.connectionName) {
return o.name;
} else {
return undefined;
@@ -267,6 +292,7 @@ export class ProviderConnectionInfo extends Disposable implements sqlops.Connect
element.specialValueType !== ConnectionOptionSpecialType.databaseName &&
element.specialValueType !== ConnectionOptionSpecialType.authType &&
element.specialValueType !== ConnectionOptionSpecialType.password &&
element.specialValueType !== ConnectionOptionSpecialType.connectionName &&
element.isIdentity && element.valueType === ServiceOptionType.string) {
let value = this.getOptionValue(element.name);
if (value) {

View File

@@ -43,6 +43,7 @@ export class ConnectionWidget {
private _serverGroupSelectBox: SelectBox;
private _previousGroupOption: string;
private _serverGroupOptions: IConnectionProfileGroup[];
private _connectionNameInputBox: InputBox;
private _serverNameInputBox: InputBox;
private _databaseNameInputBox: Dropdown;
private _userNameInputBox: InputBox;
@@ -154,6 +155,12 @@ export class ConnectionWidget {
}
private fillInConnectionForm(): void {
// Connection name
let connectionNameOption = this._optionsMaps[ConnectionOptionSpecialType.connectionName];
let connectionNameBuilder = DialogHelper.appendRow(this._tableContainer, connectionNameOption.displayName, 'connection-label', 'connection-input');
this._connectionNameInputBox = new InputBox(connectionNameBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: connectionNameOption.displayName });
// Server name
let serverNameOption = this._optionsMaps[ConnectionOptionSpecialType.serverName];
let serverNameBuilder = DialogHelper.appendRow(this._tableContainer, serverNameOption.displayName, 'connection-label', 'connection-input');
this._serverNameInputBox = new InputBox(serverNameBuilder.getHTMLElement(), this._contextViewService, {
@@ -170,11 +177,13 @@ export class ConnectionWidget {
ariaLabel: serverNameOption.displayName
});
// Authentication type
if (this._optionsMaps[ConnectionOptionSpecialType.authType]) {
let authTypeBuilder = DialogHelper.appendRow(this._tableContainer, this._optionsMaps[ConnectionOptionSpecialType.authType].displayName, 'connection-label', 'connection-input');
DialogHelper.appendInputSelectBox(authTypeBuilder, this._authTypeSelectBox);
}
// Username
let self = this;
let userNameOption = this._optionsMaps[ConnectionOptionSpecialType.userName];
let userNameBuilder = DialogHelper.appendRow(this._tableContainer, userNameOption.displayName, 'connection-label', 'connection-input');
@@ -185,15 +194,18 @@ export class ConnectionWidget {
ariaLabel: userNameOption.displayName
});
// Password
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
this._passwordInputBox = new InputBox(passwordBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: passwordOption.displayName });
this._passwordInputBox.inputElement.type = 'password';
this._password = '';
// Remember password
let rememberPasswordLabel = localize('rememberPassword', 'Remember password');
this._rememberPasswordCheckBox = this.appendCheckbox(this._tableContainer, rememberPasswordLabel, 'connection-checkbox', 'connection-input', false);
// Database
let databaseOption = this._optionsMaps[ConnectionOptionSpecialType.databaseName];
let databaseNameBuilder = DialogHelper.appendRow(this._tableContainer, databaseOption.displayName, 'connection-label', 'connection-input');
@@ -206,6 +218,7 @@ export class ConnectionWidget {
actionLabel: localize('connectionWidget.toggleDatabaseNameDropdown', 'Select Database Toggle Dropdown')
});
// Server group
let serverGroupLabel = localize('serverGroup', 'Server group');
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, serverGroupLabel, 'connection-label', 'connection-input');
DialogHelper.appendInputSelectBox(serverGroupBuilder, this._serverGroupSelectBox);
@@ -257,6 +270,7 @@ export class ConnectionWidget {
// Theme styler
this._toDispose.push(attachInputBoxStyler(this._serverNameInputBox, this._themeService));
this._toDispose.push(attachEditableDropdownStyler(this._databaseNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._connectionNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._userNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._passwordInputBox, this._themeService));
this._toDispose.push(styler.attachSelectBoxStyler(this._serverGroupSelectBox, this._themeService));
@@ -385,7 +399,7 @@ export class ConnectionWidget {
public focusOnOpen(): void {
this._handleClipboard();
this._serverNameInputBox.focus();
this._connectionNameInputBox.focus();
this.focusPasswordIfNeeded();
this.clearValidationMessages();
}
@@ -403,6 +417,7 @@ export class ConnectionWidget {
if (connectionInfo) {
this._serverNameInputBox.value = this.getModelValue(connectionInfo.serverName);
this._databaseNameInputBox.value = this.getModelValue(connectionInfo.databaseName);
this._connectionNameInputBox.value = this.getModelValue(connectionInfo.connectionName);
this._userNameInputBox.value = this.getModelValue(connectionInfo.userName);
this._passwordInputBox.value = connectionInfo.password ? Constants.passwordChars : '';
this._password = this.getModelValue(connectionInfo.password);
@@ -507,6 +522,10 @@ export class ConnectionWidget {
}
}
public get connectionName(): string {
return this._connectionNameInputBox.value;
}
public get serverName(): string {
return this._serverNameInputBox.value;
}
@@ -550,6 +569,7 @@ export class ConnectionWidget {
public connect(model: IConnectionProfile): boolean {
let validInputs = this.validateInputs();
if (validInputs) {
model.connectionName = this.connectionName;
model.serverName = this.serverName;
model.databaseName = this.databaseName;
model.userName = this.userName;

View File

@@ -144,6 +144,7 @@ export class AddServerAction extends Action {
public run(element: ConnectionProfileGroup): TPromise<boolean> {
let connection: IConnectionProfile = element === undefined ? undefined : {
connectionName: undefined,
serverName: undefined,
databaseName: undefined,
userName: undefined,

View File

@@ -160,7 +160,7 @@ export class ServerTreeRenderer implements IRenderer {
}
templateData.label.textContent = label;
templateData.root.title = label;
templateData.root.title = connection.serverInfo;
templateData.connectionProfile = connection;
}

2
src/sql/sqlops.d.ts vendored
View File

@@ -195,6 +195,7 @@ declare module 'sqlops' {
}
export interface IConnectionProfile extends ConnectionInfo {
connectionName: string;
serverName: string;
databaseName: string;
userName: string;
@@ -349,6 +350,7 @@ declare module 'sqlops' {
}
export enum ConnectionOptionSpecialType {
connectionName = 'connectionName',
serverName = 'serverName',
databaseName = 'databaseName',
authType = 'authType',

View File

@@ -18,6 +18,7 @@ export enum ServiceOptionType {
}
export enum ConnectionOptionSpecialType {
connectionName = 'connectionName',
serverName = 'serverName',
databaseName = 'databaseName',
authType = 'authType',

View File

@@ -18,6 +18,7 @@ suite('SQL Telemetry Utilities tests', () => {
let telemetryKey: string = 'tel key';
let connectionProfile = {
connectionName: '',
databaseName: '',
serverName: '',
authenticationType: '',

View File

@@ -77,6 +77,7 @@ suite('Firewall rule dialog controller tests', () => {
.returns(() => mockFirewallRuleDialog.object);
connectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',

View File

@@ -50,6 +50,7 @@ suite('SQL ConnectionManagementService tests', () => {
let none: void;
let connectionProfile: IConnectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',

View File

@@ -19,6 +19,7 @@ suite('SQL ConnectionProfileInfo tests', () => {
let capabilitiesService: CapabilitiesTestService;
let connectionProfile: IConnectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',
@@ -39,6 +40,7 @@ suite('SQL ConnectionProfileInfo tests', () => {
groupId: 'groupId',
id: 'id',
options: {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',
@@ -51,6 +53,18 @@ suite('SQL ConnectionProfileInfo tests', () => {
setup(() => {
let connectionProvider: sqlops.ConnectionOption[] = [
{
name: 'connectionName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: ConnectionOptionSpecialType.connectionName,
valueType: ServiceOptionType.string
},
{
name: 'serverName',
displayName: undefined,
@@ -124,6 +138,7 @@ suite('SQL ConnectionProfileInfo tests', () => {
test('set properties should set the values correctly', () => {
let conn = new ConnectionProfile(capabilitiesService, undefined);
assert.equal(conn.serverName, undefined);
conn.connectionName = connectionProfile.connectionName;
conn.serverName = connectionProfile.serverName;
conn.databaseName = connectionProfile.databaseName;
conn.authenticationType = connectionProfile.authenticationType;
@@ -132,6 +147,7 @@ suite('SQL ConnectionProfileInfo tests', () => {
conn.groupId = connectionProfile.groupId;
conn.groupFullName = connectionProfile.groupFullName;
conn.savePassword = connectionProfile.savePassword;
assert.equal(conn.connectionName, connectionProfile.connectionName);
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);
@@ -145,6 +161,7 @@ suite('SQL ConnectionProfileInfo tests', () => {
test('constructor should initialize the options given a valid model', () => {
let conn = new ConnectionProfile(capabilitiesService, connectionProfile);
assert.equal(conn.connectionName, connectionProfile.connectionName);
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);

View File

@@ -17,6 +17,7 @@ let connections: ConnectionStatusManager;
let capabilitiesService: CapabilitiesTestService;
let connectionProfileObject: ConnectionProfile;
let connectionProfile: IConnectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',
@@ -33,6 +34,7 @@ let connectionProfile: IConnectionProfile = {
id: undefined
};
let editorConnectionProfile: IConnectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',
@@ -49,6 +51,7 @@ let editorConnectionProfile: IConnectionProfile = {
id: undefined
};
let connectionProfileWithoutDbName: IConnectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: '',
userName: 'user',

View File

@@ -41,6 +41,7 @@ suite('SQL ConnectionStore tests', () => {
setup(() => {
defaultNamedProfile = Object.assign({}, {
connectionName: 'new name',
serverName: 'namedServer',
databaseName: 'bcd',
authenticationType: 'SqlLogin',
@@ -58,6 +59,7 @@ suite('SQL ConnectionStore tests', () => {
});
defaultUnnamedProfile = Object.assign({}, {
connectionName: 'new name',
serverName: 'unnamedServer',
databaseName: undefined,
authenticationType: 'SqlLogin',
@@ -75,6 +77,7 @@ suite('SQL ConnectionStore tests', () => {
});
profileForProvider2 = Object.assign({}, {
connectionName: 'new name',
serverName: 'unnamedServer',
databaseName: undefined,
authenticationType: 'SqlLogin',
@@ -117,6 +120,18 @@ suite('SQL ConnectionStore tests', () => {
capabilitiesService = new CapabilitiesTestService();
let connectionProvider: sqlops.ConnectionOption[] = [
{
name: 'connectionName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: ConnectionOptionSpecialType.connectionName,
valueType: ServiceOptionType.string
},
{
name: 'serverName',
displayName: undefined,

View File

@@ -85,6 +85,7 @@ suite('SQL Connection Tree Action tests', () => {
test('ManageConnectionAction - test if connect is called for manage action if not already connected', (done) => {
let isConnectedReturnValue: boolean = false;
let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
connectionName: 'Test',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
@@ -122,6 +123,7 @@ suite('SQL Connection Tree Action tests', () => {
test('ManageConnectionAction - test if connect is called for manage action on database node if not already connected', (done) => {
let isConnectedReturnValue: boolean = false;
let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
connectionName: 'Test',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
@@ -162,6 +164,7 @@ suite('SQL Connection Tree Action tests', () => {
test('DisconnectConnectionAction - test if disconnect is called when profile is connected', (done) => {
let isConnectedReturnValue: boolean = true;
let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
connectionName: 'Test',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
@@ -274,6 +277,7 @@ suite('SQL Connection Tree Action tests', () => {
let connectionManagementService = createConnectionManagementService(true, undefined);
let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
connectionName: 'Test',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
@@ -320,6 +324,7 @@ suite('SQL Connection Tree Action tests', () => {
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue, undefined);
let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
connectionName: 'Test',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
@@ -356,6 +361,7 @@ suite('SQL Connection Tree Action tests', () => {
capabilitiesService.capabilities['MSSQL'] = { connection: sqlProvider };
var connection = new ConnectionProfile(capabilitiesService, {
connectionName: 'Test',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
@@ -444,6 +450,7 @@ suite('SQL Connection Tree Action tests', () => {
capabilitiesService.capabilities['MSSQL'] = { connection: sqlProvider };
var connection = new ConnectionProfile(capabilitiesService, {
connectionName: 'Test',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',

View File

@@ -131,6 +131,18 @@ suite('SQL Object Explorer Service tests', () => {
providerId: 'MSSQL',
displayName: 'MSSQL',
connectionOptions: [
{
name: 'connectionName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: ConnectionOptionSpecialType.connectionName,
valueType: ServiceOptionType.string
},
{
name: 'serverName',
displayName: undefined,
@@ -210,6 +222,7 @@ suite('SQL Object Explorer Service tests', () => {
capabilitiesService.capabilities['MSSQL'] = { connection: sqlProvider };
connection = new ConnectionProfile(capabilitiesService, {
connectionName: 'newName',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
@@ -228,6 +241,7 @@ suite('SQL Object Explorer Service tests', () => {
conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
connectionToFail = new ConnectionProfile(capabilitiesService, {
connectionName: 'newName2',
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName2',

View File

@@ -19,6 +19,7 @@ suite('SQL ProviderConnectionInfo tests', () => {
let capabilitiesService: CapabilitiesTestService;
let connectionProfile: IConnectionProfile = {
connectionName: 'name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',
@@ -38,6 +39,18 @@ suite('SQL ProviderConnectionInfo tests', () => {
setup(() => {
let capabilities: sqlops.DataProtocolServerCapabilities[] = [];
let connectionProvider: sqlops.ConnectionOption[] = [
{
name: 'connectionName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: ConnectionOptionSpecialType.connectionName,
valueType: ServiceOptionType.string
},
{
name: 'serverName',
displayName: undefined,
@@ -129,11 +142,13 @@ suite('SQL ProviderConnectionInfo tests', () => {
test('set properties should set the values correctly', () => {
let conn = new ProviderConnectionInfo(capabilitiesService, 'MSSQL');
assert.equal(conn.serverName, undefined);
conn.connectionName = connectionProfile.connectionName;
conn.serverName = connectionProfile.serverName;
conn.databaseName = connectionProfile.databaseName;
conn.authenticationType = connectionProfile.authenticationType;
conn.password = connectionProfile.password;
conn.userName = connectionProfile.userName;
assert.equal(conn.connectionName, connectionProfile.connectionName);
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);
@@ -159,6 +174,7 @@ suite('SQL ProviderConnectionInfo tests', () => {
test('constructor should initialize the options given a valid model', () => {
let conn = new ProviderConnectionInfo(capabilitiesService, connectionProfile);
assert.equal(conn.connectionName, connectionProfile.connectionName);
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);
@@ -170,6 +186,7 @@ suite('SQL ProviderConnectionInfo tests', () => {
let conn = new ProviderConnectionInfo(capabilitiesService, connectionProfile);
let conn2 = conn.clone();
assert.equal(conn.connectionName, conn2.connectionName);
assert.equal(conn.serverName, conn2.serverName);
assert.equal(conn.databaseName, conn2.databaseName);
assert.equal(conn.authenticationType, conn2.authenticationType);
@@ -191,6 +208,7 @@ suite('SQL ProviderConnectionInfo tests', () => {
let conn2 = Object.assign({}, connectionProfile, { options: options });
let conn = new ProviderConnectionInfo(capabilitiesService, conn2);
assert.equal(conn.connectionName, conn2.connectionName);
assert.equal(conn.serverName, conn2.serverName);
assert.equal(conn.databaseName, conn2.databaseName);
assert.equal(conn.authenticationType, conn2.authenticationType);

View File

@@ -52,6 +52,7 @@ suite('Insights Dialog Controller Tests', () => {
);
let profile: IConnectionProfile = {
connectionName: 'newname',
serverName: 'server',
databaseName: 'database',
userName: 'user',

View File

@@ -23,6 +23,18 @@ export class CapabilitiesTestService implements ICapabilitiesService {
constructor() {
let connectionProvider: sqlops.ConnectionOption[] = [
{
name: 'connectionName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: ConnectionOptionSpecialType.connectionName,
valueType: ServiceOptionType.string
},
{
name: 'serverName',
displayName: undefined,