mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add global current connection (#505)
This commit is contained in:
@@ -10,6 +10,8 @@ import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
|||||||
import { RunQueryOnConnectionMode, IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
import { RunQueryOnConnectionMode, IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||||
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
|
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
|
||||||
import { InsightActionContext } from 'sql/workbench/common/actions';
|
import { InsightActionContext } from 'sql/workbench/common/actions';
|
||||||
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
|
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
|
||||||
export class RunInsightQueryAction extends Action {
|
export class RunInsightQueryAction extends Action {
|
||||||
public static ID = 'runQuery';
|
public static ID = 'runQuery';
|
||||||
@@ -18,7 +20,9 @@ export class RunInsightQueryAction extends Action {
|
|||||||
constructor(
|
constructor(
|
||||||
id: string, label: string,
|
id: string, label: string,
|
||||||
@IQueryEditorService protected _queryEditorService: IQueryEditorService,
|
@IQueryEditorService protected _queryEditorService: IQueryEditorService,
|
||||||
@IConnectionManagementService protected _connectionManagementService: IConnectionManagementService
|
@IConnectionManagementService protected _connectionManagementService: IConnectionManagementService,
|
||||||
|
@IObjectExplorerService protected _objectExplorerService: IObjectExplorerService,
|
||||||
|
@IWorkbenchEditorService protected _workbenchEditorService: IWorkbenchEditorService
|
||||||
) {
|
) {
|
||||||
super(id, label);
|
super(id, label);
|
||||||
}
|
}
|
||||||
@@ -29,6 +33,8 @@ export class RunInsightQueryAction extends Action {
|
|||||||
context.profile,
|
context.profile,
|
||||||
this._connectionManagementService,
|
this._connectionManagementService,
|
||||||
this._queryEditorService,
|
this._queryEditorService,
|
||||||
|
this._objectExplorerService,
|
||||||
|
this._workbenchEditorService,
|
||||||
context.insight.query as string,
|
context.insight.query as string,
|
||||||
RunQueryOnConnectionMode.executeQuery
|
RunQueryOnConnectionMode.executeQuery
|
||||||
).then(() => resolve(true), () => resolve(false));
|
).then(() => resolve(true), () => resolve(false));
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
|||||||
import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { warn, error } from 'sql/base/common/log';
|
import { warn, error } from 'sql/base/common/log';
|
||||||
|
import { ServerTreeView } from 'sql/parts/registeredServer/viewlet/serverTreeView';
|
||||||
|
|
||||||
export const SERVICE_ID = 'ObjectExplorerService';
|
export const SERVICE_ID = 'ObjectExplorerService';
|
||||||
|
|
||||||
@@ -54,6 +55,12 @@ export interface IObjectExplorerService {
|
|||||||
deleteObjectExplorerNode(connection: IConnectionProfile): void;
|
deleteObjectExplorerNode(connection: IConnectionProfile): void;
|
||||||
|
|
||||||
onUpdateObjectExplorerNodes: Event<ObjectExplorerNodeEventArgs>;
|
onUpdateObjectExplorerNodes: Event<ObjectExplorerNodeEventArgs>;
|
||||||
|
|
||||||
|
registerServerTreeView(view: ServerTreeView): void;
|
||||||
|
|
||||||
|
getSelectedProfileAndDatabase(): { profile: ConnectionProfile, databaseName: string };
|
||||||
|
|
||||||
|
isFocused(): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SessionStatus {
|
interface SessionStatus {
|
||||||
@@ -85,6 +92,8 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
|||||||
|
|
||||||
private _onUpdateObjectExplorerNodes: Emitter<ObjectExplorerNodeEventArgs>;
|
private _onUpdateObjectExplorerNodes: Emitter<ObjectExplorerNodeEventArgs>;
|
||||||
|
|
||||||
|
private _serverTreeView: ServerTreeView;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||||
@ITelemetryService private _telemetryService: ITelemetryService
|
@ITelemetryService private _telemetryService: ITelemetryService
|
||||||
@@ -355,4 +364,44 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
|||||||
return new TreeNode(nodeInfo.nodeType, nodeInfo.label, isLeaf, nodeInfo.nodePath,
|
return new TreeNode(nodeInfo.nodeType, nodeInfo.label, isLeaf, nodeInfo.nodePath,
|
||||||
nodeInfo.nodeSubType, nodeInfo.nodeStatus, parent, nodeInfo.metadata);
|
nodeInfo.nodeSubType, nodeInfo.nodeStatus, parent, nodeInfo.metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public registerServerTreeView(view: ServerTreeView): void {
|
||||||
|
if (this._serverTreeView) {
|
||||||
|
throw new Error('The object explorer server tree view is already registered');
|
||||||
|
}
|
||||||
|
this._serverTreeView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connection profile corresponding to the current Object Explorer selection,
|
||||||
|
* or undefined if there are multiple selections or no such connection
|
||||||
|
*/
|
||||||
|
public getSelectedProfileAndDatabase(): { profile: ConnectionProfile, databaseName: string } {
|
||||||
|
if (!this._serverTreeView) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let selection = this._serverTreeView.getSelection();
|
||||||
|
if (selection.length === 1) {
|
||||||
|
let selectedNode = selection[0];
|
||||||
|
if (selectedNode instanceof ConnectionProfile) {
|
||||||
|
return { profile: selectedNode, databaseName: undefined };
|
||||||
|
} else if (selectedNode instanceof TreeNode) {
|
||||||
|
let profile = selectedNode.getConnectionProfile();
|
||||||
|
let database = selectedNode.getDatabaseName();
|
||||||
|
// If the database is unavailable, use the server connection
|
||||||
|
if (selectedNode.nodeTypeId === 'Database' && selectedNode.isAlwaysLeaf) {
|
||||||
|
database = undefined;
|
||||||
|
}
|
||||||
|
return { profile: profile, databaseName: database };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a boolean indicating whether the Object Explorer tree has focus
|
||||||
|
*/
|
||||||
|
public isFocused(): boolean {
|
||||||
|
return this._serverTreeView.isFocused();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@ import { IObjectExplorerService } from 'sql/parts/registeredServer/common/object
|
|||||||
import { TreeNode } from 'sql/parts/registeredServer/common/treeNode';
|
import { TreeNode } from 'sql/parts/registeredServer/common/treeNode';
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
import { ObjectExplorerActionsContext, ObjectExplorerActionUtilities } from 'sql/parts/registeredServer/viewlet/objectExplorerActions';
|
import { ObjectExplorerActionsContext, ObjectExplorerActionUtilities } from 'sql/parts/registeredServer/viewlet/objectExplorerActions';
|
||||||
|
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
|
||||||
export class RefreshAction extends Action {
|
export class RefreshAction extends Action {
|
||||||
|
|
||||||
@@ -373,7 +374,9 @@ export class NewQueryAction extends Action {
|
|||||||
id: string,
|
id: string,
|
||||||
label: string,
|
label: string,
|
||||||
@IQueryEditorService private queryEditorService: IQueryEditorService,
|
@IQueryEditorService private queryEditorService: IQueryEditorService,
|
||||||
@IConnectionManagementService private connectionManagementService: IConnectionManagementService
|
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
||||||
|
@IObjectExplorerService protected _objectExplorerService: IObjectExplorerService,
|
||||||
|
@IWorkbenchEditorService protected _workbenchEditorService: IWorkbenchEditorService
|
||||||
) {
|
) {
|
||||||
super(id, label);
|
super(id, label);
|
||||||
this.class = 'extension-action update';
|
this.class = 'extension-action update';
|
||||||
@@ -384,7 +387,7 @@ export class NewQueryAction extends Action {
|
|||||||
this._connectionProfile = actionContext.connectionProfile;
|
this._connectionProfile = actionContext.connectionProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskUtilities.newQuery(this._connectionProfile, this.connectionManagementService, this.queryEditorService);
|
TaskUtilities.newQuery(this._connectionProfile, this.connectionManagementService, this.queryEditorService, this._objectExplorerService, this._workbenchEditorService);
|
||||||
return TPromise.as(true);
|
return TPromise.as(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
|
|||||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||||
import { ClearSearchAction, AddServerAction, AddServerGroupAction, ActiveConnectionsFilterAction } from 'sql/parts/registeredServer/viewlet/connectionTreeAction';
|
import { ClearSearchAction, AddServerAction, AddServerGroupAction, ActiveConnectionsFilterAction } from 'sql/parts/registeredServer/viewlet/connectionTreeAction';
|
||||||
import { warn } from 'sql/base/common/log';
|
import { warn } from 'sql/base/common/log';
|
||||||
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
|
|
||||||
export class ConnectionViewlet extends Viewlet implements IConnectionsViewlet {
|
export class ConnectionViewlet extends Viewlet implements IConnectionsViewlet {
|
||||||
|
|
||||||
@@ -48,7 +49,8 @@ export class ConnectionViewlet extends Viewlet implements IConnectionsViewlet {
|
|||||||
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
||||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||||
@IViewletService private viewletService: IViewletService,
|
@IViewletService private viewletService: IViewletService,
|
||||||
@IMessageService private messageService: IMessageService
|
@IMessageService private messageService: IMessageService,
|
||||||
|
@IObjectExplorerService private objectExplorerService: IObjectExplorerService
|
||||||
) {
|
) {
|
||||||
super(VIEWLET_ID, telemetryService, _themeService);
|
super(VIEWLET_ID, telemetryService, _themeService);
|
||||||
this._searchDelayer = new ThrottledDelayer(500);
|
this._searchDelayer = new ThrottledDelayer(500);
|
||||||
@@ -62,6 +64,7 @@ export class ConnectionViewlet extends Viewlet implements IConnectionsViewlet {
|
|||||||
AddServerGroupAction.LABEL);
|
AddServerGroupAction.LABEL);
|
||||||
this._serverTreeView = this._instantiationService.createInstance(ServerTreeView);
|
this._serverTreeView = this._instantiationService.createInstance(ServerTreeView);
|
||||||
this._activeConnectionsFilterAction = this._serverTreeView.activeConnectionsFilterAction;
|
this._activeConnectionsFilterAction = this._serverTreeView.activeConnectionsFilterAction;
|
||||||
|
this.objectExplorerService.registerServerTreeView(this._serverTreeView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onError(err: any): void {
|
private onError(err: any): void {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { IScriptingService } from 'sql/services/scripting/scriptingService';
|
|||||||
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
|
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
|
||||||
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
import * as Constants from 'sql/parts/connection/common/constants';
|
import * as Constants from 'sql/parts/connection/common/constants';
|
||||||
|
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
|
||||||
export class ObjectExplorerActionsContext {
|
export class ObjectExplorerActionsContext {
|
||||||
public treeNode: TreeNode;
|
public treeNode: TreeNode;
|
||||||
@@ -39,9 +40,11 @@ export class OENewQueryAction extends NewQueryAction {
|
|||||||
id: string, label: string, icon: string,
|
id: string, label: string, icon: string,
|
||||||
@IQueryEditorService protected _queryEditorService: IQueryEditorService,
|
@IQueryEditorService protected _queryEditorService: IQueryEditorService,
|
||||||
@IConnectionManagementService protected _connectionManagementService: IConnectionManagementService,
|
@IConnectionManagementService protected _connectionManagementService: IConnectionManagementService,
|
||||||
@IInstantiationService private _instantiationService: IInstantiationService
|
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||||
|
@IObjectExplorerService protected _objectExplorerService: IObjectExplorerService,
|
||||||
|
@IWorkbenchEditorService protected _workbenchEditorService: IWorkbenchEditorService
|
||||||
) {
|
) {
|
||||||
super(id, label, icon, _queryEditorService, _connectionManagementService);
|
super(id, label, icon, _queryEditorService, _connectionManagementService, _objectExplorerService, _workbenchEditorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public run(actionContext: any): TPromise<boolean> {
|
public run(actionContext: any): TPromise<boolean> {
|
||||||
|
|||||||
@@ -406,6 +406,20 @@ export class ServerTreeView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of selected nodes in the tree
|
||||||
|
*/
|
||||||
|
public getSelection(): any[] {
|
||||||
|
return this._tree.getSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether the tree view currently has focus
|
||||||
|
*/
|
||||||
|
public isFocused(): boolean {
|
||||||
|
return this._tree.isDOMFocused();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dispose the server tree view
|
* dispose the server tree view
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import { Action } from 'vs/base/common/actions';
|
|||||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||||
|
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
|
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
|
||||||
export interface BaseActionContext {
|
export interface BaseActionContext {
|
||||||
object?: ObjectMetadata;
|
object?: ObjectMetadata;
|
||||||
@@ -47,7 +49,9 @@ export class NewQueryAction extends TaskAction {
|
|||||||
constructor(
|
constructor(
|
||||||
id: string, label: string, icon: string,
|
id: string, label: string, icon: string,
|
||||||
@IQueryEditorService protected _queryEditorService: IQueryEditorService,
|
@IQueryEditorService protected _queryEditorService: IQueryEditorService,
|
||||||
@IConnectionManagementService protected _connectionManagementService: IConnectionManagementService
|
@IConnectionManagementService protected _connectionManagementService: IConnectionManagementService,
|
||||||
|
@IObjectExplorerService protected _objectExplorerService: IObjectExplorerService,
|
||||||
|
@IWorkbenchEditorService protected _workbenchEditorService: IWorkbenchEditorService
|
||||||
) {
|
) {
|
||||||
super(id, label, icon);
|
super(id, label, icon);
|
||||||
}
|
}
|
||||||
@@ -57,7 +61,9 @@ export class NewQueryAction extends TaskAction {
|
|||||||
TaskUtilities.newQuery(
|
TaskUtilities.newQuery(
|
||||||
actionContext.profile,
|
actionContext.profile,
|
||||||
this._connectionManagementService,
|
this._connectionManagementService,
|
||||||
this._queryEditorService
|
this._queryEditorService,
|
||||||
|
this._objectExplorerService,
|
||||||
|
this._workbenchEditorService
|
||||||
).then(
|
).then(
|
||||||
result => {
|
result => {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ import data = require('data');
|
|||||||
import nls = require('vs/nls');
|
import nls = require('vs/nls');
|
||||||
import os = require('os');
|
import os = require('os');
|
||||||
import path = require('path');
|
import path = require('path');
|
||||||
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
|
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
import { QueryInput } from 'sql/parts/query/common/queryInput';
|
||||||
|
import { DashboardInput } from 'sql/parts/dashboard/dashboardInput';
|
||||||
|
|
||||||
// map for the version of SQL Server (default is 140)
|
// map for the version of SQL Server (default is 140)
|
||||||
const scriptCompatibilityOptionMap = {
|
const scriptCompatibilityOptionMap = {
|
||||||
@@ -237,10 +241,15 @@ export function newQuery(
|
|||||||
connectionProfile: IConnectionProfile,
|
connectionProfile: IConnectionProfile,
|
||||||
connectionService: IConnectionManagementService,
|
connectionService: IConnectionManagementService,
|
||||||
queryEditorService: IQueryEditorService,
|
queryEditorService: IQueryEditorService,
|
||||||
|
objectExplorerService: IObjectExplorerService,
|
||||||
|
workbenchEditorService: IWorkbenchEditorService,
|
||||||
sqlContent?: string,
|
sqlContent?: string,
|
||||||
executeOnOpen: RunQueryOnConnectionMode = RunQueryOnConnectionMode.none
|
executeOnOpen: RunQueryOnConnectionMode = RunQueryOnConnectionMode.none
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return new Promise<void>((resolve) => {
|
return new Promise<void>((resolve) => {
|
||||||
|
if (!connectionProfile) {
|
||||||
|
connectionProfile = getCurrentGlobalConnection(objectExplorerService, connectionService, workbenchEditorService);
|
||||||
|
}
|
||||||
queryEditorService.newSqlEditor(sqlContent).then((owner: IConnectableInput) => {
|
queryEditorService.newSqlEditor(sqlContent).then((owner: IConnectableInput) => {
|
||||||
// Connect our editor to the input connection
|
// Connect our editor to the input connection
|
||||||
let options: IConnectionCompletionOptions = {
|
let options: IConnectionCompletionOptions = {
|
||||||
@@ -250,9 +259,13 @@ export function newQuery(
|
|||||||
showConnectionDialogOnError: true,
|
showConnectionDialogOnError: true,
|
||||||
showFirewallRuleOnError: true
|
showFirewallRuleOnError: true
|
||||||
};
|
};
|
||||||
connectionService.connect(connectionProfile, owner.uri, options).then(() => {
|
if (connectionProfile) {
|
||||||
|
connectionService.connect(connectionProfile, owner.uri, options).then(() => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -331,6 +344,39 @@ export function openInsight(query: IInsightsConfig, profile: IConnectionProfile,
|
|||||||
insightDialogService.show(query, profile);
|
insightDialogService.show(query, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current global connection, which is the connection from the active editor, unless OE
|
||||||
|
* is focused or there is no such editor, in which case it comes from the OE selection. Returns
|
||||||
|
* undefined when there is no such connection.
|
||||||
|
*/
|
||||||
|
export function getCurrentGlobalConnection(objectExplorerService: IObjectExplorerService, connectionManagementService: IConnectionManagementService, workbenchEditorService: IWorkbenchEditorService): IConnectionProfile {
|
||||||
|
let connection: IConnectionProfile;
|
||||||
|
|
||||||
|
let objectExplorerSelection = objectExplorerService.getSelectedProfileAndDatabase();
|
||||||
|
if (objectExplorerSelection) {
|
||||||
|
let objectExplorerProfile = objectExplorerSelection.profile;
|
||||||
|
if (connectionManagementService.isProfileConnected(objectExplorerProfile)) {
|
||||||
|
if (objectExplorerSelection.databaseName) {
|
||||||
|
connection = objectExplorerProfile.cloneWithDatabase(objectExplorerSelection.databaseName);
|
||||||
|
} else {
|
||||||
|
connection = objectExplorerProfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (objectExplorerService.isFocused()) {
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let activeInput = workbenchEditorService.getActiveEditorInput();
|
||||||
|
if (activeInput) {
|
||||||
|
if (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput) {
|
||||||
|
connection = connectionManagementService.getConnectionProfile(activeInput.uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper Methods */
|
/* Helper Methods */
|
||||||
function getStartPos(script: string, operation: ScriptOperation, typeName: string): number {
|
function getStartPos(script: string, operation: ScriptOperation, typeName: string): number {
|
||||||
let objectTypeName = objectScriptMap[typeName];
|
let objectTypeName = objectScriptMap[typeName];
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
|||||||
import * as data from 'data';
|
import * as data from 'data';
|
||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
|
import { ServerTreeView } from 'sql/parts/registeredServer/viewlet/serverTreeView';
|
||||||
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
|
|
||||||
suite('SQL Object Explorer Service tests', () => {
|
suite('SQL Object Explorer Service tests', () => {
|
||||||
@@ -448,4 +449,57 @@ suite('SQL Object Explorer Service tests', () => {
|
|||||||
assert.equal(table1Node.getConnectionProfile(), connection);
|
assert.equal(table1Node.getConnectionProfile(), connection);
|
||||||
assert.equal(table1Node.getDatabaseName(), 'Db1');
|
assert.equal(table1Node.getDatabaseName(), 'Db1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getSelectedProfileAndDatabase returns the profile if it is selected', () => {
|
||||||
|
let serverTreeView = TypeMoq.Mock.ofInstance({ getSelection: () => undefined } as ServerTreeView);
|
||||||
|
serverTreeView.setup(x => x.getSelection()).returns(() => [connection]);
|
||||||
|
objectExplorerService.registerServerTreeView(serverTreeView.object);
|
||||||
|
|
||||||
|
let selectedProfileAndDatabase = objectExplorerService.getSelectedProfileAndDatabase();
|
||||||
|
assert.equal(selectedProfileAndDatabase.profile, connection);
|
||||||
|
assert.equal(selectedProfileAndDatabase.databaseName, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getSelectedProfileAndDatabase returns the profile but no database if children of a server are selected', () => {
|
||||||
|
let serverTreeView = TypeMoq.Mock.ofInstance({ getSelection: () => undefined } as ServerTreeView);
|
||||||
|
let databaseNode = new TreeNode(NodeType.Folder, 'Folder1', false, 'testServerName\\Folder1', '', '', undefined, undefined);
|
||||||
|
databaseNode.connection = connection;
|
||||||
|
serverTreeView.setup(x => x.getSelection()).returns(() => [databaseNode]);
|
||||||
|
objectExplorerService.registerServerTreeView(serverTreeView.object);
|
||||||
|
|
||||||
|
let selectedProfileAndDatabase = objectExplorerService.getSelectedProfileAndDatabase();
|
||||||
|
assert.equal(selectedProfileAndDatabase.profile, connection);
|
||||||
|
assert.equal(selectedProfileAndDatabase.databaseName, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getSelectedProfileAndDatabase returns the profile and database if children of a database node are selected', () => {
|
||||||
|
let serverTreeView = TypeMoq.Mock.ofInstance({ getSelection: () => undefined } as ServerTreeView);
|
||||||
|
let databaseMetadata = {
|
||||||
|
metadataType: 0,
|
||||||
|
metadataTypeName: 'Database',
|
||||||
|
urn: '//server/db1/',
|
||||||
|
name: 'Db1',
|
||||||
|
schema: undefined
|
||||||
|
};
|
||||||
|
let databaseName = 'Db1';
|
||||||
|
let databaseNode = new TreeNode(NodeType.Database, databaseName, false, 'testServerName\\Db1', '', '', undefined, databaseMetadata);
|
||||||
|
let tablesNode = new TreeNode(NodeType.Folder, 'Tables', false, 'testServerName\\Db1\\tables', '', '', databaseNode, undefined);
|
||||||
|
databaseNode.connection = connection;
|
||||||
|
databaseNode.children = [tablesNode];
|
||||||
|
serverTreeView.setup(x => x.getSelection()).returns(() => [tablesNode]);
|
||||||
|
objectExplorerService.registerServerTreeView(serverTreeView.object);
|
||||||
|
|
||||||
|
let selectedProfileAndDatabase = objectExplorerService.getSelectedProfileAndDatabase();
|
||||||
|
assert.equal(selectedProfileAndDatabase.profile, connection);
|
||||||
|
assert.equal(selectedProfileAndDatabase.databaseName, databaseName);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getSelectedProfileAndDatabase returns undefined when there is no selection', () => {
|
||||||
|
let serverTreeView = TypeMoq.Mock.ofInstance({ getSelection: () => undefined } as ServerTreeView);
|
||||||
|
serverTreeView.setup(x => x.getSelection()).returns(() => []);
|
||||||
|
objectExplorerService.registerServerTreeView(serverTreeView.object);
|
||||||
|
|
||||||
|
let selectedProfileAndDatabase = objectExplorerService.getSelectedProfileAndDatabase();
|
||||||
|
assert.equal(selectedProfileAndDatabase, undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
113
src/sqltest/workbench/common/taskUtilities.test.ts
Normal file
113
src/sqltest/workbench/common/taskUtilities.test.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as assert from 'assert';
|
||||||
|
import * as TypeMoq from 'typemoq';
|
||||||
|
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
||||||
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
|
import { TestConnectionManagementService } from 'sqltest/stubs/connectionManagementService.test';
|
||||||
|
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||||
|
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
|
||||||
|
import { WorkbenchEditorTestService } from 'sqltest/stubs/workbenchEditorTestService';
|
||||||
|
import URI from 'vs/base/common/uri';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { QueryInput } from 'sql/parts/query/common/queryInput';
|
||||||
|
|
||||||
|
suite('TaskUtilities', function() {
|
||||||
|
test('getCurrentGlobalConnection returns the selected OE server if a server or one of its children is selected', () => {
|
||||||
|
let connectionProfile = { databaseName: 'test_database', id: 'test_id', authenticationType: 'SQL Login', password: 'test_password', serverName: 'test_server', userName: 'test_user' } as IConnectionProfile;
|
||||||
|
let mockObjectExplorerService = TypeMoq.Mock.ofInstance({isFocused: () => undefined, getSelectedProfileAndDatabase: () => undefined } as IObjectExplorerService);
|
||||||
|
let mockConnectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService);
|
||||||
|
let mockWorkbenchEditorService = TypeMoq.Mock.ofType(WorkbenchEditorTestService);
|
||||||
|
let expectedProfile = new ConnectionProfile(undefined, connectionProfile);
|
||||||
|
mockObjectExplorerService.setup(x => x.isFocused()).returns(() => true);
|
||||||
|
mockObjectExplorerService.setup(x => x.getSelectedProfileAndDatabase()).returns(() => {
|
||||||
|
return { profile: expectedProfile, databaseName: undefined };
|
||||||
|
});
|
||||||
|
mockConnectionManagementService.setup(x => x.isProfileConnected(TypeMoq.It.is(profile => profile === expectedProfile))).returns(() => true);
|
||||||
|
mockWorkbenchEditorService.setup(x => x.getActiveEditorInput()).returns(() => undefined);
|
||||||
|
|
||||||
|
// If I call getCurrentGlobalConnection, it should return the expected server profile
|
||||||
|
let actualProfile = TaskUtilities.getCurrentGlobalConnection(mockObjectExplorerService.object, mockConnectionManagementService.object, mockWorkbenchEditorService.object);
|
||||||
|
assert.equal(actualProfile, expectedProfile);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getCurrentGlobalConnection returns the selected OE database if a database or its children is selected', () => {
|
||||||
|
let connectionProfile = { databaseName: 'test_database', id: 'test_id', authenticationType: 'SQL Login', password: 'test_password', serverName: 'test_server', userName: 'test_user' } as IConnectionProfile;
|
||||||
|
let mockObjectExplorerService = TypeMoq.Mock.ofInstance({isFocused: () => undefined, getSelectedProfileAndDatabase: () => undefined } as IObjectExplorerService);
|
||||||
|
let mockConnectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService);
|
||||||
|
let mockWorkbenchEditorService = TypeMoq.Mock.ofType(WorkbenchEditorTestService);
|
||||||
|
let serverProfile = new ConnectionProfile(undefined, connectionProfile);
|
||||||
|
let dbName = 'test_database';
|
||||||
|
mockObjectExplorerService.setup(x => x.isFocused()).returns(() => true);
|
||||||
|
mockObjectExplorerService.setup(x => x.getSelectedProfileAndDatabase()).returns(() => {
|
||||||
|
return { profile: serverProfile, databaseName: dbName };
|
||||||
|
});
|
||||||
|
mockConnectionManagementService.setup(x => x.isProfileConnected(TypeMoq.It.is(profile => profile === serverProfile))).returns(() => true);
|
||||||
|
mockWorkbenchEditorService.setup(x => x.getActiveEditorInput()).returns(() => undefined);
|
||||||
|
|
||||||
|
// If I call getCurrentGlobalConnection, it should return the expected database profile
|
||||||
|
let actualProfile = TaskUtilities.getCurrentGlobalConnection(mockObjectExplorerService.object, mockConnectionManagementService.object, mockWorkbenchEditorService.object);
|
||||||
|
assert.equal(actualProfile.databaseName, dbName);
|
||||||
|
assert.notEqual(actualProfile.id, serverProfile.id);
|
||||||
|
// Other connection attributes still match
|
||||||
|
assert.equal(actualProfile.authenticationType, serverProfile.authenticationType);
|
||||||
|
assert.equal(actualProfile.password, serverProfile.password);
|
||||||
|
assert.equal(actualProfile.serverName, serverProfile.serverName);
|
||||||
|
assert.equal(actualProfile.userName, serverProfile.userName);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getCurrentGlobalConnection returns the connection from the active tab, if there is one and OE is not focused', () => {
|
||||||
|
let connectionProfile = { databaseName: 'test_database', id: 'test_id', authenticationType: 'SQL Login', password: 'test_password', serverName: 'test_server', userName: 'test_user' } as IConnectionProfile;
|
||||||
|
let mockObjectExplorerService = TypeMoq.Mock.ofInstance({isFocused: () => undefined, getSelectedProfileAndDatabase: () => undefined } as IObjectExplorerService);
|
||||||
|
let mockConnectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService);
|
||||||
|
let mockWorkbenchEditorService = TypeMoq.Mock.ofType(WorkbenchEditorTestService);
|
||||||
|
let oeProfile = new ConnectionProfile(undefined, connectionProfile);
|
||||||
|
let connectionProfile2 = Object.assign({}, connectionProfile);
|
||||||
|
connectionProfile2.serverName = 'test_server_2';
|
||||||
|
connectionProfile2.id = 'test_id_2';
|
||||||
|
let tabProfile = new ConnectionProfile(undefined, connectionProfile2);
|
||||||
|
mockObjectExplorerService.setup(x => x.isFocused()).returns(() => false);
|
||||||
|
mockObjectExplorerService.setup(x => x.getSelectedProfileAndDatabase()).returns(() => {
|
||||||
|
return { profile: oeProfile, databaseName: undefined };
|
||||||
|
});
|
||||||
|
mockConnectionManagementService.setup(x => x.isProfileConnected(TypeMoq.It.is(profile => profile === oeProfile || profile === tabProfile))).returns(() => true);
|
||||||
|
|
||||||
|
// Mock the workbench service to return the active tab connection
|
||||||
|
let tabConnectionUri = 'test_uri';
|
||||||
|
let editorInput = new UntitledEditorInput(URI.parse(tabConnectionUri), false, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
||||||
|
let queryInput = new QueryInput(undefined, undefined, editorInput, undefined, undefined, undefined, undefined, undefined);
|
||||||
|
mockWorkbenchEditorService.setup(x => x.getActiveEditorInput()).returns(() => queryInput);
|
||||||
|
mockConnectionManagementService.setup(x => x.getConnectionProfile(tabConnectionUri)).returns(() => tabProfile);
|
||||||
|
|
||||||
|
// If I call getCurrentGlobalConnection, it should return the expected profile from the active tab
|
||||||
|
let actualProfile = TaskUtilities.getCurrentGlobalConnection(mockObjectExplorerService.object, mockConnectionManagementService.object, mockWorkbenchEditorService.object);
|
||||||
|
assert.equal(actualProfile.databaseName, tabProfile.databaseName);
|
||||||
|
assert.equal(actualProfile.authenticationType, tabProfile.authenticationType);
|
||||||
|
assert.equal(actualProfile.password, tabProfile.password);
|
||||||
|
assert.equal(actualProfile.serverName, tabProfile.serverName);
|
||||||
|
assert.equal(actualProfile.userName, tabProfile.userName);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getCurrentGlobalConnection returns the connection from OE if there is no active tab, even if OE is not focused', () => {
|
||||||
|
let connectionProfile = { databaseName: 'test_database', id: 'test_id', authenticationType: 'SQL Login', password: 'test_password', serverName: 'test_server', userName: 'test_user' } as IConnectionProfile;
|
||||||
|
let mockObjectExplorerService = TypeMoq.Mock.ofInstance({isFocused: () => undefined, getSelectedProfileAndDatabase: () => undefined } as IObjectExplorerService);
|
||||||
|
let mockConnectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService);
|
||||||
|
let mockWorkbenchEditorService = TypeMoq.Mock.ofType(WorkbenchEditorTestService);
|
||||||
|
let oeProfile = new ConnectionProfile(undefined, connectionProfile);
|
||||||
|
mockObjectExplorerService.setup(x => x.isFocused()).returns(() => false);
|
||||||
|
mockObjectExplorerService.setup(x => x.getSelectedProfileAndDatabase()).returns(() => {
|
||||||
|
return { profile: oeProfile, databaseName: undefined };
|
||||||
|
});
|
||||||
|
mockConnectionManagementService.setup(x => x.isProfileConnected(TypeMoq.It.is(profile => profile === oeProfile))).returns(() => true);
|
||||||
|
mockWorkbenchEditorService.setup(x => x.getActiveEditorInput()).returns(() => undefined);
|
||||||
|
|
||||||
|
// If I call getCurrentGlobalConnection, it should return the expected profile from OE
|
||||||
|
let actualProfile = TaskUtilities.getCurrentGlobalConnection(mockObjectExplorerService.object, mockConnectionManagementService.object, mockWorkbenchEditorService.object);
|
||||||
|
assert.equal(actualProfile, oeProfile);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -50,6 +50,10 @@ import { Color } from 'vs/base/common/color';
|
|||||||
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
|
||||||
import * as QueryConstants from 'sql/parts/query/common/constants';
|
import * as QueryConstants from 'sql/parts/query/common/constants';
|
||||||
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
|
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
|
||||||
|
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
||||||
|
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||||
|
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
|
||||||
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
|
|
||||||
interface IEditorInputLabel {
|
interface IEditorInputLabel {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -85,7 +89,11 @@ export class TabsTitleControl extends TitleControl {
|
|||||||
@IFileService private fileService: IFileService,
|
@IFileService private fileService: IFileService,
|
||||||
@IWorkspacesService private workspacesService: IWorkspacesService,
|
@IWorkspacesService private workspacesService: IWorkspacesService,
|
||||||
// {{SQL CARBON EDIT}} -- Display the editor's tab color
|
// {{SQL CARBON EDIT}} -- Display the editor's tab color
|
||||||
@IWorkspaceConfigurationService private workspaceConfigurationService: IWorkspaceConfigurationService
|
@IWorkspaceConfigurationService private workspaceConfigurationService: IWorkspaceConfigurationService,
|
||||||
|
@IConnectionManagementService private connectionService: IConnectionManagementService,
|
||||||
|
@IQueryEditorService private queryEditorService: IQueryEditorService,
|
||||||
|
@IObjectExplorerService private objectExplorerService: IObjectExplorerService,
|
||||||
|
@IWorkbenchEditorService private workbenchEditorService: IWorkbenchEditorService,
|
||||||
) {
|
) {
|
||||||
super(contextMenuService, instantiationService, editorService, editorGroupService, contextKeyService, keybindingService, telemetryService, messageService, menuService, quickOpenService, themeService);
|
super(contextMenuService, instantiationService, editorService, editorGroupService, contextKeyService, keybindingService, telemetryService, messageService, menuService, quickOpenService, themeService);
|
||||||
|
|
||||||
@@ -154,7 +162,7 @@ export class TabsTitleControl extends TitleControl {
|
|||||||
|
|
||||||
const group = this.context;
|
const group = this.context;
|
||||||
if (group) {
|
if (group) {
|
||||||
this.editorService.openEditor({ options: { pinned: true, index: group.count /* always at the end */ } } as IUntitledResourceInput).done(null, errors.onUnexpectedError); // untitled are always pinned
|
TaskUtilities.newQuery(undefined, this.connectionService, this.queryEditorService, this.objectExplorerService, this.workbenchEditorService).then(undefined, errors.onUnexpectedError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
|
|||||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||||
import { once } from 'vs/base/common/event';
|
import { once } from 'vs/base/common/event';
|
||||||
|
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
|
||||||
|
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||||
|
import { IObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
|
||||||
|
|
||||||
export interface IEditableData {
|
export interface IEditableData {
|
||||||
action: IAction;
|
action: IAction;
|
||||||
@@ -533,14 +536,17 @@ export class GlobalNewUntitledFileAction extends Action {
|
|||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
@IQueryEditorService private queryEditorService: IQueryEditorService
|
@IQueryEditorService private queryEditorService: IQueryEditorService,
|
||||||
|
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
||||||
|
@IObjectExplorerService protected _objectExplorerService: IObjectExplorerService,
|
||||||
|
@IWorkbenchEditorService protected _workbenchEditorService: IWorkbenchEditorService
|
||||||
) {
|
) {
|
||||||
super(id, label);
|
super(id, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public run(): TPromise<any> {
|
public run(): TPromise<any> {
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
this.queryEditorService.newSqlEditor(undefined, undefined);
|
TaskUtilities.newQuery(undefined, this.connectionManagementService, this.queryEditorService, this._objectExplorerService, this._workbenchEditorService);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user