From 0816cd4ac12a3b2b37bad02cb382168d1b6b2499 Mon Sep 17 00:00:00 2001 From: Vitalii Yarmus <71256742+Vitalii4as@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:57:52 +0300 Subject: [PATCH] HCK-7455: FE cross-target relationships in container level script (#223) --- forward_engineering/api.js | 84 ++++++++------- .../helpers/feScriptBuilder.js | 23 ++-- .../helpers/relationshipHelper.js | 102 ++++++++++-------- 3 files changed, 119 insertions(+), 90 deletions(-) diff --git a/forward_engineering/api.js b/forward_engineering/api.js index ceb2b1cc..b7f73c5b 100644 --- a/forward_engineering/api.js +++ b/forward_engineering/api.js @@ -51,19 +51,21 @@ const { getDataForSampleGeneration } = require('./sampleGeneration/sampleGenerat */ const parseEntities = (entities, serializedItems) => { - return entities.reduce((result, entityId) => { - try { - return Object.assign({}, result, { - [entityId]: JSON.parse(serializedItems[entityId]), - }); - } catch (e) { - return result; - } - }, {}); + return ( + entities?.reduce((result, entityId) => { + try { + return Object.assign({}, result, { + [entityId]: JSON.parse(serializedItems[entityId]), + }); + } catch (e) { + return result; + } + }, {}) ?? {} + ); }; /** - * @param data {CoreData} + * @param {CoreData} data * @return {{ * jsonSchema: unknown, * modelDefinitions: ModelDefinitions | unknown, @@ -97,7 +99,7 @@ const parseDataForEntityLevelScript = data => { }; /** - * @param data {CoreData} + * @param {CoreData} data * @return {{ * modelDefinitions: ModelDefinitions | unknown, * internalDefinitions: InternalDefinitions | unknown, @@ -115,6 +117,7 @@ const parseDataForContainerLevelScript = data => { const externalDefinitions = JSON.parse(data.externalDefinitions); const entitiesJsonSchema = parseEntities(data.entities, data.jsonSchema); const internalDefinitions = parseEntities(data.entities, data.internalDefinitions); + const relatedSchemas = parseEntities(data.relatedEntities, data.relatedSchemas); const { jsonData, entitiesData } = getDataForSampleGeneration(data, entitiesJsonSchema); return { @@ -126,12 +129,13 @@ const parseDataForContainerLevelScript = data => { entitiesJsonSchema, jsonData, entitiesData, + relatedSchemas, }; }; /** - * @param script {string} - * @param sample {string} + * @param {string} script + * @param {string} sample * @return {Array<{ title: string, script: string, mode: string }>} * */ const getScriptAndSampleResponse = (script, sample) => { @@ -151,8 +155,8 @@ const getScriptAndSampleResponse = (script, sample) => { }; /** - * @param data {CoreData} - * @param app {App} + * @param {CoreData} data + * @param {App} app * @return {Promise<{ * container: string, * entities: Array<{ name: string, script: string }>, @@ -181,8 +185,8 @@ const getContainerScriptWithSeparateBuckets = async (app, data) => { }; /** - * @param data {CoreData} - * @param app {App} + * @param {CoreData} data + * @param {App} app * @return {Promise>} * */ const getContainerScriptWithNotSeparateBuckets = async (app, data) => { @@ -220,10 +224,10 @@ const getContainerScriptWithNotSeparateBuckets = async (app, data) => { module.exports = { /** - * @param data {CoreData} - * @param logger {Logger} - * @param callback {PluginCallback} - * @param app {App} + * @param {CoreData} data + * @param {Logger} logger + * @param {PluginCallback} callback + * @param {App} app * */ generateScript(data, logger, callback, app) { try { @@ -248,10 +252,10 @@ module.exports = { }, /** - * @param data {CoreData} - * @param logger {Logger} - * @param callback {PluginCallback} - * @param app {App} + * @param {CoreData} data + * @param {Logger} logger + * @param {PluginCallback} callback + * @param {App} app * */ generateViewScript(data, logger, callback, app) { try { @@ -281,10 +285,10 @@ module.exports = { }, /** - * @param data {CoreData} - * @param logger {Logger} - * @param callback {PluginCallback} - * @param app {App} + * @param {CoreData} data + * @param {Logger} logger + * @param {PluginCallback} callback + * @param {App} app * */ async generateContainerScript(data, logger, callback, app) { try { @@ -308,10 +312,10 @@ module.exports = { }, /** - * @param data {CoreData} - * @param logger {Logger} - * @param cb {PluginCallback} - * @param app {App} + * @param {CoreData} data + * @param {Logger} logger + * @param {PluginCallback} cb + * @param {App} app * */ async applyToInstance(data, logger, cb, app) { const connectionData = { @@ -334,9 +338,9 @@ module.exports = { }, /** - * @param connectionInfo {CoreData} - * @param logger {Logger} - * @param cb {PluginCallback} + * @param {CoreData} connectionInfo + * @param {Logger} logger + * @param {PluginCallback} cb * */ async testConnection(connectionInfo, logger, cb) { try { @@ -362,10 +366,10 @@ module.exports = { }, /** - * @param data {CoreData} - * @param logger {Logger} - * @param callback {PluginCallback} - * @param app {App} + * @param {CoreData} data + * @param {Logger} logger + * @param {PluginCallback} callback + * @param {App} app * */ isDropInStatements(data, logger, callback, app) { try { diff --git a/forward_engineering/helpers/feScriptBuilder.js b/forward_engineering/helpers/feScriptBuilder.js index 8ce50e07..42ae4cff 100644 --- a/forward_engineering/helpers/feScriptBuilder.js +++ b/forward_engineering/helpers/feScriptBuilder.js @@ -111,7 +111,10 @@ const buildEntityLevelFEScript = const relationshipsWithThisTableAsChild = modelData[1]?.relationships.filter( relationship => relationship.childCollection === entityId, ); - relationshipScripts = getCreateRelationshipScripts(app)(relationshipsWithThisTableAsChild, jsonSchema); + relationshipScripts = getCreateRelationshipScripts(app)({ + relationships: relationshipsWithThisTableAsChild, + jsonSchemas: jsonSchema, + }); } return buildScript([ @@ -198,6 +201,7 @@ const getContainerLevelEntitiesScriptDtos = areNotNullConstraintsAvailable, includeRelationshipsInEntityScripts, includeSamplesInEntityScripts, + relatedSchemas, }) => { const _ = app.require('lodash'); const scriptDtos = []; @@ -226,10 +230,11 @@ const getContainerLevelEntitiesScriptDtos = const relationshipsWithThisTableAsChild = data.relationships.filter( relationship => relationship.childCollection === entityId, ); - relationshipScripts = getCreateRelationshipScripts(app)( - relationshipsWithThisTableAsChild, - entitiesJsonSchema, - ); + relationshipScripts = getCreateRelationshipScripts(app)({ + relationships: relationshipsWithThisTableAsChild, + jsonSchemas: entitiesJsonSchema, + relatedSchemas, + }); } const sampleScript = await getSampleScriptForContainerLevelScript(_)({ @@ -283,6 +288,7 @@ const buildContainerLevelFEScriptDto = containerData, includeRelationshipsInEntityScripts, includeSamplesInEntityScripts, + relatedSchemas, }) => { const _ = app.require('lodash'); const dbVersion = data.modelData[0].dbVersion; @@ -305,11 +311,16 @@ const buildContainerLevelFEScriptDto = areNotNullConstraintsAvailable, includeRelationshipsInEntityScripts, includeSamplesInEntityScripts, + relatedSchemas, }); let relationshipScrips = []; if (!includeRelationshipsInEntityScripts && arePkFkConstraintsAvailable) { - relationshipScrips = getCreateRelationshipScripts(app)(data.relationships, entitiesJsonSchema); + relationshipScrips = getCreateRelationshipScripts(app)({ + relationships: data.relationships, + jsonSchemas: entitiesJsonSchema, + relatedSchemas, + }); } return { diff --git a/forward_engineering/helpers/relationshipHelper.js b/forward_engineering/helpers/relationshipHelper.js index 875b6d79..c2751669 100644 --- a/forward_engineering/helpers/relationshipHelper.js +++ b/forward_engineering/helpers/relationshipHelper.js @@ -18,7 +18,7 @@ const getCollectionPropertyNamesByIds = _ => (collection, propertiesIds) => { }; /** - * @param relationship {Object} + * @param {Object} relationship * @return {Array} **/ const getChildFieldIds = relationship => { @@ -28,7 +28,7 @@ const getChildFieldIds = relationship => { }; /** - * @param relationship {Object} + * @param {Object} relationship * @return {Array} **/ const getParentFieldIds = relationship => { @@ -38,54 +38,68 @@ const getParentFieldIds = relationship => { }; /** - * @return {(relationship: Object, entitiesJsonSchema: Object) => string} - **/ -const createSingleRelationship = (_, ddlProvider) => (relationship, entitiesJsonSchema) => { - const parentTable = entitiesJsonSchema[relationship.parentCollection]; - const childTable = entitiesJsonSchema[relationship.childCollection]; - const childBucketName = prepareName(childTable?.bucketName); - const parentBucketName = prepareName(parentTable?.bucketName); + * @returns {({ relationship: Object, jsonSchemas: Record, relatedSchemas?: Record }) => string} + */ +const createSingleRelationship = + (_, ddlProvider) => + ({ relationship, jsonSchemas, relatedSchemas }) => { + const parentTable = + jsonSchemas[relationship.parentCollection] ?? relatedSchemas?.[relationship.parentCollection]; + const childTable = jsonSchemas[relationship.childCollection]; + const childBucketName = prepareName(childTable?.bucketName); + const parentBucketName = prepareName(parentTable?.bucketName); - if (!parentTable || !childTable) { - return ''; - } - const childFieldIds = getChildFieldIds(relationship); - const parentFieldIds = getParentFieldIds(relationship); + if (!parentTable || !childTable) { + return ''; + } + const childFieldIds = getChildFieldIds(relationship); + const parentFieldIds = getParentFieldIds(relationship); - const parentColumnNames = getCollectionPropertyNamesByIds(_)(parentTable, parentFieldIds); - const childColumnNames = getCollectionPropertyNamesByIds(_)(childTable, childFieldIds); - if (!parentColumnNames?.length || !childColumnNames?.length) { - return ''; - } + const parentColumnNames = getCollectionPropertyNamesByIds(_)(parentTable, parentFieldIds); + const childColumnNames = getCollectionPropertyNamesByIds(_)(childTable, childFieldIds); + if (!parentColumnNames?.length || !childColumnNames?.length) { + return ''; + } - const childBucketNameForDDL = replaceSpaceWithUnderscore(childBucketName); - const childTableNameForDDL = prepareName(replaceSpaceWithUnderscore(getName(childTable))); - const parentBucketNameForDDL = replaceSpaceWithUnderscore(parentBucketName); - const parentTableNameForDDL = prepareName(replaceSpaceWithUnderscore(getName(parentTable))); + const childBucketNameForDDL = replaceSpaceWithUnderscore(childBucketName); + const childTableNameForDDL = prepareName(replaceSpaceWithUnderscore(getName(childTable))); + const parentBucketNameForDDL = replaceSpaceWithUnderscore(parentBucketName); + const parentTableNameForDDL = prepareName(replaceSpaceWithUnderscore(getName(parentTable))); - const addFkScript = ddlProvider.addFkConstraint({ - childTableName: getFullEntityName(childBucketNameForDDL, childTableNameForDDL), - childColumns: childColumnNames.map(name => prepareName(name)), - fkConstraintName: wrapInTicks(getRelationshipName(relationship)), - parentColumns: parentColumnNames.map(name => prepareName(name)), - parentTableName: getFullEntityName(parentBucketNameForDDL, parentTableNameForDDL), - }); - if (relationship.isActivated === false) { - return commentDeactivatedStatements(addFkScript, false); - } - return addFkScript; -}; + const addFkScript = ddlProvider.addFkConstraint({ + childTableName: getFullEntityName(childBucketNameForDDL, childTableNameForDDL), + childColumns: childColumnNames.map(name => prepareName(name)), + fkConstraintName: wrapInTicks(getRelationshipName(relationship)), + parentColumns: parentColumnNames.map(name => prepareName(name)), + parentTableName: getFullEntityName(parentBucketNameForDDL, parentTableNameForDDL), + }); + if (relationship.isActivated === false) { + return commentDeactivatedStatements(addFkScript, false); + } + return addFkScript; + }; /** - * @return {(relationships: Array, entitiesJsonSchema: Object) => Array} - **/ -const getCreateRelationshipScripts = app => (relationships, entitiesJsonSchema) => { - const _ = app.require('lodash'); - const ddlProvider = require('../ddlProvider/ddlProvider')(app); - return relationships - .map(relationship => createSingleRelationship(_, ddlProvider)(relationship, entitiesJsonSchema)) - .filter(Boolean); -}; + * @returns {({ relationships: Object[], jsonSchemas: Record, relatedSchemas?: Record }) => Array} + */ +const getCreateRelationshipScripts = + app => + ({ relationships, jsonSchemas, relatedSchemas }) => { + const _ = app.require('lodash'); + const ddlProvider = require('../ddlProvider/ddlProvider')(app); + return relationships + .map(relationship => + createSingleRelationship( + _, + ddlProvider, + )({ + relationship, + jsonSchemas, + relatedSchemas, + }), + ) + .filter(Boolean); + }; module.exports = { getCreateRelationshipScripts,