Skip to content

Commit 4522e90

Browse files
author
unknown
committed
merged with main
2 parents c889407 + 7f6bd99 commit 4522e90

File tree

8 files changed

+228
-35
lines changed

8 files changed

+228
-35
lines changed

forward_engineering/configs/templates.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ module.exports = {
3232

3333
renameColumn: 'ALTER TABLE IF EXISTS ${tableName} RENAME COLUMN ${oldColumnName} TO ${newColumnName};',
3434

35+
addCheckConstraint: 'ALTER TABLE IF EXISTS ${tableName} ADD CONSTRAINT ${constraintName} CHECK (${expression});',
36+
37+
dropConstraint: 'ALTER TABLE IF EXISTS ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};',
38+
3539
createForeignKey:
3640
'ALTER TABLE IF EXISTS ${foreignTable} ADD CONSTRAINT ${name} FOREIGN KEY (${foreignKey}) REFERENCES ${primaryTable}(${primaryKey})${match}${onDelete}${onUpdate};',
3741

forward_engineering/ddlProvider.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,5 +771,33 @@ module.exports = (baseProvider, options, app) => {
771771
newColumnName
772772
});
773773
},
774+
775+
/**
776+
* @param tableName {string}
777+
* @param constraintName {string}
778+
* @param expression {expression}
779+
* @return string
780+
* */
781+
addCheckConstraint(tableName, constraintName, expression) {
782+
const templateConfig = {
783+
tableName,
784+
constraintName,
785+
expression
786+
};
787+
return assignTemplates(templates.addCheckConstraint, templateConfig);
788+
},
789+
790+
/**
791+
* @param tableName {string}
792+
* @param constraintName {string}
793+
* @return string
794+
* */
795+
dropConstraint(tableName, constraintName) {
796+
const templateConfig = {
797+
tableName,
798+
constraintName,
799+
};
800+
return assignTemplates(templates.dropConstraint, templateConfig);
801+
},
774802
};
775803
};

forward_engineering/helpers/alterScriptFromDeltaHelper.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const {
44
getDeleteCollectionScript,
55
getAddColumnScript,
66
getDeleteColumnScript,
7-
getModifyColumnScript,
7+
getModifyColumnScript, getModifyCollectionScript,
88
} = require('./alterScriptHelpers/alterEntityHelper');
99
const {
1010
getDeleteUdtScript,
@@ -57,6 +57,12 @@ const getAlterCollectionsScripts = ({
5757
.map(item => Object.values(item.properties)[0])
5858
.filter(collection => collection.compMod?.deleted)
5959
.map(getDeleteCollectionScript(app));
60+
const modifyCollectionScripts = []
61+
.concat(collection.properties?.entities?.properties?.modified?.items)
62+
.filter(Boolean)
63+
.map(item => Object.values(item.properties)[0])
64+
.map(getModifyCollectionScript(app))
65+
.flat();
6066
const addColumnScripts = []
6167
.concat(collection.properties?.entities?.properties?.added?.items)
6268
.filter(Boolean)
@@ -79,6 +85,7 @@ const getAlterCollectionsScripts = ({
7985
return [
8086
...createCollectionsScripts,
8187
...deleteCollectionScripts,
88+
...modifyCollectionScripts,
8289
...addColumnScripts,
8390
...deleteColumnScripts,
8491
...modifyColumnScript,

forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js

Lines changed: 132 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
const {checkFieldPropertiesChanged} = require('./common');
22

3+
/**
4+
* @typedef {{
5+
* id: string,
6+
* chkConstrName: string,
7+
* constrExpression: string,
8+
* }} CheckConstraint
9+
*
10+
* @typedef {{
11+
* old?: CheckConstraint,
12+
* new?: CheckConstraint
13+
* }} CheckConstraintHistoryEntry
14+
* */
15+
16+
const getFullTableName = (_) => (collection) => {
17+
const {getEntityName} = require('../../utils/general')(_);
18+
const {getNamePrefixedWithSchemaName} = require('../general')({_});
19+
20+
const collectionSchema = {...collection, ...(_.omit(collection?.role, 'properties') || {})};
21+
const tableName = getEntityName(collectionSchema);
22+
const schemaName = collectionSchema.compMod?.keyspaceName;
23+
return getNamePrefixedWithSchemaName(tableName, schemaName);
24+
}
25+
326
const getAddCollectionScript =
427
({app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions}) =>
528
collection => {
@@ -48,17 +71,117 @@ const getAddCollectionScript =
4871

4972
const getDeleteCollectionScript = app => collection => {
5073
const _ = app.require('lodash');
51-
const {getEntityName} = require('../../utils/general')(_);
52-
const {getNamePrefixedWithSchemaName} = require('../general')({_});
53-
54-
const jsonData = {...collection, ...(_.omit(collection?.role, 'properties') || {})};
55-
const tableName = getEntityName(jsonData);
56-
const schemaName = collection.compMod.keyspaceName;
57-
const fullName = getNamePrefixedWithSchemaName(tableName, schemaName);
58-
74+
const fullName = getFullTableName(_)(collection);
5975
return `DROP TABLE IF EXISTS ${fullName};`;
6076
};
6177

78+
/**
79+
* @return {(collection: Object) => Array<CheckConstraintHistoryEntry>}
80+
* */
81+
const mapCheckConstraintNamesToChangeHistory = (_) => (collection) => {
82+
const checkConstraintHistory = collection?.compMod?.chkConstr;
83+
if (!checkConstraintHistory) {
84+
return [];
85+
}
86+
const newConstraints = checkConstraintHistory.new || [];
87+
const oldConstraints = checkConstraintHistory.old || [];
88+
const constrNames = _.chain([ ...newConstraints, ...oldConstraints ])
89+
.map(constr => constr.chkConstrName)
90+
.uniq()
91+
.value();
92+
93+
return constrNames.map(chkConstrName => {
94+
return {
95+
old: _.find(oldConstraints, { chkConstrName }),
96+
new: _.find(newConstraints, { chkConstrName }),
97+
};
98+
})
99+
}
100+
101+
/**
102+
* @return {(constraintHistory: Array<CheckConstraintHistoryEntry>, fullTableName: string) => Array<string>}
103+
* */
104+
const getDropCheckConstraintScripts = (_, ddlProvider) => (constraintHistory, fullTableName) => {
105+
const {wrapInQuotes} = require('../general')({_});
106+
107+
return constraintHistory
108+
.filter(historyEntry => historyEntry.old && !historyEntry.new)
109+
.map(historyEntry => {
110+
const wrappedConstraintName = wrapInQuotes(historyEntry.old.chkConstrName);
111+
return ddlProvider.dropConstraint(fullTableName, wrappedConstraintName);
112+
});
113+
}
114+
115+
/**
116+
* @return {(constraintHistory: Array<CheckConstraintHistoryEntry>, fullTableName: string) => Array<string>}
117+
* */
118+
const getAddCheckConstraintScripts = (_, ddlProvider) => (constraintHistory, fullTableName) => {
119+
const {wrapInQuotes} = require('../general')({_});
120+
121+
return constraintHistory
122+
.filter(historyEntry => historyEntry.new && !historyEntry.old)
123+
.map(historyEntry => {
124+
const { chkConstrName, constrExpression } = historyEntry.new;
125+
return ddlProvider.addCheckConstraint(fullTableName, wrapInQuotes(chkConstrName), constrExpression);
126+
});
127+
}
128+
129+
/**
130+
* @return {(constraintHistory: Array<CheckConstraintHistoryEntry>, fullTableName: string) => Array<string>}
131+
* */
132+
const getUpdateCheckConstraintScripts = (_, ddlProvider) => (constraintHistory, fullTableName) => {
133+
const {wrapInQuotes} = require('../general')({_});
134+
135+
return constraintHistory
136+
.filter(historyEntry => {
137+
if (historyEntry.old && historyEntry.new) {
138+
const oldExpression = historyEntry.old.constrExpression;
139+
const newExpression = historyEntry.new.constrExpression;
140+
return oldExpression !== newExpression;
141+
}
142+
return false;
143+
})
144+
.map(historyEntry => {
145+
const { chkConstrName: oldConstrainName } = historyEntry.old;
146+
const dropConstraintScript = ddlProvider.dropConstraint(fullTableName, wrapInQuotes(oldConstrainName));
147+
148+
const { chkConstrName: newConstrainName, constrExpression: newConstraintExpression } = historyEntry.new;
149+
const addConstraintScript = ddlProvider.addCheckConstraint(fullTableName, wrapInQuotes(newConstrainName), newConstraintExpression);
150+
151+
return [dropConstraintScript, addConstraintScript];
152+
})
153+
.flat();
154+
}
155+
156+
/**
157+
* @return (collection: Object) => Array<string>
158+
* */
159+
const getModifyCheckConstraintScripts = (_, ddlProvider) => (collection) => {
160+
const fullTableName = getFullTableName(_)(collection);
161+
const constraintHistory = mapCheckConstraintNamesToChangeHistory(_)(collection);
162+
163+
const addCheckConstraintScripts = getAddCheckConstraintScripts(_, ddlProvider)(constraintHistory, fullTableName);
164+
const dropCheckConstraintScripts = getDropCheckConstraintScripts(_, ddlProvider)(constraintHistory, fullTableName);
165+
const updateCheckConstraintScripts = getUpdateCheckConstraintScripts(_, ddlProvider)(constraintHistory, fullTableName);
166+
167+
return [
168+
...addCheckConstraintScripts,
169+
...dropCheckConstraintScripts,
170+
...updateCheckConstraintScripts,
171+
]
172+
}
173+
174+
/**
175+
* @return (collection: Object) => Array<string>
176+
* */
177+
const getModifyCollectionScript = (app) => (collection) => {
178+
const _ = app.require('lodash');
179+
const ddlProvider = require('../../ddlProvider')(null, null, app);
180+
181+
const modifyCheckConstraintScripts = getModifyCheckConstraintScripts(_, ddlProvider)(collection);
182+
return [...modifyCheckConstraintScripts]
183+
}
184+
62185
const getAddColumnScript =
63186
({app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions}) =>
64187
collection => {
@@ -113,16 +236,6 @@ const getDeleteColumnScript = app => collection => {
113236
.map(([name]) => `ALTER TABLE IF EXISTS ${fullName} DROP COLUMN IF EXISTS ${wrapInQuotes(name)};`);
114237
};
115238

116-
const getFullTableName = (_) => (collection) => {
117-
const {getEntityName} = require('../../utils/general')(_);
118-
const {getNamePrefixedWithSchemaName} = require('../general')({_});
119-
120-
const collectionSchema = {...collection, ...(_.omit(collection?.role, 'properties') || {})};
121-
const tableName = getEntityName(collectionSchema);
122-
const schemaName = collectionSchema.compMod?.keyspaceName;
123-
return getNamePrefixedWithSchemaName(tableName, schemaName);
124-
}
125-
126239
const hasLengthChanged = (collection, oldFieldName, currentJsonSchema) => {
127240
const oldProperty = collection.role.properties[oldFieldName];
128241

@@ -231,6 +344,7 @@ const getModifyColumnScript = app => collection => {
231344
module.exports = {
232345
getAddCollectionScript,
233346
getDeleteCollectionScript,
347+
getModifyCollectionScript,
234348
getAddColumnScript,
235349
getDeleteColumnScript,
236350
getModifyColumnScript,

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "PostgreSQL",
3-
"version": "0.1.38",
4-
"versionDate": "2023-04-14",
3+
"version": "0.1.40",
4+
"versionDate": "2023-04-21",
55
"author": "hackolade",
66
"engines": {
77
"hackolade": "6.1.2",

reverse_engineering/api.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ module.exports = {
130130
collections[schemaName],
131131
data.recordSamplingSettings,
132132
data.includePartitions,
133+
data.ignoreUdfUdpTriggers,
133134
);
134135
const { functions, procedures, triggers } = await postgresService.retrieveSchemaLevelData(
135136
schemaName,
137+
data.ignoreUdfUdpTriggers,
136138
);
137139

138140
postgresLogger.progress('Schema reversed successfully', schemaName);
@@ -194,6 +196,10 @@ module.exports = {
194196
})
195197
.then(({ packages, relationships }) => ({ packages: orderPackages(packages), relationships }));
196198

199+
postgresLogger.info('The data is processed and sent to the application', {
200+
packagesLength: packages?.length,
201+
relationshipsLength: relationships?.length,
202+
});
197203
callback(null, packages, modelData, relationships);
198204
} catch (error) {
199205
logger.log('error', prepareError(error), 'Retrieve tables data');

reverse_engineering/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
"inputLabel": "Include partitions",
2121
"inputTooltip": "Reverse-engineer all partitions as tables",
2222
"inputKeyword": "includePartitions"
23+
},
24+
{
25+
"inputLabel": "Ignore Functions, Procedures and Triggers",
26+
"inputTooltip": "Ignore reverse-engineering of function, procedures and triggers",
27+
"inputKeyword": "ignoreUdfUdpTriggers"
2328
}
2429
]
2530
}

0 commit comments

Comments
 (0)