diff --git a/src/sql/base/common/eventEmitter.ts b/src/sql/base/common/eventEmitter.ts deleted file mode 100644 index ba5289a555..0000000000 --- a/src/sql/base/common/eventEmitter.ts +++ /dev/null @@ -1,301 +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 * as errors from 'vs/base/common/errors'; -import { IDisposable } from 'vs/base/common/lifecycle'; - -export class EmitterEvent { - - public readonly type: string; - public readonly data: any; - - constructor(eventType: string, data: any) { - this.type = eventType; - this.data = data; - } -} - -export interface ListenerCallback { - (value: any): void; -} - -export interface BulkListenerCallback { - (value: EmitterEvent[]): void; -} - -export interface IBaseEventEmitter { - addBulkListener(listener: BulkListenerCallback): IDisposable; -} - -export interface IEventEmitter extends IBaseEventEmitter, IDisposable { - addListener(eventType: string, listener: ListenerCallback): IDisposable; - addOneTimeListener(eventType: string, listener: ListenerCallback): IDisposable; - addEmitter(eventEmitter: IEventEmitter): IDisposable; -} - -export interface IListenersMap { - [key: string]: ListenerCallback[]; -} - -export class EventEmitter implements IEventEmitter { - - protected _listeners: IListenersMap; - protected _bulkListeners: ListenerCallback[]; - private _collectedEvents: EmitterEvent[]; - private _deferredCnt: number; - private _allowedEventTypes: { [eventType: string]: boolean; } | null; - - constructor(allowedEventTypes?: string[]) { - this._listeners = {}; - this._bulkListeners = []; - this._collectedEvents = []; - this._deferredCnt = 0; - if (allowedEventTypes) { - this._allowedEventTypes = {}; - for (let i = 0; i < allowedEventTypes.length; i++) { - this._allowedEventTypes[allowedEventTypes[i]] = true; - } - } else { - this._allowedEventTypes = null; - } - } - - public dispose(): void { - this._listeners = {}; - this._bulkListeners = []; - this._collectedEvents = []; - this._deferredCnt = 0; - this._allowedEventTypes = null; - } - - public addListener(eventType: string, listener: ListenerCallback): IDisposable { - if (eventType === '*') { - throw new Error('Use addBulkListener(listener) to register your listener!'); - } - - if (this._allowedEventTypes && !this._allowedEventTypes.hasOwnProperty(eventType)) { - throw new Error('This object will never emit this event type!'); - } - - if (this._listeners.hasOwnProperty(eventType)) { - this._listeners[eventType].push(listener); - } else { - this._listeners[eventType] = [listener]; - } - - let bound: this | null = this; - let _listener: ListenerCallback | null = listener; - return { - dispose: () => { - if (!bound) { - // Already called - return; - } - - bound._removeListener(eventType, _listener!); - - // Prevent leakers from holding on to the event emitter - bound = null; - _listener = null; - } - }; - } - - public addOneTimeListener(eventType: string, listener: ListenerCallback): IDisposable { - const disposable = this.addListener(eventType, value => { - disposable.dispose(); - listener(value); - }); - - return disposable; - } - - public addBulkListener(listener: BulkListenerCallback): IDisposable { - - this._bulkListeners.push(listener); - - return { - dispose: () => { - this._removeBulkListener(listener); - } - }; - } - - public addEmitter(eventEmitter: IBaseEventEmitter): IDisposable { - return eventEmitter.addBulkListener((events: EmitterEvent[]): void => { - if (this._deferredCnt === 0) { - this._emitEvents(events); - } else { - // Collect for later - this._collectedEvents.push.apply(this._collectedEvents, events); - } - }); - } - - private _removeListener(eventType: string, listener: ListenerCallback): void { - if (this._listeners.hasOwnProperty(eventType)) { - let listeners = this._listeners[eventType]; - for (let i = 0, len = listeners.length; i < len; i++) { - if (listeners[i] === listener) { - listeners.splice(i, 1); - break; - } - } - } - } - - private _removeBulkListener(listener: BulkListenerCallback): void { - for (let i = 0, len = this._bulkListeners.length; i < len; i++) { - if (this._bulkListeners[i] === listener) { - this._bulkListeners.splice(i, 1); - break; - } - } - } - - protected _emitToSpecificTypeListeners(eventType: string, data: any): void { - if (this._listeners.hasOwnProperty(eventType)) { - const listeners = this._listeners[eventType].slice(0); - for (let i = 0, len = listeners.length; i < len; i++) { - safeInvoke1Arg(listeners[i], data); - } - } - } - - protected _emitToBulkListeners(events: EmitterEvent[]): void { - const bulkListeners = this._bulkListeners.slice(0); - for (let i = 0, len = bulkListeners.length; i < len; i++) { - safeInvoke1Arg(bulkListeners[i], events); - } - } - - protected _emitEvents(events: EmitterEvent[]): void { - if (this._bulkListeners.length > 0) { - this._emitToBulkListeners(events); - } - for (let i = 0, len = events.length; i < len; i++) { - const e = events[i]; - - this._emitToSpecificTypeListeners(e.type, e.data); - } - } - - public emit(eventType: string, data: any = {}): void { - if (this._allowedEventTypes && !this._allowedEventTypes.hasOwnProperty(eventType)) { - throw new Error('Cannot emit this event type because it wasn\'t listed!'); - } - // Early return if no listeners would get this - if (!this._listeners.hasOwnProperty(eventType) && this._bulkListeners.length === 0) { - return; - } - const emitterEvent = new EmitterEvent(eventType, data); - - if (this._deferredCnt === 0) { - this._emitEvents([emitterEvent]); - } else { - // Collect for later - this._collectedEvents.push(emitterEvent); - } - } - - public beginDeferredEmit(): void { - this._deferredCnt = this._deferredCnt + 1; - } - - public endDeferredEmit(): void { - this._deferredCnt = this._deferredCnt - 1; - - if (this._deferredCnt === 0) { - this._emitCollected(); - } - } - - public deferredEmit(callback: () => T): T | undefined { - this.beginDeferredEmit(); - - let result: T | undefined = safeInvokeNoArg(callback); - - this.endDeferredEmit(); - - return result; - } - - private _emitCollected(): void { - if (this._collectedEvents.length === 0) { - return; - } - // Flush collected events - const events = this._collectedEvents; - this._collectedEvents = []; - this._emitEvents(events); - } -} - -class EmitQueueElement { - public target: Function; - public arg: any; - - constructor(target: Function, arg: any) { - this.target = target; - this.arg = arg; - } -} - -/** - * Same as EventEmitter, but guarantees events are delivered in order to each listener - */ -export class OrderGuaranteeEventEmitter extends EventEmitter { - - private _emitQueue: EmitQueueElement[]; - - constructor() { - super(); - this._emitQueue = []; - } - - protected _emitToSpecificTypeListeners(eventType: string, data: any): void { - if (this._listeners.hasOwnProperty(eventType)) { - let listeners = this._listeners[eventType]; - for (let i = 0, len = listeners.length; i < len; i++) { - this._emitQueue.push(new EmitQueueElement(listeners[i], data)); - } - } - } - - protected _emitToBulkListeners(events: EmitterEvent[]): void { - let bulkListeners = this._bulkListeners; - for (let i = 0, len = bulkListeners.length; i < len; i++) { - this._emitQueue.push(new EmitQueueElement(bulkListeners[i], events)); - } - } - - protected _emitEvents(events: EmitterEvent[]): void { - super._emitEvents(events); - - while (this._emitQueue.length > 0) { - let queueElement = this._emitQueue.shift(); - if (queueElement) { - safeInvoke1Arg(queueElement.target, queueElement.arg); - } - } - } -} - -function safeInvokeNoArg(func: Function): T | undefined { - try { - return func(); - } catch (e) { - errors.onUnexpectedError(e); - } - return undefined; -} - -function safeInvoke1Arg(func: Function, arg1: any): any { - try { - return func(arg1); - } catch (e) { - errors.onUnexpectedError(e); - } -} diff --git a/src/sql/platform/query/common/queryModelService.ts b/src/sql/platform/query/common/queryModelService.ts index b9d225f200..c6d81a506d 100644 --- a/src/sql/platform/query/common/queryModelService.ts +++ b/src/sql/platform/query/common/queryModelService.ts @@ -5,7 +5,7 @@ import * as GridContentEvents from 'sql/workbench/parts/grid/common/gridContentEvents'; import * as LocalizedConstants from 'sql/workbench/parts/query/common/localizedConstants'; -import QueryRunner, { EventType as QREvents } from 'sql/platform/query/common/queryRunner'; +import QueryRunner from 'sql/platform/query/common/queryRunner'; import { DataService } from 'sql/workbench/parts/grid/services/dataService'; import { IQueryModelService, IQueryEvent } from 'sql/platform/query/common/queryModel'; import { QueryInput } from 'sql/workbench/parts/query/common/queryInput'; @@ -277,10 +277,10 @@ export class QueryModelService implements IQueryModelService { private initQueryRunner(uri: string): QueryInfo { let queryRunner = this._instantiationService.createInstance(QueryRunner, uri); let info = new QueryInfo(); - queryRunner.addListener(QREvents.RESULT_SET, e => { + queryRunner.onResultSet(e => { this._fireQueryEvent(uri, 'resultSet', e); }); - queryRunner.addListener(QREvents.BATCH_START, b => { + queryRunner.onBatchStart(b => { let link = undefined; let messageText = LocalizedConstants.runQueryBatchStartMessage; if (b.selection) { @@ -304,10 +304,10 @@ export class QueryModelService implements IQueryModelService { this._fireQueryEvent(uri, 'message', message); info.selection.push(this._validateSelection(b.selection)); }); - queryRunner.addListener(QREvents.MESSAGE, m => { + queryRunner.onMessage(m => { this._fireQueryEvent(uri, 'message', m); }); - queryRunner.addListener(QREvents.COMPLETE, totalMilliseconds => { + queryRunner.onQueryEnd(totalMilliseconds => { this._onRunQueryComplete.fire(uri); // fire extensibility API event @@ -320,7 +320,7 @@ export class QueryModelService implements IQueryModelService { // fire UI event this._fireQueryEvent(uri, 'complete', totalMilliseconds); }); - queryRunner.addListener(QREvents.START, () => { + queryRunner.onQueryStart(() => { this._onRunQueryStart.fire(uri); // fire extensibility API event @@ -333,7 +333,7 @@ export class QueryModelService implements IQueryModelService { this._fireQueryEvent(uri, 'start'); }); - queryRunner.addListener(QREvents.QUERY_PLAN_AVAILABLE, (planInfo) => { + queryRunner.onQueryPlanAvailable(planInfo => { // fire extensibility API event let event: IQueryEvent = { type: 'executionPlan', @@ -416,13 +416,13 @@ export class QueryModelService implements IQueryModelService { // and map it to the results uri queryRunner = this._instantiationService.createInstance(QueryRunner, ownerUri); const resultSetEventType = 'resultSet'; - queryRunner.addListener(QREvents.RESULT_SET, resultSet => { + queryRunner.onResultSet(resultSet => { this._fireQueryEvent(ownerUri, resultSetEventType, resultSet); }); queryRunner.onResultSetUpdate(resultSetSummary => { this._fireQueryEvent(ownerUri, resultSetEventType, resultSetSummary); }); - queryRunner.addListener(QREvents.BATCH_START, batch => { + queryRunner.onBatchStart(batch => { let link = undefined; let messageText = LocalizedConstants.runQueryBatchStartMessage; if (batch.selection) { @@ -445,10 +445,10 @@ export class QueryModelService implements IQueryModelService { }; this._fireQueryEvent(ownerUri, 'message', message); }); - queryRunner.addListener(QREvents.MESSAGE, message => { + queryRunner.onMessage(message => { this._fireQueryEvent(ownerUri, 'message', message); }); - queryRunner.addListener(QREvents.COMPLETE, totalMilliseconds => { + queryRunner.onQueryEnd(totalMilliseconds => { this._onRunQueryComplete.fire(ownerUri); // fire extensibility API event let event: IQueryEvent = { @@ -460,7 +460,7 @@ export class QueryModelService implements IQueryModelService { // fire UI event this._fireQueryEvent(ownerUri, 'complete', totalMilliseconds); }); - queryRunner.addListener(QREvents.START, () => { + queryRunner.onQueryStart(() => { this._onRunQueryStart.fire(ownerUri); // fire extensibility API event let event: IQueryEvent = { @@ -472,7 +472,7 @@ export class QueryModelService implements IQueryModelService { // fire UI event this._fireQueryEvent(ownerUri, 'start'); }); - queryRunner.addListener(QREvents.EDIT_SESSION_READY, e => { + queryRunner.onEditSessionReady(e => { this._onEditSessionReady.fire(e); this._fireQueryEvent(e.ownerUri, 'editSessionReady'); }); diff --git a/src/sql/platform/query/common/queryRunner.ts b/src/sql/platform/query/common/queryRunner.ts index a7838bf7cd..ae0a869f69 100644 --- a/src/sql/platform/query/common/queryRunner.ts +++ b/src/sql/platform/query/common/queryRunner.ts @@ -11,19 +11,18 @@ import { IQueryManagementService } from 'sql/platform/query/common/queryManageme import * as Utils from 'sql/platform/connection/common/utils'; import { SaveFormat } from 'sql/workbench/parts/grid/common/interfaces'; import { Deferred } from 'sql/base/common/promise'; +import { IQueryPlanInfo } from 'sql/platform/query/common/queryModel'; +import { ResultSerializer } from 'sql/platform/node/resultSerializer'; import Severity from 'vs/base/common/severity'; 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 { Disposable } 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'; -import { ResultSerializer } from 'sql/platform/node/resultSerializer'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IQueryPlanInfo } from 'sql/platform/query/common/queryModel'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; import { URI } from 'vs/base/common/uri'; @@ -33,28 +32,6 @@ export interface IEditSessionReadyEvent { message: string; } -export const enum EventType { - START = 'start', - COMPLETE = 'complete', - MESSAGE = 'message', - BATCH_START = 'batchStart', - BATCH_COMPLETE = 'batchComplete', - RESULT_SET = 'resultSet', - EDIT_SESSION_READY = 'editSessionReady', - QUERY_PLAN_AVAILABLE = 'queryPlanAvailable' -} - -export interface IEventType { - start: void; - complete: string; - message: azdata.IResultMessage; - batchStart: azdata.BatchSummary; - batchComplete: azdata.BatchSummary; - resultSet: azdata.ResultSetSummary; - editSessionReady: IEditSessionReadyEvent; - queryPlanAvailable: IQueryPlanInfo; -} - export interface IGridMessage extends azdata.IResultMessage { selection: azdata.ISelectionData; } @@ -71,7 +48,6 @@ export default class QueryRunner extends Disposable { private _hasCompleted: boolean = false; private _batchSets: azdata.BatchSummary[] = []; private _messages: azdata.IResultMessage[] = []; - private _eventEmitter = new EventEmitter(); private registered = false; private _isQueryPlan: boolean; @@ -80,7 +56,7 @@ export default class QueryRunner extends Disposable { public get planXml(): Thenable { return this._planXml.promise; } private _onMessage = this._register(new Emitter()); - public readonly onMessage = this._onMessage.event; + public get onMessage(): Event { return this._onMessage.event; } // this is the only way typemoq can moq this... needs investigation @todo anthonydresser 5/2/2019 private _onResultSet = this._register(new Emitter()); public readonly onResultSet = this._onResultSet.event; @@ -92,7 +68,7 @@ export default class QueryRunner extends Disposable { public readonly onQueryStart: Event = this._onQueryStart.event; private _onQueryEnd = this._register(new Emitter()); - public readonly onQueryEnd: Event = this._onQueryEnd.event; + public get onQueryEnd(): Event { return this._onQueryEnd.event; } private _onBatchStart = this._register(new Emitter()); public readonly onBatchStart: Event = this._onBatchStart.event; @@ -100,6 +76,12 @@ export default class QueryRunner extends Disposable { private _onBatchEnd = this._register(new Emitter()); public readonly onBatchEnd: Event = this._onBatchEnd.event; + private _onEditSessionReady = this._register(new Emitter()); + public readonly onEditSessionReady = this._onEditSessionReady.event; + + private _onQueryPlanAvailable = this._register(new Emitter()); + public readonly onQueryPlanAvailable = this._onQueryPlanAvailable.event; + private _queryStartTime: Date; public get queryStartTime(): Date { return this._queryStartTime; @@ -146,10 +128,6 @@ export default class QueryRunner extends Disposable { // PUBLIC METHODS ====================================================== - public addListener(event: K, f: (e: IEventType[K]) => void): IDisposable { - return this._eventEmitter.addListener(event, f); - } - /** * Cancels the running query, if there is one */ @@ -229,7 +207,6 @@ export default class QueryRunner extends Disposable { // this isn't exact, but its the best we can do this._queryStartTime = new Date(); // The query has started, so lets fire up the result pane - this._eventEmitter.emit(EventType.START); if (!this.registered) { this.registered = true; this._queryManagementService.registerRunner(this, this.uri); @@ -270,8 +247,6 @@ export default class QueryRunner extends Disposable { }); let timeStamp = Utils.parseNumAsTimeString(this._totalElapsedMilliseconds); - - this._eventEmitter.emit(EventType.COMPLETE, timeStamp); // We're done with this query so shut down any waiting mechanisms let message = { @@ -311,7 +286,6 @@ export default class QueryRunner extends Disposable { isError: false }; this._messages.push(message); - this._eventEmitter.emit(EventType.BATCH_START, batch); this._onMessage.fire(message); this._onBatchStart.fire(batch); } @@ -331,7 +305,6 @@ export default class QueryRunner extends Disposable { this.sendBatchTimeMessage(batch.id, Utils.parseNumAsTimeString(executionTime)); } - this._eventEmitter.emit(EventType.BATCH_COMPLETE, batch); this._onBatchEnd.fire(batch); } @@ -376,7 +349,6 @@ export default class QueryRunner extends Disposable { if (batchSet && !batchSet.resultSetSummaries[resultSet.id]) { // Store the result set in the batch and emit that a result set has completed batchSet.resultSetSummaries[resultSet.id] = resultSet; - this._eventEmitter.emit(EventType.RESULT_SET, resultSet); this._onResultSet.fire(resultSet); } } @@ -398,7 +370,7 @@ export default class QueryRunner extends Disposable { this._planXml.resolve(e.resultSubset.rows[0][0].displayValue); // fire query plan available event if execution is completed if (result.resultSetSummary.complete) { - this._eventEmitter.emit(EventType.QUERY_PLAN_AVAILABLE, { + this._onQueryPlanAvailable.fire({ providerId: 'MSSQL', fileUri: result.ownerUri, planXml: planXmlString @@ -425,7 +397,6 @@ export default class QueryRunner extends Disposable { this._messages.push(message); // Send the message to the results pane - this._eventEmitter.emit(EventType.MESSAGE, message); this._onMessage.fire(message); } @@ -461,7 +432,7 @@ export default class QueryRunner extends Disposable { return this._queryManagementService.initializeEdit(ownerUri, schemaName, objectName, objectType, rowLimit, queryString).then(result => { // The query has started, so lets fire up the result pane - this._eventEmitter.emit(EventType.START); + this._onQueryStart.fire(); this._queryManagementService.registerRunner(this, ownerUri); }, error => { // Attempting to launch the query failed, show the error message @@ -511,7 +482,7 @@ export default class QueryRunner extends Disposable { } public handleEditSessionReady(ownerUri: string, success: boolean, message: string): void { - this._eventEmitter.emit(EventType.EDIT_SESSION_READY, { ownerUri, success, message }); + this._onEditSessionReady.fire({ ownerUri, success, message }); } public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable { diff --git a/src/sql/workbench/parts/editData/browser/editDataActions.ts b/src/sql/workbench/parts/editData/browser/editDataActions.ts index 5ebe3dda42..fe8301b719 100644 --- a/src/sql/workbench/parts/editData/browser/editDataActions.ts +++ b/src/sql/workbench/parts/editData/browser/editDataActions.ts @@ -7,7 +7,6 @@ import { Action, IActionItem, IActionRunner } from 'vs/base/common/actions'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IQueryModelService } from 'sql/platform/query/common/queryModel'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox'; -import { EventEmitter } from 'sql/base/common/eventEmitter'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { EditDataEditor } from 'sql/workbench/parts/editData/browser/editDataEditor'; import * as nls from 'vs/nls'; @@ -151,7 +150,7 @@ export class ChangeMaxRowsAction extends EditDataAction { * Action item that handles the dropdown (combobox) that lists the avaliable number of row selections * for an edit data session */ -export class ChangeMaxRowsActionItem extends EventEmitter implements IActionItem { +export class ChangeMaxRowsActionItem implements IActionItem { public actionRunner: IActionRunner; public defaultRowCount: number; @@ -167,7 +166,6 @@ export class ChangeMaxRowsActionItem extends EventEmitter implements IActionItem private _editor: EditDataEditor, @IContextViewService contextViewService: IContextViewService, @IThemeService private _themeService: IThemeService) { - super(); this._options = ['200', '1000', '10000']; this._currentOptionsIndex = 0; this.toDispose = []; diff --git a/src/sql/workbench/parts/profiler/browser/profilerEditor.ts b/src/sql/workbench/parts/profiler/browser/profilerEditor.ts index e6ccd1b625..c23f4f878f 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerEditor.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerEditor.ts @@ -433,7 +433,7 @@ export class ProfilerEditor extends BaseEditor { if (this._stateListener) { this._stateListener.dispose(); } - this._stateListener = input.state.addChangeListener(e => this._onStateChange(e)); + this._stateListener = input.state.onProfilerStateChange(e => this._onStateChange(e)); this._onStateChange({ isConnected: true, isRunning: true, diff --git a/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts b/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts index 25cf9f0768..1114151b63 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerTableEditor.ts @@ -123,7 +123,7 @@ export class ProfilerTableEditor extends BaseEditor implements IProfilerControll if (this._stateListener) { this._stateListener.dispose(); } - this._stateListener = input.state.addChangeListener(e => this._onStateChange(e)); + this._stateListener = input.state.onProfilerStateChange(e => this._onStateChange(e)); input.data.onRowCountChange(() => { this._profilerTable.updateRowCount(); this._updateRowCountStatus(); diff --git a/src/sql/workbench/parts/profiler/common/profilerState.ts b/src/sql/workbench/parts/profiler/common/profilerState.ts index a1ba1031de..590566b503 100644 --- a/src/sql/workbench/parts/profiler/common/profilerState.ts +++ b/src/sql/workbench/parts/profiler/common/profilerState.ts @@ -3,8 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { EventEmitter } from 'sql/base/common/eventEmitter'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { Emitter } from 'vs/base/common/event'; export interface IProfilerStateChangedEvent { isConnected?: boolean; @@ -25,7 +25,6 @@ export interface INewProfilerState { } export class ProfilerState implements IDisposable { - private static _CHANGED_EVENT = 'changed'; private _isConnected: boolean; private _isRunning: boolean; @@ -33,7 +32,6 @@ export class ProfilerState implements IDisposable { private _isStopped: boolean; private _autoscroll: boolean; private _isPanelCollapsed = true; - private _eventEmitter: EventEmitter; public get isConnected(): boolean { return this._isConnected; } public get isRunning(): boolean { return this._isRunning; } @@ -42,16 +40,10 @@ export class ProfilerState implements IDisposable { public get autoscroll(): boolean { return this._autoscroll; } public get isPanelCollapsed(): boolean { return this._isPanelCollapsed; } - constructor() { - this._eventEmitter = new EventEmitter(); - } + private readonly _onProfilerStateChange = new Emitter(); + public readonly onProfilerStateChange = this._onProfilerStateChange.event; public dispose(): void { - this._eventEmitter.dispose(); - } - - public addChangeListener(listener: (e: IProfilerStateChangedEvent) => void): IDisposable { - return this._eventEmitter.addListener(ProfilerState._CHANGED_EVENT, listener); } public change(newState: INewProfilerState): void { @@ -109,7 +101,7 @@ export class ProfilerState implements IDisposable { } if (somethingChanged) { - this._eventEmitter.emit(ProfilerState._CHANGED_EVENT, changeEvent); + this._onProfilerStateChange.fire(changeEvent); } } } diff --git a/src/sql/workbench/parts/query/browser/queryActions.ts b/src/sql/workbench/parts/query/browser/queryActions.ts index 953ddd4f73..5267252710 100644 --- a/src/sql/workbench/parts/query/browser/queryActions.ts +++ b/src/sql/workbench/parts/query/browser/queryActions.ts @@ -26,7 +26,6 @@ import { QueryEditor } from 'sql/workbench/parts/query/browser/queryEditor'; import { IQueryModelService } from 'sql/platform/query/common/queryModel'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox'; import { attachEditableDropdownStyler, attachSelectBoxStyler } from 'sql/platform/theme/common/styler'; -import { EventEmitter } from 'sql/base/common/eventEmitter'; import { Dropdown } from 'sql/base/parts/editableDropdown/browser/dropdown'; /** @@ -428,7 +427,7 @@ export class ListDatabasesAction extends QueryTaskbarAction { * Action item that handles the dropdown (combobox) that lists the available databases. * Based off StartDebugActionItem. */ -export class ListDatabasesActionItem extends EventEmitter implements IActionItem { +export class ListDatabasesActionItem implements IActionItem { public static ID = 'listDatabaseQueryActionItem'; public actionRunner: IActionRunner; @@ -450,7 +449,6 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem @IContextViewService contextViewProvider: IContextViewService, @IConfigurationService private readonly _configurationService: IConfigurationService ) { - super(); this._toDispose = []; this._databaseListDropdown = $('.databaseListDropdown'); this._isInAccessibilityMode = this._configurationService.getValue('editor.accessibilitySupport') === 'on'; diff --git a/src/sql/workbench/services/insights/node/insightsDialogController.ts b/src/sql/workbench/services/insights/node/insightsDialogController.ts index 4c9ee8ce9b..b4eed15899 100644 --- a/src/sql/workbench/services/insights/node/insightsDialogController.ts +++ b/src/sql/workbench/services/insights/node/insightsDialogController.ts @@ -6,7 +6,7 @@ import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IInsightsConfigDetails } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces'; -import QueryRunner, { EventType as QREvents } from 'sql/platform/query/common/queryRunner'; +import QueryRunner from 'sql/platform/query/common/queryRunner'; import * as Utils from 'sql/platform/connection/common/utils'; import { IInsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogService'; import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; @@ -141,12 +141,12 @@ export class InsightsDialogController { } private addQueryEventListeners(queryRunner: QueryRunner): void { - queryRunner.addListener(QREvents.COMPLETE, () => { + queryRunner.onQueryEnd(() => { this.queryComplete().catch(error => { this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), error); }); }); - queryRunner.addListener(QREvents.MESSAGE, message => { + queryRunner.onMessage(message => { if (message.isError) { this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), message.message); } diff --git a/src/sqltest/parts/insights/insightsDialogModel.test.ts b/src/sql/workbench/services/insights/test/common/insightsDialogModel.test.ts similarity index 100% rename from src/sqltest/parts/insights/insightsDialogModel.test.ts rename to src/sql/workbench/services/insights/test/common/insightsDialogModel.test.ts diff --git a/src/sqltest/parts/insights/insightsUtils.test.ts b/src/sql/workbench/services/insights/test/common/insightsUtils.test.ts similarity index 100% rename from src/sqltest/parts/insights/insightsUtils.test.ts rename to src/sql/workbench/services/insights/test/common/insightsUtils.test.ts diff --git a/src/sqltest/parts/insights/insightsDialogController.test.ts b/src/sql/workbench/services/insights/test/node/insightsDialogController.test.ts similarity index 83% rename from src/sqltest/parts/insights/insightsDialogController.test.ts rename to src/sql/workbench/services/insights/test/node/insightsDialogController.test.ts index 763070a088..9e89b98906 100644 --- a/src/sqltest/parts/insights/insightsDialogController.test.ts +++ b/src/sql/workbench/services/insights/test/node/insightsDialogController.test.ts @@ -5,18 +5,18 @@ import { InsightsDialogController } from 'sql/workbench/services/insights/node/insightsDialogController'; import { InsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogModel'; -import QueryRunner, { EventType } from 'sql/platform/query/common/queryRunner'; +import QueryRunner from 'sql/platform/query/common/queryRunner'; import { ConnectionManagementService } from 'sql/platform/connection/common/connectionManagementService'; import { IInsightsConfigDetails } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; -import { IDbColumn, BatchSummary, QueryExecuteSubsetResult, ResultSetSubset } from 'azdata'; -import { EventEmitter } from 'sql/base/common/eventEmitter'; +import * as azdata from 'azdata'; import { equal } from 'assert'; import { Mock, MockBehavior, It } from 'typemoq'; import { TestStorageService } from 'vs/workbench/test/workbenchTestServices'; +import { Emitter } from 'vs/base/common/event'; const testData: string[][] = [ ['1', '2', '3', '4'], @@ -98,16 +98,17 @@ interface IPrimedQueryRunner { * Returns a mock of query runner than will recreate what a query runner does to return data */ function getPrimedQueryRunner(data: string[][], columns: string[]): IPrimedQueryRunner { - let emitter = new EventEmitter(); - let querymock = Mock.ofType(QueryRunner, MockBehavior.Strict); - querymock.setup(x => x.addListener(It.isAny(), It.isAny())).returns((event, func) => emitter.addListener(event, func)); + const emitter = new Emitter(); + const querymock = Mock.ofType(QueryRunner, MockBehavior.Strict); + querymock.setup(x => x.onQueryEnd).returns(x => emitter.event); + querymock.setup(x => x.onMessage).returns(x => new Emitter().event); querymock.setup(x => x.batchSets).returns(x => { - return >[ + return >[ { id: 0, resultSetSummaries: [ { - columnInfo: >columns.map(c => { return { columnName: c }; }), + columnInfo: >columns.map(c => { return { columnName: c }; }), id: 0, rowCount: data.length } @@ -117,8 +118,8 @@ function getPrimedQueryRunner(data: string[][], columns: string[]): IPrimedQuery }); querymock.setup(x => x.getQueryRows(It.isAnyNumber(), It.isAnyNumber(), It.isAnyNumber(), It.isAnyNumber())) - .returns(x => Promise.resolve({ - resultSubset: { + .returns(x => Promise.resolve({ + resultSubset: { rowCount: data.length, rows: data.map(r => r.map(c => { return { displayValue: c }; })) } @@ -126,8 +127,8 @@ function getPrimedQueryRunner(data: string[][], columns: string[]): IPrimedQuery querymock.setup(x => x.runQuery(It.isAnyString())).returns(x => Promise.resolve()); - let complete = () => { - emitter.emit(EventType.COMPLETE); + const complete = () => { + emitter.fire('time'); }; return { diff --git a/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts b/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts index 57687e3adc..0c62f09118 100644 --- a/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts +++ b/src/sql/workbench/services/notebook/sql/sqlSessionManager.ts @@ -8,7 +8,7 @@ import { nb, QueryExecuteSubsetResult, IDbColumn, BatchSummary, IResultMessage, import { localize } from 'vs/nls'; import * as strings from 'vs/base/common/strings'; import { FutureInternal, ILanguageMagic, notebookConstants } from 'sql/workbench/parts/notebook/models/modelInterfaces'; -import QueryRunner, { EventType } from 'sql/platform/query/common/queryRunner'; +import QueryRunner from 'sql/platform/query/common/queryRunner'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import Severity from 'vs/base/common/severity'; @@ -304,18 +304,18 @@ class SqlKernel extends Disposable implements nb.IKernel { } private addQueryEventListeners(queryRunner: QueryRunner): void { - this._register(queryRunner.addListener(EventType.COMPLETE, () => { + this._register(queryRunner.onQueryEnd(() => { this.queryComplete().catch(error => { this._errorMessageService.showDialog(Severity.Error, sqlKernelError, error); }); })); - this._register(queryRunner.addListener(EventType.MESSAGE, message => { + this._register(queryRunner.onMessage(message => { // TODO handle showing a messages output (should be updated with all messages, only changing 1 output in total) if (this._future) { this._future.handleMessage(message); } })); - this._register(queryRunner.addListener(EventType.BATCH_COMPLETE, batch => { + this._register(queryRunner.onBatchEnd(batch => { if (this._future) { this._future.handleBatchEnd(batch); }