MLS R package management bug fixing (#8920)

* MLS R package management bug fixing
This commit is contained in:
Leila Lali
2020-01-27 11:10:52 -08:00
committed by GitHub
parent a41073adbf
commit 28fff9ace8
7 changed files with 37 additions and 32 deletions

View File

@@ -59,6 +59,7 @@ export const pythonConfigError = localize('mls.pythonConfigError', "Python execu
export const rConfigError = localize('mls.rConfigError', "R executable is not configured"); export const rConfigError = localize('mls.rConfigError', "R executable is not configured");
export const installingDependencies = localize('mls.installingDependencies', "Installing dependencies ..."); export const installingDependencies = localize('mls.installingDependencies', "Installing dependencies ...");
export const resourceNotFoundError = localize('mls.resourceNotFound', "Could not find the specified resource"); export const resourceNotFoundError = localize('mls.resourceNotFound', "Could not find the specified resource");
export const latestVersion = localize('mls.latestVersion', "Latest");
export function httpGetRequestError(code: number, message: string): string { export function httpGetRequestError(code: number, message: string): string {
return localize('mls.httpGetRequestError', "Package info request failed with error: {0} {1}", return localize('mls.httpGetRequestError', "Package info request failed with error: {0} {1}",
code, code,

View File

@@ -25,13 +25,6 @@ EXEC sp_execute_external_script
OutputDataSet <- as.data.frame(installed.packages()[,c(1,3)])' OutputDataSet <- as.data.frame(installed.packages()[,c(1,3)])'
`; `;
const listRAvailablePackagesQuery = `
EXEC sp_execute_external_script
@language=N'R',
@script=N'
OutputDataSet <- as.data.frame(installed.packages()[,c(1,3)])'
`;
const checkMlInstalledQuery = ` const checkMlInstalledQuery = `
Declare @tablevar table(name NVARCHAR(MAX), min INT, max INT, config_value bit, run_value bit) Declare @tablevar table(name NVARCHAR(MAX), min INT, max INT, config_value bit, run_value bit)
insert into @tablevar(name, min, max, config_value, run_value) exec sp_configure insert into @tablevar(name, min, max, config_value, run_value) exec sp_configure
@@ -82,14 +75,6 @@ export class QueryRunner {
return this.getPackages(connection, listRPackagesQuery); return this.getPackages(connection, listRPackagesQuery);
} }
/**
* Returns python packages installed in SQL server instance
* @param connection SQL Connection
*/
public async getRAvailablePackages(connection: azdata.connection.ConnectionProfile): Promise<nbExtensionApis.IPackageDetails[]> {
return this.getPackages(connection, listRAvailablePackagesQuery);
}
private async getPackages(connection: azdata.connection.ConnectionProfile, script: string): Promise<nbExtensionApis.IPackageDetails[]> { private async getPackages(connection: azdata.connection.ConnectionProfile, script: string): Promise<nbExtensionApis.IPackageDetails[]> {
let packages: nbExtensionApis.IPackageDetails[] = []; let packages: nbExtensionApis.IPackageDetails[] = [];
let result: azdata.SimpleExecuteResult | undefined = undefined; let result: azdata.SimpleExecuteResult | undefined = undefined;

View File

@@ -7,5 +7,7 @@
"requiredRPackages": [ "requiredRPackages": [
{ "name": "RODBCext", "repository": "https://cran.microsoft.com" }, { "name": "RODBCext", "repository": "https://cran.microsoft.com" },
{ "name": "sqlmlutils", "fileName": "sqlmlutils_0.7.1.zip", "downloadUrl": "https://github.com/microsoft/sqlmlutils/blob/master/R/dist/sqlmlutils_0.7.1.zip?raw=true"} { "name": "sqlmlutils", "fileName": "sqlmlutils_0.7.1.zip", "downloadUrl": "https://github.com/microsoft/sqlmlutils/blob/master/R/dist/sqlmlutils_0.7.1.zip?raw=true"}
] ],
"rPackagesRepository": "https://cran.r-project.org"
} }

View File

@@ -30,7 +30,7 @@ export class Config {
* Loads the config values * Loads the config values
*/ */
public async load(): Promise<void> { public async load(): Promise<void> {
const rawConfig = await fs.readFile(path.join(this._root, 'src', 'configurations', configFileName)); const rawConfig = await fs.readFile(path.join(this._root, 'out', 'configurations', configFileName));
this._configValues = JSON.parse(rawConfig.toString()); this._configValues = JSON.parse(rawConfig.toString());
} }
@@ -48,6 +48,13 @@ export class Config {
return this._configValues.requiredRPackages; return this._configValues.requiredRPackages;
} }
/**
* Returns r packages repository
*/
public get rPackagesRepository(): string {
return this._configValues.rPackagesRepository;
}
/** /**
* Returns python path from user settings * Returns python path from user settings
*/ */

View File

@@ -38,7 +38,7 @@ export class PackageManager {
private _config: Config, private _config: Config,
private _httpClient: HttpClient) { private _httpClient: HttpClient) {
this._sqlPythonPackagePackageManager = new SqlPythonPackageManageProvider(this._outputChannel, this._apiWrapper, this._queryRunner, this._processService, this._config, this._httpClient); this._sqlPythonPackagePackageManager = new SqlPythonPackageManageProvider(this._outputChannel, this._apiWrapper, this._queryRunner, this._processService, this._config, this._httpClient);
this._sqlRPackageManager = new SqlRPackageManageProvider(this._outputChannel, this._apiWrapper, this._queryRunner, this._processService, this._config); this._sqlRPackageManager = new SqlRPackageManageProvider(this._outputChannel, this._apiWrapper, this._queryRunner, this._processService, this._config, this._httpClient);
} }
/** /**
@@ -205,7 +205,7 @@ export class PackageManager {
output = await this._processService.executeBufferedCommand(cmd, this._outputChannel); output = await this._processService.executeBufferedCommand(cmd, this._outputChannel);
} else if (model.repository) { } else if (model.repository) {
cmd = `"${this._rExecutable}" -e "install.packages('${model.name}', repos='${model.repository}')"`; cmd = `"${this._rExecutable}" -e "install.packages('${model.name}', repos='${model.repository}')"`;
output = output + await this._processService.executeBufferedCommand(cmd, this._outputChannel); output = await this._processService.executeBufferedCommand(cmd, this._outputChannel);
} }
return output; return output;
} }

View File

@@ -12,6 +12,8 @@ import { ApiWrapper } from '../common/apiWrapper';
import { ProcessService } from '../common/processService'; import { ProcessService } from '../common/processService';
import { Config } from '../configurations/config'; import { Config } from '../configurations/config';
import { SqlPackageManageProviderBase, ScriptMode } from './SqlPackageManageProviderBase'; import { SqlPackageManageProviderBase, ScriptMode } from './SqlPackageManageProviderBase';
import { HttpClient } from '../common/httpClient';
import * as constants from '../common/constants';
@@ -30,7 +32,8 @@ export class SqlRPackageManageProvider extends SqlPackageManageProviderBase impl
apiWrapper: ApiWrapper, apiWrapper: ApiWrapper,
private _queryRunner: QueryRunner, private _queryRunner: QueryRunner,
private _processService: ProcessService, private _processService: ProcessService,
private _config: Config) { private _config: Config,
private _httpClient: HttpClient) {
super(apiWrapper); super(apiWrapper);
} }
@@ -73,6 +76,9 @@ export class SqlRPackageManageProvider extends SqlPackageManageProviderBase impl
'formals(quit)$save <- formals(q)$save <- "no"', 'formals(quit)$save <- formals(q)$save <- "no"',
'library(sqlmlutils)', 'library(sqlmlutils)',
`connection <- connectionInfo(${connectionParts})`, `connection <- connectionInfo(${connectionParts})`,
`r = getOption("repos")`,
`r["CRAN"] = "${this._config.rPackagesRepository}"`,
`options(repos = r)`,
`pkgs <- c("${packageDetails.name}")`, `pkgs <- c("${packageDetails.name}")`,
`${rCommandScript}(connectionString = connection, pkgs, scope = "PUBLIC")`, `${rCommandScript}(connectionString = connection, pkgs, scope = "PUBLIC")`,
'q()' 'q()'
@@ -93,6 +99,10 @@ export class SqlRPackageManageProvider extends SqlPackageManageProviderBase impl
return false; return false;
} }
private getPackageLink(packageName: string): string {
return `${this._config.rPackagesRepository}/web/packages/${packageName}`;
}
/** /**
* Returns package overview for given name * Returns package overview for given name
* @param packageName Package Name * @param packageName Package Name
@@ -100,13 +110,11 @@ export class SqlRPackageManageProvider extends SqlPackageManageProviderBase impl
protected async fetchPackage(packageName: string): Promise<nbExtensionApis.IPackageOverview> { protected async fetchPackage(packageName: string): Promise<nbExtensionApis.IPackageOverview> {
let packagePreview: nbExtensionApis.IPackageOverview = { let packagePreview: nbExtensionApis.IPackageOverview = {
name: packageName, name: packageName,
versions: [], versions: [constants.latestVersion],
summary: '' summary: ''
}; };
let connection = await this.getCurrentConnection();
let availablePackages = await this._queryRunner.getRAvailablePackages(connection); await this._httpClient.fetch(this.getPackageLink(packageName));
let versions = availablePackages.filter(x => x.name === packageName).map(x => x.version);
packagePreview.versions = versions;
return packagePreview; return packagePreview;
} }
} }

View File

@@ -247,14 +247,14 @@ describe('SQL R Package Manager', () => {
let testContext = createContext(); let testContext = createContext();
let packagePreview = { let packagePreview = {
'name': 'a-name', 'name': 'a-name',
'versions': ['1.1.2'], 'versions': ['Latest'],
'summary': '' 'summary': ''
}; };
let allPackages = [{
'name': 'a-name', testContext.httpClient.setup(x => x.fetch(TypeMoq.It.isAny())).returns(() => {
'version': '1.1.2' return Promise.resolve(``);
}]; });
testContext.queryRunner.setup(x => x.getRAvailablePackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(allPackages));
let provider = createProvider(testContext); let provider = createProvider(testContext);
let actual = await provider.getPackageOverview('a-name'); let actual = await provider.getPackageOverview('a-name');
@@ -301,11 +301,13 @@ describe('SQL R Package Manager', () => {
function createProvider(testContext: TestContext): SqlRPackageManageProvider { function createProvider(testContext: TestContext): SqlRPackageManageProvider {
testContext.config.setup(x => x.rExecutable).returns(() => 'r'); testContext.config.setup(x => x.rExecutable).returns(() => 'r');
testContext.config.setup(x => x.rPackagesRepository).returns(() => 'http://cran.r-project.org');
return new SqlRPackageManageProvider( return new SqlRPackageManageProvider(
testContext.outputChannel, testContext.outputChannel,
testContext.apiWrapper.object, testContext.apiWrapper.object,
testContext.queryRunner.object, testContext.queryRunner.object,
testContext.processService.object, testContext.processService.object,
testContext.config.object); testContext.config.object,
testContext.httpClient.object);
} }
}); });