mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-01 17:23:35 -05:00
Capabilities Cache (#831)
* init * finished compile erros * fixed all merge conflicts * fix dialog problems * formatting * fix opening dialog on first open * fix various problems with connectiondialog * formatting * fix tests
This commit is contained in:
@@ -111,4 +111,3 @@ export class TrieMap<E> {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,19 +43,12 @@ export class AdminService implements IAdminService {
|
||||
|
||||
private _providers: { [handle: string]: sqlops.AdminServicesProvider; } = Object.create(null);
|
||||
|
||||
private _providerOptions: { [handle: string]: sqlops.AdminServicesOptions; } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IWorkbenchEditorService private _editorService: IWorkbenchEditorService,
|
||||
@IConnectionManagementService private _connectionService: IConnectionManagementService,
|
||||
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
if (_capabilitiesService && _capabilitiesService.onProviderRegisteredEvent) {
|
||||
_capabilitiesService.onProviderRegisteredEvent((capabilities => {
|
||||
this._providerOptions[capabilities.providerName] = capabilities.adminServicesProvider;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private _runAction<T>(uri: string, action: (handler: sqlops.AdminServicesProvider) => Thenable<T>): Thenable<T> {
|
||||
|
||||
@@ -29,32 +29,14 @@ export interface ISaveGroupResult {
|
||||
*/
|
||||
export class ConnectionConfig implements IConnectionConfig {
|
||||
|
||||
private _providerCapabilitiesMap: { [providerName: string]: sqlops.DataProtocolServerCapabilities };
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public constructor(
|
||||
private _configurationEditService: ConfigurationEditingService,
|
||||
private _workspaceConfigurationService: IWorkspaceConfigurationService,
|
||||
private _capabilitiesService: ICapabilitiesService,
|
||||
cachedMetadata?: sqlops.DataProtocolServerCapabilities[]
|
||||
) {
|
||||
this._providerCapabilitiesMap = {};
|
||||
this.setCachedMetadata(cachedMetadata);
|
||||
if (this._capabilitiesService && this._capabilitiesService.onCapabilitiesReady()) {
|
||||
this._capabilitiesService.onCapabilitiesReady().then(() => {
|
||||
this.setCachedMetadata(this._capabilitiesService.getCapabilities());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public setCachedMetadata(cachedMetadata: sqlops.DataProtocolServerCapabilities[]): void {
|
||||
if (cachedMetadata) {
|
||||
cachedMetadata.forEach(item => {
|
||||
this.updateCapabilitiesCache(item.providerName, item);
|
||||
});
|
||||
}
|
||||
}
|
||||
private _capabilitiesService: ICapabilitiesService
|
||||
) { }
|
||||
|
||||
/**
|
||||
* Returns connection groups from user and workspace settings.
|
||||
@@ -81,44 +63,6 @@ export class ConnectionConfig implements IConnectionConfig {
|
||||
return allGroups;
|
||||
}
|
||||
|
||||
private updateCapabilitiesCache(providerName: string, providerCapabilities: sqlops.DataProtocolServerCapabilities): void {
|
||||
if (providerName && providerCapabilities) {
|
||||
this._providerCapabilitiesMap[providerName] = providerCapabilities;
|
||||
}
|
||||
}
|
||||
|
||||
private getCapabilitiesFromCache(providerName: string): sqlops.DataProtocolServerCapabilities {
|
||||
if (providerName in this._providerCapabilitiesMap) {
|
||||
return this._providerCapabilitiesMap[providerName];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the capabilities for given provider name. First tries to get it from capabilitiesService and if it's not registered yet,
|
||||
* Gets the data from the metadata stored in the config
|
||||
* @param providerName Provider Name
|
||||
*/
|
||||
public getCapabilities(providerName: string): sqlops.DataProtocolServerCapabilities {
|
||||
let result: sqlops.DataProtocolServerCapabilities = this.getCapabilitiesFromCache(providerName);
|
||||
if (result) {
|
||||
return result;
|
||||
} else {
|
||||
let capabilities = this._capabilitiesService.getCapabilities();
|
||||
if (capabilities) {
|
||||
let providerCapabilities = capabilities.find(c => c.providerName === providerName);
|
||||
if (providerCapabilities) {
|
||||
this.updateCapabilitiesCache(providerName, providerCapabilities);
|
||||
return providerCapabilities;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new connection to the connection config.
|
||||
*/
|
||||
@@ -131,14 +75,12 @@ export class ConnectionConfig implements IConnectionConfig {
|
||||
profiles = [];
|
||||
}
|
||||
|
||||
let providerCapabilities = this.getCapabilities(profile.providerName);
|
||||
let connectionProfile = this.getConnectionProfileInstance(profile, groupId, providerCapabilities);
|
||||
let newProfile = ConnectionProfile.convertToProfileStore(providerCapabilities, connectionProfile);
|
||||
let connectionProfile = this.getConnectionProfileInstance(profile, groupId);
|
||||
let newProfile = ConnectionProfile.convertToProfileStore(this._capabilitiesService, connectionProfile);
|
||||
|
||||
// Remove the profile if already set
|
||||
var sameProfileInList = profiles.find(value => {
|
||||
let providerCapabilities = this.getCapabilities(value.providerName);
|
||||
let providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, providerCapabilities);
|
||||
let providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, this._capabilitiesService);
|
||||
return providerConnectionProfile.matches(connectionProfile);
|
||||
});
|
||||
if (sameProfileInList) {
|
||||
@@ -159,10 +101,10 @@ export class ConnectionConfig implements IConnectionConfig {
|
||||
});
|
||||
}
|
||||
|
||||
private getConnectionProfileInstance(profile: IConnectionProfile, groupId: string, providerCapabilities: sqlops.DataProtocolServerCapabilities): ConnectionProfile {
|
||||
private getConnectionProfileInstance(profile: IConnectionProfile, groupId: string): ConnectionProfile {
|
||||
let connectionProfile = profile as ConnectionProfile;
|
||||
if (connectionProfile === undefined) {
|
||||
connectionProfile = new ConnectionProfile(providerCapabilities, profile);
|
||||
connectionProfile = new ConnectionProfile(this._capabilitiesService, profile);
|
||||
}
|
||||
connectionProfile.groupId = groupId;
|
||||
return connectionProfile;
|
||||
@@ -286,15 +228,7 @@ export class ConnectionConfig implements IConnectionConfig {
|
||||
}
|
||||
|
||||
let connectionProfiles = profiles.map(p => {
|
||||
let capabilitiesForProvider = this.getCapabilities(p.providerName);
|
||||
|
||||
let providerConnectionProfile = ConnectionProfile.createFromStoredProfile(p, capabilitiesForProvider);
|
||||
providerConnectionProfile.setServerCapabilities(capabilitiesForProvider);
|
||||
this._capabilitiesService.onProviderRegisteredEvent((serverCapabilities) => {
|
||||
providerConnectionProfile.onProviderRegistered(serverCapabilities);
|
||||
});
|
||||
|
||||
return providerConnectionProfile;
|
||||
return ConnectionProfile.createFromStoredProfile(p, this._capabilitiesService);
|
||||
});
|
||||
|
||||
return connectionProfiles;
|
||||
@@ -308,8 +242,7 @@ export class ConnectionConfig implements IConnectionConfig {
|
||||
let profiles = this._workspaceConfigurationService.inspect<IConnectionProfileStore[]>(Constants.connectionsArrayName).user;
|
||||
// Remove the profile from the connections
|
||||
profiles = profiles.filter(value => {
|
||||
let providerCapabilities = this.getCapabilities(value.providerName);
|
||||
let providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, providerCapabilities);
|
||||
let providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, this._capabilitiesService);
|
||||
return providerConnectionProfile.getOptionsKey() !== profile.getOptionsKey();
|
||||
});
|
||||
|
||||
@@ -330,8 +263,7 @@ export class ConnectionConfig implements IConnectionConfig {
|
||||
let profiles = this._workspaceConfigurationService.inspect<IConnectionProfileStore[]>(Constants.connectionsArrayName).user;
|
||||
// Remove the profiles from the connections
|
||||
profiles = profiles.filter(value => {
|
||||
let providerCapabilities = this.getCapabilities(value.providerName);
|
||||
let providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, providerCapabilities);
|
||||
let providerConnectionProfile = ConnectionProfile.createFromStoredProfile(value, this._capabilitiesService);
|
||||
return !connections.some((val) => val.getOptionsKey() === providerConnectionProfile.getOptionsKey());
|
||||
});
|
||||
|
||||
@@ -382,13 +314,12 @@ export class ConnectionConfig implements IConnectionConfig {
|
||||
let profiles = target === ConfigurationTarget.USER ? this._workspaceConfigurationService.inspect<IConnectionProfileStore[]>(Constants.connectionsArrayName).user :
|
||||
this._workspaceConfigurationService.inspect<IConnectionProfileStore[]>(Constants.connectionsArrayName).workspace;
|
||||
if (profiles) {
|
||||
let providerCapabilities = this.getCapabilities(profile.providerName);
|
||||
if (profile.parent && profile.parent.id === Constants.unsavedGroupId) {
|
||||
profile.groupId = newGroupID;
|
||||
profiles.push(ConnectionProfile.convertToProfileStore(providerCapabilities, profile));
|
||||
profiles.push(ConnectionProfile.convertToProfileStore(this._capabilitiesService, profile));
|
||||
} else {
|
||||
profiles.forEach((value) => {
|
||||
let configProf = ConnectionProfile.createFromStoredProfile(value, providerCapabilities);
|
||||
let configProf = ConnectionProfile.createFromStoredProfile(value, this._capabilitiesService);
|
||||
if (configProf.getOptionsKey() === profile.getOptionsKey()) {
|
||||
value.groupId = newGroupID;
|
||||
}
|
||||
|
||||
@@ -216,8 +216,6 @@ export interface IConnectionManagementService {
|
||||
|
||||
hasRegisteredServers(): boolean;
|
||||
|
||||
getCapabilities(providerName: string): sqlops.DataProtocolServerCapabilities;
|
||||
|
||||
canChangeConnectionConfig(profile: ConnectionProfile, newGroupID: string): boolean;
|
||||
|
||||
getTabColorForUri(uri: string): string;
|
||||
|
||||
@@ -137,9 +137,9 @@ export class ConnectionManagementService implements IConnectionManagementService
|
||||
100 /* High Priority */
|
||||
));
|
||||
|
||||
if (_capabilitiesService && _capabilitiesService.onProviderRegisteredEvent) {
|
||||
_capabilitiesService.onProviderRegisteredEvent((capabilities => {
|
||||
if (capabilities.providerName === 'MSSQL') {
|
||||
if (_capabilitiesService) {
|
||||
_capabilitiesService.onCapabilitiesRegistered((p => {
|
||||
if (p === 'MSSQL') {
|
||||
if (!this.hasRegisteredServers()) {
|
||||
// prompt the user for a new connection on startup if no profiles are registered
|
||||
this.showConnectionDialog();
|
||||
@@ -679,21 +679,13 @@ export class ConnectionManagementService implements IConnectionManagementService
|
||||
return Object.keys(this._providers);
|
||||
}
|
||||
|
||||
public getCapabilities(providerName: string): sqlops.DataProtocolServerCapabilities {
|
||||
let capabilities = this._capabilitiesService.getCapabilities();
|
||||
if (capabilities !== undefined && capabilities.length > 0) {
|
||||
return capabilities.find(c => c.providerName === providerName);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getAdvancedProperties(): sqlops.ConnectionOption[] {
|
||||
|
||||
let capabilities = this._capabilitiesService.getCapabilities();
|
||||
if (capabilities !== undefined && capabilities.length > 0) {
|
||||
let providers = this._capabilitiesService.providers;
|
||||
if (providers !== undefined && providers.length > 0) {
|
||||
// just grab the first registered provider for now, this needs to change
|
||||
// to lookup based on currently select provider
|
||||
let providerCapabilities = capabilities[0];
|
||||
let providerCapabilities = this._capabilitiesService.getCapabilities(providers[0]);
|
||||
if (!!providerCapabilities.connectionProvider) {
|
||||
return providerCapabilities.connectionProvider.options;
|
||||
}
|
||||
@@ -1362,7 +1354,7 @@ export class ConnectionManagementService implements IConnectionManagementService
|
||||
}
|
||||
|
||||
// Find the password option for the connection provider
|
||||
let passwordOption = this._capabilitiesService.getCapabilities().find(capability => capability.providerName === profile.providerName).connectionProvider.options.find(
|
||||
let passwordOption = this._capabilitiesService.getCapabilities(profile.providerName).connectionProvider.options.find(
|
||||
option => option.specialValueType === ConnectionOptionSpecialType.password);
|
||||
if (!passwordOption) {
|
||||
return undefined;
|
||||
|
||||
@@ -12,6 +12,8 @@ import * as interfaces from 'sql/parts/connection/common/interfaces';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import * as objects from 'sql/base/common/objects';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
|
||||
// Concrete implementation of the IConnectionProfile interface
|
||||
|
||||
@@ -28,9 +30,13 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
public saveProfile: boolean;
|
||||
|
||||
public isDisconnecting: boolean = false;
|
||||
public constructor(serverCapabilities?: sqlops.DataProtocolServerCapabilities, model?: interfaces.IConnectionProfile) {
|
||||
super(serverCapabilities, model);
|
||||
if (model) {
|
||||
|
||||
public constructor(
|
||||
capabilitiesService: ICapabilitiesService,
|
||||
model: string | interfaces.IConnectionProfile
|
||||
) {
|
||||
super(capabilitiesService, model);
|
||||
if (model && !isString(model)) {
|
||||
this.groupId = model.groupId;
|
||||
this.groupFullName = model.groupFullName;
|
||||
this.savePassword = model.savePassword;
|
||||
@@ -91,7 +97,7 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
}
|
||||
|
||||
public clone(): ConnectionProfile {
|
||||
let instance = new ConnectionProfile(this._serverCapabilities, this);
|
||||
let instance = new ConnectionProfile(this.capabilitiesService, this);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -137,12 +143,6 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
return super.getOptionsKey();
|
||||
}
|
||||
|
||||
public onProviderRegistered(serverCapabilities: sqlops.DataProtocolServerCapabilities): void {
|
||||
if (serverCapabilities.providerName === this.providerName) {
|
||||
this.setServerCapabilities(serverCapabilities);
|
||||
}
|
||||
}
|
||||
|
||||
public toIConnectionProfile(): interfaces.IConnectionProfile {
|
||||
let result: interfaces.IConnectionProfile = {
|
||||
serverName: this.serverName,
|
||||
@@ -170,8 +170,19 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
};
|
||||
}
|
||||
|
||||
public static createFromStoredProfile(profile: interfaces.IConnectionProfileStore, serverCapabilities: sqlops.DataProtocolServerCapabilities): ConnectionProfile {
|
||||
let connectionInfo = new ConnectionProfile(serverCapabilities, undefined);
|
||||
public static fromIConnectionProfile(capabilitiesService: ICapabilitiesService, profile: interfaces.IConnectionProfile) {
|
||||
if (profile) {
|
||||
if (profile instanceof ConnectionProfile) {
|
||||
return profile;
|
||||
} else {
|
||||
return new ConnectionProfile(capabilitiesService, profile);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public static createFromStoredProfile(profile: interfaces.IConnectionProfileStore, capabilitiesService: ICapabilitiesService): ConnectionProfile {
|
||||
let connectionInfo = new ConnectionProfile(capabilitiesService, profile.providerName);
|
||||
connectionInfo.options = profile.options;
|
||||
|
||||
// append group ID and original display name to build unique OE session ID
|
||||
@@ -187,28 +198,11 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
public static convertToConnectionProfile(serverCapabilities: sqlops.DataProtocolServerCapabilities, conn: interfaces.IConnectionProfile): ConnectionProfile {
|
||||
if (conn) {
|
||||
let connectionProfile: ConnectionProfile = undefined;
|
||||
let connectionProfileInstance = conn as ConnectionProfile;
|
||||
if (connectionProfileInstance && conn instanceof ConnectionProfile) {
|
||||
connectionProfile = connectionProfileInstance;
|
||||
connectionProfile.setServerCapabilities(serverCapabilities);
|
||||
} else {
|
||||
connectionProfile = new ConnectionProfile(serverCapabilities, conn);
|
||||
}
|
||||
|
||||
return connectionProfile;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public static convertToProfileStore(
|
||||
serverCapabilities: sqlops.DataProtocolServerCapabilities,
|
||||
capabilitiesService: ICapabilitiesService,
|
||||
connectionProfile: interfaces.IConnectionProfile): interfaces.IConnectionProfileStore {
|
||||
if (connectionProfile) {
|
||||
let connectionInfo = ConnectionProfile.convertToConnectionProfile(serverCapabilities, connectionProfile);
|
||||
let connectionInfo = ConnectionProfile.fromIConnectionProfile(capabilitiesService, connectionProfile);
|
||||
let profile: interfaces.IConnectionProfileStore = {
|
||||
options: {},
|
||||
groupId: connectionProfile.groupId,
|
||||
@@ -224,5 +218,4 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,25 +22,6 @@ export class ConnectionStatusManager {
|
||||
this._providerCapabilitiesMap = {};
|
||||
}
|
||||
|
||||
public getCapabilities(providerName: string): sqlops.DataProtocolServerCapabilities {
|
||||
let result: sqlops.DataProtocolServerCapabilities;
|
||||
|
||||
if (providerName in this._providerCapabilitiesMap) {
|
||||
result = this._providerCapabilitiesMap[providerName];
|
||||
} else {
|
||||
let capabilities = this._capabilitiesService.getCapabilities();
|
||||
if (capabilities) {
|
||||
let providerCapabilities = capabilities.find(c => c.providerName === providerName);
|
||||
if (providerCapabilities) {
|
||||
this._providerCapabilitiesMap[providerName] = providerCapabilities;
|
||||
result = providerCapabilities;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public findConnection(id: string): ConnectionManagementInfo {
|
||||
if (id in this._connections) {
|
||||
return this._connections[id];
|
||||
@@ -80,15 +61,14 @@ export class ConnectionStatusManager {
|
||||
|
||||
public addConnection(connection: IConnectionProfile, id: string): ConnectionManagementInfo {
|
||||
// Always create a copy and save that in the list
|
||||
let connectionProfile = new ConnectionProfile(this.getCapabilities(connection.providerName), connection);
|
||||
const self = this;
|
||||
let connectionProfile = new ConnectionProfile(this._capabilitiesService, connection);
|
||||
let connectionInfo: ConnectionManagementInfo = new ConnectionManagementInfo();
|
||||
connectionInfo.providerId = connection.providerName;
|
||||
connectionInfo.extensionTimer = StopWatch.create();
|
||||
connectionInfo.intelliSenseTimer = StopWatch.create();
|
||||
connectionInfo.connectionProfile = connectionProfile;
|
||||
connectionInfo.connecting = true;
|
||||
self._connections[id] = connectionInfo;
|
||||
this._connections[id] = connectionInfo;
|
||||
connectionInfo.serviceTimer = StopWatch.create();
|
||||
connectionInfo.ownerUri = id;
|
||||
|
||||
|
||||
@@ -50,14 +50,8 @@ export class ConnectionStore {
|
||||
this._groupIdToFullNameMap = {};
|
||||
this._groupFullNameToIdMap = {};
|
||||
if (!this._connectionConfig) {
|
||||
let cachedServerCapabilities = this.getCachedServerCapabilities();
|
||||
this._connectionConfig = new ConnectionConfig(this._configurationEditService,
|
||||
this._workspaceConfigurationService, this._capabilitiesService, cachedServerCapabilities);
|
||||
}
|
||||
if (_capabilitiesService) {
|
||||
_capabilitiesService.onProviderRegisteredEvent(e => {
|
||||
this.saveCachedServerCapabilities();
|
||||
});
|
||||
this._workspaceConfigurationService, this._capabilitiesService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +78,8 @@ export class ConnectionStore {
|
||||
* @returns {string} formatted string with server, DB and username
|
||||
*/
|
||||
public formatCredentialId(connectionProfile: IConnectionProfile, itemType?: string): string {
|
||||
let connectionProfileInstance: ConnectionProfile = ConnectionProfile.convertToConnectionProfile(
|
||||
this._connectionConfig.getCapabilities(connectionProfile.providerName), connectionProfile);
|
||||
let connectionProfileInstance: ConnectionProfile = ConnectionProfile.fromIConnectionProfile(
|
||||
this._capabilitiesService, connectionProfile);
|
||||
if (!connectionProfileInstance.getConnectionInfoId()) {
|
||||
throw new Error('Missing Id, which is required');
|
||||
}
|
||||
@@ -111,7 +105,7 @@ export class ConnectionStore {
|
||||
*/
|
||||
public isPasswordRequired(connection: IConnectionProfile): boolean {
|
||||
if (connection) {
|
||||
let connectionProfile = ConnectionProfile.convertToConnectionProfile(this._connectionConfig.getCapabilities(connection.providerName), connection);
|
||||
let connectionProfile = ConnectionProfile.fromIConnectionProfile(this._capabilitiesService, connection);
|
||||
return connectionProfile.isPasswordRequired();
|
||||
} else {
|
||||
return false;
|
||||
@@ -174,7 +168,6 @@ export class ConnectionStore {
|
||||
// Add necessary default properties before returning
|
||||
// this is needed to support immediate connections
|
||||
ConnInfo.fixupConnectionCredentials(profile);
|
||||
this.saveCachedServerCapabilities();
|
||||
resolve(profile);
|
||||
}, err => {
|
||||
reject(err);
|
||||
@@ -214,23 +207,6 @@ export class ConnectionStore {
|
||||
});
|
||||
}
|
||||
|
||||
private getCachedServerCapabilities(): sqlops.DataProtocolServerCapabilities[] {
|
||||
if (this._memento) {
|
||||
let metadata: sqlops.DataProtocolServerCapabilities[] = this._memento[Constants.capabilitiesOptions];
|
||||
return metadata;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private saveCachedServerCapabilities(): void {
|
||||
if (this._memento) {
|
||||
let capabilities = this._capabilitiesService.getCapabilities();
|
||||
this._memento[Constants.capabilitiesOptions] = capabilities;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -250,11 +226,7 @@ export class ConnectionStore {
|
||||
private convertConfigValuesToConnectionProfiles(configValues: IConnectionProfile[]): ConnectionProfile[] {
|
||||
return configValues.map(c => {
|
||||
if (c) {
|
||||
let capabilities = this._connectionConfig.getCapabilities(c.providerName);
|
||||
let connectionProfile = new ConnectionProfile(capabilities, c);
|
||||
this._capabilitiesService.onProviderRegisteredEvent((serverCapabilities) => {
|
||||
connectionProfile.onProviderRegistered(serverCapabilities);
|
||||
});
|
||||
let connectionProfile = new ConnectionProfile(this._capabilitiesService, c);
|
||||
if (connectionProfile.saveProfile) {
|
||||
if (!connectionProfile.groupFullName && connectionProfile.groupId) {
|
||||
connectionProfile.groupFullName = this.getGroupFullName(connectionProfile.groupId);
|
||||
@@ -289,7 +261,7 @@ export class ConnectionStore {
|
||||
|
||||
public getProfileWithoutPassword(conn: IConnectionProfile): ConnectionProfile {
|
||||
if (conn) {
|
||||
let savedConn: ConnectionProfile = ConnectionProfile.convertToConnectionProfile(this._connectionConfig.getCapabilities(conn.providerName), conn);
|
||||
let savedConn: ConnectionProfile = ConnectionProfile.fromIConnectionProfile(this._capabilitiesService, conn);
|
||||
savedConn = savedConn.withoutPassword();
|
||||
|
||||
return savedConn;
|
||||
|
||||
@@ -23,8 +23,6 @@ export interface IConnectionConfig {
|
||||
getAllGroups(): IConnectionProfileGroup[];
|
||||
changeGroupIdForConnectionGroup(source: ConnectionProfileGroup, target: ConnectionProfileGroup): Promise<void>;
|
||||
changeGroupIdForConnection(source: ConnectionProfile, targetGroupId: string): Promise<void>;
|
||||
setCachedMetadata(cachedMetaData: sqlops.DataProtocolServerCapabilities[]): void;
|
||||
getCapabilities(providerName: string): sqlops.DataProtocolServerCapabilities;
|
||||
editGroup(group: ConnectionProfileGroup): Promise<void>;
|
||||
deleteConnection(profile: ConnectionProfile): Promise<void>;
|
||||
deleteGroup(group: ConnectionProfileGroup): Promise<void>;
|
||||
|
||||
@@ -5,45 +5,68 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as interfaces from 'sql/parts/connection/common/interfaces';
|
||||
import { ConnectionOptionSpecialType, ServiceOptionType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import * as Constants from 'sql/parts/connection/common/constants';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
|
||||
export class ProviderConnectionInfo implements sqlops.ConnectionInfo {
|
||||
export class ProviderConnectionInfo extends Disposable implements sqlops.ConnectionInfo {
|
||||
|
||||
options: { [name: string]: any };
|
||||
options: { [name: string]: any } = {};
|
||||
|
||||
public providerName: string;
|
||||
private _providerName: string;
|
||||
protected _serverCapabilities: sqlops.DataProtocolServerCapabilities;
|
||||
private static readonly SqlAuthentication = 'SqlLogin';
|
||||
public static readonly ProviderPropertyName = 'providerName';
|
||||
|
||||
public constructor(serverCapabilities?: sqlops.DataProtocolServerCapabilities, model?: interfaces.IConnectionProfile) {
|
||||
this.options = {};
|
||||
if (serverCapabilities) {
|
||||
this._serverCapabilities = serverCapabilities;
|
||||
this.providerName = serverCapabilities.providerName;
|
||||
}
|
||||
if (model) {
|
||||
if (model.options && this._serverCapabilities) {
|
||||
this._serverCapabilities.connectionProvider.options.forEach(option => {
|
||||
let value = model.options[option.name];
|
||||
this.options[option.name] = value;
|
||||
});
|
||||
public constructor(
|
||||
protected capabilitiesService: ICapabilitiesService,
|
||||
model: string | interfaces.IConnectionProfile
|
||||
) {
|
||||
super();
|
||||
// we can't really do a whole lot if we don't have a provider
|
||||
if (isString(model) || (model && model.providerName)) {
|
||||
this.providerName = isString(model) ? model : model.providerName;
|
||||
|
||||
if (!isString(model)) {
|
||||
if (model.options && this._serverCapabilities) {
|
||||
this._serverCapabilities.connectionProvider.options.forEach(option => {
|
||||
let value = model.options[option.name];
|
||||
this.options[option.name] = value;
|
||||
});
|
||||
}
|
||||
this.serverName = model.serverName;
|
||||
this.authenticationType = model.authenticationType;
|
||||
this.databaseName = model.databaseName;
|
||||
this.password = model.password;
|
||||
this.userName = model.userName;
|
||||
}
|
||||
this.serverName = model.serverName;
|
||||
this.authenticationType = model.authenticationType;
|
||||
this.databaseName = model.databaseName;
|
||||
this.password = model.password;
|
||||
this.userName = model.userName;
|
||||
}
|
||||
}
|
||||
|
||||
public get providerName(): string {
|
||||
return this._providerName;
|
||||
}
|
||||
|
||||
public set providerName(name: string) {
|
||||
this._providerName = name;
|
||||
if (!this._serverCapabilities) {
|
||||
this._serverCapabilities = this.capabilitiesService.getCapabilities(this.providerName);
|
||||
this._register(this.capabilitiesService.onCapabilitiesRegistered(e => {
|
||||
if (e === this.providerName) {
|
||||
this._serverCapabilities = this.capabilitiesService.getCapabilities(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public clone(): ProviderConnectionInfo {
|
||||
let instance = new ProviderConnectionInfo(this._serverCapabilities);
|
||||
let instance = new ProviderConnectionInfo(this.capabilitiesService, this.providerName);
|
||||
instance.options = Object.assign({}, this.options);
|
||||
instance.providerName = this.providerName;
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -51,10 +74,6 @@ export class ProviderConnectionInfo implements sqlops.ConnectionInfo {
|
||||
return this._serverCapabilities;
|
||||
}
|
||||
|
||||
public setServerCapabilities(value: sqlops.DataProtocolServerCapabilities) {
|
||||
this._serverCapabilities = value;
|
||||
}
|
||||
|
||||
public get serverName(): string {
|
||||
return this.getSpecialTypeOptionValue(ConnectionOptionSpecialType.serverName);
|
||||
}
|
||||
|
||||
@@ -65,13 +65,12 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
private _connectionManagementService: IConnectionManagementService;
|
||||
private _container: HTMLElement;
|
||||
private _connectionDialog: ConnectionDialogWidget;
|
||||
private _connectionControllerMap: { [providerDisplayName: string]: IConnectionComponentController };
|
||||
private _connectionControllerMap: { [providerDisplayName: string]: IConnectionComponentController } = {};
|
||||
private _model: ConnectionProfile;
|
||||
private _params: INewConnectionParams;
|
||||
private _inputModel: IConnectionProfile;
|
||||
private _capabilitiesMaps: { [providerDisplayName: string]: sqlops.DataProtocolServerCapabilities };
|
||||
private _providerNameToDisplayNameMap: { [providerDisplayName: string]: string };
|
||||
private _providerTypes: string[];
|
||||
private _providerNameToDisplayNameMap: { [providerDisplayName: string]: string } = {};
|
||||
private _providerTypes: string[] = [];
|
||||
private _currentProviderType: string = 'Microsoft SQL Server';
|
||||
private _connecting: boolean = false;
|
||||
private _connectionErrorTitle = localize('connectionError', 'Connection error');
|
||||
@@ -85,29 +84,11 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
@IWindowsService private _windowsService: IWindowsService,
|
||||
@IClipboardService private _clipboardService: IClipboardService,
|
||||
@ICommandService private _commandService: ICommandService
|
||||
) {
|
||||
this._capabilitiesMaps = {};
|
||||
this._providerNameToDisplayNameMap = {};
|
||||
this._connectionControllerMap = {};
|
||||
this._providerTypes = [];
|
||||
if (_capabilitiesService) {
|
||||
_capabilitiesService.onProviderRegisteredEvent((capabilities => {
|
||||
let defaultProvider = this.getDefaultProviderName();
|
||||
if (capabilities.providerName === defaultProvider) {
|
||||
this.showDialogWithModel();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
) { }
|
||||
|
||||
private getDefaultProviderName() {
|
||||
if (this._workspaceConfigurationService) {
|
||||
let defaultProvider = WorkbenchUtils.getSqlConfigValue<string>(this._workspaceConfigurationService, Constants.defaultEngine);
|
||||
if (defaultProvider
|
||||
&& this._capabilitiesMaps
|
||||
&& defaultProvider in this._capabilitiesMaps) {
|
||||
return defaultProvider;
|
||||
}
|
||||
}
|
||||
// as a fallback, default to MSSQL if the value from settings is not available
|
||||
return Constants.mssqlProviderName;
|
||||
@@ -209,7 +190,7 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
// Set the model name, initialize the controller if needed, and return the controller
|
||||
this._model.providerName = providerName;
|
||||
if (!this._connectionControllerMap[providerName]) {
|
||||
this._connectionControllerMap[providerName] = this._instantiationService.createInstance(ConnectionController, this._container, this._connectionManagementService, this._capabilitiesMaps[providerName], {
|
||||
this._connectionControllerMap[providerName] = this._instantiationService.createInstance(ConnectionController, this._container, this._connectionManagementService, this._capabilitiesService.getCapabilities(providerName), {
|
||||
onSetConnectButton: (enable: boolean) => this.handleSetConnectButtonEnable(enable)
|
||||
}, providerName);
|
||||
}
|
||||
@@ -222,7 +203,7 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
|
||||
private handleShowUiComponent(input: OnShowUIResponse) {
|
||||
this._currentProviderType = input.selectedProviderType;
|
||||
this._model = new ConnectionProfile(this._capabilitiesMaps[this.getCurrentProviderName()], this._model);
|
||||
this._model = new ConnectionProfile(this._capabilitiesService, this._model);
|
||||
this.uiController.showUiComponent(input.container);
|
||||
}
|
||||
|
||||
@@ -249,9 +230,11 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
|
||||
private updateModelServerCapabilities(model: IConnectionProfile) {
|
||||
this._model = this.createModel(model);
|
||||
this._currentProviderType = this._providerNameToDisplayNameMap[this._model.providerName];
|
||||
if (this._connectionDialog) {
|
||||
this._connectionDialog.updateProvider(this._currentProviderType);
|
||||
if (this._model.providerName) {
|
||||
this._currentProviderType = this._providerNameToDisplayNameMap[this._model.providerName];
|
||||
if (this._connectionDialog) {
|
||||
this._connectionDialog.updateProvider(this._currentProviderType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,8 +242,7 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
let defaultProvider = this.getDefaultProviderName();
|
||||
let providerName = model ? model.providerName : defaultProvider;
|
||||
providerName = providerName ? providerName : defaultProvider;
|
||||
let serverCapabilities = this._capabilitiesMaps[providerName];
|
||||
let newProfile = new ConnectionProfile(serverCapabilities, model);
|
||||
let newProfile = new ConnectionProfile(this._capabilitiesService, model || providerName);
|
||||
newProfile.saveProfile = true;
|
||||
newProfile.generateNewId();
|
||||
// If connecting from a query editor set "save connection" to false
|
||||
@@ -270,23 +252,11 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
return newProfile;
|
||||
}
|
||||
|
||||
private cacheCapabilities(capabilities: sqlops.DataProtocolServerCapabilities) {
|
||||
if (capabilities) {
|
||||
this._providerTypes.push(capabilities.providerDisplayName);
|
||||
this._capabilitiesMaps[capabilities.providerName] = capabilities;
|
||||
this._providerNameToDisplayNameMap[capabilities.providerName] = capabilities.providerDisplayName;
|
||||
}
|
||||
}
|
||||
|
||||
private showDialogWithModel(): TPromise<void> {
|
||||
return new TPromise<void>((resolve, reject) => {
|
||||
if (this.getDefaultProviderName() in this._capabilitiesMaps) {
|
||||
this.updateModelServerCapabilities(this._inputModel);
|
||||
|
||||
this.doShowDialog(this._params);
|
||||
}
|
||||
let none: void;
|
||||
resolve(none);
|
||||
this.updateModelServerCapabilities(this._inputModel);
|
||||
this.doShowDialog(this._params);
|
||||
resolve(null);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -305,14 +275,14 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
let capabilitiesPromise: Promise<void> = Promise.resolve();
|
||||
if (this._providerTypes.length === 0) {
|
||||
capabilitiesPromise = this._capabilitiesService.onCapabilitiesReady().then(() => {
|
||||
let capabilities = this._capabilitiesService.getCapabilities();
|
||||
capabilities.forEach(c => {
|
||||
this.cacheCapabilities(c);
|
||||
this._capabilitiesService.providers.map(p => {
|
||||
let capabilities = this._capabilitiesService.getCapabilities(p);
|
||||
this._providerTypes.push(capabilities.providerDisplayName);
|
||||
this._providerNameToDisplayNameMap[capabilities.providerName] = capabilities.providerDisplayName;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
capabilitiesPromise.then(success => {
|
||||
capabilitiesPromise.then(s => {
|
||||
this.updateModelServerCapabilities(model);
|
||||
// If connecting from a query editor set "save connection" to false
|
||||
if (params && params.input && params.connectionType === ConnectionType.editor) {
|
||||
@@ -324,7 +294,7 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
||||
this.showErrorDialog(Severity.Error, this._connectionErrorTitle, connectionResult.errorMessage, connectionResult.callStack);
|
||||
}
|
||||
}));
|
||||
}, err => reject(err));
|
||||
}, e => reject(e));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ export class ConnectionDialogWidget extends Modal {
|
||||
resolve(confirmed);
|
||||
});
|
||||
|
||||
//this._messageService.confirm(confirm).then(confirmation => {
|
||||
//this._messageService.confirm(confirm).then(confirmation => {
|
||||
// if (!confirmation.confirmed) {
|
||||
// return TPromise.as(false);
|
||||
// } else {
|
||||
@@ -453,7 +453,6 @@ export class ConnectionDialogWidget extends Modal {
|
||||
|
||||
public updateProvider(displayName: string) {
|
||||
this._providerTypeSelectBox.selectWithOptionName(displayName);
|
||||
this.onProviderTypeSelected(displayName);
|
||||
}
|
||||
|
||||
public set databaseDropdownExpanded(val: boolean) {
|
||||
|
||||
@@ -105,7 +105,7 @@ export class ExplorerWidget extends DashboardWidget implements IDashboardWidget,
|
||||
this._register(toDisposableSubscription(this._bootstrap.metadataService.databaseNames.subscribe(
|
||||
data => {
|
||||
let profileData = data.map(d => {
|
||||
let profile = new ConnectionProfile(currentProfile.serverCapabilities, currentProfile);
|
||||
let profile = new ConnectionProfile(this._bootstrap.capabilitiesService, currentProfile);
|
||||
profile.databaseName = d;
|
||||
return profile;
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as ConnectionUtils from 'sql/parts/connection/common/utils';
|
||||
import { ProviderConnectionInfo } from 'sql/parts/connection/common/providerConnectionInfo';
|
||||
import { ServiceOption } from 'sqlops';
|
||||
|
||||
export class BackupService implements IBackupService {
|
||||
|
||||
@@ -88,7 +89,6 @@ export class BackupUiService implements IBackupUiService {
|
||||
public _serviceBrand: any;
|
||||
private _backupDialogs: { [providerName: string]: BackupDialog | OptionsDialog } = {};
|
||||
private _currentProvider: string;
|
||||
private _optionsMap: { [providerName: string]: sqlops.ServiceOption[] } = {};
|
||||
private _optionValues: { [optionName: string]: any } = {};
|
||||
private _connectionUri: string;
|
||||
private static _connectionUniqueId: number = 0;
|
||||
@@ -115,20 +115,22 @@ export class BackupUiService implements IBackupUiService {
|
||||
});
|
||||
}
|
||||
|
||||
private getOptions(provider: string): ServiceOption[] {
|
||||
let feature = this._capabilitiesService.getCapabilities(this._currentProvider).features.find(f => f.featureName === 'backup');
|
||||
if (feature) {
|
||||
return feature.optionsMetadata;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public showBackupDialog(connection: IConnectionProfile): TPromise<void> {
|
||||
let self = this;
|
||||
self._connectionUri = ConnectionUtils.generateUri(connection);
|
||||
self._currentProvider = connection.providerName;
|
||||
let backupDialog = self._backupDialogs[self._currentProvider];
|
||||
if (!backupDialog) {
|
||||
let capabilitiesList = this._capabilitiesService.getCapabilities();
|
||||
capabilitiesList.forEach(providerCapabilities => {
|
||||
let backupFeature = providerCapabilities.features.find(feature => feature.featureName === 'backup');
|
||||
if (backupFeature && backupFeature.optionsMetadata) {
|
||||
this._optionsMap[providerCapabilities.providerName] = backupFeature.optionsMetadata;
|
||||
}
|
||||
});
|
||||
let backupOptions = self._optionsMap[self._currentProvider];
|
||||
let backupOptions = this.getOptions(this._currentProvider);
|
||||
if (backupOptions) {
|
||||
backupDialog = self._instantiationService ? self._instantiationService.createInstance(
|
||||
OptionsDialog, 'Backup database - ' + connection.serverName + ':' + connection.databaseName, 'BackupOptions', undefined) : undefined;
|
||||
@@ -141,7 +143,7 @@ export class BackupUiService implements IBackupUiService {
|
||||
self._backupDialogs[self._currentProvider] = backupDialog;
|
||||
}
|
||||
|
||||
let backupOptions = this._optionsMap[self._currentProvider];
|
||||
let backupOptions = this.getOptions(this._currentProvider);
|
||||
return new TPromise<void>(() => {
|
||||
if (backupOptions) {
|
||||
(backupDialog as OptionsDialog).open(backupOptions, self._optionValues);
|
||||
|
||||
@@ -139,7 +139,7 @@ export class RestoreDialogController implements IRestoreDialogController {
|
||||
private _sessionId: string;
|
||||
private readonly _restoreFeature = 'Restore';
|
||||
private readonly _restoreTaskName: string = 'Restore Database';
|
||||
private readonly _restoreCompleted : string = 'Completed';
|
||||
private readonly _restoreCompleted: string = 'Completed';
|
||||
private _optionValues: { [optionName: string]: any } = {};
|
||||
|
||||
constructor(
|
||||
@@ -178,11 +178,11 @@ export class RestoreDialogController implements IRestoreDialogController {
|
||||
|
||||
private isSuccessfulRestore(response: TaskNode): boolean {
|
||||
return (response.taskName === this._restoreTaskName &&
|
||||
response.message === this._restoreCompleted &&
|
||||
(response.status === TaskStatus.succeeded ||
|
||||
response.status === TaskStatus.succeededWithWarning) &&
|
||||
(response.taskExecutionMode === TaskExecutionMode.execute ||
|
||||
response.taskExecutionMode === TaskExecutionMode.executeAndScript));
|
||||
response.message === this._restoreCompleted &&
|
||||
(response.status === TaskStatus.succeeded ||
|
||||
response.status === TaskStatus.succeededWithWarning) &&
|
||||
(response.taskExecutionMode === TaskExecutionMode.execute ||
|
||||
response.taskExecutionMode === TaskExecutionMode.executeAndScript));
|
||||
}
|
||||
|
||||
private handleMssqlOnValidateFile(overwriteTargetDatabase: boolean = false): void {
|
||||
@@ -266,7 +266,7 @@ export class RestoreDialogController implements IRestoreDialogController {
|
||||
private getRestoreOption(): sqlops.ServiceOption[] {
|
||||
let options: sqlops.ServiceOption[] = [];
|
||||
let providerId: string = this.getCurrentProviderId();
|
||||
let providerCapabilities = this._capabilitiesService.getCapabilities().find(c => c.providerName === providerId);
|
||||
let providerCapabilities = this._capabilitiesService.getCapabilities(providerId);
|
||||
|
||||
if (providerCapabilities) {
|
||||
let restoreMetadataProvider = providerCapabilities.features.find(f => f.featureName === this._restoreFeature);
|
||||
|
||||
@@ -38,6 +38,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { MenuRegistry, ExecuteCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
|
||||
const labelDisplay = nls.localize("insights.item", "Item");
|
||||
const valueDisplay = nls.localize("insights.value", "Value");
|
||||
@@ -129,7 +130,8 @@ export class InsightsDialogView extends Modal {
|
||||
@IContextMenuService private _contextMenuService: IContextMenuService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@ICommandService private _commandService: ICommandService
|
||||
@ICommandService private _commandService: ICommandService,
|
||||
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
super(nls.localize("InsightsDialogTitle", "Insights"), TelemetryKeys.Insights, partService, telemetryService, contextKeyService);
|
||||
this._model.onDataChange(e => this.build());
|
||||
@@ -388,7 +390,7 @@ export class InsightsDialogView extends Modal {
|
||||
}
|
||||
|
||||
let currentProfile = this._connectionProfile as ConnectionProfile;
|
||||
let profile = new ConnectionProfile(currentProfile.serverCapabilities, currentProfile);
|
||||
let profile = new ConnectionProfile(this._capabilitiesService, currentProfile);
|
||||
profile.databaseName = database;
|
||||
profile.serverName = server;
|
||||
profile.userName = user;
|
||||
|
||||
@@ -19,6 +19,7 @@ import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { warn, error } from 'sql/base/common/log';
|
||||
import { ServerTreeView } from 'sql/parts/registeredServer/viewlet/serverTreeView';
|
||||
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
|
||||
|
||||
export const SERVICE_ID = 'ObjectExplorerService';
|
||||
|
||||
@@ -102,7 +103,8 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
|
||||
constructor(
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@ITelemetryService private _telemetryService: ITelemetryService
|
||||
@ITelemetryService private _telemetryService: ITelemetryService,
|
||||
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService
|
||||
) {
|
||||
this._onUpdateObjectExplorerNodes = new Emitter<ObjectExplorerNodeEventArgs>();
|
||||
this._activeObjectExplorerNodes = {};
|
||||
@@ -124,8 +126,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
|
||||
public updateObjectExplorerNodes(connection: IConnectionProfile): Promise<void> {
|
||||
return this._connectionManagementService.addSavedPassword(connection).then(withPassword => {
|
||||
let connectionProfile = ConnectionProfile.convertToConnectionProfile(
|
||||
this._connectionManagementService.getCapabilities(connection.providerName), withPassword);
|
||||
let connectionProfile = ConnectionProfile.fromIConnectionProfile(this._capabilitiesService, withPassword);
|
||||
return this.updateNewObjectExplorerNode(connectionProfile);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,19 +7,32 @@
|
||||
|
||||
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
||||
import * as Constants from 'sql/common/constants';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { IExtensionManagementService, ILocalExtension, IExtensionEnablementService, LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { Memento } from 'vs/workbench/common/memento';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
|
||||
export const SERVICE_ID = 'capabilitiesService';
|
||||
export const HOST_NAME = 'sqlops';
|
||||
export const HOST_VERSION = '1.0';
|
||||
|
||||
interface IProtocolMomento {
|
||||
[id: string]: sqlops.DataProtocolServerCapabilities;
|
||||
}
|
||||
|
||||
export const clientCapabilities = {
|
||||
hostName: HOST_NAME,
|
||||
hostVersion: HOST_VERSION
|
||||
};
|
||||
|
||||
export const ICapabilitiesService = createDecorator<ICapabilitiesService>(SERVICE_ID);
|
||||
|
||||
/**
|
||||
@@ -31,7 +44,7 @@ export interface ICapabilitiesService {
|
||||
/**
|
||||
* Retrieve a list of registered capabilities providers
|
||||
*/
|
||||
getCapabilities(): sqlops.DataProtocolServerCapabilities[];
|
||||
getCapabilities(provider: string): sqlops.DataProtocolServerCapabilities;
|
||||
|
||||
/**
|
||||
* Register a capabilities provider
|
||||
@@ -43,43 +56,38 @@ export interface ICapabilitiesService {
|
||||
*/
|
||||
isFeatureAvailable(action: IAction, connectionManagementInfo: ConnectionManagementInfo): boolean;
|
||||
|
||||
/**
|
||||
* Event raised when a provider is registered
|
||||
*/
|
||||
onProviderRegisteredEvent: Event<sqlops.DataProtocolServerCapabilities>;
|
||||
|
||||
/**
|
||||
* Promise fulfilled when Capabilities are ready
|
||||
*/
|
||||
onCapabilitiesReady(): Promise<void>;
|
||||
|
||||
/**
|
||||
* When a new capabilities is registered, it emits the provider name, be to use to get the new capabilities
|
||||
*/
|
||||
readonly onCapabilitiesRegistered: Event<string>;
|
||||
|
||||
/**
|
||||
* Get an array of all known providers
|
||||
*/
|
||||
readonly providers: string[];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Capabilities service implementation class. This class provides the ability
|
||||
* to discover the DMP capabilties that a DMP provider offers.
|
||||
*/
|
||||
export class CapabilitiesService implements ICapabilitiesService {
|
||||
export class CapabilitiesService extends Disposable implements ICapabilitiesService {
|
||||
|
||||
public _serviceBrand: any;
|
||||
|
||||
private _momento = new Memento('capabilitiesCache');
|
||||
|
||||
private static DATA_PROVIDER_CATEGORY: string = 'Data Provider';
|
||||
|
||||
private _providers: sqlops.CapabilitiesProvider[] = [];
|
||||
|
||||
private _capabilities: sqlops.DataProtocolServerCapabilities[] = [];
|
||||
|
||||
private _onProviderRegistered: Emitter<sqlops.DataProtocolServerCapabilities>;
|
||||
|
||||
private _clientCapabilties: sqlops.DataProtocolClientCapabilities = {
|
||||
|
||||
hostName: HOST_NAME,
|
||||
hostVersion: HOST_VERSION
|
||||
};
|
||||
|
||||
private disposables: IDisposable[] = [];
|
||||
|
||||
private _onCapabilitiesReady: Deferred<void>;
|
||||
private _onCapabilitiesReady = new Deferred<void>();
|
||||
|
||||
// Setting this to 1 by default as we have MS SQL provider by default and then we increament
|
||||
// this number based on extensions installed.
|
||||
@@ -89,12 +97,15 @@ export class CapabilitiesService implements ICapabilitiesService {
|
||||
|
||||
private _registeredCapabilities: number = 0;
|
||||
|
||||
constructor( @IExtensionManagementService private extensionManagementService: IExtensionManagementService,
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService) {
|
||||
private _onCapabilitiesRegistered = this._register(new Emitter<string>());
|
||||
public readonly onCapabilitiesRegistered = this._onCapabilitiesRegistered.event;
|
||||
|
||||
this._onProviderRegistered = new Emitter<sqlops.DataProtocolServerCapabilities>();
|
||||
this.disposables.push(this._onProviderRegistered);
|
||||
this._onCapabilitiesReady = new Deferred();
|
||||
constructor(
|
||||
@IExtensionManagementService private extensionManagementService: IExtensionManagementService,
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService,
|
||||
@IStorageService private _storageService: IStorageService
|
||||
) {
|
||||
super();
|
||||
|
||||
// Get extensions and filter where the category has 'Data Provider' in it
|
||||
this.extensionManagementService.getInstalled(LocalExtensionType.User).then((extensions: ILocalExtension[]) => {
|
||||
@@ -140,8 +151,16 @@ export class CapabilitiesService implements ICapabilitiesService {
|
||||
/**
|
||||
* Retrieve a list of registered server capabilities
|
||||
*/
|
||||
public getCapabilities(): sqlops.DataProtocolServerCapabilities[] {
|
||||
return this._capabilities;
|
||||
public getCapabilities(provider: string): sqlops.DataProtocolServerCapabilities {
|
||||
return this.capabilities[provider];
|
||||
}
|
||||
|
||||
public get providers(): string[] {
|
||||
return Object.keys(this.capabilities);
|
||||
}
|
||||
|
||||
private get capabilities(): IProtocolMomento {
|
||||
return this._momento.getMemento(this._storageService) as IProtocolMomento;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,12 +168,11 @@ export class CapabilitiesService implements ICapabilitiesService {
|
||||
* @param provider
|
||||
*/
|
||||
public registerProvider(provider: sqlops.CapabilitiesProvider): void {
|
||||
this._providers.push(provider);
|
||||
|
||||
// request the capabilities from server
|
||||
provider.getServerCapabilities(this._clientCapabilties).then(serverCapabilities => {
|
||||
this._capabilities.push(serverCapabilities);
|
||||
this._onProviderRegistered.fire(serverCapabilities);
|
||||
provider.getServerCapabilities(clientCapabilities).then(serverCapabilities => {
|
||||
this.capabilities[serverCapabilities.providerName] = serverCapabilities;
|
||||
this._momento.saveMemento();
|
||||
this._onCapabilitiesRegistered.fire(serverCapabilities.providerName);
|
||||
this._registeredCapabilities++;
|
||||
this.resolveCapabilitiesIfReady();
|
||||
});
|
||||
@@ -198,13 +216,4 @@ export class CapabilitiesService implements ICapabilitiesService {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Event Emitters
|
||||
public get onProviderRegisteredEvent(): Event<sqlops.DataProtocolServerCapabilities> {
|
||||
return this._onProviderRegistered.event;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ export class SerializationService implements ISerializationService {
|
||||
|
||||
public getSerializationFeatureMetadataProvider(ownerUri: string): sqlops.FeatureMetadataProvider {
|
||||
let providerId: string = this._connectionService.getProviderIdFromUri(ownerUri);
|
||||
let providerCapabilities = this._capabilitiesService.getCapabilities().find(c => c.providerName === providerId);
|
||||
let providerCapabilities = this._capabilitiesService.getCapabilities(providerId);
|
||||
|
||||
if (providerCapabilities) {
|
||||
return providerCapabilities.features.find(f => f.featureName === SERVICE_ID);
|
||||
|
||||
Reference in New Issue
Block a user