mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-21 09:35:38 -05:00
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:
@@ -97,71 +97,71 @@ export class MainThreadDataProtocol extends Disposable implements MainThreadData
|
||||
public $registerQueryProvider(providerId: string, handle: number): Promise<any> {
|
||||
const self = this;
|
||||
this._queryManagementService.addQueryRequestHandler(providerId, {
|
||||
cancelQuery(ownerUri: string): Thenable<azdata.QueryCancelResult> {
|
||||
return self._proxy.$cancelQuery(handle, ownerUri);
|
||||
cancelQuery(ownerUri: string): Promise<azdata.QueryCancelResult> {
|
||||
return Promise.resolve(self._proxy.$cancelQuery(handle, ownerUri));
|
||||
},
|
||||
runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable<void> {
|
||||
return self._proxy.$runQuery(handle, ownerUri, selection, runOptions);
|
||||
runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$runQuery(handle, ownerUri, selection, runOptions));
|
||||
},
|
||||
runQueryStatement(ownerUri: string, line: number, column: number): Thenable<void> {
|
||||
return self._proxy.$runQueryStatement(handle, ownerUri, line, column);
|
||||
runQueryStatement(ownerUri: string, line: number, column: number): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$runQueryStatement(handle, ownerUri, line, column));
|
||||
},
|
||||
runQueryString(ownerUri: string, queryString: string): Thenable<void> {
|
||||
return self._proxy.$runQueryString(handle, ownerUri, queryString);
|
||||
runQueryString(ownerUri: string, queryString: string): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$runQueryString(handle, ownerUri, queryString));
|
||||
},
|
||||
runQueryAndReturn(ownerUri: string, queryString: string): Thenable<azdata.SimpleExecuteResult> {
|
||||
return self._proxy.$runQueryAndReturn(handle, ownerUri, queryString);
|
||||
runQueryAndReturn(ownerUri: string, queryString: string): Promise<azdata.SimpleExecuteResult> {
|
||||
return Promise.resolve(self._proxy.$runQueryAndReturn(handle, ownerUri, queryString));
|
||||
},
|
||||
parseSyntax(ownerUri: string, query: string): Thenable<azdata.SyntaxParseResult> {
|
||||
return self._proxy.$parseSyntax(handle, ownerUri, query);
|
||||
parseSyntax(ownerUri: string, query: string): Promise<azdata.SyntaxParseResult> {
|
||||
return Promise.resolve(self._proxy.$parseSyntax(handle, ownerUri, query));
|
||||
},
|
||||
getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable<azdata.QueryExecuteSubsetResult> {
|
||||
return self._proxy.$getQueryRows(handle, rowData);
|
||||
getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Promise<azdata.QueryExecuteSubsetResult> {
|
||||
return Promise.resolve(self._proxy.$getQueryRows(handle, rowData));
|
||||
},
|
||||
setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable<void> {
|
||||
return self._proxy.$setQueryExecutionOptions(handle, ownerUri, options);
|
||||
setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$setQueryExecutionOptions(handle, ownerUri, options));
|
||||
},
|
||||
disposeQuery(ownerUri: string): Thenable<void> {
|
||||
return self._proxy.$disposeQuery(handle, ownerUri);
|
||||
disposeQuery(ownerUri: string): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$disposeQuery(handle, ownerUri));
|
||||
},
|
||||
saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable<azdata.SaveResultRequestResult> {
|
||||
saveResults(requestParams: azdata.SaveResultsRequestParams): Promise<azdata.SaveResultRequestResult> {
|
||||
let saveResultsFeatureInfo = self._serializationService.getSaveResultsFeatureMetadataProvider(requestParams.ownerUri);
|
||||
if (saveResultsFeatureInfo && saveResultsFeatureInfo.enabled) {
|
||||
return self._proxy.$saveResults(handle, requestParams);
|
||||
return Promise.resolve(self._proxy.$saveResults(handle, requestParams));
|
||||
}
|
||||
else if (saveResultsFeatureInfo && !saveResultsFeatureInfo.enabled) {
|
||||
return self._serializationService.disabledSaveAs();
|
||||
return Promise.resolve(self._serializationService.disabledSaveAs());
|
||||
}
|
||||
else {
|
||||
return self._serializationService.saveAs(requestParams.resultFormat, requestParams.filePath, undefined, true);
|
||||
return Promise.resolve(self._serializationService.saveAs(requestParams.resultFormat, requestParams.filePath, undefined, true));
|
||||
}
|
||||
},
|
||||
initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable<void> {
|
||||
return self._proxy.$initializeEdit(handle, ownerUri, schemaName, objectName, objectType, rowLimit, queryString);
|
||||
initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$initializeEdit(handle, ownerUri, schemaName, objectName, objectType, rowLimit, queryString));
|
||||
},
|
||||
updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable<azdata.EditUpdateCellResult> {
|
||||
return self._proxy.$updateCell(handle, ownerUri, rowId, columnId, newValue);
|
||||
updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise<azdata.EditUpdateCellResult> {
|
||||
return Promise.resolve(self._proxy.$updateCell(handle, ownerUri, rowId, columnId, newValue));
|
||||
},
|
||||
commitEdit(ownerUri): Thenable<void> {
|
||||
return self._proxy.$commitEdit(handle, ownerUri);
|
||||
commitEdit(ownerUri): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$commitEdit(handle, ownerUri));
|
||||
},
|
||||
createRow(ownerUri: string): Thenable<azdata.EditCreateRowResult> {
|
||||
return self._proxy.$createRow(handle, ownerUri);
|
||||
createRow(ownerUri: string): Promise<azdata.EditCreateRowResult> {
|
||||
return Promise.resolve(self._proxy.$createRow(handle, ownerUri));
|
||||
},
|
||||
deleteRow(ownerUri: string, rowId: number): Thenable<void> {
|
||||
return self._proxy.$deleteRow(handle, ownerUri, rowId);
|
||||
deleteRow(ownerUri: string, rowId: number): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$deleteRow(handle, ownerUri, rowId));
|
||||
},
|
||||
disposeEdit(ownerUri: string): Thenable<void> {
|
||||
return self._proxy.$disposeEdit(handle, ownerUri);
|
||||
disposeEdit(ownerUri: string): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$disposeEdit(handle, ownerUri));
|
||||
},
|
||||
revertCell(ownerUri: string, rowId: number, columnId: number): Thenable<azdata.EditRevertCellResult> {
|
||||
return self._proxy.$revertCell(handle, ownerUri, rowId, columnId);
|
||||
revertCell(ownerUri: string, rowId: number, columnId: number): Promise<azdata.EditRevertCellResult> {
|
||||
return Promise.resolve(self._proxy.$revertCell(handle, ownerUri, rowId, columnId));
|
||||
},
|
||||
revertRow(ownerUri: string, rowId: number): Thenable<void> {
|
||||
return self._proxy.$revertRow(handle, ownerUri, rowId);
|
||||
revertRow(ownerUri: string, rowId: number): Promise<void> {
|
||||
return Promise.resolve(self._proxy.$revertRow(handle, ownerUri, rowId));
|
||||
},
|
||||
getEditRows(rowData: azdata.EditSubsetParams): Thenable<azdata.EditSubsetResult> {
|
||||
return self._proxy.$getEditRows(handle, rowData);
|
||||
getEditRows(rowData: azdata.EditSubsetParams): Promise<azdata.EditSubsetResult> {
|
||||
return Promise.resolve(self._proxy.$getEditRows(handle, rowData));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -207,31 +207,29 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On
|
||||
|
||||
// Setup a function for generating a promise to lookup result subsets
|
||||
this.loadDataFunction = (offset: number, count: number): Promise<{}[]> => {
|
||||
return new Promise<{}[]>((resolve, reject) => {
|
||||
self.dataService.getEditRows(offset, count).subscribe(result => {
|
||||
let gridData = result.subset.map(r => {
|
||||
let dataWithSchema = {};
|
||||
// skip the first column since its a number column
|
||||
for (let i = 1; i < this.dataSet.columnDefinitions.length; i++) {
|
||||
dataWithSchema[this.dataSet.columnDefinitions[i].field] = {
|
||||
displayValue: r.cells[i - 1].displayValue,
|
||||
ariaLabel: escape(r.cells[i - 1].displayValue),
|
||||
isNull: r.cells[i - 1].isNull
|
||||
};
|
||||
}
|
||||
return dataWithSchema;
|
||||
});
|
||||
|
||||
// should add null row?
|
||||
if (offset + count > this.dataSet.totalRows - 1) {
|
||||
gridData.push(this.dataSet.columnDefinitions.reduce((p, c) => {
|
||||
p[c.field] = 'NULL';
|
||||
return p;
|
||||
}, {}));
|
||||
return self.dataService.getEditRows(offset, count).then(result => {
|
||||
let gridData = result.subset.map(r => {
|
||||
let dataWithSchema = {};
|
||||
// skip the first column since its a number column
|
||||
for (let i = 1; i < this.dataSet.columnDefinitions.length; i++) {
|
||||
dataWithSchema[this.dataSet.columnDefinitions[i].field] = {
|
||||
displayValue: r.cells[i - 1].displayValue,
|
||||
ariaLabel: escape(r.cells[i - 1].displayValue),
|
||||
isNull: r.cells[i - 1].isNull
|
||||
};
|
||||
}
|
||||
|
||||
resolve(gridData);
|
||||
return dataWithSchema;
|
||||
});
|
||||
|
||||
// should add null row?
|
||||
if (offset + count > this.dataSet.totalRows - 1) {
|
||||
gridData.push(this.dataSet.columnDefinitions.reduce((p, c) => {
|
||||
p[c.field] = 'NULL';
|
||||
return p;
|
||||
}, {}));
|
||||
}
|
||||
|
||||
return gridData;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,13 +40,8 @@ export class DataService {
|
||||
* @param rowStart The row to start retrieving from (inclusive)
|
||||
* @param numberOfRows The maximum number of rows to return
|
||||
*/
|
||||
getEditRows(rowStart: number, numberOfRows: number): Observable<EditSubsetResult> {
|
||||
const self = this;
|
||||
return Observable.create(function (observer: Observer<EditSubsetResult>) {
|
||||
self._queryModel.getEditRows(self._uri, rowStart, numberOfRows).then(results => {
|
||||
observer.next(results);
|
||||
});
|
||||
});
|
||||
getEditRows(rowStart: number, numberOfRows: number): Promise<EditSubsetResult | undefined> {
|
||||
return this._queryModel.getEditRows(this._uri, rowStart, numberOfRows);
|
||||
}
|
||||
|
||||
updateCell(rowId: number, columnId: number, newValue: string): Thenable<EditUpdateCellResult> {
|
||||
|
||||
@@ -30,7 +30,7 @@ export class GridTableState extends Disposable {
|
||||
/* The top row of the current scroll */
|
||||
public scrollPositionY = 0;
|
||||
public scrollPositionX = 0;
|
||||
public columnSizes: number[] = undefined;
|
||||
public columnSizes?: number[] = undefined;
|
||||
public selection: Slick.Range[];
|
||||
public activeCell: Slick.Cell;
|
||||
|
||||
|
||||
@@ -276,12 +276,12 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
||||
}
|
||||
|
||||
// State update funtions
|
||||
public runQuery(selection: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void {
|
||||
public runQuery(selection?: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void {
|
||||
this._queryModelService.runQuery(this.uri, selection, this, executePlanOptions);
|
||||
this.state.executing = true;
|
||||
}
|
||||
|
||||
public runQueryStatement(selection: ISelectionData): void {
|
||||
public runQueryStatement(selection?: ISelectionData): void {
|
||||
this._queryModelService.runQueryStatement(this.uri, selection, this);
|
||||
this.state.executing = true;
|
||||
}
|
||||
@@ -316,7 +316,7 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
||||
|
||||
let isRunningQuery = this._queryModelService.isRunningQuery(this.uri);
|
||||
if (!isRunningQuery && params && params.runQueryOnCompletion) {
|
||||
let selection: ISelectionData = params ? params.querySelection : undefined;
|
||||
let selection: ISelectionData | undefined = params ? params.querySelection : undefined;
|
||||
if (params.runQueryOnCompletion === RunQueryOnConnectionMode.executeCurrentQuery) {
|
||||
this.runQueryStatement(selection);
|
||||
} else if (params.runQueryOnCompletion === RunQueryOnConnectionMode.executeQuery) {
|
||||
@@ -361,6 +361,6 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
|
||||
}
|
||||
|
||||
public get isSharedSession(): boolean {
|
||||
return this.uri && this.uri.startsWith('vsls:');
|
||||
return !!(this.uri && this.uri.startsWith('vsls:'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@ export class ResultsViewState {
|
||||
*/
|
||||
export class QueryResultsInput extends EditorInput {
|
||||
|
||||
private _state = new ResultsViewState();
|
||||
private _state?= new ResultsViewState();
|
||||
|
||||
public get state(): ResultsViewState {
|
||||
public get state(): ResultsViewState | undefined {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ export class QueryResultsInput extends EditorInput {
|
||||
}
|
||||
|
||||
close() {
|
||||
this.state.dispose();
|
||||
this.state!.dispose();
|
||||
this._state = undefined;
|
||||
super.close();
|
||||
}
|
||||
|
||||
@@ -67,12 +67,12 @@ export class ResultSerializer {
|
||||
/**
|
||||
* Handle save request by getting filename from user and sending request to service
|
||||
*/
|
||||
public saveResults(uri: string, saveRequest: ISaveRequest): Thenable<void> {
|
||||
public saveResults(uri: string, saveRequest: ISaveRequest): Promise<void> {
|
||||
const self = this;
|
||||
return this.promptForFilepath(saveRequest.format, uri).then(filePath => {
|
||||
if (filePath) {
|
||||
if (!path.isAbsolute(filePath)) {
|
||||
filePath = resolveFilePath(uri, filePath, this.rootPath);
|
||||
filePath = resolveFilePath(uri, filePath, this.rootPath)!;
|
||||
}
|
||||
let saveResultsParams = this.getParameters(uri, filePath, saveRequest.batchIndex, saveRequest.resultSetNumber, saveRequest.format, saveRequest.selection ? saveRequest.selection[0] : undefined);
|
||||
let sendRequest = () => this.sendSaveRequestToService(saveResultsParams);
|
||||
@@ -98,9 +98,9 @@ export class ResultSerializer {
|
||||
return this.promptForFilepath(format, uri).then(filePath => {
|
||||
if (filePath) {
|
||||
if (!path.isAbsolute(filePath)) {
|
||||
filePath = resolveFilePath(uri, filePath, this.rootPath);
|
||||
filePath = resolveFilePath(uri, filePath, this.rootPath)!;
|
||||
}
|
||||
return self.doSave(filePath, format, () => sendRequest(filePath));
|
||||
return self.doSave(filePath, format, () => sendRequest(filePath!));
|
||||
}
|
||||
return Promise.resolve();
|
||||
});
|
||||
@@ -117,10 +117,10 @@ export class ResultSerializer {
|
||||
|
||||
private get outputChannel(): IOutputChannel {
|
||||
this.ensureOutputChannelExists();
|
||||
return this._outputService.getChannel(ConnectionConstants.outputChannelName);
|
||||
return this._outputService.getChannel(ConnectionConstants.outputChannelName)!;
|
||||
}
|
||||
|
||||
private get rootPath(): string {
|
||||
private get rootPath(): string | undefined {
|
||||
return getRootPath(this._contextService);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ export class ResultSerializer {
|
||||
}
|
||||
|
||||
|
||||
private promptForFilepath(format: SaveFormat, resourceUri: string): Thenable<string | undefined> {
|
||||
private promptForFilepath(format: SaveFormat, resourceUri: string): Promise<string | undefined> {
|
||||
let filepathPlaceHolder = prevSavePath ? path.dirname(prevSavePath) : resolveCurrentDirectory(resourceUri, this.rootPath);
|
||||
if (filepathPlaceHolder) {
|
||||
filepathPlaceHolder = path.join(filepathPlaceHolder, this.getResultsDefaultFilename(format));
|
||||
@@ -171,7 +171,7 @@ export class ResultSerializer {
|
||||
|
||||
private getResultsFileExtension(format: SaveFormat): FileFilter[] {
|
||||
let fileFilters = new Array<FileFilter>();
|
||||
let fileFilter: { extensions: string[]; name: string } = { extensions: undefined, name: undefined };
|
||||
let fileFilter: { extensions: string[]; name: string } = Object.create(null);
|
||||
|
||||
switch (format) {
|
||||
case SaveFormat.CSV:
|
||||
@@ -211,7 +211,7 @@ export class ResultSerializer {
|
||||
} else if (format === SaveFormat.XML) {
|
||||
saveResultsParams = this.getConfigForXml();
|
||||
}
|
||||
return saveResultsParams;
|
||||
return saveResultsParams!; // this could be unsafe
|
||||
}
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ export class ResultSerializer {
|
||||
}
|
||||
|
||||
|
||||
private getParameters(uri: string, filePath: string, batchIndex: number, resultSetNo: number, format: string, selection: Slick.Range): SaveResultsRequestParams {
|
||||
private getParameters(uri: string, filePath: string, batchIndex: number, resultSetNo: number, format: string, selection?: Slick.Range): SaveResultsRequestParams {
|
||||
let saveResultsParams = this.getBasicSaveParameters(format);
|
||||
saveResultsParams.filePath = filePath;
|
||||
saveResultsParams.ownerUri = uri;
|
||||
@@ -298,8 +298,8 @@ export class ResultSerializer {
|
||||
/**
|
||||
* Check if a range of cells were selected.
|
||||
*/
|
||||
private isSelected(selection: Slick.Range): boolean {
|
||||
return (selection && !((selection.fromCell === selection.toCell) && (selection.fromRow === selection.toRow)));
|
||||
private isSelected(selection?: Slick.Range): selection is Slick.Range {
|
||||
return !!(selection && !((selection.fromCell === selection.toCell) && (selection.fromRow === selection.toRow)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user