Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HCK-7455: FE cross-target relationships in container level script #223

Merged
merged 1 commit into from
Aug 1, 2024
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
84 changes: 44 additions & 40 deletions forward_engineering/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -97,7 +99,7 @@ const parseDataForEntityLevelScript = data => {
};

/**
* @param data {CoreData}
* @param {CoreData} data
* @return {{
* modelDefinitions: ModelDefinitions | unknown,
* internalDefinitions: InternalDefinitions | unknown,
Expand All @@ -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 {
Expand All @@ -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) => {
Expand All @@ -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 }>,
Expand Down Expand Up @@ -181,8 +185,8 @@ const getContainerScriptWithSeparateBuckets = async (app, data) => {
};

/**
* @param data {CoreData}
* @param app {App}
* @param {CoreData} data
* @param {App} app
* @return {Promise<string | Array<{ title: string, script: string, mode: string }>>}
* */
const getContainerScriptWithNotSeparateBuckets = async (app, data) => {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 = {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
23 changes: 17 additions & 6 deletions forward_engineering/helpers/feScriptBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down Expand Up @@ -198,6 +201,7 @@ const getContainerLevelEntitiesScriptDtos =
areNotNullConstraintsAvailable,
includeRelationshipsInEntityScripts,
includeSamplesInEntityScripts,
relatedSchemas,
}) => {
const _ = app.require('lodash');
const scriptDtos = [];
Expand Down Expand Up @@ -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(_)({
Expand Down Expand Up @@ -283,6 +288,7 @@ const buildContainerLevelFEScriptDto =
containerData,
includeRelationshipsInEntityScripts,
includeSamplesInEntityScripts,
relatedSchemas,
}) => {
const _ = app.require('lodash');
const dbVersion = data.modelData[0].dbVersion;
Expand All @@ -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 {
Expand Down
102 changes: 58 additions & 44 deletions forward_engineering/helpers/relationshipHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const getCollectionPropertyNamesByIds = _ => (collection, propertiesIds) => {
};

/**
* @param relationship {Object}
* @param {Object} relationship
* @return {Array<string>}
**/
const getChildFieldIds = relationship => {
Expand All @@ -28,7 +28,7 @@ const getChildFieldIds = relationship => {
};

/**
* @param relationship {Object}
* @param {Object} relationship
* @return {Array<string>}
**/
const getParentFieldIds = relationship => {
Expand All @@ -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<string, Object>, relatedSchemas?: Record<string, Object> }) => 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<Object>, entitiesJsonSchema: Object) => Array<string>}
**/
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<string, Object>, relatedSchemas?: Record<string, Object> }) => Array<string>}
*/
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,
Expand Down