From f19f21d5475767054d70c14b056e53070c035999 Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Wed, 3 Jul 2019 13:45:19 -0700 Subject: [PATCH] use file service for insights (#6248) --- .../insights/insightsWidget.component.ts | 14 +-- .../insights/browser/insightsDialogService.ts | 2 +- .../insightsDialogController.ts | 30 +++--- .../services/insights/common/insightsUtils.ts | 16 +-- .../insightsDialogController.test.ts | 3 +- .../test/common/insightsUtils.test.ts | 99 +++++++++++++++++-- 6 files changed, 120 insertions(+), 44 deletions(-) rename src/sql/workbench/services/insights/{node => common}/insightsDialogController.ts (84%) rename src/sql/workbench/services/insights/test/{node => common}/insightsDialogController.test.ts (98%) diff --git a/src/sql/workbench/parts/dashboard/widgets/insights/insightsWidget.component.ts b/src/sql/workbench/parts/dashboard/widgets/insights/insightsWidget.component.ts index bf558da5ee..46fb782d78 100644 --- a/src/sql/workbench/parts/dashboard/widgets/insights/insightsWidget.component.ts +++ b/src/sql/workbench/parts/dashboard/widgets/insights/insightsWidget.component.ts @@ -24,17 +24,16 @@ import { SimpleExecuteResult } from 'azdata'; import { Action } from 'vs/base/common/actions'; import * as types from 'vs/base/common/types'; -import * as pfs from 'vs/base/node/pfs'; import * as nls from 'vs/nls'; 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 { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { toDisposable } from 'vs/base/common/lifecycle'; import { isPromiseCanceledError } from 'vs/base/common/errors'; 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(Extensions.InsightContribution); @@ -75,9 +74,8 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget, @Inject(forwardRef(() => Injector)) private _injector: Injector, @Inject(IInstantiationService) private instantiationService: IInstantiationService, @Inject(IStorageService) private storageService: IStorageService, - @Inject(IWorkspaceContextService) private readonly _workspaceContextService: IWorkspaceContextService, @Inject(IConfigurationService) private readonly _configurationService: IConfigurationService, - @Inject(IConfigurationResolverService) private readonly _configurationResolverService: IConfigurationResolverService + @Inject(IFileService) private readonly fileService: IFileService ) { super(); this.insightConfig = this._config.widget['insights-widget']; @@ -298,11 +296,9 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget, if (types.isStringArray(this.insightConfig.query)) { this.insightConfig.query = this.insightConfig.query.join(' '); } else if (this.insightConfig.queryFile) { - const filePath = await resolveQueryFilePath(this.insightConfig.queryFile, - this._workspaceContextService, - this._configurationResolverService); + const filePath = await this.instantiationService.invokeFunction(resolveQueryFilePath, this.insightConfig.queryFile); - this.insightConfig.query = (await pfs.readFile(filePath)).toString(); + this.insightConfig.query = (await this.fileService.readFile(URI.file(filePath))).value.toString(); } } } diff --git a/src/sql/workbench/services/insights/browser/insightsDialogService.ts b/src/sql/workbench/services/insights/browser/insightsDialogService.ts index 3632266e2c..bb9d2455b4 100644 --- a/src/sql/workbench/services/insights/browser/insightsDialogService.ts +++ b/src/sql/workbench/services/insights/browser/insightsDialogService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 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 { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IInsightsConfig } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces'; diff --git a/src/sql/workbench/services/insights/node/insightsDialogController.ts b/src/sql/workbench/services/insights/common/insightsDialogController.ts similarity index 84% rename from src/sql/workbench/services/insights/node/insightsDialogController.ts rename to src/sql/workbench/services/insights/common/insightsDialogController.ts index b4eed15899..c5f17ceff0 100644 --- a/src/sql/workbench/services/insights/node/insightsDialogController.ts +++ b/src/sql/workbench/services/insights/common/insightsDialogController.ts @@ -10,19 +10,18 @@ import QueryRunner from 'sql/platform/query/common/queryRunner'; import * as Utils from 'sql/platform/connection/common/utils'; import { IInsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogService'; import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService'; -import { resolveQueryFilePath } from '../common/insightsUtils'; +import { resolveQueryFilePath } from './insightsUtils'; import { DbCellValue, IDbColumn, QueryExecuteSubsetResult } from 'azdata'; import Severity from 'vs/base/common/severity'; 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 } from 'vs/platform/workspace/common/workspace'; 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 { IFileService } from 'vs/platform/files/common/files'; +import { URI } from 'vs/base/common/uri'; export class InsightsDialogController { private _queryRunner: QueryRunner; @@ -32,14 +31,13 @@ export class InsightsDialogController { private _rows: DbCellValue[][]; constructor( - private _model: IInsightsDialogModel, - @INotificationService private _notificationService: INotificationService, - @IErrorMessageService private _errorMessageService: IErrorMessageService, - @IInstantiationService private _instantiationService: IInstantiationService, - @IConnectionManagementService private _connectionManagementService: IConnectionManagementService, - @IWorkspaceContextService private _workspaceContextService: IWorkspaceContextService, - @IConfigurationResolverService private _configurationResolverService: IConfigurationResolverService, - @ILogService private logService: ILogService + private readonly _model: IInsightsDialogModel, + @INotificationService private readonly _notificationService: INotificationService, + @IErrorMessageService private readonly _errorMessageService: IErrorMessageService, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IConnectionManagementService private readonly _connectionManagementService: IConnectionManagementService, + @ILogService private readonly logService: ILogService, + @IFileService private readonly fileService: IFileService ) { } public async update(input: IInsightsConfigDetails, connectionProfile: IConnectionProfile): Promise { @@ -63,9 +61,7 @@ export class InsightsDialogController { } else if (types.isString(input.queryFile)) { let filePath: string; try { - filePath = await resolveQueryFilePath(input.queryFile, - this._workspaceContextService, - this._configurationResolverService); + filePath = await this._instantiationService.invokeFunction(resolveQueryFilePath, input.queryFile); } catch (e) { this._notificationService.notify({ @@ -76,8 +72,8 @@ export class InsightsDialogController { } try { - let buffer: Buffer = await pfs.readFile(filePath); - this.createQuery(buffer.toString(), connectionProfile).catch(e => { + let buffer = await this.fileService.readFile(URI.file(filePath)); + this.createQuery(buffer.value.toString(), connectionProfile).catch(e => { this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), e); }); } diff --git a/src/sql/workbench/services/insights/common/insightsUtils.ts b/src/sql/workbench/services/insights/common/insightsUtils.ts index 2e53f126ca..7a05468114 100644 --- a/src/sql/workbench/services/insights/common/insightsUtils.ts +++ b/src/sql/workbench/services/insights/common/insightsUtils.ts @@ -3,11 +3,13 @@ * 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 { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; 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 @@ -17,13 +19,15 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati * @param workspaceContextService The workspace context to use for resolving workspace vars * @param configurationResolverService The resolver service to use to resolve the vars */ -export async function resolveQueryFilePath(filePath: string, - workspaceContextService: IWorkspaceContextService, - configurationResolverService: IConfigurationResolverService): Promise { - if (!filePath || !workspaceContextService || !configurationResolverService) { +export async function resolveQueryFilePath(services: ServicesAccessor, filePath: string): Promise { + if (!filePath) { return filePath; } + const workspaceContextService = services.get(IWorkspaceContextService); + const configurationResolverService = services.get(IConfigurationResolverService); + const fileService = services.get(IFileService); + let workspaceFolders: IWorkspaceFolder[] = workspaceContextService.getWorkspace().folders; // 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) @@ -32,7 +36,7 @@ export async function resolveQueryFilePath(filePath: string, // Just need a single query file so use the first we find that exists for (const path of resolvedFilePaths) { - if (await pfs.exists(path)) { + if (await fileService.exists(URI.file(path))) { return path; } } diff --git a/src/sql/workbench/services/insights/test/node/insightsDialogController.test.ts b/src/sql/workbench/services/insights/test/common/insightsDialogController.test.ts similarity index 98% rename from src/sql/workbench/services/insights/test/node/insightsDialogController.test.ts rename to src/sql/workbench/services/insights/test/common/insightsDialogController.test.ts index 9e89b98906..fef7bc5534 100644 --- a/src/sql/workbench/services/insights/test/node/insightsDialogController.test.ts +++ b/src/sql/workbench/services/insights/test/common/insightsDialogController.test.ts @@ -3,7 +3,7 @@ * 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 QueryRunner from 'sql/platform/query/common/queryRunner'; import { ConnectionManagementService } from 'sql/platform/connection/common/connectionManagementService'; @@ -50,7 +50,6 @@ suite('Insights Dialog Controller Tests', () => { instMoq.object, connMoq.object, undefined, - undefined, undefined ); diff --git a/src/sql/workbench/services/insights/test/common/insightsUtils.test.ts b/src/sql/workbench/services/insights/test/common/insightsUtils.test.ts index 6fd373643e..867c60d943 100644 --- a/src/sql/workbench/services/insights/test/common/insightsUtils.test.ts +++ b/src/sql/workbench/services/insights/test/common/insightsUtils.test.ts @@ -12,13 +12,16 @@ import * as path from 'vs/base/common/path'; import * as pfs from 'vs/base/node/pfs'; 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 { 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 { URI } from 'vs/base/common/uri'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; 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 { machineSettingsHome: string; @@ -104,7 +107,19 @@ suite('Insights Utils tests', function () { new TestContextService(), undefined); - const resolvedPath = await resolveQueryFilePath(queryFilePath, new TestContextService(), configurationResolverService); + const fileService = new class extends TestFileService { + exists(uri: URI): Promise { + 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); }); @@ -123,7 +138,18 @@ suite('Insights Utils tests', function () { contextService, undefined); - const resolvedPath = await resolveQueryFilePath(path.join('${workspaceRoot}', 'test.sql'), contextService, configurationResolverService); + const fileService = new class extends TestFileService { + exists(uri: URI): Promise { + 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); }); @@ -143,8 +169,19 @@ suite('Insights Utils tests', function () { contextService, undefined); + const fileService = new class extends TestFileService { + exists(uri: URI): Promise { + return pfs.exists(uri.fsPath); + } + }; + + const instantiationService = new TestInstantiationService(); + instantiationService.set(IConfigurationResolverService, configurationResolverService); + instantiationService.set(IWorkspaceContextService, contextService); + instantiationService.set(IFileService, fileService); + try { - await resolveQueryFilePath(tokenizedPath, contextService, configurationResolverService); + await instantiationService.invokeFunction(resolveQueryFilePath, tokenizedPath); fail('Should have thrown'); } catch (e) { @@ -166,8 +203,19 @@ suite('Insights Utils tests', function () { contextService, undefined); + const fileService = new class extends TestFileService { + exists(uri: URI): Promise { + return pfs.exists(uri.fsPath); + } + }; + + const instantiationService = new TestInstantiationService(); + instantiationService.set(IConfigurationResolverService, configurationResolverService); + instantiationService.set(IWorkspaceContextService, contextService); + instantiationService.set(IFileService, fileService); + try { - await resolveQueryFilePath(tokenizedPath, contextService, configurationResolverService); + await instantiationService.invokeFunction(resolveQueryFilePath, tokenizedPath); fail('Should have thrown'); } catch (e) { @@ -188,7 +236,18 @@ suite('Insights Utils tests', function () { 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 { + 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); }); @@ -205,7 +264,18 @@ suite('Insights Utils tests', function () { 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 { + 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); }); @@ -219,8 +289,19 @@ suite('Insights Utils tests', function () { undefined, undefined); + const fileService = new class extends TestFileService { + exists(uri: URI): Promise { + return pfs.exists(uri.fsPath); + } + }; + + const instantiationService = new TestInstantiationService(); + instantiationService.set(IConfigurationResolverService, configurationResolverService); + instantiationService.set(IWorkspaceContextService, new TestContextService()); + instantiationService.set(IFileService, fileService); + try { - await resolveQueryFilePath(invalidPath, new TestContextService(), configurationResolverService); + await instantiationService.invokeFunction(resolveQueryFilePath, invalidPath); fail('Should have thrown'); } catch (e) { done();