mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-28 17:23:19 -05:00
Connection URI with complete options (finalized) (#22735)
* Connection URI made to include every option available instead of basic details (#22045) * Revert "Merge remote-tracking branch 'origin' into feat/connectionUri" This reverts commit 11b2d31bf99e216daee823f732254f69a017fee1, reversing changes made to 36e4db8c0744f81565efdfd2f56a3ae3c0026896. * Revert "Revert "Merge remote-tracking branch 'origin' into feat/connectionUri"" This reverts commit f439673c2693e1144c52e04c14e82cd8566c13a6. * Added changes and fixes for feat connectionuri (#22706) * add title generation at start * added await to refreshConnectionTreeTitles
This commit is contained in:
@@ -70,6 +70,51 @@ export class ConnectionConfig {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to make sure that the profile that is being edited is not identical to another profile.
|
||||
*/
|
||||
public isDuplicateEdit(profile: IConnectionProfile, matcher: ProfileMatcher = ConnectionProfile.matchesProfile): Promise<boolean> {
|
||||
let profiles = deepClone(this.configurationService.inspect<IConnectionProfileStore[]>(CONNECTIONS_CONFIG_KEY).userValue as IConnectionProfileStore[]);
|
||||
if (!profiles) {
|
||||
profiles = [];
|
||||
}
|
||||
|
||||
return this.addGroupFromProfile(profile).then(groupId => {
|
||||
let connectionProfile = this.getConnectionProfileInstance(profile, groupId);
|
||||
// Profile to be stored during an edit, used to check for duplicate profile edits.
|
||||
let firstMatchProfile = undefined;
|
||||
|
||||
profiles.find(value => {
|
||||
const providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, this._capabilitiesService);
|
||||
const match = matcher(providerConnectionProfile, connectionProfile);
|
||||
// If we have a profile match, and the matcher is an edit, we must store this match.
|
||||
if (match && (matcher.toString() !== ConnectionProfile.matchesProfile.toString())) {
|
||||
firstMatchProfile = value;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
|
||||
// If a profile edit, we must now check to see it does not match the other profiles available.
|
||||
if (firstMatchProfile) {
|
||||
// Copy over profile list so that we can remove the actual profile we want to edit.
|
||||
const index = profiles.indexOf(firstMatchProfile);
|
||||
if (index > -1) {
|
||||
profiles.splice(index, 1);
|
||||
}
|
||||
|
||||
// Use the regular profile matching here to find if edit is duplicate.
|
||||
let matchesExistingProfile = profiles.find(value => {
|
||||
const providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, this._capabilitiesService);
|
||||
const match = ConnectionProfile.matchesProfile(providerConnectionProfile, connectionProfile);
|
||||
return match;
|
||||
});
|
||||
|
||||
return Promise.resolve(matchesExistingProfile !== undefined);
|
||||
}
|
||||
return Promise.resolve(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new connection to the connection config.
|
||||
*/
|
||||
@@ -317,10 +362,18 @@ export class ConnectionConfig {
|
||||
p.options.database === profile.options.database &&
|
||||
p.options.server === profile.options.server &&
|
||||
p.options.user === profile.options.user &&
|
||||
p.groupId === newGroupID);
|
||||
p.options.connectionName === profile.options.connectionName &&
|
||||
p.groupId === newGroupID &&
|
||||
this.checkIfNonDefaultOptionsMatch(p, profile));
|
||||
return existingProfile === undefined;
|
||||
}
|
||||
|
||||
private checkIfNonDefaultOptionsMatch(profileStore: IConnectionProfileStore, profile: ConnectionProfile): boolean {
|
||||
let tempProfile = ConnectionProfile.createFromStoredProfile(profileStore, this._capabilitiesService);
|
||||
let result = profile.getNonDefaultOptionsString() === tempProfile.getNonDefaultOptionsString();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the connection under the target group with the new ID.
|
||||
*/
|
||||
|
||||
@@ -378,6 +378,14 @@ export interface IConnectionManagementService {
|
||||
* @returns the new valid password that is entered, or undefined if cancelled or errored.
|
||||
*/
|
||||
openChangePasswordDialog(profile: IConnectionProfile): Promise<string | undefined>;
|
||||
|
||||
/**
|
||||
* Gets the formatted title of the connection profile for display.
|
||||
* @param profile The connection profile to change the password.
|
||||
* @param getNonDefaultsOnly Provide if you only want to get the non default options string (for some titles).
|
||||
* @returns the new valid password that is entered, or undefined if cancelled or errored.
|
||||
*/
|
||||
getEditorConnectionProfileTitle(profile: IConnectionProfile, getNonDefaultsOnly?: boolean): string;
|
||||
}
|
||||
|
||||
export enum RunQueryOnConnectionMode {
|
||||
|
||||
@@ -38,6 +38,9 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
|
||||
public isDisconnecting: boolean = false;
|
||||
|
||||
// title from ProviderConnectionInfo cannot be changed, in order to show different dynamic options appended, we must override the title with our own.
|
||||
private _title?: string;
|
||||
|
||||
public constructor(
|
||||
capabilitiesService: ICapabilitiesService,
|
||||
model: string | azdata.IConnectionProfile | azdata.connection.ConnectionProfile | undefined) {
|
||||
@@ -191,6 +194,33 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
return (this._groupName === ConnectionProfile.RootGroupName);
|
||||
}
|
||||
|
||||
public override get title(): string {
|
||||
if (this._title) {
|
||||
return this._title;
|
||||
}
|
||||
return this.getOriginalTitle();
|
||||
}
|
||||
|
||||
public getOriginalTitle(): string {
|
||||
return super.title;
|
||||
}
|
||||
|
||||
public getEditorFullTitleWithOptions(): string {
|
||||
let textResult = '';
|
||||
if (this.connectionName) {
|
||||
textResult += `${this.connectionName}: `;
|
||||
}
|
||||
textResult += this.serverInfo;
|
||||
if (textResult.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return textResult;
|
||||
}
|
||||
|
||||
public override set title(value: string) {
|
||||
this._title = value;
|
||||
}
|
||||
|
||||
public override clone(): ConnectionProfile {
|
||||
let instance = new ConnectionProfile(this.capabilitiesService, this);
|
||||
return instance;
|
||||
@@ -219,24 +249,33 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
|
||||
/**
|
||||
* Returns a key derived the connections options (providerName, authenticationType, serverName, databaseName, userName, groupid)
|
||||
* and all the other properties if useFullOptions is enabled for the provider.
|
||||
* This key uniquely identifies a connection in a group
|
||||
* Example: "providerName:MSSQL|authenticationType:|databaseName:database|serverName:server3|userName:user|group:testid"
|
||||
* @param getOriginalOptions will return the original URI format regardless if useFullOptions was set or not. (used for retrieving passwords)
|
||||
*/
|
||||
public override getOptionsKey(): string {
|
||||
let id = super.getOptionsKey();
|
||||
public override getOptionsKey(getOriginalOptions?: boolean): string {
|
||||
let id = super.getOptionsKey(getOriginalOptions);
|
||||
let databaseDisplayName: string = this.options['databaseDisplayName'];
|
||||
if (databaseDisplayName) {
|
||||
id += ProviderConnectionInfo.idSeparator + 'databaseDisplayName' + ProviderConnectionInfo.nameValueSeparator + databaseDisplayName;
|
||||
}
|
||||
|
||||
return id + ProviderConnectionInfo.idSeparator + 'group' + ProviderConnectionInfo.nameValueSeparator + this.groupId;
|
||||
return id + ProviderConnectionInfo.idSeparator + 'groupId' + ProviderConnectionInfo.nameValueSeparator + this.groupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique id for the connection that doesn't include the group name
|
||||
* Returns the unique id for the connection that doesn't include the group name.
|
||||
* Used primarily for retrieving shared passwords among different connections in default state.
|
||||
* @param getOriginalOptions will return the original URI format regardless if useFullOptions was set or not. (used for retrieving passwords)
|
||||
*/
|
||||
public getConnectionInfoId(): string {
|
||||
return super.getOptionsKey();
|
||||
public getConnectionInfoId(getOriginalOptions = true): string {
|
||||
let id = super.getOptionsKey(getOriginalOptions);
|
||||
let databaseDisplayName: string = this.options['databaseDisplayName'];
|
||||
if (databaseDisplayName && !getOriginalOptions && this.serverCapabilities?.useFullOptions) {
|
||||
id += ProviderConnectionInfo.idSeparator + 'databaseDisplayName' + ProviderConnectionInfo.nameValueSeparator + databaseDisplayName;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public toIConnectionProfile(): interfaces.IConnectionProfile {
|
||||
|
||||
@@ -67,6 +67,7 @@ export class ConnectionStore {
|
||||
}
|
||||
|
||||
cred.push(CRED_ITEMTYPE_PREFIX.concat(itemType));
|
||||
// Use basic info for credentials so that passwords can be shared among similar profiles for now.
|
||||
cred.push(CRED_ID_PREFIX.concat(connectionProfileInstance.getConnectionInfoId()));
|
||||
return cred.join(CRED_SEPARATOR);
|
||||
}
|
||||
@@ -149,6 +150,17 @@ export class ConnectionStore {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a connection profile edit is not identical to an existing saved profile.
|
||||
*
|
||||
* @param profile the profile group that is being edited.
|
||||
* @param matcher the profile matching function for the actual connection we want to edit.
|
||||
* @returns a boolean value indicating if there's an identical profile to the edit.
|
||||
*/
|
||||
public isDuplicateEdit(profile: IConnectionProfile, matcher?: ProfileMatcher): Promise<boolean> {
|
||||
return this.connectionConfig.isDuplicateEdit(profile, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of recently used connections. These will not include the password - a separate call to
|
||||
* {addSavedPassword} is needed to fill that before connecting
|
||||
@@ -217,7 +229,7 @@ export class ConnectionStore {
|
||||
|
||||
// Remove the connection from the list if it already exists
|
||||
list = list.filter(value => {
|
||||
let equal = value && value.getConnectionInfoId() === savedProfile.getConnectionInfoId();
|
||||
let equal = value && value.getConnectionInfoId(false) === savedProfile.getConnectionInfoId(false);
|
||||
if (equal && savedProfile.saveProfile) {
|
||||
equal = value.groupId === savedProfile.groupId ||
|
||||
ConnectionProfileGroup.sameGroupName(value.groupFullName, savedProfile.groupFullName);
|
||||
@@ -235,7 +247,7 @@ export class ConnectionStore {
|
||||
|
||||
// Remove the connection from the list if it already exists
|
||||
list = list.filter(value => {
|
||||
let equal = value && value.getConnectionInfoId() === savedProfile.getConnectionInfoId();
|
||||
let equal = value && value.getConnectionInfoId(false) === savedProfile.getConnectionInfoId(false);
|
||||
if (equal && savedProfile.saveProfile) {
|
||||
equal = value.groupId === savedProfile.groupId ||
|
||||
ConnectionProfileGroup.sameGroupName(value.groupFullName, savedProfile.groupFullName);
|
||||
@@ -270,6 +282,8 @@ export class ConnectionStore {
|
||||
|
||||
private doSavePassword(conn: IConnectionProfile): Promise<boolean> {
|
||||
if (conn.password) {
|
||||
// Credentials are currently shared between profiles with the same basic details.
|
||||
// Credentials are currently not cleared upon deletion of a profile.
|
||||
const credentialId = this.formatCredentialId(conn);
|
||||
return this.credentialService.saveCredential(credentialId, conn.password);
|
||||
} else {
|
||||
|
||||
@@ -9,7 +9,7 @@ import * as azdata from 'azdata';
|
||||
export type ProfileMatcher = (a: IConnectionProfile, b: IConnectionProfile) => boolean;
|
||||
|
||||
export interface IConnectionProfile extends azdata.IConnectionProfile {
|
||||
getOptionsKey(): string;
|
||||
getOptionsKey(getOriginalOptions?: boolean): string;
|
||||
matches(profile: azdata.IConnectionProfile): boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { isString } from 'vs/base/common/types';
|
||||
import * as azdata from 'azdata';
|
||||
import * as Constants from 'sql/platform/connection/common/constants';
|
||||
import { ICapabilitiesService, ConnectionProviderProperties } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { ConnectionOptionSpecialType, ServiceOptionType } from 'sql/platform/connection/common/interfaces';
|
||||
import { ConnectionOptionSpecialType } from 'sql/platform/connection/common/interfaces';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
type SettableProperty = 'serverName' | 'authenticationType' | 'databaseName' | 'password' | 'connectionName' | 'userName';
|
||||
@@ -29,7 +29,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
this.providerName = isString(model) ? model : 'providerName' in model ? model.providerName : model.providerId;
|
||||
|
||||
if (!isString(model)) {
|
||||
if (model.options && this.serverCapabilities) {
|
||||
if (model.options && this.hasServerCapabilities()) {
|
||||
this.serverCapabilities.connectionOptions.forEach(option => {
|
||||
let value = model.options[option.name];
|
||||
this.options[option.name] = value;
|
||||
@@ -136,7 +136,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
|
||||
private getServerInfo() {
|
||||
let title = '';
|
||||
if (this.serverCapabilities) {
|
||||
if (this.hasServerCapabilities()) {
|
||||
title = this.serverName;
|
||||
// Only show database name if the provider supports it.
|
||||
if (this.serverCapabilities.connectionOptions?.find(option => option.specialValueType === ConnectionOptionSpecialType.databaseName)) {
|
||||
@@ -153,7 +153,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
public get title(): string {
|
||||
let label = '';
|
||||
|
||||
if (this.serverCapabilities) {
|
||||
if (this.hasServerCapabilities()) {
|
||||
if (this.connectionName) {
|
||||
label = this.connectionName;
|
||||
} else {
|
||||
@@ -161,7 +161,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
}
|
||||
}
|
||||
// The provider capabilities are registered at the same time at load time, we can assume all providers are registered as long as the collection is not empty.
|
||||
else if (Object.keys(this.capabilitiesService.providers).length > 0) {
|
||||
else if (this.hasLoaded()) {
|
||||
return localize('connection.unsupported', "Unsupported connection");
|
||||
} else {
|
||||
return localize('loading', "Loading...");
|
||||
@@ -169,13 +169,25 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
return label;
|
||||
}
|
||||
|
||||
public hasServerCapabilities(): boolean {
|
||||
return (this.serverCapabilities !== undefined);
|
||||
}
|
||||
|
||||
public hasLoaded(): boolean {
|
||||
return Object.keys(this.capabilitiesService.providers).length > 0;
|
||||
}
|
||||
|
||||
public get serverInfo(): string {
|
||||
return this.getServerInfo();
|
||||
let value = this.getServerInfo();
|
||||
if (this.serverCapabilities?.useFullOptions) {
|
||||
value += this.getNonDefaultOptionsString();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public isPasswordRequired(): boolean {
|
||||
// if there is no provider capabilities metadata assume a password is not required
|
||||
if (!this.serverCapabilities) {
|
||||
if (!this.hasServerCapabilities()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -198,16 +210,23 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
|
||||
/**
|
||||
* Returns a key derived the connections options (providerName, authenticationType, serverName, databaseName, userName, groupid)
|
||||
* and all the other properties if useFullOptions is enabled for the provider.
|
||||
* This key uniquely identifies a connection in a group
|
||||
* Example: "providerName:MSSQL|authenticationType:|databaseName:database|serverName:server3|userName:user|group:testid"
|
||||
* @param getOriginalOptions will return the original URI format regardless if useFullOptions was set or not. (used for retrieving passwords)
|
||||
*/
|
||||
public getOptionsKey(): string {
|
||||
public getOptionsKey(getOriginalOptions?: boolean): string {
|
||||
let useFullOptions = false;
|
||||
let idNames = [];
|
||||
if (this.serverCapabilities) {
|
||||
if (this.hasServerCapabilities()) {
|
||||
useFullOptions = this.serverCapabilities.useFullOptions;
|
||||
idNames = this.serverCapabilities.connectionOptions.map(o => {
|
||||
if ((o.specialValueType || o.isIdentity)
|
||||
&& o.specialValueType !== ConnectionOptionSpecialType.password
|
||||
&& o.specialValueType !== ConnectionOptionSpecialType.connectionName) {
|
||||
// All options enabled, use every property besides password.
|
||||
let newProperty = useFullOptions && o.specialValueType !== ConnectionOptionSpecialType.password && !getOriginalOptions;
|
||||
// Fallback to original base IsIdentity properties otherwise.
|
||||
let originalProperty = (o.specialValueType || o.isIdentity) && o.specialValueType !== ConnectionOptionSpecialType.password
|
||||
&& o.specialValueType !== ConnectionOptionSpecialType.connectionName;
|
||||
if (newProperty || originalProperty) {
|
||||
return o.name;
|
||||
} else {
|
||||
return undefined;
|
||||
@@ -226,14 +245,45 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
let idValues: string[] = [];
|
||||
for (let index = 0; index < idNames.length; index++) {
|
||||
let value = this.options[idNames[index]!];
|
||||
value = value ? value : '';
|
||||
idValues.push(`${idNames[index]}${ProviderConnectionInfo.nameValueSeparator}${value}`);
|
||||
// If we're using the new URI format, we do not include any values that are empty or are default.
|
||||
let isFullOptions = useFullOptions && !getOriginalOptions;
|
||||
if (isFullOptions) {
|
||||
let finalValue = undefined;
|
||||
let options = this.serverCapabilities.connectionOptions.filter(value => value.name === idNames[index]!);
|
||||
if (options.length > 0 && value) {
|
||||
finalValue = value !== options[0].defaultValue ? value : undefined;
|
||||
}
|
||||
value = finalValue;
|
||||
}
|
||||
else {
|
||||
value = value ? value : '';
|
||||
}
|
||||
if ((isFullOptions && value !== undefined) || !isFullOptions) {
|
||||
idValues.push(`${idNames[index]}${ProviderConnectionInfo.nameValueSeparator}${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
return ProviderConnectionInfo.ProviderPropertyName + ProviderConnectionInfo.nameValueSeparator +
|
||||
this.providerName + ProviderConnectionInfo.idSeparator + idValues.join(ProviderConnectionInfo.idSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a more readable version of the options key intended for display areas, replaces the regular separators with display separators
|
||||
* @param optionsKey options key in the original format.
|
||||
*/
|
||||
public static getDisplayOptionsKey(optionsKey: string) {
|
||||
let ids: string[] = optionsKey.split(ProviderConnectionInfo.idSeparator);
|
||||
ids = ids.map(id => {
|
||||
let idParts = id.split(ProviderConnectionInfo.nameValueSeparator);
|
||||
let result = idParts[0] + ProviderConnectionInfo.displayNameValueSeparator;
|
||||
if (idParts.length >= 2) {
|
||||
result += idParts.slice(1).join(ProviderConnectionInfo.nameValueSeparator);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
return ids.join(ProviderConnectionInfo.displayIdSeparator);
|
||||
}
|
||||
|
||||
public static getProviderFromOptionsKey(optionsKey: string) {
|
||||
let providerId: string = '';
|
||||
if (optionsKey) {
|
||||
@@ -249,7 +299,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
}
|
||||
|
||||
public getSpecialTypeOptionName(type: string): string | undefined {
|
||||
if (this.serverCapabilities) {
|
||||
if (this.hasServerCapabilities()) {
|
||||
let optionMetadata = this.serverCapabilities.connectionOptions.find(o => o.specialValueType === type);
|
||||
return !!optionMetadata ? optionMetadata.name : undefined;
|
||||
} else {
|
||||
@@ -265,7 +315,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
}
|
||||
|
||||
public get authenticationTypeDisplayName(): string {
|
||||
let optionMetadata = this.serverCapabilities ? this.serverCapabilities.connectionOptions.find(o => o.specialValueType === ConnectionOptionSpecialType.authType) : undefined;
|
||||
let optionMetadata = this.hasServerCapabilities() ? this.serverCapabilities.connectionOptions.find(o => o.specialValueType === ConnectionOptionSpecialType.authType) : undefined;
|
||||
let authType = this.authenticationType;
|
||||
let displayName: string = authType;
|
||||
|
||||
@@ -291,28 +341,68 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
|
||||
return ':';
|
||||
}
|
||||
|
||||
public get titleParts(): string[] {
|
||||
let parts: string[] = [];
|
||||
// Always put these three on top. TODO: maybe only for MSSQL?
|
||||
parts.push(this.serverName);
|
||||
parts.push(this.databaseName);
|
||||
parts.push(this.authenticationTypeDisplayName);
|
||||
public static get displayIdSeparator(): string {
|
||||
return '; ';
|
||||
}
|
||||
|
||||
if (this.serverCapabilities) {
|
||||
public static get displayNameValueSeparator(): string {
|
||||
return '=';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all non specialValueType (or if distinct connections share same connection name, everything but connectionName and password).
|
||||
* Also allows for getting the non default options for this profile. (this function is used for changing the title).
|
||||
* @param needSpecial include all the special options key besides connection name or password in case we have multiple
|
||||
* distinct connections sharing the same connection name.
|
||||
* @param getNonDefault get only the non default options (for individual connections) to be used for identfying different properties
|
||||
* among connections sharing the same title.
|
||||
*/
|
||||
public getConnectionOptionsList(needSpecial: boolean, getNonDefault: boolean): azdata.ConnectionOption[] {
|
||||
let connectionOptions: azdata.ConnectionOption[] = [];
|
||||
|
||||
if (this.hasServerCapabilities()) {
|
||||
this.serverCapabilities.connectionOptions.forEach(element => {
|
||||
if (element.specialValueType !== ConnectionOptionSpecialType.serverName &&
|
||||
if (((!needSpecial && element.specialValueType !== ConnectionOptionSpecialType.serverName &&
|
||||
element.specialValueType !== ConnectionOptionSpecialType.databaseName &&
|
||||
element.specialValueType !== ConnectionOptionSpecialType.authType &&
|
||||
element.specialValueType !== ConnectionOptionSpecialType.password &&
|
||||
element.specialValueType !== ConnectionOptionSpecialType.userName) || needSpecial) &&
|
||||
element.specialValueType !== ConnectionOptionSpecialType.connectionName &&
|
||||
element.isIdentity && element.valueType === ServiceOptionType.string) {
|
||||
let value = this.getOptionValue(element.name);
|
||||
if (value) {
|
||||
parts.push(value);
|
||||
element.specialValueType !== ConnectionOptionSpecialType.password) {
|
||||
if (getNonDefault) {
|
||||
let value = this.getOptionValue(element.name);
|
||||
if (value && value !== element.defaultValue) {
|
||||
connectionOptions.push(element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
connectionOptions.push(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//Need to sort for consistency.
|
||||
connectionOptions.sort();
|
||||
return connectionOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append all non default options to tooltip string if useFullOptions is enabled.
|
||||
*/
|
||||
public getNonDefaultOptionsString(): string {
|
||||
let parts: string = "";
|
||||
let nonDefaultOptions = this.getConnectionOptionsList(false, true);
|
||||
nonDefaultOptions.forEach(element => {
|
||||
let value = this.getOptionValue(element.name);
|
||||
if (parts.length === 0) {
|
||||
parts = " (";
|
||||
}
|
||||
let addValue = element.name + ProviderConnectionInfo.displayNameValueSeparator + `${value}`;
|
||||
parts += parts === " (" ? addValue : (ProviderConnectionInfo.displayIdSeparator + addValue);
|
||||
});
|
||||
if (parts.length > 0) {
|
||||
parts += ")";
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user