mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 01:25:36 -05:00
Add db and server sqlcmd variables for database references (#12089)
* add support for adding db and server sqlcmd variables * fix incrementing * split up test
This commit is contained in:
@@ -197,6 +197,8 @@ export const Value = 'Value';
|
||||
export const ArtifactReference = 'ArtifactReference';
|
||||
export const SuppressMissingDependenciesErrors = 'SuppressMissingDependenciesErrors';
|
||||
export const DatabaseVariableLiteralValue = 'DatabaseVariableLiteralValue';
|
||||
export const DatabaseSqlCmdVariable = 'DatabaseSqlCmdVariable';
|
||||
export const ServerSqlCmdVariable = 'ServerSqlCmdVariable';
|
||||
export const DSP = 'DSP';
|
||||
export const Properties = 'Properties';
|
||||
export const RelativeOuterPath = '..';
|
||||
|
||||
@@ -126,7 +126,9 @@ export class AddDatabaseReferenceDialog {
|
||||
databaseName: <string>this.databaseNameTextbox?.value,
|
||||
databaseLocation: <DatabaseReferenceLocation>this.referenceLocationMap.get(<string>this.locationDropdown?.value),
|
||||
dacpacFileLocation: vscode.Uri.file(<string>this.dacpacTextbox?.value),
|
||||
databaseVariable: <string>this.databaseVariableTextbox?.value
|
||||
databaseVariable: <string>this.databaseVariableTextbox?.value,
|
||||
serverName: <string>this.serverNameTextbox?.value,
|
||||
serverVariable: <string>this.serverVariableTextbox?.value
|
||||
};
|
||||
// TODO: add project reference support
|
||||
}
|
||||
|
||||
@@ -498,7 +498,6 @@ export class Project {
|
||||
if (isSystemDatabaseProjectEntry) {
|
||||
this.addSystemDatabaseReferenceToProjFile(<SystemDatabaseReferenceProjectEntry>entry);
|
||||
} else {
|
||||
|
||||
const referenceNode = this.projFileXmlDoc.createElement(constants.ArtifactReference);
|
||||
referenceNode.setAttribute(constants.Include, entry.pathForSqlProj());
|
||||
this.addDatabaseReferenceChildren(referenceNode, entry);
|
||||
@@ -519,13 +518,30 @@ export class Project {
|
||||
suppressMissingDependenciesErrorNode.appendChild(falseTextNode);
|
||||
referenceNode.appendChild(suppressMissingDependenciesErrorNode);
|
||||
|
||||
// TODO: add support for sqlcmd vars and server https://github.com/microsoft/azuredatastudio/issues/12036
|
||||
if (entry.databaseVariableLiteralValue) {
|
||||
if ((<DacpacReferenceProjectEntry>entry).databaseSqlCmdVariable) {
|
||||
const databaseSqlCmdVariableElement = this.projFileXmlDoc.createElement(constants.DatabaseSqlCmdVariable);
|
||||
const databaseSqlCmdVariableTextNode = this.projFileXmlDoc.createTextNode((<DacpacReferenceProjectEntry>entry).databaseSqlCmdVariable);
|
||||
databaseSqlCmdVariableElement.appendChild(databaseSqlCmdVariableTextNode);
|
||||
referenceNode.appendChild(databaseSqlCmdVariableElement);
|
||||
|
||||
// add SQLCMD variable
|
||||
this.addSqlCmdVariable((<DacpacReferenceProjectEntry>entry).databaseSqlCmdVariable!, (<DacpacReferenceProjectEntry>entry).databaseName);
|
||||
} else if (entry.databaseVariableLiteralValue) {
|
||||
const databaseVariableLiteralValueElement = this.projFileXmlDoc.createElement(constants.DatabaseVariableLiteralValue);
|
||||
const databaseTextNode = this.projFileXmlDoc.createTextNode(entry.databaseVariableLiteralValue);
|
||||
databaseVariableLiteralValueElement.appendChild(databaseTextNode);
|
||||
referenceNode.appendChild(databaseVariableLiteralValueElement);
|
||||
}
|
||||
|
||||
if ((<DacpacReferenceProjectEntry>entry).serverSqlCmdVariable) {
|
||||
const serverSqlCmdVariableElement = this.projFileXmlDoc.createElement(constants.ServerSqlCmdVariable);
|
||||
const serverSqlCmdVariableTextNode = this.projFileXmlDoc.createTextNode((<DacpacReferenceProjectEntry>entry).serverSqlCmdVariable);
|
||||
serverSqlCmdVariableElement.appendChild(serverSqlCmdVariableTextNode);
|
||||
referenceNode.appendChild(serverSqlCmdVariableElement);
|
||||
|
||||
// add SQLCMD variable
|
||||
this.addSqlCmdVariable((<DacpacReferenceProjectEntry>entry).serverSqlCmdVariable!, (<DacpacReferenceProjectEntry>entry).serverName!);
|
||||
}
|
||||
}
|
||||
|
||||
public addSqlCmdVariableToProjFile(entry: SqlCmdVariableProjectEntry): void {
|
||||
@@ -561,7 +577,7 @@ export class Project {
|
||||
*/
|
||||
private getNextSqlCmdVariableCounter(): number {
|
||||
const sqlCmdVariableNodes = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.SqlCmdVariable);
|
||||
let highestNumber = 1;
|
||||
let highestNumber = 0;
|
||||
|
||||
for (let i = 0; i < sqlCmdVariableNodes.length; i++) {
|
||||
const value: string = sqlCmdVariableNodes[i].getElementsByTagName(constants.Value)[0].childNodes[0].nodeValue;
|
||||
@@ -767,11 +783,17 @@ export interface IDatabaseReferenceProjectEntry extends FileProjectEntry {
|
||||
export class DacpacReferenceProjectEntry extends FileProjectEntry implements IDatabaseReferenceProjectEntry {
|
||||
databaseLocation: DatabaseReferenceLocation;
|
||||
databaseVariableLiteralValue?: string;
|
||||
databaseSqlCmdVariable?: string;
|
||||
serverName?: string;
|
||||
serverSqlCmdVariable?: string;
|
||||
|
||||
constructor(settings: IDacpacReferenceSettings) {
|
||||
super(settings.dacpacFileLocation, '', EntryType.DatabaseReference);
|
||||
this.databaseLocation = settings.databaseLocation;
|
||||
this.databaseSqlCmdVariable = settings.databaseVariable;
|
||||
this.databaseVariableLiteralValue = settings.databaseName;
|
||||
this.serverName = settings.serverName;
|
||||
this.serverSqlCmdVariable = settings.serverVariable;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -187,11 +187,11 @@ describe('Project: sqlproj content operations', function (): void {
|
||||
await testUtils.shouldThrowSpecificError(async () => await project.getSystemDacpacUri(constants.masterDacpac), constants.invalidDataSchemaProvider);
|
||||
});
|
||||
|
||||
it('Should add database references correctly', async function (): Promise<void> {
|
||||
it('Should add system database references correctly', async function (): Promise<void> {
|
||||
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||
const project = await Project.openProject(projFilePath);
|
||||
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no datbase references to start with');
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
||||
await project.addSystemDatabaseReference({ databaseName: 'master', systemDb: SystemDatabase.master });
|
||||
should(project.databaseReferences.length).equal(1, 'There should be one database reference after adding a reference to master');
|
||||
should(project.databaseReferences[0].databaseName).equal(constants.master, 'The database reference should be master');
|
||||
@@ -207,13 +207,66 @@ describe('Project: sqlproj content operations', function (): void {
|
||||
projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText).containEql(convertSlashesForSqlProj(project.getSystemDacpacUri(constants.msdb).fsPath.substring(1)));
|
||||
should(projFileText).containEql(convertSlashesForSqlProj(project.getSystemDacpacSsdtUri(constants.msdb).fsPath.substring(1)));
|
||||
});
|
||||
|
||||
await project.addDatabaseReference({ dacpacFileLocation: Uri.file('test.dacpac'), databaseLocation: DatabaseReferenceLocation.sameDatabase });
|
||||
should(project.databaseReferences.length).equal(3, 'There should be three database references after adding a reference to test');
|
||||
should(project.databaseReferences[2].databaseName).equal('test', 'The database reference should be test');
|
||||
it('Should add a dacpac reference to the same database correctly', async function (): Promise<void> {
|
||||
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||
const project = await Project.openProject(projFilePath);
|
||||
|
||||
// add database reference in the same database
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
||||
await project.addDatabaseReference({ dacpacFileLocation: Uri.file('test1.dacpac'), databaseLocation: DatabaseReferenceLocation.sameDatabase });
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test1');
|
||||
should(project.databaseReferences[0].databaseName).equal('test1', 'The database reference should be test1');
|
||||
// make sure reference to test.dacpac was added
|
||||
projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText).containEql('test.dacpac');
|
||||
let projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText).containEql('test1.dacpac');
|
||||
});
|
||||
|
||||
it('Should add a dacpac reference to a different database in the same server correctly', async function (): Promise<void> {
|
||||
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||
const project = await Project.openProject(projFilePath);
|
||||
|
||||
// add database reference to a different database on the same server
|
||||
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
||||
await project.addDatabaseReference({
|
||||
dacpacFileLocation: Uri.file('test2.dacpac'),
|
||||
databaseLocation: DatabaseReferenceLocation.differentDatabaseSameServer,
|
||||
databaseName: 'test2DbName',
|
||||
databaseVariable: 'test2Db'
|
||||
});
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test2');
|
||||
should(project.databaseReferences[0].databaseName).equal('test2', 'The database reference should be test2');
|
||||
// make sure reference to test2.dacpac and SQLCMD variable was added
|
||||
let projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText).containEql('test2.dacpac');
|
||||
should(projFileText).containEql('<DatabaseSqlCmdVariable>test2Db</DatabaseSqlCmdVariable>');
|
||||
should(projFileText).containEql('<SqlCmdVariable Include="test2Db">');
|
||||
});
|
||||
|
||||
it('Should add a dacpac reference to a different database in a different server correctly', async function (): Promise<void> {
|
||||
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||
const project = await Project.openProject(projFilePath);
|
||||
|
||||
// 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');
|
||||
await project.addDatabaseReference({
|
||||
dacpacFileLocation: Uri.file('test3.dacpac'),
|
||||
databaseLocation: DatabaseReferenceLocation.differentDatabaseDifferentServer,
|
||||
databaseName: 'test3DbName',
|
||||
databaseVariable: 'test3Db',
|
||||
serverName: 'otherServerName',
|
||||
serverVariable: 'otherServer'
|
||||
});
|
||||
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test3');
|
||||
should(project.databaseReferences[0].databaseName).equal('test3', 'The database reference should be test3');
|
||||
// make sure reference to test2.dacpac and SQLCMD variables were added
|
||||
let projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText).containEql('test3.dacpac');
|
||||
should(projFileText).containEql('<DatabaseSqlCmdVariable>test3Db</DatabaseSqlCmdVariable>');
|
||||
should(projFileText).containEql('<SqlCmdVariable Include="test3Db">');
|
||||
should(projFileText).containEql('<ServerSqlCmdVariable>otherServer</ServerSqlCmdVariable>');
|
||||
should(projFileText).containEql('<SqlCmdVariable Include="otherServer">');
|
||||
});
|
||||
|
||||
it('Should not allow adding duplicate database references', async function (): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user