Fix weird exception when no connection is present for SQL kernel, Limit Max Rows to 2000 (#3870)

Fixes #3856. Matches the Jupyter behavior that we have, where we don't show any message when a connection is required. We no longer will throw a bizarre exception about getOptionsKey being undefined.

Also sets max rows returned to 2000.
This commit is contained in:
Chris LaFreniere
2019-01-31 09:38:59 -08:00
committed by Kevin Cunnane
parent d9c383b2ef
commit c43085beab

View File

@@ -21,6 +21,7 @@ import { escape } from 'sql/base/common/strings';
export const sqlKernel: string = localize('sqlKernel', 'SQL'); export const sqlKernel: string = localize('sqlKernel', 'SQL');
export const sqlKernelError: string = localize("sqlKernelError", "SQL kernel error"); export const sqlKernelError: string = localize("sqlKernelError", "SQL kernel error");
export const MAX_ROWS = 2000;
let sqlKernelSpec: nb.IKernelSpec = ({ let sqlKernelSpec: nb.IKernelSpec = ({
name: sqlKernel, name: sqlKernel,
@@ -188,7 +189,7 @@ class SqlKernel extends Disposable implements nb.IKernel {
requestExecute(content: nb.IExecuteRequest, disposeOnDone?: boolean): nb.IFuture { requestExecute(content: nb.IExecuteRequest, disposeOnDone?: boolean): nb.IFuture {
if (this._queryRunner) { if (this._queryRunner) {
this._queryRunner.runQuery(content.code); this._queryRunner.runQuery(content.code);
} else { } else if (this._currentConnection) {
let connectionUri = Utils.generateUri(this._currentConnection, 'notebook'); let connectionUri = Utils.generateUri(this._currentConnection, 'notebook');
this._queryRunner = this._instantiationService.createInstance(QueryRunner, connectionUri, undefined); this._queryRunner = this._instantiationService.createInstance(QueryRunner, connectionUri, undefined);
this._connectionManagementService.connect(this._currentConnection, connectionUri).then((result) => this._connectionManagementService.connect(this._currentConnection, connectionUri).then((result) =>
@@ -255,7 +256,7 @@ export class SQLFuture extends Disposable implements FutureInternal {
super(); super();
} }
get inProgress(): boolean { get inProgress(): boolean {
return !this._queryRunner.hasCompleted; return this._queryRunner && !this._queryRunner.hasCompleted;
} }
set inProgress(val: boolean) { set inProgress(val: boolean) {
if (this._queryRunner && !val) { if (this._queryRunner && !val) {
@@ -269,18 +270,22 @@ export class SQLFuture extends Disposable implements FutureInternal {
get done(): Thenable<nb.IShellMessage> { get done(): Thenable<nb.IShellMessage> {
let deferred = new Deferred<nb.IShellMessage>(); let deferred = new Deferred<nb.IShellMessage>();
try { try {
this._register(this._queryRunner.onBatchEnd(e => { if (this._queryRunner) {
let msg: nb.IShellMessage = { this._register(this._queryRunner.onBatchEnd(e => {
channel: 'shell', let msg: nb.IShellMessage = {
type: 'execute_reply', channel: 'shell',
content: { status: 'ok' }, type: 'execute_reply',
header: undefined, content: { status: 'ok' },
metadata: {}, header: undefined,
parent_header: undefined metadata: {},
}; parent_header: undefined
this._msg = msg; };
deferred.resolve(msg); this._msg = msg;
})); deferred.resolve(msg);
}));
} else {
deferred.resolve();
}
} catch { } catch {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
@@ -298,29 +303,32 @@ export class SQLFuture extends Disposable implements FutureInternal {
// no-op // no-op
} }
setIOPubHandler(handler: nb.MessageHandler<nb.IIOPubMessage>): void { setIOPubHandler(handler: nb.MessageHandler<nb.IIOPubMessage>): void {
this._register(this._queryRunner.onBatchEnd(batch => { if (this._queryRunner) {
this._queryRunner.getQueryRows(0, batch.resultSetSummaries[0].rowCount, 0, 0).then(d => { this._register(this._queryRunner.onBatchEnd(batch => {
let columns = batch.resultSetSummaries[0].columnInfo; let rowCount = batch.resultSetSummaries[0].rowCount > MAX_ROWS ? MAX_ROWS : batch.resultSetSummaries[0].rowCount;
this._queryRunner.getQueryRows(0, rowCount, 0, 0).then(d => {
let columns = batch.resultSetSummaries[0].columnInfo;
let msg: nb.IIOPubMessage = { let msg: nb.IIOPubMessage = {
channel: 'iopub', channel: 'iopub',
type: 'iopub', type: 'iopub',
header: <nb.IHeader>{ header: <nb.IHeader>{
msg_id: undefined, msg_id: undefined,
msg_type: 'execute_result' msg_type: 'execute_result'
}, },
content: <nb.IExecuteResult>{ content: <nb.IExecuteResult>{
output_type: 'execute_result', output_type: 'execute_result',
metadata: {}, metadata: {},
execution_count: 0, execution_count: 0,
data: { 'application/vnd.dataresource+json': this.convertToDataResource(columns, d), 'text/html': this.convertToHtmlTable(columns, d) } data: { 'application/vnd.dataresource+json': this.convertToDataResource(columns, d), 'text/html': this.convertToHtmlTable(columns, d) }
}, },
metadata: undefined, metadata: undefined,
parent_header: undefined parent_header: undefined
}; };
handler.handle(msg); handler.handle(msg);
}); });
})); }));
}
} }
registerMessageHook(hook: (msg: nb.IIOPubMessage) => boolean | Thenable<boolean>): void { registerMessageHook(hook: (msg: nb.IIOPubMessage) => boolean | Thenable<boolean>): void {
// no-op // no-op