mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Rework how we handle custom editors (#5696)
* update how we handle editors * small edit * handle changing languages * implement generic language association * implement notebook serializers * fix tests * formatting * update how we handle editors * small edit * handle changing languages * implement generic language association * implement notebook serializers * fix tests * formatting * fix broken * fix compile * fix tests * add back in removed note book contributions * fix layering * fix compile errors * fix workbench * fix hanging promises * idk why these changed * fix change * add comments to language change code * fix a few bugs * add query plan association
This commit is contained in:
@@ -7,7 +7,7 @@ import QueryRunner, { IQueryMessage } from 'sql/platform/query/common/queryRunne
|
|||||||
import { DataService } from 'sql/workbench/contrib/grid/common/dataService';
|
import { DataService } from 'sql/workbench/contrib/grid/common/dataService';
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import {
|
import {
|
||||||
ISelectionData,
|
ISelectionData,
|
||||||
ResultSetSubset,
|
ResultSetSubset,
|
||||||
@@ -52,9 +52,9 @@ export interface IQueryModelService {
|
|||||||
getQueryRunner(uri: string): QueryRunner | undefined;
|
getQueryRunner(uri: string): QueryRunner | undefined;
|
||||||
|
|
||||||
getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Promise<ResultSetSubset | undefined>;
|
getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Promise<ResultSetSubset | undefined>;
|
||||||
runQuery(uri: string, selection: ISelectionData | undefined, queryInput: QueryInput, runOptions?: ExecutionPlanOptions): void;
|
runQuery(uri: string, selection: ISelectionData | undefined, queryInput: QueryEditorInput, runOptions?: ExecutionPlanOptions): void;
|
||||||
runQueryStatement(uri: string, selection: ISelectionData | undefined, queryInput: QueryInput): void;
|
runQueryStatement(uri: string, selection: ISelectionData | undefined, queryInput: QueryEditorInput): void;
|
||||||
runQueryString(uri: string, selection: string | undefined, queryInput: QueryInput): void;
|
runQueryString(uri: string, selection: string | undefined, queryInput: QueryEditorInput): void;
|
||||||
cancelQuery(input: QueryRunner | string): void;
|
cancelQuery(input: QueryRunner | string): void;
|
||||||
disposeQuery(uri: string): void;
|
disposeQuery(uri: string): void;
|
||||||
isRunningQuery(uri: string): boolean;
|
isRunningQuery(uri: string): boolean;
|
||||||
@@ -66,9 +66,6 @@ export interface IQueryModelService {
|
|||||||
onAngularLoaded(uri: string): void;
|
onAngularLoaded(uri: string): void;
|
||||||
|
|
||||||
copyResults(uri: string, selection: Slick.Range[], batchId: number, resultId: number, includeHeaders?: boolean): void;
|
copyResults(uri: string, selection: Slick.Range[], batchId: number, resultId: number, includeHeaders?: boolean): void;
|
||||||
setEditorSelection(uri: string, index: number): void;
|
|
||||||
showWarning(uri: string, message: string): void;
|
|
||||||
showError(uri: string, message: string): void;
|
|
||||||
showCommitError(error: string): void;
|
showCommitError(error: string): void;
|
||||||
|
|
||||||
onRunQueryStart: Event<string>;
|
onRunQueryStart: Event<string>;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import * as LocalizedConstants from 'sql/workbench/contrib/query/common/localize
|
|||||||
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
||||||
import { DataService } from 'sql/workbench/contrib/grid/common/dataService';
|
import { DataService } from 'sql/workbench/contrib/grid/common/dataService';
|
||||||
import { IQueryModelService, IQueryEvent } from 'sql/platform/query/common/queryModel';
|
import { IQueryModelService, IQueryEvent } from 'sql/platform/query/common/queryModel';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
@@ -19,6 +18,7 @@ import * as strings from 'vs/base/common/strings';
|
|||||||
import * as types from 'vs/base/common/types';
|
import * as types from 'vs/base/common/types';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
|
||||||
const selectionSnippetMaxLen = 100;
|
const selectionSnippetMaxLen = 100;
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export class QueryInfo {
|
|||||||
public dataService: DataService;
|
public dataService: DataService;
|
||||||
public queryEventQueue: QueryEvent[];
|
public queryEventQueue: QueryEvent[];
|
||||||
public selection: Array<azdata.ISelectionData>;
|
public selection: Array<azdata.ISelectionData>;
|
||||||
public queryInput: QueryInput;
|
public queryInput: QueryEditorInput;
|
||||||
public selectionSnippet?: string;
|
public selectionSnippet?: string;
|
||||||
|
|
||||||
// Notes if the angular components have obtained the DataService. If not, all messages sent
|
// Notes if the angular components have obtained the DataService. If not, all messages sent
|
||||||
@@ -158,19 +158,6 @@ export class QueryModelService implements IQueryModelService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public setEditorSelection(uri: string, index: number): void {
|
|
||||||
let info = this._queryInfoMap.get(uri);
|
|
||||||
if (info && info.queryInput) {
|
|
||||||
info.queryInput.updateSelection(info.selection[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public showWarning(uri: string, message: string): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public showError(uri: string, message: string): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public showCommitError(error: string): void {
|
public showCommitError(error: string): void {
|
||||||
this._notificationService.notify({
|
this._notificationService.notify({
|
||||||
severity: Severity.Error,
|
severity: Severity.Error,
|
||||||
@@ -187,28 +174,28 @@ export class QueryModelService implements IQueryModelService {
|
|||||||
/**
|
/**
|
||||||
* Run a query for the given URI with the given text selection
|
* Run a query for the given URI with the given text selection
|
||||||
*/
|
*/
|
||||||
public async runQuery(uri: string, selection: azdata.ISelectionData, queryInput: QueryInput, runOptions?: azdata.ExecutionPlanOptions): Promise<void> {
|
public async runQuery(uri: string, selection: azdata.ISelectionData, queryInput: QueryEditorInput, runOptions?: azdata.ExecutionPlanOptions): Promise<void> {
|
||||||
return this.doRunQuery(uri, selection, queryInput, false, runOptions);
|
return this.doRunQuery(uri, selection, queryInput, false, runOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the current SQL statement for the given URI
|
* Run the current SQL statement for the given URI
|
||||||
*/
|
*/
|
||||||
public async runQueryStatement(uri: string, selection: azdata.ISelectionData, queryInput: QueryInput): Promise<void> {
|
public async runQueryStatement(uri: string, selection: azdata.ISelectionData, queryInput: QueryEditorInput): Promise<void> {
|
||||||
return this.doRunQuery(uri, selection, queryInput, true);
|
return this.doRunQuery(uri, selection, queryInput, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the current SQL statement for the given URI
|
* Run the current SQL statement for the given URI
|
||||||
*/
|
*/
|
||||||
public async runQueryString(uri: string, selection: string, queryInput: QueryInput): Promise<void> {
|
public async runQueryString(uri: string, selection: string, queryInput: QueryEditorInput): Promise<void> {
|
||||||
return this.doRunQuery(uri, selection, queryInput, true);
|
return this.doRunQuery(uri, selection, queryInput, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run Query implementation
|
* Run Query implementation
|
||||||
*/
|
*/
|
||||||
private async doRunQuery(uri: string, selection: azdata.ISelectionData | string, queryInput: QueryInput,
|
private async doRunQuery(uri: string, selection: azdata.ISelectionData | string, queryInput: QueryEditorInput,
|
||||||
runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise<void> {
|
runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise<void> {
|
||||||
// Reuse existing query runner if it exists
|
// Reuse existing query runner if it exists
|
||||||
let queryRunner: QueryRunner | undefined;
|
let queryRunner: QueryRunner | undefined;
|
||||||
|
|||||||
116
src/sql/platform/query/test/common/testQueryModelService.ts
Normal file
116
src/sql/platform/query/test/common/testQueryModelService.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { IQueryModelService, IQueryEvent } from 'sql/platform/query/common/queryModel';
|
||||||
|
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
||||||
|
import * as azdata from 'azdata';
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
import { Event } from 'vs/base/common/event';
|
||||||
|
import { QueryInfo } from 'sql/platform/query/common/queryModelService';
|
||||||
|
import { DataService } from 'sql/workbench/contrib/grid/common/dataService';
|
||||||
|
|
||||||
|
export class TestQueryModelService implements IQueryModelService {
|
||||||
|
_serviceBrand: any;
|
||||||
|
onRunQueryUpdate: Event<string>;
|
||||||
|
getQueryRunner(uri: string): QueryRunner {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
getConfig(): Promise<{ [key: string]: any; }> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
getShortcuts(): Promise<any> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Promise<azdata.ResultSetSubset> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
runQuery(uri: string, selection: azdata.ISelectionData, queryInput: QueryEditorInput, runOptions?: azdata.ExecutionPlanOptions): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
runQueryStatement(uri: string, selection: azdata.ISelectionData, queryInput: QueryEditorInput): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
runQueryString(uri: string, selection: string, queryInput: QueryEditorInput) {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
cancelQuery(input: string | QueryRunner): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
disposeQuery(uri: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
isRunningQuery(uri: string): boolean {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
getDataService(uri: string): DataService {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
refreshResultsets(uri: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
sendGridContentEvent(uri: string, eventName: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
resizeResultsets(uri: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
onAngularLoaded(uri: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
copyResults(uri: string, selection: Slick.Range[], batchId: number, resultId: number, includeHeaders?: boolean): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
showWarning(uri: string, message: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
showError(uri: string, message: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
showCommitError(error: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
get onRunQueryStart(): Event<string> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
get onRunQueryComplete(): Event<string> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
get onQueryEvent(): Event<IQueryEvent> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
disposeEdit(ownerUri: string): Promise<void> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise<azdata.EditUpdateCellResult> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
commitEdit(ownerUri: any): Promise<void> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
createRow(ownerUri: string): Promise<azdata.EditCreateRowResult> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
deleteRow(ownerUri: string, rowId: number): Promise<void> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
revertCell(ownerUri: string, rowId: number, columnId: number): Promise<azdata.EditRevertCellResult> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
revertRow(ownerUri: string, rowId: number): Promise<void> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
getEditRows(ownerUri: string, rowStart: number, numberOfRows: number): Promise<azdata.EditSubsetResult> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
_getQueryInfo(uri: string): QueryInfo {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
onEditSessionReady: Event<azdata.EditSessionReadyParams>;
|
||||||
|
}
|
||||||
@@ -30,9 +30,10 @@ import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilit
|
|||||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||||
import { viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
|
import { viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
|
||||||
import { notebookModeId } from 'sql/workbench/browser/customInputConverter';
|
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { IFileService } from 'vs/platform/files/common/files';
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
import { UntitledNotebookInput } from 'sql/workbench/contrib/notebook/common/models/untitledNotebookInput';
|
||||||
|
import { FileNotebookInput } from 'sql/workbench/contrib/notebook/common/models/fileNotebookInput';
|
||||||
import { find } from 'vs/base/common/arrays';
|
import { find } from 'vs/base/common/arrays';
|
||||||
|
|
||||||
class MainThreadNotebookEditor extends Disposable {
|
class MainThreadNotebookEditor extends Disposable {
|
||||||
@@ -453,13 +454,18 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
|
|||||||
};
|
};
|
||||||
let isUntitled: boolean = uri.scheme === Schemas.untitled;
|
let isUntitled: boolean = uri.scheme === Schemas.untitled;
|
||||||
|
|
||||||
const fileInput = isUntitled ? this._untitledEditorService.createOrGet(uri, notebookModeId, options.initialContent) :
|
const fileInput = isUntitled ? this._untitledEditorService.createOrGet(uri, 'notebook', options.initialContent) :
|
||||||
this._editorService.createInput({ resource: uri, mode: notebookModeId });
|
this._editorService.createInput({ resource: uri, mode: 'notebook' });
|
||||||
let input = this._instantiationService.createInstance(NotebookInput, path.basename(uri.fsPath), uri, fileInput);
|
let input: NotebookInput;
|
||||||
|
if (isUntitled) {
|
||||||
|
input = this._instantiationService.createInstance(UntitledNotebookInput, path.basename(uri.fsPath), uri, fileInput);
|
||||||
|
} else {
|
||||||
|
input = this._instantiationService.createInstance(FileNotebookInput, path.basename(uri.fsPath), uri, fileInput);
|
||||||
|
}
|
||||||
input.defaultKernel = options.defaultKernel;
|
input.defaultKernel = options.defaultKernel;
|
||||||
input.connectionProfile = new ConnectionProfile(this._capabilitiesService, options.connectionProfile);
|
input.connectionProfile = new ConnectionProfile(this._capabilitiesService, options.connectionProfile);
|
||||||
if (isUntitled) {
|
if (isUntitled) {
|
||||||
let untitledModel = await input.textInput.resolve();
|
let untitledModel = await (input as UntitledNotebookInput).textInput.resolve();
|
||||||
await untitledModel.load();
|
await untitledModel.load();
|
||||||
input.untitledEditorModel = untitledModel;
|
input.untitledEditorModel = untitledModel;
|
||||||
if (options.initialDirtyState === false) {
|
if (options.initialDirtyState === false) {
|
||||||
|
|||||||
@@ -1,246 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
import { EditorInput, IEditorInput } from 'vs/workbench/common/editor';
|
|
||||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
|
||||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
|
||||||
import { URI } from 'vs/base/common/uri';
|
|
||||||
|
|
||||||
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import { IQueryEditorOptions } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
|
||||||
import { QueryPlanInput } from 'sql/workbench/contrib/queryPlan/common/queryPlanInput';
|
|
||||||
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
|
||||||
import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
|
|
||||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
|
||||||
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
|
||||||
import { find } from 'vs/base/common/arrays';
|
|
||||||
|
|
||||||
////// Exported public functions/vars
|
|
||||||
|
|
||||||
// prefix for untitled sql editors
|
|
||||||
export const untitledFilePrefix = 'SQLQuery';
|
|
||||||
|
|
||||||
// mode identifier for SQL mode
|
|
||||||
export const sqlModeId = 'sql';
|
|
||||||
export const notebookModeId = 'notebook';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the specified input is supported by one our custom input types, and if so convert it
|
|
||||||
* to that type.
|
|
||||||
* @param input The input to check for conversion
|
|
||||||
* @param options Editor options for controlling the conversion
|
|
||||||
* @param instantiationService The instantiation service to use to create the new input types
|
|
||||||
*/
|
|
||||||
export function convertEditorInput(input: EditorInput, options: IQueryEditorOptions, instantiationService: IInstantiationService): EditorInput {
|
|
||||||
let denyQueryEditor: boolean = options && options.denyQueryEditor;
|
|
||||||
let untitledEditorInput: UntitledEditorInput = input as UntitledEditorInput;
|
|
||||||
let mode: string = (untitledEditorInput && untitledEditorInput.getMode) ? untitledEditorInput.getMode() : 'sql';
|
|
||||||
if (input && !denyQueryEditor) {
|
|
||||||
let uri: URI;
|
|
||||||
if (mode === 'sql') {
|
|
||||||
//QueryInput
|
|
||||||
uri = getQueryEditorFileUri(input);
|
|
||||||
if (uri) {
|
|
||||||
const queryResultsInput: QueryResultsInput = instantiationService.createInstance(QueryResultsInput, uri.toString(true));
|
|
||||||
let queryInput: QueryInput = instantiationService.createInstance(QueryInput, '', input, queryResultsInput, undefined);
|
|
||||||
return queryInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
//QueryPlanInput
|
|
||||||
uri = getQueryPlanEditorUri(input);
|
|
||||||
if (uri) {
|
|
||||||
return instantiationService.createInstance(QueryPlanInput, uri, undefined);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Notebook
|
|
||||||
uri = getNotebookEditorUri(input, instantiationService);
|
|
||||||
if (uri) {
|
|
||||||
let notebookInput: NotebookInput = instantiationService.createInstance(NotebookInput, input.getName(), uri, input);
|
|
||||||
return notebookInput;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the resource of the input if it's one of the ones we support.
|
|
||||||
* @param input The IEditorInput to get the resource of
|
|
||||||
*/
|
|
||||||
export function getSupportedInputResource(input: IEditorInput): URI {
|
|
||||||
if (input instanceof UntitledEditorInput) {
|
|
||||||
let untitledCast: UntitledEditorInput = <UntitledEditorInput>input;
|
|
||||||
if (untitledCast) {
|
|
||||||
return untitledCast.getResource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input instanceof FileEditorInput) {
|
|
||||||
let fileCast: FileEditorInput = <FileEditorInput>input;
|
|
||||||
if (fileCast) {
|
|
||||||
return fileCast.getResource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input instanceof ResourceEditorInput) {
|
|
||||||
let resourceCast: ResourceEditorInput = <ResourceEditorInput>input;
|
|
||||||
if (resourceCast) {
|
|
||||||
return resourceCast.getResource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
////// Non-Exported Private functions/vars
|
|
||||||
|
|
||||||
// file extensions for the inputs we support (should be all upper case for comparison)
|
|
||||||
const sqlFileTypes = ['SQL'];
|
|
||||||
const sqlPlanFileTypes = ['SQLPLAN'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If input is a supported query editor file, return it's URI. Otherwise return undefined.
|
|
||||||
* @param input The EditorInput to retrieve the URI of
|
|
||||||
*/
|
|
||||||
function getQueryEditorFileUri(input: EditorInput): URI {
|
|
||||||
if (!input || !input.getName()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this editor is not already of type queryinput
|
|
||||||
if (!(input instanceof QueryInput)) {
|
|
||||||
|
|
||||||
// If this editor has a URI
|
|
||||||
let uri: URI = getSupportedInputResource(input);
|
|
||||||
if (uri) {
|
|
||||||
let isValidUri: boolean = !!uri && !!uri.toString;
|
|
||||||
|
|
||||||
if (isValidUri && (hasFileExtension(sqlFileTypes, input, true) || hasSqlFileMode(input))) {
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If input is a supported query plan editor file (.sqlplan), return it's URI. Otherwise return undefined.
|
|
||||||
* @param input The EditorInput to get the URI of
|
|
||||||
*/
|
|
||||||
function getQueryPlanEditorUri(input: EditorInput): URI {
|
|
||||||
if (!input || !input.getName()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this editor is not already of type queryinput
|
|
||||||
if (!(input instanceof QueryPlanInput)) {
|
|
||||||
let uri: URI = getSupportedInputResource(input);
|
|
||||||
if (uri) {
|
|
||||||
if (hasFileExtension(sqlPlanFileTypes, input, false)) {
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If input is a supported notebook editor file (.ipynb), return it's URI. Otherwise return undefined.
|
|
||||||
* @param input The EditorInput to get the URI of.
|
|
||||||
*/
|
|
||||||
function getNotebookEditorUri(input: EditorInput, instantiationService: IInstantiationService): URI {
|
|
||||||
if (!input || !input.getName()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this editor is not already of type notebook input
|
|
||||||
if (!(input instanceof NotebookInput)) {
|
|
||||||
let uri: URI = getSupportedInputResource(input);
|
|
||||||
if (uri) {
|
|
||||||
if (hasFileExtension(getNotebookFileExtensions(instantiationService), input, false) || hasNotebookFileMode(input)) {
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNotebookFileExtensions(instantiationService: IInstantiationService): string[] {
|
|
||||||
return withService<INotebookService, string[]>(instantiationService, INotebookService, notebookService => {
|
|
||||||
return notebookService.getSupportedFileExtensions();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given EditorInput is set to either undefined or notebook mode
|
|
||||||
* @param input The EditorInput to check the mode of
|
|
||||||
*/
|
|
||||||
function hasNotebookFileMode(input: EditorInput): boolean {
|
|
||||||
if (input instanceof UntitledEditorInput) {
|
|
||||||
let untitledCast: UntitledEditorInput = <UntitledEditorInput>input;
|
|
||||||
return (untitledCast && untitledCast.getMode() === notebookModeId);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function withService<TService, TResult>(instantiationService: IInstantiationService, serviceId: ServiceIdentifier<TService>, action: (service: TService) => TResult, ): TResult {
|
|
||||||
return instantiationService.invokeFunction(accessor => {
|
|
||||||
let service = accessor.get(serviceId);
|
|
||||||
return action(service);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given EditorInput is set to either undefined or sql mode
|
|
||||||
* @param input The EditorInput to check the mode of
|
|
||||||
*/
|
|
||||||
function hasSqlFileMode(input: EditorInput): boolean {
|
|
||||||
if (input instanceof UntitledEditorInput) {
|
|
||||||
let untitledCast: UntitledEditorInput = <UntitledEditorInput>input;
|
|
||||||
return untitledCast && (untitledCast.getMode() === undefined || untitledCast.getMode() === sqlModeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the name of the specified input has an extension that is
|
|
||||||
* @param extensions The extensions to check for
|
|
||||||
* @param input The input to check for the specified extensions
|
|
||||||
*/
|
|
||||||
function hasFileExtension(extensions: string[], input: EditorInput, checkUntitledFileType: boolean): boolean {
|
|
||||||
// Check the extension type
|
|
||||||
let lastPeriodIndex = input.getName().lastIndexOf('.');
|
|
||||||
if (lastPeriodIndex > -1) {
|
|
||||||
let extension: string = input.getName().substr(lastPeriodIndex + 1).toUpperCase();
|
|
||||||
return !!find(extensions, x => x === extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for untitled file type
|
|
||||||
if (checkUntitledFileType && find(input.getName(), x => x === untitledFilePrefix)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return false if not a queryEditor file
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns file mode - notebookModeId or sqlModeId
|
|
||||||
export function getFileMode(instantiationService: IInstantiationService, resource: URI): string {
|
|
||||||
if (!resource) {
|
|
||||||
return sqlModeId;
|
|
||||||
}
|
|
||||||
return withService<INotebookService, string>(instantiationService, INotebookService, notebookService => {
|
|
||||||
for (const editor of notebookService.listNotebookEditors()) {
|
|
||||||
if (editor.notebookParams.notebookUri === resource) {
|
|
||||||
return notebookModeId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sqlModeId;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { IModeSupport, IEditorInput } from 'vs/workbench/common/editor';
|
||||||
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
import { getCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||||
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
|
import { localize } from 'vs/nls';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
|
||||||
|
import { ILanguageAssociationRegistry, Extensions as LanguageAssociationExtensions } from 'sql/workbench/common/languageAssociation';
|
||||||
|
|
||||||
|
const languageAssociationRegistry = Registry.as<ILanguageAssociationRegistry>(LanguageAssociationExtensions.LanguageAssociations);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles setting a mode from the editor status and converts inputs if necessary
|
||||||
|
*/
|
||||||
|
export async function setMode(accessor: ServicesAccessor, modeSupport: IModeSupport, activeEditor: IEditorInput, language: string): Promise<void> {
|
||||||
|
const editorService = accessor.get(IEditorService);
|
||||||
|
const instantiationService = accessor.get(IInstantiationService);
|
||||||
|
const activeWidget = getCodeEditor(editorService.activeTextEditorWidget);
|
||||||
|
const activeControl = editorService.activeControl;
|
||||||
|
const textModel = activeWidget.getModel();
|
||||||
|
const oldLanguage = textModel.getLanguageIdentifier().language;
|
||||||
|
if (language !== oldLanguage) {
|
||||||
|
const oldInputCreator = languageAssociationRegistry.getAssociations().filter(e => e.language === oldLanguage)[0]; // who knows how to handle the current language
|
||||||
|
const newInputCreator = languageAssociationRegistry.getAssociations().filter(e => e.language === language)[0]; // who knows how to handle the requested language
|
||||||
|
if ((oldInputCreator || newInputCreator) && activeEditor.isDirty()) { // theres some issues with changing the language on a dirty file with one of our editors (we should look into this)
|
||||||
|
const notificationService = accessor.get(INotificationService);
|
||||||
|
notificationService.error(localize('languageChangeUnsupported', "Changing editor types on unsaved files is unsupported"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modeSupport.setMode(language);
|
||||||
|
let input: IEditorInput;
|
||||||
|
if (oldInputCreator) { // only transform the input if we have someone who knows how to deal with it (e.x QueryInput -> UntitledInput, etc)
|
||||||
|
input = oldInputCreator.baseInputCreator(activeEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newInputCreator) { // if we know how to handle the new language, tranform the input and replace the editor (e.x notebook, sql, etc)
|
||||||
|
const newInput = instantiationService.invokeFunction(newInputCreator.creator, input || activeEditor);
|
||||||
|
if (newInput) { // the factory will return undefined if it doesn't know how to handle the input
|
||||||
|
await editorService.replaceEditors([{ editor: activeEditor, replacement: newInput }], activeControl.group);
|
||||||
|
}
|
||||||
|
} else if (oldInputCreator) { // if we don't know handle to handle the new language but we know how to handle the current language, replace the editor with the reverted input (e.x sql -> text)
|
||||||
|
await editorService.replaceEditors([{ editor: activeEditor, replacement: input }], activeControl.group);
|
||||||
|
} // otherwise we don't know the old language and we don't know the new langauge, so don't do anything and just let vscode handle it (e.x text -> powershell)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,12 +12,12 @@ import {
|
|||||||
import { EditDataInput } from 'sql/workbench/contrib/editData/browser/editDataInput';
|
import { EditDataInput } from 'sql/workbench/contrib/editData/browser/editDataInput';
|
||||||
import { IInsightsDialogService } from 'sql/workbench/services/insights/browser/insightsDialogService';
|
import { IInsightsDialogService } from 'sql/workbench/services/insights/browser/insightsDialogService';
|
||||||
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
|
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import { DashboardInput } from 'sql/workbench/contrib/dashboard/browser/dashboardInput';
|
import { DashboardInput } from 'sql/workbench/contrib/dashboard/browser/dashboardInput';
|
||||||
import { ProfilerInput } from 'sql/workbench/contrib/profiler/browser/profilerInput';
|
import { ProfilerInput } from 'sql/workbench/contrib/profiler/browser/profilerInput';
|
||||||
|
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry';
|
import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry';
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
|
||||||
export function replaceConnection(oldUri: string, newUri: string, connectionService: IConnectionManagementService): Promise<IConnectionResult> {
|
export function replaceConnection(oldUri: string, newUri: string, connectionService: IConnectionManagementService): Promise<IConnectionResult> {
|
||||||
return new Promise<IConnectionResult>((resolve, reject) => {
|
return new Promise<IConnectionResult>((resolve, reject) => {
|
||||||
@@ -87,7 +87,7 @@ export function getCurrentGlobalConnection(objectExplorerService: IObjectExplore
|
|||||||
|
|
||||||
let activeInput = workbenchEditorService.activeEditor;
|
let activeInput = workbenchEditorService.activeEditor;
|
||||||
if (activeInput) {
|
if (activeInput) {
|
||||||
if (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput) {
|
if (activeInput instanceof QueryEditorInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput) {
|
||||||
connection = connectionManagementService.getConnectionProfile(activeInput.uri);
|
connection = connectionManagementService.getConnectionProfile(activeInput.uri);
|
||||||
}
|
}
|
||||||
else if (activeInput instanceof ProfilerInput) {
|
else if (activeInput instanceof ProfilerInput) {
|
||||||
|
|||||||
12
src/sql/workbench/common/editorReplacer.contribution.ts
Normal file
12
src/sql/workbench/common/editorReplacer.contribution.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { EditorReplacementContribution } from 'sql/workbench/common/editorReplacerContribution';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||||
|
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||||
|
|
||||||
|
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||||
|
workbenchContributionsRegistry.registerWorkbenchContribution(EditorReplacementContribution, LifecyclePhase.Starting);
|
||||||
83
src/sql/workbench/common/editorReplacerContribution.ts
Normal file
83
src/sql/workbench/common/editorReplacerContribution.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
|
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||||
|
import { IEditorService, IOpenEditorOverride } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||||
|
import { IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||||
|
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
|
||||||
|
import { ILanguageAssociationRegistry, Extensions as LanguageAssociationExtensions } from 'sql/workbench/common/languageAssociation';
|
||||||
|
|
||||||
|
const languageAssociationRegistry = Registry.as<ILanguageAssociationRegistry>(LanguageAssociationExtensions.LanguageAssociations);
|
||||||
|
|
||||||
|
export class EditorReplacementContribution implements IWorkbenchContribution {
|
||||||
|
private editorOpeningListener: IDisposable;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@IEditorService private readonly editorService: IEditorService,
|
||||||
|
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||||
|
@IModeService private readonly modeService: IModeService
|
||||||
|
) {
|
||||||
|
this.editorOpeningListener = this.editorService.overrideOpenEditor((editor, options, group) => this.onEditorOpening(editor, options, group));
|
||||||
|
}
|
||||||
|
|
||||||
|
private onEditorOpening(editor: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup): IOpenEditorOverride | undefined {
|
||||||
|
// If the resource was already opened before in the group, do not prevent
|
||||||
|
// the opening of that resource. Otherwise we would have the same settings
|
||||||
|
// opened twice (https://github.com/Microsoft/vscode/issues/36447)
|
||||||
|
// if (group.isOpened(editor)) {
|
||||||
|
// return undefined;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (!(editor instanceof FileEditorInput) && !(editor instanceof UntitledEditorInput)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
let language: string;
|
||||||
|
if (editor instanceof FileEditorInput) {
|
||||||
|
language = editor.getPreferredMode();
|
||||||
|
} else if (editor instanceof UntitledEditorInput) {
|
||||||
|
language = editor.getMode();
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!language) { // in the case the input doesn't have a preferred mode set we will attempt to guess the mode from the file path
|
||||||
|
language = this.modeService.getModeIdByFilepathOrFirstLine(editor.getResource());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!language) {
|
||||||
|
const defaultInputCreator = languageAssociationRegistry.getAssociations().filter(e => e.isDefault)[0];
|
||||||
|
if (defaultInputCreator) {
|
||||||
|
editor.setMode(defaultInputCreator.language);
|
||||||
|
const newInput = this.instantiationService.invokeFunction(defaultInputCreator.creator, editor);
|
||||||
|
if (newInput) {
|
||||||
|
return { override: this.editorService.openEditor(newInput, options, group) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const inputCreator = languageAssociationRegistry.getAssociations().filter(e => e.language === language)[0];
|
||||||
|
if (inputCreator) {
|
||||||
|
const newInput = this.instantiationService.invokeFunction(inputCreator.creator, editor);
|
||||||
|
if (newInput) {
|
||||||
|
return { override: this.editorService.openEditor(newInput, options, group) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
dispose(this.editorOpeningListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/sql/workbench/common/languageAssociation.ts
Normal file
34
src/sql/workbench/common/languageAssociation.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||||
|
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
|
export type InputCreator = (servicesAccessor: ServicesAccessor, activeEditor: IEditorInput) => IEditorInput | undefined;
|
||||||
|
export type BaseInputCreator = (activeEditor: IEditorInput) => IEditorInput;
|
||||||
|
|
||||||
|
export interface ILanguageAssociationRegistry {
|
||||||
|
registerLanguageAssociation(language: string, creator: InputCreator, baseInputCreator: BaseInputCreator, isDefault?: boolean): void;
|
||||||
|
getAssociations(): Array<{ language: string, creator: InputCreator, baseInputCreator: BaseInputCreator, isDefault: boolean }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LanguageAssociationRegistry implements ILanguageAssociationRegistry {
|
||||||
|
private associations = new Array<{ language: string, creator: InputCreator, baseInputCreator: BaseInputCreator, isDefault: boolean }>();
|
||||||
|
|
||||||
|
registerLanguageAssociation(language: string, creator: InputCreator, baseInputCreator: BaseInputCreator, isDefault: boolean = false): void {
|
||||||
|
this.associations.push({ language, creator, baseInputCreator, isDefault });
|
||||||
|
}
|
||||||
|
|
||||||
|
getAssociations(): Array<{ language: string, creator: InputCreator, baseInputCreator: BaseInputCreator, isDefault: boolean }> {
|
||||||
|
return this.associations.slice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Extensions = {
|
||||||
|
LanguageAssociations: 'workbench.contributions.editor.languageAssociation'
|
||||||
|
};
|
||||||
|
|
||||||
|
Registry.add(Extensions.LanguageAssociations, new LanguageAssociationRegistry());
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as ConnectionConstants from 'sql/platform/connection/common/constants';
|
import * as ConnectionConstants from 'sql/platform/connection/common/constants';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
@@ -26,11 +26,8 @@ export function getSqlConfigValue<T>(workspaceConfigService: IConfigurationServi
|
|||||||
|
|
||||||
export function getEditorUri(input: IEditorInput): string {
|
export function getEditorUri(input: IEditorInput): string {
|
||||||
let uri: URI;
|
let uri: URI;
|
||||||
if (input instanceof QueryInput) {
|
if (input instanceof QueryEditorInput) {
|
||||||
let queryCast: QueryInput = <QueryInput>input;
|
uri = input.getResource();
|
||||||
if (queryCast) {
|
|
||||||
uri = queryCast.getResource();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uri) {
|
if (uri) {
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
|
|||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry';
|
import { IInsightsConfig } from 'sql/platform/dashboard/browser/insightRegistry';
|
||||||
import { IInsightOptions } from 'sql/workbench/contrib/charts/common/interfaces';
|
import { IInsightOptions } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import { IFileService } from 'vs/platform/files/common/files';
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
import { IFileDialogService, FileFilter } from 'vs/platform/dialogs/common/dialogs';
|
import { IFileDialogService, FileFilter } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { VSBuffer } from 'vs/base/common/buffer';
|
import { VSBuffer } from 'vs/base/common/buffer';
|
||||||
@@ -89,7 +89,7 @@ export class CreateInsightAction extends Action {
|
|||||||
|
|
||||||
private getActiveUriString(): string {
|
private getActiveUriString(): string {
|
||||||
let editor = this.editorService.activeEditor;
|
let editor = this.editorService.activeEditor;
|
||||||
if (editor instanceof QueryInput) {
|
if (editor instanceof QueryEditorInput) {
|
||||||
return editor.uri;
|
return editor.uri;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { ipcRenderer as ipc } from 'electron';
|
|||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
@@ -202,11 +202,9 @@ export class CommandLineWorkbenchContribution implements IWorkbenchContribution,
|
|||||||
// If an open and connectable query editor exists for the given URI, attach it to the connection profile
|
// If an open and connectable query editor exists for the given URI, attach it to the connection profile
|
||||||
private async processFile(uriString: string, profile: IConnectionProfile, warnOnConnectFailure: boolean): Promise<void> {
|
private async processFile(uriString: string, profile: IConnectionProfile, warnOnConnectFailure: boolean): Promise<void> {
|
||||||
let activeEditor = this._editorService.editors.filter(v => v.getResource().toString() === uriString).pop();
|
let activeEditor = this._editorService.editors.filter(v => v.getResource().toString() === uriString).pop();
|
||||||
if (activeEditor) {
|
if (activeEditor instanceof QueryEditorInput && activeEditor.state.connected) {
|
||||||
let queryInput = activeEditor as QueryInput;
|
|
||||||
if (queryInput && queryInput.state.connected) {
|
|
||||||
let options: IConnectionCompletionOptions = {
|
let options: IConnectionCompletionOptions = {
|
||||||
params: { connectionType: ConnectionType.editor, runQueryOnCompletion: RunQueryOnConnectionMode.none, input: queryInput },
|
params: { connectionType: ConnectionType.editor, runQueryOnCompletion: RunQueryOnConnectionMode.none, input: activeEditor },
|
||||||
saveTheConnection: false,
|
saveTheConnection: false,
|
||||||
showDashboard: false,
|
showDashboard: false,
|
||||||
showConnectionDialogOnError: warnOnConnectFailure,
|
showConnectionDialogOnError: warnOnConnectFailure,
|
||||||
@@ -218,7 +216,6 @@ export class CommandLineWorkbenchContribution implements IWorkbenchContribution,
|
|||||||
await this._connectionManagementService.connect(profile, uriString, options);
|
await this._connectionManagementService.connect(profile, uriString, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private readProfileFromArgs(args: SqlArgs) {
|
private readProfileFromArgs(args: SqlArgs) {
|
||||||
let profile = new ConnectionProfile(this._capabilitiesService, null);
|
let profile = new ConnectionProfile(this._capabilitiesService, null);
|
||||||
|
|||||||
@@ -21,11 +21,16 @@ import { TestCommandService } from 'vs/editor/test/browser/editorTestServices';
|
|||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
import { assertThrowsAsync } from 'sql/base/test/common/async';
|
import { assertThrowsAsync } from 'sql/base/test/common/async';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { TestEditorService, TestDialogService } from 'vs/workbench/test/workbenchTestServices';
|
|
||||||
import { QueryInput, QueryEditorState } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import { URI } from 'vs/base/common/uri';
|
|
||||||
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
|
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
|
||||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||||
|
import { TestEditorService, TestDialogService } from 'vs/workbench/test/workbenchTestServices';
|
||||||
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
import { UntitledQueryEditorInput } from 'sql/workbench/contrib/query/common/untitledQueryEditorInput';
|
||||||
|
import { TestQueryModelService } from 'sql/platform/query/test/common/testQueryModelService';
|
||||||
|
import { Event } from 'vs/base/common/event';
|
||||||
|
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
||||||
@@ -129,6 +134,7 @@ suite('commandLineService tests', () => {
|
|||||||
function getConfigurationServiceMock(showConnectDialogOnStartup: boolean): TypeMoq.Mock<IConfigurationService> {
|
function getConfigurationServiceMock(showConnectDialogOnStartup: boolean): TypeMoq.Mock<IConfigurationService> {
|
||||||
let configurationService = TypeMoq.Mock.ofType<IConfigurationService>(TestConfigurationService);
|
let configurationService = TypeMoq.Mock.ofType<IConfigurationService>(TestConfigurationService);
|
||||||
configurationService.setup((c) => c.getValue(TypeMoq.It.isAnyString())).returns((config: string) => showConnectDialogOnStartup);
|
configurationService.setup((c) => c.getValue(TypeMoq.It.isAnyString())).returns((config: string) => showConnectDialogOnStartup);
|
||||||
|
configurationService.object.onDidChangeConfiguration = Event.None;
|
||||||
return configurationService;
|
return configurationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,23 +383,26 @@ suite('commandLineService tests', () => {
|
|||||||
return Promise.resolve('unused');
|
return Promise.resolve('unused');
|
||||||
}).verifiable(TypeMoq.Times.once());
|
}).verifiable(TypeMoq.Times.once());
|
||||||
connectionManagementService.setup(c => c.getConnectionProfileById(TypeMoq.It.isAnyString())).returns(() => originalProfile);
|
connectionManagementService.setup(c => c.getConnectionProfileById(TypeMoq.It.isAnyString())).returns(() => originalProfile);
|
||||||
|
connectionManagementService.setup(c => c.onDisconnect).returns(() => Event.None);
|
||||||
|
connectionManagementService.setup(c => c.ensureDefaultLanguageFlavor(TypeMoq.It.isAny()));
|
||||||
const configurationService = getConfigurationServiceMock(true);
|
const configurationService = getConfigurationServiceMock(true);
|
||||||
const queryInput: TypeMoq.Mock<QueryInput> = TypeMoq.Mock.ofType<QueryInput>(QueryInput);
|
const querymodelService = TypeMoq.Mock.ofType<IQueryModelService>(TestQueryModelService, TypeMoq.MockBehavior.Strict);
|
||||||
|
querymodelService.setup(c => c.onRunQueryStart).returns(() => Event.None);
|
||||||
|
querymodelService.setup(c => c.onRunQueryComplete).returns(() => Event.None);
|
||||||
|
const instantiationService = new TestInstantiationService();
|
||||||
let uri = URI.file(args._[0]);
|
let uri = URI.file(args._[0]);
|
||||||
const queryState = new QueryEditorState();
|
const untitledEditorInput = new UntitledEditorInput(uri, false, '', '', '', instantiationService, undefined, undefined);
|
||||||
queryState.connected = true;
|
const queryInput = new UntitledQueryEditorInput(undefined, untitledEditorInput, undefined, connectionManagementService.object, querymodelService.object, configurationService.object, undefined);
|
||||||
queryInput.setup(q => q.state).returns(() => queryState);
|
queryInput.state.connected = true;
|
||||||
queryInput.setup(q => q.getResource()).returns(() => uri).verifiable(TypeMoq.Times.once());
|
|
||||||
const editorService: TypeMoq.Mock<IEditorService> = TypeMoq.Mock.ofType<IEditorService>(TestEditorService, TypeMoq.MockBehavior.Strict);
|
const editorService: TypeMoq.Mock<IEditorService> = TypeMoq.Mock.ofType<IEditorService>(TestEditorService, TypeMoq.MockBehavior.Strict);
|
||||||
editorService.setup(e => e.editors).returns(() => [queryInput.object]);
|
editorService.setup(e => e.editors).returns(() => [queryInput]);
|
||||||
connectionManagementService.setup(c =>
|
connectionManagementService.setup(c =>
|
||||||
c.connect(TypeMoq.It.is<ConnectionProfile>(p => p.serverName === 'myserver' && p.authenticationType === Constants.sqlLogin),
|
c.connect(TypeMoq.It.is<ConnectionProfile>(p => p.serverName === 'myserver' && p.authenticationType === Constants.sqlLogin),
|
||||||
uri.toString(),
|
uri.toString(),
|
||||||
TypeMoq.It.is<IConnectionCompletionOptions>(i => i.params.input === queryInput.object && i.params.connectionType === ConnectionType.editor))
|
TypeMoq.It.is<IConnectionCompletionOptions>(i => i.params.input === queryInput && i.params.connectionType === ConnectionType.editor))
|
||||||
).verifiable(TypeMoq.Times.once());
|
).verifiable(TypeMoq.Times.once());
|
||||||
let contribution = getCommandLineContribution(connectionManagementService.object, configurationService.object, capabilitiesService, undefined, editorService.object);
|
let contribution = getCommandLineContribution(connectionManagementService.object, configurationService.object, capabilitiesService, undefined, editorService.object);
|
||||||
await contribution.processCommandLine(args);
|
await contribution.processCommandLine(args);
|
||||||
queryInput.verifyAll();
|
|
||||||
connectionManagementService.verifyAll();
|
connectionManagementService.verifyAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { INotificationService, INotificationActions } from 'vs/platform/notifica
|
|||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
import { IDialogService, IConfirmation, IConfirmationResult } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService, IConfirmation, IConfirmationResult } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import { EditDataInput } from 'sql/workbench/contrib/editData/browser/editDataInput';
|
import { EditDataInput } from 'sql/workbench/contrib/editData/browser/editDataInput';
|
||||||
import { DashboardInput } from 'sql/workbench/contrib/dashboard/browser/dashboardInput';
|
import { DashboardInput } from 'sql/workbench/contrib/dashboard/browser/dashboardInput';
|
||||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||||
@@ -156,7 +156,7 @@ export class GetCurrentConnectionStringAction extends Action {
|
|||||||
public run(): Promise<void> {
|
public run(): Promise<void> {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
let activeInput = this._editorService.activeEditor;
|
let activeInput = this._editorService.activeEditor;
|
||||||
if (activeInput && (activeInput instanceof QueryInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput)
|
if (activeInput && (activeInput instanceof QueryEditorInput || activeInput instanceof EditDataInput || activeInput instanceof DashboardInput)
|
||||||
&& this._connectionManagementService.isConnected(activeInput.uri)) {
|
&& this._connectionManagementService.isConnected(activeInput.uri)) {
|
||||||
let includePassword = false;
|
let includePassword = false;
|
||||||
let connectionProfile = this._connectionManagementService.getConnectionProfile(activeInput.uri);
|
let connectionProfile = this._connectionManagementService.getConnectionProfile(activeInput.uri);
|
||||||
|
|||||||
@@ -60,9 +60,7 @@ export class EditDataInput extends EditorInput implements IConnectableInput {
|
|||||||
// re-emit sql editor events through this editor if it exists
|
// re-emit sql editor events through this editor if it exists
|
||||||
if (this._sql) {
|
if (this._sql) {
|
||||||
this._register(this._sql.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
this._register(this._sql.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
||||||
this._sql.disableSaving();
|
|
||||||
}
|
}
|
||||||
this.disableSaving();
|
|
||||||
|
|
||||||
//TODO determine is this is a table or a view
|
//TODO determine is this is a table or a view
|
||||||
this._objectType = 'TABLE';
|
this._objectType = 'TABLE';
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ import { Deferred } from 'sql/base/common/promise';
|
|||||||
import { NotebookTextFileModel } from 'sql/workbench/contrib/notebook/browser/models/notebookTextFileModel';
|
import { NotebookTextFileModel } from 'sql/workbench/contrib/notebook/browser/models/notebookTextFileModel';
|
||||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
|
import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
|
||||||
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
|
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
|
||||||
|
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
|
||||||
|
|
||||||
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;
|
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;
|
||||||
|
|
||||||
@@ -195,8 +198,9 @@ export class NotebookEditorModel extends EditorModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NotebookInput extends EditorInput {
|
type TextInput = ResourceEditorInput | UntitledEditorInput | FileEditorInput;
|
||||||
public static ID: string = 'workbench.editorinputs.notebookInput';
|
|
||||||
|
export abstract class NotebookInput extends EditorInput {
|
||||||
private _providerId: string;
|
private _providerId: string;
|
||||||
private _providers: string[];
|
private _providers: string[];
|
||||||
private _standardKernels: IStandardKernelWithProvider[];
|
private _standardKernels: IStandardKernelWithProvider[];
|
||||||
@@ -217,7 +221,7 @@ export class NotebookInput extends EditorInput {
|
|||||||
|
|
||||||
constructor(private _title: string,
|
constructor(private _title: string,
|
||||||
private resource: URI,
|
private resource: URI,
|
||||||
private _textInput: UntitledEditorInput,
|
private _textInput: TextInput,
|
||||||
@ITextModelService private textModelService: ITextModelService,
|
@ITextModelService private textModelService: ITextModelService,
|
||||||
@IInstantiationService private instantiationService: IInstantiationService,
|
@IInstantiationService private instantiationService: IInstantiationService,
|
||||||
@INotebookService private notebookService: INotebookService,
|
@INotebookService private notebookService: INotebookService,
|
||||||
@@ -233,7 +237,7 @@ export class NotebookInput extends EditorInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get textInput(): UntitledEditorInput {
|
public get textInput(): TextInput {
|
||||||
return this._textInput;
|
return this._textInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,9 +323,7 @@ export class NotebookInput extends EditorInput {
|
|||||||
this._layoutChanged.fire();
|
this._layoutChanged.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTypeId(): string {
|
public abstract getTypeId(): string;
|
||||||
return NotebookInput.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
getResource(): URI {
|
getResource(): URI {
|
||||||
return this.resource;
|
return this.resource;
|
||||||
@@ -352,7 +354,9 @@ export class NotebookInput extends EditorInput {
|
|||||||
textOrUntitledEditorModel = this._untitledEditorModel;
|
textOrUntitledEditorModel = this._untitledEditorModel;
|
||||||
} else {
|
} else {
|
||||||
let resolvedInput = await this._textInput.resolve();
|
let resolvedInput = await this._textInput.resolve();
|
||||||
|
if (!(resolvedInput instanceof BinaryEditorModel)) {
|
||||||
resolvedInput.textEditorModel.onBeforeAttached();
|
resolvedInput.textEditorModel.onBeforeAttached();
|
||||||
|
}
|
||||||
textOrUntitledEditorModel = resolvedInput;
|
textOrUntitledEditorModel = resolvedInput;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,7 +5,17 @@
|
|||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { EditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
|
import { EditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
|
||||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { localize } from 'vs/nls';
|
||||||
|
import { IEditorInputFactoryRegistry, Extensions as EditorInputFactoryExtensions } from 'vs/workbench/common/editor';
|
||||||
|
|
||||||
|
import { ILanguageAssociationRegistry, Extensions as LanguageAssociationExtensions } from 'sql/workbench/common/languageAssociation';
|
||||||
|
import { UntitledNotebookInput } from 'sql/workbench/contrib/notebook/common/models/untitledNotebookInput';
|
||||||
|
import { FileNotebookInput } from 'sql/workbench/contrib/notebook/common/models/fileNotebookInput';
|
||||||
|
import { FileNoteBookEditorInputFactory, UntitledNoteBookEditorInputFactory } from 'sql/workbench/contrib/notebook/common/models/nodebookInputFactory';
|
||||||
|
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionsExtensions } from 'vs/workbench/common/actions';
|
||||||
import { SyncActionDescriptor, registerAction, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
import { SyncActionDescriptor, registerAction, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||||
|
|
||||||
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
||||||
@@ -14,7 +24,6 @@ import { NewNotebookAction } from 'sql/workbench/contrib/notebook/browser/notebo
|
|||||||
import { KeyMod } from 'vs/editor/common/standalone/standaloneBase';
|
import { KeyMod } from 'vs/editor/common/standalone/standaloneBase';
|
||||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||||
import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||||
import { localize } from 'vs/nls';
|
|
||||||
import { GridOutputComponent } from 'sql/workbench/contrib/notebook/browser/outputs/gridOutput.component';
|
import { GridOutputComponent } from 'sql/workbench/contrib/notebook/browser/outputs/gridOutput.component';
|
||||||
import { PlotlyOutputComponent } from 'sql/workbench/contrib/notebook/browser/outputs/plotlyOutput.component';
|
import { PlotlyOutputComponent } from 'sql/workbench/contrib/notebook/browser/outputs/plotlyOutput.component';
|
||||||
import { registerComponentType } from 'sql/workbench/contrib/notebook/browser/outputs/mimeRegistry';
|
import { registerComponentType } from 'sql/workbench/contrib/notebook/browser/outputs/mimeRegistry';
|
||||||
@@ -30,7 +39,6 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
|||||||
import { TreeViewItemHandleArg } from 'sql/workbench/common/views';
|
import { TreeViewItemHandleArg } from 'sql/workbench/common/views';
|
||||||
import { ConnectedContext } from 'azdata';
|
import { ConnectedContext } from 'azdata';
|
||||||
import { TreeNodeContextKey } from 'sql/workbench/contrib/objectExplorer/common/treeNodeContextKey';
|
import { TreeNodeContextKey } from 'sql/workbench/contrib/objectExplorer/common/treeNodeContextKey';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
|
||||||
import { ObjectExplorerActionsContext } from 'sql/workbench/contrib/objectExplorer/browser/objectExplorerActions';
|
import { ObjectExplorerActionsContext } from 'sql/workbench/contrib/objectExplorer/browser/objectExplorerActions';
|
||||||
import { ItemContextKey } from 'sql/workbench/contrib/dashboard/browser/widgets/explorer/explorerTreeContext';
|
import { ItemContextKey } from 'sql/workbench/contrib/dashboard/browser/widgets/explorer/explorerTreeContext';
|
||||||
import { ManageActionContext } from 'sql/workbench/browser/actions';
|
import { ManageActionContext } from 'sql/workbench/browser/actions';
|
||||||
@@ -39,18 +47,30 @@ import { MarkdownOutputComponent } from 'sql/workbench/contrib/notebook/browser/
|
|||||||
import { registerCellComponent } from 'sql/platform/notebooks/common/outputRegistry';
|
import { registerCellComponent } from 'sql/platform/notebooks/common/outputRegistry';
|
||||||
import { TextCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/textCell.component';
|
import { TextCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/textCell.component';
|
||||||
|
|
||||||
// Model View editor registration
|
Registry.as<IEditorInputFactoryRegistry>(EditorInputFactoryExtensions.EditorInputFactories)
|
||||||
const viewModelEditorDescriptor = new EditorDescriptor(
|
.registerEditorInputFactory(FileNotebookInput.ID, FileNoteBookEditorInputFactory);
|
||||||
NotebookEditor,
|
|
||||||
NotebookEditor.ID,
|
Registry.as<IEditorInputFactoryRegistry>(EditorInputFactoryExtensions.EditorInputFactories)
|
||||||
'Notebook'
|
.registerEditorInputFactory(UntitledNotebookInput.ID, UntitledNoteBookEditorInputFactory);
|
||||||
);
|
|
||||||
|
Registry.as<ILanguageAssociationRegistry>(LanguageAssociationExtensions.LanguageAssociations)
|
||||||
|
.registerLanguageAssociation('notebook', (accessor, editor) => {
|
||||||
|
const instantiationService = accessor.get(IInstantiationService);
|
||||||
|
if (editor instanceof FileEditorInput) {
|
||||||
|
return instantiationService.createInstance(FileNotebookInput, editor.getName(), editor.getResource(), editor);
|
||||||
|
} else if (editor instanceof UntitledEditorInput) {
|
||||||
|
return instantiationService.createInstance(UntitledNotebookInput, editor.getName(), editor.getResource(), editor);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}, (editor: NotebookInput) => editor.textInput);
|
||||||
|
|
||||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
||||||
.registerEditor(viewModelEditorDescriptor, [new SyncDescriptor(NotebookInput)]);
|
.registerEditor(new EditorDescriptor(NotebookEditor, NotebookEditor.ID, localize('notebookEditor.name', "Notebook Editor")), [new SyncDescriptor(UntitledNotebookInput), new SyncDescriptor(FileNotebookInput)]);
|
||||||
|
|
||||||
|
|
||||||
// Global Actions
|
// Global Actions
|
||||||
let actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchActionsExtensions.WorkbenchActions);
|
||||||
|
|
||||||
actionRegistry.registerWorkbenchAction(
|
actionRegistry.registerWorkbenchAction(
|
||||||
new SyncActionDescriptor(
|
new SyncActionDescriptor(
|
||||||
@@ -145,7 +165,7 @@ registerAction({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigExtensions.Configuration);
|
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigExtensions.Configuration);
|
||||||
configurationRegistry.registerConfiguration({
|
configurationRegistry.registerConfiguration({
|
||||||
'id': 'notebook',
|
'id': 'notebook',
|
||||||
'title': 'Notebook',
|
'title': 'Notebook',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|||||||
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
|
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
|
||||||
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
|
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
|
||||||
import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin';
|
import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin';
|
||||||
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/contrib/query/common/resultsGridContribution';
|
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/contrib/query/common/resultsGrid.contribution';
|
||||||
import { values } from 'vs/base/common/collections';
|
import { values } from 'vs/base/common/collections';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
|
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
||||||
|
import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
|
|
||||||
|
export class FileNotebookInput extends NotebookInput {
|
||||||
|
public static ID: string = 'workbench.editorinputs.fileNotebookInput';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
title: string,
|
||||||
|
resource: URI,
|
||||||
|
textInput: FileEditorInput,
|
||||||
|
@ITextModelService textModelService: ITextModelService,
|
||||||
|
@IInstantiationService instantiationService: IInstantiationService,
|
||||||
|
@INotebookService notebookService: INotebookService,
|
||||||
|
@IExtensionService extensionService: IExtensionService
|
||||||
|
) {
|
||||||
|
super(title, resource, textInput, textModelService, instantiationService, notebookService, extensionService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get textInput(): FileEditorInput {
|
||||||
|
return super.textInput as FileEditorInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPreferredMode(): string {
|
||||||
|
return this.textInput.getPreferredMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setMode(mode: string): void {
|
||||||
|
this.textInput.setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPreferredMode(mode: string): void {
|
||||||
|
this.textInput.setPreferredMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTypeId(): string {
|
||||||
|
return FileNotebookInput.ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { IEditorInputFactory, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions } from 'vs/workbench/common/editor';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
|
||||||
|
import { FileNotebookInput } from 'sql/workbench/contrib/notebook/common/models/fileNotebookInput';
|
||||||
|
import { UntitledNotebookInput } from 'sql/workbench/contrib/notebook/common/models/untitledNotebookInput';
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
|
||||||
|
const editorInputFactoryRegistry = Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories);
|
||||||
|
|
||||||
|
export class FileNoteBookEditorInputFactory implements IEditorInputFactory {
|
||||||
|
serialize(editorInput: FileNotebookInput): string {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(FILE_EDITOR_INPUT_ID);
|
||||||
|
if (factory) {
|
||||||
|
return factory.serialize(editorInput.textInput); // serialize based on the underlying input
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): FileNotebookInput | undefined {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(FILE_EDITOR_INPUT_ID);
|
||||||
|
const fileEditorInput = factory.deserialize(instantiationService, serializedEditorInput) as FileEditorInput;
|
||||||
|
return instantiationService.createInstance(FileNotebookInput, fileEditorInput.getName(), fileEditorInput.getResource(), fileEditorInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UntitledNoteBookEditorInputFactory implements IEditorInputFactory {
|
||||||
|
serialize(editorInput: UntitledNotebookInput): string {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(UntitledEditorInput.ID);
|
||||||
|
if (factory) {
|
||||||
|
return factory.serialize(editorInput.textInput); // serialize based on the underlying input
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): UntitledNotebookInput | undefined {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(UntitledEditorInput.ID);
|
||||||
|
const untitledEditorInput = factory.deserialize(instantiationService, serializedEditorInput) as UntitledEditorInput;
|
||||||
|
return instantiationService.createInstance(UntitledNotebookInput, untitledEditorInput.getName(), untitledEditorInput.getResource(), untitledEditorInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
||||||
|
import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
|
|
||||||
|
export class UntitledNotebookInput extends NotebookInput {
|
||||||
|
public static ID: string = 'workbench.editorinputs.untitledNotebookInput';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
title: string,
|
||||||
|
resource: URI,
|
||||||
|
textInput: UntitledEditorInput,
|
||||||
|
@ITextModelService textModelService: ITextModelService,
|
||||||
|
@IInstantiationService instantiationService: IInstantiationService,
|
||||||
|
@INotebookService notebookService: INotebookService,
|
||||||
|
@IExtensionService extensionService: IExtensionService
|
||||||
|
) {
|
||||||
|
super(title, resource, textInput, textModelService, instantiationService, notebookService, extensionService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get textInput(): UntitledEditorInput {
|
||||||
|
return super.textInput as UntitledEditorInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setMode(mode: string): void {
|
||||||
|
this.textInput.setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTypeId(): string {
|
||||||
|
return UntitledNotebookInput.ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ import * as ConnectionConstants from 'sql/platform/connection/common/constants';
|
|||||||
import { EditDataEditor } from 'sql/workbench/contrib/editData/browser/editDataEditor';
|
import { EditDataEditor } from 'sql/workbench/contrib/editData/browser/editDataEditor';
|
||||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import { firstIndex } from 'vs/base/common/arrays';
|
import { firstIndex } from 'vs/base/common/arrays';
|
||||||
|
|
||||||
const singleQuote = '\'';
|
const singleQuote = '\'';
|
||||||
@@ -199,7 +199,7 @@ export class RefreshIntellisenseKeyboardAction extends Action {
|
|||||||
|
|
||||||
public run(): Promise<void> {
|
public run(): Promise<void> {
|
||||||
const editor = this.editorService.activeEditor;
|
const editor = this.editorService.activeEditor;
|
||||||
if (editor instanceof QueryInput) {
|
if (editor instanceof QueryEditorInput) {
|
||||||
this.connectionManagementService.rebuildIntelliSenseCache(editor.uri);
|
this.connectionManagementService.rebuildIntelliSenseCache(editor.uri);
|
||||||
}
|
}
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import { QueryEditor } from 'sql/workbench/contrib/query/browser/queryEditor';
|
|||||||
import { QueryResultsEditor } from 'sql/workbench/contrib/query/browser/queryResultsEditor';
|
import { QueryResultsEditor } from 'sql/workbench/contrib/query/browser/queryResultsEditor';
|
||||||
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
||||||
import * as queryContext from 'sql/workbench/contrib/query/common/queryContext';
|
import * as queryContext from 'sql/workbench/contrib/query/common/queryContext';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import {
|
import {
|
||||||
RunQueryKeyboardAction, RunCurrentQueryKeyboardAction, CancelQueryKeyboardAction, RefreshIntellisenseKeyboardAction, ToggleQueryResultsKeyboardAction,
|
RunQueryKeyboardAction, RunCurrentQueryKeyboardAction, CancelQueryKeyboardAction, RefreshIntellisenseKeyboardAction, ToggleQueryResultsKeyboardAction,
|
||||||
RunQueryShortcutAction, RunCurrentQueryWithActualPlanKeyboardAction, FocusOnCurrentQueryKeyboardAction, ParseSyntaxAction
|
RunQueryShortcutAction, RunCurrentQueryWithActualPlanKeyboardAction, FocusOnCurrentQueryKeyboardAction, ParseSyntaxAction
|
||||||
@@ -33,6 +32,14 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr
|
|||||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||||
import { TimeElapsedStatusBarContributions, RowCountStatusBarContributions, QueryStatusStatusBarContributions } from 'sql/workbench/contrib/query/browser/statusBarItems';
|
import { TimeElapsedStatusBarContributions, RowCountStatusBarContributions, QueryStatusStatusBarContributions } from 'sql/workbench/contrib/query/browser/statusBarItems';
|
||||||
import { SqlFlavorStatusbarItem } from 'sql/workbench/contrib/query/browser/flavorStatus';
|
import { SqlFlavorStatusbarItem } from 'sql/workbench/contrib/query/browser/flavorStatus';
|
||||||
|
import { IEditorInputFactoryRegistry, Extensions as EditorInputFactoryExtensions } from 'vs/workbench/common/editor';
|
||||||
|
import { FileQueryEditorInput } from 'sql/workbench/contrib/query/common/fileQueryEditorInput';
|
||||||
|
import { FileQueryEditorInputFactory, UntitledQueryEditorInputFactory } from 'sql/workbench/contrib/query/common/queryInputFactory';
|
||||||
|
import { UntitledQueryEditorInput } from 'sql/workbench/contrib/query/common/untitledQueryEditorInput';
|
||||||
|
import { ILanguageAssociationRegistry, Extensions as LanguageAssociationExtensions } from 'sql/workbench/common/languageAssociation';
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
import { NewQueryTask, OE_NEW_QUERY_ACTION_ID, DE_NEW_QUERY_COMMAND_ID } from 'sql/workbench/contrib/query/browser/queryActions';
|
import { NewQueryTask, OE_NEW_QUERY_ACTION_ID, DE_NEW_QUERY_COMMAND_ID } from 'sql/workbench/contrib/query/browser/queryActions';
|
||||||
import { TreeNodeContextKey } from 'sql/workbench/contrib/objectExplorer/common/treeNodeContextKey';
|
import { TreeNodeContextKey } from 'sql/workbench/contrib/objectExplorer/common/treeNodeContextKey';
|
||||||
import { MssqlNodeContext } from 'sql/workbench/contrib/dataExplorer/browser/mssqlNodeContext';
|
import { MssqlNodeContext } from 'sql/workbench/contrib/dataExplorer/browser/mssqlNodeContext';
|
||||||
@@ -44,25 +51,30 @@ export const QueryEditorVisibleCondition = ContextKeyExpr.has(queryContext.query
|
|||||||
export const ResultsGridFocusCondition = ContextKeyExpr.and(ContextKeyExpr.has(queryContext.resultsVisibleId), ContextKeyExpr.has(queryContext.resultsGridFocussedId));
|
export const ResultsGridFocusCondition = ContextKeyExpr.and(ContextKeyExpr.has(queryContext.resultsVisibleId), ContextKeyExpr.has(queryContext.resultsGridFocussedId));
|
||||||
export const ResultsMessagesFocusCondition = ContextKeyExpr.and(ContextKeyExpr.has(queryContext.resultsVisibleId), ContextKeyExpr.has(queryContext.resultsMessagesFocussedId));
|
export const ResultsMessagesFocusCondition = ContextKeyExpr.and(ContextKeyExpr.has(queryContext.resultsVisibleId), ContextKeyExpr.has(queryContext.resultsMessagesFocussedId));
|
||||||
|
|
||||||
// Editor
|
Registry.as<IEditorInputFactoryRegistry>(EditorInputFactoryExtensions.EditorInputFactories)
|
||||||
const queryResultsEditorDescriptor = new EditorDescriptor(
|
.registerEditorInputFactory(FileQueryEditorInput.ID, FileQueryEditorInputFactory);
|
||||||
QueryResultsEditor,
|
|
||||||
QueryResultsEditor.ID,
|
Registry.as<IEditorInputFactoryRegistry>(EditorInputFactoryExtensions.EditorInputFactories)
|
||||||
'QueryResults'
|
.registerEditorInputFactory(UntitledQueryEditorInput.ID, UntitledQueryEditorInputFactory);
|
||||||
);
|
|
||||||
|
Registry.as<ILanguageAssociationRegistry>(LanguageAssociationExtensions.LanguageAssociations)
|
||||||
|
.registerLanguageAssociation('sql', (accessor, editor) => {
|
||||||
|
const instantiationService = accessor.get(IInstantiationService);
|
||||||
|
const queryResultsInput = instantiationService.createInstance(QueryResultsInput, editor.getResource().toString());
|
||||||
|
if (editor instanceof FileEditorInput) {
|
||||||
|
return instantiationService.createInstance(FileQueryEditorInput, '', editor, queryResultsInput);
|
||||||
|
} else if (editor instanceof UntitledEditorInput) {
|
||||||
|
return instantiationService.createInstance(UntitledQueryEditorInput, '', editor, queryResultsInput);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}, (editor: QueryEditorInput) => editor.text, true);
|
||||||
|
|
||||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
||||||
.registerEditor(queryResultsEditorDescriptor, [new SyncDescriptor(QueryResultsInput)]);
|
.registerEditor(new EditorDescriptor(QueryResultsEditor, QueryResultsEditor.ID, localize('queryResultsEditor.name', "Query Results")), [new SyncDescriptor(QueryResultsInput)]);
|
||||||
|
|
||||||
// Editor
|
|
||||||
const queryEditorDescriptor = new EditorDescriptor(
|
|
||||||
QueryEditor,
|
|
||||||
QueryEditor.ID,
|
|
||||||
'Query'
|
|
||||||
);
|
|
||||||
|
|
||||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
||||||
.registerEditor(queryEditorDescriptor, [new SyncDescriptor(QueryInput)]);
|
.registerEditor(new EditorDescriptor(QueryEditor, QueryEditor.ID, localize('queryEditor.name', "Query Editor")), [new SyncDescriptor(FileQueryEditorInput), new SyncDescriptor(UntitledQueryEditorInput)]);
|
||||||
|
|
||||||
const actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
const actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileE
|
|||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files';
|
import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files';
|
||||||
|
|
||||||
import { QueryInput, IQueryEditorStateChange } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput, IQueryEditorStateChange } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import { QueryResultsEditor } from 'sql/workbench/contrib/query/browser/queryResultsEditor';
|
import { QueryResultsEditor } from 'sql/workbench/contrib/query/browser/queryResultsEditor';
|
||||||
import * as queryContext from 'sql/workbench/contrib/query/common/queryContext';
|
import * as queryContext from 'sql/workbench/contrib/query/common/queryContext';
|
||||||
import { Taskbar, ITaskbarContent } from 'sql/base/browser/ui/taskbar/taskbar';
|
import { Taskbar, ITaskbarContent } from 'sql/base/browser/ui/taskbar/taskbar';
|
||||||
@@ -120,8 +120,8 @@ export class QueryEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PUBLIC METHODS ////////////////////////////////////////////////////////////
|
// PUBLIC METHODS ////////////////////////////////////////////////////////////
|
||||||
public get input(): QueryInput | null {
|
public get input(): QueryEditorInput | null {
|
||||||
return this._input as QueryInput;
|
return this._input as QueryEditorInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,7 +278,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
this.taskbar.setContent(content);
|
this.taskbar.setContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setInput(newInput: QueryInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
public async setInput(newInput: QueryEditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||||
const oldInput = this.input;
|
const oldInput = this.input;
|
||||||
|
|
||||||
if (newInput.matches(oldInput)) {
|
if (newInput.matches(oldInput)) {
|
||||||
@@ -293,7 +293,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we're switching editor types switch out the views
|
// If we're switching editor types switch out the views
|
||||||
const newTextEditor = newInput.sql instanceof FileEditorInput ? this.textFileEditor : this.textResourceEditor;
|
const newTextEditor = newInput.text instanceof FileEditorInput ? this.textFileEditor : this.textResourceEditor;
|
||||||
if (newTextEditor !== this.currentTextEditor) {
|
if (newTextEditor !== this.currentTextEditor) {
|
||||||
this.currentTextEditor = newTextEditor;
|
this.currentTextEditor = newTextEditor;
|
||||||
this.splitview.removeView(0, Sizing.Distribute);
|
this.splitview.removeView(0, Sizing.Distribute);
|
||||||
@@ -309,7 +309,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
super.setInput(newInput, options, token),
|
super.setInput(newInput, options, token),
|
||||||
this.currentTextEditor.setInput(newInput.sql, options, token),
|
this.currentTextEditor.setInput(newInput.text, options, token),
|
||||||
this.resultsEditor.setInput(newInput.results, options)
|
this.resultsEditor.setInput(newInput.results, options)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -324,7 +324,7 @@ export class QueryEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private saveQueryEditorViewState(input: QueryInput): void {
|
private saveQueryEditorViewState(input: QueryEditorInput): void {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return; // ensure we have an input to handle view state for
|
return; // ensure we have an input to handle view state for
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResul
|
|||||||
import { QueryResultsView } from 'sql/workbench/contrib/query/browser/queryResultsView';
|
import { QueryResultsView } from 'sql/workbench/contrib/query/browser/queryResultsView';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||||
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/contrib/query/common/resultsGridContribution';
|
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/contrib/query/common/resultsGrid.contribution';
|
||||||
|
|
||||||
export const TextCompareEditorVisible = new RawContextKey<boolean>('textCompareEditorVisible', false);
|
export const TextCompareEditorVisible = new RawContextKey<boolean>('textCompareEditorVisible', false);
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import { IntervalTimer } from 'vs/base/common/async';
|
|||||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
||||||
import { parseNumAsTimeString } from 'sql/platform/connection/common/utils';
|
import { parseNumAsTimeString } from 'sql/platform/connection/common/utils';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import { IStatusbarService, IStatusbarEntryAccessor, StatusbarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
|
import { IStatusbarService, IStatusbarEntryAccessor, StatusbarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
|
||||||
|
|
||||||
export class TimeElapsedStatusBarContributions extends Disposable implements IWorkbenchContribution {
|
export class TimeElapsedStatusBarContributions extends Disposable implements IWorkbenchContribution {
|
||||||
@@ -56,7 +56,7 @@ export class TimeElapsedStatusBarContributions extends Disposable implements IWo
|
|||||||
this.disposable.clear();
|
this.disposable.clear();
|
||||||
this.hide();
|
this.hide();
|
||||||
const activeInput = this.editorService.activeEditor;
|
const activeInput = this.editorService.activeEditor;
|
||||||
if (activeInput && activeInput instanceof QueryInput && activeInput.uri) {
|
if (activeInput && activeInput instanceof QueryEditorInput && activeInput.uri) {
|
||||||
const uri = activeInput.uri;
|
const uri = activeInput.uri;
|
||||||
const runner = this.queryModelService.getQueryRunner(uri);
|
const runner = this.queryModelService.getQueryRunner(uri);
|
||||||
if (runner) {
|
if (runner) {
|
||||||
@@ -148,7 +148,7 @@ export class RowCountStatusBarContributions extends Disposable implements IWorkb
|
|||||||
this.disposable.clear();
|
this.disposable.clear();
|
||||||
this.hide();
|
this.hide();
|
||||||
const activeInput = this.editorService.activeEditor;
|
const activeInput = this.editorService.activeEditor;
|
||||||
if (activeInput && activeInput instanceof QueryInput && activeInput.uri) {
|
if (activeInput && activeInput instanceof QueryEditorInput && activeInput.uri) {
|
||||||
const uri = activeInput.uri;
|
const uri = activeInput.uri;
|
||||||
const runner = this.queryModelService.getQueryRunner(uri);
|
const runner = this.queryModelService.getQueryRunner(uri);
|
||||||
if (runner) {
|
if (runner) {
|
||||||
@@ -227,7 +227,7 @@ export class QueryStatusStatusBarContributions extends Disposable implements IWo
|
|||||||
this.hide();
|
this.hide();
|
||||||
this.visisbleUri = undefined;
|
this.visisbleUri = undefined;
|
||||||
const activeInput = this.editorService.activeEditor;
|
const activeInput = this.editorService.activeEditor;
|
||||||
if (activeInput && activeInput instanceof QueryInput && activeInput.uri) {
|
if (activeInput && activeInput instanceof QueryEditorInput && activeInput.uri) {
|
||||||
this.visisbleUri = activeInput.uri;
|
this.visisbleUri = activeInput.uri;
|
||||||
const runner = this.queryModelService.getQueryRunner(this.visisbleUri);
|
const runner = this.queryModelService.getQueryRunner(this.visisbleUri);
|
||||||
if (runner && runner.isExecuting) {
|
if (runner && runner.isExecuting) {
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
||||||
|
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||||
|
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||||
|
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
import { EncodingMode } from 'vs/workbench/common/editor';
|
||||||
|
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
|
||||||
|
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
|
||||||
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
|
||||||
|
type PublicPart<T> = { [K in keyof T]: T[K] };
|
||||||
|
|
||||||
|
export class FileQueryEditorInput extends QueryEditorInput implements PublicPart<FileEditorInput> {
|
||||||
|
|
||||||
|
public static readonly ID = 'workbench.editorInput.fileQueryInput';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
description: string,
|
||||||
|
text: FileEditorInput,
|
||||||
|
results: QueryResultsInput,
|
||||||
|
@IConnectionManagementService connectionManagementService: IConnectionManagementService,
|
||||||
|
@IQueryModelService queryModelService: IQueryModelService,
|
||||||
|
@IConfigurationService configurationService: IConfigurationService,
|
||||||
|
@IFileService fileService: IFileService
|
||||||
|
) {
|
||||||
|
super(description, text, results, connectionManagementService, queryModelService, configurationService, fileService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public resolve(): Promise<TextFileEditorModel | BinaryEditorModel> {
|
||||||
|
return this.text.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get text(): FileEditorInput {
|
||||||
|
return this._text as FileEditorInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTypeId(): string {
|
||||||
|
return FileQueryEditorInput.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getEncoding(): string {
|
||||||
|
return this.text.getEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setEncoding(encoding: string, mode: EncodingMode) {
|
||||||
|
this.text.setEncoding(encoding, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPreferredEncoding(): string {
|
||||||
|
return this.text.getPreferredEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPreferredEncoding(encoding: string) {
|
||||||
|
this.text.setPreferredEncoding(encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPreferredMode(): string {
|
||||||
|
return this.text.getPreferredMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setMode(mode: string) {
|
||||||
|
this.text.setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPreferredMode(mode: string) {
|
||||||
|
this.text.setPreferredMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setForceOpenAsText() {
|
||||||
|
this.text.setForceOpenAsText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setForceOpenAsBinary() {
|
||||||
|
this.text.setForceOpenAsBinary();
|
||||||
|
}
|
||||||
|
|
||||||
|
public isResolved(): boolean {
|
||||||
|
return this.text.isResolved();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,10 +5,9 @@
|
|||||||
|
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
import { EditorInput, ConfirmResult } from 'vs/workbench/common/editor';
|
||||||
import { EditorInput, ConfirmResult, EncodingMode, IEncodingSupport } from 'vs/workbench/common/editor';
|
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IFileService } from 'vs/platform/files/common/files';
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
|
||||||
@@ -17,14 +16,10 @@ import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResul
|
|||||||
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||||
|
|
||||||
import { ISelectionData, ExecutionPlanOptions } from 'azdata';
|
import { ISelectionData, ExecutionPlanOptions } from 'azdata';
|
||||||
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
|
|
||||||
import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
|
|
||||||
import { startsWith } from 'vs/base/common/strings';
|
import { startsWith } from 'vs/base/common/strings';
|
||||||
|
|
||||||
const MAX_SIZE = 13;
|
const MAX_SIZE = 13;
|
||||||
|
|
||||||
type PublicPart<T> = { [K in keyof T]: T[K] };
|
|
||||||
|
|
||||||
function trimTitle(title: string): string {
|
function trimTitle(title: string): string {
|
||||||
const length = title.length;
|
const length = title.length;
|
||||||
const diff = length - MAX_SIZE;
|
const diff = length - MAX_SIZE;
|
||||||
@@ -115,79 +110,48 @@ export class QueryEditorState extends Disposable {
|
|||||||
* Input for the QueryEditor. This input is simply a wrapper around a QueryResultsInput for the QueryResultsEditor
|
* Input for the QueryEditor. This input is simply a wrapper around a QueryResultsInput for the QueryResultsEditor
|
||||||
* and a UntitledEditorInput for the SQL File Editor.
|
* and a UntitledEditorInput for the SQL File Editor.
|
||||||
*/
|
*/
|
||||||
export class QueryInput extends EditorInput implements IEncodingSupport, IConnectableInput, PublicPart<UntitledEditorInput>, IDisposable {
|
export abstract class QueryEditorInput extends EditorInput implements IConnectableInput, IDisposable {
|
||||||
|
|
||||||
public static ID: string = 'workbench.editorinputs.queryInput';
|
|
||||||
public static SCHEMA: string = 'sql';
|
public static SCHEMA: string = 'sql';
|
||||||
|
|
||||||
private _state = this._register(new QueryEditorState());
|
private _state = this._register(new QueryEditorState());
|
||||||
public get state(): QueryEditorState { return this._state; }
|
public get state(): QueryEditorState { return this._state; }
|
||||||
|
|
||||||
private _updateSelection: Emitter<ISelectionData>;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _description: string,
|
private _description: string,
|
||||||
private _sql: UntitledEditorInput,
|
protected _text: EditorInput,
|
||||||
private _results: QueryResultsInput,
|
protected _results: QueryResultsInput,
|
||||||
private _connectionProviderName: string,
|
@IConnectionManagementService private readonly connectionManagementService: IConnectionManagementService,
|
||||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
@IQueryModelService private readonly queryModelService: IQueryModelService,
|
||||||
@IQueryModelService private _queryModelService: IQueryModelService,
|
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||||
@IConfigurationService private _configurationService: IConfigurationService,
|
|
||||||
@IFileService private _fileService: IFileService
|
@IFileService private _fileService: IFileService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._updateSelection = new Emitter<ISelectionData>();
|
|
||||||
|
|
||||||
this._register(this._sql);
|
this._register(this._text);
|
||||||
this._register(this._results);
|
this._register(this._results);
|
||||||
|
|
||||||
// re-emit sql editor events through this editor if it exists
|
this._text.onDidChangeDirty(() => this._onDidChangeDirty.fire());
|
||||||
if (this._sql) {
|
|
||||||
this._register(this._sql.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attach to event callbacks
|
|
||||||
if (this._queryModelService) {
|
|
||||||
// Register callbacks for the Actions
|
|
||||||
this._register(
|
|
||||||
this._queryModelService.onRunQueryStart(uri => {
|
|
||||||
if (this.uri === uri) {
|
|
||||||
this.onRunQuery();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
this._register(
|
this._register(
|
||||||
this._queryModelService.onRunQueryComplete(uri => {
|
this.queryModelService.onRunQueryComplete(uri => {
|
||||||
if (this.uri === uri) {
|
if (this.uri === uri) {
|
||||||
this.onQueryComplete();
|
this.onQueryComplete();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (this._connectionManagementService) {
|
this._register(this.connectionManagementService.onDisconnect(result => {
|
||||||
this._register(this._connectionManagementService.onDisconnect(result => {
|
|
||||||
if (result.connectionUri === this.uri) {
|
if (result.connectionUri === this.uri) {
|
||||||
this.onDisconnect();
|
this.onDisconnect();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
if (this.uri) {
|
|
||||||
if (this._connectionProviderName) {
|
|
||||||
this._connectionManagementService.doChangeLanguageFlavor(this.uri, 'sql', this._connectionProviderName);
|
|
||||||
} else {
|
|
||||||
this._connectionManagementService.ensureDefaultLanguageFlavor(this.uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._configurationService) {
|
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||||
this._register(this._configurationService.onDidChangeConfiguration(e => {
|
if (e.affectedKeys.indexOf('sql.showConnectionInfoInTitle') > -1) {
|
||||||
if (e.affectsConfiguration('sql.showConnectionInfoInTitle')) {
|
|
||||||
this._onDidChangeLabel.fire();
|
this._onDidChangeLabel.fire();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
|
|
||||||
this.onDisconnect();
|
this.onDisconnect();
|
||||||
this.onQueryComplete();
|
this.onQueryComplete();
|
||||||
@@ -195,47 +159,30 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
|||||||
|
|
||||||
// Getters for private properties
|
// Getters for private properties
|
||||||
public get uri(): string { return this.getResource().toString(true); }
|
public get uri(): string { return this.getResource().toString(true); }
|
||||||
public get sql(): UntitledEditorInput { return this._sql; }
|
public get text(): EditorInput { return this._text; }
|
||||||
public get results(): QueryResultsInput { return this._results; }
|
public get results(): QueryResultsInput { return this._results; }
|
||||||
public updateSelection(selection: ISelectionData): void { this._updateSelection.fire(selection); }
|
|
||||||
public getTypeId(): string { return QueryInput.ID; }
|
|
||||||
// Description is shown beside the tab name in the combobox of open editors
|
// Description is shown beside the tab name in the combobox of open editors
|
||||||
public getDescription(): string { return this._description; }
|
public getDescription(): string { return this._description; }
|
||||||
public supportsSplitEditor(): boolean { return false; }
|
public supportsSplitEditor(): boolean { return false; }
|
||||||
public getMode(): string { return QueryInput.SCHEMA; }
|
public revert(): Promise<boolean> { return this._text.revert(); }
|
||||||
public revert(): Promise<boolean> { return this._sql.revert(); }
|
|
||||||
public setMode(mode: string) {
|
|
||||||
this._sql.setMode(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public matches(otherInput: any): boolean {
|
public matches(otherInput: any): boolean {
|
||||||
if (otherInput instanceof QueryInput) {
|
// we want to be able to match against our underlying input as well, bascially we are our underlying input
|
||||||
return this._sql.matches(otherInput.sql);
|
if (otherInput instanceof QueryEditorInput) {
|
||||||
|
return this._text.matches(otherInput._text);
|
||||||
|
} else {
|
||||||
|
return this._text.matches(otherInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._sql.matches(otherInput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forwarding resource functions to the inline sql file editor
|
// Forwarding resource functions to the inline sql file editor
|
||||||
public get onDidModelChangeContent(): Event<void> { return this._sql.onDidModelChangeContent; }
|
public save(): Promise<boolean> { return this._text.save(); }
|
||||||
public get onDidModelChangeEncoding(): Event<void> { return this._sql.onDidModelChangeEncoding; }
|
public isDirty(): boolean { return this._text.isDirty(); }
|
||||||
public resolve(): Promise<UntitledEditorModel & IResolvedTextEditorModel> { return this._sql.resolve(); }
|
public confirmSave(): Promise<ConfirmResult> { return this._text.confirmSave(); }
|
||||||
public save(): Promise<boolean> { return this._sql.save(); }
|
public getResource(): URI { return this._text.getResource(); }
|
||||||
public isDirty(): boolean { return this._sql.isDirty(); }
|
|
||||||
public confirmSave(): Promise<ConfirmResult> { return this._sql.confirmSave(); }
|
|
||||||
public getResource(): URI { return this._sql.getResource(); }
|
|
||||||
public getEncoding(): string { return this._sql.getEncoding(); }
|
|
||||||
public suggestFileName(): string { return this._sql.suggestFileName(); }
|
|
||||||
hasBackup(): boolean {
|
|
||||||
if (this.sql) {
|
|
||||||
return this.sql.hasBackup();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public matchInputInstanceType(inputType: any): boolean {
|
public matchInputInstanceType(inputType: any): boolean {
|
||||||
return (this._sql instanceof inputType);
|
return (this._text instanceof inputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public inputFileExists(): Promise<boolean> {
|
public inputFileExists(): Promise<boolean> {
|
||||||
@@ -243,8 +190,8 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getName(longForm?: boolean): string {
|
public getName(longForm?: boolean): string {
|
||||||
if (this._configurationService.getValue('sql.showConnectionInfoInTitle')) {
|
if (this.configurationService.getValue('sql.showConnectionInfoInTitle')) {
|
||||||
let profile = this._connectionManagementService.getConnectionProfile(this.uri);
|
let profile = this.connectionManagementService.getConnectionProfile(this.uri);
|
||||||
let title = '';
|
let title = '';
|
||||||
if (this._description && this._description !== '') {
|
if (this._description && this._description !== '') {
|
||||||
title = this._description + ' ';
|
title = this._description + ' ';
|
||||||
@@ -258,36 +205,30 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
|||||||
} else {
|
} else {
|
||||||
title += localize('disconnected', "disconnected");
|
title += localize('disconnected', "disconnected");
|
||||||
}
|
}
|
||||||
return this._sql.getName() + (longForm ? (' - ' + title) : ` - ${trimTitle(title)}`);
|
return this._text.getName() + (longForm ? (' - ' + title) : ` - ${trimTitle(title)}`);
|
||||||
} else {
|
} else {
|
||||||
return this._sql.getName();
|
return this._text.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to get the tooltip of the tab
|
// Called to get the tooltip of the tab
|
||||||
public getTitle() {
|
public getTitle(): string {
|
||||||
return this.getName(true);
|
return this.getName(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get hasAssociatedFilePath(): boolean { return this._sql.hasAssociatedFilePath; }
|
|
||||||
|
|
||||||
public setEncoding(encoding: string, mode: EncodingMode /* ignored, we only have Encode */): void {
|
|
||||||
this._sql.setEncoding(encoding, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// State update funtions
|
// State update funtions
|
||||||
public runQuery(selection?: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void {
|
public runQuery(selection?: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void {
|
||||||
this._queryModelService.runQuery(this.uri, selection, this, executePlanOptions);
|
this.queryModelService.runQuery(this.uri, selection, this, executePlanOptions);
|
||||||
this.state.executing = true;
|
this.state.executing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public runQueryStatement(selection?: ISelectionData): void {
|
public runQueryStatement(selection?: ISelectionData): void {
|
||||||
this._queryModelService.runQueryStatement(this.uri, selection, this);
|
this.queryModelService.runQueryStatement(this.uri, selection, this);
|
||||||
this.state.executing = true;
|
this.state.executing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public runQueryString(text: string): void {
|
public runQueryString(text: string): void {
|
||||||
this._queryModelService.runQueryString(this.uri, text, this);
|
this.queryModelService.runQueryString(this.uri, text, this);
|
||||||
this.state.executing = true;
|
this.state.executing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +255,7 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
|||||||
this.state.connected = true;
|
this.state.connected = true;
|
||||||
this.state.connecting = false;
|
this.state.connecting = false;
|
||||||
|
|
||||||
let isRunningQuery = this._queryModelService.isRunningQuery(this.uri);
|
let isRunningQuery = this.queryModelService.isRunningQuery(this.uri);
|
||||||
if (!isRunningQuery && params && params.runQueryOnCompletion) {
|
if (!isRunningQuery && params && params.runQueryOnCompletion) {
|
||||||
let selection: ISelectionData | undefined = params ? params.querySelection : undefined;
|
let selection: ISelectionData | undefined = params ? params.querySelection : undefined;
|
||||||
if (params.runQueryOnCompletion === RunQueryOnConnectionMode.executeCurrentQuery) {
|
if (params.runQueryOnCompletion === RunQueryOnConnectionMode.executeCurrentQuery) {
|
||||||
@@ -345,10 +286,10 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
|||||||
}
|
}
|
||||||
|
|
||||||
public close(): void {
|
public close(): void {
|
||||||
this._queryModelService.disposeQuery(this.uri);
|
this.queryModelService.disposeQuery(this.uri);
|
||||||
this._connectionManagementService.disconnectEditor(this, true);
|
this.connectionManagementService.disconnectEditor(this, true);
|
||||||
|
|
||||||
this._sql.close();
|
this._text.close();
|
||||||
this._results.close();
|
this._results.close();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
@@ -357,7 +298,7 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
|||||||
* Get the color that should be displayed
|
* Get the color that should be displayed
|
||||||
*/
|
*/
|
||||||
public get tabColor(): string {
|
public get tabColor(): string {
|
||||||
return this._connectionManagementService.getTabColorForUri(this.uri);
|
return this.connectionManagementService.getTabColorForUri(this.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get isSharedSession(): boolean {
|
public get isSharedSession(): boolean {
|
||||||
50
src/sql/workbench/contrib/query/common/queryInputFactory.ts
Normal file
50
src/sql/workbench/contrib/query/common/queryInputFactory.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { IEditorInputFactory, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions } from 'vs/workbench/common/editor';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
||||||
|
import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
|
||||||
|
import { UntitledQueryEditorInput } from 'sql/workbench/contrib/query/common/untitledQueryEditorInput';
|
||||||
|
import { FileQueryEditorInput } from 'sql/workbench/contrib/query/common/fileQueryEditorInput';
|
||||||
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
|
||||||
|
const editorInputFactoryRegistry = Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories);
|
||||||
|
|
||||||
|
export class FileQueryEditorInputFactory implements IEditorInputFactory {
|
||||||
|
serialize(editorInput: FileQueryEditorInput): string {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(FILE_EDITOR_INPUT_ID);
|
||||||
|
if (factory) {
|
||||||
|
return factory.serialize(editorInput.text); // serialize based on the underlying input
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): FileQueryEditorInput | undefined {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(FILE_EDITOR_INPUT_ID);
|
||||||
|
const fileEditorInput = factory.deserialize(instantiationService, serializedEditorInput) as FileEditorInput;
|
||||||
|
const queryResultsInput = instantiationService.createInstance(QueryResultsInput, fileEditorInput.getResource().toString());
|
||||||
|
return instantiationService.createInstance(FileQueryEditorInput, '', fileEditorInput, queryResultsInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UntitledQueryEditorInputFactory implements IEditorInputFactory {
|
||||||
|
serialize(editorInput: UntitledQueryEditorInput): string {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(UntitledEditorInput.ID);
|
||||||
|
if (factory) {
|
||||||
|
return factory.serialize(editorInput.text); // serialize based on the underlying input
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): UntitledQueryEditorInput | undefined {
|
||||||
|
const factory = editorInputFactoryRegistry.getEditorInputFactory(UntitledEditorInput.ID);
|
||||||
|
const untitledEditorInput = factory.deserialize(instantiationService, serializedEditorInput) as UntitledEditorInput;
|
||||||
|
const queryResultsInput = instantiationService.createInstance(QueryResultsInput, untitledEditorInput.getResource().toString());
|
||||||
|
return instantiationService.createInstance(UntitledQueryEditorInput, '', untitledEditorInput, queryResultsInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
||||||
|
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||||
|
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||||
|
|
||||||
|
import { IEncodingSupport, EncodingMode } from 'vs/workbench/common/editor';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
|
||||||
|
import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||||
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
|
||||||
|
type PublicPart<T> = { [K in keyof T]: T[K] };
|
||||||
|
|
||||||
|
export class UntitledQueryEditorInput extends QueryEditorInput implements IEncodingSupport, PublicPart<UntitledEditorInput> {
|
||||||
|
|
||||||
|
public static readonly ID = 'workbench.editorInput.untitledQueryInput';
|
||||||
|
|
||||||
|
public readonly onDidModelChangeContent = this.text.onDidModelChangeContent;
|
||||||
|
public readonly onDidModelChangeEncoding = this.text.onDidModelChangeEncoding;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
description: string,
|
||||||
|
text: UntitledEditorInput,
|
||||||
|
results: QueryResultsInput,
|
||||||
|
@IConnectionManagementService connectionManagementService: IConnectionManagementService,
|
||||||
|
@IQueryModelService queryModelService: IQueryModelService,
|
||||||
|
@IConfigurationService configurationService: IConfigurationService,
|
||||||
|
@IFileService fileService: IFileService
|
||||||
|
) {
|
||||||
|
super(description, text, results, connectionManagementService, queryModelService, configurationService, fileService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public resolve(): Promise<UntitledEditorModel & IResolvedTextEditorModel> {
|
||||||
|
return this.text.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get text(): UntitledEditorInput {
|
||||||
|
return this._text as UntitledEditorInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hasAssociatedFilePath(): boolean {
|
||||||
|
return this.text.hasAssociatedFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public suggestFileName(): string {
|
||||||
|
return this.text.suggestFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setMode(mode: string): void {
|
||||||
|
this.text.setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMode(): string {
|
||||||
|
return this.text.getMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTypeId(): string {
|
||||||
|
return UntitledQueryEditorInput.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getEncoding(): string {
|
||||||
|
return this.text.getEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setEncoding(encoding: string, mode: EncodingMode): void {
|
||||||
|
this.text.setEncoding(encoding, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasBackup(): boolean {
|
||||||
|
if (this.text) {
|
||||||
|
return this.text.hasBackup();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,50 +3,48 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
|
|
||||||
import { ISelectionData } from 'azdata';
|
import { ISelectionData } from 'azdata';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IConnectionManagementService,
|
|
||||||
IConnectionParams,
|
IConnectionParams,
|
||||||
INewConnectionParams,
|
INewConnectionParams,
|
||||||
ConnectionType,
|
ConnectionType,
|
||||||
RunQueryOnConnectionMode
|
RunQueryOnConnectionMode
|
||||||
} from 'sql/platform/connection/common/connectionManagement';
|
} from 'sql/platform/connection/common/connectionManagement';
|
||||||
import { ConnectionDialogService } from 'sql/workbench/services/connection/browser/connectionDialogService';
|
|
||||||
import {
|
import {
|
||||||
RunQueryAction, CancelQueryAction, ListDatabasesActionItem,
|
RunQueryAction, CancelQueryAction, ListDatabasesActionItem,
|
||||||
DisconnectDatabaseAction, ConnectDatabaseAction, QueryTaskbarAction
|
DisconnectDatabaseAction, ConnectDatabaseAction, QueryTaskbarAction
|
||||||
} from 'sql/workbench/contrib/query/browser/queryActions';
|
} from 'sql/workbench/contrib/query/browser/queryActions';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import { QueryEditor } from 'sql/workbench/contrib/query/browser/queryEditor';
|
import { QueryEditor } from 'sql/workbench/contrib/query/browser/queryEditor';
|
||||||
import { QueryModelService } from 'sql/platform/query/common/queryModelService';
|
import { QueryModelService } from 'sql/platform/query/common/queryModelService';
|
||||||
import { ConnectionManagementService } from 'sql/workbench/services/connection/browser/connectionManagementService';
|
|
||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
|
|
||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import { TestStorageService, TestFileService } from 'vs/workbench/test/workbenchTestServices';
|
import { TestStorageService, TestFileService } from 'vs/workbench/test/workbenchTestServices';
|
||||||
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
||||||
|
import { UntitledQueryEditorInput } from 'sql/workbench/contrib/query/common/untitledQueryEditorInput';
|
||||||
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { TestQueryModelService } from 'sql/platform/query/test/common/testQueryModelService';
|
||||||
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
let none: void;
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||||
|
import { TestConnectionManagementService } from 'sql/platform/connection/test/common/testConnectionManagementService';
|
||||||
|
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||||
|
|
||||||
suite('SQL QueryAction Tests', () => {
|
suite('SQL QueryAction Tests', () => {
|
||||||
|
|
||||||
let testUri: string = 'testURI';
|
let testUri: string = 'testURI';
|
||||||
let editor: TypeMoq.Mock<QueryEditor>;
|
let editor: TypeMoq.Mock<QueryEditor>;
|
||||||
let calledRunQueryOnInput: boolean = undefined;
|
let calledRunQueryOnInput: boolean = undefined;
|
||||||
let testQueryInput: TypeMoq.Mock<QueryInput>;
|
let testQueryInput: TypeMoq.Mock<UntitledQueryEditorInput>;
|
||||||
let configurationService: TypeMoq.Mock<IConfigurationService>;
|
let configurationService: TypeMoq.Mock<TestConfigurationService>;
|
||||||
|
let queryModelService: TypeMoq.Mock<TestQueryModelService>;
|
||||||
|
let connectionManagementService: TypeMoq.Mock<TestConnectionManagementService>;
|
||||||
|
|
||||||
setup(() => {
|
setup(() => {
|
||||||
// Setup a reusable mock QueryInput
|
|
||||||
testQueryInput = TypeMoq.Mock.ofType(QueryInput, TypeMoq.MockBehavior.Strict);
|
|
||||||
testQueryInput.setup(x => x.uri).returns(() => testUri);
|
|
||||||
testQueryInput.setup(x => x.runQuery(undefined)).callback(() => { calledRunQueryOnInput = true; });
|
|
||||||
|
|
||||||
const contextkeyservice = new MockContextKeyService();
|
const contextkeyservice = new MockContextKeyService();
|
||||||
|
|
||||||
@@ -65,6 +63,17 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
configurationService.setup(x => x.getValue(TypeMoq.It.isAny())).returns(() => {
|
configurationService.setup(x => x.getValue(TypeMoq.It.isAny())).returns(() => {
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
queryModelService = TypeMoq.Mock.ofType<TestQueryModelService>(TestQueryModelService);
|
||||||
|
queryModelService.setup(q => q.onRunQueryStart).returns(() => Event.None);
|
||||||
|
queryModelService.setup(q => q.onRunQueryComplete).returns(() => Event.None);
|
||||||
|
connectionManagementService = TypeMoq.Mock.ofType<TestConnectionManagementService>(TestConnectionManagementService);
|
||||||
|
connectionManagementService.setup(q => q.onDisconnect).returns(() => Event.None);
|
||||||
|
const instantiationService = new TestInstantiationService();
|
||||||
|
let fileInput = new UntitledEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, undefined);
|
||||||
|
// Setup a reusable mock QueryInput
|
||||||
|
testQueryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Strict, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||||
|
testQueryInput.setup(x => x.uri).returns(() => testUri);
|
||||||
|
testQueryInput.setup(x => x.runQuery(undefined)).callback(() => { calledRunQueryOnInput = true; });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('setClass sets child CSS class correctly', (done) => {
|
test('setClass sets child CSS class correctly', (done) => {
|
||||||
@@ -82,7 +91,6 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let isConnectedReturnValue: boolean = false;
|
let isConnectedReturnValue: boolean = false;
|
||||||
|
|
||||||
// ... Mock "isConnected in ConnectionManagementService
|
// ... Mock "isConnected in ConnectionManagementService
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {}, {}, new TestStorageService());
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnectedReturnValue);
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnectedReturnValue);
|
||||||
|
|
||||||
const contextkeyservice = new MockContextKeyService();
|
const contextkeyservice = new MockContextKeyService();
|
||||||
@@ -114,19 +122,15 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let connectionParams: INewConnectionParams = undefined;
|
let connectionParams: INewConnectionParams = undefined;
|
||||||
let countCalledShowDialog: number = 0;
|
let countCalledShowDialog: number = 0;
|
||||||
|
|
||||||
// ... Mock "showDialog" ConnectionDialogService
|
// ... Mock "isConnected" in ConnectionManagementService
|
||||||
let connectionDialogService = TypeMoq.Mock.ofType(ConnectionDialogService, TypeMoq.MockBehavior.Loose);
|
connectionManagementService.callBase = true;
|
||||||
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), undefined, undefined, undefined))
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
||||||
.callback((service: IConnectionManagementService, params: INewConnectionParams) => {
|
connectionManagementService.setup(x => x.showConnectionDialog(TypeMoq.It.isAny()))
|
||||||
|
.callback((params: INewConnectionParams) => {
|
||||||
connectionParams = params;
|
connectionParams = params;
|
||||||
countCalledShowDialog++;
|
countCalledShowDialog++;
|
||||||
})
|
})
|
||||||
.returns(() => Promise.resolve(none));
|
.returns(() => Promise.resolve());
|
||||||
|
|
||||||
// ... Mock "isConnected" in ConnectionManagementService
|
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {}, undefined, connectionDialogService.object);
|
|
||||||
connectionManagementService.callBase = true;
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
|
||||||
|
|
||||||
// ... Mock QueryModelService
|
// ... Mock QueryModelService
|
||||||
let queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose);
|
let queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose);
|
||||||
@@ -143,7 +147,6 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
testQueryInput.verify(x => x.runQuery(undefined), TypeMoq.Times.never());
|
testQueryInput.verify(x => x.runQuery(undefined), TypeMoq.Times.never());
|
||||||
|
|
||||||
// and the connection dialog should open with the correct parameter details
|
// and the connection dialog should open with the correct parameter details
|
||||||
assert.equal(countCalledShowDialog, 1, 'run should call showDialog');
|
|
||||||
assert.equal(connectionParams.connectionType, ConnectionType.editor, 'connectionType should be queryEditor');
|
assert.equal(connectionParams.connectionType, ConnectionType.editor, 'connectionType should be queryEditor');
|
||||||
assert.equal(connectionParams.runQueryOnCompletion, RunQueryOnConnectionMode.executeQuery, 'runQueryOnCompletion should be true`');
|
assert.equal(connectionParams.runQueryOnCompletion, RunQueryOnConnectionMode.executeQuery, 'runQueryOnCompletion should be true`');
|
||||||
assert.equal(connectionParams.input.uri, testUri, 'URI should be set to the test URI');
|
assert.equal(connectionParams.input.uri, testUri, 'URI should be set to the test URI');
|
||||||
@@ -166,9 +169,18 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let isSelectionEmpty: boolean = undefined;
|
let isSelectionEmpty: boolean = undefined;
|
||||||
let countCalledRunQuery: number = 0;
|
let countCalledRunQuery: number = 0;
|
||||||
|
|
||||||
|
// ... Mock "isConnected" in ConnectionManagementService
|
||||||
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => true);
|
||||||
|
|
||||||
|
// ... Mock QueryModelService
|
||||||
|
let queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose);
|
||||||
|
queryModelService.setup(x => x.onRunQueryStart).returns(() => Event.None);
|
||||||
|
queryModelService.setup(x => x.onRunQueryComplete).returns(() => Event.None);
|
||||||
|
const instantiationService = new TestInstantiationService();
|
||||||
|
let fileInput = new UntitledEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, undefined);
|
||||||
|
|
||||||
// ... Mock "isSelectionEmpty" in QueryEditor
|
// ... Mock "isSelectionEmpty" in QueryEditor
|
||||||
let queryInput: TypeMoq.Mock<QueryInput> = TypeMoq.Mock.ofType(QueryInput, TypeMoq.MockBehavior.Strict);
|
let queryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Strict, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||||
queryInput = TypeMoq.Mock.ofType(QueryInput, TypeMoq.MockBehavior.Strict);
|
|
||||||
queryInput.setup(x => x.uri).returns(() => testUri);
|
queryInput.setup(x => x.uri).returns(() => testUri);
|
||||||
queryInput.setup(x => x.runQuery(undefined)).callback(() => {
|
queryInput.setup(x => x.runQuery(undefined)).callback(() => {
|
||||||
countCalledRunQuery++;
|
countCalledRunQuery++;
|
||||||
@@ -183,14 +195,6 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
queryEditor.setup(x => x.getSelection(false)).returns(() => undefined);
|
queryEditor.setup(x => x.getSelection(false)).returns(() => undefined);
|
||||||
queryEditor.setup(x => x.isSelectionEmpty()).returns(() => isSelectionEmpty);
|
queryEditor.setup(x => x.isSelectionEmpty()).returns(() => isSelectionEmpty);
|
||||||
|
|
||||||
// ... Mock "isConnected" in ConnectionManagementService
|
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {});
|
|
||||||
connectionManagementService.callBase = true;
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => true);
|
|
||||||
|
|
||||||
// ... Mock QueryModelService
|
|
||||||
let queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose);
|
|
||||||
|
|
||||||
// If I call run on RunQueryAction when I have a non empty selection
|
// If I call run on RunQueryAction when I have a non empty selection
|
||||||
let queryAction: RunQueryAction = new RunQueryAction(queryEditor.object, queryModelService.object, connectionManagementService.object);
|
let queryAction: RunQueryAction = new RunQueryAction(queryEditor.object, queryModelService.object, connectionManagementService.object);
|
||||||
isSelectionEmpty = false;
|
isSelectionEmpty = false;
|
||||||
@@ -221,17 +225,11 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let selectionToReturnInGetSelection: ISelectionData = undefined;
|
let selectionToReturnInGetSelection: ISelectionData = undefined;
|
||||||
let predefinedSelection: ISelectionData = { startLine: 1, startColumn: 2, endLine: 3, endColumn: 4 };
|
let predefinedSelection: ISelectionData = { startLine: 1, startColumn: 2, endLine: 3, endColumn: 4 };
|
||||||
|
|
||||||
// ... Mock "showDialog" ConnectionDialogService
|
|
||||||
let connectionDialogService = TypeMoq.Mock.ofType(ConnectionDialogService, TypeMoq.MockBehavior.Loose);
|
|
||||||
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), undefined, undefined, undefined))
|
|
||||||
.callback((service: IConnectionManagementService, params: INewConnectionParams) => {
|
|
||||||
showDialogConnectionParams = params;
|
|
||||||
countCalledShowDialog++;
|
|
||||||
})
|
|
||||||
.returns(() => Promise.resolve(none));
|
|
||||||
|
|
||||||
// ... Mock "getSelection" in QueryEditor
|
// ... Mock "getSelection" in QueryEditor
|
||||||
let queryInput = TypeMoq.Mock.ofType(QueryInput, TypeMoq.MockBehavior.Loose);
|
const instantiationService = new TestInstantiationService();
|
||||||
|
let fileInput = new UntitledEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, undefined);
|
||||||
|
|
||||||
|
let queryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Loose, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||||
queryInput.setup(x => x.uri).returns(() => testUri);
|
queryInput.setup(x => x.uri).returns(() => testUri);
|
||||||
queryInput.setup(x => x.runQuery(TypeMoq.It.isAny())).callback((selection: ISelectionData) => {
|
queryInput.setup(x => x.runQuery(TypeMoq.It.isAny())).callback((selection: ISelectionData) => {
|
||||||
runQuerySelection = selection;
|
runQuerySelection = selection;
|
||||||
@@ -256,9 +254,13 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ... Mock "isConnected" in ConnectionManagementService
|
// ... Mock "isConnected" in ConnectionManagementService
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {}, undefined, connectionDialogService.object);
|
|
||||||
connectionManagementService.callBase = true;
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
||||||
|
connectionManagementService.setup(x => x.showConnectionDialog(TypeMoq.It.isAny()))
|
||||||
|
.callback((params: INewConnectionParams) => {
|
||||||
|
showDialogConnectionParams = params;
|
||||||
|
countCalledShowDialog++;
|
||||||
|
})
|
||||||
|
.returns(() => Promise.resolve());
|
||||||
|
|
||||||
/// End Setup Test ///
|
/// End Setup Test ///
|
||||||
|
|
||||||
@@ -320,7 +322,6 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let calledCancelQuery: boolean = false;
|
let calledCancelQuery: boolean = false;
|
||||||
|
|
||||||
// ... Mock "isConnected" in ConnectionManagementService
|
// ... Mock "isConnected" in ConnectionManagementService
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {});
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
||||||
|
|
||||||
// ... Mock QueryModelService
|
// ... Mock QueryModelService
|
||||||
@@ -353,7 +354,6 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let countCalledDisconnectEditor: number = 0;
|
let countCalledDisconnectEditor: number = 0;
|
||||||
|
|
||||||
// ... Mock "isConnected" and "disconnectEditor" in ConnectionManagementService
|
// ... Mock "isConnected" and "disconnectEditor" in ConnectionManagementService
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {});
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
||||||
connectionManagementService.setup(x => x.disconnectEditor(TypeMoq.It.isAny())).callback(() => {
|
connectionManagementService.setup(x => x.disconnectEditor(TypeMoq.It.isAny())).callback(() => {
|
||||||
countCalledDisconnectEditor++;
|
countCalledDisconnectEditor++;
|
||||||
@@ -382,19 +382,14 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let connectionParams: INewConnectionParams = undefined;
|
let connectionParams: INewConnectionParams = undefined;
|
||||||
let countCalledShowDialog: number = 0;
|
let countCalledShowDialog: number = 0;
|
||||||
|
|
||||||
// ... Mock "showDialog" ConnectionDialogService
|
// ... Mock "isConnected" in ConnectionManagementService
|
||||||
let connectionDialogService = TypeMoq.Mock.ofType(ConnectionDialogService, TypeMoq.MockBehavior.Loose);
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
||||||
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), undefined, undefined, undefined))
|
connectionManagementService.setup(x => x.showConnectionDialog(TypeMoq.It.isAny()))
|
||||||
.callback((service: IConnectionManagementService, params: INewConnectionParams) => {
|
.callback((params: INewConnectionParams) => {
|
||||||
connectionParams = params;
|
connectionParams = params;
|
||||||
countCalledShowDialog++;
|
countCalledShowDialog++;
|
||||||
})
|
})
|
||||||
.returns(() => Promise.resolve(none));
|
.returns(() => Promise.resolve());
|
||||||
|
|
||||||
// ... Mock "isConnected" in ConnectionManagementService
|
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {}, undefined, connectionDialogService.object);
|
|
||||||
connectionManagementService.callBase = true;
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
|
||||||
|
|
||||||
// If I call run on ConnectDatabaseAction when I am not connected
|
// If I call run on ConnectDatabaseAction when I am not connected
|
||||||
let queryAction: ConnectDatabaseAction = new ConnectDatabaseAction(editor.object, false, connectionManagementService.object);
|
let queryAction: ConnectDatabaseAction = new ConnectDatabaseAction(editor.object, false, connectionManagementService.object);
|
||||||
@@ -428,19 +423,13 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let connectionParams: INewConnectionParams = undefined;
|
let connectionParams: INewConnectionParams = undefined;
|
||||||
let calledShowDialog: number = 0;
|
let calledShowDialog: number = 0;
|
||||||
|
|
||||||
// ... Mock "showDialog" ConnectionDialogService
|
// ... Mock "isConnected" in ConnectionManagementService
|
||||||
let connectionDialogService = TypeMoq.Mock.ofType(ConnectionDialogService, TypeMoq.MockBehavior.Loose);
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
||||||
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), undefined, undefined, undefined))
|
connectionManagementService.setup(x => x.showConnectionDialog(TypeMoq.It.isAny()))
|
||||||
.callback((service: IConnectionManagementService, params: INewConnectionParams) => {
|
.callback((params: INewConnectionParams) => {
|
||||||
calledShowDialog++;
|
calledShowDialog++;
|
||||||
connectionParams = params;
|
connectionParams = params;
|
||||||
})
|
}).returns(() => Promise.resolve());
|
||||||
.returns(() => Promise.resolve(none));
|
|
||||||
|
|
||||||
// ... Mock "isConnected" in ConnectionManagementService
|
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {}, undefined, connectionDialogService.object);
|
|
||||||
connectionManagementService.callBase = true;
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
|
||||||
|
|
||||||
// If I call run on ChangeConnectionAction when I am not connected
|
// If I call run on ChangeConnectionAction when I am not connected
|
||||||
queryAction = new ConnectDatabaseAction(editor.object, false, connectionManagementService.object);
|
queryAction = new ConnectDatabaseAction(editor.object, false, connectionManagementService.object);
|
||||||
@@ -473,9 +462,8 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let databaseName: string = undefined;
|
let databaseName: string = undefined;
|
||||||
|
|
||||||
// ... Mock "isConnected" in ConnectionManagementService
|
// ... Mock "isConnected" in ConnectionManagementService
|
||||||
let connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {});
|
|
||||||
connectionManagementService.callBase = true;
|
|
||||||
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAnyString())).returns(() => isConnected);
|
||||||
|
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => Event.None);
|
||||||
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{
|
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{
|
||||||
databaseName: databaseName
|
databaseName: databaseName
|
||||||
});
|
});
|
||||||
@@ -510,13 +498,11 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
|
|
||||||
// ... Create mock connection management service
|
// ... Create mock connection management service
|
||||||
let databaseName = 'foobar';
|
let databaseName = 'foobar';
|
||||||
let cms = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {});
|
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
||||||
cms.callBase = true;
|
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
||||||
cms.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
|
||||||
cms.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
|
||||||
|
|
||||||
// ... Create a database dropdown that has been connected
|
// ... Create a database dropdown that has been connected
|
||||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, undefined, configurationService.object);
|
let listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object);
|
||||||
listItem.onConnected();
|
listItem.onConnected();
|
||||||
|
|
||||||
// If: I raise a connection changed event
|
// If: I raise a connection changed event
|
||||||
@@ -534,13 +520,11 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
|
|
||||||
// ... Create mock connection management service that will not claim it's connected
|
// ... Create mock connection management service that will not claim it's connected
|
||||||
let databaseName = 'foobar';
|
let databaseName = 'foobar';
|
||||||
let cms = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {}, {}, new TestStorageService());
|
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
||||||
cms.callBase = true;
|
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
||||||
cms.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
|
||||||
cms.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
|
||||||
|
|
||||||
// ... Create a database dropdown that has been connected
|
// ... Create a database dropdown that has been connected
|
||||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, undefined, configurationService.object);
|
let listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object);
|
||||||
listItem.onConnected();
|
listItem.onConnected();
|
||||||
|
|
||||||
// If: I raise a connection changed event for the 'wrong' URI
|
// If: I raise a connection changed event for the 'wrong' URI
|
||||||
@@ -562,12 +546,10 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let dbChangedEmitter = new Emitter<IConnectionParams>();
|
let dbChangedEmitter = new Emitter<IConnectionParams>();
|
||||||
|
|
||||||
// ... Create mock connection management service
|
// ... Create mock connection management service
|
||||||
let cms = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, {}, {}, new TestStorageService());
|
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
||||||
cms.callBase = true;
|
|
||||||
cms.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
|
||||||
|
|
||||||
// ... Create a database dropdown
|
// ... Create a database dropdown
|
||||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, undefined, configurationService.object);
|
let listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object);
|
||||||
|
|
||||||
// If: I raise a connection changed event
|
// If: I raise a connection changed event
|
||||||
let eventParams = <IConnectionParams>{
|
let eventParams = <IConnectionParams>{
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import { Memento } from 'vs/workbench/common/memento';
|
|||||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
|
|
||||||
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
||||||
import { QueryModelService } from 'sql/platform/query/common/queryModelService';
|
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import { INewConnectionParams, ConnectionType, RunQueryOnConnectionMode } from 'sql/platform/connection/common/connectionManagement';
|
import { INewConnectionParams, ConnectionType, RunQueryOnConnectionMode } from 'sql/platform/connection/common/connectionManagement';
|
||||||
import { ConnectionManagementService } from 'sql/workbench/services/connection/browser/connectionManagementService';
|
import { ConnectionManagementService } from 'sql/workbench/services/connection/browser/connectionManagementService';
|
||||||
import { RunQueryAction, ListDatabasesActionItem } from 'sql/workbench/contrib/query/browser/queryActions';
|
import { RunQueryAction, ListDatabasesActionItem } from 'sql/workbench/contrib/query/browser/queryActions';
|
||||||
@@ -23,6 +21,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||||
import { TestStorageService } from 'vs/workbench/test/workbenchTestServices';
|
import { TestStorageService } from 'vs/workbench/test/workbenchTestServices';
|
||||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||||
|
import { UntitledQueryEditorInput } from 'sql/workbench/contrib/query/common/untitledQueryEditorInput';
|
||||||
|
import { TestQueryModelService } from 'sql/platform/query/test/common/testQueryModelService';
|
||||||
|
import { Event } from 'vs/base/common/event';
|
||||||
|
|
||||||
suite('SQL QueryEditor Tests', () => {
|
suite('SQL QueryEditor Tests', () => {
|
||||||
let instantiationService: TypeMoq.Mock<InstantiationService>;
|
let instantiationService: TypeMoq.Mock<InstantiationService>;
|
||||||
@@ -247,8 +248,8 @@ suite('SQL QueryEditor Tests', () => {
|
|||||||
suite('Action Tests', () => {
|
suite('Action Tests', () => {
|
||||||
let queryActionInstantiationService: TypeMoq.Mock<InstantiationService>;
|
let queryActionInstantiationService: TypeMoq.Mock<InstantiationService>;
|
||||||
let queryConnectionService: TypeMoq.Mock<ConnectionManagementService>;
|
let queryConnectionService: TypeMoq.Mock<ConnectionManagementService>;
|
||||||
let queryModelService: TypeMoq.Mock<QueryModelService>;
|
let queryModelService: TypeMoq.Mock<TestQueryModelService>;
|
||||||
let queryInput: QueryInput;
|
let queryInput: UntitledQueryEditorInput;
|
||||||
setup(() => {
|
setup(() => {
|
||||||
|
|
||||||
// Mock ConnectionManagementService but don't set connected state
|
// Mock ConnectionManagementService but don't set connected state
|
||||||
@@ -284,17 +285,17 @@ suite('SQL QueryEditor Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let fileInput = new UntitledEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService.object, undefined, undefined);
|
let fileInput = new UntitledEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService.object, undefined, undefined);
|
||||||
queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose, undefined, undefined);
|
queryModelService = TypeMoq.Mock.ofType(TestQueryModelService, TypeMoq.MockBehavior.Strict);
|
||||||
queryModelService.callBase = true;
|
queryModelService.setup(x => x.disposeQuery(TypeMoq.It.isAny()));
|
||||||
queryModelService.setup(x => x.disposeQuery(TypeMoq.It.isAny())).returns(() => void 0);
|
queryModelService.setup(x => x.onRunQueryComplete).returns(() => Event.None);
|
||||||
queryInput = new QueryInput(
|
queryModelService.setup(x => x.onRunQueryStart).returns(() => Event.None);
|
||||||
|
queryInput = new UntitledQueryEditorInput(
|
||||||
'',
|
'',
|
||||||
fileInput,
|
fileInput,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
|
||||||
connectionManagementService.object,
|
connectionManagementService.object,
|
||||||
queryModelService.object,
|
queryModelService.object,
|
||||||
undefined,
|
configurationService.object,
|
||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -311,8 +312,8 @@ suite('SQL QueryEditor Tests', () => {
|
|||||||
|
|
||||||
test('Taskbar buttons are set correctly upon connect', () => {
|
test('Taskbar buttons are set correctly upon connect', () => {
|
||||||
let params: INewConnectionParams = { connectionType: ConnectionType.editor, runQueryOnCompletion: RunQueryOnConnectionMode.none };
|
let params: INewConnectionParams = { connectionType: ConnectionType.editor, runQueryOnCompletion: RunQueryOnConnectionMode.none };
|
||||||
queryInput.onConnectSuccess(params);
|
|
||||||
queryModelService.setup(x => x.isRunningQuery(TypeMoq.It.isAny())).returns(() => false);
|
queryModelService.setup(x => x.isRunningQuery(TypeMoq.It.isAny())).returns(() => false);
|
||||||
|
queryInput.onConnectSuccess(params);
|
||||||
assert.equal(queryInput.state.connected, true, 'query state should be not connected');
|
assert.equal(queryInput.state.connected, true, 'query state should be not connected');
|
||||||
assert.equal(queryInput.state.executing, false, 'query state should be not executing');
|
assert.equal(queryInput.state.executing, false, 'query state should be not executing');
|
||||||
assert.equal(queryInput.state.connecting, false, 'query state should be not connecting');
|
assert.equal(queryInput.state.connecting, false, 'query state should be not connecting');
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { EditorDescriptor, IEditorRegistry, Extensions } from 'vs/workbench/brow
|
|||||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { QueryPlanEditor } from 'sql/workbench/contrib/queryPlan/browser/queryPlanEditor';
|
import { QueryPlanEditor } from 'sql/workbench/contrib/queryPlan/browser/queryPlanEditor';
|
||||||
|
import { ILanguageAssociationRegistry, Extensions as LanguageAssociationExtensions } from 'sql/workbench/common/languageAssociation';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
// Query Plan editor registration
|
// Query Plan editor registration
|
||||||
|
|
||||||
@@ -19,3 +21,9 @@ const queryPlanEditorDescriptor = new EditorDescriptor(
|
|||||||
|
|
||||||
Registry.as<IEditorRegistry>(Extensions.Editors)
|
Registry.as<IEditorRegistry>(Extensions.Editors)
|
||||||
.registerEditor(queryPlanEditorDescriptor, [new SyncDescriptor(QueryPlanInput)]);
|
.registerEditor(queryPlanEditorDescriptor, [new SyncDescriptor(QueryPlanInput)]);
|
||||||
|
|
||||||
|
Registry.as<ILanguageAssociationRegistry>(LanguageAssociationExtensions.LanguageAssociations)
|
||||||
|
.registerLanguageAssociation('sqlplan', (accessor, editor) => {
|
||||||
|
const instantiationService = accessor.get(IInstantiationService);
|
||||||
|
return instantiationService.createInstance(QueryPlanInput, editor.getResource());
|
||||||
|
}, (editor: QueryPlanInput) => undefined);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
import { EditorInput, EditorModel } from 'vs/workbench/common/editor';
|
import { EditorInput, EditorModel } from 'vs/workbench/common/editor';
|
||||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
import { ConnectionManagementInfo } from 'sql/platform/connection/common/connectionManagementInfo';
|
|
||||||
import { IFileService } from 'vs/platform/files/common/files';
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
|
||||||
@@ -19,7 +18,7 @@ export class QueryPlanInput extends EditorInput {
|
|||||||
private _xml: string;
|
private _xml: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _uri: URI, private _connection: ConnectionManagementInfo,
|
private _uri: URI,
|
||||||
@IFileService private readonly fileService: IFileService
|
@IFileService private readonly fileService: IFileService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
@@ -68,8 +67,4 @@ export class QueryPlanInput extends EditorInput {
|
|||||||
public get uniqueSelector(): string {
|
public get uniqueSelector(): string {
|
||||||
return this._uniqueSelector;
|
return this._uniqueSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getConnectionInfo(): ConnectionManagementInfo {
|
|
||||||
return this._connection;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,33 +4,23 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
import { QueryResultsInput } from 'sql/workbench/contrib/query/common/queryResultsInput';
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
import { EditDataInput } from 'sql/workbench/contrib/editData/browser/editDataInput';
|
import { EditDataInput } from 'sql/workbench/contrib/editData/browser/editDataInput';
|
||||||
import { IConnectableInput, IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
import { IConnectableInput, IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||||
import { IQueryEditorService, IQueryEditorOptions } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
||||||
import { sqlModeId, untitledFilePrefix, getSupportedInputResource } from 'sql/workbench/browser/customInputConverter';
|
import { UntitledQueryEditorInput } from 'sql/workbench/contrib/query/common/untitledQueryEditorInput';
|
||||||
import * as TaskUtilities from 'sql/workbench/browser/taskUtilities';
|
|
||||||
|
|
||||||
import { ITextModel } from 'vs/editor/common/model';
|
|
||||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import Severity from 'vs/base/common/severity';
|
|
||||||
import nls = require('vs/nls');
|
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import paths = require('vs/base/common/extpath');
|
import * as paths from 'vs/base/common/extpath';
|
||||||
import { isLinux } from 'vs/base/common/platform';
|
import { isLinux } from 'vs/base/common/platform';
|
||||||
import { Schemas } from 'vs/base/common/network';
|
import { Schemas } from 'vs/base/common/network';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
|
||||||
import { EditDataResultsInput } from 'sql/workbench/contrib/editData/browser/editDataResultsInput';
|
|
||||||
import { IEditorInput, IEditor } from 'vs/workbench/common/editor';
|
|
||||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
|
||||||
import { ILanguageSelection } from 'vs/editor/common/services/modeService';
|
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
|
import { replaceConnection } from 'sql/workbench/browser/taskUtilities';
|
||||||
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
import { EditDataResultsInput } from 'sql/workbench/contrib/editData/browser/editDataResultsInput';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { assign } from 'vs/base/common/objects';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service wrapper for opening and creating SQL documents as sql editor inputs
|
* Service wrapper for opening and creating SQL documents as sql editor inputs
|
||||||
@@ -39,18 +29,7 @@ export class QueryEditorService implements IQueryEditorService {
|
|||||||
|
|
||||||
public _serviceBrand: undefined;
|
public _serviceBrand: undefined;
|
||||||
|
|
||||||
private static CHANGE_UNSUPPORTED_ERROR_MESSAGE = nls.localize(
|
|
||||||
'queryEditorServiceChangeUnsupportedError',
|
|
||||||
"Change Language Mode is not supported for unsaved queries"
|
|
||||||
);
|
|
||||||
|
|
||||||
private static CHANGE_ERROR_MESSAGE = nls.localize(
|
|
||||||
'queryEditorServiceChangeError',
|
|
||||||
"Please save or discard changes before switching to/from the SQL Language Mode"
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@INotificationService private _notificationService: INotificationService,
|
|
||||||
@IUntitledEditorService private _untitledEditorService: IUntitledEditorService,
|
@IUntitledEditorService private _untitledEditorService: IUntitledEditorService,
|
||||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||||
@IEditorService private _editorService: IEditorService,
|
@IEditorService private _editorService: IEditorService,
|
||||||
@@ -83,12 +62,11 @@ export class QueryEditorService implements IQueryEditorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const queryResultsInput: QueryResultsInput = this._instantiationService.createInstance(QueryResultsInput, docUri.toString());
|
const queryResultsInput: QueryResultsInput = this._instantiationService.createInstance(QueryResultsInput, docUri.toString());
|
||||||
let queryInput: QueryInput = this._instantiationService.createInstance(QueryInput, objectName, fileInput, queryResultsInput, connectionProviderName);
|
let queryInput = this._instantiationService.createInstance(UntitledQueryEditorInput, objectName, fileInput, queryResultsInput);
|
||||||
|
|
||||||
this._editorService.openEditor(queryInput, { pinned: true })
|
this._editorService.openEditor(queryInput, { pinned: true })
|
||||||
.then((editor) => {
|
.then((editor) => {
|
||||||
let params = <QueryInput>editor.input;
|
resolve(editor.input as UntitledQueryEditorInput);
|
||||||
resolve(params);
|
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
@@ -128,14 +106,14 @@ export class QueryEditorService implements IQueryEditorService {
|
|||||||
let oldResourceString: string = oldResource.toString();
|
let oldResourceString: string = oldResource.toString();
|
||||||
|
|
||||||
this._editorService.editors.forEach(input => {
|
this._editorService.editors.forEach(input => {
|
||||||
if (input instanceof QueryInput) {
|
if (input instanceof QueryEditorInput) {
|
||||||
const resource = input.getResource();
|
const resource = input.getResource();
|
||||||
|
|
||||||
// Update Editor if file (or any parent of the input) got renamed or moved
|
// Update Editor if file (or any parent of the input) got renamed or moved
|
||||||
// Note: must check the new file name for this since this method is called after the rename is completed
|
// Note: must check the new file name for this since this method is called after the rename is completed
|
||||||
if (paths.isEqualOrParent(resource.fsPath, newResource.fsPath, !isLinux /* ignorecase */)) {
|
if (paths.isEqualOrParent(resource.fsPath, newResource.fsPath, !isLinux /* ignorecase */)) {
|
||||||
// In this case, we know that this is a straight rename so support this as a rename / replace operation
|
// In this case, we know that this is a straight rename so support this as a rename / replace operation
|
||||||
TaskUtilities.replaceConnection(oldResourceString, newResource.toString(), this._connectionManagementService).then(result => {
|
replaceConnection(oldResourceString, newResource.toString(), this._connectionManagementService).then(result => {
|
||||||
if (result && result.connected) {
|
if (result && result.connected) {
|
||||||
input.onConnectSuccess();
|
input.onConnectSuccess();
|
||||||
} else {
|
} else {
|
||||||
@@ -147,84 +125,10 @@ export class QueryEditorService implements IQueryEditorService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
////// Public static functions
|
|
||||||
// These functions are static to reduce extra lines needed in the vscode code base
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the Language Mode is being changed to/from SQL. If so, swaps out the input of the
|
|
||||||
* given editor with a new input, opens a new editor, then returns the new editor's IModel.
|
|
||||||
*
|
|
||||||
* Returns an immediately resolved promise if the SQL Language mode is not involved. In this case,
|
|
||||||
* the calling function in editorStatus.ts will handle the language change normally.
|
|
||||||
*
|
|
||||||
* Returns an immediately resolved promise with undefined if SQL is involved in the language change
|
|
||||||
* and the editor is dirty. In this case, the calling function in editorStatus.ts will not perform
|
|
||||||
* the language change. TODO: change this - tracked by issue #727
|
|
||||||
*
|
|
||||||
* In all other cases (when SQL is involved in the language change and the editor is not dirty),
|
|
||||||
* returns a promise that will resolve when the old editor has been replaced by a new editor.
|
|
||||||
*/
|
|
||||||
public async sqlLanguageModeCheck(model: ITextModel, languageSelection: ILanguageSelection, editor: IEditor): Promise<ITextModel> {
|
|
||||||
if (!model || !languageSelection || !editor) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
let newLanguage: string = languageSelection.languageIdentifier.language;
|
|
||||||
let oldLanguage: string = model.getLanguageIdentifier().language;
|
|
||||||
let changingToSql = sqlModeId === newLanguage;
|
|
||||||
let changingFromSql = sqlModeId === oldLanguage;
|
|
||||||
let changingLanguage = newLanguage !== oldLanguage;
|
|
||||||
|
|
||||||
if (!changingLanguage) {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
if (!changingFromSql && !changingToSql) {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
let uri: URI = QueryEditorService._getEditorChangeUri(editor.input, changingToSql);
|
|
||||||
if (uri.scheme === Schemas.untitled && (editor.input instanceof QueryInput || editor.input instanceof EditDataInput)) {
|
|
||||||
this._notificationService.notify({
|
|
||||||
severity: Severity.Error,
|
|
||||||
message: QueryEditorService.CHANGE_UNSUPPORTED_ERROR_MESSAGE
|
|
||||||
});
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return undefined to notify the calling funciton to not perform the language change
|
|
||||||
// TODO change this - tracked by issue #727
|
|
||||||
if (editor.input.isDirty()) {
|
|
||||||
this._notificationService.notify({
|
|
||||||
severity: Severity.Error,
|
|
||||||
message: QueryEditorService.CHANGE_ERROR_MESSAGE
|
|
||||||
});
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
let group: IEditorGroup = editor.group;
|
|
||||||
let index: number = group.editors.indexOf(editor.input);
|
|
||||||
let options: IQueryEditorOptions = editor.options ? editor.options : {};
|
|
||||||
options = assign(options, { index: index });
|
|
||||||
|
|
||||||
// Return a promise that will resovle when the old editor has been replaced by a new editor
|
|
||||||
let newEditorInput = this.getNewEditorInput(changingToSql, editor.input, uri);
|
|
||||||
|
|
||||||
// Override queryEditorCheck to not open this file in a QueryEditor
|
|
||||||
if (!changingToSql) {
|
|
||||||
options.denyQueryEditor = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
await group.closeEditor(editor.input);
|
|
||||||
// Reopen a new editor in the same position/index
|
|
||||||
const newEditor = await this._editorService.openEditor(newEditorInput, options, group);
|
|
||||||
|
|
||||||
return QueryEditorService._onEditorOpened(newEditor, uri.toString(), undefined, options.pinned);
|
|
||||||
}
|
|
||||||
|
|
||||||
////// Private functions
|
////// Private functions
|
||||||
|
|
||||||
private createUntitledSqlFilePath(): Promise<string> {
|
private createUntitledSqlFilePath(): Promise<string> {
|
||||||
return this.createPrefixedSqlFilePath(untitledFilePrefix);
|
return this.createPrefixedSqlFilePath('SQLQuery');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createPrefixedSqlFilePath(prefix: string): Promise<string> {
|
private async createPrefixedSqlFilePath(prefix: string): Promise<string> {
|
||||||
@@ -242,69 +146,4 @@ export class QueryEditorService implements IQueryEditorService {
|
|||||||
|
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
////// Private static functions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a QueryInput if we are changingToSql. Returns a FileEditorInput if we are !changingToSql.
|
|
||||||
*/
|
|
||||||
private getNewEditorInput(changingToSql: boolean, input: IEditorInput, uri: URI): IEditorInput {
|
|
||||||
if (!uri) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
let newEditorInput: IEditorInput = undefined;
|
|
||||||
if (changingToSql) {
|
|
||||||
const queryResultsInput: QueryResultsInput = this._instantiationService.createInstance(QueryResultsInput, uri.toString());
|
|
||||||
let queryInput: QueryInput = this._instantiationService.createInstance(QueryInput, '', input, queryResultsInput, undefined);
|
|
||||||
newEditorInput = queryInput;
|
|
||||||
} else {
|
|
||||||
let uriCopy: URI = URI.from({ scheme: uri.scheme, authority: uri.authority, path: uri.path, query: uri.query, fragment: uri.fragment });
|
|
||||||
newEditorInput = this._instantiationService.createInstance(FileEditorInput, uriCopy, undefined, undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newEditorInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the URI for this IEditorInput or returns undefined if one does not exist.
|
|
||||||
*/
|
|
||||||
private static _getEditorChangeUri(input: IEditorInput, changingToSql: boolean): URI {
|
|
||||||
let uriSource: IEditorInput = input;
|
|
||||||
|
|
||||||
// It is assumed that if we got here, !changingToSql is logically equivalent to changingFromSql
|
|
||||||
let changingFromSql = !changingToSql;
|
|
||||||
if (input instanceof QueryInput && changingFromSql) {
|
|
||||||
let queryInput: QueryInput = <QueryInput>input;
|
|
||||||
uriSource = queryInput.sql;
|
|
||||||
}
|
|
||||||
return getSupportedInputResource(uriSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle all cleanup actions that need to wait until the editor is fully open.
|
|
||||||
*/
|
|
||||||
private static _onEditorOpened(editor: IEditor, uri: string, position: Position, isPinned: boolean): ITextModel {
|
|
||||||
|
|
||||||
// Reset the editor pin state
|
|
||||||
// TODO: change this so it happens automatically in openEditor in sqlLanguageModeCheck. Performing this here
|
|
||||||
// causes the text on the tab to slightly flicker for unpinned files (from non-italic to italic to non-italic).
|
|
||||||
// This is currently unavoidable because vscode ignores "pinned" on IEditorOptions if "index" is not undefined,
|
|
||||||
// and we need to specify "index"" so the editor tab remains in the same place
|
|
||||||
// let group: IEditorGroup = QueryEditorService.editorGroupService.getStacksModel().groupAt(position);
|
|
||||||
// if (isPinned) {
|
|
||||||
// QueryEditorService.editorGroupService.pinEditor(group, editor.input);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @SQLTODO do we need the below
|
|
||||||
// else {
|
|
||||||
// QueryEditorService.editorGroupService.p .unpinEditor(group, editor.input);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Grab and returns the IModel that will be used to resolve the sqlLanguageModeCheck promise.
|
|
||||||
let control = editor.getControl();
|
|
||||||
let codeEditor: ICodeEditor = <ICodeEditor>control;
|
|
||||||
let newModel = codeEditor ? codeEditor.getModel() : undefined;
|
|
||||||
return newModel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,6 @@ import { IConnectableInput } from 'sql/platform/connection/common/connectionMana
|
|||||||
import { IEditorOptions } from 'vs/platform/editor/common/editor';
|
import { IEditorOptions } from 'vs/platform/editor/common/editor';
|
||||||
|
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { ITextModel } from 'vs/editor/common/model';
|
|
||||||
import { ILanguageSelection } from 'vs/editor/common/services/modeService';
|
|
||||||
import { IEditor } from 'vs/workbench/common/editor';
|
|
||||||
|
|
||||||
export interface IQueryEditorOptions extends IEditorOptions {
|
export interface IQueryEditorOptions extends IEditorOptions {
|
||||||
|
|
||||||
@@ -38,6 +35,4 @@ export interface IQueryEditorService {
|
|||||||
* @param newResource URI of the file after the save as operation was completed
|
* @param newResource URI of the file after the save as operation was completed
|
||||||
*/
|
*/
|
||||||
onSaveAsCompleted(oldResource: URI, newResource: URI): void;
|
onSaveAsCompleted(oldResource: URI, newResource: URI): void;
|
||||||
|
|
||||||
sqlLanguageModeCheck(model: ITextModel, languageSelection: ILanguageSelection, editor: IEditor): Promise<ITextModel>;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,11 +124,6 @@ class UntitledEditorInputFactory implements IEditorInputFactory {
|
|||||||
|
|
||||||
const untitledEditorInput = <UntitledEditorInput>editorInput;
|
const untitledEditorInput = <UntitledEditorInput>editorInput;
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}} @todo anthonydresser 4/12/19 investigate
|
|
||||||
if (!untitledEditorInput.getResource()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
let resource = untitledEditorInput.getResource();
|
let resource = untitledEditorInput.getResource();
|
||||||
if (untitledEditorInput.hasAssociatedFilePath) {
|
if (untitledEditorInput.hasAssociatedFilePath) {
|
||||||
resource = toLocalResource(resource, this.environmentService.configuration.remoteAuthority); // untitled with associated file path use the local schema
|
resource = toLocalResource(resource, this.environmentService.configuration.remoteAuthority); // untitled with associated file path use the local schema
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import { RunOnceWorker } from 'vs/base/common/async';
|
|||||||
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||||
import { TitleControl } from 'vs/workbench/browser/parts/editor/titleControl';
|
import { TitleControl } from 'vs/workbench/browser/parts/editor/titleControl';
|
||||||
import { IEditorGroupsAccessor, IEditorGroupView, IEditorPartOptionsChangeEvent, getActiveTextEditorOptions, IEditorOpeningEvent } from 'vs/workbench/browser/parts/editor/editor';
|
import { IEditorGroupsAccessor, IEditorGroupView, IEditorPartOptionsChangeEvent, getActiveTextEditorOptions, IEditorOpeningEvent } from 'vs/workbench/browser/parts/editor/editor';
|
||||||
// import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { ActionRunner, IAction, Action } from 'vs/base/common/actions';
|
import { ActionRunner, IAction, Action } from 'vs/base/common/actions';
|
||||||
@@ -42,10 +42,6 @@ import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions'
|
|||||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||||
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
|
||||||
import { GlobalNewUntitledFileAction } from 'vs/workbench/contrib/files/browser/fileActions';
|
|
||||||
// {{SQL CARBON EDIT}} - End
|
|
||||||
import { isErrorWithActions, IErrorWithActions } from 'vs/base/common/errorsWithActions';
|
import { isErrorWithActions, IErrorWithActions } from 'vs/base/common/errorsWithActions';
|
||||||
import { IVisibleEditor } from 'vs/workbench/services/editor/common/editorService';
|
import { IVisibleEditor } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types';
|
import { withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types';
|
||||||
@@ -132,12 +128,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||||||
@INotificationService private readonly notificationService: INotificationService,
|
@INotificationService private readonly notificationService: INotificationService,
|
||||||
@IDialogService private readonly dialogService: IDialogService,
|
@IDialogService private readonly dialogService: IDialogService,
|
||||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||||
// @IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService, {{SQL CARBON EDIT}} no unused
|
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService,
|
||||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||||
@IMenuService private readonly menuService: IMenuService,
|
@IMenuService private readonly menuService: IMenuService,
|
||||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
@IContextMenuService private readonly contextMenuService: IContextMenuService
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
@ICommandService private commandService: ICommandService
|
|
||||||
) {
|
) {
|
||||||
super(themeService);
|
super(themeService);
|
||||||
|
|
||||||
@@ -260,8 +254,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||||||
this._register(addDisposableListener(this.element, EventType.DBLCLICK, e => {
|
this._register(addDisposableListener(this.element, EventType.DBLCLICK, e => {
|
||||||
if (this.isEmpty) {
|
if (this.isEmpty) {
|
||||||
EventHelper.stop(e);
|
EventHelper.stop(e);
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
this.commandService.executeCommand(GlobalNewUntitledFileAction.ID).then(undefined, err => this.notificationService.warn(err));
|
this.openEditor(this.untitledEditorService.createOrGet(), EditorOptions.create({ pinned: true }));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -1463,7 +1457,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||||||
inactiveReplacements.forEach(({ editor, replacement, options }) => {
|
inactiveReplacements.forEach(({ editor, replacement, options }) => {
|
||||||
|
|
||||||
// Open inactive editor
|
// Open inactive editor
|
||||||
this.doOpenEditor(replacement, options);
|
this.openEditor(replacement, options); // {{SQL CARBON EDIT}} use this.openEditor to allow us to override the open, we could potentially add this to vscode but i don't think they would care
|
||||||
|
|
||||||
// Close replaced inactive editor unless they match
|
// Close replaced inactive editor unless they match
|
||||||
if (!editor.matches(replacement)) {
|
if (!editor.matches(replacement)) {
|
||||||
@@ -1476,7 +1470,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||||||
if (activeReplacement) {
|
if (activeReplacement) {
|
||||||
|
|
||||||
// Open replacement as active editor
|
// Open replacement as active editor
|
||||||
const openEditorResult = this.doOpenEditor(activeReplacement.replacement, activeReplacement.options);
|
const openEditorResult = this.openEditor(activeReplacement.replacement, activeReplacement.options); // {{SQL CARBON EDIT}} use this.openEditor to allow us to override the open, we could potentially add this to vscode but i don't think they would care
|
||||||
|
|
||||||
// Close replaced active editor unless they match
|
// Close replaced active editor unless they match
|
||||||
if (!activeReplacement.editor.matches(activeReplacement.replacement)) {
|
if (!activeReplacement.editor.matches(activeReplacement.replacement)) {
|
||||||
|
|||||||
@@ -50,9 +50,7 @@ import { Event } from 'vs/base/common/event';
|
|||||||
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar';
|
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar';
|
||||||
|
import { setMode } from 'sql/workbench/browser/parts/editor/editorStatusModeSelect'; // {{SQL CARBON EDIT}}
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
|
||||||
|
|
||||||
class SideBySideEditorEncodingSupport implements IEncodingSupport {
|
class SideBySideEditorEncodingSupport implements IEncodingSupport {
|
||||||
constructor(private master: IEncodingSupport, private details: IEncodingSupport) { }
|
constructor(private master: IEncodingSupport, private details: IEncodingSupport) { }
|
||||||
@@ -872,8 +870,7 @@ export class ChangeModeAction extends Action {
|
|||||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||||
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
||||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||||
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService,
|
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService
|
||||||
@IQueryEditorService private readonly queryEditorService: IQueryEditorService // {{ SQL CARBON EDIT }}
|
|
||||||
) {
|
) {
|
||||||
super(actionId, actionLabel);
|
super(actionId, actionLabel);
|
||||||
}
|
}
|
||||||
@@ -973,16 +970,16 @@ export class ChangeModeAction extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change mode for active editor
|
// Change mode for active editor
|
||||||
const activeEditor = this.editorService.activeControl; // {{SQL CARBON EDIT}} @anthonydresser change to activeControl from active editor
|
const activeEditor = this.editorService.activeEditor;
|
||||||
if (activeEditor) {
|
if (activeEditor) {
|
||||||
const modeSupport = toEditorWithModeSupport(activeEditor.input); // {{SQL CARBON EDIT}} @anthonydresser reference input rather than activeeditor directly
|
const modeSupport = toEditorWithModeSupport(activeEditor);
|
||||||
if (modeSupport) {
|
if (modeSupport) {
|
||||||
|
|
||||||
// Find mode
|
// Find mode
|
||||||
let languageSelection: ILanguageSelection | undefined;
|
let languageSelection: ILanguageSelection | undefined;
|
||||||
if (pick === autoDetectMode) {
|
if (pick === autoDetectMode) {
|
||||||
if (textModel) {
|
if (textModel) {
|
||||||
const resource = toResource(activeEditor.input, { supportSideBySide: SideBySideEditor.MASTER }); // {{SQL CARBON EDIT}} @anthonydresser reference input rather than activeeditor directly
|
const resource = toResource(activeEditor, { supportSideBySide: SideBySideEditor.MASTER });
|
||||||
if (resource) {
|
if (resource) {
|
||||||
languageSelection = this.modeService.createByFilepathOrFirstLine(resource, textModel.getLineContent(1));
|
languageSelection = this.modeService.createByFilepathOrFirstLine(resource, textModel.getLineContent(1));
|
||||||
}
|
}
|
||||||
@@ -991,14 +988,9 @@ export class ChangeModeAction extends Action {
|
|||||||
languageSelection = this.modeService.createByLanguageName(pick.label);
|
languageSelection = this.modeService.createByLanguageName(pick.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}} @anthonydresser preform a check before we actuall set the mode
|
|
||||||
// Change mode
|
// Change mode
|
||||||
if (typeof languageSelection !== 'undefined') {
|
if (typeof languageSelection !== 'undefined') {
|
||||||
this.queryEditorService.sqlLanguageModeCheck(textModel, languageSelection, activeEditor).then(newTextModel => {
|
return this.instantiationService.invokeFunction(setMode, modeSupport, activeEditor, languageSelection.languageIdentifier.language); // {{SQL CARBON EDIT}} @anthonydresser use custom setMode
|
||||||
if (newTextModel) {
|
|
||||||
modeSupport.setMode(languageSelection.languageIdentifier.language);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import { Color } from 'vs/base/common/color';
|
|||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { MergeGroupMode, IMergeGroupOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
|
import { MergeGroupMode, IMergeGroupOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||||
// import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||||
import { addClass, addDisposableListener, hasClass, EventType, EventHelper, removeClass, Dimension, scheduleAtNextAnimationFrame, findParentWithClass, clearNode } from 'vs/base/browser/dom';
|
import { addClass, addDisposableListener, hasClass, EventType, EventHelper, removeClass, Dimension, scheduleAtNextAnimationFrame, findParentWithClass, clearNode } from 'vs/base/browser/dom';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { IEditorGroupsAccessor, IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor';
|
import { IEditorGroupsAccessor, IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor';
|
||||||
@@ -44,10 +44,8 @@ import { withNullAsUndefined, assertAllDefined, assertIsDefined } from 'vs/base/
|
|||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}} -- Display the editor's tab color
|
// {{SQL CARBON EDIT}} -- Display the editor's tab color
|
||||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
|
||||||
import * as QueryConstants from 'sql/workbench/contrib/query/common/constants';
|
import * as QueryConstants from 'sql/workbench/contrib/query/common/constants';
|
||||||
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
|
import * as WorkbenchUtils from 'sql/workbench/common/sqlWorkbenchUtils';
|
||||||
import { GlobalNewUntitledFileAction } from 'vs/workbench/contrib/files/browser/fileActions';
|
|
||||||
// {{SQL CARBON EDIT}} -- End
|
// {{SQL CARBON EDIT}} -- End
|
||||||
|
|
||||||
interface IEditorInputLabel {
|
interface IEditorInputLabel {
|
||||||
@@ -81,7 +79,7 @@ export class TabsTitleControl extends TitleControl {
|
|||||||
group: IEditorGroupView,
|
group: IEditorGroupView,
|
||||||
@IContextMenuService contextMenuService: IContextMenuService,
|
@IContextMenuService contextMenuService: IContextMenuService,
|
||||||
@IInstantiationService instantiationService: IInstantiationService,
|
@IInstantiationService instantiationService: IInstantiationService,
|
||||||
// @IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService, {{SQL CARBON EDIT}} comment out inject
|
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService,
|
||||||
@IContextKeyService contextKeyService: IContextKeyService,
|
@IContextKeyService contextKeyService: IContextKeyService,
|
||||||
@IKeybindingService keybindingService: IKeybindingService,
|
@IKeybindingService keybindingService: IKeybindingService,
|
||||||
@ITelemetryService telemetryService: ITelemetryService,
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
@@ -92,9 +90,6 @@ export class TabsTitleControl extends TitleControl {
|
|||||||
@IExtensionService extensionService: IExtensionService,
|
@IExtensionService extensionService: IExtensionService,
|
||||||
@IConfigurationService configurationService: IConfigurationService,
|
@IConfigurationService configurationService: IConfigurationService,
|
||||||
@IFileService fileService: IFileService,
|
@IFileService fileService: IFileService,
|
||||||
// {{SQL CARBON EDIT}} -- Display the editor's tab color
|
|
||||||
@ICommandService private commandService: ICommandService,
|
|
||||||
// {{SQL CARBON EDIT}} -- End
|
|
||||||
@ILabelService labelService: ILabelService
|
@ILabelService labelService: ILabelService
|
||||||
) {
|
) {
|
||||||
super(parent, accessor, group, contextMenuService, instantiationService, contextKeyService, keybindingService, telemetryService, notificationService, menuService, quickOpenService, themeService, extensionService, configurationService, fileService, labelService);
|
super(parent, accessor, group, contextMenuService, instantiationService, contextKeyService, keybindingService, telemetryService, notificationService, menuService, quickOpenService, themeService, extensionService, configurationService, fileService, labelService);
|
||||||
@@ -186,8 +181,8 @@ export class TabsTitleControl extends TitleControl {
|
|||||||
this._register(addDisposableListener(tabsContainer, EventType.DBLCLICK, e => {
|
this._register(addDisposableListener(tabsContainer, EventType.DBLCLICK, e => {
|
||||||
if (e.target === tabsContainer) {
|
if (e.target === tabsContainer) {
|
||||||
EventHelper.stop(e);
|
EventHelper.stop(e);
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
this.commandService.executeCommand(GlobalNewUntitledFileAction.ID).then(undefined, err => this.notificationService.warn(err));
|
this.group.openEditor(this.untitledEditorService.createOrGet(), { pinned: true /* untitled is always pinned */, index: this.group.count /* always at the end */ });
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -447,8 +447,7 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
|
|||||||
* Subclasses can set this to false if it does not make sense to split the editor input.
|
* Subclasses can set this to false if it does not make sense to split the editor input.
|
||||||
*/
|
*/
|
||||||
supportsSplitEditor(): boolean {
|
supportsSplitEditor(): boolean {
|
||||||
// {{SQL CARBON EDIT}} @anthonydresser 05/19/2019 investigate
|
return true;
|
||||||
return false; // TODO reenable when multiple Angular components of the same type can be open simultaneously
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -475,16 +474,6 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
|
|||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}} @anthonydresser 05/19/2019 investigate
|
|
||||||
// Saving is not supported in the EditData query editor, so this can be overriden in its Input.
|
|
||||||
private _savingSupported: boolean = true;
|
|
||||||
public get savingSupported(): boolean {
|
|
||||||
return this._savingSupported;
|
|
||||||
}
|
|
||||||
public disableSaving() {
|
|
||||||
this._savingSupported = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum ConfirmResult {
|
export const enum ConfirmResult {
|
||||||
|
|||||||
@@ -14,11 +14,9 @@ import { ResourceMap } from 'vs/base/common/map';
|
|||||||
import { coalesce, firstIndex } from 'vs/base/common/arrays';
|
import { coalesce, firstIndex } from 'vs/base/common/arrays';
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
|
||||||
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
|
||||||
import * as CustomInputConverter from 'sql/workbench/browser/customInputConverter';
|
|
||||||
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
|
||||||
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
|
||||||
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
|
||||||
const EditorOpenPositioning = {
|
const EditorOpenPositioning = {
|
||||||
LEFT: 'left',
|
LEFT: 'left',
|
||||||
@@ -643,16 +641,7 @@ export class EditorGroup extends Disposable {
|
|||||||
let serializableEditors: EditorInput[] = [];
|
let serializableEditors: EditorInput[] = [];
|
||||||
let serializedEditors: ISerializedEditorInput[] = [];
|
let serializedEditors: ISerializedEditorInput[] = [];
|
||||||
let serializablePreviewIndex: number | undefined;
|
let serializablePreviewIndex: number | undefined;
|
||||||
// {{SQL CARBON EDIT}}
|
this.editors.forEach(e => {
|
||||||
const editors = this.editors.map(e => {
|
|
||||||
if (e instanceof QueryInput) {
|
|
||||||
return e.sql;
|
|
||||||
} else if (e instanceof NotebookInput) {
|
|
||||||
return e.textInput;
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
});
|
|
||||||
editors.forEach(e => {
|
|
||||||
const factory = registry.getEditorInputFactory(e.getTypeId());
|
const factory = registry.getEditorInputFactory(e.getTypeId());
|
||||||
if (factory) {
|
if (factory) {
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
@@ -675,16 +664,7 @@ export class EditorGroup extends Disposable {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
const serializableMru = this.mru.map(e => this.indexOf(e, serializableEditors)).filter(i => i >= 0);
|
||||||
let mru = this.mru.map(e => {
|
|
||||||
if (e instanceof QueryInput) {
|
|
||||||
return e.sql;
|
|
||||||
} else if (e instanceof NotebookInput) {
|
|
||||||
return e.textInput;
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
});
|
|
||||||
const serializableMru = mru.map(e => this.indexOf(e, serializableEditors)).filter(i => i >= 0);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
@@ -714,8 +694,7 @@ export class EditorGroup extends Disposable {
|
|||||||
this.updateResourceMap(editor, false /* add */);
|
this.updateResourceMap(editor, false /* add */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
return editor;
|
||||||
return CustomInputConverter.convertEditorInput(editor, undefined, this.instantiationService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -737,7 +716,7 @@ export class EditorGroup extends Disposable {
|
|||||||
let n = 0;
|
let n = 0;
|
||||||
while (n < this.editors.length) {
|
while (n < this.editors.length) {
|
||||||
let editor = this.editors[n];
|
let editor = this.editors[n];
|
||||||
if (editor instanceof QueryInput && editor.matchInputInstanceType(FileEditorInput) && !editor.isDirty() && await editor.inputFileExists() === false && this.editors.length > 1) {
|
if (editor instanceof QueryEditorInput && editor.matchInputInstanceType(FileEditorInput) && !editor.isDirty() && await editor.inputFileExists() === false && this.editors.length > 1) {
|
||||||
// remove from editors list so that they do not get restored
|
// remove from editors list so that they do not get restored
|
||||||
this.editors.splice(n, 1);
|
this.editors.splice(n, 1);
|
||||||
let index = firstIndex(this.mru, e => e.matches(editor));
|
let index = firstIndex(this.mru, e => e.matches(editor));
|
||||||
|
|||||||
@@ -125,11 +125,6 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
|
|||||||
}
|
}
|
||||||
|
|
||||||
isDirty(): boolean {
|
isDirty(): boolean {
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
if (!this.savingSupported) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.cachedModel) {
|
if (this.cachedModel) {
|
||||||
return this.cachedModel.isDirty();
|
return this.cachedModel.isDirty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import { withNullAsUndefined } from 'vs/base/common/types';
|
|||||||
import { EditorActivation } from 'vs/platform/editor/common/editor';
|
import { EditorActivation } from 'vs/platform/editor/common/editor';
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
import { QueryInput } from 'sql/workbench/contrib/query/common/queryInput';
|
import { QueryEditorInput } from 'sql/workbench/contrib/query/common/queryEditorInput';
|
||||||
|
|
||||||
export class FileEditorTracker extends Disposable implements IWorkbenchContribution {
|
export class FileEditorTracker extends Disposable implements IWorkbenchContribution {
|
||||||
|
|
||||||
@@ -186,12 +186,12 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
|
|||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}} - Support FileEditorInput or QueryInput
|
// {{SQL CARBON EDIT}} - Support FileEditorInput or QueryInput
|
||||||
private getOpenedFileEditors(dirtyState: boolean): (FileEditorInput | QueryInput)[] {
|
private getOpenedFileEditors(dirtyState: boolean): (FileEditorInput | QueryEditorInput)[] {
|
||||||
const editors: (FileEditorInput | QueryInput)[] = [];
|
const editors: (FileEditorInput | QueryEditorInput)[] = [];
|
||||||
|
|
||||||
this.editorService.editors.forEach(editor => {
|
this.editorService.editors.forEach(editor => {
|
||||||
// {{SQL CARBON EDIT}} - Support FileEditorInput or QueryInput
|
// {{SQL CARBON EDIT}} - Support FileEditorInput or QueryInput
|
||||||
if (editor instanceof FileEditorInput || editor instanceof QueryInput) {
|
if (editor instanceof FileEditorInput || editor instanceof QueryEditorInput) {
|
||||||
if (!!editor.isDirty() === dirtyState) {
|
if (!!editor.isDirty() === dirtyState) {
|
||||||
editors.push(editor);
|
editors.push(editor);
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
|
|||||||
this.editorGroupService.groups.forEach(group => {
|
this.editorGroupService.groups.forEach(group => {
|
||||||
group.editors.forEach(editor => {
|
group.editors.forEach(editor => {
|
||||||
// {{SQL CARBON EDIT}} - Support FileEditorInput or QueryInput
|
// {{SQL CARBON EDIT}} - Support FileEditorInput or QueryInput
|
||||||
if (editor instanceof FileEditorInput || editor instanceof QueryInput) {
|
if (editor instanceof FileEditorInput || editor instanceof QueryEditorInput) {
|
||||||
const resource = editor.getResource();
|
const resource = editor.getResource();
|
||||||
|
|
||||||
// Update Editor if file (or any parent of the input) got renamed or moved
|
// Update Editor if file (or any parent of the input) got renamed or moved
|
||||||
|
|||||||
@@ -46,9 +46,6 @@ import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
|
|||||||
import { ExplorerItem, NewExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel';
|
import { ExplorerItem, NewExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel';
|
||||||
import { onUnexpectedError, getErrorMessage } from 'vs/base/common/errors';
|
import { onUnexpectedError, getErrorMessage } from 'vs/base/common/errors';
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
import { openNewQuery } from 'sql/workbench/contrib/query/browser/queryActions';
|
|
||||||
|
|
||||||
export const NEW_FILE_COMMAND_ID = 'explorer.newFile';
|
export const NEW_FILE_COMMAND_ID = 'explorer.newFile';
|
||||||
export const NEW_FILE_LABEL = nls.localize('newFile', "New File");
|
export const NEW_FILE_LABEL = nls.localize('newFile', "New File");
|
||||||
|
|
||||||
@@ -155,15 +152,13 @@ export class GlobalNewUntitledFileAction extends Action {
|
|||||||
constructor(
|
constructor(
|
||||||
id: string,
|
id: string,
|
||||||
label: string,
|
label: string,
|
||||||
// {{SQL CARBON EDIT}} - Make editorService protected and add other services
|
@IEditorService private readonly editorService: IEditorService
|
||||||
@IEditorService protected readonly editorService: IEditorService,
|
|
||||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
|
||||||
) {
|
) {
|
||||||
super(id, label);
|
super(id, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
run(): Promise<any> {
|
run(): Promise<any> {
|
||||||
return this.instantiationService.invokeFunction(openNewQuery); // {{SQL CARBON EDIT}}
|
return this.editorService.openEditor({ options: { pinned: true } }); // untitled are always pinned
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { toResource, IEditorCommandsContext, SideBySideEditor, EditorInput } from 'vs/workbench/common/editor'; // {{SQL CARBON EDIT}} add edit input
|
import { toResource, IEditorCommandsContext, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||||
import { IWindowOpenable, IOpenWindowOptions, isWorkspaceToOpen, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
|
import { IWindowOpenable, IOpenWindowOptions, isWorkspaceToOpen, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
|
||||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||||
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
@@ -128,14 +128,6 @@ async function save(
|
|||||||
return doSaveAs(resource, isSaveAs, options, editorService, fileService, untitledEditorService, textFileService, editorGroupService, queryEditorService, environmentService); // {{SQL CARBON EDIT}} add paramater
|
return doSaveAs(resource, isSaveAs, options, editorService, fileService, untitledEditorService, textFileService, editorGroupService, queryEditorService, environmentService); // {{SQL CARBON EDIT}} add paramater
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource && (fileService.canHandleResource(resource) || resource.scheme === Schemas.untitled)) {
|
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
let editorInput = editorService.activeEditor;
|
|
||||||
if (editorInput instanceof EditorInput && !(<EditorInput>editorInput).savingSupported) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
return doSave(resource, options, editorService, textFileService);
|
return doSave(resource, options, editorService, textFileService);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import { IEditorGroupView, IEditorOpeningEvent, EditorServiceImpl } from 'vs/wor
|
|||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||||
import { convertEditorInput, getFileMode } from 'sql/workbench/browser/customInputConverter'; //{{SQL CARBON EDIT}}
|
|
||||||
|
|
||||||
type CachedEditorInput = ResourceEditorInput | IFileEditorInput | DataUriEditorInput;
|
type CachedEditorInput = ResourceEditorInput | IFileEditorInput | DataUriEditorInput;
|
||||||
type OpenInEditorGroup = IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE;
|
type OpenInEditorGroup = IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE;
|
||||||
@@ -571,10 +570,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||||||
// Untitled file support
|
// Untitled file support
|
||||||
const untitledInput = input as IUntitledResourceInput;
|
const untitledInput = input as IUntitledResourceInput;
|
||||||
if (untitledInput.forceUntitled || !untitledInput.resource || (untitledInput.resource && untitledInput.resource.scheme === Schemas.untitled)) {
|
if (untitledInput.forceUntitled || !untitledInput.resource || (untitledInput.resource && untitledInput.resource.scheme === Schemas.untitled)) {
|
||||||
// {{SQL CARBON EDIT}}
|
return this.untitledEditorService.createOrGet(untitledInput.resource, untitledInput.mode, untitledInput.contents, untitledInput.encoding);
|
||||||
// Need to get mode for QueryEditor and Notebook
|
|
||||||
let mode: string = untitledInput.mode ? untitledInput.mode : getFileMode(this.instantiationService, untitledInput.resource);
|
|
||||||
return convertEditorInput(this.untitledEditorService.createOrGet(untitledInput.resource, mode, untitledInput.contents, untitledInput.encoding), undefined, this.instantiationService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resource Editor Support
|
// Resource Editor Support
|
||||||
@@ -585,9 +581,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||||||
label = basename(resourceInput.resource); // derive the label from the path (but not for data URIs)
|
label = basename(resourceInput.resource); // derive the label from the path (but not for data URIs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
return this.createOrGet(resourceInput.resource, this.instantiationService, label, resourceInput.description, resourceInput.encoding, resourceInput.mode, resourceInput.forceFile) as EditorInput;
|
||||||
return convertEditorInput(this.createOrGet(resourceInput.resource, this.instantiationService, label, resourceInput.description, resourceInput.encoding, resourceInput.mode, resourceInput.forceFile) as EditorInput,
|
|
||||||
undefined, this.instantiationService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error('Unknown input type');
|
throw new Error('Unknown input type');
|
||||||
|
|||||||
@@ -363,13 +363,16 @@ import 'vs/workbench/contrib/userDataSync/browser/userDataSync.contribution';
|
|||||||
|
|
||||||
// query
|
// query
|
||||||
import 'sql/workbench/contrib/query/browser/query.contribution';
|
import 'sql/workbench/contrib/query/browser/query.contribution';
|
||||||
import 'sql/workbench/contrib/query/common/resultsGridContribution';
|
import 'sql/workbench/contrib/query/common/resultsGrid.contribution';
|
||||||
|
|
||||||
// data explorer
|
// data explorer
|
||||||
import 'sql/workbench/contrib/dataExplorer/browser/dataExplorer.contribution';
|
import 'sql/workbench/contrib/dataExplorer/browser/dataExplorer.contribution';
|
||||||
import 'sql/workbench/contrib/dataExplorer/browser/nodeActions.common.contribution';
|
import 'sql/workbench/contrib/dataExplorer/browser/nodeActions.common.contribution';
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
|
//editor replacement
|
||||||
|
import 'sql/workbench/common/editorReplacer.contribution';
|
||||||
|
|
||||||
// tasks
|
// tasks
|
||||||
import 'sql/workbench/contrib/tasks/browser/tasks.contribution';
|
import 'sql/workbench/contrib/tasks/browser/tasks.contribution';
|
||||||
import 'sql/workbench/browser/actions.contribution';
|
import 'sql/workbench/browser/actions.contribution';
|
||||||
|
|||||||
Reference in New Issue
Block a user