Strict null on some query and connection (#7300)

* wip

* make connection work with strict-nulls

* change comments

* fix tests; remove unneeded type forcing

* address feedback

* adjust the logic of query editor

* clean up typing
This commit is contained in:
Anthony Dresser
2019-10-21 15:50:12 -07:00
committed by GitHub
parent 6a375fdd8c
commit 06e86e57e7
22 changed files with 367 additions and 369 deletions

View File

@@ -55,7 +55,7 @@ export default class QueryRunner extends Disposable {
private _isQueryPlan: boolean = false;
public get isQueryPlan(): boolean { return this._isQueryPlan; }
private _planXml = new Deferred<string>();
public get planXml(): Thenable<string> { return this._planXml.promise; }
public get planXml(): Promise<string> { return this._planXml.promise; }
private _onMessage = this._register(new Emitter<IQueryMessage>());
public get onMessage(): Event<IQueryMessage> { return this._onMessage.event; } // this is the only way typemoq can moq this... needs investigation @todo anthonydresser 5/2/2019
@@ -87,12 +87,12 @@ export default class QueryRunner extends Disposable {
private _onVisualize = this._register(new Emitter<azdata.ResultSetSummary>());
public readonly onVisualize = this._onVisualize.event;
private _queryStartTime: Date;
public get queryStartTime(): Date {
private _queryStartTime?: Date;
public get queryStartTime(): Date | undefined {
return this._queryStartTime;
}
private _queryEndTime: Date;
public get queryEndTime(): Date {
private _queryEndTime?: Date;
public get queryEndTime(): Date | undefined {
return this._queryEndTime;
}
@@ -135,7 +135,7 @@ export default class QueryRunner extends Disposable {
/**
* Cancels the running query, if there is one
*/
public cancelQuery(): Thenable<azdata.QueryCancelResult> {
public cancelQuery(): Promise<azdata.QueryCancelResult> {
return this._queryManagementService.cancelQuery(this.uri);
}
@@ -143,21 +143,25 @@ export default class QueryRunner extends Disposable {
* Runs the query with the provided query
* @param input Query string to execute
*/
public runQuery(input: string, runOptions?: azdata.ExecutionPlanOptions): Thenable<void>;
public runQuery(input: string, runOptions?: azdata.ExecutionPlanOptions): Promise<void>;
/**
* Runs the query by pulling the query from the document using the provided selection data
* @param input selection data
*/
public runQuery(input: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable<void>;
public runQuery(input, runOptions?: azdata.ExecutionPlanOptions): Thenable<void> {
return this.doRunQuery(input, false, runOptions);
public runQuery(input: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise<void>;
public runQuery(input: string | azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise<void> {
if (types.isString(input)) {
return this.doRunQuery(input, false, runOptions);
} else {
return this.doRunQuery(input, false, runOptions);
}
}
/**
* Runs the current SQL statement by pulling the query from the document using the provided selection data
* @param input selection data
*/
public runQueryStatement(input: azdata.ISelectionData): Thenable<void> {
public runQueryStatement(input: azdata.ISelectionData): Promise<void> {
return this.doRunQuery(input, true);
}
@@ -165,11 +169,11 @@ export default class QueryRunner extends Disposable {
* Implementation that runs the query with the provided query
* @param input Query string to execute
*/
private doRunQuery(input: string, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Thenable<void>;
private doRunQuery(input: azdata.ISelectionData, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Thenable<void>;
private doRunQuery(input, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Thenable<void> {
private doRunQuery(input: string, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise<void>;
private doRunQuery(input: azdata.ISelectionData, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise<void>;
private doRunQuery(input: string | azdata.ISelectionData, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise<void> {
if (this.isExecuting) {
return Promise.resolve(undefined);
return Promise.resolve();
}
this._planXml = new Deferred<string>();
this._batchSets = [];
@@ -177,7 +181,7 @@ export default class QueryRunner extends Disposable {
this._queryStartTime = undefined;
this._queryEndTime = undefined;
this._messages = [];
if (types.isObject(input) || types.isUndefinedOrNull(input)) {
if (isSelectionOrUndefined(input)) {
// Update internal state to show that we're executing the query
this._resultLineOffset = input ? input.startLine : 0;
this._resultColumnOffset = input ? input.startColumn : 0;
@@ -191,7 +195,7 @@ export default class QueryRunner extends Disposable {
return runCurrentStatement
? this._queryManagementService.runQueryStatement(this.uri, input.startLine, input.startColumn).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e))
: this._queryManagementService.runQuery(this.uri, input, runOptions).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e));
} else if (types.isString(input)) {
} else {
// Update internal state to show that we're executing the query
this._isExecuting = true;
this._totalElapsedMilliseconds = 0;
@@ -199,8 +203,6 @@ export default class QueryRunner extends Disposable {
this._onQueryStart.fire();
return this._queryManagementService.runQueryString(this.uri, input).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e));
} else {
return Promise.reject('Unknown input');
}
}
@@ -329,7 +331,7 @@ export default class QueryRunner extends Disposable {
if (this._batchSets.length > 0) {
batchSet = this._batchSets[0];
} else {
batchSet = <azdata.BatchSummary>{
batchSet = <azdata.BatchSummary><unknown>{
id: 0,
selection: undefined,
hasError: false,
@@ -399,7 +401,7 @@ export default class QueryRunner extends Disposable {
*/
public handleMessage(obj: azdata.QueryExecuteMessageParams): void {
let message = obj.message;
message.time = new Date(message.time).toLocaleTimeString();
message.time = new Date(message.time!).toLocaleTimeString();
this._messages.push(message);
// Send the message to the results pane
@@ -409,7 +411,7 @@ export default class QueryRunner extends Disposable {
/**
* Get more data rows from the current resultSets from the service layer
*/
public getQueryRows(rowStart: number, numberOfRows: number, batchIndex: number, resultSetIndex: number): Thenable<azdata.QueryExecuteSubsetResult> {
public getQueryRows(rowStart: number, numberOfRows: number, batchIndex: number, resultSetIndex: number): Promise<azdata.QueryExecuteSubsetResult> {
let rowData: azdata.QueryExecuteSubsetParams = <azdata.QueryExecuteSubsetParams>{
ownerUri: this.uri,
resultSetIndex: resultSetIndex,
@@ -430,7 +432,7 @@ export default class QueryRunner extends Disposable {
/*
* Handle a session ready event for Edit Data
*/
public initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable<void> {
public initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Promise<void> {
// Update internal state to show that we're executing the query
this._isExecuting = true;
this._totalElapsedMilliseconds = 0;
@@ -454,7 +456,7 @@ export default class QueryRunner extends Disposable {
* @param rowStart The index of the row to start returning (inclusive)
* @param numberOfRows The number of rows to return
*/
public getEditRows(rowStart: number, numberOfRows: number): Thenable<azdata.EditSubsetResult> {
public getEditRows(rowStart: number, numberOfRows: number): Promise<azdata.EditSubsetResult> {
const self = this;
let rowData: azdata.EditSubsetParams = {
ownerUri: this.uri,
@@ -488,35 +490,35 @@ export default class QueryRunner extends Disposable {
this._onEditSessionReady.fire({ ownerUri, success, message });
}
public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable<azdata.EditUpdateCellResult> {
public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise<azdata.EditUpdateCellResult> {
return this._queryManagementService.updateCell(ownerUri, rowId, columnId, newValue);
}
public commitEdit(ownerUri): Thenable<void> {
public commitEdit(ownerUri: string): Promise<void> {
return this._queryManagementService.commitEdit(ownerUri);
}
public createRow(ownerUri: string): Thenable<azdata.EditCreateRowResult> {
public createRow(ownerUri: string): Promise<azdata.EditCreateRowResult> {
return this._queryManagementService.createRow(ownerUri).then(result => {
return result;
});
}
public deleteRow(ownerUri: string, rowId: number): Thenable<void> {
public deleteRow(ownerUri: string, rowId: number): Promise<void> {
return this._queryManagementService.deleteRow(ownerUri, rowId);
}
public revertCell(ownerUri: string, rowId: number, columnId: number): Thenable<azdata.EditRevertCellResult> {
public revertCell(ownerUri: string, rowId: number, columnId: number): Promise<azdata.EditRevertCellResult> {
return this._queryManagementService.revertCell(ownerUri, rowId, columnId).then(result => {
return result;
});
}
public revertRow(ownerUri: string, rowId: number): Thenable<void> {
public revertRow(ownerUri: string, rowId: number): Promise<void> {
return this._queryManagementService.revertRow(ownerUri, rowId);
}
public disposeEdit(ownerUri: string): Thenable<void> {
public disposeEdit(ownerUri: string): Promise<void> {
return this._queryManagementService.disposeEdit(ownerUri);
}
@@ -530,7 +532,7 @@ export default class QueryRunner extends Disposable {
}
public dispose() {
this._batchSets = undefined;
this._batchSets = undefined!;
super.dispose();
}
@@ -551,8 +553,8 @@ export default class QueryRunner extends Disposable {
}
public getColumnHeaders(batchId: number, resultId: number, range: Slick.Range): string[] {
let headers: string[] = undefined;
public getColumnHeaders(batchId: number, resultId: number, range: Slick.Range): string[] | undefined {
let headers: string[] | undefined = undefined;
let batchSummary: azdata.BatchSummary = this._batchSets[batchId];
if (batchSummary !== undefined) {
let resultSetSummary = batchSummary.resultSetSummaries[resultId];
@@ -612,7 +614,7 @@ export class QueryGridDataProvider implements IGridDataProvider {
) {
}
getRowData(rowStart: number, numberOfRows: number): Thenable<azdata.QueryExecuteSubsetResult> {
getRowData(rowStart: number, numberOfRows: number): Promise<azdata.QueryExecuteSubsetResult> {
return this.queryRunner.getQueryRows(rowStart, numberOfRows, this.batchId, this.resultSetId);
}
@@ -637,7 +639,7 @@ export class QueryGridDataProvider implements IGridDataProvider {
shouldRemoveNewLines(): boolean {
return shouldRemoveNewLines(this._configurationService);
}
getColumnHeaders(range: Slick.Range): string[] {
getColumnHeaders(range: Slick.Range): string[] | undefined {
return this.queryRunner.getColumnHeaders(this.batchId, this.resultSetId, range);
}
@@ -645,7 +647,7 @@ export class QueryGridDataProvider implements IGridDataProvider {
return true;
}
serializeResults(format: SaveFormat, selection: Slick.Range[]): Thenable<void> {
serializeResults(format: SaveFormat, selection: Slick.Range[]): Promise<void> {
return this.queryRunner.serializeResults(this.batchId, this.resultSetId, format, selection);
}
}
@@ -670,3 +672,7 @@ export function shouldRemoveNewLines(configurationService: IConfigurationService
let removeNewLines = configurationService.getValue<boolean>('sql.copyRemoveNewLine');
return !!removeNewLines;
}
function isSelectionOrUndefined(input: string | azdata.ISelectionData | undefined): input is azdata.ISelectionData | undefined {
return types.isObject(input) || types.isUndefinedOrNull(input);
}