mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
Swapping Record usage to Map in SQL Projects (#22758)
* Changing SqlCmdVars from Record to Map * Converting the rest * Updating tests * more cleanup * Updating test to use new test creation API
This commit is contained in:
@@ -39,11 +39,11 @@ export class DacFxTestService implements mssql.IDacFxService {
|
||||
this.dacfxResult.operationId = importOperationId;
|
||||
return Promise.resolve(this.dacfxResult);
|
||||
}
|
||||
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>): Promise<mssql.DacFxResult> {
|
||||
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>): Promise<mssql.DacFxResult> {
|
||||
this.dacfxResult.operationId = deployOperationId;
|
||||
return Promise.resolve(this.dacfxResult);
|
||||
}
|
||||
generateDeployScript(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>): Promise<mssql.DacFxResult> {
|
||||
generateDeployScript(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>): Promise<mssql.DacFxResult> {
|
||||
this.dacfxResult.operationId = generateScript;
|
||||
return Promise.resolve(this.dacfxResult);
|
||||
}
|
||||
@@ -90,7 +90,7 @@ export class DacFxTestService implements mssql.IDacFxService {
|
||||
return Promise.resolve({ containsCreateTableStatement: true });
|
||||
}
|
||||
|
||||
savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Record<string, string>): Thenable<azdata.ResultStatus> {
|
||||
savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Map<string, string>): Thenable<azdata.ResultStatus> {
|
||||
return Promise.resolve(this.dacfxResult);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,7 +515,7 @@ export interface DeployParams {
|
||||
packageFilePath: string;
|
||||
databaseName: string;
|
||||
upgradeExisting: boolean;
|
||||
sqlCommandVariableValues?: Record<string, string>;
|
||||
sqlCommandVariableValues?: Map<string, string>;
|
||||
deploymentOptions?: mssql.DeploymentOptions;
|
||||
ownerUri: string;
|
||||
taskExecutionMode: TaskExecutionMode;
|
||||
@@ -524,7 +524,7 @@ export interface DeployParams {
|
||||
export interface GenerateDeployScriptParams {
|
||||
packageFilePath: string;
|
||||
databaseName: string;
|
||||
sqlCommandVariableValues?: Record<string, string>;
|
||||
sqlCommandVariableValues?: Map<string, string>;
|
||||
deploymentOptions?: mssql.DeploymentOptions
|
||||
ownerUri: string;
|
||||
taskExecutionMode: TaskExecutionMode;
|
||||
@@ -555,7 +555,7 @@ export interface SavePublishProfileParams {
|
||||
profilePath: string;
|
||||
databaseName: string;
|
||||
connectionString: string;
|
||||
sqlCommandVariableValues?: Record<string, string>;
|
||||
sqlCommandVariableValues?: Map<string, string>;
|
||||
deploymentOptions?: mssql.DeploymentOptions;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,12 +54,12 @@ export class DacFxService extends BaseService implements mssql.IDacFxService {
|
||||
return this.runWithErrorHandling(contracts.ExtractRequest.type, params);
|
||||
}
|
||||
|
||||
public async deployDacpac(packageFilePath: string, targetDatabaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<mssql.DacFxResult> {
|
||||
public async deployDacpac(packageFilePath: string, targetDatabaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<mssql.DacFxResult> {
|
||||
const params: contracts.DeployParams = { packageFilePath: packageFilePath, databaseName: targetDatabaseName, upgradeExisting: upgradeExisting, sqlCommandVariableValues: sqlCommandVariableValues, deploymentOptions: deploymentOptions, ownerUri: ownerUri, taskExecutionMode: taskExecutionMode };
|
||||
return this.runWithErrorHandling(contracts.DeployRequest.type, params);
|
||||
}
|
||||
|
||||
public async generateDeployScript(packageFilePath: string, targetDatabaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<mssql.DacFxResult> {
|
||||
public async generateDeployScript(packageFilePath: string, targetDatabaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<mssql.DacFxResult> {
|
||||
const params: contracts.GenerateDeployScriptParams = { packageFilePath: packageFilePath, databaseName: targetDatabaseName, sqlCommandVariableValues: sqlCommandVariableValues, deploymentOptions: deploymentOptions, ownerUri: ownerUri, taskExecutionMode: taskExecutionMode };
|
||||
return this.runWithErrorHandling(contracts.GenerateDeployScriptRequest.type, params);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ export class DacFxService extends BaseService implements mssql.IDacFxService {
|
||||
return this.runWithErrorHandling(contracts.ParseTSqlScriptRequest.type, params);
|
||||
}
|
||||
|
||||
public async savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<azdata.ResultStatus> {
|
||||
public async savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<azdata.ResultStatus> {
|
||||
const params: contracts.SavePublishProfileParams = { profilePath, databaseName, connectionString, sqlCommandVariableValues, deploymentOptions };
|
||||
return this.runWithErrorHandling(contracts.SavePublishProfileRequest.type, params);
|
||||
}
|
||||
|
||||
6
extensions/mssql/src/mssql.d.ts
vendored
6
extensions/mssql/src/mssql.d.ts
vendored
@@ -236,13 +236,13 @@ declare module 'mssql' {
|
||||
importBacpac(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<DacFxResult>;
|
||||
extractDacpac(databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<DacFxResult>;
|
||||
createProjectFromDatabase(databaseName: string, targetFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, extractTarget: ExtractTarget, taskExecutionMode: azdata.TaskExecutionMode, includePermissions?: boolean): Thenable<DacFxResult>;
|
||||
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
generateDeployScript(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
generateDeployScript(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
generateDeployPlan(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<GenerateDeployPlanResult>;
|
||||
getOptionsFromProfile(profilePath: string): Thenable<DacFxOptionsResult>;
|
||||
validateStreamingJob(packageFilePath: string, createStreamingJobTsql: string): Thenable<ValidateStreamingJobResult>;
|
||||
parseTSqlScript(filePath: string, databaseSchemaProvider: string): Thenable<ParseTSqlScriptResult>;
|
||||
savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: DeploymentOptions): Thenable<azdata.ResultStatus>;
|
||||
savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: DeploymentOptions): Thenable<azdata.ResultStatus>;
|
||||
}
|
||||
|
||||
export interface DacFxResult extends azdata.ResultStatus {
|
||||
|
||||
@@ -170,8 +170,8 @@ export function systemDatabaseToString(systemDb: mssql.SystemDatabase): string {
|
||||
* @param xmlDoc xml doc to read SQLCMD variables from. Format must be the same that sqlproj and publish profiles use
|
||||
* @param publishProfile true if reading from publish profile
|
||||
*/
|
||||
export function readSqlCmdVariables(xmlDoc: Document, publishProfile: boolean): Record<string, string> {
|
||||
let sqlCmdVariables: Record<string, string> = {};
|
||||
export function readSqlCmdVariables(xmlDoc: Document, publishProfile: boolean): Map<string, string> {
|
||||
let sqlCmdVariables: Map<string, string> = new Map();
|
||||
for (let i = 0; i < xmlDoc.documentElement.getElementsByTagName(constants.SqlCmdVariable)?.length; i++) {
|
||||
const sqlCmdVar = xmlDoc.documentElement.getElementsByTagName(constants.SqlCmdVariable)[i];
|
||||
const varName = sqlCmdVar.getAttribute(constants.Include)!;
|
||||
@@ -181,11 +181,11 @@ export function readSqlCmdVariables(xmlDoc: Document, publishProfile: boolean):
|
||||
// are local variable values you can set in VS in the properties. Since we don't support that in ADS, only DefaultValue is supported for sqlproj.
|
||||
if (!publishProfile && sqlCmdVar.getElementsByTagName(constants.DefaultValue)[0] !== undefined) {
|
||||
// project file path
|
||||
sqlCmdVariables[varName] = sqlCmdVar.getElementsByTagName(constants.DefaultValue)[0].childNodes[0].nodeValue!;
|
||||
sqlCmdVariables.set(varName, sqlCmdVar.getElementsByTagName(constants.DefaultValue)[0].childNodes[0].nodeValue!);
|
||||
}
|
||||
else {
|
||||
// profile path
|
||||
sqlCmdVariables[varName] = sqlCmdVar.getElementsByTagName(constants.Value)[0].childNodes[0].nodeValue!;
|
||||
sqlCmdVariables.set(varName, sqlCmdVar.getElementsByTagName(constants.Value)[0].childNodes[0].nodeValue!);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,17 +225,17 @@ export class ProjectsController {
|
||||
if (projectTypeId === constants.edgeSqlDatabaseProjectTypeId) {
|
||||
const project = await Project.openProject(newProjFilePath);
|
||||
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.table), 'DataTable.sql', { 'OBJECT_NAME': 'DataTable' });
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.dataSource), 'EdgeHubInputDataSource.sql', { 'OBJECT_NAME': 'EdgeHubInputDataSource', 'LOCATION': 'edgehub://' });
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.dataSource), 'SqlOutputDataSource.sql', { 'OBJECT_NAME': 'SqlOutputDataSource', 'LOCATION': 'sqlserver://tcp:.,1433' });
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.fileFormat), 'StreamFileFormat.sql', { 'OBJECT_NAME': 'StreamFileFormat' });
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.externalStream), 'EdgeHubInputStream.sql', { 'OBJECT_NAME': 'EdgeHubInputStream', 'DATA_SOURCE_NAME': 'EdgeHubInputDataSource', 'LOCATION': 'input', 'OPTIONS': ',\n\tFILE_FORMAT = StreamFileFormat' });
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.externalStream), 'SqlOutputStream.sql', { 'OBJECT_NAME': 'SqlOutputStream', 'DATA_SOURCE_NAME': 'SqlOutputDataSource', 'LOCATION': 'TSQLStreaming.dbo.DataTable', 'OPTIONS': '' });
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.externalStreamingJob), 'EdgeStreamingJob.sql', { 'OBJECT_NAME': 'EdgeStreamingJob' });
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.table), 'DataTable.sql', new Map([['OBJECT_NAME', 'DataTable']]));
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.dataSource), 'EdgeHubInputDataSource.sql', new Map([['OBJECT_NAME', 'EdgeHubInputDataSource'], ['LOCATION', 'edgehub://']]));
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.dataSource), 'SqlOutputDataSource.sql', new Map([['OBJECT_NAME', 'SqlOutputDataSource'], ['LOCATION', 'sqlserver://tcp:.,1433']]));
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.fileFormat), 'StreamFileFormat.sql', new Map([['OBJECT_NAME', 'StreamFileFormat']]));
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.externalStream), 'EdgeHubInputStream.sql', new Map([['OBJECT_NAME', 'EdgeHubInputStream'], ['DATA_SOURCE_NAME', 'EdgeHubInputDataSource'], ['LOCATION', 'input'], ['OPTIONS', ',\n\tFILE_FORMAT = StreamFileFormat']]));
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.externalStream), 'SqlOutputStream.sql', new Map([['OBJECT_NAME', 'SqlOutputStream'], ['DATA_SOURCE_NAME', 'SqlOutputDataSource'], ['LOCATION', 'TSQLStreaming.dbo.DataTable'], ['OPTIONS', '']]));
|
||||
await this.addFileToProjectFromTemplate(project, templates.get(ItemType.externalStreamingJob), 'EdgeStreamingJob.sql', new Map([['OBJECT_NAME', 'EdgeStreamingJob']]));
|
||||
}
|
||||
}
|
||||
|
||||
private async addFileToProjectFromTemplate(project: ISqlProject, itemType: templates.ProjectScriptType, relativePath: string, expansionMacros: Record<string, string>): Promise<string> {
|
||||
private async addFileToProjectFromTemplate(project: ISqlProject, itemType: templates.ProjectScriptType, relativePath: string, expansionMacros: Map<string, string>): Promise<string> {
|
||||
const newFileText = templates.macroExpansion(itemType.templateScript, expansionMacros);
|
||||
const absolutePath = path.join(project.projectFolderPath, relativePath)
|
||||
await utils.ensureFileExists(absolutePath, newFileText);
|
||||
@@ -587,7 +587,7 @@ export class ProjectsController {
|
||||
const timeToPublish = actionEndTime - actionStartTime;
|
||||
telemetryProps.actionDuration = timeToPublish.toString();
|
||||
telemetryProps.totalDuration = (actionEndTime - buildStartTime).toString();
|
||||
telemetryProps.sqlcmdVariablesCount = Object.keys(project.sqlCmdVariables).length.toString();
|
||||
telemetryProps.sqlcmdVariablesCount = project.sqlCmdVariables.size.toString();
|
||||
telemetryProps.projectTargetPLatform = project.getProjectTargetVersion();
|
||||
|
||||
const currentPublishIndex = this.publishInfo.findIndex(d => d.startDate === currentPublishTimeInfo);
|
||||
@@ -750,7 +750,7 @@ export class ProjectsController {
|
||||
}
|
||||
|
||||
try {
|
||||
const absolutePath = await this.addFileToProjectFromTemplate(project, itemType, relativeFilePath, { 'OBJECT_NAME': itemObjectName });
|
||||
const absolutePath = await this.addFileToProjectFromTemplate(project, itemType, relativeFilePath, new Map([['OBJECT_NAME', itemObjectName]]));
|
||||
|
||||
TelemetryReporter.createActionEvent(TelemetryViews.ProjectTree, TelemetryActions.addItemFromTree)
|
||||
.withAdditionalProperties(telemetryProps)
|
||||
@@ -957,7 +957,7 @@ export class ProjectsController {
|
||||
const node = context.element as SqlCmdVariableTreeItem;
|
||||
const project = await this.getProjectFromContext(node);
|
||||
const variableName = node.friendlyName;
|
||||
const originalValue = project.sqlCmdVariables[variableName];
|
||||
const originalValue = project.sqlCmdVariables.get(variableName);
|
||||
|
||||
const newValue = await vscode.window.showInputBox(
|
||||
{
|
||||
@@ -986,7 +986,7 @@ export class ProjectsController {
|
||||
title: constants.enterNewSqlCmdVariableName,
|
||||
ignoreFocusOut: true,
|
||||
validateInput: (value) => {
|
||||
return this.sqlCmdVariableNameAlreadyExists(value, project) ? constants.sqlcmdVariableAlreadyExists : undefined;
|
||||
return project.sqlCmdVariables.has(value) ? constants.sqlcmdVariableAlreadyExists : undefined;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1008,10 +1008,6 @@ export class ProjectsController {
|
||||
this.refreshProjectsTree(context);
|
||||
}
|
||||
|
||||
private sqlCmdVariableNameAlreadyExists(newVariableName: string, project: Project): boolean {
|
||||
return Object.keys(project.sqlCmdVariables).findIndex(v => v === newVariableName) !== -1;
|
||||
}
|
||||
|
||||
private getDatabaseReference(project: Project, context: BaseProjectTreeItem): IDatabaseReferenceProjectEntry | undefined {
|
||||
const databaseReference = context as DatabaseReferenceTreeItem;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export class PublishDatabaseDialog {
|
||||
private existingServerSelected: boolean = true;
|
||||
private connectionId: string | undefined;
|
||||
private connectionIsDataSource: boolean | undefined;
|
||||
private sqlCmdVars: Record<string, string> | undefined;
|
||||
private sqlCmdVars: Map<string, string> | undefined;
|
||||
private deploymentOptions: DeploymentOptions | undefined;
|
||||
private profileUsed: boolean = false;
|
||||
private serverName: string | undefined;
|
||||
@@ -70,7 +70,7 @@ export class PublishDatabaseDialog {
|
||||
public publishToContainer: ((proj: Project, profile: IPublishToDockerSettings) => any) | undefined;
|
||||
public generateScript: ((proj: Project, profile: ISqlProjectPublishSettings) => any) | undefined;
|
||||
public readPublishProfile: ((profileUri: vscode.Uri) => any) | undefined;
|
||||
public savePublishProfile: ((profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: DeploymentOptions) => any) | undefined;
|
||||
public savePublishProfile: ((profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: DeploymentOptions) => any) | undefined;
|
||||
|
||||
constructor(private project: Project) {
|
||||
this.dialog = utils.getAzdataApi()!.window.createModelViewDialog(constants.publishDialogName, 'sqlProjectPublishDialog');
|
||||
@@ -190,7 +190,7 @@ export class PublishDatabaseDialog {
|
||||
});
|
||||
|
||||
// add SQLCMD variables table if the project has any
|
||||
if (Object.keys(this.project.sqlCmdVariables).length > 0) {
|
||||
if (this.project.sqlCmdVariables.size > 0) {
|
||||
this.formBuilder.addFormItem(this.sqlCmdVariablesFormComponentGroup);
|
||||
}
|
||||
|
||||
@@ -311,9 +311,9 @@ export class PublishDatabaseDialog {
|
||||
return this.deploymentOptions;
|
||||
}
|
||||
|
||||
public getSqlCmdVariablesForPublish(): Record<string, string> {
|
||||
public getSqlCmdVariablesForPublish(): Map<string, string> {
|
||||
// get SQLCMD variables from table
|
||||
let sqlCmdVariables = { ...this.sqlCmdVars };
|
||||
let sqlCmdVariables = this.sqlCmdVars ?? new Map();
|
||||
return sqlCmdVariables;
|
||||
}
|
||||
|
||||
@@ -681,9 +681,9 @@ export class PublishDatabaseDialog {
|
||||
}).component();
|
||||
|
||||
table.onDataChanged(() => {
|
||||
this.sqlCmdVars = {};
|
||||
this.sqlCmdVars = new Map();
|
||||
table.dataValues?.forEach((row) => {
|
||||
(<Record<string, string>>this.sqlCmdVars)[<string>row[0].value] = <string>row[1].value;
|
||||
this.sqlCmdVars?.set(<string>row[0].value, <string>row[1].value);
|
||||
});
|
||||
|
||||
this.updateRevertSqlCmdVarsButtonState();
|
||||
@@ -708,7 +708,7 @@ export class PublishDatabaseDialog {
|
||||
loadSqlCmdVarsButton.onDidClick(async () => {
|
||||
for (const varName in this.sqlCmdVars) {
|
||||
|
||||
this.sqlCmdVars[varName] = this.getDefaultSqlCmdValue(varName);
|
||||
this.sqlCmdVars.set(varName, this.getDefaultSqlCmdValue(varName));
|
||||
}
|
||||
|
||||
const data = this.convertSqlCmdVarsToTableFormat(this.sqlCmdVars!);
|
||||
@@ -729,7 +729,7 @@ export class PublishDatabaseDialog {
|
||||
* @returns value defined in the sqlproj file, or blank string if not defined
|
||||
*/
|
||||
private getDefaultSqlCmdValue(varName: string): string {
|
||||
return Object.keys(this.project.sqlCmdVariables).includes(varName) ? this.project.sqlCmdVariables[varName] : '';
|
||||
return this.project.sqlCmdVariables.get(varName) ?? '';
|
||||
}
|
||||
|
||||
private createSelectConnectionButton(view: azdataType.ModelView): azdataType.Component {
|
||||
@@ -804,18 +804,18 @@ export class PublishDatabaseDialog {
|
||||
// set options coming from the publish profiles to deployment options
|
||||
this.setDeploymentOptions(result.options);
|
||||
|
||||
if (Object.keys(result.sqlCmdVariables).length) {
|
||||
if ((<Map<string, string>>result.sqlCmdVariables).size) {
|
||||
// add SQLCMD Variables table if it wasn't there before and the profile had sqlcmd variables
|
||||
if (Object.keys(this.project.sqlCmdVariables).length === 0 && Object.keys(<Record<string, string>>this.sqlCmdVars).length === 0) {
|
||||
if (this.project.sqlCmdVariables.size === 0 && this.sqlCmdVars?.size === 0) {
|
||||
this.formBuilder?.addFormItem(<azdataType.FormComponentGroup>this.sqlCmdVariablesFormComponentGroup);
|
||||
}
|
||||
} else if (Object.keys(this.project.sqlCmdVariables).length === 0) {
|
||||
} else if (this.project.sqlCmdVariables.size === 0) {
|
||||
// remove the table if there are no SQLCMD variables in the project and loaded profile
|
||||
this.formBuilder?.removeFormItem(<azdataType.FormComponentGroup>this.sqlCmdVariablesFormComponentGroup);
|
||||
}
|
||||
|
||||
for (let key in result.sqlCmdVariables) {
|
||||
(<Record<string, string>>this.sqlCmdVars)[key] = result.sqlCmdVariables[key];
|
||||
this.sqlCmdVars?.set(key, result.sqlCmdVariableColumn.get(key));
|
||||
}
|
||||
|
||||
this.updateRevertSqlCmdVarsButtonState();
|
||||
@@ -880,10 +880,10 @@ export class PublishDatabaseDialog {
|
||||
return saveProfileAsButton;
|
||||
}
|
||||
|
||||
private convertSqlCmdVarsToTableFormat(sqlCmdVars: Record<string, string>): azdataType.DeclarativeTableCellValue[][] {
|
||||
private convertSqlCmdVarsToTableFormat(sqlCmdVars: Map<string, string>): azdataType.DeclarativeTableCellValue[][] {
|
||||
let data = [];
|
||||
for (let key in sqlCmdVars) {
|
||||
data.push([{ value: key }, { value: sqlCmdVars[key] }]);
|
||||
data.push([{ value: key }, { value: sqlCmdVars.get(key)! }]);
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -901,7 +901,7 @@ export class PublishDatabaseDialog {
|
||||
let revertButtonEnabled = false;
|
||||
|
||||
for (const varName in this.sqlCmdVars) {
|
||||
if (this.sqlCmdVars![varName] !== this.getDefaultSqlCmdValue(varName)) {
|
||||
if (this.sqlCmdVars!.get(varName) !== this.getDefaultSqlCmdValue(varName)) {
|
||||
revertButtonEnabled = true;
|
||||
break;
|
||||
}
|
||||
@@ -936,7 +936,7 @@ export class PublishDatabaseDialog {
|
||||
|
||||
private allSqlCmdVariablesFilled(): boolean {
|
||||
for (let key in this.sqlCmdVars) {
|
||||
if (this.sqlCmdVars[key] === '' || this.sqlCmdVars[key] === undefined) {
|
||||
if (this.sqlCmdVars.get(key) === '' || this.sqlCmdVars.get(key) === undefined) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ export async function getPublishDatabaseSettings(project: ISqlProject, promptFor
|
||||
// project file (if they exist)
|
||||
let sqlCmdVariables = Object.assign({}, project.sqlCmdVariables, publishProfile?.sqlCmdVariables);
|
||||
|
||||
if (Object.keys(sqlCmdVariables).length > 0) {
|
||||
if (sqlCmdVariables.size > 0) {
|
||||
// Continually loop here, allowing the user to modify SQLCMD variables one
|
||||
// at a time until they're done (either by selecting the "Done" option or
|
||||
// escaping out of the quick pick dialog). Users can modify each variable
|
||||
@@ -173,7 +173,7 @@ export async function getPublishDatabaseSettings(project: ISqlProject, promptFor
|
||||
const quickPickItems = Object.keys(sqlCmdVariables).map(key => {
|
||||
return {
|
||||
label: key,
|
||||
description: sqlCmdVariables[key],
|
||||
description: sqlCmdVariables.get(key),
|
||||
key: key
|
||||
} as vscode.QuickPickItem & { key?: string, isResetAllVars?: boolean, isDone?: boolean };
|
||||
});
|
||||
@@ -192,12 +192,12 @@ export async function getPublishDatabaseSettings(project: ISqlProject, promptFor
|
||||
const newValue = await vscode.window.showInputBox(
|
||||
{
|
||||
title: constants.enterNewValueForVar(sqlCmd.key),
|
||||
value: sqlCmdVariables[sqlCmd.key],
|
||||
value: sqlCmdVariables.get(sqlCmd.key),
|
||||
ignoreFocusOut: true
|
||||
}
|
||||
);
|
||||
if (newValue) {
|
||||
sqlCmdVariables[sqlCmd.key] = newValue;
|
||||
sqlCmdVariables.set(sqlCmd.key, newValue);
|
||||
}
|
||||
} else if (sqlCmd.isResetAllVars) {
|
||||
sqlCmdVariables = Object.assign({}, project.sqlCmdVariables, publishProfile?.sqlCmdVariables);
|
||||
|
||||
@@ -16,7 +16,7 @@ export interface ISqlProjectPublishSettings {
|
||||
databaseName: string;
|
||||
serverName: string;
|
||||
connectionUri: string;
|
||||
sqlCmdVariables?: Record<string, string>;
|
||||
sqlCmdVariables?: Map<string, string>;
|
||||
deploymentOptions?: DeploymentOptions;
|
||||
profileUsed?: boolean;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export class Project implements ISqlProject {
|
||||
private _folders: FileProjectEntry[] = [];
|
||||
private _dataSources: DataSource[] = [];
|
||||
private _databaseReferences: IDatabaseReferenceProjectEntry[] = [];
|
||||
private _sqlCmdVariables: Record<string, string> = {};
|
||||
private _sqlCmdVariables: Map<string, string> = new Map();
|
||||
private _preDeployScripts: FileProjectEntry[] = [];
|
||||
private _postDeployScripts: FileProjectEntry[] = [];
|
||||
private _noneDeployScripts: FileProjectEntry[] = [];
|
||||
@@ -97,7 +97,7 @@ export class Project implements ISqlProject {
|
||||
return this._databaseReferences;
|
||||
}
|
||||
|
||||
public get sqlCmdVariables(): Record<string, string> {
|
||||
public get sqlCmdVariables(): Map<string, string> {
|
||||
return this._sqlCmdVariables;
|
||||
}
|
||||
|
||||
@@ -267,10 +267,10 @@ export class Project implements ISqlProject {
|
||||
throw new Error(constants.errorReadingProject(constants.sqlCmdVariables, this.projectFilePath, sqlcmdVariablesResult.errorMessage));
|
||||
}
|
||||
|
||||
this._sqlCmdVariables = {};
|
||||
this._sqlCmdVariables = new Map();
|
||||
|
||||
for (const variable of sqlcmdVariablesResult.sqlCmdVariables) {
|
||||
this._sqlCmdVariables[variable.varName] = variable.defaultValue; // store the default value that's specified in the .sqlproj
|
||||
this._sqlCmdVariables.set(variable.varName, variable.defaultValue); // store the default value that's specified in the .sqlproj
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ export class Project implements ISqlProject {
|
||||
private resetProject(): void {
|
||||
this._files = [];
|
||||
this._databaseReferences = [];
|
||||
this._sqlCmdVariables = {};
|
||||
this._sqlCmdVariables = new Map();
|
||||
this._preDeployScripts = [];
|
||||
this._postDeployScripts = [];
|
||||
this._noneDeployScripts = [];
|
||||
@@ -843,7 +843,8 @@ export class Project implements ISqlProject {
|
||||
* @param defaultValue
|
||||
*/
|
||||
public async addSqlCmdVariable(name: string, defaultValue: string): Promise<void> {
|
||||
await this.sqlProjService.addSqlCmdVariable(this.projectFilePath, name, defaultValue);
|
||||
const result = await this.sqlProjService.addSqlCmdVariable(this.projectFilePath, name, defaultValue);
|
||||
this.throwIfFailed(result);
|
||||
await this.readSqlCmdVariables();
|
||||
}
|
||||
|
||||
@@ -853,7 +854,8 @@ export class Project implements ISqlProject {
|
||||
* @param defaultValue
|
||||
*/
|
||||
public async updateSqlCmdVariable(name: string, defaultValue: string): Promise<void> {
|
||||
await this.sqlProjService.updateSqlCmdVariable(this.projectFilePath, name, defaultValue);
|
||||
const result = await this.sqlProjService.updateSqlCmdVariable(this.projectFilePath, name, defaultValue);
|
||||
this.throwIfFailed(result);
|
||||
await this.readSqlCmdVariables();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface PublishProfile {
|
||||
serverName: string;
|
||||
connectionId: string;
|
||||
connection: string;
|
||||
sqlCmdVariables: Record<string, string>;
|
||||
sqlCmdVariables: Map<string, string>;
|
||||
options?: mssql.DeploymentOptions | vscodeMssql.DeploymentOptions;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ export async function load(profileUri: vscode.Uri, dacfxService: utils.IDacFxSer
|
||||
.withAdditionalProperties({
|
||||
hasTargetDbName: (!!targetDbName).toString(),
|
||||
hasConnectionString: (!!connectionInfo?.connectionId).toString(),
|
||||
hasSqlCmdVariables: (Object.keys(sqlCmdVariables).length > 0).toString()
|
||||
hasSqlCmdVariables: (sqlCmdVariables.size > 0).toString()
|
||||
}).send();
|
||||
|
||||
return {
|
||||
@@ -129,7 +129,7 @@ async function readConnectionString(xmlDoc: any): Promise<{ connectionId: string
|
||||
/**
|
||||
* saves publish settings to the specified profile file
|
||||
*/
|
||||
export async function savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<void> {
|
||||
export async function savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: mssql.DeploymentOptions): Promise<void> {
|
||||
const dacFxService = await utils.getDacFxService();
|
||||
await dacFxService.savePublishProfile(profilePath, databaseName, connectionString, sqlCommandVariableValues, deploymentOptions);
|
||||
}
|
||||
|
||||
@@ -23,21 +23,19 @@ export class SqlCmdVariablesTreeItem extends BaseProjectTreeItem {
|
||||
* @param sqlCmdVariables Collection of SQLCMD variables in the project
|
||||
* @param project
|
||||
*/
|
||||
constructor(projectNodeName: string, sqlprojUri: vscode.Uri, sqlCmdVariables: Record<string, string>) {
|
||||
constructor(projectNodeName: string, sqlprojUri: vscode.Uri, sqlCmdVariables: Map<string, string>) {
|
||||
super(vscode.Uri.file(path.join(projectNodeName, constants.sqlcmdVariablesNodeName)), sqlprojUri);
|
||||
|
||||
this.construct(sqlCmdVariables);
|
||||
}
|
||||
|
||||
private construct(sqlCmdVariables: Record<string, string>) {
|
||||
private construct(sqlCmdVariables: Map<string, string>) {
|
||||
if (!sqlCmdVariables) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const sqlCmdVariable of Object.keys(sqlCmdVariables)) {
|
||||
if (sqlCmdVariable) {
|
||||
this.sqlcmdVariableTreeItems.push(new SqlCmdVariableTreeItem(sqlCmdVariable, this.relativeProjectUri, this.projectFileUri));
|
||||
}
|
||||
for (const sqlCmdVariable of sqlCmdVariables.keys()) {
|
||||
this.sqlcmdVariableTreeItems.push(new SqlCmdVariableTreeItem(sqlCmdVariable, this.relativeProjectUri, this.projectFileUri));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ declare module 'sqldbproj' {
|
||||
/**
|
||||
* SqlCmd variables and their values
|
||||
*/
|
||||
readonly sqlCmdVariables: Record<string, string>;
|
||||
readonly sqlCmdVariables: Map<string, string>;
|
||||
|
||||
/**
|
||||
* Pre-deployment scripts in this project
|
||||
|
||||
@@ -13,14 +13,14 @@ export let newSdkSqlProjectTemplate: string;
|
||||
|
||||
// Object maps
|
||||
|
||||
let scriptTypeMap: Record<string, ProjectScriptType> = {};
|
||||
let scriptTypeMap: Map<string, ProjectScriptType> = new Map();
|
||||
|
||||
export function get(key: string): ProjectScriptType {
|
||||
if (Object.keys(scriptTypeMap).length === 0) {
|
||||
if (scriptTypeMap.size === 0) {
|
||||
throw new Error('Templates must be loaded from file before attempting to use.');
|
||||
}
|
||||
|
||||
return scriptTypeMap[key.toLocaleLowerCase()];
|
||||
return scriptTypeMap.get(key.toLocaleLowerCase())!;
|
||||
}
|
||||
|
||||
let scriptTypes: ProjectScriptType[] = [];
|
||||
@@ -52,26 +52,26 @@ export async function loadTemplates(templateFolderPath: string) {
|
||||
]);
|
||||
|
||||
for (const scriptType of scriptTypes) {
|
||||
if (Object.keys(scriptTypeMap).find(s => s === scriptType.type.toLocaleLowerCase() || s === scriptType.friendlyName.toLocaleLowerCase())) {
|
||||
if (scriptTypeMap.has(scriptType.type.toLocaleLowerCase()) || scriptTypeMap.has(scriptType.friendlyName.toLocaleLowerCase())) {
|
||||
throw new Error(`Script type map already contains ${scriptType.type} or its friendlyName.`);
|
||||
}
|
||||
|
||||
scriptTypeMap[scriptType.type.toLocaleLowerCase()] = scriptType;
|
||||
scriptTypeMap[scriptType.friendlyName.toLocaleLowerCase()] = scriptType;
|
||||
scriptTypeMap.set(scriptType.type.toLocaleLowerCase(), scriptType);
|
||||
scriptTypeMap.set(scriptType.friendlyName.toLocaleLowerCase(), scriptType);
|
||||
}
|
||||
}
|
||||
|
||||
export function macroExpansion(template: string, macroDict: Record<string, string>): string {
|
||||
export function macroExpansion(template: string, macroDict: Map<string, string>): string {
|
||||
const macroIndicator = '@@';
|
||||
let output = template;
|
||||
|
||||
for (const macro in macroDict) {
|
||||
// check if value contains the macroIndicator, which could break expansion for successive macros
|
||||
if (macroDict[macro].includes(macroIndicator)) {
|
||||
throw new Error(`Macro value ${macroDict[macro]} is invalid because it contains ${macroIndicator}`);
|
||||
if (macroDict.get(macro)!.includes(macroIndicator)) {
|
||||
throw new Error(`Macro value ${macroDict.get(macro)} is invalid because it contains ${macroIndicator}`);
|
||||
}
|
||||
|
||||
output = output.replace(new RegExp(macroIndicator + macro + macroIndicator, 'g'), macroDict[macro]);
|
||||
output = output.replace(new RegExp(macroIndicator + macro + macroIndicator, 'g'), macroDict.get(macro)!);
|
||||
}
|
||||
|
||||
return output;
|
||||
@@ -104,6 +104,6 @@ export class ProjectScriptType {
|
||||
* For testing purposes only
|
||||
*/
|
||||
export function reset() {
|
||||
scriptTypeMap = {};
|
||||
scriptTypeMap = new Map();
|
||||
scriptTypes = [];
|
||||
}
|
||||
|
||||
@@ -83,10 +83,10 @@ describe('Publish Database Dialog', () => {
|
||||
databaseName: 'MockDatabaseName',
|
||||
serverName: 'MockServer',
|
||||
connectionUri: 'Mock|Connection|Uri',
|
||||
sqlCmdVariables: {
|
||||
'ProdDatabaseName': 'MyProdDatabase',
|
||||
'BackupDatabaseName': 'MyBackupDatabase'
|
||||
},
|
||||
sqlCmdVariables: new Map([
|
||||
['ProdDatabaseName', 'MyProdDatabase'],
|
||||
['BackupDatabaseName', 'MyBackupDatabase']
|
||||
]),
|
||||
deploymentOptions: mockDacFxOptionsResult.deploymentOptions,
|
||||
profileUsed: false
|
||||
};
|
||||
@@ -100,10 +100,10 @@ describe('Publish Database Dialog', () => {
|
||||
databaseName: 'MockDatabaseName',
|
||||
serverName: 'MockServer',
|
||||
connectionUri: 'Mock|Connection|Uri',
|
||||
sqlCmdVariables: {
|
||||
'ProdDatabaseName': 'MyProdDatabase',
|
||||
'BackupDatabaseName': 'MyBackupDatabase'
|
||||
},
|
||||
sqlCmdVariables: new Map([
|
||||
['ProdDatabaseName', 'MyProdDatabase'],
|
||||
['BackupDatabaseName', 'MyBackupDatabase']
|
||||
]),
|
||||
deploymentOptions: mockDacFxOptionsResult.deploymentOptions,
|
||||
profileUsed: false
|
||||
};
|
||||
@@ -128,10 +128,10 @@ describe('Publish Database Dialog', () => {
|
||||
databaseName: 'MockDatabaseName',
|
||||
serverName: 'localhost',
|
||||
connectionUri: '',
|
||||
sqlCmdVariables: {
|
||||
'ProdDatabaseName': 'MyProdDatabase',
|
||||
'BackupDatabaseName': 'MyBackupDatabase'
|
||||
},
|
||||
sqlCmdVariables: new Map([
|
||||
['ProdDatabaseName', 'MyProdDatabase'],
|
||||
['BackupDatabaseName', 'MyBackupDatabase']
|
||||
]),
|
||||
deploymentOptions: mockDacFxOptionsResult.deploymentOptions,
|
||||
profileUsed: false
|
||||
}
|
||||
|
||||
@@ -48,9 +48,9 @@ describe('Project: sqlproj content operations', function (): void {
|
||||
'Views\\User']);
|
||||
|
||||
// SqlCmdVariables
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2);
|
||||
should(project.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
|
||||
should(project.sqlCmdVariables['BackupDatabaseName']).equal('MyBackupDatabase');
|
||||
should(project.sqlCmdVariables.size).equal(2);
|
||||
should(project.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
|
||||
should(project.sqlCmdVariables.get('BackupDatabaseName')).equal('MyBackupDatabase');
|
||||
|
||||
// Database references
|
||||
// should only have one database reference even though there are two master.dacpac references (1 for ADS and 1 for SSDT)
|
||||
@@ -647,7 +647,7 @@ describe('Project: database references', function (): void {
|
||||
|
||||
// add database reference to a different database on a different server
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(0, `There should be no sqlcmd variables to start with. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
|
||||
should(project.sqlCmdVariables.size).equal(0, `There should be no sqlcmd variables to start with. Actual: ${project.sqlCmdVariables.size}`);
|
||||
await project.addProjectReference({
|
||||
projectName: 'project1',
|
||||
projectGuid: '',
|
||||
@@ -658,7 +658,7 @@ describe('Project: database references', function (): void {
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to project1');
|
||||
should(project.databaseReferences[0].referenceName).equal('project1', 'The database reference should be project1');
|
||||
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(0, `There should be no sqlcmd variables added. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
|
||||
should(project.sqlCmdVariables.size).equal(0, `There should be no sqlcmd variables added. Actual: ${project.sqlCmdVariables.size}`);
|
||||
});
|
||||
|
||||
it('Should add a project reference to a different database in the same server correctly', async function (): Promise<void> {
|
||||
@@ -667,7 +667,7 @@ describe('Project: database references', function (): void {
|
||||
|
||||
// add database reference to a different database on a different server
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(0, 'There should be no sqlcmd variables to start with');
|
||||
should(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
|
||||
await project.addProjectReference({
|
||||
projectName: 'project1',
|
||||
projectGuid: '',
|
||||
@@ -680,7 +680,7 @@ describe('Project: database references', function (): void {
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to project1');
|
||||
should(project.databaseReferences[0].referenceName).equal('project1', 'The database reference should be project1');
|
||||
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(1, `There should be one new sqlcmd variable added. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
|
||||
should(project.sqlCmdVariables.size).equal(1, `There should be one new sqlcmd variable added. Actual: ${project.sqlCmdVariables.size}`);
|
||||
});
|
||||
|
||||
it('Should add a project reference to a different database in a different server correctly', async function (): Promise<void> {
|
||||
@@ -689,7 +689,7 @@ describe('Project: database references', function (): void {
|
||||
|
||||
// add database reference to a different database on a different server
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(0, 'There should be no sqlcmd variables to start with');
|
||||
should(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
|
||||
await project.addProjectReference({
|
||||
projectName: 'project1',
|
||||
projectGuid: '',
|
||||
@@ -704,7 +704,7 @@ describe('Project: database references', function (): void {
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to project1');
|
||||
should(project.databaseReferences[0].referenceName).equal('project1', 'The database reference should be project1');
|
||||
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, `There should be two new sqlcmd variables added. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
|
||||
should(project.sqlCmdVariables.size).equal(2, `There should be two new sqlcmd variables added. Actual: ${project.sqlCmdVariables.size}`);
|
||||
});
|
||||
|
||||
it('Should not allow adding duplicate dacpac references', async function (): Promise<void> {
|
||||
@@ -803,7 +803,7 @@ describe('Project: database references', function (): void {
|
||||
});
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test3');
|
||||
should(project.databaseReferences[0].referenceName).equal('test3', 'The database reference should be test3');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'There should be 2 sqlcmdvars after adding the dacpac reference');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'There should be 2 sqlcmdvars after adding the dacpac reference');
|
||||
|
||||
// make sure reference to test3.dacpac and SQLCMD variables were added
|
||||
let projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
@@ -815,7 +815,7 @@ describe('Project: database references', function (): void {
|
||||
// delete reference
|
||||
await project.deleteDatabaseReferenceByEntry(project.databaseReferences[0]);
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no database references after deleting');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'There should still be 2 sqlcmdvars after deleting the dacpac reference');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'There should still be 2 sqlcmdvars after deleting the dacpac reference');
|
||||
|
||||
// add reference to the same dacpac again but with different values for the sqlcmd variables
|
||||
await project.addDatabaseReference({
|
||||
@@ -828,7 +828,7 @@ describe('Project: database references', function (): void {
|
||||
});
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test3');
|
||||
should(project.databaseReferences[0].referenceName).equal('test3', 'The database reference should be test3');
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'There should still be 2 sqlcmdvars after adding the dacpac reference again with different sqlcmdvar values');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'There should still be 2 sqlcmdvars after adding the dacpac reference again with different sqlcmdvar values');
|
||||
|
||||
projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText).containEql('<SqlCmdVariable Include="test3Db">');
|
||||
@@ -850,7 +850,7 @@ describe('Project: add SQLCMD Variables', function (): void {
|
||||
it('Should update .sqlproj with new sqlcmd variables', async function (): Promise<void> {
|
||||
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectFileBaseline);
|
||||
let project = await Project.openProject(projFilePath);
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should have 2 sqlcmd variables when opened');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should have 2 sqlcmd variables when opened');
|
||||
|
||||
// add a new variable
|
||||
await project.addSqlCmdVariable('TestDatabaseName', 'TestDb');
|
||||
@@ -858,9 +858,9 @@ describe('Project: add SQLCMD Variables', function (): void {
|
||||
// update value of an existing sqlcmd variable
|
||||
await project.updateSqlCmdVariable('ProdDatabaseName', 'NewProdName');
|
||||
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(3, 'There should be 3 sqlcmd variables after adding TestDatabaseName');
|
||||
should(project.sqlCmdVariables['TestDatabaseName']).equal('TestDb', 'Value of TestDatabaseName should be TestDb');
|
||||
should(project.sqlCmdVariables['ProdDatabaseName']).equal('NewProdName', 'ProdDatabaseName value should have been updated to the new value');
|
||||
should(project.sqlCmdVariables.size).equal(3, 'There should be 3 sqlcmd variables after adding TestDatabaseName');
|
||||
should(project.sqlCmdVariables.get('TestDatabaseName')).equal('TestDb', 'Value of TestDatabaseName should be TestDb');
|
||||
should(project.sqlCmdVariables.get('ProdDatabaseName')).equal('NewProdName', 'ProdDatabaseName value should have been updated to the new value');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ describe('ProjectsController', function (): void {
|
||||
});
|
||||
|
||||
it('Should exclude nested ProjectEntry from node', async function (): Promise<void> {
|
||||
let proj = await testUtils.createTestProject(this.test, templates.newSqlProjectTemplate);
|
||||
let proj = await testUtils.createTestSqlProject(this.test);
|
||||
const setupResult = await setupDeleteExcludeTest(proj);
|
||||
const scriptEntry = setupResult[0], projTreeRoot = setupResult[1], preDeployEntry = setupResult[2], postDeployEntry = setupResult[3], noneEntry = setupResult[4];
|
||||
|
||||
@@ -997,14 +997,14 @@ describe('ProjectsController', function (): void {
|
||||
const projController = new ProjectsController(testContext.outputChannel);
|
||||
const projRoot = new ProjectRootTreeItem(project);
|
||||
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should start with 2 sqlcmd variables');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should start with 2 sqlcmd variables');
|
||||
|
||||
sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Cancel'));
|
||||
await projController.delete(createWorkspaceTreeItem(projRoot.children.find(x => x.friendlyName === constants.sqlcmdVariablesNodeName)!.children[0]));
|
||||
|
||||
// reload project
|
||||
project = await Project.openProject(project.projectFilePath);
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables if no was selected');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables if no was selected');
|
||||
|
||||
sinon.restore();
|
||||
sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
|
||||
@@ -1012,7 +1012,7 @@ describe('ProjectsController', function (): void {
|
||||
|
||||
// reload project
|
||||
project = await Project.openProject(project.projectFilePath);
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(1, 'The project should only have 1 sqlcmd variable after deletion');
|
||||
should(project.sqlCmdVariables.size).equal(1, 'The project should only have 1 sqlcmd variable after deletion');
|
||||
});
|
||||
|
||||
it('Should add sqlcmd variable', async function (): Promise<void> {
|
||||
@@ -1023,7 +1023,7 @@ describe('ProjectsController', function (): void {
|
||||
const projController = new ProjectsController(testContext.outputChannel);
|
||||
const projRoot = new ProjectRootTreeItem(project);
|
||||
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should start with 2 sqlcmd variables');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should start with 2 sqlcmd variables');
|
||||
|
||||
const inputBoxStub = sinon.stub(vscode.window, 'showInputBox');
|
||||
inputBoxStub.resolves('');
|
||||
@@ -1031,7 +1031,7 @@ describe('ProjectsController', function (): void {
|
||||
|
||||
// reload project
|
||||
project = await Project.openProject(project.projectFilePath);
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables if no name was provided');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables if no name was provided');
|
||||
|
||||
inputBoxStub.reset();
|
||||
inputBoxStub.onFirstCall().resolves('newVariable');
|
||||
@@ -1040,7 +1040,7 @@ describe('ProjectsController', function (): void {
|
||||
|
||||
// reload project
|
||||
project = await Project.openProject(project.projectFilePath);
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(3, 'The project should have 3 sqlcmd variable after adding a new one');
|
||||
should(project.sqlCmdVariables.size).equal(3, 'The project should have 3 sqlcmd variable after adding a new one');
|
||||
});
|
||||
|
||||
it('Should update sqlcmd variable', async function (): Promise<void> {
|
||||
@@ -1051,18 +1051,18 @@ describe('ProjectsController', function (): void {
|
||||
const projController = new ProjectsController(testContext.outputChannel);
|
||||
const projRoot = new ProjectRootTreeItem(project);
|
||||
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should start with 2 sqlcmd variables');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should start with 2 sqlcmd variables');
|
||||
|
||||
const inputBoxStub = sinon.stub(vscode.window, 'showInputBox');
|
||||
inputBoxStub.resolves('');
|
||||
const sqlcmdVarToUpdate = projRoot.children.find(x => x.friendlyName === constants.sqlcmdVariablesNodeName)!.children[0];
|
||||
const originalValue = project.sqlCmdVariables[sqlcmdVarToUpdate.friendlyName];
|
||||
const originalValue = project.sqlCmdVariables.get(sqlcmdVarToUpdate.friendlyName);
|
||||
await projController.editSqlCmdVariable(createWorkspaceTreeItem(sqlcmdVarToUpdate));
|
||||
|
||||
// reload project
|
||||
project = await Project.openProject(project.projectFilePath);
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables');
|
||||
should(project.sqlCmdVariables[sqlcmdVarToUpdate.friendlyName]).equal(originalValue, 'The value of the sqlcmd variable should not have changed');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables');
|
||||
should(project.sqlCmdVariables.get(sqlcmdVarToUpdate.friendlyName)).equal(originalValue, 'The value of the sqlcmd variable should not have changed');
|
||||
|
||||
inputBoxStub.reset();
|
||||
const updatedValue = 'newValue';
|
||||
@@ -1071,8 +1071,8 @@ describe('ProjectsController', function (): void {
|
||||
|
||||
// reload project
|
||||
project = await Project.openProject(project.projectFilePath);
|
||||
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables');
|
||||
should(project.sqlCmdVariables[sqlcmdVarToUpdate.friendlyName]).equal(updatedValue, 'The value of the sqlcmd variable should have been updated');
|
||||
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables');
|
||||
should(project.sqlCmdVariables.get(sqlcmdVarToUpdate.friendlyName)).equal(updatedValue, 'The value of the sqlcmd variable should have been updated');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,8 +49,8 @@ describe('Publish profile tests', function (): void {
|
||||
|
||||
const result = await load(vscode.Uri.file(profilePath), testContext.dacFxService.object);
|
||||
should(result.databaseName).equal('targetDb');
|
||||
should(Object.keys(result.sqlCmdVariables).length).equal(1);
|
||||
should(result.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
|
||||
should(result.sqlCmdVariables.size).equal(1);
|
||||
should(result.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
|
||||
should(result.connectionId).equal('connId');
|
||||
should(result.connection).equal('testserver (default)');
|
||||
should(result.options).equal(mockDacFxOptionsResult.deploymentOptions);
|
||||
@@ -74,8 +74,8 @@ describe('Publish profile tests', function (): void {
|
||||
|
||||
const result = await load(vscode.Uri.file(profilePath), testContext.dacFxService.object);
|
||||
should(result.databaseName).equal('targetDb');
|
||||
should(Object.keys(result.sqlCmdVariables).length).equal(1);
|
||||
should(result.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
|
||||
should(result.sqlCmdVariables.size).equal(1);
|
||||
should(result.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
|
||||
should(result.connectionId).equal('connId');
|
||||
should(result.connection).equal('testserver (testUser)');
|
||||
should(result.options).equal(mockDacFxOptionsResult.deploymentOptions);
|
||||
@@ -89,10 +89,10 @@ describe('Publish profile tests', function (): void {
|
||||
});
|
||||
|
||||
const result = await load(vscode.Uri.file(profilePath), testContext.dacFxService.object);
|
||||
should(Object.keys(result.sqlCmdVariables).length).equal(1);
|
||||
should(result.sqlCmdVariables.size).equal(1);
|
||||
|
||||
// the profile has both Value and DefaultValue, but Value should be the one used
|
||||
should(result.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
|
||||
should(result.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
|
||||
});
|
||||
|
||||
it('Should throw error when connecting does not work', async function (): Promise<void> {
|
||||
|
||||
@@ -56,13 +56,13 @@ export class MockDacFxService implements mssql.IDacFxService {
|
||||
public importBacpac(_packageFilePath: string, _databaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public extractDacpac(_databaseName: string, _packageFilePath: string, _applicationName: string, _applicationVersion: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public createProjectFromDatabase(_databaseName: string, _targetFilePath: string, _applicationName: string, _applicationVersion: string, _ownerUri: string, _extractTarget: mssql.ExtractTarget, _taskExecutionMode: azdata.TaskExecutionMode, _includePermissions?: boolean): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public deployDacpac(_packageFilePath: string, _targetDatabaseName: string, _upgradeExisting: boolean, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Record<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public generateDeployScript(_packageFilePath: string, _targetDatabaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Record<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public deployDacpac(_packageFilePath: string, _targetDatabaseName: string, _upgradeExisting: boolean, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Map<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public generateDeployScript(_packageFilePath: string, _targetDatabaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Map<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public generateDeployPlan(_packageFilePath: string, _targetDatabaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.GenerateDeployPlanResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public getOptionsFromProfile(_profilePath: string): Thenable<mssql.DacFxOptionsResult> { return Promise.resolve(mockDacFxOptionsResult); }
|
||||
public validateStreamingJob(_packageFilePath: string, _createStreamingJobTsql: string): Thenable<mssql.ValidateStreamingJobResult> { return Promise.resolve(mockDacFxResult); }
|
||||
public parseTSqlScript(_filePath: string, _databaseSchemaProvider: string): Thenable<mssql.ParseTSqlScriptResult> { return Promise.resolve({ containsCreateTableStatement: true }); }
|
||||
public savePublishProfile(_profilePath: string, _databaseName: string, _connectionString: string, _sqlCommandVariableValues?: Record<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<azdata.ResultStatus> { return Promise.resolve(mockSavePublishResult); }
|
||||
public savePublishProfile(_profilePath: string, _databaseName: string, _connectionString: string, _sqlCommandVariableValues?: Map<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<azdata.ResultStatus> { return Promise.resolve(mockSavePublishResult); }
|
||||
}
|
||||
|
||||
export function createContext(): TestContext {
|
||||
|
||||
@@ -43,9 +43,7 @@ export async function getTestProjectPath(test: Mocha.Runnable | undefined): Prom
|
||||
|
||||
export async function createTestSqlProjFile(test: Mocha.Runnable | undefined, contents: string, folderPath?: string): Promise<string> {
|
||||
folderPath = folderPath ?? path.join(await generateTestFolderPath(test), 'TestProject');
|
||||
const macroDict: Record<string, string> = {
|
||||
'PROJECT_DSP': constants.defaultDSP
|
||||
};
|
||||
const macroDict: Map<string, string> = new Map([['PROJECT_DSP', constants.defaultDSP]]);
|
||||
contents = templates.macroExpansion(contents, macroDict);
|
||||
return await createTestFile(test, contents, 'TestProject.sqlproj', folderPath);
|
||||
}
|
||||
|
||||
6
extensions/types/vscode-mssql.d.ts
vendored
6
extensions/types/vscode-mssql.d.ts
vendored
@@ -426,12 +426,12 @@ declare module 'vscode-mssql' {
|
||||
importBacpac(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable<DacFxResult>;
|
||||
extractDacpac(databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable<DacFxResult>;
|
||||
createProjectFromDatabase(databaseName: string, targetFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, extractTarget: ExtractTarget, taskExecutionMode: TaskExecutionMode, includePermissions?: boolean): Thenable<DacFxResult>;
|
||||
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
generateDeployScript(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
generateDeployScript(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: DeploymentOptions): Thenable<DacFxResult>;
|
||||
generateDeployPlan(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable<GenerateDeployPlanResult>;
|
||||
getOptionsFromProfile(profilePath: string): Thenable<DacFxOptionsResult>;
|
||||
validateStreamingJob(packageFilePath: string, createStreamingJobTsql: string): Thenable<ValidateStreamingJobResult>;
|
||||
savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Record<string, string>, deploymentOptions?: DeploymentOptions): Thenable<ResultStatus>;
|
||||
savePublishProfile(profilePath: string, databaseName: string, connectionString: string, sqlCommandVariableValues?: Map<string, string>, deploymentOptions?: DeploymentOptions): Thenable<ResultStatus>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user