mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-07 01:25:38 -05:00
This reverts commit 8925d44807.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { $ } from 'vs/base/browser/dom';
|
||||
import { escape } from 'sql/base/common/strings';
|
||||
|
||||
export class DBCellValue {
|
||||
@@ -40,24 +41,20 @@ export function hyperLinkFormatter(row: number, cell: any, value: any, columnDef
|
||||
*/
|
||||
export function textFormatter(row: number, cell: any, value: any, columnDef: any, dataContext: any): string {
|
||||
let cellClasses = 'grid-cell-value-container';
|
||||
let valueToDisplay = '';
|
||||
let titleValue = '';
|
||||
let valueToDisplay: string = '';
|
||||
|
||||
if (DBCellValue.isDBCellValue(value)) {
|
||||
valueToDisplay = 'NULL';
|
||||
if (!value.isNull) {
|
||||
valueToDisplay = value.displayValue.replace(/(\r\n|\n|\r)/g, ' ');
|
||||
valueToDisplay = escape(valueToDisplay.length > 250 ? valueToDisplay.slice(0, 250) + '...' : valueToDisplay);
|
||||
titleValue = value.displayValue;
|
||||
valueToDisplay = escape(value.displayValue.replace(/(\r\n|\n|\r)/g, ' '));
|
||||
} else {
|
||||
cellClasses += ' missing-value';
|
||||
}
|
||||
} else if (typeof value === 'string') {
|
||||
valueToDisplay = escape(value.length > 250 ? value.slice(0, 250) + '...' : value);
|
||||
titleValue = value;
|
||||
valueToDisplay = escape(value);
|
||||
}
|
||||
|
||||
return `<span title="${titleValue}" class="${cellClasses}">${valueToDisplay}</span>`;
|
||||
return `<span title="${valueToDisplay}" class="${cellClasses}">${valueToDisplay}</span>`;
|
||||
}
|
||||
|
||||
/** The following code is a rewrite over the both formatter function using dom builder
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface IQueryManagementService {
|
||||
runQueryStatement(ownerUri: string, line: number, column: number): Thenable<void>;
|
||||
runQueryString(ownerUri: string, queryString: string): Thenable<void>;
|
||||
runQueryAndReturn(ownerUri: string, queryString: string): Thenable<sqlops.SimpleExecuteResult>;
|
||||
parseSyntax(ownerUri: string, query: string): Thenable<sqlops.SyntaxParseResult>;
|
||||
parseSyntax(ownerUri:string, query: string): Thenable<sqlops.SyntaxParseResult>;
|
||||
getQueryRows(rowData: sqlops.QueryExecuteSubsetParams): Thenable<sqlops.QueryExecuteSubsetResult>;
|
||||
disposeQuery(ownerUri: string): Thenable<void>;
|
||||
saveResults(requestParams: sqlops.SaveResultsRequestParams): Thenable<sqlops.SaveResultRequestResult>;
|
||||
@@ -38,8 +38,7 @@ export interface IQueryManagementService {
|
||||
onQueryComplete(result: sqlops.QueryExecuteCompleteNotificationResult): void;
|
||||
onBatchStart(batchInfo: sqlops.QueryExecuteBatchNotificationParams): void;
|
||||
onBatchComplete(batchInfo: sqlops.QueryExecuteBatchNotificationParams): void;
|
||||
onResultSetAvailable(resultSetInfo: sqlops.QueryExecuteResultSetNotificationParams): void;
|
||||
onResultSetUpdated(resultSetInfo: sqlops.QueryExecuteResultSetNotificationParams): void;
|
||||
onResultSetComplete(resultSetInfo: sqlops.QueryExecuteResultSetCompleteNotificationParams): void;
|
||||
onMessage(message: sqlops.QueryExecuteMessageParams): void;
|
||||
|
||||
// Edit Data Callbacks
|
||||
@@ -66,7 +65,7 @@ export interface IQueryRequestHandler {
|
||||
runQueryStatement(ownerUri: string, line: number, column: number): Thenable<void>;
|
||||
runQueryString(ownerUri: string, queryString: string): Thenable<void>;
|
||||
runQueryAndReturn(ownerUri: string, queryString: string): Thenable<sqlops.SimpleExecuteResult>;
|
||||
parseSyntax(ownerUri: string, query: string): Thenable<sqlops.SyntaxParseResult>;
|
||||
parseSyntax(ownerUri:string, query: string): Thenable<sqlops.SyntaxParseResult>;
|
||||
getQueryRows(rowData: sqlops.QueryExecuteSubsetParams): Thenable<sqlops.QueryExecuteSubsetResult>;
|
||||
disposeQuery(ownerUri: string): Thenable<void>;
|
||||
saveResults(requestParams: sqlops.SaveResultsRequestParams): Thenable<sqlops.SaveResultRequestResult>;
|
||||
@@ -245,15 +244,9 @@ export class QueryManagementService implements IQueryManagementService {
|
||||
});
|
||||
}
|
||||
|
||||
public onResultSetAvailable(resultSetInfo: sqlops.QueryExecuteResultSetNotificationParams): void {
|
||||
public onResultSetComplete(resultSetInfo: sqlops.QueryExecuteResultSetCompleteNotificationParams): void {
|
||||
this._notify(resultSetInfo.ownerUri, (runner: QueryRunner) => {
|
||||
runner.handleResultSetAvailable(resultSetInfo);
|
||||
});
|
||||
}
|
||||
|
||||
public onResultSetUpdated(resultSetInfo: sqlops.QueryExecuteResultSetNotificationParams): void {
|
||||
this._notify(resultSetInfo.ownerUri, (runner: QueryRunner) => {
|
||||
runner.handleResultSetUpdated(resultSetInfo);
|
||||
runner.handleResultSetComplete(resultSetInfo);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as pretty from 'pretty-data';
|
||||
|
||||
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';
|
||||
@@ -14,7 +12,7 @@ import { ScrollableSplitView } from 'sql/base/browser/ui/scrollableSplitview/scr
|
||||
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
|
||||
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
|
||||
import { SaveFormat } from 'sql/parts/grid/common/interfaces';
|
||||
import { IGridActionContext, SaveResultAction, CopyResultAction, SelectAllGridAction, MaximizeTableAction, RestoreTableAction, ChartDataAction } from 'sql/parts/query/editor/actions';
|
||||
import { IGridActionContext, SaveResultAction, CopyResultAction, SelectAllGridAction, MaximizeTableAction, RestoreTableAction, ChartDataAction, ShowQueryPlanAction } from 'sql/parts/query/editor/actions';
|
||||
import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin';
|
||||
import { RowNumberColumn } from 'sql/base/browser/ui/table/plugins/rowNumberColumn.plugin';
|
||||
import { escape } from 'sql/base/common/strings';
|
||||
@@ -22,9 +20,9 @@ import { hyperLinkFormatter, textFormatter } from 'sql/parts/grid/services/share
|
||||
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 { warn } from 'sql/base/common/log';
|
||||
|
||||
import * as sqlops from 'sqlops';
|
||||
import * as pretty from 'pretty-data';
|
||||
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
@@ -40,7 +38,7 @@ import { $ } from 'vs/base/browser/builder';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Separator, ActionBar, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { isInDOM } from 'vs/base/browser/dom';
|
||||
import { Dimension, getContentWidth, isInDOM } from 'vs/base/browser/dom';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
@@ -177,8 +175,7 @@ export class GridPanel extends ViewletPanel {
|
||||
this.reset();
|
||||
this.queryRunnerDisposables = [];
|
||||
this.runner = runner;
|
||||
this.queryRunnerDisposables.push(this.runner.onResultSet(this.onResultSet, this));
|
||||
this.queryRunnerDisposables.push(this.runner.onResultSetUpdate(this.updateResultSet, this));
|
||||
this.queryRunnerDisposables.push(this.runner.onResultSet(e => this.onResultSet(e)));
|
||||
this.queryRunnerDisposables.push(this.runner.onQueryStart(() => {
|
||||
if (this.state) {
|
||||
this.state.tableStates = [];
|
||||
@@ -203,33 +200,6 @@ export class GridPanel extends ViewletPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private updateResultSet(resultSet: sqlops.ResultSetSummary | sqlops.ResultSetSummary[]) {
|
||||
|
||||
let resultsToUpdate: sqlops.ResultSetSummary[];
|
||||
if (!Array.isArray(resultSet)) {
|
||||
resultsToUpdate = [resultSet];
|
||||
} else {
|
||||
resultsToUpdate = resultSet;
|
||||
}
|
||||
|
||||
for (let set of resultsToUpdate) {
|
||||
let table = this.tables.find(t => t.resultSet.batchId === set.batchId && t.resultSet.id === set.id);
|
||||
if (table) {
|
||||
table.updateResult(set);
|
||||
} else {
|
||||
warn('Got result set update request for non-existant table');
|
||||
}
|
||||
}
|
||||
|
||||
this.maximumBodySize = this.tables.reduce((p, c) => {
|
||||
return p + c.maximumSize;
|
||||
}, 0);
|
||||
|
||||
if (this.state && this.state.scrollPosition) {
|
||||
this.splitView.setScrollPosition(this.state.scrollPosition);
|
||||
}
|
||||
}
|
||||
|
||||
private addResultSet(resultSet: sqlops.ResultSetSummary | sqlops.ResultSetSummary[]) {
|
||||
let resultsToAdd: sqlops.ResultSetSummary[];
|
||||
if (!Array.isArray(resultSet)) {
|
||||
@@ -353,12 +323,9 @@ class GridTable<T> extends Disposable implements IView {
|
||||
private selectionModel = new CellSelectionModel();
|
||||
private styles: ITableStyles;
|
||||
private currentHeight: number;
|
||||
private dataProvider: AsyncDataProvider<T>;
|
||||
|
||||
private columns: Slick.Column<T>[];
|
||||
|
||||
private rowNumberColumn: RowNumberColumn<T>;
|
||||
|
||||
private _onDidChange = new Emitter<number>();
|
||||
public readonly onDidChange: Event<number> = this._onDidChange.event;
|
||||
|
||||
@@ -368,20 +335,13 @@ class GridTable<T> extends Disposable implements IView {
|
||||
private _state: GridTableState;
|
||||
|
||||
private scrolled = false;
|
||||
private visible = false;
|
||||
|
||||
public get resultSet(): sqlops.ResultSetSummary {
|
||||
return this._resultSet;
|
||||
}
|
||||
|
||||
// this handles if the row count is small, like 4-5 rows
|
||||
private get maxSize(): number {
|
||||
return ((this.resultSet.rowCount) * ROW_HEIGHT) + HEADER_HEIGHT + ESTIMATED_SCROLL_BAR_HEIGHT;
|
||||
}
|
||||
private readonly maxSize = ((this.resultSet.rowCount) * ROW_HEIGHT) + HEADER_HEIGHT + ESTIMATED_SCROLL_BAR_HEIGHT;
|
||||
|
||||
constructor(
|
||||
private runner: QueryRunner,
|
||||
private _resultSet: sqlops.ResultSetSummary,
|
||||
public readonly resultSet: sqlops.ResultSetSummary,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@@ -407,31 +367,7 @@ class GridTable<T> extends Disposable implements IView {
|
||||
});
|
||||
}
|
||||
|
||||
public onAdd() {
|
||||
this.visible = true;
|
||||
let collection = new VirtualizedCollection(
|
||||
50,
|
||||
index => this.placeholdGenerator(index),
|
||||
this.resultSet.rowCount,
|
||||
(offset, count) => this.loadData(offset, count)
|
||||
);
|
||||
collection.setCollectionChangedCallback((startIndex, count) => {
|
||||
this.renderGridDataRowsRange(startIndex, count);
|
||||
});
|
||||
this.dataProvider.dataRows = collection;
|
||||
this.table.updateRowCount();
|
||||
}
|
||||
|
||||
public onRemove() {
|
||||
this.visible = false;
|
||||
let collection = new VirtualizedCollection(
|
||||
50,
|
||||
index => this.placeholdGenerator(index),
|
||||
0,
|
||||
() => TPromise.as([])
|
||||
);
|
||||
this.dataProvider.dataRows = collection;
|
||||
this.table.updateRowCount();
|
||||
// when we are removed slickgrid acts badly so we need to account for that
|
||||
this.scrolled = false;
|
||||
}
|
||||
@@ -443,38 +379,34 @@ class GridTable<T> extends Disposable implements IView {
|
||||
private build(): void {
|
||||
let tableContainer = document.createElement('div');
|
||||
tableContainer.style.display = 'inline-block';
|
||||
tableContainer.style.width = `calc(100% - ${ACTIONBAR_WIDTH}px)`;
|
||||
|
||||
this.container.appendChild(tableContainer);
|
||||
|
||||
let collection = new VirtualizedCollection(
|
||||
50,
|
||||
index => this.placeholdGenerator(index),
|
||||
0,
|
||||
() => TPromise.as([])
|
||||
let collection = new VirtualizedCollection(50, this.resultSet.rowCount,
|
||||
(offset, count) => this.loadData(offset, count),
|
||||
index => this.placeholdGenerator(index)
|
||||
);
|
||||
collection.setCollectionChangedCallback((startIndex, count) => {
|
||||
collection.setCollectionChangedCallback((change, startIndex, count) => {
|
||||
this.renderGridDataRowsRange(startIndex, count);
|
||||
});
|
||||
this.rowNumberColumn = new RowNumberColumn({ numberOfRows: this.resultSet.rowCount });
|
||||
let numberColumn = new RowNumberColumn({ numberOfRows: this.resultSet.rowCount });
|
||||
let copyHandler = new CopyKeybind();
|
||||
copyHandler.onCopy(e => {
|
||||
new CopyResultAction(CopyResultAction.COPY_ID, CopyResultAction.COPY_LABEL, false).run(this.generateContext());
|
||||
});
|
||||
this.columns.unshift(this.rowNumberColumn.getColumnDefinition());
|
||||
this.columns.unshift(numberColumn.getColumnDefinition());
|
||||
let tableOptions: Slick.GridOptions<T> = {
|
||||
rowHeight: ROW_HEIGHT,
|
||||
showRowNumber: true,
|
||||
forceFitColumns: false,
|
||||
defaultColumnWidth: 120
|
||||
};
|
||||
this.dataProvider = new AsyncDataProvider(collection);
|
||||
this.table = this._register(new Table(tableContainer, { dataProvider: this.dataProvider, columns: this.columns }, tableOptions));
|
||||
this.table = this._register(new Table(tableContainer, { dataProvider: new AsyncDataProvider(collection), columns: this.columns }, tableOptions));
|
||||
this.table.setSelectionModel(this.selectionModel);
|
||||
this.table.registerPlugin(new MouseWheelSupport());
|
||||
this.table.registerPlugin(new AutoColumnSize());
|
||||
this.table.registerPlugin(copyHandler);
|
||||
this.table.registerPlugin(this.rowNumberColumn);
|
||||
this.table.registerPlugin(numberColumn);
|
||||
this.table.registerPlugin(new AdditionalKeyBindings());
|
||||
this._register(this.table.onContextMenu(this.contextMenu, this));
|
||||
this._register(this.table.onClick(this.onTableClick, this));
|
||||
@@ -575,7 +507,7 @@ class GridTable<T> extends Disposable implements IView {
|
||||
} catch (e) {
|
||||
// If Xml fails to parse, fall back on original Xml content
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
let jsonContent: string = undefined;
|
||||
try {
|
||||
jsonContent = JSON.parse(content);
|
||||
@@ -594,15 +526,6 @@ class GridTable<T> extends Disposable implements IView {
|
||||
}
|
||||
}
|
||||
|
||||
public updateResult(resultSet: sqlops.ResultSetSummary) {
|
||||
this._resultSet = resultSet;
|
||||
if (this.table && this.visible) {
|
||||
this.dataProvider.length = resultSet.rowCount;
|
||||
this.table.updateRowCount();
|
||||
}
|
||||
this.rowNumberColumn.updateRowCount(resultSet.rowCount);
|
||||
}
|
||||
|
||||
private generateContext(cell?: Slick.Cell): IGridActionContext {
|
||||
const selection = this.selectionModel.getSelectedRanges();
|
||||
return <IGridActionContext>{
|
||||
@@ -654,7 +577,12 @@ class GridTable<T> extends Disposable implements IView {
|
||||
} else {
|
||||
this.currentHeight = size;
|
||||
}
|
||||
this.table.layout(size, Orientation.VERTICAL);
|
||||
this.table.layout(
|
||||
new Dimension(
|
||||
getContentWidth(this.container) - ACTIONBAR_WIDTH,
|
||||
size
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public get minimumSize(): number {
|
||||
@@ -668,9 +596,6 @@ class GridTable<T> extends Disposable implements IView {
|
||||
|
||||
private loadData(offset: number, count: number): Thenable<T[]> {
|
||||
return this.runner.getQueryRows(offset, count, this.resultSet.batchId, this.resultSet.id).then(response => {
|
||||
if (!response.resultSubset) {
|
||||
return [];
|
||||
}
|
||||
return response.resultSubset.rows.map(r => {
|
||||
let dataWithSchema = {};
|
||||
// skip the first column since its a number column
|
||||
|
||||
@@ -100,18 +100,6 @@ export default class QueryRunner extends Disposable {
|
||||
private _echoedResultSet = echo(this._debouncedResultSet.event);
|
||||
public readonly onResultSet = this._echoedResultSet.event;
|
||||
|
||||
private _onResultSetUpdate = this._register(new Emitter<sqlops.ResultSetSummary>());
|
||||
private _debouncedResultSetUpdate = debounceEvent<sqlops.ResultSetSummary, sqlops.ResultSetSummary[]>(this._onResultSetUpdate.event, (l, e) => {
|
||||
// on first run
|
||||
if (types.isUndefinedOrNull(l)) {
|
||||
return [e];
|
||||
} else {
|
||||
return l.concat(e);
|
||||
}
|
||||
});
|
||||
private _echoedResultSetUpdate = echo(this._debouncedResultSetUpdate.event);
|
||||
public readonly onResultSetUpdate = this._echoedResultSetUpdate.event;
|
||||
|
||||
private _onQueryStart = this._register(new Emitter<void>());
|
||||
public readonly onQueryStart: Event<void> = this._onQueryStart.event;
|
||||
|
||||
@@ -348,7 +336,7 @@ export default class QueryRunner extends Disposable {
|
||||
/**
|
||||
* Handle a ResultSetComplete from the service layer
|
||||
*/
|
||||
public handleResultSetAvailable(result: sqlops.QueryExecuteResultSetNotificationParams): void {
|
||||
public handleResultSetComplete(result: sqlops.QueryExecuteResultSetCompleteNotificationParams): void {
|
||||
if (result && result.resultSetSummary) {
|
||||
let resultSet = result.resultSetSummary;
|
||||
let batchSet: sqlops.BatchSummary;
|
||||
@@ -386,27 +374,6 @@ export default class QueryRunner extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public handleResultSetUpdated(result: sqlops.QueryExecuteResultSetNotificationParams): void {
|
||||
if (result && result.resultSetSummary) {
|
||||
let resultSet = result.resultSetSummary;
|
||||
let batchSet: sqlops.BatchSummary;
|
||||
batchSet = this.batchSets[resultSet.batchId];
|
||||
// handle getting queryPlanxml if we need too
|
||||
if (this.isQueryPlan) {
|
||||
// check if this result has show plan, this needs work, it won't work for any other provider
|
||||
let hasShowPlan = !!result.resultSetSummary.columnInfo.find(e => e.columnName === 'Microsoft SQL Server 2005 XML Showplan');
|
||||
if (hasShowPlan) {
|
||||
this.getQueryRows(0, 1, result.resultSetSummary.batchId, result.resultSetSummary.id).then(e => this._planXml.resolve(e.resultSubset.rows[0][0].displayValue));
|
||||
}
|
||||
}
|
||||
if (batchSet) {
|
||||
// Store the result set in the batch and emit that a result set has completed
|
||||
batchSet.resultSetSummaries[resultSet.id] = resultSet;
|
||||
this._onResultSetUpdate.fire(resultSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a Mssage from the service layer
|
||||
*/
|
||||
|
||||
@@ -249,9 +249,9 @@ export class QueryEditorService implements IQueryEditorService {
|
||||
QueryEditorService.editorService.openEditor(newEditorInput, options, group).then((editor) => {
|
||||
resolve(QueryEditorService._onEditorOpened(editor, uri.toString(), undefined, options.pinned));
|
||||
},
|
||||
(error) => {
|
||||
reject(error);
|
||||
});
|
||||
(error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user