Thanks to visit codestin.com
Credit goes to github.com

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
124 changes: 107 additions & 17 deletions forward_engineering/alterScript/alterScriptFromDeltaHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,57 @@ const getAlterContainersScriptDtos = ({ collection, app, scriptFormat }) => {
return [...addContainersScriptDtos, ...deleteContainersScriptDtos].filter(Boolean);
};

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]);
};

/**
* @param dto {{
* collection: Object,
Expand All @@ -78,6 +129,7 @@ const getAlterCollectionsScriptDtos = ({
internalDefinitions,
externalDefinitions,
scriptFormat,
inlineDeltaRelationships = [],
}) => {
const createScriptsData = []
.concat(collection.properties?.entities?.properties?.added?.items)
Expand All @@ -94,18 +146,20 @@ const getAlterCollectionsScriptDtos = ({
.filter(Boolean)
.map(item => Object.values(item.properties)[0]);

const createCollectionsScriptDtos = createScriptsData
.filter(collection => collection.compMod?.created)
.map(
getAddCollectionScriptDto({
app,
dbVersion,
modelDefinitions,
internalDefinitions,
externalDefinitions,
scriptFormat,
}),
);
const createCollectionsScriptDtos = sortCollectionsByRelationships(
createScriptsData.filter(collection => collection.compMod?.created),
inlineDeltaRelationships,
).map(
getAddCollectionScriptDto({
app,
dbVersion,
modelDefinitions,
internalDefinitions,
externalDefinitions,
scriptFormat,
inlineDeltaRelationships,
}),
);
const deleteCollectionScriptDtos = deleteScriptsData
.filter(collection => collection.compMod?.deleted)
.map(getDeleteCollectionScriptDto(app, scriptFormat));
Expand Down Expand Up @@ -291,7 +345,7 @@ const getAlterModelDefinitionsScriptDtos = ({
/**
* @return Array<AlterScriptDto>
* */
const getAlterRelationshipsScriptDtos = ({ collection, app, scriptFormat }) => {
const getAlterRelationshipsScriptDtos = ({ collection, app, scriptFormat, ignoreRelationshipIDs = [] }) => {
const ddlProvider = require('../ddlProvider/ddlProvider')(
null,
{ targetScriptOptions: { keyword: scriptFormat } },
Expand All @@ -302,19 +356,28 @@ const getAlterRelationshipsScriptDtos = ({ collection, app, scriptFormat }) => {
.concat(collection.properties?.relationships?.properties?.added?.items)
.filter(Boolean)
.map(item => Object.values(item.properties)[0])
.filter(relationship => relationship?.role?.compMod?.created);
.filter(
relationship =>
relationship?.role?.compMod?.created && !ignoreRelationshipIDs.includes(relationship?.role?.id),
);

const deletedRelationships = []
.concat(collection.properties?.relationships?.properties?.deleted?.items)
.filter(Boolean)
.map(item => Object.values(item.properties)[0])
.filter(relationship => relationship?.role?.compMod?.deleted);
.filter(
relationship =>
relationship?.role?.compMod?.deleted && !ignoreRelationshipIDs.includes(relationship?.role?.id),
);

const modifiedRelationships = []
.concat(collection.properties?.relationships?.properties?.modified?.items)
.filter(Boolean)
.map(item => Object.values(item.properties)[0])
.filter(relationship => relationship?.role?.compMod?.modified);
.filter(
relationship =>
relationship?.role?.compMod?.modified && !ignoreRelationshipIDs.includes(relationship?.role?.id),
);

const deleteFkScriptDtos = getDeleteForeignKeyScriptDtos(ddlProvider, scriptFormat)(deletedRelationships);
const addFkScriptDtos = getAddForeignKeyScriptDtos(ddlProvider)(addedRelationships);
Expand Down Expand Up @@ -383,6 +446,24 @@ const getAlterContainersSequencesScriptDtos = ({ collection, app, dbVersion }) =
);
};

const getInlineRelationships = ({ collection, options }) => {
if (options?.scriptGenerationOptions?.feActiveOptions?.foreignKeys !== 'inline') {
return [];
}

const addedCollectionIDs = []
.concat(collection.properties?.entities?.properties?.added?.items)
.filter(item => item && Object.values(item.properties)?.[0]?.compMod?.created)
.map(item => Object.values(item.properties)[0].role.id);

const addedRelationships = []
.concat(collection.properties?.relationships?.properties?.added?.items)
.map(item => item && Object.values(item.properties)[0])
.filter(r => r?.role?.compMod?.created && addedCollectionIDs.includes(r?.role?.childCollection));

return addedRelationships;
};

/**
* @param data {CoreData}
* @param app {App}
Expand All @@ -404,6 +485,9 @@ const getAlterScriptDtos = (data, app) => {

const dbVersion = data.modelData[0]?.dbVersion;

const inlineDeltaRelationships = getInlineRelationships({ collection, options: data.options });
const ignoreRelationshipIDs = inlineDeltaRelationships.map(relationship => relationship.role.id);

const containersScriptDtos = getAlterContainersScriptDtos({ collection, app, scriptFormat });

const collectionsScriptDtos = getAlterCollectionsScriptDtos({
Expand All @@ -414,6 +498,7 @@ const getAlterScriptDtos = (data, app) => {
internalDefinitions,
externalDefinitions,
scriptFormat,
inlineDeltaRelationships,
});

const viewScriptDtos = getAlterViewScriptDtos(collection, app, dbVersion, scriptFormat);
Expand All @@ -428,7 +513,12 @@ const getAlterScriptDtos = (data, app) => {
scriptFormat,
});

const relationshipScriptDtos = getAlterRelationshipsScriptDtos({ collection, app, scriptFormat });
const relationshipScriptDtos = getAlterRelationshipsScriptDtos({
collection,
app,
scriptFormat,
ignoreRelationshipIDs,
});

const containersSequencesScriptDtos = getAlterContainersSequencesScriptDtos({ collection, app, dbVersion });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,21 @@ const { getModifyNonNullColumnsScriptDtos } = require('./columnHelpers/nonNullCo
const { getModifiedDefaultColumnValueScriptDtos } = require('./columnHelpers/defaultValueHelper');
const { getModifyEntityCommentsScriptDtos } = require('./entityHelpers/commentsHelper');
const { getModifiedCommentOnColumnScriptDtos } = require('./columnHelpers/commentsHelper');
const { getRelationshipName } = require('./alterRelationshipsHelper');

/**
* @return {(collection: AlterCollectionDto) => AlterScriptDto | undefined}
* */
const getAddCollectionScriptDto =
({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions, scriptFormat }) =>
({
app,
dbVersion,
modelDefinitions,
internalDefinitions,
externalDefinitions,
scriptFormat,
inlineDeltaRelationships,
}) =>
collection => {
const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(app);
const ddlProvider = require('../../ddlProvider/ddlProvider')(
Expand Down Expand Up @@ -55,11 +64,31 @@ const getAddCollectionScriptDto =
const checkConstraints = (jsonSchema.chkConstr || []).map(check =>
ddlProvider.createCheckConstraint(ddlProvider.hydrateCheckConstraint(check)),
);
const foreignKeyConstraints = inlineDeltaRelationships
.filter(relationship => relationship.role.childCollection === collection.role.id)
.map(relationship => {
const compMod = relationship.role.compMod;
const relationshipName =
compMod.code?.new || compMod.name?.new || getRelationshipName(relationship) || '';
return ddlProvider.createForeignKeyConstraint({
name: relationshipName,
foreignKey: compMod.child.collection.fkFields,
primaryKey: compMod.parent.collection.fkFields,
customProperties: compMod.customProperties?.new,
foreignTable: compMod.child.collection.name,
foreignSchemaName: compMod.child.bucket.name,
foreignTableActivated: compMod.child.collection.isActivated,
primaryTable: compMod.parent.collection.name,
primarySchemaName: compMod.parent.bucket.name,
primaryTableActivated: compMod.parent.collection.isActivated,
isActivated: Boolean(relationship.role?.compMod?.isActivated?.new),
});
});
const tableData = {
name: getEntityName(jsonSchema),
columns: columnDefinitions.map(data => ddlProvider.convertColumnDefinition(data)),
checkConstraints: checkConstraints,
foreignKeyConstraints: [],
foreignKeyConstraints,
schemaData,
columnDefinitions,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,5 @@ module.exports = {
getDeleteForeignKeyScriptDtos,
getModifyForeignKeyScriptDtos,
getAddForeignKeyScriptDtos,
getRelationshipName,
};