Skip to content

Commit 1e5aee7

Browse files
HCK-13083: generate FK in delta models inline or separate (#168)
* HCK-13083: generate FK in delta models inline or separate * fix
1 parent 2c32d12 commit 1e5aee7

File tree

4 files changed

+118
-13
lines changed

4 files changed

+118
-13
lines changed

forward_engineering/ddlProvider.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ module.exports = (baseProvider, options, app) => {
299299

300300
return {
301301
statement: assignTemplates(templates.createForeignKeyConstraint, {
302-
primaryTable: getTableName(primaryTable, primarySchemaName || schemaData.schemaName, true),
302+
primaryTable: getTableName(primaryTable, primarySchemaName || schemaData?.schemaName, true),
303303
name: wrapInBrackets(relationshipName),
304304
foreignKey: isActivated ? foreignKeysToString(foreignKey) : foreignActiveKeysToString(foreignKey),
305305
primaryKey: isActivated ? foreignKeysToString(primaryKey) : foreignActiveKeysToString(primaryKey),

forward_engineering/helpers/alterScriptFromDeltaHelper.js

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,61 @@ module.exports = _ => {
5252
return { addContainersScriptsDtos, deleteContainersScriptsDtos };
5353
};
5454

55+
const sortCollectionsByRelationships = (collections, relationships) => {
56+
const collectionToChildren = new Map(); // Map of collection IDs to their children
57+
const collectionParentCount = new Map(); // Track how many parents each collection has
58+
59+
// Initialize maps
60+
for (const collection of collections) {
61+
collectionToChildren.set(collection.role.id, []);
62+
collectionParentCount.set(collection.role.id, 0);
63+
}
64+
65+
for (const relationship of relationships) {
66+
const parent = relationship.role.parentCollection;
67+
const child = relationship.role.childCollection;
68+
if (collectionToChildren.has(parent)) {
69+
collectionToChildren.get(parent).push(child);
70+
}
71+
collectionParentCount.set(child, (collectionParentCount.get(child) || 0) + 1);
72+
}
73+
74+
// Find collections with no parents
75+
const queue = collections
76+
.filter(collection => collectionParentCount.get(collection.role.id) === 0)
77+
.map(collection => collection.role.id);
78+
79+
const sortedIds = [];
80+
81+
// Sort collections
82+
while (queue.length > 0) {
83+
const current = queue.shift();
84+
sortedIds.push(current);
85+
86+
for (const child of collectionToChildren.get(current) || []) {
87+
collectionParentCount.set(child, collectionParentCount.get(child) - 1);
88+
if (collectionParentCount.get(child) <= 0) {
89+
queue.push(child);
90+
}
91+
}
92+
}
93+
94+
// Add any unvisited collection
95+
for (const collection of collections) {
96+
if (!sortedIds.includes(collection.role.id)) {
97+
sortedIds.unshift(collection.role.id);
98+
}
99+
}
100+
101+
// Map back to collection objects in sorted order
102+
const idToCollection = Object.fromEntries(collections.map(c => [c.role.id, c]));
103+
return sortedIds.map(id => idToCollection[id]);
104+
};
105+
55106
/**
56107
* @return {{ [key: string]: Array<AlterScriptDto>}}}
57108
* */
58-
const getAlterCollectionsScriptsDtos = (collection, app, options) => {
109+
const getAlterCollectionsScriptsDtos = (collection, app, options, inlineDeltaRelationships = []) => {
59110
const {
60111
getAddCollectionScriptDto,
61112
getDeleteCollectionScriptDto,
@@ -80,9 +131,10 @@ module.exports = _ => {
80131
.filter(Boolean)
81132
.map(item => Object.values(item.properties)[0]);
82133

83-
const createCollectionsScriptsDtos = createScriptsData
84-
.filter(collection => collection.compMod?.created)
85-
.flatMap(getAddCollectionScriptDto);
134+
const createCollectionsScriptsDtos = sortCollectionsByRelationships(
135+
createScriptsData.filter(collection => collection.compMod?.created),
136+
inlineDeltaRelationships,
137+
).flatMap(collection => getAddCollectionScriptDto(collection, inlineDeltaRelationships));
86138
const deleteCollectionScriptsDtos = deleteScriptsData
87139
.filter(collection => collection.compMod?.deleted)
88140
.flatMap(getDeleteCollectionScriptDto);
@@ -175,7 +227,7 @@ module.exports = _ => {
175227
return { deleteUdtScriptsDtos, createUdtScriptsDtos };
176228
};
177229

178-
const getAlterRelationshipsScriptDtos = (collection, app) => {
230+
const getAlterRelationshipsScriptDtos = (collection, app, ignoreRelationshipIDs = []) => {
179231
const _ = app.require('lodash');
180232
const ddlProvider = require('../ddlProvider')(null, null, app);
181233
const {
@@ -188,17 +240,26 @@ module.exports = _ => {
188240
.concat(collection.properties?.relationships?.properties?.added?.items)
189241
.filter(Boolean)
190242
.map(item => Object.values(item.properties)[0])
191-
.filter(relationship => relationship?.role?.compMod?.created);
243+
.filter(
244+
relationship =>
245+
relationship?.role?.compMod?.created && !ignoreRelationshipIDs.includes(relationship?.role?.id),
246+
);
192247
const deletedRelationships = []
193248
.concat(collection.properties?.relationships?.properties?.deleted?.items)
194249
.filter(Boolean)
195250
.map(item => Object.values(item.properties)[0])
196-
.filter(relationship => relationship?.role?.compMod?.deleted);
251+
.filter(
252+
relationship =>
253+
relationship?.role?.compMod?.deleted && !ignoreRelationshipIDs.includes(relationship?.role?.id),
254+
);
197255
const modifiedRelationships = []
198256
.concat(collection.properties?.relationships?.properties?.modified?.items)
199257
.filter(Boolean)
200258
.map(item => Object.values(item.properties)[0])
201-
.filter(relationship => relationship?.role?.compMod?.modified);
259+
.filter(
260+
relationship =>
261+
relationship?.role?.compMod?.modified && !ignoreRelationshipIDs.includes(relationship?.role?.id),
262+
);
202263

203264
const deleteFkScriptDtos = getDeleteForeignKeyScriptDtos(ddlProvider, _)(deletedRelationships);
204265
const addFkScriptDtos = getAddForeignKeyScriptDtos(ddlProvider, _)(addedRelationships);
@@ -349,19 +410,39 @@ module.exports = _ => {
349410
return assertNoEmptyStatements(scripts);
350411
};
351412

413+
const getInlineRelationships = ({ collection, options }) => {
414+
if (options?.scriptGenerationOptions?.feActiveOptions?.foreignKeys !== 'inline') {
415+
return [];
416+
}
417+
418+
const addedCollectionIDs = []
419+
.concat(collection.properties?.entities?.properties?.added?.items)
420+
.filter(item => item && Object.values(item.properties)?.[0]?.compMod?.created)
421+
.map(item => Object.values(item.properties)[0].role.id);
422+
423+
const addedRelationships = []
424+
.concat(collection.properties?.relationships?.properties?.added?.items)
425+
.map(item => item && Object.values(item.properties)[0])
426+
.filter(r => r?.role?.compMod?.created && addedCollectionIDs.includes(r?.role?.childCollection));
427+
428+
return addedRelationships;
429+
};
430+
352431
/**
353432
* @return Array<AlterScriptDto>
354433
* */
355434
const getAlterScriptDtos = (collection, app, options) => {
435+
const inlineDeltaRelationships = getInlineRelationships({ collection, options });
436+
const ignoreRelationshipIDs = inlineDeltaRelationships.map(relationship => relationship.role.id);
356437
const script = {
357-
...getAlterCollectionsScriptsDtos(collection, app, options),
438+
...getAlterCollectionsScriptsDtos(collection, app, options, inlineDeltaRelationships),
358439
...getAlterContainersScriptsDtos(collection, app, options),
359440
...getAlterViewScriptsDtos(collection, app, options),
360441
...getAlterModelDefinitionsScriptsDtos(collection, app, options),
361442
...getContainersCommentsAlterScriptsDtos(collection, app, options),
362443
...getCollectionsCommentsAlterScriptsDtos(collection, app, options),
363444
...getViewsCommentsAlterScriptsDtos(collection, app, options),
364-
...getAlterRelationshipsScriptDtos(collection, app),
445+
...getAlterRelationshipsScriptDtos(collection, app, ignoreRelationshipIDs),
365446
};
366447

367448
return [

forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ module.exports = (app, options) => {
2020
const { getModifyPkConstraintsScriptDtos } = require('./entityHelpers/primaryKeyHelper');
2121
const { getModifyNonNullColumnsScriptDtos } = require('./columnHelpers/notNullConstraintsHelper');
2222
const { getModifyUniqueConstraintsScriptDtos } = require('./entityHelpers/uniqueConstraintHelper');
23+
const { getRelationshipName } = require('./alterRelationshipsHelper');
2324

2425
/**
2526
* @param {Collection} collection
2627
* @return Array<AlterScriptDto>
2728
* */
28-
const getAddCollectionScriptDto = collection => {
29+
const getAddCollectionScriptDto = (collection, inlineDeltaRelationships) => {
2930
//done but need clean up
3031
const schemaName = collection.compMod.keyspaceName;
3132
const schemaData = { schemaName };
@@ -45,11 +46,33 @@ module.exports = (app, options) => {
4546
const checkConstraints = (jsonSchema.chkConstr || []).map(check =>
4647
ddlProvider.createCheckConstraint(ddlProvider.hydrateCheckConstraint(check)),
4748
);
49+
50+
const foreignKeyConstraints = inlineDeltaRelationships
51+
.filter(relationship => relationship.role.childCollection === collection.role.id)
52+
.map(relationship => {
53+
const compMod = relationship.role.compMod;
54+
const relationshipName =
55+
compMod.code?.new || compMod.name?.new || getRelationshipName(relationship) || '';
56+
return ddlProvider.createForeignKeyConstraint({
57+
name: relationshipName,
58+
foreignKey: compMod.child.collection.fkFields,
59+
primaryKey: compMod.parent.collection.fkFields,
60+
customProperties: compMod.customProperties?.new,
61+
foreignTable: compMod.child.collection.name,
62+
foreignSchemaName: compMod.child.bucket.name,
63+
foreignTableActivated: compMod.child.collection.isActivated,
64+
primaryTable: compMod.parent.collection.name,
65+
primarySchemaName: compMod.parent.bucket.name,
66+
primaryTableActivated: compMod.parent.collection.isActivated,
67+
isActivated: Boolean(relationship.role?.compMod?.isActivated?.new),
68+
});
69+
});
70+
4871
const tableData = {
4972
name: tableName,
5073
columns: columnDefinitions.map(ddlProvider.convertColumnDefinition),
5174
checkConstraints: checkConstraints,
52-
foreignKeyConstraints: [],
75+
foreignKeyConstraints,
5376
schemaData,
5477
columnDefinitions,
5578
};

forward_engineering/helpers/alterScriptHelpers/alterRelationshipsHelper.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,5 @@ module.exports = {
164164
getDeleteForeignKeyScriptDtos,
165165
getModifyForeignKeyScriptDtos,
166166
getAddForeignKeyScriptDtos,
167+
getRelationshipName,
167168
};

0 commit comments

Comments
 (0)