Export function to prompt user to select/create connection (#17010)
* Export function to prompt user to select/create connection * change name * update typings * Fix compile-view
This commit is contained in:
Родитель
d2284a9897
Коммит
b2201cebda
|
@ -77,7 +77,8 @@ gulp.task('ext:compile-src', (done) => {
|
|||
// Compile angular view
|
||||
gulp.task('ext:compile-view', (done) => {
|
||||
return gulp.src([
|
||||
config.paths.project.root + '/src/views/htmlcontent/**/*.ts'])
|
||||
config.paths.project.root + '/src/views/htmlcontent/**/*.ts',
|
||||
config.paths.project.root + '/typings/**/*.d.ts'])
|
||||
.pipe(srcmap.init())
|
||||
.pipe(tsProject())
|
||||
.pipe(nls.rewriteLocalizeCalls())
|
||||
|
|
|
@ -22,13 +22,14 @@ import { Runtime, PlatformInformation } from '../models/platform';
|
|||
import { Deferred } from '../protocol';
|
||||
import { AccountService } from '../azure/accountService';
|
||||
import { FirewallService } from '../firewall/firewallService';
|
||||
import { IConnectionCredentials, IConnectionProfile } from '../models/interfaces';
|
||||
import { IConnectionProfile } from '../models/interfaces';
|
||||
import { ConnectionSummary } from '../models/contracts/connection';
|
||||
import { AccountStore } from '../azure/accountStore';
|
||||
import { ConnectionProfile } from '../models/connectionProfile';
|
||||
import { QuestionTypes, IQuestion } from '../prompts/question';
|
||||
import { IAccount } from '../models/contracts/azure/accountInterfaces';
|
||||
import { AzureController } from '../azure/azureController';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
/**
|
||||
* Information for a document's connection. Exported for testing purposes.
|
||||
|
@ -42,7 +43,7 @@ export class ConnectionInfo {
|
|||
/**
|
||||
* Credentials used to connect
|
||||
*/
|
||||
public credentials: IConnectionCredentials;
|
||||
public credentials: IConnectionInfo;
|
||||
|
||||
/**
|
||||
* Callback for when a connection notification is received.
|
||||
|
@ -79,7 +80,7 @@ export default class ConnectionManager {
|
|||
private _statusView: StatusView;
|
||||
private _connections: { [fileUri: string]: ConnectionInfo };
|
||||
private _connectionCredentialsToServerInfoMap:
|
||||
Map<IConnectionCredentials, ConnectionContracts.ServerInfo>;
|
||||
Map<IConnectionInfo, ConnectionContracts.ServerInfo>;
|
||||
private _uriToConnectionPromiseMap: Map<string, Deferred<boolean>>;
|
||||
private _failedUriToFirewallIpMap: Map<string, string>;
|
||||
private _accountService: AccountService;
|
||||
|
@ -97,7 +98,7 @@ export default class ConnectionManager {
|
|||
this._statusView = statusView;
|
||||
this._connections = {};
|
||||
this._connectionCredentialsToServerInfoMap =
|
||||
new Map<IConnectionCredentials, ConnectionContracts.ServerInfo>();
|
||||
new Map<IConnectionInfo, ConnectionContracts.ServerInfo>();
|
||||
this._uriToConnectionPromiseMap = new Map<string, Deferred<boolean>>();
|
||||
|
||||
|
||||
|
@ -233,7 +234,7 @@ export default class ConnectionManager {
|
|||
return this._firewallService;
|
||||
}
|
||||
|
||||
public isActiveConnection(credential: IConnectionCredentials): boolean {
|
||||
public isActiveConnection(credential: IConnectionInfo): boolean {
|
||||
const connectedCredentials = Object.keys(this._connections).map((uri) => this._connections[uri].credentials);
|
||||
for (let connectedCredential of connectedCredentials) {
|
||||
if (Utils.isSameConnection(credential, connectedCredential)) {
|
||||
|
@ -243,7 +244,7 @@ export default class ConnectionManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
public getUriForConnection(connection: IConnectionCredentials): string {
|
||||
public getUriForConnection(connection: IConnectionInfo): string {
|
||||
for (let uri of Object.keys(this._connections)) {
|
||||
if (Utils.isSameConnection(this._connections[uri].credentials, connection)) {
|
||||
return uri;
|
||||
|
@ -319,7 +320,7 @@ export default class ConnectionManager {
|
|||
let connection = self.getConnectionInfo(fileUri);
|
||||
connection.connecting = false;
|
||||
|
||||
let mruConnection: IConnectionCredentials = <any>{};
|
||||
let mruConnection: IConnectionInfo = <any>{};
|
||||
|
||||
if (Utils.isNotEmpty(result.connectionId)) {
|
||||
// Convert to credentials if it's a connection string based connection
|
||||
|
@ -330,8 +331,8 @@ export default class ConnectionManager {
|
|||
|
||||
// We have a valid connection
|
||||
// Copy credentials as the database name will be updated
|
||||
let newCredentials: IConnectionCredentials = <any>{};
|
||||
Object.assign<IConnectionCredentials, IConnectionCredentials>(newCredentials, connection.credentials);
|
||||
let newCredentials: IConnectionInfo = <any>{};
|
||||
Object.assign<IConnectionInfo, IConnectionInfo>(newCredentials, connection.credentials);
|
||||
if (result.connectionSummary && result.connectionSummary.databaseName) {
|
||||
newCredentials.database = result.connectionSummary.databaseName;
|
||||
}
|
||||
|
@ -365,7 +366,7 @@ export default class ConnectionManager {
|
|||
|
||||
private handleConnectionSuccess(fileUri: string,
|
||||
connection: ConnectionInfo,
|
||||
newCredentials: IConnectionCredentials,
|
||||
newCredentials: IConnectionInfo,
|
||||
result: ConnectionContracts.ConnectionCompleteParams): void {
|
||||
connection.connectionId = result.connectionId;
|
||||
connection.serverInfo = result.serverInfo;
|
||||
|
@ -426,9 +427,9 @@ export default class ConnectionManager {
|
|||
);
|
||||
}
|
||||
|
||||
private async tryAddMruConnection(connection: ConnectionInfo, newConnection: IConnectionCredentials): Promise<void> {
|
||||
private async tryAddMruConnection(connection: ConnectionInfo, newConnection: IConnectionInfo): Promise<void> {
|
||||
if (newConnection) {
|
||||
let connectionToSave: IConnectionCredentials = Object.assign({}, newConnection);
|
||||
let connectionToSave: IConnectionInfo = Object.assign({}, newConnection);
|
||||
try {
|
||||
await this._connectionStore.addRecentlyUsed(connectionToSave);
|
||||
connection.connectHandler(true);
|
||||
|
@ -443,7 +444,7 @@ export default class ConnectionManager {
|
|||
/**
|
||||
* Populates a credential object based on the credential connection string
|
||||
*/
|
||||
private populateCredentialsFromConnectionString(credentials: IConnectionCredentials, connectionSummary: ConnectionSummary): IConnectionCredentials {
|
||||
private populateCredentialsFromConnectionString(credentials: IConnectionInfo, connectionSummary: ConnectionSummary): IConnectionInfo {
|
||||
// populate credential details
|
||||
credentials.database = connectionSummary.databaseName;
|
||||
credentials.user = connectionSummary.userName;
|
||||
|
@ -510,7 +511,7 @@ export default class ConnectionManager {
|
|||
}
|
||||
}
|
||||
|
||||
public async changeDatabase(newDatabaseCredentials: IConnectionCredentials): Promise<boolean> {
|
||||
public async changeDatabase(newDatabaseCredentials: IConnectionInfo): Promise<boolean> {
|
||||
const fileUri = this.vscodeWrapper.activeTextEditorUri;
|
||||
if (!this.isConnected(fileUri)) {
|
||||
this.vscodeWrapper.showWarningMessage(LocalizedConstants.msgChooseDatabaseNotConnected);
|
||||
|
@ -591,9 +592,9 @@ export default class ConnectionManager {
|
|||
/**
|
||||
* Helper to show all connections and perform connect logic.
|
||||
*/
|
||||
public async showConnectionsAndConnect(fileUri: string): Promise<IConnectionCredentials> {
|
||||
public async showConnectionsAndConnect(fileUri: string): Promise<IConnectionInfo> {
|
||||
// show connection picklist
|
||||
const connectionCreds = await this.connectionUI.showConnections();
|
||||
const connectionCreds = await this.connectionUI.promptForConnection();
|
||||
if (connectionCreds) {
|
||||
// close active connection
|
||||
await this.disconnect(fileUri);
|
||||
|
@ -608,7 +609,7 @@ export default class ConnectionManager {
|
|||
* Get the server info for a connection
|
||||
* @param connectionCreds
|
||||
*/
|
||||
public getServerInfo(connectionCredentials: IConnectionCredentials): ConnectionContracts.ServerInfo {
|
||||
public getServerInfo(connectionCredentials: IConnectionInfo): ConnectionContracts.ServerInfo {
|
||||
if (this._connectionCredentialsToServerInfoMap.has(connectionCredentials)) {
|
||||
return this._connectionCredentialsToServerInfoMap.get(connectionCredentials);
|
||||
}
|
||||
|
@ -621,7 +622,7 @@ export default class ConnectionManager {
|
|||
* @param fileUri file Uri
|
||||
* @param connectionCreds Connection Profile
|
||||
*/
|
||||
private async handleConnectionResult(result: boolean, fileUri: string, connectionCreds: IConnectionCredentials): Promise<boolean> {
|
||||
private async handleConnectionResult(result: boolean, fileUri: string, connectionCreds: IConnectionInfo): Promise<boolean> {
|
||||
let connection = this._connections[fileUri];
|
||||
if (!result && connection && connection.loginFailed) {
|
||||
const newConnection = await this.connectionUI.createProfileWithDifferentCredentials(connectionCreds);
|
||||
|
@ -648,7 +649,7 @@ export default class ConnectionManager {
|
|||
}
|
||||
|
||||
// let users pick from a picklist of connections
|
||||
public async onNewConnection(): Promise<IConnectionCredentials> {
|
||||
public async onNewConnection(): Promise<IConnectionInfo> {
|
||||
const fileUri = this.vscodeWrapper.activeTextEditorUri;
|
||||
if (!fileUri) {
|
||||
// A text document needs to be open before we can connect
|
||||
|
@ -668,7 +669,7 @@ export default class ConnectionManager {
|
|||
}
|
||||
|
||||
// create a new connection with the connectionCreds provided
|
||||
public async connect(fileUri: string, connectionCreds: IConnectionCredentials, promise?: Deferred<boolean>): Promise<boolean> {
|
||||
public async connect(fileUri: string, connectionCreds: IConnectionInfo, promise?: Deferred<boolean>): Promise<boolean> {
|
||||
const self = this;
|
||||
let connectionPromise = new Promise<boolean>(async (resolve, reject) => {
|
||||
let connectionInfo: ConnectionInfo = new ConnectionInfo();
|
||||
|
@ -783,7 +784,7 @@ export default class ConnectionManager {
|
|||
}
|
||||
|
||||
// Connect the saved uri and disconnect the untitled uri on successful connection
|
||||
let creds: IConnectionCredentials = this._connections[oldFileUri].credentials;
|
||||
let creds: IConnectionInfo = this._connections[oldFileUri].credentials;
|
||||
let result = await this.connect(newFileUri, creds);
|
||||
if (result) {
|
||||
await this.disconnect(oldFileUri);
|
||||
|
|
|
@ -18,7 +18,7 @@ import { IPrompter } from '../prompts/question';
|
|||
import CodeAdapter from '../prompts/adapter';
|
||||
import VscodeWrapper from './vscodeWrapper';
|
||||
import UntitledSqlDocumentService from './untitledSqlDocumentService';
|
||||
import { ISelectionData, IConnectionProfile, IConnectionCredentials } from './../models/interfaces';
|
||||
import { ISelectionData, IConnectionProfile } from './../models/interfaces';
|
||||
import * as path from 'path';
|
||||
import fs = require('fs');
|
||||
import { ObjectExplorerProvider } from '../objectExplorer/objectExplorerProvider';
|
||||
|
@ -32,6 +32,7 @@ import { ScriptOperation } from '../models/contracts/scripting/scriptingRequest'
|
|||
import { QueryHistoryProvider } from '../queryHistory/queryHistoryProvider';
|
||||
import { QueryHistoryNode } from '../queryHistory/queryHistoryNode';
|
||||
import { DacFxService } from '../dacFxService/dacFxService';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
/**
|
||||
* The main controller class that initializes the extension
|
||||
|
@ -258,7 +259,7 @@ export default class MainController implements vscode.Disposable {
|
|||
/**
|
||||
* Creates a new Object Explorer session
|
||||
*/
|
||||
private async createObjectExplorerSession(connectionCredentials?: IConnectionCredentials): Promise<void> {
|
||||
private async createObjectExplorerSession(connectionCredentials?: IConnectionInfo): Promise<void> {
|
||||
let createSessionPromise = new Deferred<TreeNodeInfo>();
|
||||
const sessionId = await this._objectExplorerProvider.createSession(createSessionPromise, connectionCredentials, this._context);
|
||||
if (sessionId) {
|
||||
|
@ -339,7 +340,7 @@ export default class MainController implements vscode.Disposable {
|
|||
let profile = <IConnectionProfile>node.parentNode.connectionCredentials;
|
||||
profile = await self.connectionManager.connectionUI.promptForRetryCreateProfile(profile);
|
||||
if (profile) {
|
||||
node.parentNode.connectionCredentials = <IConnectionCredentials>profile;
|
||||
node.parentNode.connectionCredentials = <IConnectionInfo>profile;
|
||||
self._objectExplorerProvider.updateNode(node.parentNode);
|
||||
self._objectExplorerProvider.signInNodeServer(node.parentNode);
|
||||
return self._objectExplorerProvider.refresh(undefined);
|
||||
|
|
|
@ -29,6 +29,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<IExten
|
|||
vscode.commands.registerCommand('mssql.getControllerForTests', () => controller);
|
||||
await controller.activate();
|
||||
return {
|
||||
promptForConnection: () => {
|
||||
return controller.connectionManager.connectionUI.promptForConnection();
|
||||
},
|
||||
dacFx: controller.dacFxService
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
'use strict';
|
||||
import LocalizedConstants = require('../constants/localizedConstants');
|
||||
import { ConnectionDetails } from './contracts/connection';
|
||||
import { IConnectionCredentials, IConnectionProfile, AuthenticationTypes } from './interfaces';
|
||||
import { IConnectionProfile, AuthenticationTypes } from './interfaces';
|
||||
import { ConnectionStore } from './connectionStore';
|
||||
import * as utils from './utils';
|
||||
import { QuestionTypes, IQuestion, IPrompter, INameValueChoice } from '../prompts/question';
|
||||
import SqlToolsServerClient from '../languageservice/serviceclient';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
// Concrete implementation of the IConnectionCredentials interface
|
||||
export class ConnectionCredentials implements IConnectionCredentials {
|
||||
export class ConnectionCredentials implements IConnectionInfo {
|
||||
public server: string;
|
||||
public database: string;
|
||||
public user: string;
|
||||
|
@ -50,7 +51,7 @@ export class ConnectionCredentials implements IConnectionCredentials {
|
|||
/**
|
||||
* Create a connection details contract from connection credentials.
|
||||
*/
|
||||
public static createConnectionDetails(credentials: IConnectionCredentials): ConnectionDetails {
|
||||
public static createConnectionDetails(credentials: IConnectionInfo): ConnectionDetails {
|
||||
let details: ConnectionDetails = new ConnectionDetails();
|
||||
|
||||
details.options['connectionString'] = credentials.connectionString;
|
||||
|
@ -91,17 +92,17 @@ export class ConnectionCredentials implements IConnectionCredentials {
|
|||
}
|
||||
|
||||
public static async ensureRequiredPropertiesSet(
|
||||
credentials: IConnectionCredentials,
|
||||
credentials: IConnectionInfo,
|
||||
isProfile: boolean,
|
||||
isPasswordRequired: boolean,
|
||||
wasPasswordEmptyInConfigFile: boolean,
|
||||
prompter: IPrompter,
|
||||
connectionStore: ConnectionStore,
|
||||
defaultProfileValues?: IConnectionCredentials): Promise<IConnectionCredentials> {
|
||||
defaultProfileValues?: IConnectionInfo): Promise<IConnectionInfo> {
|
||||
|
||||
let questions: IQuestion[] = await ConnectionCredentials.getRequiredCredentialValuesQuestions(credentials, false,
|
||||
isPasswordRequired, connectionStore, defaultProfileValues);
|
||||
let unprocessedCredentials: IConnectionCredentials = Object.assign({}, credentials);
|
||||
let unprocessedCredentials: IConnectionInfo = Object.assign({}, credentials);
|
||||
|
||||
// Potentially ask to save password
|
||||
questions.push({
|
||||
|
@ -160,11 +161,11 @@ export class ConnectionCredentials implements IConnectionCredentials {
|
|||
|
||||
// gets a set of questions that ensure all required and core values are set
|
||||
protected static async getRequiredCredentialValuesQuestions(
|
||||
credentials: IConnectionCredentials,
|
||||
credentials: IConnectionInfo,
|
||||
promptForDbName: boolean,
|
||||
isPasswordRequired: boolean,
|
||||
connectionStore: ConnectionStore,
|
||||
defaultProfileValues?: IConnectionCredentials): Promise<IQuestion[]> {
|
||||
defaultProfileValues?: IConnectionInfo): Promise<IQuestion[]> {
|
||||
|
||||
let authenticationChoices: INameValueChoice[] = ConnectionCredentials.getAuthenticationTypesChoice();
|
||||
|
||||
|
@ -252,7 +253,7 @@ export class ConnectionCredentials implements IConnectionCredentials {
|
|||
}
|
||||
|
||||
// Detect if a given value is a server name or a connection string, and assign the result accordingly
|
||||
private static processServerOrConnectionString(value: string, credentials: IConnectionCredentials): void {
|
||||
private static processServerOrConnectionString(value: string, credentials: IConnectionInfo): void {
|
||||
// If the value contains a connection string server name key, assume it is a connection string
|
||||
const dataSourceKeys = ['data source=', 'server=', 'address=', 'addr=', 'network address='];
|
||||
let isConnectionString = dataSourceKeys.some(key => value.toLowerCase().indexOf(key) !== -1);
|
||||
|
@ -264,13 +265,13 @@ export class ConnectionCredentials implements IConnectionCredentials {
|
|||
}
|
||||
}
|
||||
|
||||
private static shouldPromptForUser(credentials: IConnectionCredentials): boolean {
|
||||
private static shouldPromptForUser(credentials: IConnectionInfo): boolean {
|
||||
return utils.isEmpty(credentials.user) && ConnectionCredentials.isPasswordBasedCredential(credentials);
|
||||
}
|
||||
|
||||
// Prompt for password if this is a password based credential and the password for the profile was empty
|
||||
// and not explicitly set as empty. If it was explicitly set as empty, only prompt if pw not saved
|
||||
public static shouldPromptForPassword(credentials: IConnectionCredentials): boolean {
|
||||
public static shouldPromptForPassword(credentials: IConnectionInfo): boolean {
|
||||
let isSavedEmptyPassword: boolean = (<IConnectionProfile>credentials).emptyPasswordInput
|
||||
&& (<IConnectionProfile>credentials).savePassword;
|
||||
|
||||
|
@ -280,7 +281,7 @@ export class ConnectionCredentials implements IConnectionCredentials {
|
|||
|
||||
}
|
||||
|
||||
public static isPasswordBasedCredential(credentials: IConnectionCredentials): boolean {
|
||||
public static isPasswordBasedCredential(credentials: IConnectionInfo): boolean {
|
||||
// TODO consider enum based verification and handling of AD auth here in the future
|
||||
let authenticationType = credentials.authenticationType;
|
||||
if (typeof credentials.authenticationType === 'undefined') {
|
||||
|
|
|
@ -10,6 +10,7 @@ import Interfaces = require('./interfaces');
|
|||
import { IConnectionProfile } from '../models/interfaces';
|
||||
import * as ConnectionContracts from '../models/contracts/connection';
|
||||
import * as Utils from './utils';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
/**
|
||||
* Sets sensible defaults for key connection properties, especially
|
||||
|
@ -19,7 +20,7 @@ import * as Utils from './utils';
|
|||
* @param {Interfaces.IConnectionCredentials} connCreds connection to be fixed up
|
||||
* @returns {Interfaces.IConnectionCredentials} the updated connection
|
||||
*/
|
||||
export function fixupConnectionCredentials(connCreds: Interfaces.IConnectionCredentials): Interfaces.IConnectionCredentials {
|
||||
export function fixupConnectionCredentials(connCreds: IConnectionInfo): IConnectionInfo {
|
||||
if (!connCreds.server) {
|
||||
connCreds.server = '';
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ function isAzureDatabase(server: string): boolean {
|
|||
* @param {Interfaces.CredentialsQuickPickItemType} itemType type of quickpick item to display - this influences the icon shown to the user
|
||||
* @returns {string} user readable label
|
||||
*/
|
||||
export function getPicklistLabel(connCreds: Interfaces.IConnectionCredentials, itemType: Interfaces.CredentialsQuickPickItemType): string {
|
||||
export function getPicklistLabel(connCreds: IConnectionInfo, itemType: Interfaces.CredentialsQuickPickItemType): string {
|
||||
let profile: Interfaces.IConnectionProfile = <Interfaces.IConnectionProfile> connCreds;
|
||||
|
||||
if (profile.profileName) {
|
||||
|
@ -92,7 +93,7 @@ export function getPicklistLabel(connCreds: Interfaces.IConnectionCredentials, i
|
|||
* @param {Interfaces.IConnectionCredentials} connCreds connection
|
||||
* @returns {string} description
|
||||
*/
|
||||
export function getPicklistDescription(connCreds: Interfaces.IConnectionCredentials): string {
|
||||
export function getPicklistDescription(connCreds: IConnectionInfo): string {
|
||||
let desc: string = `[${getConnectionDisplayString(connCreds)}]`;
|
||||
return desc;
|
||||
}
|
||||
|
@ -104,7 +105,7 @@ export function getPicklistDescription(connCreds: Interfaces.IConnectionCredenti
|
|||
* @param {Interfaces.IConnectionCredentials} connCreds connection
|
||||
* @returns {string} details
|
||||
*/
|
||||
export function getPicklistDetails(connCreds: Interfaces.IConnectionCredentials): string {
|
||||
export function getPicklistDetails(connCreds: IConnectionInfo): string {
|
||||
// In the current spec this is left empty intentionally. Leaving the method as this may change in the future
|
||||
return undefined;
|
||||
}
|
||||
|
@ -117,7 +118,7 @@ export function getPicklistDetails(connCreds: Interfaces.IConnectionCredentials)
|
|||
* @param {Interfaces.IConnectionCredentials} conn connection
|
||||
* @returns {string} display string that can be used in status view or other locations
|
||||
*/
|
||||
export function getConnectionDisplayString(creds: Interfaces.IConnectionCredentials): string {
|
||||
export function getConnectionDisplayString(creds: IConnectionInfo): string {
|
||||
// Update the connection text
|
||||
let text: string;
|
||||
if (creds.connectionString) {
|
||||
|
@ -163,7 +164,7 @@ function appendIfNotEmpty(connectionText: string, value: string): string {
|
|||
* @param {string} [defaultValue] optional default value to use if username is empty and this is not an Integrated auth profile
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getUserNameOrDomainLogin(creds: Interfaces.IConnectionCredentials, defaultValue?: string): string {
|
||||
export function getUserNameOrDomainLogin(creds: IConnectionInfo, defaultValue?: string): string {
|
||||
if (!defaultValue) {
|
||||
defaultValue = '';
|
||||
}
|
||||
|
@ -182,7 +183,7 @@ export function getUserNameOrDomainLogin(creds: Interfaces.IConnectionCredential
|
|||
* @param {Interfaces.IConnectionCredentials} connCreds connection
|
||||
* @returns {string} tooltip
|
||||
*/
|
||||
export function getTooltip(connCreds: Interfaces.IConnectionCredentials, serverInfo?: ConnectionContracts.ServerInfo): string {
|
||||
export function getTooltip(connCreds: IConnectionInfo, serverInfo?: ConnectionContracts.ServerInfo): string {
|
||||
let tooltip: string =
|
||||
connCreds.connectionString ? 'Connection string: ' + connCreds.connectionString + '\r\n' :
|
||||
('Server name: ' + connCreds.server + '\r\n' +
|
||||
|
|
|
@ -11,12 +11,13 @@ import ConnInfo = require('./connectionInfo');
|
|||
import Utils = require('../models/utils');
|
||||
import ValidationException from '../utils/validationException';
|
||||
import { ConnectionCredentials } from '../models/connectionCredentials';
|
||||
import { IConnectionCredentials, IConnectionProfile, IConnectionCredentialsQuickPickItem, CredentialsQuickPickItemType, AuthenticationTypes } from '../models/interfaces';
|
||||
import { IConnectionProfile, IConnectionCredentialsQuickPickItem, CredentialsQuickPickItemType, AuthenticationTypes } from '../models/interfaces';
|
||||
import { ICredentialStore } from '../credentialstore/icredentialstore';
|
||||
import { CredentialStore } from '../credentialstore/credentialstore';
|
||||
import { IConnectionConfig } from '../connectionconfig/iconnectionconfig';
|
||||
import { ConnectionConfig } from '../connectionconfig/connectionconfig';
|
||||
import VscodeWrapper from '../controllers/vscodeWrapper';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
/**
|
||||
* Manages the connections list including saved profiles and the most recently used connections
|
||||
|
@ -52,7 +53,7 @@ export class ConnectionStore {
|
|||
public static get CRED_PROFILE_USER(): string { return CredentialsQuickPickItemType[CredentialsQuickPickItemType.Profile]; }
|
||||
public static get CRED_MRU_USER(): string { return CredentialsQuickPickItemType[CredentialsQuickPickItemType.Mru]; }
|
||||
|
||||
public static formatCredentialIdForCred(creds: IConnectionCredentials, itemType?: CredentialsQuickPickItemType): string {
|
||||
public static formatCredentialIdForCred(creds: IConnectionInfo, itemType?: CredentialsQuickPickItemType): string {
|
||||
if (Utils.isEmpty(creds)) {
|
||||
throw new ValidationException('Missing Connection which is required');
|
||||
}
|
||||
|
@ -162,7 +163,7 @@ export class ConnectionStore {
|
|||
* Lookup credential store
|
||||
* @param connectionCredentials Connection credentials of profile for password lookup
|
||||
*/
|
||||
public async lookupPassword(connectionCredentials: IConnectionCredentials, isConnectionString: boolean = false): Promise<string> {
|
||||
public async lookupPassword(connectionCredentials: IConnectionInfo, isConnectionString: boolean = false): Promise<string> {
|
||||
const credentialId = ConnectionStore.formatCredentialId(
|
||||
connectionCredentials.server, connectionCredentials.database,
|
||||
connectionCredentials.user, ConnectionStore.CRED_PROFILE_USER, isConnectionString);
|
||||
|
@ -236,10 +237,10 @@ export class ConnectionStore {
|
|||
* 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
|
||||
*
|
||||
* @returns {IConnectionCredentials[]} the array of connections, empty if none are found
|
||||
* @returns {IConnectionInfo[]} the array of connections, empty if none are found
|
||||
*/
|
||||
public getRecentlyUsedConnections(): IConnectionCredentials[] {
|
||||
let configValues = this._context.globalState.get<IConnectionCredentials[]>(Constants.configRecentConnections);
|
||||
public getRecentlyUsedConnections(): IConnectionInfo[] {
|
||||
let configValues = this._context.globalState.get<IConnectionInfo[]>(Constants.configRecentConnections);
|
||||
if (!configValues) {
|
||||
configValues = [];
|
||||
}
|
||||
|
@ -250,10 +251,10 @@ export class ConnectionStore {
|
|||
* Adds a connection to the recently used list.
|
||||
* Password values are stored to a separate credential store if the "savePassword" option is true
|
||||
*
|
||||
* @param {IConnectionCredentials} conn the connection to add
|
||||
* @param {IConnectionInfo} conn the connection to add
|
||||
* @returns {Promise<void>} a Promise that returns when the connection was saved
|
||||
*/
|
||||
public addRecentlyUsed(conn: IConnectionCredentials): Promise<void> {
|
||||
public addRecentlyUsed(conn: IConnectionInfo): Promise<void> {
|
||||
const self = this;
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
// Get all profiles
|
||||
|
@ -264,7 +265,7 @@ export class ConnectionStore {
|
|||
configValues = configValues.filter(value => !Utils.isSameProfile(<IConnectionProfile>value, <IConnectionProfile>conn));
|
||||
|
||||
// Add the connection to the front of the list, taking care to clear out the password field
|
||||
let savedConn: IConnectionCredentials = Object.assign({}, conn, { password: '' });
|
||||
let savedConn: IConnectionInfo = Object.assign({}, conn, { password: '' });
|
||||
configValues.unshift(savedConn);
|
||||
|
||||
// Remove last element if needed
|
||||
|
@ -341,7 +342,7 @@ export class ConnectionStore {
|
|||
return this.doSaveCredential(profile, CredentialsQuickPickItemType.Profile, true);
|
||||
}
|
||||
|
||||
private doSaveCredential(conn: IConnectionCredentials, type: CredentialsQuickPickItemType, isConnectionString: boolean = false): Promise<boolean> {
|
||||
private doSaveCredential(conn: IConnectionInfo, type: CredentialsQuickPickItemType, isConnectionString: boolean = false): Promise<boolean> {
|
||||
let self = this;
|
||||
let password = isConnectionString ? conn.connectionString : conn.password;
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
|
@ -399,7 +400,7 @@ export class ConnectionStore {
|
|||
});
|
||||
}
|
||||
|
||||
private createQuickPickItem(item: IConnectionCredentials, itemType: CredentialsQuickPickItemType): IConnectionCredentialsQuickPickItem {
|
||||
private createQuickPickItem(item: IConnectionInfo, itemType: CredentialsQuickPickItemType): IConnectionCredentialsQuickPickItem {
|
||||
return <IConnectionCredentialsQuickPickItem> {
|
||||
label: ConnInfo.getPicklistLabel(item, itemType),
|
||||
description: ConnInfo.getPicklistDescription(item),
|
||||
|
@ -423,7 +424,7 @@ export class ConnectionStore {
|
|||
/**
|
||||
* Removes password from a saved profile and credential store
|
||||
*/
|
||||
public async removeProfilePassword(connection: IConnectionCredentials): Promise<void> {
|
||||
public async removeProfilePassword(connection: IConnectionInfo): Promise<void> {
|
||||
// if the password is saved in the credential store, remove it
|
||||
let profile = connection as IConnectionProfile;
|
||||
profile.password = '';
|
||||
|
@ -475,7 +476,7 @@ export class ConnectionStore {
|
|||
return quickPickItems;
|
||||
}
|
||||
|
||||
private getConnectionsFromGlobalState<T extends IConnectionCredentials>(configName: string): T[] {
|
||||
private getConnectionsFromGlobalState<T extends IConnectionInfo>(configName: string): T[] {
|
||||
let connections: T[] = [];
|
||||
// read from the global state
|
||||
let configValues = this._context.globalState.get<T[]>(configName);
|
||||
|
@ -483,7 +484,7 @@ export class ConnectionStore {
|
|||
return connections;
|
||||
}
|
||||
|
||||
private mapToQuickPickItems(connections: IConnectionCredentials[], itemType: CredentialsQuickPickItemType): IConnectionCredentialsQuickPickItem[] {
|
||||
private mapToQuickPickItems(connections: IConnectionInfo[], itemType: CredentialsQuickPickItemType): IConnectionCredentialsQuickPickItem[] {
|
||||
return connections.map(c => this.createQuickPickItem(c, itemType));
|
||||
}
|
||||
|
||||
|
@ -493,7 +494,7 @@ export class ConnectionStore {
|
|||
return quickPickItems;
|
||||
}
|
||||
|
||||
private addConnections(connections: IConnectionCredentials[], configValues: IConnectionCredentials[]): void {
|
||||
private addConnections(connections: IConnectionInfo[], configValues: IConnectionInfo[]): void {
|
||||
if (configValues) {
|
||||
for (let index = 0; index < configValues.length; index++) {
|
||||
let element = configValues[index];
|
||||
|
|
|
@ -8,6 +8,7 @@ import { AzureAuthType } from 'ads-adal-library';
|
|||
import vscode = require('vscode');
|
||||
import { AccountStore } from '../azure/accountStore';
|
||||
import Constants = require('../constants/constants');
|
||||
import * as vscodeMssql from 'vscode-mssql';
|
||||
|
||||
// interfaces
|
||||
export enum ContentType {
|
||||
|
@ -55,172 +56,9 @@ export const contentTypes = [
|
|||
Constants.localizedTexts
|
||||
];
|
||||
|
||||
/**
|
||||
* Interface exposed to the user for creating new database connections.
|
||||
*/
|
||||
export interface IConnectionCredentials {
|
||||
/**
|
||||
* server name
|
||||
*/
|
||||
server: string;
|
||||
|
||||
/**
|
||||
* database name
|
||||
*/
|
||||
database: string;
|
||||
|
||||
/**
|
||||
* user name
|
||||
*/
|
||||
user: string;
|
||||
|
||||
/**
|
||||
* password
|
||||
*/
|
||||
password: string;
|
||||
|
||||
/**
|
||||
* email
|
||||
*/
|
||||
email: string;
|
||||
|
||||
/**
|
||||
* accountId
|
||||
*/
|
||||
accountId: string;
|
||||
|
||||
/**
|
||||
* The port number to connect to.
|
||||
*/
|
||||
port: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the authentication to use.
|
||||
*/
|
||||
authenticationType: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the azure account token to use
|
||||
*/
|
||||
azureAccountToken: string;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates whether SQL Server uses SSL encryption for all data sent between the client and server if
|
||||
* the server has a certificate installed.
|
||||
*/
|
||||
encrypt: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets a value that indicates whether the channel will be encrypted while bypassing walking the certificate chain to validate trust.
|
||||
*/
|
||||
trustServerCertificate: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection
|
||||
* if the connection is open or has ever been in an open state.
|
||||
*/
|
||||
persistSecurityInfo: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error.
|
||||
*/
|
||||
connectTimeout: number;
|
||||
|
||||
/**
|
||||
* The number of reconnections attempted after identifying that there was an idle connection failure.
|
||||
*/
|
||||
connectRetryCount: number;
|
||||
|
||||
/**
|
||||
* Amount of time (in seconds) between each reconnection attempt after identifying that there was an idle connection failure.
|
||||
*/
|
||||
connectRetryInterval: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the name of the application associated with the connection string.
|
||||
*/
|
||||
applicationName: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the name of the workstation connecting to SQL Server.
|
||||
*/
|
||||
workstationId: string;
|
||||
|
||||
/**
|
||||
* Declares the application workload type when connecting to a database in an SQL Server Availability Group.
|
||||
*/
|
||||
applicationIntent: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the SQL Server Language record name.
|
||||
*/
|
||||
currentLanguage: string;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates whether the connection will be pooled or explicitly opened every time that the connection is requested.
|
||||
*/
|
||||
pooling: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the maximum number of connections allowed in the connection pool for this specific connection string.
|
||||
*/
|
||||
maxPoolSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the minimum number of connections allowed in the connection pool for this specific connection string.
|
||||
*/
|
||||
minPoolSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the minimum time, in seconds, for the connection to live in the connection pool before being destroyed.
|
||||
*/
|
||||
loadBalanceTimeout: number;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates whether replication is supported using the connection.
|
||||
*/
|
||||
replication: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets a string that contains the name of the primary data file. This includes the full path name of an attachable database.
|
||||
*/
|
||||
attachDbFilename: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the name or address of the partner server to connect to if the primary server is down.
|
||||
*/
|
||||
failoverPartner: string;
|
||||
|
||||
/**
|
||||
* If your application is connecting to an AlwaysOn availability group (AG) on different subnets, setting MultiSubnetFailover=true
|
||||
* provides faster detection of and connection to the (currently) active server.
|
||||
*/
|
||||
multiSubnetFailover: boolean;
|
||||
|
||||
/**
|
||||
* When true, an application can maintain multiple active result sets (MARS).
|
||||
*/
|
||||
multipleActiveResultSets: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the size in bytes of the network packets used to communicate with an instance of SQL Server.
|
||||
*/
|
||||
packetSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets a string value that indicates the type system the application expects.
|
||||
*/
|
||||
typeSystemVersion: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the connection string to use for this connection
|
||||
*/
|
||||
connectionString: string;
|
||||
}
|
||||
|
||||
// A Connection Profile contains all the properties of connection credentials, with additional
|
||||
// optional name and details on whether password should be saved
|
||||
export interface IConnectionProfile extends IConnectionCredentials {
|
||||
export interface IConnectionProfile extends vscodeMssql.IConnectionInfo {
|
||||
profileName: string;
|
||||
savePassword: boolean;
|
||||
emptyPasswordInput: boolean;
|
||||
|
@ -236,7 +74,7 @@ export enum CredentialsQuickPickItemType {
|
|||
NewConnection
|
||||
}
|
||||
export interface IConnectionCredentialsQuickPickItem extends vscode.QuickPickItem {
|
||||
connectionCreds: IConnectionCredentials;
|
||||
connectionCreds: vscodeMssql.IConnectionInfo;
|
||||
quickPickItemType: CredentialsQuickPickItemType;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,12 @@ import * as path from 'path';
|
|||
import * as findRemoveSync from 'find-remove';
|
||||
import vscode = require('vscode');
|
||||
import Constants = require('../constants/constants');
|
||||
import { IAzureSignInQuickPickItem, IConnectionCredentials, IConnectionProfile, AuthenticationTypes } from './interfaces';
|
||||
import { IAzureSignInQuickPickItem, IConnectionProfile, AuthenticationTypes } from './interfaces';
|
||||
import { ExtensionContext } from 'vscode';
|
||||
import LocalizedConstants = require('../constants/localizedConstants');
|
||||
import fs = require('fs');
|
||||
import { AzureAuthType } from 'ads-adal-library';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
// CONSTANTS //////////////////////////////////////////////////////////////////////////////////////
|
||||
const msInH = 3.6e6;
|
||||
|
@ -270,11 +271,11 @@ export function isSameProfile(currentProfile: IConnectionProfile, expectedProfil
|
|||
* match on all key properties (connectionString or server, db, auth type, user) being identical.
|
||||
* Other properties are ignored for this purpose
|
||||
*
|
||||
* @param {IConnectionCredentials} conn the connection to check
|
||||
* @param {IConnectionCredentials} expectedConn the connection to try to match
|
||||
* @param {IConnectionInfo} conn the connection to check
|
||||
* @param {IConnectionInfo} expectedConn the connection to try to match
|
||||
* @returns boolean that is true if the connections match
|
||||
*/
|
||||
export function isSameConnection(conn: IConnectionCredentials, expectedConn: IConnectionCredentials): boolean {
|
||||
export function isSameConnection(conn: IConnectionInfo, expectedConn: IConnectionInfo): boolean {
|
||||
return (conn.connectionString || expectedConn.connectionString) ? conn.connectionString === expectedConn.connectionString :
|
||||
expectedConn.server === conn.server
|
||||
&& isSameDatabase(expectedConn.database, conn.database)
|
||||
|
|
|
@ -7,8 +7,8 @@ import * as vscode from 'vscode';
|
|||
import ConnectionManager from '../controllers/connectionManager';
|
||||
import { ObjectExplorerService } from './objectExplorerService';
|
||||
import { TreeNodeInfo } from './treeNodeInfo';
|
||||
import { IConnectionCredentials } from '../models/interfaces';
|
||||
import { Deferred } from '../protocol';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
export class ObjectExplorerProvider implements vscode.TreeDataProvider<any> {
|
||||
|
||||
|
@ -37,7 +37,7 @@ export class ObjectExplorerProvider implements vscode.TreeDataProvider<any> {
|
|||
}
|
||||
}
|
||||
|
||||
async createSession(promise: Deferred<TreeNodeInfo>, connectionCredentials?: IConnectionCredentials, context?: vscode.ExtensionContext): Promise<string> {
|
||||
async createSession(promise: Deferred<TreeNodeInfo>, connectionCredentials?: IConnectionInfo, context?: vscode.ExtensionContext): Promise<string> {
|
||||
return this._objectExplorerService.createSession(promise, connectionCredentials, context);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ export class ObjectExplorerProvider implements vscode.TreeDataProvider<any> {
|
|||
return this._objectExplorerService.expandNode(node, sessionId, promise);
|
||||
}
|
||||
|
||||
public getConnectionCredentials(sessionId: string): IConnectionCredentials {
|
||||
public getConnectionCredentials(sessionId: string): IConnectionInfo {
|
||||
if (sessionId) {
|
||||
return this._objectExplorerService.getConnectionCredentials(sessionId);
|
||||
}
|
||||
|
@ -68,11 +68,11 @@ export class ObjectExplorerProvider implements vscode.TreeDataProvider<any> {
|
|||
this._objectExplorerService.updateNode(node);
|
||||
}
|
||||
|
||||
public async removeConnectionNodes(connections: IConnectionCredentials[]): Promise<void> {
|
||||
public async removeConnectionNodes(connections: IConnectionInfo[]): Promise<void> {
|
||||
await this._objectExplorerService.removeConnectionNodes(connections);
|
||||
}
|
||||
|
||||
public addDisconnectedNode(connectionCredentials: IConnectionCredentials): void {
|
||||
public addDisconnectedNode(connectionCredentials: IConnectionInfo): void {
|
||||
this._objectExplorerService.addDisconnectedNode(connectionCredentials);
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ export class ObjectExplorerProvider implements vscode.TreeDataProvider<any> {
|
|||
return this._objectExplorerExists;
|
||||
}
|
||||
|
||||
public get rootNodeConnections(): IConnectionCredentials[] {
|
||||
public get rootNodeConnections(): IConnectionInfo[] {
|
||||
return this._objectExplorerService.rootNodeConnections;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { TreeItemCollapsibleState } from 'vscode';
|
|||
import { RefreshRequest, RefreshParams } from '../models/contracts/objectExplorer/refreshSessionRequest';
|
||||
import { CloseSessionRequest, CloseSessionParams } from '../models/contracts/objectExplorer/closeSessionRequest';
|
||||
import { TreeNodeInfo } from './treeNodeInfo';
|
||||
import { AuthenticationTypes, IConnectionCredentials, IConnectionProfile } from '../models/interfaces';
|
||||
import { AuthenticationTypes, IConnectionProfile } from '../models/interfaces';
|
||||
import LocalizedConstants = require('../constants/localizedConstants');
|
||||
import { AddConnectionTreeNode } from './addConnectionTreeNode';
|
||||
import { AccountSignInTreeNode } from './accountSignInTreeNode';
|
||||
|
@ -24,8 +24,8 @@ import { ObjectExplorerUtils } from './objectExplorerUtils';
|
|||
import Utils = require('../models/utils');
|
||||
import { ConnectionCredentials } from '../models/connectionCredentials';
|
||||
import { ConnectionProfile } from '../models/connectionProfile';
|
||||
import { AzureController } from '../azure/azureController';
|
||||
import providerSettings from '../azure/providerSettings';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
export class ObjectExplorerService {
|
||||
|
||||
|
@ -34,7 +34,7 @@ export class ObjectExplorerService {
|
|||
private _treeNodeToChildrenMap: Map<vscode.TreeItem, vscode.TreeItem[]>;
|
||||
private _nodePathToNodeLabelMap: Map<string, string>;
|
||||
private _rootTreeNodeArray: Array<TreeNodeInfo>;
|
||||
private _sessionIdToConnectionCredentialsMap: Map<string, IConnectionCredentials>;
|
||||
private _sessionIdToConnectionCredentialsMap: Map<string, IConnectionInfo>;
|
||||
private _expandParamsToTreeNodeInfoMap: Map<ExpandParams, TreeNodeInfo>;
|
||||
|
||||
// Deferred promise maps
|
||||
|
@ -46,7 +46,7 @@ export class ObjectExplorerService {
|
|||
this._client = this._connectionManager.client;
|
||||
this._treeNodeToChildrenMap = new Map<vscode.TreeItem, vscode.TreeItem[]>();
|
||||
this._rootTreeNodeArray = new Array<TreeNodeInfo>();
|
||||
this._sessionIdToConnectionCredentialsMap = new Map<string, IConnectionCredentials>();
|
||||
this._sessionIdToConnectionCredentialsMap = new Map<string, IConnectionInfo>();
|
||||
this._nodePathToNodeLabelMap = new Map<string, string>();
|
||||
this._sessionIdToPromiseMap = new Map<string, Deferred<vscode.TreeItem>>();
|
||||
this._expandParamsToPromiseMap = new Map<ExpandParams, Deferred<TreeNodeInfo[]>>();
|
||||
|
@ -379,11 +379,11 @@ export class ObjectExplorerService {
|
|||
* OE out of
|
||||
* @param connectionCredentials Connection Credentials for a node
|
||||
*/
|
||||
public async createSession(promise: Deferred<vscode.TreeItem | undefined>, connectionCredentials?: IConnectionCredentials,
|
||||
public async createSession(promise: Deferred<vscode.TreeItem | undefined>, connectionCredentials?: IConnectionInfo,
|
||||
context?: vscode.ExtensionContext): Promise<string> {
|
||||
if (!connectionCredentials) {
|
||||
const connectionUI = this._connectionManager.connectionUI;
|
||||
connectionCredentials = await connectionUI.showConnections(false);
|
||||
connectionCredentials = await connectionUI.createAndSaveProfile();
|
||||
}
|
||||
if (connectionCredentials) {
|
||||
// connection string based credential
|
||||
|
@ -463,7 +463,7 @@ export class ObjectExplorerService {
|
|||
}
|
||||
}
|
||||
|
||||
public getConnectionCredentials(sessionId: string): IConnectionCredentials {
|
||||
public getConnectionCredentials(sessionId: string): IConnectionInfo {
|
||||
if (this._sessionIdToConnectionCredentialsMap.has(sessionId)) {
|
||||
return this._sessionIdToConnectionCredentialsMap.get(sessionId);
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ export class ObjectExplorerService {
|
|||
this.cleanNodeChildren(node);
|
||||
}
|
||||
|
||||
public async removeConnectionNodes(connections: IConnectionCredentials[]): Promise<void> {
|
||||
public async removeConnectionNodes(connections: IConnectionInfo[]): Promise<void> {
|
||||
for (let conn of connections) {
|
||||
for (let node of this._rootTreeNodeArray) {
|
||||
if (Utils.isSameConnection(node.connectionCredentials, conn)) {
|
||||
|
@ -529,7 +529,7 @@ export class ObjectExplorerService {
|
|||
}
|
||||
}
|
||||
|
||||
public addDisconnectedNode(connectionCredentials: IConnectionCredentials): void {
|
||||
public addDisconnectedNode(connectionCredentials: IConnectionInfo): void {
|
||||
const label = (<IConnectionProfile>connectionCredentials).profileName ?
|
||||
(<IConnectionProfile>connectionCredentials).profileName :
|
||||
this.createNodeLabel(connectionCredentials);
|
||||
|
@ -540,7 +540,7 @@ export class ObjectExplorerService {
|
|||
this.updateNode(node);
|
||||
}
|
||||
|
||||
private createNodeLabel(credentials: IConnectionCredentials): string {
|
||||
private createNodeLabel(credentials: IConnectionInfo): string {
|
||||
let database = credentials.database;
|
||||
const server = credentials.server;
|
||||
const authType = credentials.authenticationType;
|
||||
|
@ -591,7 +591,7 @@ export class ObjectExplorerService {
|
|||
return this._rootTreeNodeArray;
|
||||
}
|
||||
|
||||
public get rootNodeConnections(): IConnectionCredentials[] {
|
||||
public get rootNodeConnections(): IConnectionInfo[] {
|
||||
const connections = this._rootTreeNodeArray.map(node => node.connectionCredentials);
|
||||
return connections;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
import * as vscode from 'vscode';
|
||||
import { NodeInfo } from '../models/contracts/objectExplorer/nodeInfo';
|
||||
import { ObjectExplorerUtils } from './objectExplorerUtils';
|
||||
import { IConnectionCredentials } from '../models/interfaces';
|
||||
import Constants = require('../constants/constants');
|
||||
import { ObjectMetadata } from '../models/contracts/metadata/metadataRequest';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
export class TreeNodeInfo extends vscode.TreeItem {
|
||||
|
||||
|
@ -20,7 +20,7 @@ export class TreeNodeInfo extends vscode.TreeItem {
|
|||
private _errorMessage: string;
|
||||
private _sessionId: string;
|
||||
private _parentNode: TreeNodeInfo;
|
||||
private _connectionCredentials: IConnectionCredentials;
|
||||
private _connectionCredentials: IConnectionInfo;
|
||||
private _metadata: ObjectMetadata;
|
||||
|
||||
constructor(
|
||||
|
@ -31,7 +31,7 @@ export class TreeNodeInfo extends vscode.TreeItem {
|
|||
nodeStatus: string,
|
||||
nodeType: string,
|
||||
sessionId: string,
|
||||
connectionCredentials: IConnectionCredentials,
|
||||
connectionCredentials: IConnectionInfo,
|
||||
parentNode: TreeNodeInfo,
|
||||
objectMetadata?: ObjectMetadata
|
||||
) {
|
||||
|
@ -51,7 +51,7 @@ export class TreeNodeInfo extends vscode.TreeItem {
|
|||
nodeInfo: NodeInfo,
|
||||
sessionId: string,
|
||||
parentNode: TreeNodeInfo,
|
||||
connectionCredentials: IConnectionCredentials,
|
||||
connectionCredentials: IConnectionInfo,
|
||||
label?: string,
|
||||
nodeType?: string): TreeNodeInfo {
|
||||
let type = nodeType ? nodeType : nodeInfo.nodeType;
|
||||
|
@ -97,7 +97,7 @@ export class TreeNodeInfo extends vscode.TreeItem {
|
|||
return this._parentNode;
|
||||
}
|
||||
|
||||
public get connectionCredentials(): IConnectionCredentials {
|
||||
public get connectionCredentials(): IConnectionInfo {
|
||||
return this._connectionCredentials;
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ export class TreeNodeInfo extends vscode.TreeItem {
|
|||
this._parentNode = value;
|
||||
}
|
||||
|
||||
public set connectionCredentials(value: IConnectionCredentials) {
|
||||
public set connectionCredentials(value: IConnectionInfo) {
|
||||
this._connectionCredentials = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,14 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
import vscode = require('vscode');
|
||||
import Constants = require('../constants/constants');
|
||||
import * as vscode from 'vscode';
|
||||
import * as constants from '../constants/constants';
|
||||
import LocalizedConstants = require('../constants/localizedConstants');
|
||||
import { ConnectionCredentials } from '../models/connectionCredentials';
|
||||
import ConnectionManager from '../controllers/connectionManager';
|
||||
import { ConnectionStore } from '../models/connectionStore';
|
||||
import { ConnectionProfile } from '../models/connectionProfile';
|
||||
import { IConnectionCredentials, IConnectionProfile, IConnectionCredentialsQuickPickItem, CredentialsQuickPickItemType } from '../models/interfaces';
|
||||
import { IConnectionProfile, IConnectionCredentialsQuickPickItem, CredentialsQuickPickItemType } from '../models/interfaces';
|
||||
import { INameValueChoice, IQuestion, IPrompter, QuestionTypes } from '../prompts/question';
|
||||
import { Timer } from '../models/utils';
|
||||
import * as Utils from '../models/utils';
|
||||
|
@ -22,8 +21,7 @@ import { AccountStore } from '../azure/accountStore';
|
|||
import { AzureController } from '../azure/azureController';
|
||||
import { IAccount } from '../models/contracts/azure/accountInterfaces';
|
||||
import providerSettings from '../azure/providerSettings';
|
||||
import { FirewallService } from '../firewall/firewallService';
|
||||
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
/**
|
||||
* The different tasks for managing connection profiles.
|
||||
|
@ -81,37 +79,24 @@ export class ConnectionUI {
|
|||
this._errorOutputChannel.show(true);
|
||||
}
|
||||
|
||||
// Helper to let user choose a connection from a picklist
|
||||
// Return the ConnectionInfo for the user's choice
|
||||
public showConnections(showExistingConnections: boolean = true): Promise<IConnectionCredentials> {
|
||||
const self = this;
|
||||
return new Promise<IConnectionCredentials>((resolve, reject) => {
|
||||
let picklist: IConnectionCredentialsQuickPickItem[];
|
||||
if (showExistingConnections) {
|
||||
picklist = self._connectionStore.getPickListItems();
|
||||
} else {
|
||||
picklist = [];
|
||||
}
|
||||
if (picklist.length === 0) {
|
||||
// No connections - go to the create profile workflow
|
||||
self.createAndSaveProfile().then(resolvedProfile => {
|
||||
resolve(resolvedProfile);
|
||||
});
|
||||
} else {
|
||||
// We have recent connections - show them in a picklist
|
||||
self.promptItemChoice({
|
||||
placeHolder: LocalizedConstants.recentConnectionsPlaceholder,
|
||||
matchOnDescription: true
|
||||
}, picklist)
|
||||
.then(selection => {
|
||||
if (selection) {
|
||||
resolve(self.handleSelectedConnection(selection));
|
||||
} else {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper to let user choose a connection from a picklist, or to create a new connection.
|
||||
* Return the ConnectionInfo for the user's choice
|
||||
* @returns The connection picked or created.
|
||||
*/
|
||||
public async promptForConnection(): Promise<IConnectionInfo | undefined> {
|
||||
let picklist = this._connectionStore.getPickListItems();
|
||||
// We have recent connections - show them in a picklist
|
||||
const selection = await this.promptItemChoice({
|
||||
placeHolder: LocalizedConstants.recentConnectionsPlaceholder,
|
||||
matchOnDescription: true
|
||||
}, picklist);
|
||||
if (selection) {
|
||||
return this.handleSelectedConnection(selection);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public promptLanguageFlavor(): Promise<string> {
|
||||
|
@ -121,12 +106,12 @@ export class ConnectionUI {
|
|||
{
|
||||
label: LocalizedConstants.mssqlProviderName,
|
||||
description: LocalizedConstants.flavorDescriptionMssql,
|
||||
providerId: Constants.mssqlProviderName
|
||||
providerId: constants.mssqlProviderName
|
||||
},
|
||||
{
|
||||
label: LocalizedConstants.noneProviderName,
|
||||
description: LocalizedConstants.flavorDescriptionNone,
|
||||
providerId: Constants.noneProviderName
|
||||
providerId: constants.noneProviderName
|
||||
}
|
||||
];
|
||||
self.promptItemChoice({
|
||||
|
@ -158,7 +143,7 @@ export class ConnectionUI {
|
|||
* Helper for waitForLanguageModeToBeSql() method.
|
||||
*/
|
||||
private waitForLanguageModeToBeSqlHelper(resolve: any, timer: Timer): void {
|
||||
if (timer.getDuration() > Constants.timeToWaitForLanguageModeChange) {
|
||||
if (timer.getDuration() > constants.timeToWaitForLanguageModeChange) {
|
||||
resolve(false);
|
||||
} else if (this.vscodeWrapper.isEditingSqlFile) {
|
||||
resolve(true);
|
||||
|
@ -248,13 +233,13 @@ export class ConnectionUI {
|
|||
|
||||
// Helper to let the user choose a database on the current server
|
||||
public showDatabasesOnCurrentServer(
|
||||
currentCredentials: IConnectionCredentials,
|
||||
databaseNames: Array<string>): Promise<IConnectionCredentials> {
|
||||
currentCredentials: IConnectionInfo,
|
||||
databaseNames: Array<string>): Promise<IConnectionInfo> {
|
||||
const self = this;
|
||||
return new Promise<IConnectionCredentials>((resolve, reject) => {
|
||||
return new Promise<IConnectionInfo>((resolve, reject) => {
|
||||
const pickListItems: vscode.QuickPickItem[] = databaseNames.map(name => {
|
||||
let newCredentials: IConnectionCredentials = <any>{};
|
||||
Object.assign<IConnectionCredentials, IConnectionCredentials>(newCredentials, currentCredentials);
|
||||
let newCredentials: IConnectionInfo = <any>{};
|
||||
Object.assign<IConnectionInfo, IConnectionInfo>(newCredentials, currentCredentials);
|
||||
if (newCredentials['profileName']) {
|
||||
delete newCredentials['profileName'];
|
||||
}
|
||||
|
@ -311,9 +296,9 @@ export class ConnectionUI {
|
|||
});
|
||||
}
|
||||
|
||||
public createProfileWithDifferentCredentials(connection: IConnectionCredentials): Promise<IConnectionCredentials> {
|
||||
public createProfileWithDifferentCredentials(connection: IConnectionInfo): Promise<IConnectionInfo> {
|
||||
|
||||
return new Promise<IConnectionCredentials>((resolve, reject) => {
|
||||
return new Promise<IConnectionInfo>((resolve, reject) => {
|
||||
this.promptForRetryConnectWithDifferentCredentials().then(result => {
|
||||
if (result) {
|
||||
let connectionWithoutCredentials = Object.assign({}, connection, { user: '', password: '', emptyPasswordInput: false });
|
||||
|
@ -336,11 +321,11 @@ export class ConnectionUI {
|
|||
});
|
||||
}
|
||||
|
||||
private handleSelectedConnection(selection: IConnectionCredentialsQuickPickItem): Promise<IConnectionCredentials> {
|
||||
private handleSelectedConnection(selection: IConnectionCredentialsQuickPickItem): Promise<IConnectionInfo> {
|
||||
const self = this;
|
||||
return new Promise<IConnectionCredentials>((resolve, reject) => {
|
||||
return new Promise<IConnectionInfo>((resolve, reject) => {
|
||||
if (selection !== undefined) {
|
||||
let connectFunc: Promise<IConnectionCredentials>;
|
||||
let connectFunc: Promise<IConnectionInfo>;
|
||||
if (selection.quickPickItemType === CredentialsQuickPickItemType.NewConnection) {
|
||||
// call the workflow to create a new connection
|
||||
connectFunc = self.createAndSaveProfile();
|
||||
|
@ -566,7 +551,7 @@ export class ConnectionUI {
|
|||
placeHolder: startIpAddress,
|
||||
default: startIpAddress,
|
||||
validate: (value: string) => {
|
||||
if (!Number.parseFloat(value) || !value.match(Constants.ipAddressRegex)) {
|
||||
if (!Number.parseFloat(value) || !value.match(constants.ipAddressRegex)) {
|
||||
return LocalizedConstants.msgInvalidIpAddress;
|
||||
}
|
||||
}
|
||||
|
@ -577,7 +562,7 @@ export class ConnectionUI {
|
|||
message: LocalizedConstants.endIpAddressPrompt,
|
||||
placeHolder: startIpAddress,
|
||||
validate: (value: string) => {
|
||||
if (!Number.parseFloat(value) || !value.match(Constants.ipAddressRegex) ||
|
||||
if (!Number.parseFloat(value) || !value.match(constants.ipAddressRegex) ||
|
||||
(Number.parseFloat(value) > Number.parseFloat(startIpAddress))) {
|
||||
return LocalizedConstants.msgInvalidIpAddress;
|
||||
}
|
||||
|
@ -636,10 +621,10 @@ export class ConnectionUI {
|
|||
});
|
||||
}
|
||||
|
||||
private fillOrPromptForMissingInfo(selection: IConnectionCredentialsQuickPickItem): Promise<IConnectionCredentials> {
|
||||
private fillOrPromptForMissingInfo(selection: IConnectionCredentialsQuickPickItem): Promise<IConnectionInfo> {
|
||||
// If a connection string is present, don't prompt for any other info
|
||||
if (selection.connectionCreds.connectionString) {
|
||||
return new Promise<IConnectionCredentials> ((resolve, reject) => {
|
||||
return new Promise<IConnectionInfo> ((resolve, reject) => {
|
||||
resolve(selection.connectionCreds);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import Constants = require('../constants/constants');
|
|||
import LocalizedConstants = require('../constants/localizedConstants');
|
||||
import ConnInfo = require('../models/connectionInfo');
|
||||
import * as ConnectionContracts from '../models/contracts/connection';
|
||||
import Interfaces = require('../models/interfaces');
|
||||
import * as Utils from '../models/utils';
|
||||
import VscodeWrapper from '../controllers/vscodeWrapper';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
// Status bar element for each file in the editor
|
||||
class FileStatusBar {
|
||||
|
@ -146,7 +146,7 @@ export default class StatusView implements vscode.Disposable {
|
|||
this.showStatusBarItem(fileUri, bar.statusLanguageFlavor);
|
||||
}
|
||||
|
||||
public connecting(fileUri: string, connCreds: Interfaces.IConnectionCredentials): void {
|
||||
public connecting(fileUri: string, connCreds: IConnectionInfo): void {
|
||||
let bar = this.getStatusBar(fileUri);
|
||||
bar.statusConnection.text = LocalizedConstants.connectingLabel;
|
||||
bar.statusConnection.command = Constants.cmdDisconnect;
|
||||
|
@ -155,7 +155,7 @@ export default class StatusView implements vscode.Disposable {
|
|||
this.showProgress(fileUri, LocalizedConstants.connectingLabel, bar.statusConnection);
|
||||
}
|
||||
|
||||
public connectSuccess(fileUri: string, connCreds: Interfaces.IConnectionCredentials, serverInfo: ConnectionContracts.ServerInfo): void {
|
||||
public connectSuccess(fileUri: string, connCreds: IConnectionInfo, serverInfo: ConnectionContracts.ServerInfo): void {
|
||||
let bar = this.getStatusBar(fileUri);
|
||||
bar.statusConnection.command = Constants.cmdChooseDatabase;
|
||||
bar.statusConnection.text = ConnInfo.getConnectionDisplayString(connCreds);
|
||||
|
@ -164,7 +164,7 @@ export default class StatusView implements vscode.Disposable {
|
|||
this.sqlCmdModeChanged(fileUri, false);
|
||||
}
|
||||
|
||||
public connectError(fileUri: string, credentials: Interfaces.IConnectionCredentials, error: ConnectionContracts.ConnectionCompleteParams): void {
|
||||
public connectError(fileUri: string, credentials: IConnectionInfo, error: ConnectionContracts.ConnectionCompleteParams): void {
|
||||
let bar = this.getStatusBar(fileUri);
|
||||
bar.statusConnection.command = Constants.cmdConnect;
|
||||
bar.statusConnection.text = LocalizedConstants.connectErrorLabel;
|
||||
|
|
|
@ -16,10 +16,11 @@ import { ConnectionStore } from '../src/models/connectionStore';
|
|||
import { ConnectionCredentials } from '../src/models/connectionCredentials';
|
||||
import { IPrompter, IQuestion} from '../src/prompts/question';
|
||||
import { TestPrompter } from './stubs';
|
||||
import { IConnectionProfile, IConnectionCredentials } from '../src/models/interfaces';
|
||||
import { IConnectionProfile } from '../src/models/interfaces';
|
||||
import VscodeWrapper from '../src/controllers/vscodeWrapper';
|
||||
|
||||
import assert = require('assert');
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
suite('ConnectionCredentials Tests', () => {
|
||||
let defaultProfile: interfaces.IConnectionProfile;
|
||||
|
@ -54,7 +55,7 @@ suite('ConnectionCredentials Tests', () => {
|
|||
});
|
||||
|
||||
// ConnectProfile sets up a connection call to ensureRequiredPropertiesSet with the provided profile
|
||||
function connectProfile( profile: IConnectionProfile, emptyPassword: boolean): Promise<IConnectionCredentials> {
|
||||
function connectProfile( profile: IConnectionProfile, emptyPassword: boolean): Promise<IConnectionInfo> {
|
||||
// Setup input paramaters
|
||||
let isProfile: boolean = true;
|
||||
let isPasswordRequired: boolean = false;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
'use strict';
|
||||
import vscode = require('vscode');
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import { IConnectionCredentials, IConnectionProfile, AuthenticationTypes } from '../src/models/interfaces';
|
||||
import { IConnectionProfile, AuthenticationTypes } from '../src/models/interfaces';
|
||||
import { ConnectionCredentials } from '../src/models/connectionCredentials';
|
||||
import { ConnectionProfile } from '../src/models/connectionProfile';
|
||||
import { IQuestion, IPrompter, INameValueChoice } from '../src/prompts/question';
|
||||
|
@ -15,13 +15,13 @@ import { ConnectionUI } from '../src/views/connectionUI';
|
|||
import { ConnectionStore } from '../src/models/connectionStore';
|
||||
import ConnectionManager from '../src/controllers/connectionManager';
|
||||
import VscodeWrapper from '../src/controllers/vscodeWrapper';
|
||||
import Constants = require('../src/constants/constants');
|
||||
import LocalizedConstants = require('../src/constants/localizedConstants');
|
||||
import assert = require('assert');
|
||||
import { AccountStore } from '../src/azure/accountStore';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
function createTestCredentials(): IConnectionCredentials {
|
||||
const creds: IConnectionCredentials = {
|
||||
function createTestCredentials(): IConnectionInfo {
|
||||
const creds: IConnectionInfo = {
|
||||
server: 'my-server',
|
||||
database: 'my_db',
|
||||
user: 'sa',
|
||||
|
|
|
@ -10,11 +10,12 @@ import VscodeWrapper from '../src/controllers/vscodeWrapper';
|
|||
import { IPrompter } from '../src/prompts/question';
|
||||
import { ConnectionStore } from '../src/models/connectionStore';
|
||||
import ConnectionManager from '../src/controllers/connectionManager';
|
||||
import { IConnectionProfile, IConnectionCredentials, IConnectionCredentialsQuickPickItem, CredentialsQuickPickItemType } from '../src/models/interfaces';
|
||||
import { IConnectionCredentialsQuickPickItem, CredentialsQuickPickItemType } from '../src/models/interfaces';
|
||||
import { ConnectionProfile } from '../src/models/connectionProfile';
|
||||
import { ConnectionCredentials } from '../src/models/connectionCredentials';
|
||||
import LocalizedConstants = require('../src/constants/localizedConstants');
|
||||
import { AccountStore } from '../src/azure/accountStore';
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
suite('Connection UI tests', () => {
|
||||
|
||||
|
@ -68,7 +69,7 @@ suite('Connection UI tests', () => {
|
|||
let mockConnection = { connectionString: 'test' };
|
||||
prompter.setup(p => p.promptSingle(TypeMoq.It.isAny())).returns(() => Promise.resolve(item));
|
||||
prompter.setup(p => p.prompt(TypeMoq.It.isAny(), true)).returns(() => Promise.resolve(mockConnection));
|
||||
return connectionUI.showConnections(true).then(() => {
|
||||
return connectionUI.promptForConnection().then(() => {
|
||||
connectionStore.verify(c => c.getPickListItems(), TypeMoq.Times.once());
|
||||
prompter.verify(p => p.promptSingle(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
|
@ -85,7 +86,7 @@ suite('Connection UI tests', () => {
|
|||
let mockConnection = { connectionString: 'test' };
|
||||
prompter.setup(p => p.promptSingle(TypeMoq.It.isAny())).returns(() => Promise.resolve(item));
|
||||
prompter.setup(p => p.prompt(TypeMoq.It.isAny(), true)).returns(() => Promise.resolve(mockConnection));
|
||||
return connectionUI.showConnections(true).then(() => {
|
||||
return connectionUI.promptForConnection().then(() => {
|
||||
connectionStore.verify(c => c.getPickListItems(), TypeMoq.Times.once());
|
||||
prompter.verify(p => p.promptSingle(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
|
@ -93,23 +94,12 @@ suite('Connection UI tests', () => {
|
|||
|
||||
test('showConnections with recent but no selection', () => {
|
||||
prompter.setup(p => p.promptSingle(TypeMoq.It.isAny())).returns(() => Promise.resolve(undefined));
|
||||
return connectionUI.showConnections(true).then(() => {
|
||||
return connectionUI.promptForConnection().then(() => {
|
||||
connectionStore.verify(c => c.getPickListItems(), TypeMoq.Times.once());
|
||||
prompter.verify(p => p.promptSingle(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
});
|
||||
|
||||
test('showConnection should not show recent connections if false', () => {
|
||||
let mockProvider = { providerId: 'test' };
|
||||
let mockConnection = { connectionString: 'test' };
|
||||
prompter.setup(p => p.promptSingle(TypeMoq.It.isAny())).returns(() => Promise.resolve(mockProvider));
|
||||
prompter.setup(p => p.prompt(TypeMoq.It.isAny(), true)).returns(() => Promise.resolve(mockConnection));
|
||||
return connectionUI.showConnections(false).then(() => {
|
||||
connectionStore.verify(c => c.getPickListItems(), TypeMoq.Times.never());
|
||||
prompter.verify(p => p.promptSingle(TypeMoq.It.isAny()), TypeMoq.Times.never());
|
||||
});
|
||||
});
|
||||
|
||||
test('promptLanguageFlavor should prompt for a language flavor', () => {
|
||||
let mockProvider = { providerId: 'test' };
|
||||
prompter.setup(p => p.promptSingle(TypeMoq.It.isAny())).returns(() => Promise.resolve(mockProvider));
|
||||
|
|
|
@ -11,14 +11,11 @@ import SqlToolsServiceClient from '../src/languageservice/serviceclient';
|
|||
import { expect, assert } from 'chai';
|
||||
import { TreeNodeInfo } from '../src/objectExplorer/treeNodeInfo';
|
||||
import { ConnectionCredentials } from '../src/models/connectionCredentials';
|
||||
import { Deferred } from '../src/protocol';
|
||||
import { AddConnectionTreeNode } from '../src/objectExplorer/addConnectionTreeNode';
|
||||
import * as LocalizedConstants from '../src/constants/localizedConstants';
|
||||
import { AccountSignInTreeNode } from '../src/objectExplorer/accountSignInTreeNode';
|
||||
import { ConnectTreeNode } from '../src/objectExplorer/connectTreeNode';
|
||||
import { NodeInfo } from '../src/models/contracts/objectExplorer/nodeInfo';
|
||||
import { IConnectionCredentials } from '../src/models/interfaces';
|
||||
import { Type } from '@angular/core';
|
||||
|
||||
suite('Object Explorer Provider Tests', () => {
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
import assert = require('assert');
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import { ExtensionContext, OutputChannel } from 'vscode';
|
||||
import { OutputChannel } from 'vscode';
|
||||
|
||||
import { IPrompter } from '../src/prompts/question';
|
||||
import SqlToolsServiceClient from './../src/languageservice/serviceclient';
|
||||
|
||||
import ConnectionManager from '../src/controllers/connectionManager';
|
||||
import { IConnectionCredentials, AuthenticationTypes } from '../src/models/interfaces';
|
||||
import { AuthenticationTypes } from '../src/models/interfaces';
|
||||
import * as ConnectionContracts from '../src/models/contracts/connection';
|
||||
import * as LanguageServiceContracts from '../src/models/contracts/languageService';
|
||||
import MainController from '../src/controllers/mainController';
|
||||
|
@ -24,6 +24,7 @@ import VscodeWrapper from '../src/controllers/vscodeWrapper';
|
|||
import LocalizedConstants = require('../src/constants/localizedConstants');
|
||||
import { ConnectionUI } from '../src/views/connectionUI';
|
||||
import Constants = require('../src/constants/constants');
|
||||
import { IConnectionInfo } from 'vscode-mssql';
|
||||
|
||||
function createTestConnectionResult(ownerUri?: string): ConnectionContracts.ConnectionCompleteParams {
|
||||
let result = new ConnectionContracts.ConnectionCompleteParams();
|
||||
|
@ -41,8 +42,8 @@ function createTestFailedConnectionResult(ownerUri?: string, error?: number): Co
|
|||
return result;
|
||||
}
|
||||
|
||||
function createTestCredentials(): IConnectionCredentials {
|
||||
const creds: IConnectionCredentials = {
|
||||
function createTestCredentials(): IConnectionInfo {
|
||||
const creds: IConnectionInfo = {
|
||||
server: 'my-server',
|
||||
database: 'my_db',
|
||||
user: 'sa',
|
||||
|
@ -123,7 +124,7 @@ suite('Per File Connection Tests', () => {
|
|||
|
||||
let connectionUIMock = TypeMoq.Mock.ofType(ConnectionUI);
|
||||
connectionUIMock.setup(x => x.promptToChangeLanguageMode()).returns(x => Promise.resolve(true));
|
||||
connectionUIMock.setup(x => x.showConnections()).returns(x => Promise.resolve(connectionCreds));
|
||||
connectionUIMock.setup(x => x.promptForConnection()).returns(x => Promise.resolve(connectionCreds));
|
||||
|
||||
// Return undefined to simulate the scenario that user doesn't want to enter new credentials
|
||||
connectionUIMock.setup(x => x.createProfileWithDifferentCredentials(TypeMoq.It.isAny())).returns(x => Promise.resolve(undefined));
|
||||
|
@ -164,7 +165,7 @@ suite('Per File Connection Tests', () => {
|
|||
|
||||
let connectionUIMock = TypeMoq.Mock.ofType(ConnectionUI);
|
||||
connectionUIMock.setup(x => x.promptToChangeLanguageMode()).returns(x => Promise.resolve(true));
|
||||
connectionUIMock.setup(x => x.showConnections()).returns(x => Promise.resolve(connectionCreds));
|
||||
connectionUIMock.setup(x => x.promptForConnection()).returns(x => Promise.resolve(connectionCreds));
|
||||
|
||||
connectionUIMock.setup(x => x.createProfileWithDifferentCredentials(TypeMoq.It.isAny())).returns(x => Promise.resolve(connectionCreds));
|
||||
let manager: ConnectionManager = createTestConnectionManager(undefined, vscodeWrapperMock.object, undefined, undefined, connectionUIMock.object);
|
||||
|
@ -567,7 +568,7 @@ suite('Per File Connection Tests', () => {
|
|||
let statusViewMock: TypeMoq.IMock<StatusView> = TypeMoq.Mock.ofType(StatusView);
|
||||
let actualDbName = undefined;
|
||||
statusViewMock.setup(x => x.connectSuccess(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
|
||||
.callback((fileUri, creds: IConnectionCredentials, server: ConnectionContracts.ServerInfo) => {
|
||||
.callback((fileUri, creds: IConnectionInfo, server: ConnectionContracts.ServerInfo) => {
|
||||
actualDbName = creds.database;
|
||||
});
|
||||
|
||||
|
@ -586,7 +587,7 @@ suite('Per File Connection Tests', () => {
|
|||
});
|
||||
});
|
||||
|
||||
function createConnectionResultForCreds(connectionCreds: IConnectionCredentials, dbName?: string): ConnectionContracts.ConnectionCompleteParams {
|
||||
function createConnectionResultForCreds(connectionCreds: IConnectionInfo, dbName?: string): ConnectionContracts.ConnectionCompleteParams {
|
||||
let myResult = new ConnectionContracts.ConnectionCompleteParams();
|
||||
if (!dbName) {
|
||||
dbName = connectionCreds.database;
|
||||
|
@ -625,10 +626,10 @@ suite('Per File Connection Tests', () => {
|
|||
|
||||
let statusViewMock: TypeMoq.IMock<StatusView> = TypeMoq.Mock.ofType(StatusView);
|
||||
statusViewMock.setup(x => x.connectSuccess(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
|
||||
.callback((fileUri, creds: IConnectionCredentials) => { return; });
|
||||
.callback((fileUri, creds: IConnectionInfo) => { return; });
|
||||
|
||||
// And we store any DBs saved to recent connections
|
||||
let savedConnection: IConnectionCredentials = undefined;
|
||||
let savedConnection: IConnectionInfo = undefined;
|
||||
let connectionStoreMock = TypeMoq.Mock.ofType(ConnectionStore);
|
||||
connectionStoreMock.setup(x => x.addRecentlyUsed(TypeMoq.It.isAny())).returns( conn => {
|
||||
savedConnection = conn;
|
||||
|
|
|
@ -21,7 +21,177 @@ declare module 'vscode-mssql' {
|
|||
*/
|
||||
export interface IExtension {
|
||||
|
||||
/**
|
||||
* Service for accessing DacFx functionality
|
||||
*/
|
||||
readonly dacFx: IDacFxService;
|
||||
/**
|
||||
* Prompts the user to select an existing connection or create a new one, and then returns the result
|
||||
*/
|
||||
promptForConnection(): Promise<IConnectionInfo | undefined>
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about a database connection
|
||||
*/
|
||||
export interface IConnectionInfo {
|
||||
/**
|
||||
* server name
|
||||
*/
|
||||
server: string;
|
||||
|
||||
/**
|
||||
* database name
|
||||
*/
|
||||
database: string;
|
||||
|
||||
/**
|
||||
* user name
|
||||
*/
|
||||
user: string;
|
||||
|
||||
/**
|
||||
* password
|
||||
*/
|
||||
password: string;
|
||||
|
||||
/**
|
||||
* email
|
||||
*/
|
||||
email: string;
|
||||
|
||||
/**
|
||||
* accountId
|
||||
*/
|
||||
accountId: string;
|
||||
|
||||
/**
|
||||
* The port number to connect to.
|
||||
*/
|
||||
port: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the authentication to use.
|
||||
*/
|
||||
authenticationType: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the azure account token to use
|
||||
*/
|
||||
azureAccountToken: string;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates whether SQL Server uses SSL encryption for all data sent between the client and server if
|
||||
* the server has a certificate installed.
|
||||
*/
|
||||
encrypt: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets a value that indicates whether the channel will be encrypted while bypassing walking the certificate chain to validate trust.
|
||||
*/
|
||||
trustServerCertificate: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection
|
||||
* if the connection is open or has ever been in an open state.
|
||||
*/
|
||||
persistSecurityInfo: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error.
|
||||
*/
|
||||
connectTimeout: number;
|
||||
|
||||
/**
|
||||
* The number of reconnections attempted after identifying that there was an idle connection failure.
|
||||
*/
|
||||
connectRetryCount: number;
|
||||
|
||||
/**
|
||||
* Amount of time (in seconds) between each reconnection attempt after identifying that there was an idle connection failure.
|
||||
*/
|
||||
connectRetryInterval: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the name of the application associated with the connection string.
|
||||
*/
|
||||
applicationName: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the name of the workstation connecting to SQL Server.
|
||||
*/
|
||||
workstationId: string;
|
||||
|
||||
/**
|
||||
* Declares the application workload type when connecting to a database in an SQL Server Availability Group.
|
||||
*/
|
||||
applicationIntent: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the SQL Server Language record name.
|
||||
*/
|
||||
currentLanguage: string;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates whether the connection will be pooled or explicitly opened every time that the connection is requested.
|
||||
*/
|
||||
pooling: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the maximum number of connections allowed in the connection pool for this specific connection string.
|
||||
*/
|
||||
maxPoolSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the minimum number of connections allowed in the connection pool for this specific connection string.
|
||||
*/
|
||||
minPoolSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the minimum time, in seconds, for the connection to live in the connection pool before being destroyed.
|
||||
*/
|
||||
loadBalanceTimeout: number;
|
||||
|
||||
/**
|
||||
* Gets or sets a Boolean value that indicates whether replication is supported using the connection.
|
||||
*/
|
||||
replication: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets a string that contains the name of the primary data file. This includes the full path name of an attachable database.
|
||||
*/
|
||||
attachDbFilename: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the name or address of the partner server to connect to if the primary server is down.
|
||||
*/
|
||||
failoverPartner: string;
|
||||
|
||||
/**
|
||||
* If your application is connecting to an AlwaysOn availability group (AG) on different subnets, setting MultiSubnetFailover=true
|
||||
* provides faster detection of and connection to the (currently) active server.
|
||||
*/
|
||||
multiSubnetFailover: boolean;
|
||||
|
||||
/**
|
||||
* When true, an application can maintain multiple active result sets (MARS).
|
||||
*/
|
||||
multipleActiveResultSets: boolean;
|
||||
|
||||
/**
|
||||
* Gets or sets the size in bytes of the network packets used to communicate with an instance of SQL Server.
|
||||
*/
|
||||
packetSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets a string value that indicates the type system the application expects.
|
||||
*/
|
||||
typeSystemVersion: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the connection string to use for this connection
|
||||
*/
|
||||
connectionString: string;
|
||||
}
|
||||
|
||||
export const enum ExtractTarget {
|
||||
|
|
Загрузка…
Ссылка в новой задаче