Skip to content

Commit 3d54e6c

Browse files
authored
HCK-9538: Computed Columns: Add support of constraints (#127)
* HCK-9538: Add support of constrains to computed columns * HCK-9538: improve validation * HCK-9538: code clean up * HCK-9538: Rename key * HCK-9538: improve validation
1 parent eacb7fd commit 3d54e6c

File tree

6 files changed

+226
-16
lines changed

6 files changed

+226
-16
lines changed

forward_engineering/configs/templates.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module.exports = {
1212

1313
columnDefinition:
1414
'[${name}] ${type}${primary_key}${temporalTableTime}${sparse}${maskedWithFunction}${identity}${default}${collation}${not_null}${encryptedWith}',
15-
computedColumnDefinition: '[${name}] AS ${expression}${persisted}',
15+
computedColumnDefinition: '[${name}] AS ${expression}${persisted}${key}${not_null}',
1616

1717
index:
1818
'CREATE${unique}${clustered}${columnstore} INDEX ${name}\n' +
@@ -83,8 +83,6 @@ module.exports = {
8383

8484
alterColumn: 'ALTER COLUMN [${name}] ${type}${collation}${not_null}',
8585

86-
alterComputedColumn: 'ADD [${name}] AS ${expression}${persisted}',
87-
8886
renameColumn: "EXEC sp_rename '${fullTableName}.${oldColumnName}', '${newColumnName}', 'COLUMN';${terminator}",
8987

9088
dropView: 'DROP VIEW IF EXISTS ${name}${terminator}',

forward_engineering/ddlProvider.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,19 @@ module.exports = (baseProvider, options, app) => {
177177
: fullTableStatement;
178178
},
179179

180-
createComputedColumn({ name, computedExpression, persisted }) {
180+
createComputedColumn({ name, computedExpression, persisted, primaryKey, unique, notNull }) {
181+
let key = persisted ? primaryKey : '';
182+
183+
if (!key) {
184+
key = unique;
185+
}
186+
181187
return assignTemplates(templates.computedColumnDefinition, {
182188
name,
183-
expression: wrapInBracketsIfNecessary(computedExpression),
189+
expression: wrapInBracketsIfNecessary(computedExpression.trim()),
184190
persisted: persisted ? ' PERSISTED' : '',
191+
key,
192+
not_null: notNull,
185193
});
186194
},
187195

@@ -223,6 +231,9 @@ module.exports = (baseProvider, options, app) => {
223231
name,
224232
computedExpression,
225233
persisted,
234+
primaryKey,
235+
unique,
236+
notNull,
226237
})
227238
: assignTemplates(templates.columnDefinition, {
228239
name,
@@ -750,13 +761,9 @@ module.exports = (baseProvider, options, app) => {
750761
});
751762
},
752763

753-
alterComputedColumn(fullTableName, columnName, columnDefinition) {
754-
const { computedExpression, persisted } = columnDefinition;
755-
756-
const command = assignTemplates(templates.alterComputedColumn, {
757-
name: columnName,
758-
expression: wrapInBracketsIfNecessary(computedExpression),
759-
persisted: persisted ? ' PERSISTED' : '',
764+
alterComputedColumn(fullTableName, name, columnDefinition) {
765+
const command = assignTemplates(templates.addColumn, {
766+
script: this.convertColumnDefinition(columnDefinition),
760767
});
761768

762769
return assignTemplates(templates.alterTable, {

forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterComputedColumnHelpr.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const _ = require('lodash');
55
module.exports = (app, ddlProvider) => {
66
const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_);
77
const { AlterScriptDto } = require('../types/AlterScriptDto');
8+
const { compareObjectsByProperties } = require('../../../utils/general')(_);
89

910
const changeToComputed = (fullName, columnName, columnDefinition) => {
1011
return [
@@ -24,13 +25,17 @@ module.exports = (app, ddlProvider) => {
2425
];
2526
};
2627

28+
const propsToDetectChange = ['computed', 'computedExpression', 'persisted', 'unique', 'primaryKey'];
29+
2730
const generateSqlAlterScript = ({
2831
collectionSchema,
2932
prevJsonSchema,
3033
jsonSchema,
3134
fullName,
3235
columnName,
3336
schemaName,
37+
toAddNotNull,
38+
toRemoveNotNull,
3439
}) => {
3540
const schemaData = { schemaName };
3641
const columnDefinition = createColumnDefinitionBySchema({
@@ -40,6 +45,7 @@ module.exports = (app, ddlProvider) => {
4045
ddlProvider,
4146
schemaData,
4247
});
48+
columnDefinition.nullable = toRemoveNotNull;
4349

4450
let sqlScripts = [];
4551

@@ -48,8 +54,9 @@ module.exports = (app, ddlProvider) => {
4854
const isComputedModified =
4955
prevJsonSchema.computed &&
5056
jsonSchema.computed &&
51-
(prevJsonSchema.computedExpression !== jsonSchema.computedExpression ||
52-
prevJsonSchema.persisted !== jsonSchema.persisted);
57+
(compareObjectsByProperties(prevJsonSchema, jsonSchema, propsToDetectChange) ||
58+
toAddNotNull ||
59+
toRemoveNotNull);
5360

5461
if ((isComputedRemoved || isComputedModified) && !jsonSchema.computedExpression) {
5562
sqlScripts = changeToNonComputed(fullName, columnName, columnDefinition);
@@ -67,6 +74,14 @@ module.exports = (app, ddlProvider) => {
6774
_.toPairs(collection.properties).reduce((result, [columnName, jsonSchema]) => {
6875
const oldJsonSchema = _.omit(collection.role?.properties?.[columnName], ['compMod']);
6976

77+
const currentRequiredColumnNames = collection.required || [];
78+
const previousRequiredColumnNames = collection.role.required || [];
79+
80+
const toAddNotNull =
81+
_.difference(currentRequiredColumnNames, previousRequiredColumnNames).indexOf(columnName) !== -1;
82+
const toRemoveNotNull =
83+
_.difference(previousRequiredColumnNames, currentRequiredColumnNames).indexOf(columnName) !== -1;
84+
7085
result.push(
7186
generateSqlAlterScript({
7287
collectionSchema,
@@ -75,6 +90,8 @@ module.exports = (app, ddlProvider) => {
7590
fullName,
7691
columnName,
7792
schemaName,
93+
toAddNotNull,
94+
toRemoveNotNull,
7895
}),
7996
);
8097

forward_engineering/helpers/alterScriptHelpers/columnHelpers/notNullConstraintsHelper.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const getModifyNonNullColumnsScriptDtos = (_, ddlProvider) => (collection, colle
2222
const oldName = jsonSchema.compMod.oldField.name;
2323
const shouldRemoveForOldName = columnNamesToRemoveNotNullConstraint.includes(oldName);
2424
const shouldAddForNewName = columnNamesToAddNotNullConstraint.includes(name);
25-
return shouldAddForNewName && !shouldRemoveForOldName;
25+
return shouldAddForNewName && !shouldRemoveForOldName && !jsonSchema.computed;
2626
})
2727
.map(([columnName, jsonSchema]) => {
2828
const columnDefinition = createColumnDefinitionBySchema({
@@ -42,7 +42,8 @@ const getModifyNonNullColumnsScriptDtos = (_, ddlProvider) => (collection, colle
4242
const oldName = jsonSchema.compMod.oldField.name;
4343
const shouldRemoveForOldName = columnNamesToRemoveNotNullConstraint.includes(oldName);
4444
const shouldAddForNewName = columnNamesToAddNotNullConstraint.includes(name);
45-
return shouldRemoveForOldName && !shouldAddForNewName;
45+
46+
return shouldRemoveForOldName && !shouldAddForNewName && !jsonSchema.computed;
4647
})
4748
.map(([name, jsonSchema]) => {
4849
const columnDefinition = createColumnDefinitionBySchema({

forward_engineering/utils/general.js

+5
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ module.exports = _ => {
197197
return !_.isEqual(newProperty, oldProperty);
198198
};
199199

200+
const compareObjectsByProperties = (obj1, obj2, properties) => {
201+
return properties.some(prop => obj1[prop] !== obj2[prop]);
202+
};
203+
200204
const getSchemaOfAlterCollection = collection => {
201205
return { ...collection, ...(_.omit(collection?.role, 'properties') || {}) };
202206
};
@@ -231,5 +235,6 @@ module.exports = _ => {
231235
getSchemaOfAlterCollection,
232236
getNamePrefixedWithSchemaName,
233237
buildDefaultPKName,
238+
compareObjectsByProperties,
234239
};
235240
};

0 commit comments

Comments
 (0)