use file service for insights (#6248)

This commit is contained in:
Anthony Dresser
2019-07-03 13:45:19 -07:00
committed by GitHub
parent 92fbfcdac9
commit f19f21d547
6 changed files with 120 additions and 44 deletions

View File

@@ -24,17 +24,16 @@ import { SimpleExecuteResult } from 'azdata';
import { Action } from 'vs/base/common/actions'; import { Action } from 'vs/base/common/actions';
import * as types from 'vs/base/common/types'; import * as types from 'vs/base/common/types';
import * as pfs from 'vs/base/node/pfs';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IntervalTimer, createCancelablePromise } from 'vs/base/common/async'; import { IntervalTimer, createCancelablePromise } from 'vs/base/common/async';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { toDisposable } from 'vs/base/common/lifecycle'; import { toDisposable } from 'vs/base/common/lifecycle';
import { isPromiseCanceledError } from 'vs/base/common/errors'; import { isPromiseCanceledError } from 'vs/base/common/errors';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IFileService } from 'vs/platform/files/common/files';
import { URI } from 'vs/base/common/uri';
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution); const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);
@@ -75,9 +74,8 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
@Inject(forwardRef(() => Injector)) private _injector: Injector, @Inject(forwardRef(() => Injector)) private _injector: Injector,
@Inject(IInstantiationService) private instantiationService: IInstantiationService, @Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(IStorageService) private storageService: IStorageService, @Inject(IStorageService) private storageService: IStorageService,
@Inject(IWorkspaceContextService) private readonly _workspaceContextService: IWorkspaceContextService,
@Inject(IConfigurationService) private readonly _configurationService: IConfigurationService, @Inject(IConfigurationService) private readonly _configurationService: IConfigurationService,
@Inject(IConfigurationResolverService) private readonly _configurationResolverService: IConfigurationResolverService @Inject(IFileService) private readonly fileService: IFileService
) { ) {
super(); super();
this.insightConfig = <IInsightsConfig>this._config.widget['insights-widget']; this.insightConfig = <IInsightsConfig>this._config.widget['insights-widget'];
@@ -298,11 +296,9 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget,
if (types.isStringArray(this.insightConfig.query)) { if (types.isStringArray(this.insightConfig.query)) {
this.insightConfig.query = this.insightConfig.query.join(' '); this.insightConfig.query = this.insightConfig.query.join(' ');
} else if (this.insightConfig.queryFile) { } else if (this.insightConfig.queryFile) {
const filePath = await resolveQueryFilePath(this.insightConfig.queryFile, const filePath = await this.instantiationService.invokeFunction(resolveQueryFilePath, this.insightConfig.queryFile);
this._workspaceContextService,
this._configurationResolverService);
this.insightConfig.query = (await pfs.readFile(filePath)).toString(); this.insightConfig.query = (await this.fileService.readFile(URI.file(filePath))).value.toString();
} }
} }
} }

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InsightsDialogController } from 'sql/workbench/services/insights/node/insightsDialogController'; import { InsightsDialogController } from 'sql/workbench/services/insights/common/insightsDialogController';
import { InsightsDialogView } from 'sql/workbench/services/insights/browser/insightsDialogView'; import { InsightsDialogView } from 'sql/workbench/services/insights/browser/insightsDialogView';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { IInsightsConfig } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces'; import { IInsightsConfig } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces';

View File

@@ -10,19 +10,18 @@ import QueryRunner from 'sql/platform/query/common/queryRunner';
import * as Utils from 'sql/platform/connection/common/utils'; import * as Utils from 'sql/platform/connection/common/utils';
import { IInsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogService'; import { IInsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogService';
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
import { resolveQueryFilePath } from '../common/insightsUtils'; import { resolveQueryFilePath } from './insightsUtils';
import { DbCellValue, IDbColumn, QueryExecuteSubsetResult } from 'azdata'; import { DbCellValue, IDbColumn, QueryExecuteSubsetResult } from 'azdata';
import Severity from 'vs/base/common/severity'; import Severity from 'vs/base/common/severity';
import * as types from 'vs/base/common/types'; import * as types from 'vs/base/common/types';
import * as pfs from 'vs/base/node/pfs';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { IFileService } from 'vs/platform/files/common/files';
import { URI } from 'vs/base/common/uri';
export class InsightsDialogController { export class InsightsDialogController {
private _queryRunner: QueryRunner; private _queryRunner: QueryRunner;
@@ -32,14 +31,13 @@ export class InsightsDialogController {
private _rows: DbCellValue[][]; private _rows: DbCellValue[][];
constructor( constructor(
private _model: IInsightsDialogModel, private readonly _model: IInsightsDialogModel,
@INotificationService private _notificationService: INotificationService, @INotificationService private readonly _notificationService: INotificationService,
@IErrorMessageService private _errorMessageService: IErrorMessageService, @IErrorMessageService private readonly _errorMessageService: IErrorMessageService,
@IInstantiationService private _instantiationService: IInstantiationService, @IInstantiationService private readonly _instantiationService: IInstantiationService,
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService, @IConnectionManagementService private readonly _connectionManagementService: IConnectionManagementService,
@IWorkspaceContextService private _workspaceContextService: IWorkspaceContextService, @ILogService private readonly logService: ILogService,
@IConfigurationResolverService private _configurationResolverService: IConfigurationResolverService, @IFileService private readonly fileService: IFileService
@ILogService private logService: ILogService
) { } ) { }
public async update(input: IInsightsConfigDetails, connectionProfile: IConnectionProfile): Promise<void> { public async update(input: IInsightsConfigDetails, connectionProfile: IConnectionProfile): Promise<void> {
@@ -63,9 +61,7 @@ export class InsightsDialogController {
} else if (types.isString(input.queryFile)) { } else if (types.isString(input.queryFile)) {
let filePath: string; let filePath: string;
try { try {
filePath = await resolveQueryFilePath(input.queryFile, filePath = await this._instantiationService.invokeFunction(resolveQueryFilePath, input.queryFile);
this._workspaceContextService,
this._configurationResolverService);
} }
catch (e) { catch (e) {
this._notificationService.notify({ this._notificationService.notify({
@@ -76,8 +72,8 @@ export class InsightsDialogController {
} }
try { try {
let buffer: Buffer = await pfs.readFile(filePath); let buffer = await this.fileService.readFile(URI.file(filePath));
this.createQuery(buffer.toString(), connectionProfile).catch(e => { this.createQuery(buffer.value.toString(), connectionProfile).catch(e => {
this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), e); this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), e);
}); });
} }

View File

@@ -3,11 +3,13 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as pfs from 'vs/base/node/pfs';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IFileService } from 'vs/platform/files/common/files';
import { URI } from 'vs/base/common/uri';
/** /**
* Resolves the given file path using the VS ConfigurationResolver service, replacing macros such as * Resolves the given file path using the VS ConfigurationResolver service, replacing macros such as
@@ -17,13 +19,15 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati
* @param workspaceContextService The workspace context to use for resolving workspace vars * @param workspaceContextService The workspace context to use for resolving workspace vars
* @param configurationResolverService The resolver service to use to resolve the vars * @param configurationResolverService The resolver service to use to resolve the vars
*/ */
export async function resolveQueryFilePath(filePath: string, export async function resolveQueryFilePath(services: ServicesAccessor, filePath: string): Promise<string> {
workspaceContextService: IWorkspaceContextService, if (!filePath) {
configurationResolverService: IConfigurationResolverService): Promise<string> {
if (!filePath || !workspaceContextService || !configurationResolverService) {
return filePath; return filePath;
} }
const workspaceContextService = services.get(IWorkspaceContextService);
const configurationResolverService = services.get(IConfigurationResolverService);
const fileService = services.get(IFileService);
let workspaceFolders: IWorkspaceFolder[] = workspaceContextService.getWorkspace().folders; let workspaceFolders: IWorkspaceFolder[] = workspaceContextService.getWorkspace().folders;
// Resolve the path using each folder in our workspace, or undefined if there aren't any // Resolve the path using each folder in our workspace, or undefined if there aren't any
// (so that non-folder vars such as environment vars still resolve) // (so that non-folder vars such as environment vars still resolve)
@@ -32,7 +36,7 @@ export async function resolveQueryFilePath(filePath: string,
// Just need a single query file so use the first we find that exists // Just need a single query file so use the first we find that exists
for (const path of resolvedFilePaths) { for (const path of resolvedFilePaths) {
if (await pfs.exists(path)) { if (await fileService.exists(URI.file(path))) {
return path; return path;
} }
} }

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { InsightsDialogController } from 'sql/workbench/services/insights/node/insightsDialogController'; import { InsightsDialogController } from 'sql/workbench/services/insights/common/insightsDialogController';
import { InsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogModel'; import { InsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogModel';
import QueryRunner from 'sql/platform/query/common/queryRunner'; import QueryRunner from 'sql/platform/query/common/queryRunner';
import { ConnectionManagementService } from 'sql/platform/connection/common/connectionManagementService'; import { ConnectionManagementService } from 'sql/platform/connection/common/connectionManagementService';
@@ -50,7 +50,6 @@ suite('Insights Dialog Controller Tests', () => {
instMoq.object, instMoq.object,
connMoq.object, connMoq.object,
undefined, undefined,
undefined,
undefined undefined
); );

View File

@@ -12,13 +12,16 @@ import * as path from 'vs/base/common/path';
import * as pfs from 'vs/base/node/pfs'; import * as pfs from 'vs/base/node/pfs';
import { getRandomTestPath } from 'vs/base/test/node/testUtils'; import { getRandomTestPath } from 'vs/base/test/node/testUtils';
import { Workspace, toWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Workspace, toWorkspaceFolder, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService';
import { TestContextService } from 'vs/workbench/test/workbenchTestServices'; import { TestContextService, TestFileService } from 'vs/workbench/test/workbenchTestServices';
import { IExtensionHostDebugParams, IDebugParams, ParsedArgs } from 'vs/platform/environment/common/environment'; import { IExtensionHostDebugParams, IDebugParams, ParsedArgs } from 'vs/platform/environment/common/environment';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { IFileService } from 'vs/platform/files/common/files';
class TestEnvironmentService implements IWorkbenchEnvironmentService { class TestEnvironmentService implements IWorkbenchEnvironmentService {
machineSettingsHome: string; machineSettingsHome: string;
@@ -104,7 +107,19 @@ suite('Insights Utils tests', function () {
new TestContextService(), new TestContextService(),
undefined); undefined);
const resolvedPath = await resolveQueryFilePath(queryFilePath, new TestContextService(), configurationResolverService); const fileService = new class extends TestFileService {
exists(uri: URI): Promise<boolean> {
return pfs.exists(uri.fsPath);
}
};
const instantiationService = new TestInstantiationService();
instantiationService.set(IConfigurationResolverService, configurationResolverService);
instantiationService.set(IWorkspaceContextService, new TestContextService());
instantiationService.set(IFileService, fileService);
const resolvedPath = await instantiationService.invokeFunction(resolveQueryFilePath, queryFilePath);
equal(resolvedPath, queryFilePath); equal(resolvedPath, queryFilePath);
}); });
@@ -123,7 +138,18 @@ suite('Insights Utils tests', function () {
contextService, contextService,
undefined); undefined);
const resolvedPath = await resolveQueryFilePath(path.join('${workspaceRoot}', 'test.sql'), contextService, configurationResolverService); const fileService = new class extends TestFileService {
exists(uri: URI): Promise<boolean> {
return pfs.exists(uri.fsPath);
}
};
const instantiationService = new TestInstantiationService();
instantiationService.set(IConfigurationResolverService, configurationResolverService);
instantiationService.set(IWorkspaceContextService, contextService);
instantiationService.set(IFileService, fileService);
const resolvedPath = await instantiationService.invokeFunction(resolveQueryFilePath, path.join('${workspaceRoot}', 'test.sql'));
equal(resolvedPath, queryFilePath); equal(resolvedPath, queryFilePath);
}); });
@@ -143,8 +169,19 @@ suite('Insights Utils tests', function () {
contextService, contextService,
undefined); undefined);
const fileService = new class extends TestFileService {
exists(uri: URI): Promise<boolean> {
return pfs.exists(uri.fsPath);
}
};
const instantiationService = new TestInstantiationService();
instantiationService.set(IConfigurationResolverService, configurationResolverService);
instantiationService.set(IWorkspaceContextService, contextService);
instantiationService.set(IFileService, fileService);
try { try {
await resolveQueryFilePath(tokenizedPath, contextService, configurationResolverService); await instantiationService.invokeFunction(resolveQueryFilePath, tokenizedPath);
fail('Should have thrown'); fail('Should have thrown');
} }
catch (e) { catch (e) {
@@ -166,8 +203,19 @@ suite('Insights Utils tests', function () {
contextService, contextService,
undefined); undefined);
const fileService = new class extends TestFileService {
exists(uri: URI): Promise<boolean> {
return pfs.exists(uri.fsPath);
}
};
const instantiationService = new TestInstantiationService();
instantiationService.set(IConfigurationResolverService, configurationResolverService);
instantiationService.set(IWorkspaceContextService, contextService);
instantiationService.set(IFileService, fileService);
try { try {
await resolveQueryFilePath(tokenizedPath, contextService, configurationResolverService); await instantiationService.invokeFunction(resolveQueryFilePath, tokenizedPath);
fail('Should have thrown'); fail('Should have thrown');
} }
catch (e) { catch (e) {
@@ -188,7 +236,18 @@ suite('Insights Utils tests', function () {
undefined, undefined,
undefined); undefined);
const resolvedPath = await resolveQueryFilePath(path.join('${env:TEST_PATH}', 'test.sql'), contextService, configurationResolverService); const fileService = new class extends TestFileService {
exists(uri: URI): Promise<boolean> {
return pfs.exists(uri.fsPath);
}
};
const instantiationService = new TestInstantiationService();
instantiationService.set(IConfigurationResolverService, configurationResolverService);
instantiationService.set(IWorkspaceContextService, contextService);
instantiationService.set(IFileService, fileService);
const resolvedPath = await instantiationService.invokeFunction(resolveQueryFilePath, path.join('${env:TEST_PATH}', 'test.sql'));
equal(resolvedPath, queryFilePath); equal(resolvedPath, queryFilePath);
}); });
@@ -205,7 +264,18 @@ suite('Insights Utils tests', function () {
undefined, undefined,
undefined); undefined);
const resolvedPath = await resolveQueryFilePath(path.join('${env:TEST_PATH}', 'test.sql'), contextService, configurationResolverService); const fileService = new class extends TestFileService {
exists(uri: URI): Promise<boolean> {
return pfs.exists(uri.fsPath);
}
};
const instantiationService = new TestInstantiationService();
instantiationService.set(IConfigurationResolverService, configurationResolverService);
instantiationService.set(IWorkspaceContextService, contextService);
instantiationService.set(IFileService, fileService);
const resolvedPath = await instantiationService.invokeFunction(resolveQueryFilePath, path.join('${env:TEST_PATH}', 'test.sql'));
equal(resolvedPath, queryFilePath); equal(resolvedPath, queryFilePath);
}); });
@@ -219,8 +289,19 @@ suite('Insights Utils tests', function () {
undefined, undefined,
undefined); undefined);
const fileService = new class extends TestFileService {
exists(uri: URI): Promise<boolean> {
return pfs.exists(uri.fsPath);
}
};
const instantiationService = new TestInstantiationService();
instantiationService.set(IConfigurationResolverService, configurationResolverService);
instantiationService.set(IWorkspaceContextService, new TestContextService());
instantiationService.set(IFileService, fileService);
try { try {
await resolveQueryFilePath(invalidPath, new TestContextService(), configurationResolverService); await instantiationService.invokeFunction(resolveQueryFilePath, invalidPath);
fail('Should have thrown'); fail('Should have thrown');
} catch (e) { } catch (e) {
done(); done();