mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
Add support for adding dacpac references in sql database projects (#10684)
* add dacpacs * able to add reference to appropriate master dacpac * able to add reference to a dacpac * Add a few tests * fix tests * fix wording * fix adding reference to same database * add project tests * fix test for windows * addressing comments * Adding another test * update tests * fix build error
This commit is contained in:
@@ -109,6 +109,7 @@ const indentationFilter = [
|
||||
'!extensions/sql-database-projects/src/test/baselines/*.xml',
|
||||
'!extensions/sql-database-projects/src/test/baselines/*.json',
|
||||
'!extensions/sql-database-projects/src/test/baselines/*.sqlproj',
|
||||
'!extensions/sql-database-projects/BuildDirectory/SystemDacpacs/**',
|
||||
'!extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts',
|
||||
'!extensions/big-data-cluster/src/bigDataCluster/controller/clusterApiGenerated2.ts',
|
||||
'!resources/linux/snap/electron-launch'
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -113,6 +113,11 @@
|
||||
"command": "sqlDatabaseProjects.importDatabase",
|
||||
"title": "%sqlDatabaseProjects.importDatabase%",
|
||||
"category": "%sqlDatabaseProjects.displayName%"
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.addDatabaseReference",
|
||||
"title": "%sqlDatabaseProjects.addDatabaseReference%",
|
||||
"category": "%sqlDatabaseProjects.displayName%"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -226,6 +231,11 @@
|
||||
"when": "view == sqlDatabaseProjectsView",
|
||||
"group": "3_dbProjects_newItem@9"
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.addDatabaseReference",
|
||||
"when": "view == sqlDatabaseProjectsView",
|
||||
"group": "4_dbProjects_addDatabaseReference"
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.close",
|
||||
"when": "view == sqlDatabaseProjectsView",
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
"sqlDatabaseProjects.importDatabase": "Import New Database Project",
|
||||
|
||||
"sqlDatabaseProjects.addDatabaseReference": "Add Database Reference",
|
||||
|
||||
"sqlDatabaseProjects.Settings": "Database Projects",
|
||||
"sqlDatabaseProjects.netCoreInstallLocation": "Full Path to .Net Core SDK on the machine."
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ export const sqlFileExtension = '.sql';
|
||||
export const schemaCompareExtensionId = 'microsoft.schema-compare';
|
||||
export const sqlDatabaseProjectExtensionId = 'microsoft.sql-database-projects';
|
||||
export const mssqlExtensionId = 'microsoft.mssql';
|
||||
export const dacpac = 'dacpac';
|
||||
export const master = 'master';
|
||||
export const MicrosoftDatatoolsSchemaSqlSql = 'Microsoft.Data.Tools.Schema.Sql.Sql';
|
||||
export const databaseSchemaProvider = 'DatabaseSchemaProvider';
|
||||
|
||||
// UI Strings
|
||||
|
||||
@@ -26,7 +30,13 @@ export const sqlDatabaseProject = localize('sqlDatabaseProject', "SQL database p
|
||||
export const yesString = localize('yesString', "Yes");
|
||||
export const noString = localize('noString', "No");
|
||||
export const extractTargetInput = localize('extractTargetInput', "Target for extraction:");
|
||||
export const selectFileFolder = localize('selectFileFolder', "Select");
|
||||
export const selectString = localize('selectString', "Select");
|
||||
export const addDatabaseReferenceInput = localize('addDatabaseReferenceInput', "Add database reference for:");
|
||||
export const databaseReferenceLocation = localize('databaseReferenceLocation', "Database location");
|
||||
export const databaseReferenceSameDatabase = localize('databaseReferenceSameDatabase', "Same database");
|
||||
export const databaseReferenceDifferentDabaseSameServer = localize('databaseReferenceDifferentDabaseSameServer', "Different database, same server");
|
||||
export const databaseReferenceDatabaseName = localize('databaseReferenceDatabaseName', "Database name");
|
||||
export const dacpacFiles = localize('dacpacFiles', "dacpac Files");
|
||||
export function newObjectNamePrompt(objectType: string) { return localize('newObjectNamePrompt', 'New {0} name:', objectType); }
|
||||
|
||||
// Deploy dialog strings
|
||||
@@ -63,6 +73,11 @@ export const extractTargetRequired = localize('extractTargetRequired', "Target i
|
||||
export const schemaCompareNotInstalled = localize('schemaCompareNotInstalled', "Schema compare extension installation is required to run schema compare");
|
||||
export const buildDacpacNotFound = localize('buildDacpacNotFound', "Dacpac created from build not found");
|
||||
export const updateProjectForRoundTrip = localize('updateProjectForRoundTrip', "To build this project, Azure Data Studio needs to update targets and references. If the project is created in SSDT, it will continue to work in both tools. Do you want Azure Data Studio to update the project?");
|
||||
export const databaseReferenceTypeRequired = localize('databaseReferenceTypeRequired', "Database reference type is required for adding a reference to a database");
|
||||
export const dacpacFileLocationRequired = localize('dacpacFileLocationRequired', "Dacpac file location is required for adding a reference to a database");
|
||||
export const databaseLocationRequired = localize('databaseLocation', "Database location is required for adding a reference to a database");
|
||||
export const databaseNameRequired = localize('databaseNameRequired', "Database name is required for adding a reference to a different database");
|
||||
export const invalidDataSchemaProvider = localize('invalidDataSchemaProvider', "Invalid DSP in .sqlproj file");
|
||||
export function projectAlreadyOpened(path: string) { return localize('projectAlreadyOpened', "Project '{0}' is already opened.", path); }
|
||||
export function projectAlreadyExists(name: string, path: string) { return localize('projectAlreadyExists', "A project named {0} already exists in {1}.", name, path); }
|
||||
export function noFileExist(fileName: string) { return localize('noFileExist', "File {0} doesn't exist", fileName); }
|
||||
@@ -91,6 +106,10 @@ export const Condition = 'Condition';
|
||||
export const PackageReference = 'PackageReference';
|
||||
export const Version = 'Version';
|
||||
export const PrivateAssets = 'PrivateAssets';
|
||||
export const ArtifactReference = 'ArtifactReference';
|
||||
export const SuppressMissingDependenciesErrors = 'SuppressMissingDependenciesErrors';
|
||||
export const DatabaseVariableLiteralValue = 'DatabaseVariableLiteralValue';
|
||||
export const DSP = 'DSP';
|
||||
|
||||
// SqlProj File targets
|
||||
export const NetCoreTargets = '$(NETCoreTargetsPath)\\Microsoft.Data.Tools.Schema.SqlTasks.targets';
|
||||
|
||||
@@ -64,6 +64,8 @@ export default class MainController implements Disposable {
|
||||
|
||||
this.apiWrapper.registerCommand('sqlDatabaseProjects.importDatabase', async (profile: azdata.IConnectionProfile) => { await this.projectsController.importNewDatabaseProject(profile); });
|
||||
|
||||
this.apiWrapper.registerCommand('sqlDatabaseProjects.addDatabaseReference', async (node: BaseProjectTreeItem) => { await this.projectsController.addDatabaseReference(node); });
|
||||
|
||||
// init view
|
||||
this.extensionContext.subscriptions.push(this.apiWrapper.registerTreeDataProvider(SQL_DATABASE_PROJECTS_VIEW_ID, this.dbProjectTreeViewProvider));
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { IConnectionProfile, TaskExecutionMode } from 'azdata';
|
||||
import { promises as fs } from 'fs';
|
||||
import { ApiWrapper } from '../common/apiWrapper';
|
||||
import { DeployDatabaseDialog } from '../dialogs/deployDatabaseDialog';
|
||||
import { Project } from '../models/project';
|
||||
import { Project, DatabaseReferenceLocation } from '../models/project';
|
||||
import { SqlDatabaseProjectTreeViewProvider } from './databaseProjectTreeViewProvider';
|
||||
import { FolderNode } from '../models/tree/fileFolderTreeItem';
|
||||
import { IDeploymentProfile, IGenerateScriptProfile } from '../models/IDeploymentProfile';
|
||||
@@ -292,6 +292,118 @@ export class ProjectsController {
|
||||
this.refreshProjectsTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a database reference to the project
|
||||
* @param treeNode a treeItem in a project's hierarchy, to be used to obtain a Project
|
||||
*/
|
||||
public async addDatabaseReference(context: Project | BaseProjectTreeItem): Promise<void> {
|
||||
const project = ProjectsController.getProjectFromContext(context);
|
||||
|
||||
try {
|
||||
// choose if reference is to master or a dacpac
|
||||
const databaseReferenceType = await this.getDatabaseReferenceType();
|
||||
|
||||
// if master is selected, we know which dacpac needs to be added
|
||||
if (databaseReferenceType === constants.master) {
|
||||
await project.addMasterDatabaseReference();
|
||||
} else {
|
||||
// get other information needed to add a reference to the dacpac
|
||||
const dacpacFileLocation = await this.getDacpacFileLocation();
|
||||
const databaseLocation = await this.getDatabaseLocation();
|
||||
|
||||
if (databaseLocation === DatabaseReferenceLocation.differentDatabaseSameServer) {
|
||||
const databaseName = await this.getDatabaseName(dacpacFileLocation);
|
||||
await project.addDatabaseReference(dacpacFileLocation, <DatabaseReferenceLocation>databaseLocation, databaseName);
|
||||
} else {
|
||||
await project.addDatabaseReference(dacpacFileLocation, <DatabaseReferenceLocation>databaseLocation);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
this.apiWrapper.showErrorMessage(utils.getErrorMessage(err));
|
||||
}
|
||||
}
|
||||
|
||||
private async getDatabaseReferenceType(): Promise<string> {
|
||||
let databaseReferenceOptions: QuickPickItem[] = [
|
||||
{
|
||||
label: constants.master
|
||||
},
|
||||
{
|
||||
label: constants.dacpac
|
||||
}
|
||||
];
|
||||
|
||||
let input = await this.apiWrapper.showQuickPick(databaseReferenceOptions, {
|
||||
canPickMany: false,
|
||||
placeHolder: constants.addDatabaseReferenceInput
|
||||
});
|
||||
|
||||
if (!input) {
|
||||
throw new Error(constants.databaseReferenceTypeRequired);
|
||||
}
|
||||
|
||||
return input.label;
|
||||
}
|
||||
|
||||
private async getDacpacFileLocation(): Promise<Uri> {
|
||||
let fileUris = await this.apiWrapper.showOpenDialog(
|
||||
{
|
||||
canSelectFiles: true,
|
||||
canSelectFolders: false,
|
||||
canSelectMany: false,
|
||||
defaultUri: this.apiWrapper.workspaceFolders() ? (this.apiWrapper.workspaceFolders() as WorkspaceFolder[])[0].uri : undefined,
|
||||
openLabel: constants.selectString,
|
||||
filters: {
|
||||
[constants.dacpacFiles]: ['dacpac'],
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (!fileUris || fileUris.length === 0) {
|
||||
throw new Error(constants.dacpacFileLocationRequired);
|
||||
}
|
||||
|
||||
return fileUris[0];
|
||||
}
|
||||
|
||||
private async getDatabaseLocation(): Promise<DatabaseReferenceLocation> {
|
||||
let databaseReferenceOptions: QuickPickItem[] = [
|
||||
{
|
||||
label: constants.databaseReferenceSameDatabase
|
||||
},
|
||||
{
|
||||
label: constants.databaseReferenceDifferentDabaseSameServer
|
||||
}
|
||||
];
|
||||
|
||||
let input = await this.apiWrapper.showQuickPick(databaseReferenceOptions, {
|
||||
canPickMany: false,
|
||||
placeHolder: constants.databaseReferenceLocation
|
||||
});
|
||||
|
||||
if (input === undefined) {
|
||||
throw new Error(constants.databaseLocationRequired);
|
||||
}
|
||||
|
||||
const location = input?.label === constants.databaseReferenceSameDatabase ? DatabaseReferenceLocation.sameDatabase : DatabaseReferenceLocation.differentDatabaseSameServer;
|
||||
return location;
|
||||
}
|
||||
|
||||
private async getDatabaseName(dacpac: Uri): Promise<string | undefined> {
|
||||
const dacpacName = path.parse(dacpac.toString()).name;
|
||||
let databaseName = await this.apiWrapper.showInputBox({
|
||||
prompt: constants.databaseReferenceDatabaseName,
|
||||
value: `${dacpacName}`
|
||||
});
|
||||
|
||||
if (!databaseName) {
|
||||
throw new Error(constants.databaseNameRequired);
|
||||
}
|
||||
|
||||
databaseName = databaseName?.trim();
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
//#region Helper methods
|
||||
|
||||
public getDeployDialog(project: Project): DeployDatabaseDialog {
|
||||
@@ -497,7 +609,7 @@ export class ProjectsController {
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
openLabel: constants.selectFileFolder,
|
||||
openLabel: constants.selectString,
|
||||
defaultUri: this.apiWrapper.workspaceFolders() ? (this.apiWrapper.workspaceFolders() as WorkspaceFolder[])[0].uri : undefined
|
||||
});
|
||||
if (selectionResult) {
|
||||
@@ -508,7 +620,7 @@ export class ProjectsController {
|
||||
selectionResult = await this.apiWrapper.showSaveDialog(
|
||||
{
|
||||
defaultUri: this.apiWrapper.workspaceFolders() ? (this.apiWrapper.workspaceFolders() as WorkspaceFolder[])[0].uri : undefined,
|
||||
saveLabel: constants.selectFileFolder,
|
||||
saveLabel: constants.selectString,
|
||||
filters: {
|
||||
'SQL files': ['sql'],
|
||||
'All files': ['*']
|
||||
|
||||
@@ -133,6 +133,57 @@ export class Project {
|
||||
return fileEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compat level of the project
|
||||
* Just used in tests right now, but can be used later if this functionality is added to the UI
|
||||
* @param compatLevel compat level of project
|
||||
*/
|
||||
public changeDSP(compatLevel: string): void {
|
||||
const newDSP = `${constants.MicrosoftDatatoolsSchemaSqlSql}${compatLevel}${constants.databaseSchemaProvider}`;
|
||||
this.projFileXmlDoc.getElementsByTagName(constants.DSP)[0].childNodes[0].nodeValue = newDSP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds reference to the appropriate master dacpac to the project
|
||||
*/
|
||||
public async addMasterDatabaseReference(): Promise<void> {
|
||||
const uri = this.getMasterDacpac();
|
||||
this.addDatabaseReference(uri, DatabaseReferenceLocation.differentDatabaseSameServer, constants.master);
|
||||
}
|
||||
|
||||
public getMasterDacpac(): Uri {
|
||||
// check for invalid DSP
|
||||
if (this.projFileXmlDoc.getElementsByTagName(constants.DSP).length !== 1 || this.projFileXmlDoc.getElementsByTagName(constants.DSP)[0].childNodes.length !== 1) {
|
||||
throw new Error(constants.invalidDataSchemaProvider);
|
||||
}
|
||||
|
||||
let dsp: string = this.projFileXmlDoc.getElementsByTagName(constants.DSP)[0].childNodes[0].nodeValue;
|
||||
|
||||
// get version from dsp, which is a string like Microsoft.Data.Tools.Schema.Sql.Sql130DatabaseSchemaProvider
|
||||
// remove part before the number
|
||||
let version: any = dsp.substring(constants.MicrosoftDatatoolsSchemaSqlSql.length);
|
||||
// remove DatabaseSchemaProvider
|
||||
version = version.substring(0, version.length - constants.databaseSchemaProvider.length);
|
||||
|
||||
// make sure version is valid
|
||||
console.error(Object.values(TargetPlatform));
|
||||
if (!Object.values(TargetPlatform).includes(version)) {
|
||||
throw new Error(constants.invalidDataSchemaProvider);
|
||||
}
|
||||
|
||||
return Uri.parse(path.join('$(NETCoreTargetsPath)', 'SystemDacpacs', version, 'master.dacpac'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds reference to a dacpac to the project
|
||||
* @param uri Uri of the dacpac
|
||||
* @param databaseName name of the database
|
||||
*/
|
||||
public async addDatabaseReference(uri: Uri, databaseLocation: DatabaseReferenceLocation, databaseName?: string): Promise<void> {
|
||||
let databaseReferenceEntry = new DatabaseReferenceProjectEntry(uri, databaseLocation, databaseName);
|
||||
await this.addToProjFile(databaseReferenceEntry);
|
||||
}
|
||||
|
||||
public createProjectEntry(relativePath: string, entryType: EntryType): ProjectEntry {
|
||||
return new ProjectEntry(Uri.file(path.join(this.projectFolderPath, relativePath)), relativePath, entryType);
|
||||
}
|
||||
@@ -177,6 +228,26 @@ export class Project {
|
||||
this.findOrCreateItemGroup(constants.Folder).appendChild(newFolderNode);
|
||||
}
|
||||
|
||||
private addDatabaseReferenceToProjFile(entry: DatabaseReferenceProjectEntry): void {
|
||||
const referenceNode = this.projFileXmlDoc.createElement(constants.ArtifactReference);
|
||||
referenceNode.setAttribute(constants.Condition, constants.NetCoreCondition);
|
||||
referenceNode.setAttribute(constants.Include, entry.fsUri.fsPath);
|
||||
|
||||
let suppressMissingDependenciesErrorNode = this.projFileXmlDoc.createElement(constants.SuppressMissingDependenciesErrors);
|
||||
let falseTextNode = this.projFileXmlDoc.createTextNode('False');
|
||||
suppressMissingDependenciesErrorNode.appendChild(falseTextNode);
|
||||
referenceNode.appendChild(suppressMissingDependenciesErrorNode);
|
||||
|
||||
if (entry.databaseLocation === DatabaseReferenceLocation.differentDatabaseSameServer) {
|
||||
let databaseVariableLiteralValue = this.projFileXmlDoc.createElement(constants.DatabaseVariableLiteralValue);
|
||||
let databaseTextNode = this.projFileXmlDoc.createTextNode(entry.name);
|
||||
databaseVariableLiteralValue.appendChild(databaseTextNode);
|
||||
referenceNode.appendChild(databaseVariableLiteralValue);
|
||||
}
|
||||
|
||||
this.findOrCreateItemGroup().appendChild(referenceNode);
|
||||
}
|
||||
|
||||
private async updateImportedTargetsToProjFile(condition: string, projectAttributeVal: string, oldImportNode?: any): Promise<any> {
|
||||
const importNode = this.projFileXmlDoc.createElement(constants.Import);
|
||||
importNode.setAttribute(constants.Condition, condition);
|
||||
@@ -213,6 +284,8 @@ export class Project {
|
||||
break;
|
||||
case EntryType.Folder:
|
||||
this.addFolderToProjFile(entry.relativePath);
|
||||
case EntryType.DatabaseReference:
|
||||
this.addDatabaseReferenceToProjFile(<DatabaseReferenceProjectEntry>entry);
|
||||
}
|
||||
|
||||
await this.serializeToProjFile(this.projFileXmlDoc);
|
||||
@@ -270,7 +343,33 @@ export class ProjectEntry {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a database reference entry in a project file
|
||||
*/
|
||||
class DatabaseReferenceProjectEntry extends ProjectEntry {
|
||||
constructor(uri: Uri, public databaseLocation: DatabaseReferenceLocation, public name?: string) {
|
||||
super(uri, '', EntryType.DatabaseReference);
|
||||
}
|
||||
}
|
||||
|
||||
export enum EntryType {
|
||||
File,
|
||||
Folder
|
||||
Folder,
|
||||
DatabaseReference
|
||||
}
|
||||
|
||||
export enum DatabaseReferenceLocation {
|
||||
sameDatabase,
|
||||
differentDatabaseSameServer
|
||||
}
|
||||
|
||||
export enum TargetPlatform {
|
||||
Sql90 = '90',
|
||||
Sql100 = '100',
|
||||
Sql110 = '110',
|
||||
Sql120 = '120',
|
||||
Sql130 = '130',
|
||||
Sql140 = '140',
|
||||
Sql150 = '150',
|
||||
SqlAzureV12 = 'AzureV12'
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ export let openProjectFileBaseline: string;
|
||||
export let openDataSourcesBaseline: string;
|
||||
export let SSDTProjectFileBaseline: string;
|
||||
export let SSDTProjectAfterUpdateBaseline: string;
|
||||
export let dacpacReferencesProjectFileBaseline: string;
|
||||
|
||||
const baselineFolderPath = __dirname;
|
||||
|
||||
@@ -21,6 +22,7 @@ export async function loadBaselines() {
|
||||
openDataSourcesBaseline = await loadBaseline(baselineFolderPath, 'openDataSourcesBaseline.json');
|
||||
SSDTProjectFileBaseline = await loadBaseline(baselineFolderPath, 'SSDTProjectBaseline.xml');
|
||||
SSDTProjectAfterUpdateBaseline = await loadBaseline(baselineFolderPath, 'SSDTProjectAfterUpdateBaseline.xml');
|
||||
dacpacReferencesProjectFileBaseline = await loadBaseline(baselineFolderPath, 'dacpacReferencesSqlProjectBaseline.xml');
|
||||
}
|
||||
|
||||
async function loadBaseline(baselineFolderPath: string, fileName: string): Promise<string> {
|
||||
|
||||
@@ -7,10 +7,12 @@ import * as should from 'should';
|
||||
import * as path from 'path';
|
||||
import * as baselines from './baselines/baselines';
|
||||
import * as testUtils from './testUtils';
|
||||
import * as constants from '../common/constants';
|
||||
|
||||
import { promises as fs } from 'fs';
|
||||
import { Project, EntryType } from '../models/project';
|
||||
import { Project, EntryType, TargetPlatform } from '../models/project';
|
||||
import { exists } from '../common/utils';
|
||||
import { Uri } from 'vscode';
|
||||
|
||||
let projFilePath: string;
|
||||
|
||||
@@ -82,6 +84,32 @@ describe('Project: sqlproj content operations', function (): void {
|
||||
|
||||
await testUtils.shouldThrowSpecificError(async () => await project.addToProject(list), `ENOENT: no such file or directory, stat \'${nonexistentFile}\'`);
|
||||
});
|
||||
|
||||
it('Should choose correct master dacpac', async function(): Promise<void> {
|
||||
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||
const project = new Project(projFilePath);
|
||||
await project.readProjFile();
|
||||
|
||||
let uri = project.getMasterDacpac();
|
||||
should.equal(uri.fsPath, Uri.parse(path.join('$(NETCoreTargetsPath)', 'SystemDacpacs', '130', 'master.dacpac')).fsPath);
|
||||
|
||||
project.changeDSP(TargetPlatform.Sql150.toString());
|
||||
uri = project.getMasterDacpac();
|
||||
should.equal(uri.fsPath, Uri.parse(path.join('$(NETCoreTargetsPath)', 'SystemDacpacs', '150', 'master.dacpac')).fsPath);
|
||||
|
||||
project.changeDSP(TargetPlatform.SqlAzureV12.toString());
|
||||
uri = project.getMasterDacpac();
|
||||
should.equal(uri.fsPath, Uri.parse(path.join('$(NETCoreTargetsPath)', 'SystemDacpacs', 'AzureV12', 'master.dacpac')).fsPath);
|
||||
});
|
||||
|
||||
it('Should throw error when choosing correct master dacpac if invalid DSP', async function(): Promise<void> {
|
||||
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||
const project = new Project(projFilePath);
|
||||
await project.readProjFile();
|
||||
|
||||
project.changeDSP('invalidPlatform');
|
||||
await testUtils.shouldThrowSpecificError(async () => await project.getMasterDacpac(), constants.invalidDataSchemaProvider);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Project: round trip updates', function (): void {
|
||||
|
||||
@@ -227,6 +227,36 @@ describe('ProjectsController: import operations', function (): void {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ProjectsController: add database reference operations', function (): void {
|
||||
it('Should show error when no reference type is selected', async function (): Promise<void> {
|
||||
testContext.apiWrapper.setup(x => x.showQuickPick(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(undefined));
|
||||
testContext.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns((s) => { throw new Error(s); });
|
||||
|
||||
const projController = new ProjectsController(testContext.apiWrapper.object, new SqlDatabaseProjectTreeViewProvider());
|
||||
await testUtils.shouldThrowSpecificError(async () => await projController.addDatabaseReference(new Project('FakePath')), constants.databaseReferenceTypeRequired);
|
||||
});
|
||||
|
||||
it('Should show error when no file is selected', async function (): Promise<void> {
|
||||
testContext.apiWrapper.setup(x => x.showQuickPick(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ label: constants.dacpac }));
|
||||
testContext.apiWrapper.setup(x => x.showOpenDialog(TypeMoq.It.isAny())).returns(() => Promise.resolve(undefined));
|
||||
testContext.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns((s) => { throw new Error(s); });
|
||||
|
||||
const projController = new ProjectsController(testContext.apiWrapper.object, new SqlDatabaseProjectTreeViewProvider());
|
||||
await testUtils.shouldThrowSpecificError(async () => await projController.addDatabaseReference(new Project('FakePath')), constants.dacpacFileLocationRequired);
|
||||
});
|
||||
|
||||
it('Should show error when no database name is provided', async function (): Promise<void> {
|
||||
testContext.apiWrapper.setup(x => x.showQuickPick(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ label: constants.dacpac }));
|
||||
testContext.apiWrapper.setup(x => x.showOpenDialog(TypeMoq.It.isAny())).returns(() => Promise.resolve([vscode.Uri.file('FakePath')]));
|
||||
testContext.apiWrapper.setup(x => x.showQuickPick(TypeMoq.It.isAny())).returns(() => Promise.resolve({ label: constants.databaseReferenceDifferentDabaseSameServer }));
|
||||
testContext.apiWrapper.setup(x => x.showInputBox(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(undefined));
|
||||
testContext.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns((s) => { throw new Error(s); });
|
||||
|
||||
const projController = new ProjectsController(testContext.apiWrapper.object, new SqlDatabaseProjectTreeViewProvider());
|
||||
await testUtils.shouldThrowSpecificError(async () => await projController.addDatabaseReference(new Project('FakePath')), constants.databaseNameRequired);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ProjectsController: round trip feature with SSDT', function (): void {
|
||||
it('Should show warning message for SSDT project opened in Azure Data Studio', async function (): Promise<void> {
|
||||
testContext.apiWrapper.setup(x => x.showWarningMessage(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((s) => { throw new Error(s); });
|
||||
|
||||
Reference in New Issue
Block a user