mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-26 09:35:38 -05:00
Add ability to run ADS commands
This commit is contained in:
@@ -25,14 +25,17 @@ import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvent
|
||||
import { firstIndex, find } from 'vs/base/common/arrays';
|
||||
import { HideInputTag } from 'sql/platform/notebooks/common/outputRegistry';
|
||||
import { FutureInternal, notebookConstants } from 'sql/workbench/services/notebook/browser/interfaces';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
let modelId = 0;
|
||||
|
||||
export class CellModel implements ICellModel {
|
||||
export class CellModel extends Disposable implements ICellModel {
|
||||
public id: string;
|
||||
|
||||
private _cellType: nb.CellType;
|
||||
private _source: string | string[];
|
||||
private _source: string[];
|
||||
private _language: string;
|
||||
private _cellGuid: string;
|
||||
private _future: FutureInternal;
|
||||
@@ -56,18 +59,22 @@ export class CellModel implements ICellModel {
|
||||
private _isCollapsed: boolean;
|
||||
private _onCollapseStateChanged = new Emitter<boolean>();
|
||||
private _modelContentChangedEvent: IModelContentChangedEvent;
|
||||
private _isCommandExecutionSettingEnabled: boolean;
|
||||
|
||||
constructor(cellData: nb.ICellContents,
|
||||
private _options: ICellModelOptions,
|
||||
@optional(INotebookService) private _notebookService?: INotebookService
|
||||
@optional(INotebookService) private _notebookService?: INotebookService,
|
||||
@optional(ICommandService) private _commandService?: ICommandService,
|
||||
@optional(IConfigurationService) private _configurationService?: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
this.id = `${modelId++}`;
|
||||
if (cellData) {
|
||||
// Read in contents if available
|
||||
this.fromJSON(cellData);
|
||||
} else {
|
||||
this._cellType = CellTypes.Code;
|
||||
this._source = '';
|
||||
this._source = [''];
|
||||
}
|
||||
|
||||
this._isEditMode = this._cellType !== CellTypes.Markdown;
|
||||
@@ -80,6 +87,14 @@ export class CellModel implements ICellModel {
|
||||
// if the fromJson() method was already called and _cellGuid was previously set, don't generate another UUID unnecessarily
|
||||
this._cellGuid = this._cellGuid || generateUuid();
|
||||
this.createUri();
|
||||
let commandExecutionSettingValue: boolean = this._configurationService.getValue('notebook.allowCommandExecution');
|
||||
this._isCommandExecutionSettingEnabled = commandExecutionSettingValue ? commandExecutionSettingValue : false;
|
||||
|
||||
this._register(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('notebook.allowCommandExecution')) {
|
||||
this._isCommandExecutionSettingEnabled = this._configurationService.getValue('notebook.allowCommandExecution');
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public equals(other: ICellModel) {
|
||||
@@ -336,19 +351,21 @@ export class CellModel implements ICellModel {
|
||||
|
||||
// requestExecute expects a string for the code parameter
|
||||
content = Array.isArray(content) ? content.join('') : content;
|
||||
const future = kernel.requestExecute({
|
||||
code: content,
|
||||
stop_on_error: true
|
||||
}, false);
|
||||
this.setFuture(future as FutureInternal);
|
||||
this.fireExecutionStateChanged();
|
||||
// For now, await future completion. Later we should just track and handle cancellation based on model notifications
|
||||
let result: nb.IExecuteReplyMsg = <nb.IExecuteReplyMsg><any>await future.done;
|
||||
if (result && result.content) {
|
||||
this.executionCount = result.content.execution_count;
|
||||
if (result.content.status !== 'ok') {
|
||||
// TODO track error state
|
||||
return false;
|
||||
if (!this.checkForAdsCommandMagic()) {
|
||||
const future = kernel.requestExecute({
|
||||
code: content,
|
||||
stop_on_error: true
|
||||
}, false);
|
||||
this.setFuture(future as FutureInternal);
|
||||
this.fireExecutionStateChanged();
|
||||
// For now, await future completion. Later we should just track and handle cancellation based on model notifications
|
||||
let result: nb.IExecuteReplyMsg = <nb.IExecuteReplyMsg><any>await future.done;
|
||||
if (result && result.content) {
|
||||
this.executionCount = result.content.execution_count;
|
||||
if (result.content.status !== 'ok') {
|
||||
// TODO track error state
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -682,7 +699,7 @@ export class CellModel implements ICellModel {
|
||||
}
|
||||
|
||||
|
||||
private getMultilineSource(source: string | string[]): string | string[] {
|
||||
private getMultilineSource(source: string | string[]): string[] {
|
||||
if (source === undefined) {
|
||||
return [];
|
||||
}
|
||||
@@ -707,6 +724,29 @@ export class CellModel implements ICellModel {
|
||||
return source;
|
||||
}
|
||||
|
||||
// Run ADS commands via a notebook. Configured by a setting (turned off by default).
|
||||
private checkForAdsCommandMagic(): boolean {
|
||||
if (!this._isCommandExecutionSettingEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let executeCommandMagic = '%%AZDATA_EXECUTE_COMMAND';
|
||||
if (this._source && this._source.length) {
|
||||
if (this._source[0].startsWith(executeCommandMagic)) {
|
||||
let commandNamePlusArgs = this._source[0].replace(executeCommandMagic + ' ', '');
|
||||
if (commandNamePlusArgs) {
|
||||
let commandName = commandNamePlusArgs.split(' ')[0];
|
||||
if (commandName) {
|
||||
let args = commandNamePlusArgs.replace(commandName + ' ', '');
|
||||
this._commandService.executeCommand(commandName, [args]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Dispose and set current future to undefined
|
||||
private disposeFuture() {
|
||||
if (this._future) {
|
||||
|
||||
Reference in New Issue
Block a user