mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51: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 ArtifactReference = 'ArtifactReference';
|
||||||
export const SuppressMissingDependenciesErrors = 'SuppressMissingDependenciesErrors';
|
export const SuppressMissingDependenciesErrors = 'SuppressMissingDependenciesErrors';
|
||||||
export const DatabaseVariableLiteralValue = 'DatabaseVariableLiteralValue';
|
export const DatabaseVariableLiteralValue = 'DatabaseVariableLiteralValue';
|
||||||
|
export const DatabaseSqlCmdVariable = 'DatabaseSqlCmdVariable';
|
||||||
|
export const ServerSqlCmdVariable = 'ServerSqlCmdVariable';
|
||||||
export const DSP = 'DSP';
|
export const DSP = 'DSP';
|
||||||
export const Properties = 'Properties';
|
export const Properties = 'Properties';
|
||||||
export const RelativeOuterPath = '..';
|
export const RelativeOuterPath = '..';
|
||||||
|
|||||||
@@ -126,7 +126,9 @@ export class AddDatabaseReferenceDialog {
|
|||||||
databaseName: <string>this.databaseNameTextbox?.value,
|
databaseName: <string>this.databaseNameTextbox?.value,
|
||||||
databaseLocation: <DatabaseReferenceLocation>this.referenceLocationMap.get(<string>this.locationDropdown?.value),
|
databaseLocation: <DatabaseReferenceLocation>this.referenceLocationMap.get(<string>this.locationDropdown?.value),
|
||||||
dacpacFileLocation: vscode.Uri.file(<string>this.dacpacTextbox?.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
|
// TODO: add project reference support
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -498,7 +498,6 @@ export class Project {
|
|||||||
if (isSystemDatabaseProjectEntry) {
|
if (isSystemDatabaseProjectEntry) {
|
||||||
this.addSystemDatabaseReferenceToProjFile(<SystemDatabaseReferenceProjectEntry>entry);
|
this.addSystemDatabaseReferenceToProjFile(<SystemDatabaseReferenceProjectEntry>entry);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const referenceNode = this.projFileXmlDoc.createElement(constants.ArtifactReference);
|
const referenceNode = this.projFileXmlDoc.createElement(constants.ArtifactReference);
|
||||||
referenceNode.setAttribute(constants.Include, entry.pathForSqlProj());
|
referenceNode.setAttribute(constants.Include, entry.pathForSqlProj());
|
||||||
this.addDatabaseReferenceChildren(referenceNode, entry);
|
this.addDatabaseReferenceChildren(referenceNode, entry);
|
||||||
@@ -519,13 +518,30 @@ export class Project {
|
|||||||
suppressMissingDependenciesErrorNode.appendChild(falseTextNode);
|
suppressMissingDependenciesErrorNode.appendChild(falseTextNode);
|
||||||
referenceNode.appendChild(suppressMissingDependenciesErrorNode);
|
referenceNode.appendChild(suppressMissingDependenciesErrorNode);
|
||||||
|
|
||||||
// TODO: add support for sqlcmd vars and server https://github.com/microsoft/azuredatastudio/issues/12036
|
if ((<DacpacReferenceProjectEntry>entry).databaseSqlCmdVariable) {
|
||||||
if (entry.databaseVariableLiteralValue) {
|
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 databaseVariableLiteralValueElement = this.projFileXmlDoc.createElement(constants.DatabaseVariableLiteralValue);
|
||||||
const databaseTextNode = this.projFileXmlDoc.createTextNode(entry.databaseVariableLiteralValue);
|
const databaseTextNode = this.projFileXmlDoc.createTextNode(entry.databaseVariableLiteralValue);
|
||||||
databaseVariableLiteralValueElement.appendChild(databaseTextNode);
|
databaseVariableLiteralValueElement.appendChild(databaseTextNode);
|
||||||
referenceNode.appendChild(databaseVariableLiteralValueElement);
|
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 {
|
public addSqlCmdVariableToProjFile(entry: SqlCmdVariableProjectEntry): void {
|
||||||
@@ -561,7 +577,7 @@ export class Project {
|
|||||||
*/
|
*/
|
||||||
private getNextSqlCmdVariableCounter(): number {
|
private getNextSqlCmdVariableCounter(): number {
|
||||||
const sqlCmdVariableNodes = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.SqlCmdVariable);
|
const sqlCmdVariableNodes = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.SqlCmdVariable);
|
||||||
let highestNumber = 1;
|
let highestNumber = 0;
|
||||||
|
|
||||||
for (let i = 0; i < sqlCmdVariableNodes.length; i++) {
|
for (let i = 0; i < sqlCmdVariableNodes.length; i++) {
|
||||||
const value: string = sqlCmdVariableNodes[i].getElementsByTagName(constants.Value)[0].childNodes[0].nodeValue;
|
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 {
|
export class DacpacReferenceProjectEntry extends FileProjectEntry implements IDatabaseReferenceProjectEntry {
|
||||||
databaseLocation: DatabaseReferenceLocation;
|
databaseLocation: DatabaseReferenceLocation;
|
||||||
databaseVariableLiteralValue?: string;
|
databaseVariableLiteralValue?: string;
|
||||||
|
databaseSqlCmdVariable?: string;
|
||||||
|
serverName?: string;
|
||||||
|
serverSqlCmdVariable?: string;
|
||||||
|
|
||||||
constructor(settings: IDacpacReferenceSettings) {
|
constructor(settings: IDacpacReferenceSettings) {
|
||||||
super(settings.dacpacFileLocation, '', EntryType.DatabaseReference);
|
super(settings.dacpacFileLocation, '', EntryType.DatabaseReference);
|
||||||
this.databaseLocation = settings.databaseLocation;
|
this.databaseLocation = settings.databaseLocation;
|
||||||
|
this.databaseSqlCmdVariable = settings.databaseVariable;
|
||||||
this.databaseVariableLiteralValue = settings.databaseName;
|
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);
|
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);
|
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||||
const project = await Project.openProject(projFilePath);
|
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 });
|
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.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');
|
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();
|
projFileText = (await fs.readFile(projFilePath)).toString();
|
||||||
should(projFileText).containEql(convertSlashesForSqlProj(project.getSystemDacpacUri(constants.msdb).fsPath.substring(1)));
|
should(projFileText).containEql(convertSlashesForSqlProj(project.getSystemDacpacUri(constants.msdb).fsPath.substring(1)));
|
||||||
should(projFileText).containEql(convertSlashesForSqlProj(project.getSystemDacpacSsdtUri(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 });
|
it('Should add a dacpac reference to the same database correctly', async function (): Promise<void> {
|
||||||
should(project.databaseReferences.length).equal(3, 'There should be three database references after adding a reference to test');
|
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||||
should(project.databaseReferences[2].databaseName).equal('test', 'The database reference should be test');
|
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
|
// make sure reference to test.dacpac was added
|
||||||
projFileText = (await fs.readFile(projFilePath)).toString();
|
let projFileText = (await fs.readFile(projFilePath)).toString();
|
||||||
should(projFileText).containEql('test.dacpac');
|
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> {
|
it('Should not allow adding duplicate database references', async function (): Promise<void> {
|
||||||
|
|||||||
Reference in New Issue
Block a user