mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-24 01:25:37 -05:00
SQL Kernel Improvements/Removing Spark Code from Core/Attach to Changes (#3790)
* Scenarios work besides loading saved kernel * Fix compilation issue * Save and load functional * Fix loading kernesl issue when sql kernel is not enabled * Fix language mapping to not be hardcoded any longer * Remove unnecessary comment * PR Comments vol. 1 * Code cleanup, use ConnectionProfile instead of IConnectionProfile when accessing serverName * PR changes vol. 2 * One final comment for PR * Fix linting issue
This commit is contained in:
@@ -125,6 +125,16 @@ export class ExtHostNotebook implements ExtHostNotebookShape {
|
||||
return session.changeKernel(kernelInfo).then(kernel => this.saveKernel(kernel));
|
||||
}
|
||||
|
||||
$configureKernel(sessionId: number, kernelInfo: sqlops.nb.IKernelSpec): Thenable<void> {
|
||||
let session = this._getAdapter<sqlops.nb.ISession>(sessionId);
|
||||
return session.configureKernel(kernelInfo).then(() => null);
|
||||
}
|
||||
|
||||
$configureConnection(sessionId: number, connection: sqlops.IConnectionProfile): Thenable<void> {
|
||||
let session = this._getAdapter<sqlops.nb.ISession>(sessionId);
|
||||
return session.configureConnection(connection).then(() => null);
|
||||
}
|
||||
|
||||
$getKernelReadyStatus(kernelId: number): Thenable<sqlops.nb.IInfoReply> {
|
||||
let kernel = this._getAdapter<sqlops.nb.IKernel>(kernelId);
|
||||
return kernel.ready.then(success => kernel.info);
|
||||
|
||||
@@ -168,6 +168,7 @@ export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocume
|
||||
options.position = showOptions.viewColumn;
|
||||
options.providerId = showOptions.providerId;
|
||||
options.connectionId = showOptions.connectionId;
|
||||
options.defaultKernel = showOptions.defaultKernel;
|
||||
}
|
||||
let id = await this._proxy.$tryShowNotebookDocument(uri, options);
|
||||
let editor = this.getEditor(id);
|
||||
|
||||
@@ -288,11 +288,30 @@ class SessionWrapper implements sqlops.nb.ISession {
|
||||
return this.doChangeKernel(kernelInfo);
|
||||
}
|
||||
|
||||
configureKernel(kernelInfo: sqlops.nb.IKernelSpec): Thenable<void> {
|
||||
return this.doConfigureKernel(kernelInfo);
|
||||
}
|
||||
|
||||
configureConnection(connection: sqlops.IConnectionProfile): Thenable<void> {
|
||||
if (connection['capabilitiesService'] !== undefined) {
|
||||
connection['capabilitiesService'] = undefined;
|
||||
}
|
||||
return this.doConfigureConnection(connection);
|
||||
}
|
||||
|
||||
private async doChangeKernel(kernelInfo: sqlops.nb.IKernelSpec): Promise<sqlops.nb.IKernel> {
|
||||
let kernelDetails = await this._proxy.ext.$changeKernel(this.sessionDetails.sessionId, kernelInfo);
|
||||
this._kernel = new KernelWrapper(this._proxy, kernelDetails);
|
||||
return this._kernel;
|
||||
}
|
||||
|
||||
private async doConfigureKernel(kernelInfo: sqlops.nb.IKernelSpec): Promise<void> {
|
||||
await this._proxy.ext.$configureKernel(this.sessionDetails.sessionId, kernelInfo);
|
||||
}
|
||||
|
||||
private async doConfigureConnection(connection: sqlops.IConnectionProfile): Promise<void> {
|
||||
await this._proxy.ext.$configureConnection(this.sessionDetails.sessionId, connection);
|
||||
}
|
||||
}
|
||||
|
||||
class KernelWrapper implements sqlops.nb.IKernel {
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
import { NotebookInputModel, NotebookInput } from 'sql/parts/notebook/notebookInput';
|
||||
import { INotebookService, INotebookEditor, DEFAULT_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/common/notebookService';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { getProvidersForFileName } from 'sql/parts/notebook/notebookUtils';
|
||||
import { getProvidersForFileName, getStandardKernelsForProvider } from 'sql/parts/notebook/notebookUtils';
|
||||
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||
import { disposed } from 'vs/base/common/errors';
|
||||
import { ICellModel, NotebookContentChange } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
@@ -332,6 +332,11 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
|
||||
}
|
||||
model.providers = providers;
|
||||
model.providerId = providerId;
|
||||
model.defaultKernel = options && options.defaultKernel;
|
||||
model.providers.forEach(provider => {
|
||||
let standardKernels = getStandardKernelsForProvider(provider, this._notebookService);
|
||||
model.standardKernels = standardKernels;
|
||||
});
|
||||
let input = this._instantiationService.createInstance(NotebookInput, undefined, model);
|
||||
|
||||
let editor = await this._editorService.openEditor(input, editorOptions, viewColumnToEditorGroup(this._editorGroupService, options.position));
|
||||
|
||||
@@ -773,6 +773,8 @@ export interface ExtHostNotebookShape {
|
||||
|
||||
// Session APIs
|
||||
$changeKernel(sessionId: number, kernelInfo: sqlops.nb.IKernelSpec): Thenable<INotebookKernelDetails>;
|
||||
$configureKernel(sessionId: number, kernelInfo: sqlops.nb.IKernelSpec): Thenable<void>;
|
||||
$configureConnection(sessionId: number, connection: sqlops.IConnectionProfile): Thenable<void>;
|
||||
|
||||
// Kernel APIs
|
||||
$getKernelReadyStatus(kernelId: number): Thenable<sqlops.nb.IInfoReply>;
|
||||
@@ -829,6 +831,7 @@ export interface INotebookShowOptions {
|
||||
preview?: boolean;
|
||||
providerId?: string;
|
||||
connectionId?: string;
|
||||
defaultKernel?: sqlops.nb.IKernelSpec;
|
||||
}
|
||||
|
||||
export interface ExtHostNotebookDocumentsAndEditorsShape {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { ExtensionsRegistry, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as platform from 'vs/platform/registry/common/platform';
|
||||
import * as sqlops from 'sqlops';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
export const Extensions = {
|
||||
@@ -18,7 +19,7 @@ export const Extensions = {
|
||||
export interface NotebookProviderRegistration {
|
||||
provider: string;
|
||||
fileExtensions: string | string[];
|
||||
standardKernels: string | string[];
|
||||
standardKernels: sqlops.nb.IStandardKernel | sqlops.nb.IStandardKernel[];
|
||||
}
|
||||
|
||||
let notebookProviderType: IJSONSchema = {
|
||||
@@ -44,11 +45,38 @@ let notebookProviderType: IJSONSchema = {
|
||||
standardKernels: {
|
||||
description: localize('carbon.extension.contributes.notebook.standardKernels', 'What kernels should be standard with this notebook provider'),
|
||||
oneOf: [
|
||||
{ type: 'string' },
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
connectionProviderIds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
type: 'object',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
connectionProviderIds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -48,6 +48,8 @@ export interface INotebookService {
|
||||
|
||||
getProvidersForFileType(fileType: string): string[];
|
||||
|
||||
getStandardKernelsForProvider(provider: string): sqlops.nb.IStandardKernel[];
|
||||
|
||||
/**
|
||||
* Initializes and returns a Notebook manager that can handle all important calls to open, display, and
|
||||
* run cells in a notebook.
|
||||
|
||||
@@ -80,6 +80,7 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
private _onNotebookEditorRename = new Emitter<INotebookEditor>();
|
||||
private _editors = new Map<string, INotebookEditor>();
|
||||
private _fileToProviders = new Map<string, NotebookProviderRegistration[]>();
|
||||
private _providerToStandardKernels = new Map<string, nb.IStandardKernel[]>();
|
||||
private _registrationComplete = new Deferred<void>();
|
||||
private _isRegistrationComplete = false;
|
||||
|
||||
@@ -121,6 +122,9 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
this.addFileProvider(registration.fileExtensions, registration);
|
||||
}
|
||||
}
|
||||
if (registration.standardKernels) {
|
||||
this.addStandardKernels(registration);
|
||||
}
|
||||
}
|
||||
|
||||
registerProvider(providerId: string, instance: INotebookProvider): void {
|
||||
@@ -154,6 +158,26 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
this._fileToProviders.set(fileType.toUpperCase(), providers);
|
||||
}
|
||||
|
||||
// Standard kernels are contributed where a list of kernels are defined that can be shown
|
||||
// in the kernels dropdown list before a SessionManager has been started; this way,
|
||||
// every NotebookProvider doesn't need to have an active SessionManager in order to contribute
|
||||
// kernels to the dropdown
|
||||
private addStandardKernels(provider: NotebookProviderRegistration) {
|
||||
let providerUpperCase = provider.provider.toUpperCase();
|
||||
let standardKernels = this._providerToStandardKernels.get(providerUpperCase);
|
||||
if (!standardKernels) {
|
||||
standardKernels = [];
|
||||
}
|
||||
if (Array.isArray(provider.standardKernels)) {
|
||||
provider.standardKernels.forEach(kernel => {
|
||||
standardKernels.push(kernel);
|
||||
});
|
||||
} else {
|
||||
standardKernels.push(provider.standardKernels);
|
||||
}
|
||||
this._providerToStandardKernels.set(providerUpperCase, standardKernels);
|
||||
}
|
||||
|
||||
getSupportedFileExtensions(): string[] {
|
||||
return Array.from(this._fileToProviders.keys());
|
||||
}
|
||||
@@ -165,6 +189,10 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
return providers ? providers.map(provider => provider.provider) : undefined;
|
||||
}
|
||||
|
||||
getStandardKernelsForProvider(provider: string): nb.IStandardKernel[] {
|
||||
return this._providerToStandardKernels.get(provider.toUpperCase());
|
||||
}
|
||||
|
||||
public shutdown(): void {
|
||||
this._managersMap.forEach(manager => {
|
||||
manager.forEach(m => {
|
||||
@@ -337,7 +365,7 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
notebookRegistry.registerNotebookProvider({
|
||||
provider: sqlProvider.providerId,
|
||||
fileExtensions: DEFAULT_NOTEBOOK_FILETYPE,
|
||||
standardKernels: ['SQL']
|
||||
standardKernels: { name: 'SQL', connectionProviderIds: ['MSSQL'] }
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -444,5 +472,4 @@ export class SqlNotebookManager implements INotebookManager {
|
||||
public get sessionManager(): nb.SessionManager {
|
||||
return this._sessionManager;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
import { nb } from 'sqlops';
|
||||
import { localize } from 'vs/nls';
|
||||
import { FutureInternal } from 'sql/parts/notebook/models/modelInterfaces';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
|
||||
export const noKernel: string = localize('noKernel', 'No Kernel');
|
||||
const runNotebookDisabled = localize('runNotebookDisabled', 'Cannot run cells as no kernel has been configured');
|
||||
@@ -91,6 +92,15 @@ export class EmptySession implements nb.ISession {
|
||||
changeKernel(kernelInfo: nb.IKernelSpec): Thenable<nb.IKernel> {
|
||||
return Promise.resolve(this.kernel);
|
||||
}
|
||||
|
||||
// No kernel config necessary for empty session
|
||||
configureKernel(kernelInfo: nb.IKernelSpec): Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
configureConnection(connection: ConnectionProfile): Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
class EmptyKernel implements nb.IKernel {
|
||||
|
||||
@@ -14,8 +14,9 @@ import Severity from 'vs/base/common/severity';
|
||||
import * as Utils from 'sql/platform/connection/common/utils';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
|
||||
export const sqlKernel: string = localize('sqlKernel', 'SQL');
|
||||
export const sqlKernelError: string = localize("sqlKernelError", "SQL kernel error");
|
||||
@@ -63,6 +64,7 @@ export class SqlSessionManager implements nb.SessionManager {
|
||||
export class SqlSession implements nb.ISession {
|
||||
private _kernel: SqlKernel;
|
||||
private _defaultKernelLoaded = false;
|
||||
private _currentConnection: IConnectionProfile;
|
||||
|
||||
public set defaultKernelLoaded(value) {
|
||||
this._defaultKernelLoaded = value;
|
||||
@@ -107,12 +109,25 @@ export class SqlSession implements nb.ISession {
|
||||
changeKernel(kernelInfo: nb.IKernelSpec): Thenable<nb.IKernel> {
|
||||
return Promise.resolve(this.kernel);
|
||||
}
|
||||
|
||||
configureKernel(kernelInfo: nb.IKernelSpec): Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
configureConnection(connection: ConnectionProfile): Thenable<void> {
|
||||
if (this._kernel) {
|
||||
this._kernel.connection = connection;
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
class SqlKernel extends Disposable implements nb.IKernel {
|
||||
private _queryRunner: QueryRunner;
|
||||
private _columns: IDbColumn[];
|
||||
private _rows: DbCellValue[][];
|
||||
private _currentConnection: IConnectionProfile;
|
||||
static kernelId: number = 0;
|
||||
|
||||
constructor( @IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@@ -121,7 +136,7 @@ class SqlKernel extends Disposable implements nb.IKernel {
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return '-1';
|
||||
return (SqlKernel.kernelId++).toString();
|
||||
}
|
||||
|
||||
public get name(): string {
|
||||
@@ -159,6 +174,12 @@ class SqlKernel extends Disposable implements nb.IKernel {
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public set connection(conn: IConnectionProfile) {
|
||||
this._currentConnection = conn;
|
||||
this._queryRunner = undefined;
|
||||
}
|
||||
|
||||
getSpec(): Thenable<nb.IKernelSpec> {
|
||||
return Promise.resolve(sqlKernelSpec);
|
||||
}
|
||||
@@ -167,11 +188,10 @@ class SqlKernel extends Disposable implements nb.IKernel {
|
||||
if (this._queryRunner) {
|
||||
this._queryRunner.runQuery(content.code);
|
||||
} else {
|
||||
let connections = this._connectionManagementService.getActiveConnections();
|
||||
let connectionProfile = connections.find(connection => connection.providerName === mssqlProviderName);
|
||||
let connectionUri = Utils.generateUri(connectionProfile, 'notebook');
|
||||
let connectionUri = Utils.generateUri(this._currentConnection, 'notebook');
|
||||
this._queryRunner = this._instantiationService.createInstance(QueryRunner, connectionUri, undefined);
|
||||
this._connectionManagementService.connect(connectionProfile, connectionUri).then((result) => {
|
||||
this._connectionManagementService.connect(this._currentConnection, connectionUri).then((result) =>
|
||||
{
|
||||
this.addQueryEventListeners(this._queryRunner);
|
||||
this._queryRunner.runQuery(content.code);
|
||||
});
|
||||
@@ -186,7 +206,9 @@ class SqlKernel extends Disposable implements nb.IKernel {
|
||||
}
|
||||
|
||||
interrupt(): Thenable<void> {
|
||||
return Promise.resolve(undefined);
|
||||
// TODO: figure out what to do with the QueryCancelResult
|
||||
return this._queryRunner.cancelQuery().then((cancelResult) => {
|
||||
});
|
||||
}
|
||||
|
||||
private addQueryEventListeners(queryRunner: QueryRunner): void {
|
||||
@@ -234,7 +256,11 @@ export class SQLFuture extends Disposable implements FutureInternal {
|
||||
get inProgress(): boolean {
|
||||
return !this._queryRunner.hasCompleted;
|
||||
}
|
||||
|
||||
set inProgress(val: boolean) {
|
||||
if (this._queryRunner && !val) {
|
||||
this._queryRunner.cancelQuery();
|
||||
}
|
||||
}
|
||||
get msg(): nb.IMessage {
|
||||
return this._msg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user