mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-16 17:22:29 -05:00
Initial project references changes (#11648)
* first changes for showing project references * add tests * fix interface and formatting * add try so that project still gets loaded even if dependency project loading fails * use instanceof * add circular reference error
This commit is contained in:
@@ -23,7 +23,7 @@ export class Project {
|
||||
public files: ProjectEntry[] = [];
|
||||
public dataSources: DataSource[] = [];
|
||||
public importedTargets: string[] = [];
|
||||
public databaseReferences: DatabaseReferenceProjectEntry[] = [];
|
||||
public databaseReferences: IDatabaseReferenceProjectEntry[] = [];
|
||||
public sqlCmdVariables: Record<string, string> = {};
|
||||
|
||||
public get projectFolderPath() {
|
||||
@@ -91,11 +91,24 @@ export class Project {
|
||||
throw new Error(constants.invalidDatabaseReference);
|
||||
}
|
||||
|
||||
let nameNodes = references[r].getElementsByTagName(constants.DatabaseVariableLiteralValue);
|
||||
let name = nameNodes.length === 1 ? nameNodes[0].childNodes[0].nodeValue : undefined;
|
||||
this.databaseReferences.push(new DatabaseReferenceProjectEntry(Uri.parse(filepath), name ? DatabaseReferenceLocation.differentDatabaseSameServer : DatabaseReferenceLocation.sameDatabase, name));
|
||||
const nameNodes = references[r].getElementsByTagName(constants.DatabaseVariableLiteralValue);
|
||||
const name = nameNodes.length === 1 ? nameNodes[0].childNodes[0].nodeValue : undefined;
|
||||
this.databaseReferences.push(new DacpacReferenceProjectEntry(Uri.file(filepath), name ? DatabaseReferenceLocation.differentDatabaseSameServer : DatabaseReferenceLocation.sameDatabase, name));
|
||||
}
|
||||
}
|
||||
|
||||
// find project references
|
||||
const projectReferences = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ProjectReference);
|
||||
for (let r = 0; r < projectReferences.length; r++) {
|
||||
const filepath = projectReferences[r].getAttribute(constants.Include);
|
||||
if (!filepath) {
|
||||
throw new Error(constants.invalidDatabaseReference);
|
||||
}
|
||||
|
||||
const nameNodes = projectReferences[r].getElementsByTagName(constants.Name);
|
||||
const name = nameNodes[0].childNodes[0].nodeValue;
|
||||
this.databaseReferences.push(new SqlProjectReferenceProjectEntry(Uri.file(utils.getPlatformSafeFileEntryPath(filepath)), name));
|
||||
}
|
||||
}
|
||||
|
||||
public async updateProjectForRoundTrip() {
|
||||
@@ -284,7 +297,7 @@ export class Project {
|
||||
* @param databaseName name of the database
|
||||
*/
|
||||
public async addDatabaseReference(uri: Uri, databaseLocation: DatabaseReferenceLocation, databaseName?: string): Promise<void> {
|
||||
let databaseReferenceEntry = new DatabaseReferenceProjectEntry(uri, databaseLocation, databaseName);
|
||||
let databaseReferenceEntry = new DacpacReferenceProjectEntry(uri, databaseLocation, databaseName);
|
||||
await this.addToProjFile(databaseReferenceEntry);
|
||||
}
|
||||
|
||||
@@ -359,7 +372,7 @@ export class Project {
|
||||
throw new Error(constants.unableToFindObject(path, constants.folderObject));
|
||||
}
|
||||
|
||||
private addDatabaseReferenceToProjFile(entry: DatabaseReferenceProjectEntry): void {
|
||||
private addDatabaseReferenceToProjFile(entry: IDatabaseReferenceProjectEntry): void {
|
||||
// check if reference to this database already exists
|
||||
if (this.databaseReferenceExists(entry)) {
|
||||
throw new Error(constants.databaseReferenceAlreadyExists);
|
||||
@@ -374,7 +387,7 @@ export class Project {
|
||||
}
|
||||
|
||||
referenceNode.setAttribute(constants.Include, entry.pathForSqlProj());
|
||||
this.addDatabaseReferenceChildren(referenceNode, entry.name);
|
||||
this.addDatabaseReferenceChildren(referenceNode, entry.sqlCmdName);
|
||||
this.findOrCreateItemGroup(constants.ArtifactReference).appendChild(referenceNode);
|
||||
this.databaseReferences.push(entry);
|
||||
|
||||
@@ -383,12 +396,12 @@ export class Project {
|
||||
let ssdtReferenceNode = this.projFileXmlDoc.createElement(constants.ArtifactReference);
|
||||
ssdtReferenceNode.setAttribute(constants.Condition, constants.NotNetCoreCondition);
|
||||
ssdtReferenceNode.setAttribute(constants.Include, (<SystemDatabaseReferenceProjectEntry>entry).ssdtPathForSqlProj());
|
||||
this.addDatabaseReferenceChildren(ssdtReferenceNode, entry.name);
|
||||
this.addDatabaseReferenceChildren(ssdtReferenceNode, entry.sqlCmdName);
|
||||
this.findOrCreateItemGroup(constants.ArtifactReference).appendChild(ssdtReferenceNode);
|
||||
}
|
||||
}
|
||||
|
||||
private databaseReferenceExists(entry: DatabaseReferenceProjectEntry): boolean {
|
||||
private databaseReferenceExists(entry: IDatabaseReferenceProjectEntry): boolean {
|
||||
const found = this.databaseReferences.find(reference => reference.fsUri.fsPath === entry.fsUri.fsPath) !== undefined;
|
||||
return found;
|
||||
}
|
||||
@@ -479,7 +492,7 @@ export class Project {
|
||||
this.addFolderToProjFile(entry.relativePath);
|
||||
break;
|
||||
case EntryType.DatabaseReference:
|
||||
this.addDatabaseReferenceToProjFile(<DatabaseReferenceProjectEntry>entry);
|
||||
this.addDatabaseReferenceToProjFile(<IDatabaseReferenceProjectEntry>entry);
|
||||
break; // not required but adding so that we dont miss when we add new items
|
||||
}
|
||||
|
||||
@@ -567,9 +580,18 @@ export class ProjectEntry {
|
||||
/**
|
||||
* Represents a database reference entry in a project file
|
||||
*/
|
||||
export class DatabaseReferenceProjectEntry extends ProjectEntry {
|
||||
constructor(uri: Uri, public databaseLocation: DatabaseReferenceLocation, public name?: string) {
|
||||
|
||||
export interface IDatabaseReferenceProjectEntry extends ProjectEntry {
|
||||
databaseName: string;
|
||||
sqlCmdName?: string | undefined;
|
||||
}
|
||||
|
||||
export class DacpacReferenceProjectEntry extends ProjectEntry implements IDatabaseReferenceProjectEntry {
|
||||
sqlCmdName: string | undefined;
|
||||
|
||||
constructor(uri: Uri, public databaseLocation: DatabaseReferenceLocation, name?: string) {
|
||||
super(uri, '', EntryType.DatabaseReference);
|
||||
this.sqlCmdName = name;
|
||||
}
|
||||
|
||||
public get databaseName(): string {
|
||||
@@ -577,9 +599,10 @@ export class DatabaseReferenceProjectEntry extends ProjectEntry {
|
||||
}
|
||||
}
|
||||
|
||||
class SystemDatabaseReferenceProjectEntry extends DatabaseReferenceProjectEntry {
|
||||
constructor(uri: Uri, public ssdtUri: Uri, public name: string) {
|
||||
class SystemDatabaseReferenceProjectEntry extends DacpacReferenceProjectEntry {
|
||||
constructor(uri: Uri, public ssdtUri: Uri, name: string) {
|
||||
super(uri, DatabaseReferenceLocation.differentDatabaseSameServer, name);
|
||||
this.sqlCmdName = name;
|
||||
}
|
||||
|
||||
public pathForSqlProj(): string {
|
||||
@@ -593,6 +616,19 @@ class SystemDatabaseReferenceProjectEntry extends DatabaseReferenceProjectEntry
|
||||
}
|
||||
}
|
||||
|
||||
export class SqlProjectReferenceProjectEntry extends ProjectEntry implements IDatabaseReferenceProjectEntry {
|
||||
projectName: string;
|
||||
|
||||
constructor(uri: Uri, name: string) {
|
||||
super(uri, '', EntryType.DatabaseReference);
|
||||
this.projectName = name;
|
||||
}
|
||||
|
||||
public get databaseName(): string {
|
||||
return this.projectName;
|
||||
}
|
||||
}
|
||||
|
||||
export enum EntryType {
|
||||
File,
|
||||
Folder,
|
||||
|
||||
@@ -57,8 +57,8 @@ async function readConnectionString(xmlDoc: any): Promise<{ connectionId: string
|
||||
let targetConnectionString: string = '';
|
||||
let connId: string = '';
|
||||
|
||||
if (xmlDoc.documentElement.getElementsByTagName('TargetConnectionString').length > 0) {
|
||||
targetConnectionString = xmlDoc.documentElement.getElementsByTagName('TargetConnectionString')[0].textContent;
|
||||
if (xmlDoc.documentElement.getElementsByTagName(constants.targetConnectionString).length > 0) {
|
||||
targetConnectionString = xmlDoc.documentElement.getElementsByTagName(constants.TargetConnectionString)[0].textContent;
|
||||
const dataSource = new SqlConnectionDataSource('temp', targetConnectionString);
|
||||
const connectionProfile = dataSource.getConnectionProfile();
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import * as constants from '../../common/constants';
|
||||
import { BaseProjectTreeItem } from './baseTreeItem';
|
||||
import { ProjectRootTreeItem } from './projectTreeItem';
|
||||
import { IconPathHelper } from '../../common/iconHelper';
|
||||
import { DatabaseReferenceProjectEntry } from '../../models/project';
|
||||
import { IDatabaseReferenceProjectEntry } from '../../models/project';
|
||||
|
||||
/**
|
||||
* Folder for containing references nodes in the tree
|
||||
@@ -44,7 +44,7 @@ export class DatabaseReferencesTreeItem extends BaseProjectTreeItem {
|
||||
}
|
||||
|
||||
export class DatabaseReferenceTreeItem extends BaseProjectTreeItem {
|
||||
constructor(private reference: DatabaseReferenceProjectEntry, referencesTreeItem: DatabaseReferencesTreeItem) {
|
||||
constructor(private reference: IDatabaseReferenceProjectEntry, referencesTreeItem: DatabaseReferencesTreeItem) {
|
||||
super(vscode.Uri.file(path.join(referencesTreeItem.uri.path, reference.databaseName)), referencesTreeItem);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user