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
22 changes: 22 additions & 0 deletions forward_engineering/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@
}
]
},
{
"keyword": "foreignKeys",
"label": "FE_SCRIPT_GENERATION_OPTIONS___FOREIGN_KEYS",
"disabled": false,
"value": {
"inline": {
"default": false,
"disabled": true,
"disabledLabel": ""
},
"separate": {
"default": true,
"disabled": false,
"disabledLabel": ""
},
"ignore": {
"default": false,
"disabled": false,
"disabledLabel": ""
}
}
},
{
"keyword": "uniqueConstraints",
"label": "FE_SCRIPT_GENERATION_OPTIONS___UNIQUE_KEYS",
Expand Down
46 changes: 33 additions & 13 deletions forward_engineering/helpers/alterScriptFromDeltaHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@ const {
getAddColumnsScripts,
getModifyColumnsScripts,
} = require('./alterScriptHelpers/alterEntityHelper');
const { getAlterRelationshipsScripts } = require('./alterScriptHelpers/alterRelationshipsHelper');
const {
getAddViewsScripts,
getDeleteViewsScripts,
getModifyViewsScripts,
} = require('./alterScriptHelpers/alterViewHelper');
const { getItems } = require('./alterScriptHelpers/common');
const { getContainerName } = require('./alterScriptHelpers/generalHelper');
const { DROP_STATEMENTS } = require('./constants');
const { commentDeactivatedStatements } = require('./generalHelper');
const { commentDeactivatedStatements, replaceSpaceWithUnderscore, prepareName } = require('./generalHelper');

const getItems = (entity, nameProperty, modify) =>
[]
.concat(entity.properties?.[nameProperty]?.properties?.[modify]?.items)
.filter(Boolean)
.map(items => Object.values(items.properties)[0]);
const getSchemaName = collection => replaceSpaceWithUnderscore(prepareName(getContainerName(collection.role?.compMod)));

const getAlterContainersScripts = (schema, provider) => {
const addedContainerScripts = getItems(schema, 'containers', 'added').map(getAddContainerScript);
Expand All @@ -39,20 +38,31 @@ const getAlterContainersScripts = (schema, provider) => {
};

const getAlterCollectionsScripts = (schema, definitions, provider, data) => {
const getColumnScripts = (items, getScript) => items.filter(item => item.properties).flatMap(getScript);
let currentSchemaName = '';

const setCurrentSchemaName = (entity, getScript) => {
const script = getScript(entity);

currentSchemaName = getSchemaName(entity);

return script;
};

const getColumnScripts = (items, getScript) =>
items.filter(item => item.properties).flatMap(item => setCurrentSchemaName(item, getScript));

const addedCollectionsItems = getItems(schema, 'entities', 'added');
const deletedCollectionsItems = getItems(schema, 'entities', 'deleted');
const modifiedCollectionsItems = getItems(schema, 'entities', 'modified');

const addedCollectionsScripts = addedCollectionsItems
.filter(item => item.compMod?.created)
.flatMap(getAddCollectionsScripts(definitions, data));
.flatMap(item => setCurrentSchemaName(item, getAddCollectionsScripts(definitions, data)));
const deletedCollectionsScripts = deletedCollectionsItems
.filter(item => item.compMod?.deleted)
.flatMap(getDeleteCollectionsScripts(provider));
const modifiedCollectionsScripts = modifiedCollectionsItems.flatMap(
getModifyCollectionsScripts(definitions, provider, data),
const modifiedCollectionsScripts = modifiedCollectionsItems.flatMap(item =>
setCurrentSchemaName(item, getModifyCollectionsScripts(definitions, provider, data)),
);

const addedColumnsItems = addedCollectionsItems.filter(item => !item.compMod?.created);
Expand All @@ -72,6 +82,7 @@ const getAlterCollectionsScripts = (schema, definitions, provider, data) => {
addedColumnsScripts,
deletedColumnsScripts,
modifiedColumnsScripts,
currentSchemaName,
};
};

Expand Down Expand Up @@ -108,10 +119,16 @@ const getAlterViewsScripts = (schema, provider) => {

const getAlterScript = (schema, definitions, data, app, needMinify, sqlFormatter) => {
const provider = require('./alterScriptHelpers/provider')(app);
const containerScripts = getAlterContainersScripts(schema, provider);
const { currentSchemaName, ...collectionScripts } = getAlterCollectionsScripts(schema, definitions, provider, data);
const viewScripts = getAlterViewsScripts(schema, provider);
const relationshipScripts = getAlterRelationshipsScripts(schema, provider, currentSchemaName);

let scripts = {
...getAlterContainersScripts(schema, provider),
...getAlterCollectionsScripts(schema, definitions, provider, data),
...getAlterViewsScripts(schema, provider),
...containerScripts,
...collectionScripts,
...viewScripts,
...relationshipScripts,
};

scripts = [
Expand All @@ -127,6 +144,9 @@ const getAlterScript = (schema, definitions, data, app, needMinify, sqlFormatter
'addedViewScripts',
'modifiedViewScripts',
'deletedContainerScripts',
'deleteFkScripts',
'addFkScripts',
'modifiedFkScripts',
]
.flatMap(name => scripts[name] || [])
.filter(Boolean)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
const {
getFullEntityName,
generateFullEntityName,
getEntityProperties,
getContainerName,
getEntityData,
getEntityName,
prepareScript,
hydrateProperty,
} = require('./generalHelper');
const { replaceSpaceWithUnderscore, prepareName, commentDeactivatedStatements } = require('../generalHelper');

const templates = require('./config/templates');
const { getItems } = require('./common');

const getRelationshipName = relationship => {
return relationship.role.code || relationship.role.name;
};

const getFullParentTableName = relationship => {
const compMod = relationship.role.compMod;

const parentDBName = replaceSpaceWithUnderscore(prepareName(compMod.parent.bucket.name));
const parentEntityName = replaceSpaceWithUnderscore(compMod.parent.collection.name);

return getFullEntityName(parentDBName, parentEntityName);
};

const getFullChildTableName = relationship => {
const compMod = relationship.role.compMod;

const childDBName = replaceSpaceWithUnderscore(prepareName(compMod.child.bucket.name));
const childEntityName = replaceSpaceWithUnderscore(compMod.child.collection.name);
return getFullEntityName(childDBName, childEntityName);
};

const getAddSingleForeignKeyScript = provider => relationship => {
const compMod = relationship.role.compMod;
const parentTableName = getFullParentTableName(relationship);
const childTableName = getFullChildTableName(relationship);

const relationshipName = compMod.code?.new || compMod.name?.new || getRelationshipName(relationship) || '';
const constraintName = relationshipName.includes(' ') ? `\`${relationshipName}\`` : relationshipName;
const childColumns = compMod.child.collection.fkFields.map(field => prepareName(field.name));
const parentColumns = compMod.parent.collection.fkFields.map(field => prepareName(field.name));
const disableNoValidate = relationship.role?.compMod?.customProperties?.new?.disableNoValidate;
const disableNoValidateClause = disableNoValidate ? ' DISABLE NOVALIDATE' : '';

return provider.assignTemplates(templates.addFkConstraint, {
childTableName,
constraintName,
childColumns,
parentTableName,
parentColumns,
disableNoValidate: disableNoValidateClause,
});
};

const canRelationshipBeAdded = relationship => {
const compMod = relationship.role.compMod;
if (!compMod) {
return false;
}
return [
compMod.code?.new || compMod.name?.new || getRelationshipName(relationship),
compMod.parent?.bucket,
compMod.parent?.collection,
compMod.parent?.collection?.fkFields?.length,
compMod.child?.bucket,
compMod.child?.collection,
compMod.child?.collection?.fkFields?.length,
].every(property => Boolean(property));
};

const getAddForeignKeyScript = provider => relationship => {
const script = getAddSingleForeignKeyScript(provider)(relationship);
const isActivated = Boolean(relationship.role?.compMod?.isActivated?.new);

return commentDeactivatedStatements(script, isActivated);
};

const getDeleteSingleForeignKeyScript = provider => relationship => {
const compMod = relationship.role.compMod;
const tableName = getFullChildTableName(relationship);
const relationshipName = compMod.code?.old || compMod.name?.old || getRelationshipName(relationship) || '';
const constraintName = prepareName(relationshipName);

return provider.assignTemplates(templates.dropConstraint, {
tableName,
constraintName,
});
};

const canRelationshipBeDeleted = relationship => {
const compMod = relationship.role.compMod;
if (!compMod) {
return false;
}
return [
compMod.code?.old || compMod.name?.old || getRelationshipName(relationship),
compMod.child?.bucket,
compMod.child?.collection,
].every(property => Boolean(property));
};

const getDeleteForeignKeyScripts = provider => deletedRelationships => {
return deletedRelationships
.filter(relationship => canRelationshipBeDeleted(relationship))
.map(relationship => {
const script = getDeleteSingleForeignKeyScript(provider)(relationship);
const isActivated = Boolean(relationship.role?.compMod?.isActivated?.new);

return commentDeactivatedStatements(script, isActivated);
});
};

const getModifyForeignKeyScript = provider => relationship => {
const deleteScript = getDeleteSingleForeignKeyScript(provider)(relationship);
const addScript = getAddSingleForeignKeyScript(provider)(relationship);
const isActivated = Boolean(relationship.role?.compMod?.isActivated?.new);

return (
commentDeactivatedStatements(deleteScript, isActivated) + commentDeactivatedStatements(addScript, isActivated)
);
};

const getAlterRelationshipsScripts = (schema, provider, initialSchemaName) => {
let currentSchemaName = initialSchemaName;

const generateAddFkScripts = (addedRelationships, getScript) => {
return addedRelationships.filter(relationship => canRelationshipBeAdded(relationship)).flatMap(getScript);
};

const generateModifyFkScripts = (modifiedRelationships, getScript) => {
return modifiedRelationships
.filter(relationship => canRelationshipBeAdded(relationship) && canRelationshipBeDeleted(relationship))
.flatMap(getScript);
};

const getRelationshipsScriptsWithUseSchema = (relationships, processRelationships, getScript) => {
return processRelationships(relationships, relationship => {
const script = getScript(provider)(relationship);

if (!script) {
return [];
}

const schemaName = replaceSpaceWithUnderscore(
prepareName(relationship.role.compMod.child.bucket?.name || ''),
);

if (currentSchemaName === schemaName) {
return [script];
}

currentSchemaName = schemaName;

const useSchemaScript = provider.assignTemplates(templates.useSchema, { schemaName });

return [useSchemaScript, script];
});
};

const deletedRelationships = getItems(schema, 'relationships', 'deleted').filter(
relationship => relationship.role?.compMod?.deleted,
);
const addedRelationships = getItems(schema, 'relationships', 'added').filter(
relationship => relationship.role?.compMod?.created,
);
const modifiedRelationships = getItems(schema, 'relationships', 'modified');

const deleteFkScripts = getDeleteForeignKeyScripts(provider)(deletedRelationships);
const addFkScripts = getRelationshipsScriptsWithUseSchema(
addedRelationships,
generateAddFkScripts,
getAddForeignKeyScript,
);
const modifiedFkScripts = getRelationshipsScriptsWithUseSchema(
modifiedRelationships,
generateModifyFkScripts,
getModifyForeignKeyScript,
);
return { deleteFkScripts, addFkScripts, modifiedFkScripts };
};

module.exports = {
getAlterRelationshipsScripts,
};
7 changes: 7 additions & 0 deletions forward_engineering/helpers/alterScriptHelpers/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,15 @@ const compareProperties = ({ new: newProperty, old: oldProperty }) => {
const getIsChangeProperties = (compMod, properties) =>
properties.some(property => compareProperties(compMod[property] || {}));

const getItems = (entity, nameProperty, modify) =>
[]
.concat(entity.properties?.[nameProperty]?.properties?.[modify]?.items)
.filter(Boolean)
.map(items => Object.values(items.properties)[0]);

module.exports = {
hydrateTableProperties,
getDifferentItems,
getIsChangeProperties,
getItems,
};
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,9 @@ module.exports = {

addUkConstraint:
'ALTER TABLE ${tableName} ADD CONSTRAINT ${constraintName} UNIQUE (${columnNames}) DISABLE${noValidate}${rely};',

addFkConstraint:
'ALTER TABLE ${childTableName} ADD CONSTRAINT ${constraintName} FOREIGN KEY (${childColumns}) REFERENCES ${parentTableName}(${parentColumns})${disableNoValidate};',

useSchema: 'USE ${schemaName};',
};