Compare commits

..

20 Commits
1.3.0 ... 1.2.4

Author SHA1 Message Date
Kevin Cunnane
1ebfd02356 Snippets: fix sqlCreateTable, remove database refs & use dbo schema (#3094)
- Fixed issues with sqlCreateTable snippet, which meant it couldn't effectively be used to tab through all fields and then hit execute without errors. Specifically fixed bugs where types like NVARCHAR were incorrectly escaped and the Id part of a column was outside the name section, both causing intellisense & execution breaks
- Changed SchemaName to dbo. This helps hit the "80% case" where objects are in the most common schema
- Removed DatabaseName from most snippets. The core issue is this requires you to manually type the exact database name into the snippet which is really hard. We should consider having separate "with Database" snippets or support SQLCMD variables which would let us default to the current database without needing users to manually type them in as alternatives, but having basic snippets just work on current DB is important.
2018-11-02 14:26:53 -07:00
Karl Burtram
c942bc1dbb Bump Azure Data Studio to 1.2.4 2018-11-01 15:10:50 -07:00
Karl Burtram
8439cde610 Bump SQL Tools to 1.5.0-alpha.52 2018-10-31 20:38:22 -07:00
Anthony Dresser
2080c525a7 Auto Scale Axis (#3070)
* fix input to chart that was causes scales to not auto size

* formatting

* formatting

* added comments
2018-10-31 20:33:09 -07:00
Aditya Bist
db2d380b6c Agent/edit job logic (#3023)
* lumped stepdata with jobdata in job dialog

* fix bug with empty steps

* added clumped and update steps and schedules from job dialog

* edit data sends one call instead of multiple

* cleaned code
2018-10-31 20:32:59 -07:00
Alan Ren
a06f80bdb1 fix for issue 3065 (#3067)
* fix for 3065

* remove the parameter, no need to save connection
2018-10-31 20:32:51 -07:00
Karl Burtram
1f76c85b1b Remove SQL Import dashboard tab (#3064) 2018-10-31 20:32:37 -07:00
Karl Burtram
cffc18d5ea Revert "Revert "Add a command line interface for connecting to a SQL Server (#3047)""
This reverts commit a747b6a500.
2018-10-31 20:32:17 -07:00
Karl Burtram
a747b6a500 Revert "Add a command line interface for connecting to a SQL Server (#3047)"
This reverts commit 7f66087d8c.
2018-10-31 14:39:46 -07:00
Aditya Bist
711b7bf622 fixed null ref (#3061) 2018-10-31 14:25:39 -07:00
Alan Ren
9b0757de9c a few ux improvements (#3057)
* style update

* checkbox styler

* casing update
2018-10-31 14:25:26 -07:00
Alan Ren
b9a0744a83 fix for issue 2719 (#3060) 2018-10-31 14:25:14 -07:00
Karl Burtram
c69915ca58 Bump SQL Tools to 1.5.0-alpha.51 2018-10-31 13:17:20 -07:00
Karl Burtram
a16835918a Fix build break in previous Query Plan commit 2018-10-31 13:04:32 -07:00
David Shiflet
f9e27d7112 Add a command line interface for connecting to a SQL Server (#3047)
* Add switches for server, database, user, integrated auth

* Refactor into new commandline service

* Open query editor when passed server on command line

* Add tests
2018-10-31 10:14:36 -07:00
Ryan
c072ba9c5c Add query plan theme support (#2991) (#3031)
Add monaco-editor and monaco-editor-hover to output otherwise backgrounds collide.
2018-10-31 10:14:26 -07:00
Alan Ren
807fb2ed8a fix missing footer for backup dialog (#3056)
@MattIrv  Thanks for helping out
2018-10-31 09:46:14 -07:00
Ruturaj Gujar
daf347b728 Fixed some typos and grammatical errors (#3027) 2018-10-31 09:46:06 -07:00
Karl Burtram
e76222db7a Change 'None' to 'Do not save' in Connection Dialog (#3051) 2018-10-30 10:46:24 -07:00
Karl Burtram
f676090901 Bump Azure Data Studio to 1.2.3 2018-10-30 10:28:29 -07:00
47 changed files with 201 additions and 474 deletions

View File

@@ -35,7 +35,7 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
private static readonly PagerSundayCheckBoxLabel: string = localize('createOperator.PagerSundayCheckBox', 'Sunday');
private static readonly WorkdayBeginLabel: string = localize('createOperator.workdayBegin', 'Workday begin');
private static readonly WorkdayEndLabel: string = localize('createOperator.workdayEnd', 'Workday end');
private static readonly PagerDutyScheduleLabel: string = localize('createOperator.PagerDutySchedule', 'Pager on duty schedule');
private static readonly PagerDutyScheduleLabel: string = localize('createOperator.PagerDutySchedule', 'Pager on duty schdule');
// Notifications tab strings
private static readonly AlertsTableLabel: string = localize('createOperator.AlertListHeading', 'Alert list');

View File

@@ -345,7 +345,7 @@
"specialValueType": null,
"isIdentity": false,
"name": "asynchronousProcessing",
"displayName": "Asynchronous processing",
"displayName": "Asynchronous processing enabled",
"description": "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
"groupName": "Initialization",
"valueType": "boolean",
@@ -387,7 +387,7 @@
"specialValueType": null,
"isIdentity": false,
"name": "columnEncryptionSetting",
"displayName": "Column encryption",
"displayName": "Column encryption setting",
"description": "Default column encryption setting for all the commands on the connection",
"groupName": "Security",
"valueType": "category",

View File

@@ -12,7 +12,6 @@ import { CreateSessionData } from '../data/createSessionData';
const localize = nls.loadMessageBundle();
export class CreateSessionDialog {
private readonly _providerType: string;
// Top level
private readonly DialogTitle: string = localize('createSessionDialog.newSession', 'New Session');
@@ -31,17 +30,13 @@ export class CreateSessionDialog {
public readonly onSuccess: vscode.Event<CreateSessionData> = this._onSuccess.event;
constructor(ownerUri: string, providerType: string, templates: Array<sqlops.ProfilerSessionTemplate>) {
constructor(ownerUri: string, templates: Array<sqlops.ProfilerSessionTemplate>) {
if (typeof (templates) === 'undefined' || templates === null) {
throw new Error(localize('createSessionDialog.templatesInvalid', "Invalid templates list, cannot open dialog"));
}
if (typeof (ownerUri) === 'undefined' || ownerUri === null) {
throw new Error(localize('createSessionDialog.dialogOwnerInvalid', "Invalid dialog owner, cannot open dialog"));
}
if (typeof (providerType) === 'undefined' || providerType === null) {
throw new Error(localize('createSessionDialog.invalidProviderType', "Invalid provider type, cannot open dialog"));
}
this._providerType = providerType;
this.model = new CreateSessionData(ownerUri, templates);
}
@@ -102,7 +97,8 @@ export class CreateSessionDialog {
}
private async execute(): Promise<void> {
let profilerService = sqlops.dataprotocol.getProvider<sqlops.ProfilerProvider>(this._providerType, sqlops.DataProviderType.ProfilerProvider);
let currentConnection = await sqlops.connection.getCurrentConnection();
let profilerService = sqlops.dataprotocol.getProvider<sqlops.ProfilerProvider>(currentConnection.providerName, sqlops.DataProviderType.ProfilerProvider);
let name = this.sessionNameBox.value;
let selected = this.templatesBox.value.toString();

View File

@@ -29,8 +29,8 @@ export class MainController {
}
public activate(): void {
vscode.commands.registerCommand('profiler.openCreateSessionDialog', (ownerUri: string, providerType: string, templates: Array<sqlops.ProfilerSessionTemplate>) => {
let dialog = new CreateSessionDialog(ownerUri, providerType, templates);
vscode.commands.registerCommand('profiler.openCreateSessionDialog', (ownerUri: string, templates: Array<sqlops.ProfilerSessionTemplate>) => {
let dialog = new CreateSessionDialog(ownerUri, templates);
dialog.showDialog();
});
}

View File

@@ -26,6 +26,7 @@
"Microsoft.mssql"
],
"contributes": {
"commands": [
{
"command": "profiler.newProfiler",
@@ -48,15 +49,6 @@
"category": "Profiler"
}
],
"menus": {
"objectExplorer/item/context": [
{
"command": "profiler.newProfiler",
"when": "connectionProvider == MSSQL && nodeType && nodeType == Server",
"group": "profiler"
}
]
},
"outputChannels": [
"sqlprofiler"
]
@@ -67,4 +59,4 @@
"devDependencies": {
"vscode": "1.0.1"
}
}
}

View File

@@ -67,8 +67,7 @@
"panel.background": "#212121",
"panel.border": "#515151",
"panelTitle.activeForeground": "#ffffff",
"panelTitle.inactiveForeground": "#888888",
"panelTitle.activeBorder": "#026dc8"
"panelTitle.inactiveForeground": "#888888"
},
"tokenColors": [
{

View File

@@ -77,8 +77,7 @@
"panel.background": "#ffffff",
"panel.border": "#c8c8c8",
"panelTitle.activeForeground": "#212121",
"panelTitle.inactiveForeground": "#757575",
"panelTitle.activeBorder": "#026dc8"
"panelTitle.inactiveForeground": "#757575"
},
"tokenColors": [
{

View File

@@ -611,7 +611,7 @@
</body></file>
<file original="src/sql/parts/connection/common/connectionActions" source-language="en" datatype="plaintext"><body>
<trans-unit id="ClearRecentlyUsedLabel">
<source xml:lang="en">Clear List</source>
<source xml:lang="en">Clear Recent Connections List</source>
</trans-unit>
<trans-unit id="ClearedRecentConnections">
<source xml:lang="en">Recent connections list cleared</source>
@@ -1039,10 +1039,10 @@
<source xml:lang="en">Connection</source>
</trans-unit>
<trans-unit id="recentConnectionTitle">
<source xml:lang="en">Recent Connections</source>
<source xml:lang="en">Recent connections</source>
</trans-unit>
<trans-unit id="savedConnectionTitle">
<source xml:lang="en">Saved Connections</source>
<source xml:lang="en">Saved connections</source>
</trans-unit>
<trans-unit id="connectType">
<source xml:lang="en">Connection type</source>
@@ -1644,7 +1644,7 @@
</body></file>
<file original="src/sql/parts/connection/connectionDialog/advancedPropertiesController" source-language="en" datatype="plaintext"><body>
<trans-unit id="connectionAdvancedProperties">
<source xml:lang="en">Advanced Properties</source>
<source xml:lang="en">Advanced properties</source>
</trans-unit>
<trans-unit id="advancedProperties.discard">
<source xml:lang="en">Discard</source>

View File

@@ -56,7 +56,6 @@
.modal .modal-title {
font-size: 15px;
font-weight: 600;
}
.modal .modal-title-icon {
@@ -148,7 +147,7 @@
}
.modal .footer-button {
margin-left: 5px;
margin-right: 5px;
}
.modal .right-footer .footer-button:last-of-type {

View File

@@ -20,34 +20,11 @@
}
.optionsDialog-options-groups {
margin-top: 10px;
flex: 1 1;
padding: 15px;
height: calc(100% - 150px);
overflow-y: auto;
}
.optionsDialog-options-groups {
margin: 10px 0px;
flex: 1 1;
overflow-y: auto;
}
.vs .optionsDialog-options-groups {
box-shadow: 0 1px 4px 1px rgba(220, 220, 220, 0.71);
}
.vs-dark .optionsDialog-options-groups {
box-shadow: 0 4px 5px 0px rgba(0, 0, 0, 0.71);
}
.optionsDialog-options-groups .split-view-view .header {
padding-left: 28px !important;
background-position-x: 8px !important;
}
.optionsDialog-options-groups .split-view-view .body {
padding-left: 5px !important;
}
.backButtonIcon {
content: url('back.svg');
width: 20px;
@@ -56,42 +33,21 @@
cursor: pointer;
}
.hc-black .backButtonIcon,
.vs-dark .backButtonIcon {
.vs-dark.monaco-shell .backButtonIcon {
content: url('back_inverse.svg');
}
.optionsDialog-description {
height: 90px;
margin: 15px;
overflow-y: auto;
}
.optionsDialog-description .modal-title {
background-repeat: no-repeat;
background-position: 2px center;
padding-left: 25px;
background-size: 16px;
}
.vs .optionsDialog-description .modal-title {
background-image: url('info_notification.svg')
}
.vs-dark .optionsDialog-description .modal-title,
.hc-black .optionsDialog-description .modal-title {
background-image: url('info_notification_inverse.svg')
padding: 15px;
overflow-y: auto;
}
.optionsDialog-options {
height: 100%;
display: flex;
flex-direction: column;
height: calc(100% - 30px);
}
.optionsDialog-description-content {
padding-top: 10px;
padding-left: 25px;
padding: 10px;
}
.optionsDialog-table{

View File

@@ -125,7 +125,7 @@ export class OptionsDialog extends Modal {
});
let builder = new Builder(this._body);
builder.div({}, (dividerContainer) => {
builder.div({ class: 'Connection-divider' }, (dividerContainer) => {
this._dividerBuilder = dividerContainer;
});

View File

@@ -46,9 +46,9 @@ panel {
}
.tabbedPanel .tabList .tab .tabLabel {
font-size: 14px;
text-transform: uppercase;
font-size: 13px;
padding-bottom: 4px;
font-weight: 600;
}
.tabbedPanel.vertical .tabList .tab .tabLabel {

View File

@@ -36,6 +36,7 @@ export interface IPanelTab {
interface IInternalPanelTab extends IPanelTab {
header: HTMLElement;
label: HTMLElement;
dispose(): void;
}
const defaultOptions: IPanelOptions = {
@@ -142,6 +143,8 @@ export class TabbedPanel extends Disposable implements IThemable {
this.tabList.appendChild(tabHeaderElement);
tab.header = tabHeaderElement;
tab.label = tabLabel;
tab.dispose = () => { };
this._register(tab);
}
public showTab(id: PanelTabIdentifier): void {

View File

@@ -19,7 +19,6 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
.tabbedPanel > .title .tabList .tab .tabLabel.active {
color: ${titleActive};
border-bottom-color: ${titleActiveBorder};
border-bottom-width: 2px;
}
.tabbedPanel > .title .tabList .tab-header.active {

View File

@@ -3,14 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposableDataProvider } from 'sql/base/browser/ui/table/interfaces';
export interface IObservableCollection<T> {
getLength(): number;
at(index: number): T;
getRange(start: number, end: number): T[];
setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void;
dispose(): void;
}
export interface IGridDataRow {
@@ -27,27 +24,24 @@ class LoadCancellationToken {
}
class DataWindow<TData> {
private _dataSourceLength: number;
private _data: TData[];
private _length: number = 0;
private _offsetFromDataSource: number = -1;
private loadFunction: (offset: number, count: number) => Thenable<TData[]>;
private lastLoadCancellationToken: LoadCancellationToken;
private loadCompleteCallback: (start: number, end: number) => void;
private placeholderItemGenerator: (index: number) => TData;
constructor(
private loadFunction: (offset: number, count: number) => Thenable<TData[]>,
private placeholderItemGenerator: (index: number) => TData,
private loadCompleteCallback: (start: number, end: number) => void
) {
}
dispose() {
this._data = undefined;
this.loadFunction = undefined;
this.placeholderItemGenerator = undefined;
this.loadCompleteCallback = undefined;
if (this.lastLoadCancellationToken) {
this.lastLoadCancellationToken.isCancelled = true;
}
constructor(dataSourceLength: number,
loadFunction: (offset: number, count: number) => Thenable<TData[]>,
placeholderItemGenerator: (index: number) => TData,
loadCompleteCallback: (start: number, end: number) => void) {
this._dataSourceLength = dataSourceLength;
this.loadFunction = loadFunction;
this.placeholderItemGenerator = placeholderItemGenerator;
this.loadCompleteCallback = loadCompleteCallback;
}
getStartIndex(): number {
@@ -82,9 +76,10 @@ class DataWindow<TData> {
return;
}
this.lastLoadCancellationToken = new LoadCancellationToken();
let cancellationToken = new LoadCancellationToken();
this.lastLoadCancellationToken = cancellationToken;
this.loadFunction(offset, length).then(data => {
if (!this.lastLoadCancellationToken.isCancelled) {
if (!cancellationToken.isCancelled) {
this._data = data;
this.loadCompleteCallback(this._offsetFromDataSource, this._offsetFromDataSource + this._length);
}
@@ -102,12 +97,10 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
private collectionChangedCallback: (change: CollectionChange, startIndex: number, count: number) => void;
constructor(
windowSize: number,
constructor(windowSize: number,
length: number,
loadFn: (offset: number, count: number) => Thenable<TData[]>,
private _placeHolderGenerator: (index: number) => TData
) {
private _placeHolderGenerator: (index: number) => TData) {
this._windowSize = windowSize;
this._length = length;
@@ -117,15 +110,9 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
}
};
this._bufferWindowBefore = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
this._window = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
this._bufferWindowAfter = new DataWindow(loadFn, _placeHolderGenerator, loadCompleteCallback);
}
dispose() {
this._bufferWindowAfter.dispose();
this._bufferWindowBefore.dispose();
this._window.dispose();
this._bufferWindowBefore = new DataWindow(length, loadFn, _placeHolderGenerator, loadCompleteCallback);
this._window = new DataWindow(length, loadFn, _placeHolderGenerator, loadCompleteCallback);
this._bufferWindowAfter = new DataWindow(length, loadFn, _placeHolderGenerator, loadCompleteCallback);
}
setCollectionChangedCallback(callback: (change: CollectionChange, startIndex: number, count: number) => void): void {
@@ -210,7 +197,7 @@ export class VirtualizedCollection<TData> implements IObservableCollection<TData
}
}
export class AsyncDataProvider<TData extends IGridDataRow> implements IDisposableDataProvider<TData> {
export class AsyncDataProvider<TData extends IGridDataRow> implements Slick.DataProvider<TData> {
constructor(private dataRows: IObservableCollection<TData>) { }
@@ -225,8 +212,4 @@ export class AsyncDataProvider<TData extends IGridDataRow> implements IDisposabl
public getRange(start: number, end: number): TData[] {
return !this.dataRows ? undefined : this.dataRows.getRange(start, end);
}
dispose() {
this.dataRows.dispose();
}
}

View File

@@ -1,31 +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 { IListStyles } from 'vs/base/browser/ui/list/listWidget';
import { Color } from 'vs/base/common/color';
export interface IDisposableDataProvider<T> extends Slick.DataProvider<T> {
dispose(): void;
}
export interface ITableMouseEvent {
anchor: HTMLElement | { x: number, y: number };
cell?: { row: number, cell: number };
}
export interface ITableStyles extends IListStyles {
tableHeaderBackground?: Color;
tableHeaderForeground?: Color;
}
export interface ITableSorter<T> {
sort(args: Slick.OnSortEventArgs<T>);
}
export interface ITableConfiguration<T> {
dataProvider?: IDisposableDataProvider<T> | Array<T>;
columns?: Slick.Column<T>[];
sorter?: ITableSorter<T>;
}

View File

@@ -5,18 +5,28 @@
import 'vs/css!./media/table';
import { TableDataView } from './tableDataView';
import { IDisposableDataProvider, ITableSorter, ITableMouseEvent, ITableConfiguration, ITableStyles } from 'sql/base/browser/ui/table/interfaces';
import { IThemable } from 'vs/platform/theme/common/styler';
import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
import * as DOM from 'vs/base/browser/dom';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
import { Widget } from 'vs/base/browser/ui/widget';
import { isArray, isBoolean } from 'vs/base/common/types';
import { Event, Emitter } from 'vs/base/common/event';
import { range } from 'vs/base/common/arrays';
import { $ } from 'vs/base/browser/builder';
export interface ITableMouseEvent {
anchor: HTMLElement | { x: number, y: number };
cell?: { row: number, cell: number };
}
export interface ITableStyles extends IListStyles {
tableHeaderBackground?: Color;
tableHeaderForeground?: Color;
}
function getDefaultOptions<T>(): Slick.GridOptions<T> {
return <Slick.GridOptions<T>>{
@@ -25,13 +35,23 @@ function getDefaultOptions<T>(): Slick.GridOptions<T> {
};
}
export interface ITableSorter<T> {
sort(args: Slick.OnSortEventArgs<T>);
}
export interface ITableConfiguration<T> {
dataProvider?: Slick.DataProvider<T> | Array<T>;
columns?: Slick.Column<T>[];
sorter?: ITableSorter<T>;
}
export class Table<T extends Slick.SlickData> extends Widget implements IThemable, IDisposable {
private styleElement: HTMLStyleElement;
private idPrefix: string;
private _grid: Slick.Grid<T>;
private _columns: Slick.Column<T>[];
private _data: IDisposableDataProvider<T>;
private _data: Slick.DataProvider<T>;
private _sorter: ITableSorter<T>;
private _autoscroll: boolean;
@@ -40,6 +60,8 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
private _classChangeTimeout: number;
private _disposables: IDisposable[] = [];
private _onContextMenu = new Emitter<ITableMouseEvent>();
public readonly onContextMenu: Event<ITableMouseEvent> = this._onContextMenu.event;
@@ -54,8 +76,6 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
this._data = configuration.dataProvider;
}
this._register(this._data);
if (configuration && configuration.columns) {
this._columns = configuration.columns;
} else {
@@ -97,12 +117,6 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
});
}
this._register({
dispose: () => {
this._grid.destroy();
}
});
this.mapMouseEvent(this._grid.onContextMenu, this._onContextMenu);
this.mapMouseEvent(this._grid.onClick, this._onClick);
}
@@ -117,8 +131,7 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
}
public dispose() {
$(this._container).dispose();
super.dispose();
dispose(this._disposables);
}
public invalidateRows(rows: number[], keepEditor: boolean) {
@@ -153,7 +166,7 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
this._grid.setData(this._data, true);
}
getData(): IDisposableDataProvider<T> {
getData(): Slick.DataProvider<T> {
return this._data;
}

View File

@@ -9,8 +9,6 @@ import { Event, Emitter } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import * as types from 'vs/base/common/types';
import { IDisposableDataProvider } from 'sql/base/browser/ui/table/interfaces';
export interface IFindPosition {
col: number;
row: number;
@@ -22,7 +20,7 @@ function defaultSort<T>(args: Slick.OnSortEventArgs<T>, data: Array<T>): Array<T
return data.sort((a, b) => (a[field] === b[field] ? 0 : (a[field] > b[field] ? 1 : -1)) * sign);
}
export class TableDataView<T extends Slick.SlickData> implements IDisposableDataProvider<T> {
export class TableDataView<T extends Slick.SlickData> implements Slick.DataProvider<T> {
private _data: Array<T>;
private _findArray: Array<IFindPosition>;
private _findObs: Observable<IFindPosition>;
@@ -156,10 +154,4 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
get findCount(): number {
return types.isUndefinedOrNull(this._findArray) ? 0 : this._findArray.length;
}
dispose() {
this._data = undefined;
this._findArray = undefined;
this._findObs = undefined;
}
}

View File

@@ -26,7 +26,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
export class ClearRecentConnectionsAction extends Action {
public static ID = 'clearRecentConnectionsAction';
public static LABEL = nls.localize('ClearRecentlyUsedLabel', 'Clear List');
public static LABEL = nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List');
public static ICON = 'search-action clear-search-results';
private _onRecentConnectionsRemoved = new Emitter<void>();
@@ -83,7 +83,7 @@ export class ClearRecentConnectionsAction extends Action {
{ key: nls.localize('connectionAction.no', 'No'), value: false }
];
self._quickOpenService.pick(choices.map(x => x.key), { placeHolder: nls.localize('ClearRecentlyUsedLabel', 'Clear List'), ignoreFocusLost: true }).then((choice) => {
self._quickOpenService.pick(choices.map(x => x.key), { placeHolder: nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List'), ignoreFocusLost: true }).then((choice) => {
let confirm = choices.find(x => x.key === choice);
resolve(confirm && confirm.value);
});

View File

@@ -38,7 +38,7 @@ export class AdvancedPropertiesController {
public get advancedDialog() {
if (!this._advancedDialog) {
this._advancedDialog = this._instantiationService.createInstance(
OptionsDialog, localize('connectionAdvancedProperties', 'Advanced Properties'), TelemetryKeys.ConnectionAdvancedProperties, { hasBackButton: true });
OptionsDialog, localize('connectionAdvancedProperties', 'Advanced properties'), TelemetryKeys.ConnectionAdvancedProperties, { hasBackButton: true });
this._advancedDialog.cancelLabel = localize('advancedProperties.discard', 'Discard');
this._advancedDialog.onCloseEvent(() => this._onCloseAdvancedProperties());
this._advancedDialog.onOk(() => this.handleOnOk());

View File

@@ -37,7 +37,6 @@ import * as styler from 'vs/platform/theme/common/styler';
import * as DOM from 'vs/base/browser/dom';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
export interface OnShowUIResponse {
selectedProviderType: string;
@@ -50,7 +49,7 @@ export class ConnectionDialogWidget extends Modal {
private _noRecentConnectionBuilder: Builder;
private _savedConnectionBuilder: Builder;
private _noSavedConnectionBuilder: Builder;
private _connectionDetailTitle: Builder;
private _dividerBuilder: Builder;
private _connectButton: Button;
private _closeButton: Button;
private _providerTypeSelectBox: SelectBox;
@@ -144,7 +143,7 @@ export class ConnectionDialogWidget extends Modal {
this._panel = new TabbedPanel(connectionContainer.getHTMLElement());
this._recentConnectionTabId = this._panel.pushTab({
identifier: 'recent_connection',
title: localize('recentConnectionTitle', 'Recent Connections'),
title: localize('recentConnectionTitle', 'Recent connections'),
view: {
render: c => {
recentConnectionTab.appendTo(c);
@@ -155,7 +154,7 @@ export class ConnectionDialogWidget extends Modal {
let savedConnectionTabId = this._panel.pushTab({
identifier: 'saved_connection',
title: localize('savedConnectionTitle', 'Saved Connections'),
title: localize('savedConnectionTitle', 'Saved connections'),
view: {
layout: () => { },
render: c => {
@@ -180,9 +179,8 @@ export class ConnectionDialogWidget extends Modal {
}
});
this._bodyBuilder.div({ class: 'connection-details-title' }, (dividerContainer) => {
this._connectionDetailTitle = dividerContainer;
this._connectionDetailTitle.text(localize('connectionDetailsTitle', 'Connection Details'));
this._bodyBuilder.div({ class: 'Connection-divider' }, (dividerContainer) => {
this._dividerBuilder = dividerContainer;
});
this._bodyBuilder.div({ class: 'connection-type' }, (modelTableContent) => {
@@ -219,12 +217,10 @@ export class ConnectionDialogWidget extends Modal {
private updateTheme(theme: IColorTheme): void {
let borderColor = theme.getColor(contrastBorder);
let border = borderColor ? borderColor.toString() : null;
let backgroundColor = theme.getColor(SIDE_BAR_BACKGROUND);
if (this._connectionDetailTitle) {
this._connectionDetailTitle.style('border-width', border ? '1px 0px' : null);
this._connectionDetailTitle.style('border-style', border ? 'solid none' : null);
this._connectionDetailTitle.style('border-color', border);
this._connectionDetailTitle.style('background-color', backgroundColor ? backgroundColor.toString() : null);
if (this._dividerBuilder) {
this._dividerBuilder.style('border-top-width', border ? '1px' : null);
this._dividerBuilder.style('border-top-style', border ? 'solid' : null);
this._dividerBuilder.style('border-top-color', border);
}
}
@@ -281,13 +277,17 @@ export class ConnectionDialogWidget extends Modal {
private createRecentConnectionList(): void {
this._recentConnectionBuilder.div({ class: 'connection-recent-content' }, (recentConnectionContainer) => {
let recentHistoryLabel = localize('recentHistory', 'Recent history');
recentConnectionContainer.div({ class: 'recent-titles-container' }, (container) => {
container.div({ class: 'connection-history-label' }, (recentTitle) => {
recentTitle.text(recentHistoryLabel);
});
container.div({ class: 'connection-history-actions' }, (actionsContainer) => {
this._actionbar = this._register(new ActionBar(actionsContainer.getHTMLElement(), { animated: false }));
let clearAction = this._instantiationService.createInstance(ClearRecentConnectionsAction, ClearRecentConnectionsAction.ID, ClearRecentConnectionsAction.LABEL);
clearAction.useConfirmationMessage = true;
clearAction.onRecentConnectionsRemoved(() => this.open(false));
this._actionbar.push(clearAction, { icon: true, label: true });
this._actionbar.push(clearAction, { icon: true, label: false });
});
});
recentConnectionContainer.div({ class: 'server-explorer-viewlet' }, (divContainer: Builder) => {

View File

@@ -9,35 +9,25 @@
}
.connection-input {
padding-right:8px;
width: 200px;
padding-bottom: 5px;
}
.connection-dialog {
height: 100%;
display: flex;
flex-direction: column;
overflow-x: hidden;
overflow-y: auto;
height: calc(100% - 20px);
}
.connection-dialog .tabbedPanel {
border-top-color: transparent;
flex: 1 1;
height: calc(100% - 350px);
display: block;
min-height: 120px;
overflow: hidden;
margin: 0px 11px;
}
.connection-dialog .tabBody {
overflow: hidden;
flex: 1 1;
display: flex;
flex-direction: column;
}
.connection-recent, .connection-saved {
margin: 5px;
flex: 1 1;
margin: 15px;
height: calc(100% - 60px);
overflow-y: auto;
}
@@ -55,8 +45,6 @@
.recent-titles-container {
display: flex;
justify-content: space-between;
margin: 5px;
flex: 0 0 auto;
}
.connection-provider-info {
@@ -65,13 +53,7 @@
}
.connection-recent-content {
height: 100%;
display: flex;
flex-direction: column;
}
.connection-recent-content .server-explorer-viewlet {
flex: 1 1;
height: calc(100% - 20px);
}
.connection-table-content {
@@ -84,9 +66,8 @@
}
.connection-type {
flex: 0 0 auto;
overflow: hidden;
margin: 0px 13px;
margin: 15px;
overflow-y: hidden;
}
.connection-dialog .connection-history-actions .action-label.icon {
@@ -95,9 +76,8 @@
line-height: 20px;
min-width: 20px;
background-size: 16px;
background-position: 2px center;
background-position: center center;
background-repeat: no-repeat;
padding-left: 25px;
}
.search-action.clear-search-results {
@@ -107,11 +87,4 @@
.vs-dark .search-action.clear-search-results,
.hc-black .search-action.clear-search-results {
background: url('clear-search-results-dark.svg');
}
.connection-details-title {
font-size: 14px;
margin: 5px 0px;
padding: 5px 15px;
font-weight: 600;
}

View File

@@ -5,5 +5,6 @@
.advanced-button {
width: 100px;
padding-right:8px;
padding-bottom: 5px;
}

View File

@@ -90,11 +90,9 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
* Return actions for connection elements
*/
public getConnectionActions(tree: ITree, profile: ConnectionProfile): IAction[] {
let node = new TreeNode(NodeType.Server, '', false, '', '', '', undefined, undefined, undefined, undefined);
return this.getAllActions({
tree: tree,
profile: profile,
treeNode: node
profile: profile
}, (context) => this.getBuiltinConnectionActions(context));
}
@@ -127,6 +125,10 @@ export class ServerTreeActionProvider extends ContributableActionProvider {
actions.push(this._instantiationService.createInstance(DeleteConnectionAction, DeleteConnectionAction.ID, DeleteConnectionAction.DELETE_CONNECTION_LABEL, context.profile));
actions.push(this._instantiationService.createInstance(RefreshAction, RefreshAction.ID, RefreshAction.LABEL, context.tree, context.profile));
if (process.env['VSCODE_DEV'] && constants.MssqlProviderId === context.profile.providerName) {
actions.push(this._instantiationService.createInstance(OEAction, NewProfilerAction.ID, NewProfilerAction.LABEL));
}
return actions;
}

View File

@@ -31,8 +31,8 @@ export class TreeCreationUtils {
return new Tree(treeContainer, { dataSource, renderer, controller, dnd, filter, sorter, accessibilityProvider },
{
indentPixels: 0,
twistiePixels: 0,
indentPixels: 10,
twistiePixels: 20,
ariaLabel: nls.localize('treeAriaLabel', "Recent Connections")
});
}

View File

@@ -9,7 +9,7 @@ import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiati
import * as nls from 'vs/nls';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IConnectionManagementService, IConnectionDialogService} from 'sql/parts/connection/common/connectionManagement';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { IObjectExplorerService } from '../../objectExplorer/common/objectExplorerService';
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
import { TPromise } from 'vs/base/common/winjs.base';
@@ -18,10 +18,6 @@ import { IProfilerService } from '../service/interfaces';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeyCode, KeyMod } from 'vs/editor/editor.api';
import { ProfilerEditor } from '../editor/profilerEditor';
import { ObjectExplorerActionsContext } from 'sql/parts/objectExplorer/viewlet/objectExplorerActions';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import { mssqlProviderName } from 'sql/parts/connection/common/constants';
// Contribute Global Actions
const category = nls.localize('profilerCategory', "Profiler");
@@ -34,45 +30,15 @@ const newProfilerSchema: IJSONSchema = {
CommandsRegistry.registerCommand({
id: 'profiler.newProfiler',
handler: (accessor: ServicesAccessor, ...args: any[]) => {
let connectionProfile: ConnectionProfile = undefined;
let instantiationService: IInstantiationService = accessor.get(IInstantiationService);
handler: (accessor: ServicesAccessor) => {
let editorService: IEditorService = accessor.get(IEditorService);
let instantiationService: IInstantiationService = accessor.get(IInstantiationService);
let connectionService: IConnectionManagementService = accessor.get(IConnectionManagementService);
let objectExplorerService: IObjectExplorerService = accessor.get(IObjectExplorerService);
let connectionDialogService: IConnectionDialogService = accessor.get(IConnectionDialogService);
let capabilitiesService: ICapabilitiesService = accessor.get(ICapabilitiesService);
// If a context is available if invoked from the context menu, we will use the connection profiler of the server node
if (args && args.length === 1 && args[0] && args[0] instanceof ObjectExplorerActionsContext) {
let context = args[0] as ObjectExplorerActionsContext;
connectionProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesService, context.connectionProfile);
}
else {
// No context available, we will try to get the current global active connection
connectionProfile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionService, editorService) as ConnectionProfile;
}
let promise;
if (connectionProfile) {
promise = connectionService.connectIfNotConnected(connectionProfile);
} else {
// if still no luck, we will open the Connection dialog and let user connect to a server
promise = connectionDialogService.openDialogAndWait(connectionService, { connectionType: 1, providers: [mssqlProviderName] }).then((profile) => {
connectionProfile = profile as ConnectionProfile;
});
}
return promise.then(() => {
if (!connectionProfile) {
connectionProfile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionService, editorService) as ConnectionProfile;
}
if (connectionProfile && connectionProfile.providerName === mssqlProviderName) {
let profilerInput = instantiationService.createInstance(ProfilerInput, connectionProfile);
editorService.openEditor(profilerInput, { pinned: true }, ACTIVE_GROUP).then(() => TPromise.as(true));
}
});
let connectionProfile = TaskUtilities.getCurrentGlobalConnection(objectExplorerService, connectionService, editorService);
let profilerInput = instantiationService.createInstance(ProfilerInput, connectionProfile);
return editorService.openEditor(profilerInput, { pinned: true }, ACTIVE_GROUP).then(() => TPromise.as(true));
}
});

View File

@@ -91,10 +91,6 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
});
}
public get providerType(): string {
return this._connection ? this._connection.providerName : undefined;
}
public set viewTemplate(template: IProfilerViewTemplate) {
this._data.clear();
this._viewTemplate = template;

View File

@@ -228,6 +228,6 @@ export class ProfilerService implements IProfilerService {
}
public launchCreateSessionDialog(input?: ProfilerInput): Thenable<void> {
return this._commandService.executeCommand('profiler.openCreateSessionDialog', input.id, input.providerType, this.getSessionTemplates());
return this._commandService.executeCommand('profiler.openCreateSessionDialog', input.id, this.getSessionTemplates());
}
}

View File

@@ -339,7 +339,7 @@ let registryProperties = {
'sql.showConnectionInfoInTitle': {
'type': 'boolean',
'description': localize('showConnectionInfoInTitle', "Controls whether to show the connection info for a tab in the title."),
'default': true
'default': false
},
'mssql.intelliSense.enableIntelliSense': {
'type': 'boolean',

View File

@@ -32,6 +32,9 @@ export interface IQueryEditorService {
// Creates new edit data session
newEditDataEditor(schemaName: string, tableName: string, queryString: string): Promise<IConnectableInput>;
// Clears any QueryEditor data for the given URI held by this service
onQueryInputClosed(uri: string): void;
/**
* Handles updating of SQL files on a save as event. These need special consideration
* due to query results and other information being tied to the URI of the file

View File

@@ -116,11 +116,11 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
}
if (this._configurationService) {
this._toDispose.push(this._configurationService.onDidChangeConfiguration(e => {
this._configurationService.onDidChangeConfiguration(e => {
if (e.affectedKeys.includes('sql.showConnectionInfoInTitle')) {
this._onDidChangeLabel.fire();
}
}));
});
}
this.onDisconnect();
@@ -196,17 +196,17 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
// State update funtions
public runQuery(selection: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void {
this._queryModelService.runQuery(this.uri, selection, this, executePlanOptions);
this._queryModelService.runQuery(this.uri, selection, this.uri, this, executePlanOptions);
this.showQueryResultsEditor();
}
public runQueryStatement(selection: ISelectionData): void {
this._queryModelService.runQueryStatement(this.uri, selection, this);
this._queryModelService.runQueryStatement(this.uri, selection, this.uri, this);
this.showQueryResultsEditor();
}
public runQueryString(text: string): void {
this._queryModelService.runQueryString(this.uri, text, this);
this._queryModelService.runQueryString(this.uri, text, this.uri, this);
this.showQueryResultsEditor();
}
@@ -276,6 +276,7 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
// Clean up functions
public dispose(): void {
this._queryModelService.disposeQuery(this.uri);
this._sql.dispose();
this._results.dispose();
this._toDispose = dispose(this._toDispose);
@@ -284,7 +285,7 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
}
public close(): void {
this._queryModelService.disposeQuery(this.uri);
this._queryEditorService.onQueryInputClosed(this.uri);
this._connectionManagementService.disconnectEditor(this, true);
this._sql.close();

View File

@@ -215,7 +215,6 @@ export class QueryManagementService implements IQueryManagementService {
});
}
public disposeQuery(ownerUri: string): Thenable<void> {
this._queryRunners.delete(ownerUri);
return this._runAction(ownerUri, (runner) => {
return runner.disposeQuery(ownerUri);
});

View File

@@ -29,13 +29,6 @@ export class ResultsViewState {
constructor(@IConfigurationService private configurationService: IConfigurationService) {
}
dispose() {
this.gridPanelState.dispose();
this.messagePanelState.dispose();
this.chartState.dispose();
this.queryPlanState.dispose();
}
}
/**
@@ -57,11 +50,7 @@ export class QueryResultsInput extends EditorInput {
public readonly onRestoreViewStateEmitter = new Emitter<void>();
public readonly onSaveViewStateEmitter = new Emitter<void>();
private _state = new ResultsViewState(this.configurationService);
public get state(): ResultsViewState {
return this._state;
}
public readonly state = new ResultsViewState(this.configurationService);
constructor(private _uri: string,
@IConfigurationService private configurationService: IConfigurationService
@@ -71,12 +60,6 @@ export class QueryResultsInput extends EditorInput {
this._hasBootstrapped = false;
}
close() {
this.state.dispose();
this._state = undefined;
super.close();
}
getTypeId(): string {
return QueryResultsInput.ID;
}

View File

@@ -33,8 +33,4 @@ export class ChartTab implements IPanelTab {
public dispose() {
this.view.dispose();
}
public clear() {
this.view.clear();
}
}

View File

@@ -35,10 +35,6 @@ export class ChartState {
options: IInsightOptions = {
type: ChartType.Bar
};
dispose() {
}
}
declare class Proxy {
@@ -138,15 +134,6 @@ export class ChartView extends Disposable implements IPanelView {
this.buildOptions();
}
public clear() {
}
public dispose() {
dispose(this.optionDisposables);
super.dispose();
}
render(container: HTMLElement): void {
if (!this.container) {
this.container = $('div.chart-parent-container');

View File

@@ -7,7 +7,7 @@
import { attachTableStyler } from 'sql/common/theme/styler';
import QueryRunner from 'sql/parts/query/execution/queryRunner';
import { VirtualizedCollection, AsyncDataProvider } from 'sql/base/browser/ui/table/asyncDataView';
import { Table } from 'sql/base/browser/ui/table/table';
import { Table, ITableStyles, ITableMouseEvent } from 'sql/base/browser/ui/table/table';
import { ScrollableSplitView } from 'sql/base/browser/ui/scrollableSplitview/scrollableSplitview';
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
@@ -19,7 +19,6 @@ import { escape } from 'sql/base/common/strings';
import { hyperLinkFormatter, textFormatter } from 'sql/parts/grid/services/sharedServices';
import { CopyKeybind } from 'sql/base/browser/ui/table/plugins/copyKeybind.plugin';
import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin';
import { ITableStyles, ITableMouseEvent } from 'sql/base/browser/ui/table/interfaces';
import * as sqlops from 'sqlops';
import * as pretty from 'pretty-data';
@@ -62,10 +61,6 @@ export class GridPanelState {
public tableStates: GridTableState[] = [];
public scrollPosition: number;
public collapsed = false;
dispose() {
dispose(this.tableStates);
}
}
export interface IGridTableState {
@@ -73,14 +68,14 @@ export interface IGridTableState {
maximized: boolean;
}
export class GridTableState extends Disposable {
export class GridTableState {
private _maximized: boolean;
private _onMaximizedChange = this._register(new Emitter<boolean>());
private _onMaximizedChange = new Emitter<boolean>();
public onMaximizedChange: Event<boolean> = this._onMaximizedChange.event;
private _onCanBeMaximizedChange = this._register(new Emitter<boolean>());
private _onCanBeMaximizedChange = new Emitter<boolean>();
public onCanBeMaximizedChange: Event<boolean> = this._onCanBeMaximizedChange.event;
private _canBeMaximized: boolean;
@@ -91,7 +86,6 @@ export class GridTableState extends Disposable {
public activeCell: Slick.Cell;
constructor(public readonly resultId: number, public readonly batchId: number) {
super();
}
public get canBeMaximized(): boolean {
@@ -223,13 +217,13 @@ export class GridPanel extends ViewletPanel {
}
let table = this.instantiationService.createInstance(GridTable, this.runner, set);
table.state = tableState;
this.tableDisposable.push(tableState.onMaximizedChange(e => {
tableState.onMaximizedChange(e => {
if (e) {
this.maximizeTable(table.id);
} else {
this.minimizeTables();
}
}));
});
this.tableDisposable.push(attachTableStyler(table, this.themeService));
tables.push(table);
@@ -244,17 +238,11 @@ export class GridPanel extends ViewletPanel {
this.tables = this.tables.concat(tables);
}
public clear() {
this.reset();
}
private reset() {
for (let i = this.splitView.length - 1; i >= 0; i--) {
this.splitView.removeView(i);
}
dispose(this.tables);
dispose(this.tableDisposable);
this.tableDisposable = [];
this.tables = [];
this.maximizedGrid = undefined;
@@ -305,15 +293,6 @@ export class GridPanel extends ViewletPanel {
public get state(): GridPanelState {
return this._state;
}
public dispose() {
dispose(this.queryRunnerDisposables);
dispose(this.tableDisposable);
dispose(this.tables);
this.tableDisposable = undefined;
this.tables = undefined;
super.dispose();
}
}
class GridTable<T> extends Disposable implements IView {
@@ -465,9 +444,9 @@ class GridTable<T> extends Disposable implements IView {
private setupState() {
// change actionbar on maximize change
this._register(this.state.onMaximizedChange(this.rebuildActionBar, this));
this.state.onMaximizedChange(this.rebuildActionBar, this);
this._register(this.state.onCanBeMaximizedChange(this.rebuildActionBar, this));
this.state.onCanBeMaximizedChange(this.rebuildActionBar, this);
if (this.state.scrollPosition) {
// most of the time this won't do anything
@@ -677,8 +656,6 @@ class GridTable<T> extends Disposable implements IView {
public dispose() {
$(this.container).destroy();
this.table.dispose();
this.actionBar.dispose();
super.dispose();
}
}

View File

@@ -7,7 +7,6 @@
import 'vs/css!./media/messagePanel';
import { IMessagesActionContext, SelectAllMessagesAction, CopyMessagesAction } from './actions';
import QueryRunner from 'sql/parts/query/execution/queryRunner';
import { QueryInput } from 'sql/parts/query/common/queryInput';
import { IResultMessage, ISelectionData } from 'sqlops';
@@ -29,6 +28,8 @@ import { $ } from 'vs/base/browser/builder';
import { isArray, isUndefinedOrNull } from 'vs/base/common/types';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditor } from 'vs/editor/common/editorCommon';
import { QueryInput } from 'sql/parts/query/common/queryInput';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
export interface IResultMessageIntern extends IResultMessage {
@@ -70,10 +71,6 @@ export class MessagePanelState {
this.collapsed = !messagesOpenedSettings;
}
}
dispose() {
}
}
export class MessagePanel extends ViewletPanel {
@@ -105,7 +102,6 @@ export class MessagePanel extends ViewletPanel {
renderer: this.renderer,
controller: this.controller
}, { keyboardSupport: false, horizontalScrollMode: ScrollbarVisibility.Auto });
this.disposables.push(this.tree);
this.tree.onDidScroll(e => {
if (this.state) {
this.state.scrollPosition = this.tree.getScrollPosition();
@@ -121,7 +117,7 @@ export class MessagePanel extends ViewletPanel {
protected renderBody(container: HTMLElement): void {
this.container.style.width = '100%';
this.container.style.height = '100%';
this.disposables.push(attachListStyler(this.tree, this.themeService));
attachListStyler(this.tree, this.themeService);
container.appendChild(this.container);
this.tree.setInput(this.model);
}
@@ -197,19 +193,9 @@ export class MessagePanel extends ViewletPanel {
}
this.setExpanded(!this.state.collapsed);
}
public get state(): MessagePanelState {
return this._state;
}
public clear() {
this.reset();
}
public dispose() {
dispose(this.queryRunnerDisposables);
super.dispose();
}
}
class MessageDataSource implements IDataSource {

View File

@@ -478,11 +478,11 @@ export class QueryEditor extends BaseEditor {
this.setTaskbarContent();
this._toDispose.push(this._configurationService.onDidChangeConfiguration(e => {
this._configurationService.onDidChangeConfiguration(e => {
if (e.affectedKeys.includes('workbench.enablePreviewFeatures')) {
this.setTaskbarContent();
}
}));
});
}
private setTaskbarContent(): void {

View File

@@ -90,6 +90,7 @@ export class QueryResultsEditor extends BaseEditor {
public static ID: string = 'workbench.editor.queryResultsEditor';
public static AngularSelectorString: string = 'slickgrid-container.slickgridContainer';
protected _rawOptions: BareResultsGridInfo;
protected _input: QueryResultsInput;
private resultsView: QueryResultsView;
private styleSheet = DOM.createStyleSheet();
@@ -103,17 +104,17 @@ export class QueryResultsEditor extends BaseEditor {
) {
super(QueryResultsEditor.ID, telemetryService, themeService);
this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
this._register(this._configurationService.onDidChangeConfiguration(e => {
this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('resultsGrid')) {
this._rawOptions = BareResultsGridInfo.createFromRawSettings(this._configurationService.getValue('resultsGrid'), getZoomLevel());
this.applySettings();
}
}));
});
this.applySettings();
}
public get input(): QueryResultsInput {
return this._input as QueryResultsInput;
return this._input;
}
private applySettings() {
@@ -132,16 +133,10 @@ export class QueryResultsEditor extends BaseEditor {
this.styleSheet.remove();
parent.appendChild(this.styleSheet);
if (!this.resultsView) {
this.resultsView = this._register(new QueryResultsView(parent, this._instantiationService, this._queryModelService));
this.resultsView = new QueryResultsView(parent, this._instantiationService, this._queryModelService);
}
}
dispose() {
this.styleSheet.remove();
this.styleSheet = undefined;
super.dispose();
}
layout(dimension: DOM.Dimension): void {
this.resultsView.layout(dimension);
}
@@ -152,11 +147,6 @@ export class QueryResultsEditor extends BaseEditor {
return TPromise.wrap<void>(null);
}
clearInput() {
this.resultsView.clearInput();
super.clearInput();
}
public chart(dataId: { batchId: number, resultId: number }) {
this.resultsView.chartData(dataId);
}
@@ -164,4 +154,11 @@ export class QueryResultsEditor extends BaseEditor {
public showQueryPlan(xml: string) {
this.resultsView.showPlan(xml);
}
public dispose(): void {
super.dispose();
if (this.resultsView) {
this.resultsView.dispose();
}
}
}

View File

@@ -111,15 +111,6 @@ class ResultsView extends Disposable implements IPanelView {
}
}
dispose() {
super.dispose();
}
public clear() {
this.gridPanel.clear();
this.messagePanel.clear();
}
remove(): void {
this.container.remove();
}
@@ -160,10 +151,6 @@ class ResultsTab implements IPanelTab {
public dispose() {
dispose(this.view);
}
public clear() {
this.view.clear();
}
}
export class QueryResultsView extends Disposable {
@@ -234,11 +221,8 @@ export class QueryResultsView extends Disposable {
}
}
clearInput() {
this._input = undefined;
this.resultsTab.clear();
this.qpTab.clear();
this.chartTab.clear();
public dispose() {
this._panelView.dispose();
}
public get input(): QueryResultsInput {
@@ -280,8 +264,4 @@ export class QueryResultsView extends Disposable {
this._panelView.removeTab(this.qpTab.identifier);
}
}
public dispose() {
super.dispose();
}
}

View File

@@ -35,9 +35,9 @@ export interface IQueryModelService {
getConfig(): Promise<{ [key: string]: any }>;
getShortcuts(): Promise<any>;
getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Thenable<ResultSetSubset>;
runQuery(uri: string, selection: ISelectionData, queryInput: QueryInput, runOptions?: ExecutionPlanOptions): void;
runQueryStatement(uri: string, selection: ISelectionData, queryInput: QueryInput): void;
runQueryString(uri: string, selection: string, queryInput: QueryInput);
runQuery(uri: string, selection: ISelectionData, title: string, queryInput: QueryInput, runOptions?: ExecutionPlanOptions): void;
runQueryStatement(uri: string, selection: ISelectionData, title: string, queryInput: QueryInput): void;
runQueryString(uri: string, selection: string, title: string, queryInput: QueryInput);
cancelQuery(input: QueryRunner | string): void;
disposeQuery(uri: string): void;
isRunningQuery(uri: string): boolean;

View File

@@ -209,28 +209,32 @@ export class QueryModelService implements IQueryModelService {
/**
* Run a query for the given URI with the given text selection
*/
public runQuery(uri: string, selection: sqlops.ISelectionData, queryInput: QueryInput, runOptions?: sqlops.ExecutionPlanOptions): void {
this.doRunQuery(uri, selection, queryInput, false, runOptions);
public runQuery(uri: string, selection: sqlops.ISelectionData,
title: string, queryInput: QueryInput, runOptions?: sqlops.ExecutionPlanOptions): void {
this.doRunQuery(uri, selection, title, queryInput, false, runOptions);
}
/**
* Run the current SQL statement for the given URI
*/
public runQueryStatement(uri: string, selection: sqlops.ISelectionData, queryInput: QueryInput): void {
this.doRunQuery(uri, selection, queryInput, true);
public runQueryStatement(uri: string, selection: sqlops.ISelectionData,
title: string, queryInput: QueryInput): void {
this.doRunQuery(uri, selection, title, queryInput, true);
}
/**
* Run the current SQL statement for the given URI
*/
public runQueryString(uri: string, selection: string, queryInput: QueryInput): void {
this.doRunQuery(uri, selection, queryInput, true);
public runQueryString(uri: string, selection: string,
title: string, queryInput: QueryInput): void {
this.doRunQuery(uri, selection, title, queryInput, true);
}
/**
* Run Query implementation
*/
private doRunQuery(uri: string, selection: sqlops.ISelectionData | string, queryInput: QueryInput,
private doRunQuery(uri: string, selection: sqlops.ISelectionData | string,
title: string, queryInput: QueryInput,
runCurrentStatement: boolean, runOptions?: sqlops.ExecutionPlanOptions): void {
// Reuse existing query runner if it exists
let queryRunner: QueryRunner;
@@ -252,7 +256,7 @@ export class QueryModelService implements IQueryModelService {
} else {
// We do not have a query runner for this editor, so create a new one
// and map it to the results uri
info = this.initQueryRunner(uri);
info = this.initQueryRunner(uri, title);
queryRunner = info.queryRunner;
}
@@ -273,8 +277,8 @@ export class QueryModelService implements IQueryModelService {
}
}
private initQueryRunner(uri: string): QueryInfo {
let queryRunner = this._instantiationService.createInstance(QueryRunner, uri);
private initQueryRunner(uri: string, title: string): QueryInfo {
let queryRunner = this._instantiationService.createInstance(QueryRunner, uri, title);
let info = new QueryInfo();
queryRunner.addListener(QREvents.RESULT_SET, e => {
this._fireQueryEvent(uri, 'resultSet', e);
@@ -359,10 +363,6 @@ export class QueryModelService implements IQueryModelService {
if (queryRunner) {
queryRunner.disposeQuery();
}
// remove our info map
if (this._queryInfoMap.has(ownerUri)) {
this._queryInfoMap.delete(ownerUri);
}
}
// EDIT DATA METHODS /////////////////////////////////////////////////////
@@ -386,7 +386,7 @@ export class QueryModelService implements IQueryModelService {
// We do not have a query runner for this editor, so create a new one
// and map it to the results uri
queryRunner = this._instantiationService.createInstance(QueryRunner, ownerUri);
queryRunner = this._instantiationService.createInstance(QueryRunner, ownerUri, ownerUri);
queryRunner.addListener(QREvents.RESULT_SET, resultSet => {
this._fireQueryEvent(ownerUri, 'resultSet', resultSet);
});

View File

@@ -20,7 +20,7 @@ import * as nls from 'vs/nls';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import * as types from 'vs/base/common/types';
import { EventEmitter } from 'sql/base/common/eventEmitter';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IDisposable } from 'vs/base/common/lifecycle';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { Emitter, Event } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -62,7 +62,7 @@ export interface IGridMessage extends sqlops.IResultMessage {
* Query Runner class which handles running a query, reports the results to the content manager,
* and handles getting more rows from the service layer and disposing when the content is closed.
*/
export default class QueryRunner extends Disposable {
export default class QueryRunner {
// MEMBER VARIABLES ////////////////////////////////////////////////////
private _resultLineOffset: number;
private _totalElapsedMilliseconds: number = 0;
@@ -76,7 +76,7 @@ export default class QueryRunner extends Disposable {
private _planXml = new Deferred<string>();
public get planXml(): Thenable<string> { return this._planXml.promise; }
private _onMessage = this._register(new Emitter<sqlops.IResultMessage>());
private _onMessage = new Emitter<sqlops.IResultMessage>();
private _debouncedMessage = debounceEvent<sqlops.IResultMessage, sqlops.IResultMessage[]>(this._onMessage.event, (l, e) => {
// on first run
if (types.isUndefinedOrNull(l)) {
@@ -88,7 +88,7 @@ export default class QueryRunner extends Disposable {
private _echoedMessages = echo(this._debouncedMessage.event);
public readonly onMessage = this._echoedMessages.event;
private _onResultSet = this._register(new Emitter<sqlops.ResultSetSummary>());
private _onResultSet = new Emitter<sqlops.ResultSetSummary>();
private _debouncedResultSet = debounceEvent<sqlops.ResultSetSummary, sqlops.ResultSetSummary[]>(this._onResultSet.event, (l, e) => {
// on first run
if (types.isUndefinedOrNull(l)) {
@@ -100,16 +100,16 @@ export default class QueryRunner extends Disposable {
private _echoedResultSet = echo(this._debouncedResultSet.event);
public readonly onResultSet = this._echoedResultSet.event;
private _onQueryStart = this._register(new Emitter<void>());
private _onQueryStart = new Emitter<void>();
public readonly onQueryStart: Event<void> = this._onQueryStart.event;
private _onQueryEnd = this._register(new Emitter<string>());
private _onQueryEnd = new Emitter<string>();
public readonly onQueryEnd: Event<string> = this._onQueryEnd.event;
private _onBatchStart = this._register(new Emitter<sqlops.BatchSummary>());
private _onBatchStart = new Emitter<sqlops.BatchSummary>();
public readonly onBatchStart: Event<sqlops.BatchSummary> = this._onBatchStart.event;
private _onBatchEnd = this._register(new Emitter<sqlops.BatchSummary>());
private _onBatchEnd = new Emitter<sqlops.BatchSummary>();
public readonly onBatchEnd: Event<sqlops.BatchSummary> = this._onBatchEnd.event;
private _queryStartTime: Date;
@@ -124,14 +124,13 @@ export default class QueryRunner extends Disposable {
// CONSTRUCTOR /////////////////////////////////////////////////////////
constructor(
public uri: string,
public title: string,
@IQueryManagementService private _queryManagementService: IQueryManagementService,
@INotificationService private _notificationService: INotificationService,
@IWorkspaceConfigurationService private _workspaceConfigurationService: IWorkspaceConfigurationService,
@IClipboardService private _clipboardService: IClipboardService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super();
}
) { }
get isExecuting(): boolean {
return this._isExecuting;
@@ -505,16 +504,10 @@ export default class QueryRunner extends Disposable {
/**
* Disposes the Query from the service client
* @returns A promise that will be rejected if a problem occured
*/
public disposeQuery(): void {
this._queryManagementService.disposeQuery(this.uri).then(() => {
this.dispose();
});
}
public dispose() {
this._batchSets = undefined;
super.dispose();
this._queryManagementService.disposeQuery(this.uri);
}
get totalElapsedMilliseconds(): number {

View File

@@ -152,6 +152,12 @@ export class QueryEditorService implements IQueryEditorService {
});
}
/**
* Clears any QueryEditor data for the given URI held by this service
*/
public onQueryInputClosed(uri: string): void {
}
onSaveAsCompleted(oldResource: URI, newResource: URI): void {
let oldResourceString: string = oldResource.toString();

View File

@@ -15,9 +15,6 @@ import { dispose, Disposable } from 'vs/base/common/lifecycle';
export class QueryPlanState {
xml: string;
dispose() {
}
}
export class QueryPlanTab implements IPanelTab {
@@ -32,10 +29,6 @@ export class QueryPlanTab implements IPanelTab {
public dispose() {
dispose(this.view);
}
public clear() {
this.view.clear();
}
}
export class QueryPlanView implements IPanelView {
@@ -66,12 +59,6 @@ export class QueryPlanView implements IPanelView {
this.container.style.height = dimension.height + 'px';
}
public clear() {
if (this.qp) {
this.qp.xml = undefined;
}
}
public showPlan(xml: string) {
if (this.qp) {
this.qp.xml = xml;

View File

@@ -14,7 +14,7 @@ import { attachButtonStyler, attachModalDialogStyler } from 'sql/common/theme/st
import { Builder } from 'vs/base/browser/builder';
import Severity from 'vs/base/common/severity';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND } from 'vs/workbench/common/theme';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { Event, Emitter } from 'vs/base/common/event';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -76,7 +76,7 @@ export class ErrorMessageDialog extends Modal {
this._copyButton = this.addFooterButton(copyButtonLabel, () => this._clipboardService.writeText(this._messageDetails), 'left');
this._copyButton.icon = 'icon scriptToClipboard';
this._copyButton.element.title = copyButtonLabel;
this._register(attachButtonStyler(this._copyButton, this._themeService, { buttonBackground: SIDE_BAR_BACKGROUND, buttonHoverBackground: SIDE_BAR_BACKGROUND, buttonForeground: SIDE_BAR_FOREGROUND }));
this._register(attachButtonStyler(this._copyButton, this._themeService, { buttonBackground: SIDE_BAR_BACKGROUND, buttonHoverBackground: SIDE_BAR_BACKGROUND }));
}
private createStandardButton(label: string, onSelect: () => void): Button {

View File

@@ -141,8 +141,6 @@ suite('SQL QueryEditor Tests', () => {
connectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, memento.object, undefined);
connectionManagementService.callBase = true;
connectionManagementService.setup(x => x.isConnected(TypeMoq.It.isAny())).returns(() => false);
connectionManagementService.setup(x => x.disconnectEditor(TypeMoq.It.isAny())).returns(() => void 0);
connectionManagementService.setup(x => x.ensureDefaultLanguageFlavor(TypeMoq.It.isAnyString())).returns(() => void 0);
// Create a QueryModelService
queryModelService = new QueryModelService(instantiationService.object, notificationService.object);
@@ -330,9 +328,6 @@ suite('SQL QueryEditor Tests', () => {
queryConnectionService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, memento.object, undefined);
queryConnectionService.callBase = true;
queryConnectionService.setup(x => x.disconnectEditor(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => void 0);
queryConnectionService.setup(x => x.ensureDefaultLanguageFlavor(TypeMoq.It.isAnyString())).returns(() => void 0);
// Mock InstantiationService to give us the actions
queryActionInstantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
@@ -359,13 +354,12 @@ suite('SQL QueryEditor Tests', () => {
let fileInput = new UntitledEditorInput(URI.parse('testUri'), false, '', '', '', instantiationService.object, undefined, undefined, undefined);
queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose, undefined, undefined);
queryModelService.callBase = true;
queryModelService.setup(x => x.disposeQuery(TypeMoq.It.isAny())).returns(() => void 0);
queryInput = new QueryInput(
'',
fileInput,
undefined,
undefined,
connectionManagementService.object,
undefined,
queryModelService.object,
undefined,
undefined
@@ -401,7 +395,7 @@ suite('SQL QueryEditor Tests', () => {
test('Test that we attempt to dispose query when the queryInput is disposed', (done) => {
let queryResultsInput = new QueryResultsInput('testUri', configurationService.object);
queryInput['_results'] = queryResultsInput;
queryInput.close();
queryInput.dispose();
queryModelService.verify(x => x.disposeQuery(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
done();
});