mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
MLS R package management bug fixing (#8920)
* MLS R package management bug fixing
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user