Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion forward_engineering/generateContainerScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,44 @@ const { parseEntities } = require('./helpers/parseEntities');
const { getWorkloadManagementStatements } = require('./helpers/getWorkloadManagementStatements');
const { getIsPkOrFkConstraintAvailable } = require('./helpers/constraintHelper');

const sortEntitiesByForeignKeyDependencies = ({ entities, relationships }) => {
const entitySet = new Set(entities);
const childrenMap = new Map();
const inDegree = new Map();

entities.forEach(entityId => {
inDegree.set(entityId, 0);
childrenMap.set(entityId, []);
});

relationships.forEach(relationship => {
const { parentCollection, childCollection } = relationship;
if (entitySet.has(parentCollection) && entitySet.has(childCollection) && parentCollection !== childCollection) {
childrenMap.get(parentCollection).push(childCollection);
inDegree.set(childCollection, (inDegree.get(childCollection) || 0) + 1);
}
});

const queue = entities.filter(entityId => (inDegree.get(entityId) || 0) === 0);
const sorted = [];

while (queue.length > 0) {
const current = queue.shift();
sorted.push(current);

childrenMap.get(current).forEach(child => {
const newDegree = (inDegree.get(child) || 0) - 1;
inDegree.set(child, newDegree);
if (newDegree === 0) {
queue.push(child);
}
});
}

const remaining = entities.filter(entityId => !sorted.includes(entityId));
return sorted.concat(remaining);
};

const generateContainerScript = (data, logger, callback, app) => {
try {
const containerData = data.containerData;
Expand Down Expand Up @@ -59,7 +97,12 @@ const generateContainerScript = (data, logger, callback, app) => {
relatedSchemas: relatedSchemas,
});

const entities = data.entities.reduce((result, entityId) => {
const sortedEntities = sortEntitiesByForeignKeyDependencies({
entities: data.entities,
relationships: data.relationships,
});

const entities = sortedEntities.reduce((result, entityId) => {
const foreignKeys = foreignKeyHelper.getForeignKeyStatementsByHashItem(foreignKeyHashTable[entityId] || {});

const args = [
Expand Down
63 changes: 58 additions & 5 deletions forward_engineering/helpers/alterScriptFromDeltaHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,57 @@ const getAlterContainersScripts = (schema, provider) => {
};
};

const sortCollectionsByRelationships = (collections, relationships) => {
const collectionToChildren = new Map(); // Map of collection IDs to their children
const collectionParentCount = new Map(); // Track how many parents each collection has

// Initialize maps
for (const collection of collections) {
collectionToChildren.set(collection.role.id, []);
collectionParentCount.set(collection.role.id, 0);
}

for (const relationship of relationships) {
const parent = relationship.role.parentCollection;
const child = relationship.role.childCollection;
if (collectionToChildren.has(parent)) {
collectionToChildren.get(parent).push(child);
}
collectionParentCount.set(child, (collectionParentCount.get(child) || 0) + 1);
}

// Find collections with no parents
const queue = collections
.filter(collection => collectionParentCount.get(collection.role.id) === 0)
.map(collection => collection.role.id);

const sortedIds = [];

// Sort collections
while (queue.length > 0) {
const current = queue.shift();
sortedIds.push(current);

for (const child of collectionToChildren.get(current) || []) {
collectionParentCount.set(child, collectionParentCount.get(child) - 1);
if (collectionParentCount.get(child) <= 0) {
queue.push(child);
}
}
}

// Add any unvisited collection
for (const collection of collections) {
if (!sortedIds.includes(collection.role.id)) {
sortedIds.unshift(collection.role.id);
}
}

// Map back to collection objects in sorted order
const idToCollection = Object.fromEntries(collections.map(c => [c.role.id, c]));
return sortedIds.map(id => idToCollection[id]);
};

const getAlterCollectionsScripts = ({ schema, definitions, provider, data, inlineDeltaRelationships }) => {
let currentSchemaName = '';

Expand All @@ -55,11 +106,13 @@ const getAlterCollectionsScripts = ({ schema, definitions, provider, data, inlin
const deletedCollectionsItems = getItems(schema, 'entities', 'deleted');
const modifiedCollectionsItems = getItems(schema, 'entities', 'modified');

const addedCollectionsScripts = addedCollectionsItems
.filter(item => item.compMod?.created)
.flatMap(item =>
setCurrentSchemaName(item, getAddCollectionsScripts(definitions, data, inlineDeltaRelationships)),
);
const addedCollectionsScripts = sortCollectionsByRelationships(
addedCollectionsItems.filter(collection => collection.compMod?.created),
inlineDeltaRelationships,
).flatMap(item =>
setCurrentSchemaName(item, getAddCollectionsScripts(definitions, data, inlineDeltaRelationships)),
);

const deletedCollectionsScripts = deletedCollectionsItems
.filter(item => item.compMod?.deleted)
.flatMap(getDeleteCollectionsScripts(provider));
Expand Down