SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View File

@@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import * as data from 'data';
const PROFILER_SERVICE_ID = 'profilerService';
export const IProfilerService = createDecorator<IProfilerService>(PROFILER_SERVICE_ID);
export type ProfilerSessionID = string;
export const PROFILER_SESSION_TEMPLATE_SETTINGS = 'profiler.sessionTemplates';
export const PROFILER_SETTINGS = 'profiler';
/**
* A front end provider for a profiler session
*/
export interface IProfilerSession {
/**
* Called by the service when more rows are available to render
*/
onMoreRows(rowCount: number, data: data.IProfilerTableRow);
}
/**
* A Profiler Service that handles session communication between the backends and frontends
*/
export interface IProfilerService {
_serviceBrand: any;
/**
* Registers a backend provider for profiler session. ex: mssql
*/
registerProvider(providerId: string, provider: data.IProfilerProvider): void;
/**
* Registers a session with the service that acts as the UI for a profiler session
* @returns An unique id that should be used to make subsequent calls to this service
*/
registerSession(uri: string, session: IProfilerSession): ProfilerSessionID;
/**
* Connects the session specified by the id
*/
connectSession(sessionId: ProfilerSessionID): Thenable<boolean>;
/**
* Disconnected the session specified by the id
*/
disconnectSession(sessionId: ProfilerSessionID): Thenable<boolean>;
/**
* Starts the session specified by the id
*/
startSession(sessionId: ProfilerSessionID): Thenable<boolean>;
/**
* Pauses the session specified by the id
*/
pauseSession(sessionId: ProfilerSessionID): Thenable<boolean>;
/**
* Stops the session specified by the id
*/
stopSession(sessionId: ProfilerSessionID): Thenable<boolean>;
/**
* The method called by the service provider for when more rows are available to render
*/
onMoreRows(params: data.IProfilerMoreRowsNotificationParams): void;
/**
* Gets a list of the session templates that are specified in the settings
* @param provider An optional string to limit the session template to a specific
* @returns An array of session templates that match the provider passed, if passed, and generic ones (no provider specified),
* otherwise returns all session templates
*/
getSessionTemplates(providerId?: string): Array<IProfilerSessionTemplate>;
/**
* Launches the dialog for editing the view columns of a profiler session template for the given input
* @param input input object that contains the necessary information which will be modified based on used input
*/
launchColumnEditor(input: ProfilerInput): Thenable<void>;
}
export interface IProfilerSettings {
sessionTemplates: Array<IProfilerSessionTemplate>;
}
export interface IEventTemplate {
name: string;
optionalColumns: Array<string>;
}
export interface IEventViewTemplate {
name: string;
columns: Array<string>;
}
export interface ISessionViewTemplate {
events: Array<IEventViewTemplate>;
}
export interface IProfilerSessionTemplate {
name: string;
events: Array<IEventTemplate>;
view: ISessionViewTemplate;
}

View File

@@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import {
ProfilerSessionID, IProfilerSession, IProfilerService, IProfilerSessionTemplate,
PROFILER_SETTINGS, IProfilerSettings
} from './interfaces';
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
import { ProfilerColumnEditorDialog } from 'sql/parts/profiler/dialog/profilerColumnEditorDialog';
import * as data from 'data';
import { TPromise } from 'vs/base/common/winjs.base';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
class TwoWayMap<T, K> {
private forwardMap: Map<T, K>;
private reverseMap: Map<K, T>;
constructor() {
this.forwardMap = new Map<T, K>();
this.reverseMap = new Map<K, T>();
}
get(input: T): K {
return this.forwardMap.get(input);
}
reverseGet(input: K): T {
return this.reverseMap.get(input);
}
set(input: T, input2: K): TwoWayMap<T, K> {
this.forwardMap.set(input, input2);
this.reverseMap.set(input2, input);
return this;
}
}
export class ProfilerService implements IProfilerService {
public _serviceBrand: any;
private _providers = new Map<string, data.IProfilerProvider>();
private _idMap = new TwoWayMap<ProfilerSessionID, string>();
private _sessionMap = new Map<ProfilerSessionID, IProfilerSession>();
private _dialog: ProfilerColumnEditorDialog;
constructor(
@IConnectionManagementService private _connectionService: IConnectionManagementService,
@IConfigurationService public _configurationService: IConfigurationService,
@IInstantiationService private _instantiationService: IInstantiationService
) { }
public registerProvider(providerId: string, provider: data.IProfilerProvider): void {
this._providers.set(providerId, provider);
}
public registerSession(uri: string, session: IProfilerSession): ProfilerSessionID {
this._sessionMap.set(uri, session);
this._idMap.set(uri, uri);
return uri;
}
public onMoreRows(params: data.IProfilerMoreRowsNotificationParams): void {
this._sessionMap.get(this._idMap.reverseGet(params.uri)).onMoreRows(params.rowCount, params.data);
}
public connectSession(id: ProfilerSessionID): Thenable<boolean> {
return this._runAction(id, provider => provider.connectSession(this._idMap.get(id)));
}
public disconnectSession(id: ProfilerSessionID): Thenable<boolean> {
return this._runAction(id, provider => provider.disconnectSession(this._idMap.get(id)));
}
public startSession(id: ProfilerSessionID): Thenable<boolean> {
return this._runAction(id, provider => provider.startSession(this._idMap.get(id)));
}
public pauseSession(id: ProfilerSessionID): Thenable<boolean> {
return this._runAction(id, provider => provider.pauseSession(this._idMap.get(id)));
}
public stopSession(id: ProfilerSessionID): Thenable<boolean> {
return this._runAction(id, provider => provider.stopSession(this._idMap.get(id)));
}
private _runAction<T>(id: ProfilerSessionID, action: (handler: data.IProfilerProvider) => Thenable<T>): Thenable<T> {
// let providerId = this._connectionService.getProviderIdFromUri(this._idMap.get(id));
let providerId = 'default';
if (!providerId) {
return TPromise.wrapError(new Error('Connection is required in order to interact with queries'));
}
let handler = this._providers.get(providerId);
if (handler) {
return action(handler);
} else {
return TPromise.wrapError(new Error('No Handler Registered'));
}
}
public getSessionTemplates(provider?: string): Array<IProfilerSessionTemplate> {
let config = <IProfilerSettings>this._configurationService.getConfiguration(PROFILER_SETTINGS);
if (provider) {
return config.sessionTemplates;
} else {
return config.sessionTemplates;
}
}
public launchColumnEditor(input?: ProfilerInput): Thenable<void> {
if (!this._dialog) {
this._dialog = this._instantiationService.createInstance(ProfilerColumnEditorDialog);
this._dialog.render();
}
this._dialog.open(input);
return TPromise.as(null);
}
}

View File

@@ -0,0 +1,100 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IProfilerService } from './interfaces';
import { TPromise } from 'vs/base/common/winjs.base';
import * as pfs from 'vs/base/node/pfs';
import * as path from 'path';
import * as data from 'data';
declare var __dirname;
const columns = [
'EventClass',
'TextData',
'ApplicationName',
'NTUserName',
'LoginName',
'CPU',
'Reads',
'Writes',
'Duration',
'ClientProcessID',
'SPID',
'StartTime',
'EndTime',
'BinaryData'
];
export class ProfilerTestBackend implements data.IProfilerProvider {
private index = 0;
private timeOutMap = new Map<string, number>();
private testData: Array<Array<string>> = new Array<Array<string>>();
constructor(
@IProfilerService private _profilerService: IProfilerService) { }
startSession(guid: string): Thenable<boolean> {
this.timeOutMap.set(guid, this.intervalFn(guid));
return TPromise.as(true);
}
private intervalFn(guid: string): number {
return setTimeout(() => {
let data = this.testData[this.index++];
let formattedData = {
EventClass: data[0].trim()
};
for (let i = 1; i < data.length; i++) {
formattedData[columns[i]] = data[i];
}
this._profilerService.onMoreRows({ uri: guid, rowCount: 1, data: formattedData });
if (this.index >= this.testData.length) {
this.index = 0;
}
this.timeOutMap.set(guid, this.intervalFn(guid));
}, Math.floor(Math.random() * 1000) + 300);
}
stopSession(guid: string): Thenable<boolean> {
clearTimeout(this.timeOutMap.get(guid));
this.index = 0;
return TPromise.as(true);
}
pauseSession(guid: string): Thenable<boolean> {
clearTimeout(this.timeOutMap.get(guid));
return TPromise.as(true);
}
connectSession(): Thenable<boolean> {
if (this.testData.length === 0) {
return new TPromise<boolean>((resolve, reject) => {
pfs.readFile(path.join(__dirname, 'testData.tsv')).then(result => {
let tabsep = result.toString().split('\t');
for (let i = 0; i < tabsep.length; i++) {
if (i % columns.length === 0) {
this.testData[i / columns.length] = new Array<string>();
}
this.testData[Math.floor(i / columns.length)][i % columns.length] = tabsep[i];
};
resolve(true);
});
});
} else {
return TPromise.as(true);
}
}
disconnectSession(guid: string): Thenable<boolean> {
clearTimeout(this.timeOutMap.get(guid));
this.index = 0;
return TPromise.as(true);
}
}

File diff suppressed because it is too large Load Diff