mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-28 17:23:19 -05:00
Fix workspaceRoot macro for insights (#4686)
* Fix workspaceRoot macro for insights
The workspaceRoot macro wasn't working correctly for finding the queryFile. There were a couple of issues :
1. The path separators were hardcoded as / which wasn't xplat-compatible
2. They required the first section of the path was one of the folders in the workspace - e.g. if the workspace contained a folder named foo you'd have to specify ${workspaceRoot}\foo\myfile.sql. This is inconsistent with the folder logich was just appends the path after ${workspaceRoot} to the folder that's currently open
I changed the logic to just append the relative part of the path to every folder currently open in the workspace and choose the first one that it found that contained the file we were told to look for - which follows the convention the folder logic uses. If the file doesn't exist it'll just fall back to using the path without the macro (which is likely to not resolve and thus will display an error, but there's nothing we can do at that point anyways)
* Switch to using VS Code resolver (support for more than just workspaceRoot) and move resolution code into helper method so it can be used by the multiple places it's called. Added tests for the methods.
* Add test for invalid param
* Change resolveQueryFilePath to be a standalone exported function. Change it to throw if the file can't be resolved/found so callers can display error correctly. Added more tests to covery new scenarios. Switch to using pfs instead of fs for file existance checks.
* Add extra param to InsightsDialogController construction in test
* Fix formatting and test errors.
* Change to suiteSetup and suiteTeardown so the setup/teardown is only ran once instead of once per test - we don't need unique files and this stops a race condition error with deleting the test folder.
* spaces -> tabs
This commit is contained in:
@@ -8,9 +8,10 @@ import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IInsightsConfigDetails } from 'sql/parts/dashboard/widgets/insights/interfaces';
|
||||
import QueryRunner, { EventType as QREvents } from 'sql/platform/query/common/queryRunner';
|
||||
import * as Utils from 'sql/platform/connection/common/utils';
|
||||
import { IInsightsDialogModel, insertValueRegex } from 'sql/workbench/services/insights/common/insightsDialogService';
|
||||
import { IInsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogService';
|
||||
import { error } from 'sql/base/common/log';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
import { resolveQueryFilePath } from '../common/insightsUtils';
|
||||
|
||||
import { DbCellValue, IDbColumn, QueryExecuteSubsetResult } from 'azdata';
|
||||
|
||||
@@ -19,8 +20,9 @@ import * as types from 'vs/base/common/types';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
|
||||
export class InsightsDialogController {
|
||||
private _queryRunner: QueryRunner;
|
||||
@@ -35,10 +37,11 @@ export class InsightsDialogController {
|
||||
@IErrorMessageService private _errorMessageService: IErrorMessageService,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IWorkspaceContextService private _workspaceContextService: IWorkspaceContextService
|
||||
@IWorkspaceContextService private _workspaceContextService: IWorkspaceContextService,
|
||||
@IConfigurationResolverService private _configurationResolverService: IConfigurationResolverService
|
||||
) { }
|
||||
|
||||
public update(input: IInsightsConfigDetails, connectionProfile: IConnectionProfile): Thenable<void> {
|
||||
public async update(input: IInsightsConfigDetails, connectionProfile: IConnectionProfile): Promise<void> {
|
||||
// execute string
|
||||
if (typeof input === 'object') {
|
||||
if (connectionProfile === undefined) {
|
||||
@@ -57,49 +60,32 @@ export class InsightsDialogController {
|
||||
this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), e);
|
||||
}).then(() => undefined);
|
||||
} else if (types.isString(input.queryFile)) {
|
||||
let filePath = input.queryFile;
|
||||
// check for workspace relative path
|
||||
let match = filePath.match(insertValueRegex);
|
||||
if (match && match.length > 0 && match[1] === 'workspaceRoot') {
|
||||
filePath = filePath.replace(match[0], '');
|
||||
|
||||
switch (this._workspaceContextService.getWorkbenchState()) {
|
||||
case WorkbenchState.FOLDER:
|
||||
filePath = this._workspaceContextService.getWorkspace().folders[0].toResource(filePath).fsPath;
|
||||
break;
|
||||
case WorkbenchState.WORKSPACE:
|
||||
let filePathArray = filePath.split('/');
|
||||
// filter out empty sections
|
||||
filePathArray = filePathArray.filter(i => !!i);
|
||||
let folder = this._workspaceContextService.getWorkspace().folders.find(i => i.name === filePathArray[0]);
|
||||
if (!folder) {
|
||||
return Promise.reject(new Error(`Could not find workspace folder ${filePathArray[0]}`));
|
||||
}
|
||||
// remove the folder name from the filepath
|
||||
filePathArray.shift();
|
||||
// rejoin the filepath after doing the work to find the right folder
|
||||
filePath = '/' + filePathArray.join('/');
|
||||
filePath = folder.toResource(filePath).fsPath;
|
||||
break;
|
||||
}
|
||||
|
||||
let filePath: string;
|
||||
try {
|
||||
filePath = await resolveQueryFilePath(input.queryFile,
|
||||
this._workspaceContextService,
|
||||
this._configurationResolverService);
|
||||
}
|
||||
catch (e) {
|
||||
this._notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: e
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
try {
|
||||
let buffer: Buffer = await pfs.readFile(filePath);
|
||||
this.createQuery(buffer.toString(), connectionProfile).catch(e => {
|
||||
this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), e);
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
this._notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: nls.localize("insightsFileError", "There was an error reading the query file: ") + e
|
||||
});
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
pfs.readFile(filePath).then(
|
||||
buffer => {
|
||||
this.createQuery(buffer.toString(), connectionProfile).catch(e => {
|
||||
this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), e);
|
||||
}).then(() => resolve());
|
||||
},
|
||||
error => {
|
||||
this._notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: nls.localize("insightsFileError", "There was an error reading the query file: ") + error
|
||||
});
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
error('Error reading details Query: ', input);
|
||||
this._notificationService.notify({
|
||||
|
||||
Reference in New Issue
Block a user