mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Add database name to attach to (if not connected to master) (#4076)
This commit is contained in:
@@ -12,10 +12,10 @@ import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview
|
|||||||
import { INotificationService, Severity, INotificationActions } from 'vs/platform/notification/common/notification';
|
import { INotificationService, Severity, INotificationActions } from 'vs/platform/notification/common/notification';
|
||||||
|
|
||||||
import { SelectBox, ISelectBoxOptionsWithLabel } from 'sql/base/browser/ui/selectBox/selectBox';
|
import { SelectBox, ISelectBoxOptionsWithLabel } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||||
import { INotebookModel } from 'sql/parts/notebook/models/modelInterfaces';
|
import { INotebookModel, IDefaultConnection } from 'sql/parts/notebook/models/modelInterfaces';
|
||||||
import { CellType } from 'sql/parts/notebook/models/contracts';
|
import { CellType } from 'sql/parts/notebook/models/contracts';
|
||||||
import { NotebookComponent } from 'sql/parts/notebook/notebook.component';
|
import { NotebookComponent } from 'sql/parts/notebook/notebook.component';
|
||||||
import { getErrorMessage } from 'sql/parts/notebook/notebookUtils';
|
import { getErrorMessage, formatServerNameWithDatabaseNameForAttachTo, getServerFromFormattedAttachToName, getDatabaseFromFormattedAttachToName } from 'sql/parts/notebook/notebookUtils';
|
||||||
import { IConnectionManagementService, IConnectionDialogService } from 'sql/platform/connection/common/connectionManagement';
|
import { IConnectionManagementService, IConnectionDialogService } from 'sql/platform/connection/common/connectionManagement';
|
||||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||||
@@ -299,8 +299,7 @@ export class AttachToDropdown extends SelectBox {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.onDidSelect(e => {
|
this.onDidSelect(e => {
|
||||||
let connection = this.model.contexts.otherConnections.find((c) => c.serverName === e.selected);
|
this.doChangeContext(new ConnectionProfile(this._capabilitiesService, this.getConnectionWithServerAndDatabaseNames(e.selected)));
|
||||||
this.doChangeContext(new ConnectionProfile(this._capabilitiesService, connection));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,15 +374,24 @@ export class AttachToDropdown extends SelectBox {
|
|||||||
public getConnections(model: INotebookModel): string[] {
|
public getConnections(model: INotebookModel): string[] {
|
||||||
let otherConnections: ConnectionProfile[] = [];
|
let otherConnections: ConnectionProfile[] = [];
|
||||||
model.contexts.otherConnections.forEach((conn) => { otherConnections.push(conn); });
|
model.contexts.otherConnections.forEach((conn) => { otherConnections.push(conn); });
|
||||||
|
// If current connection connects to master, select the option in the dropdown that doesn't specify a database
|
||||||
|
if (!model.contexts.defaultConnection.databaseName) {
|
||||||
this.selectWithOptionName(model.contexts.defaultConnection.serverName);
|
this.selectWithOptionName(model.contexts.defaultConnection.serverName);
|
||||||
|
} else {
|
||||||
|
if (model.contexts.defaultConnection) {
|
||||||
|
this.selectWithOptionName(formatServerNameWithDatabaseNameForAttachTo(model.contexts.defaultConnection));
|
||||||
|
} else {
|
||||||
|
this.select(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
otherConnections = this.setConnectionsList(model.contexts.defaultConnection, model.contexts.otherConnections);
|
otherConnections = this.setConnectionsList(model.contexts.defaultConnection, model.contexts.otherConnections);
|
||||||
let connections = otherConnections.map((context) => context.serverName);
|
let connections = otherConnections.map((context) => context.databaseName ? context.serverName + ' (' + context.databaseName + ')' : context.serverName);
|
||||||
return connections;
|
return connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setConnectionsList(defaultConnection: ConnectionProfile, otherConnections: ConnectionProfile[]) {
|
private setConnectionsList(defaultConnection: ConnectionProfile, otherConnections: ConnectionProfile[]) {
|
||||||
if (defaultConnection.serverName !== msgSelectConnection) {
|
if (defaultConnection.serverName !== msgSelectConnection) {
|
||||||
otherConnections = otherConnections.filter(conn => conn.serverName !== defaultConnection.serverName);
|
otherConnections = otherConnections.filter(conn => conn.id !== defaultConnection.id);
|
||||||
otherConnections.unshift(defaultConnection);
|
otherConnections.unshift(defaultConnection);
|
||||||
if (otherConnections.length > 1) {
|
if (otherConnections.length > 1) {
|
||||||
otherConnections = otherConnections.filter(val => val.serverName !== msgSelectConnection);
|
otherConnections = otherConnections.filter(val => val.serverName !== msgSelectConnection);
|
||||||
@@ -392,6 +400,20 @@ export class AttachToDropdown extends SelectBox {
|
|||||||
return otherConnections;
|
return otherConnections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getConnectionWithServerAndDatabaseNames(selection: string): ConnectionProfile {
|
||||||
|
// Find all connections with the the same server as the selected option
|
||||||
|
let connections = this.model.contexts.otherConnections.filter((c) => selection === c.serverName);
|
||||||
|
// If only one connection exists with the same server name, use that one
|
||||||
|
if (connections.length === 1) {
|
||||||
|
return connections[0];
|
||||||
|
} else {
|
||||||
|
// Extract server and database name
|
||||||
|
let serverName = getServerFromFormattedAttachToName(selection);
|
||||||
|
let databaseName = getDatabaseFromFormattedAttachToName(selection);
|
||||||
|
return this.model.contexts.otherConnections.find((c) => serverName === c.serverName && databaseName === c.databaseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public doChangeContext(connection?: ConnectionProfile, hideErrorMessage?: boolean): void {
|
public doChangeContext(connection?: ConnectionProfile, hideErrorMessage?: boolean): void {
|
||||||
if (this.value === msgAddNewConnection) {
|
if (this.value === msgAddNewConnection) {
|
||||||
this.openConnectionDialog();
|
this.openConnectionDialog();
|
||||||
@@ -416,7 +438,7 @@ export class AttachToDropdown extends SelectBox {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let connectionProfile = new ConnectionProfile(this._capabilitiesService, connection);
|
let connectionProfile = new ConnectionProfile(this._capabilitiesService, connection);
|
||||||
let connectedServer = connectionProfile.serverName;
|
let connectedServer = formatServerNameWithDatabaseNameForAttachTo(connectionProfile);
|
||||||
//Check to see if the same server is already there in dropdown. We only have server names in dropdown
|
//Check to see if the same server is already there in dropdown. We only have server names in dropdown
|
||||||
if (attachToConnections.some(val => val === connectedServer)) {
|
if (attachToConnections.some(val => val === connectedServer)) {
|
||||||
this.loadAttachToDropdown(this.model, this.getKernelDisplayName());
|
this.loadAttachToDropdown(this.model, this.getKernelDisplayName());
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { localize } from 'vs/nls';
|
|||||||
import { IOutputChannel } from 'vs/workbench/parts/output/common/output';
|
import { IOutputChannel } from 'vs/workbench/parts/output/common/output';
|
||||||
import { DEFAULT_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_FILETYPE, INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
|
import { DEFAULT_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_FILETYPE, INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
|
||||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
|
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,6 +80,26 @@ export function sqlNotebooksEnabled(contextKeyService: IContextKeyService) {
|
|||||||
return contextKeyService.contextMatchesRules(ContextKeyExpr.equals('config.notebook.sqlKernelEnabled', true));
|
return contextKeyService.contextMatchesRules(ContextKeyExpr.equals('config.notebook.sqlKernelEnabled', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In the Attach To dropdown, show the database name (if it exists) using the current connection
|
||||||
|
// Example: myFakeServer (myDatabase)
|
||||||
|
export function formatServerNameWithDatabaseNameForAttachTo(connectionProfile: ConnectionProfile): string {
|
||||||
|
if (connectionProfile && connectionProfile.serverName) {
|
||||||
|
return !connectionProfile.databaseName ? connectionProfile.serverName : connectionProfile.serverName + ' (' + connectionProfile.databaseName + ')';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract server name from format used in Attach To: serverName (databaseName)
|
||||||
|
export function getServerFromFormattedAttachToName(name: string): string {
|
||||||
|
return name.substring(0, name.lastIndexOf(' (')) ? name.substring(0, name.lastIndexOf(' (')) : name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract database name from format used in Attach To: serverName (databaseName)
|
||||||
|
export function getDatabaseFromFormattedAttachToName(name: string): string {
|
||||||
|
return name.substring(name.lastIndexOf('(') + 1, name.lastIndexOf(')')) ?
|
||||||
|
name.substring(name.lastIndexOf('(') + 1, name.lastIndexOf(')')) : '';
|
||||||
|
}
|
||||||
|
|
||||||
export interface IStandardKernelWithProvider {
|
export interface IStandardKernelWithProvider {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly connectionProviderIds: string[];
|
readonly connectionProviderIds: string[];
|
||||||
|
|||||||
88
src/sqltest/parts/notebook/model/notebookUtils.test.ts
Normal file
88
src/sqltest/parts/notebook/model/notebookUtils.test.ts
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as should from 'should';
|
||||||
|
import { nb, IConnectionProfile } from 'sqlops';
|
||||||
|
|
||||||
|
import { CapabilitiesTestService } from 'sqltest/stubs/capabilitiesTestService';
|
||||||
|
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||||
|
import { formatServerNameWithDatabaseNameForAttachTo, getServerFromFormattedAttachToName, getDatabaseFromFormattedAttachToName } from 'sql/parts/notebook/notebookUtils';
|
||||||
|
|
||||||
|
describe('notebookUtils', function(): void {
|
||||||
|
let conn: IConnectionProfile = {
|
||||||
|
connectionName: '',
|
||||||
|
serverName: '',
|
||||||
|
databaseName: '',
|
||||||
|
userName: '',
|
||||||
|
password: '',
|
||||||
|
authenticationType: '',
|
||||||
|
savePassword: true,
|
||||||
|
groupFullName: '',
|
||||||
|
groupId: '',
|
||||||
|
providerName: '',
|
||||||
|
saveProfile: true,
|
||||||
|
id: '',
|
||||||
|
options: {},
|
||||||
|
azureTenantId: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
it('Should format server and database name correctly for attach to', async function(): Promise<void> {
|
||||||
|
let capabilitiesService = new CapabilitiesTestService();
|
||||||
|
let connProfile = new ConnectionProfile(capabilitiesService, conn);
|
||||||
|
connProfile.serverName = 'serverName';
|
||||||
|
connProfile.databaseName = 'databaseName';
|
||||||
|
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
|
||||||
|
should(attachToNameFormatted).equal('serverName (databaseName)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should format server name correctly for attach to', async function(): Promise<void> {
|
||||||
|
let capabilitiesService = new CapabilitiesTestService();
|
||||||
|
let connProfile = new ConnectionProfile(capabilitiesService, conn);
|
||||||
|
connProfile.serverName = 'serverName';
|
||||||
|
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
|
||||||
|
should(attachToNameFormatted).equal('serverName');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should format server name correctly for attach to when database is undefined', async function(): Promise<void> {
|
||||||
|
let capabilitiesService = new CapabilitiesTestService();
|
||||||
|
let connProfile = new ConnectionProfile(capabilitiesService, conn);
|
||||||
|
connProfile.serverName = 'serverName';
|
||||||
|
connProfile.databaseName = undefined;
|
||||||
|
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
|
||||||
|
should(attachToNameFormatted).equal('serverName');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should format server name as empty string when server/database are undefined', async function(): Promise<void> {
|
||||||
|
let capabilitiesService = new CapabilitiesTestService();
|
||||||
|
let connProfile = new ConnectionProfile(capabilitiesService, conn);
|
||||||
|
connProfile.serverName = undefined;
|
||||||
|
connProfile.databaseName = undefined;
|
||||||
|
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
|
||||||
|
should(attachToNameFormatted).equal('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should extract server name when no database specified', async function(): Promise<void> {
|
||||||
|
let serverName = getServerFromFormattedAttachToName('serverName');
|
||||||
|
let databaseName = getDatabaseFromFormattedAttachToName('serverName');
|
||||||
|
should(serverName).equal('serverName');
|
||||||
|
should(databaseName).equal('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should extract server and database name', async function(): Promise<void> {
|
||||||
|
let serverName = getServerFromFormattedAttachToName('serverName (databaseName)');
|
||||||
|
let databaseName = getDatabaseFromFormattedAttachToName('serverName (databaseName)');
|
||||||
|
should(serverName).equal('serverName');
|
||||||
|
should(databaseName).equal('databaseName');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should extract server and database name with other parentheses', async function(): Promise<void> {
|
||||||
|
let serverName = getServerFromFormattedAttachToName('serv()erName (databaseName)');
|
||||||
|
let databaseName = getDatabaseFromFormattedAttachToName('serv()erName (databaseName)');
|
||||||
|
should(serverName).equal('serv()erName');
|
||||||
|
should(databaseName).equal('databaseName');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user