Skip to content

Commit 07f5cac

Browse files
HCK-12323: Enable script generation options (#63)
<!--do not remove this marker, its needed to replace info when ticket title is updated --> <!--jira-description-action-hidden-marker-start--> <table> <td> <a href="https://hackolade.atlassian.net/browse/HCK-12323" title="HCK-12323" target="_blank"><img alt="Task" src="https://hackolade.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10318?size=medium" />HCK-12323</a> [DB2] Enable script generation options for constraints </td></table> <br /> <!--jira-description-action-hidden-marker-end--> ## Content This is a **feature branch** for DB2 script generation options. Do not merge it until all tasks are done. --------- Co-authored-by: chulanovskyi-bs <[email protected]>
1 parent d2321a2 commit 07f5cac

35 files changed

+2851
-85
lines changed

api/fe.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const { generateContainerScript } = require('../forward_engineering/api/generateContainerScript');
2+
const { isDropInStatements } = require('../forward_engineering/api/isDropInStatements');
3+
4+
module.exports = {
5+
generateContainerScript,
6+
isDropInStatements,
7+
};

constants/constants.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,19 @@ const INLINE_COMMENT = '--';
1515

1616
const PERSENT = '__PERCENT__';
1717

18+
const CONSTRAINT_POSTFIX = {
19+
primaryKey: 'pk',
20+
foreignKey: 'fk',
21+
uniqueKey: 'uk',
22+
notNull: 'nn',
23+
check: 'check',
24+
default: 'default',
25+
};
26+
1827
module.exports = {
1928
ERROR_MESSAGE,
2029
TABLE_TYPE,
2130
INLINE_COMMENT,
2231
PERSENT,
32+
CONSTRAINT_POSTFIX,
2333
};

esbuild.package.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ esbuild
3131
.build({
3232
entryPoints: [
3333
path.resolve(__dirname, 'forward_engineering', 'api.js'),
34+
path.resolve(__dirname, 'api', 'fe.js'),
3435
path.resolve(__dirname, 'forward_engineering', 'ddlProvider.js'),
3536
path.resolve(__dirname, 'reverse_engineering', 'api.js'),
3637
],
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
const { commentIfDeactivated } = require('../utils/general');
2+
const { getAlterScriptDtos } = require('./alterScriptFromDeltaHelper');
3+
4+
const joinAlterScriptDtosIntoScript = (dtos, shouldApplyDropStatements) => {
5+
return dtos
6+
.flatMap(dto => {
7+
if (dto.isActivated === false) {
8+
return dto.scripts.map(scriptDto =>
9+
commentIfDeactivated(scriptDto.script, {
10+
isActivated: false,
11+
isPartOfLine: false,
12+
}),
13+
);
14+
}
15+
if (!shouldApplyDropStatements) {
16+
return dto.scripts.map(scriptDto =>
17+
commentIfDeactivated(scriptDto.script, {
18+
isActivated: !scriptDto.isDropScript,
19+
isPartOfLine: false,
20+
}),
21+
);
22+
}
23+
return dto.scripts.map(scriptDto => scriptDto.script);
24+
})
25+
.map(scriptLine => scriptLine?.trim())
26+
.filter(Boolean)
27+
.join('\n\n');
28+
};
29+
30+
const doesEntityLevelAlterScriptContainDropStatements = (data, app) => {
31+
const alterScriptDtos = getAlterScriptDtos(data, app);
32+
return alterScriptDtos.some(
33+
alterScriptDto =>
34+
alterScriptDto.isActivated &&
35+
alterScriptDto.scripts.some(scriptModificationDto => scriptModificationDto.isDropScript),
36+
);
37+
};
38+
39+
const mapCoreDataForContainerLevelScripts = data => {
40+
return {
41+
...data,
42+
jsonSchema: data.collections[0],
43+
internalDefinitions: Object.values(data.internalDefinitions)[0],
44+
};
45+
};
46+
47+
const buildContainerLevelAlterScript = (data, app) => {
48+
const preparedData = mapCoreDataForContainerLevelScripts(data);
49+
const alterScriptDtos = getAlterScriptDtos(preparedData, app);
50+
const shouldApplyDropStatements = preparedData.options?.additionalOptions?.some(
51+
option => option.id === 'applyDropStatements' && option.value,
52+
);
53+
54+
return joinAlterScriptDtosIntoScript(alterScriptDtos, shouldApplyDropStatements);
55+
};
56+
57+
const doesContainerLevelAlterScriptContainDropStatements = (data, app) => {
58+
const preparedData = mapCoreDataForContainerLevelScripts(data);
59+
const alterScriptDtos = getAlterScriptDtos(preparedData, app);
60+
return alterScriptDtos.some(
61+
alterScriptDto =>
62+
alterScriptDto.isActivated &&
63+
alterScriptDto.scripts.some(scriptModificationDto => scriptModificationDto.isDropScript),
64+
);
65+
};
66+
67+
module.exports = {
68+
doesEntityLevelAlterScriptContainDropStatements,
69+
buildContainerLevelAlterScript,
70+
doesContainerLevelAlterScriptContainDropStatements,
71+
};
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
const {
2+
getModifyCollectionScriptDtos,
3+
getModifyCollectionKeysScriptDtos,
4+
getModifyColumnScriptDtos,
5+
} = require('./alterScriptHelpers/alterEntityHelper');
6+
const {
7+
getDeleteForeignKeyScriptDtos,
8+
getAddForeignKeyScriptDtos,
9+
getModifyForeignKeyScriptDtos,
10+
} = require('./alterScriptHelpers/alterForeignKeyHelper');
11+
const { getModifyViewScriptDtos } = require('./alterScriptHelpers/alterViewHelper');
12+
13+
const getItems = data => [data?.items].flat().filter(Boolean);
14+
15+
const getAlterCollectionScriptDtos = ({
16+
collection,
17+
app,
18+
modelDefinitions,
19+
internalDefinitions,
20+
externalDefinitions,
21+
}) => {
22+
const modifyScriptsData = getItems(collection.properties?.entities?.properties?.modified).map(
23+
item => Object.values(item.properties)[0],
24+
);
25+
26+
const modifyCollectionScriptDtos = modifyScriptsData.flatMap(getModifyCollectionScriptDtos);
27+
const modifyCollectionKeysScriptDtos = modifyScriptsData.flatMap(getModifyCollectionKeysScriptDtos);
28+
const modifyColumnScriptDtos = modifyScriptsData.flatMap(getModifyColumnScriptDtos);
29+
30+
return [...modifyCollectionScriptDtos, ...modifyColumnScriptDtos, ...modifyCollectionKeysScriptDtos].filter(
31+
Boolean,
32+
);
33+
};
34+
35+
const getAlterViewScriptDtos = collection => {
36+
const modifyViewScriptDtos = getItems(collection.properties?.views?.properties?.modified)
37+
.map(viewWrapper => Object.values(viewWrapper.properties)[0])
38+
.map(view => ({ ...view, ...view.role }))
39+
.flatMap(getModifyViewScriptDtos);
40+
41+
return [...modifyViewScriptDtos].filter(Boolean);
42+
};
43+
44+
const getAlterRelationshipsScriptDtos = ({ collection, app, ignoreRelationshipIDs = [] }) => {
45+
const addedRelationships = getItems(collection.properties?.relationships?.properties?.added)
46+
.filter(Boolean)
47+
.map(item => Object.values(item.properties)[0])
48+
.filter(
49+
relationship =>
50+
relationship?.role?.compMod?.created && !ignoreRelationshipIDs.includes(relationship?.role?.id),
51+
);
52+
53+
const deletedRelationships = getItems(collection.properties?.relationships?.properties?.deleted)
54+
.filter(Boolean)
55+
.map(item => Object.values(item.properties)[0])
56+
.filter(
57+
relationship =>
58+
relationship?.role?.compMod?.deleted && !ignoreRelationshipIDs.includes(relationship?.role?.id),
59+
);
60+
61+
const modifiedRelationships = getItems(collection.properties?.relationships?.properties?.modified)
62+
.filter(Boolean)
63+
.map(item => Object.values(item.properties)[0])
64+
.filter(
65+
relationship =>
66+
relationship?.role?.compMod?.modified && !ignoreRelationshipIDs.includes(relationship?.role?.id),
67+
);
68+
69+
const deleteFkScriptDtos = getDeleteForeignKeyScriptDtos(deletedRelationships);
70+
const addFkScriptDtos = getAddForeignKeyScriptDtos(addedRelationships);
71+
const modifiedFkScriptDtos = getModifyForeignKeyScriptDtos(modifiedRelationships);
72+
73+
return [...deleteFkScriptDtos, ...addFkScriptDtos, ...modifiedFkScriptDtos].filter(Boolean);
74+
};
75+
76+
const getInlineRelationships = ({ collection, options }) => {
77+
if (options?.scriptGenerationOptions?.feActiveOptions?.foreignKeys !== 'inline') {
78+
return [];
79+
}
80+
81+
const addedCollectionIDs = getItems(collection.properties?.entities?.properties?.added)
82+
.filter(item => item && Object.values(item.properties)?.[0]?.compMod?.created)
83+
.map(item => Object.values(item.properties)[0].role.id);
84+
85+
const addedRelationships = getItems(collection.properties?.relationships?.properties?.added)
86+
.map(item => item && Object.values(item.properties)[0])
87+
.filter(r => r?.role?.compMod?.created && addedCollectionIDs.includes(r?.role?.childCollection));
88+
89+
return addedRelationships;
90+
};
91+
92+
const prettifyAlterScriptDto = dto => {
93+
if (!dto) {
94+
return undefined;
95+
}
96+
/**
97+
* @type {Array<ModificationScript>}
98+
* */
99+
const nonEmptyScriptModificationDtos = dto.scripts
100+
.map(scriptDto => ({
101+
...scriptDto,
102+
script: (scriptDto.script || '').trim(),
103+
}))
104+
.filter(scriptDto => Boolean(scriptDto.script));
105+
if (!nonEmptyScriptModificationDtos.length) {
106+
return undefined;
107+
}
108+
return {
109+
...dto,
110+
scripts: nonEmptyScriptModificationDtos,
111+
};
112+
};
113+
114+
const getAlterScriptDtos = (data, app) => {
115+
const collection = JSON.parse(data.jsonSchema);
116+
117+
if (!collection) {
118+
throw new Error(
119+
'"comparisonModelCollection" is not found. Alter script can be generated only from Delta model',
120+
);
121+
}
122+
123+
const modelDefinitions = JSON.parse(data.modelDefinitions);
124+
const internalDefinitions = JSON.parse(data.internalDefinitions);
125+
const externalDefinitions = JSON.parse(data.externalDefinitions);
126+
127+
const inlineDeltaRelationships = getInlineRelationships({ collection, options: data.options });
128+
const ignoreRelationshipIDs = inlineDeltaRelationships.map(relationship => relationship.role.id);
129+
130+
const collectionsScriptDtos = getAlterCollectionScriptDtos({
131+
collection,
132+
app,
133+
modelDefinitions,
134+
internalDefinitions,
135+
externalDefinitions,
136+
});
137+
138+
const viewScriptDtos = getAlterViewScriptDtos(collection);
139+
140+
const relationshipScriptDtos = getAlterRelationshipsScriptDtos({
141+
collection,
142+
app,
143+
ignoreRelationshipIDs,
144+
});
145+
146+
return [...collectionsScriptDtos, ...viewScriptDtos, ...relationshipScriptDtos]
147+
.filter(Boolean)
148+
.map(dto => dto && prettifyAlterScriptDto(dto))
149+
.filter(Boolean);
150+
};
151+
152+
module.exports = {
153+
getAlterScriptDtos,
154+
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const { getModifiedCommentOnColumnScriptDtos } = require('./columnHelpers/commentsHelper');
2+
const { getModifyNonNullColumnsScriptDtos } = require('./columnHelpers/nonNullConstraintHelper');
3+
const { getModifyCheckConstraintScriptDtos } = require('./entityHelpers/checkConstraintHelper');
4+
const { getModifyEntityCommentsScriptDtos } = require('./entityHelpers/commentsHelper');
5+
const { getModifyPkConstraintsScriptDtos } = require('./entityHelpers/primaryKeyHelper');
6+
const { getModifyUkConstraintsScriptDtos } = require('./entityHelpers/uniqueKeyHelper');
7+
const { getModifiedDefaultColumnValueScriptDtos } = require('./columnHelpers/defaultValueHelper');
8+
9+
const getModifyCollectionScriptDtos = collection => {
10+
const modifyCheckConstraintScriptDtos = getModifyCheckConstraintScriptDtos(collection);
11+
const modifyCommentScriptDtos = getModifyEntityCommentsScriptDtos(collection);
12+
return [...modifyCheckConstraintScriptDtos, ...modifyCommentScriptDtos].filter(Boolean);
13+
};
14+
15+
const getModifyCollectionKeysScriptDtos = collection => {
16+
const modifyPkConstraintDtos = getModifyPkConstraintsScriptDtos(collection);
17+
const modifyUkConstraintDtos = getModifyUkConstraintsScriptDtos(collection);
18+
return [...modifyPkConstraintDtos, ...modifyUkConstraintDtos].filter(Boolean);
19+
};
20+
21+
const getModifyColumnScriptDtos = collection => {
22+
const modifyNotNullScriptDtos = getModifyNonNullColumnsScriptDtos(collection);
23+
const modifyCommentScriptDtos = getModifiedCommentOnColumnScriptDtos(collection);
24+
const modifyDefaultColumnValueScriptDtos = getModifiedDefaultColumnValueScriptDtos({ collection });
25+
26+
return [...modifyNotNullScriptDtos, ...modifyDefaultColumnValueScriptDtos, ...modifyCommentScriptDtos].filter(
27+
Boolean,
28+
);
29+
};
30+
31+
module.exports = {
32+
getModifyCollectionScriptDtos,
33+
getModifyColumnScriptDtos,
34+
getModifyCollectionKeysScriptDtos,
35+
};

0 commit comments

Comments
 (0)