From c4e8fe1c11fe59290c02062507660f7e46f349a5 Mon Sep 17 00:00:00 2001 From: chulanovskyi Date: Wed, 17 Dec 2025 18:17:13 +0200 Subject: [PATCH 1/2] fix: properly combine and format all column constraints --- .../alterScriptHelpers/alterEntityHelper.js | 2 +- .../alterForeignKeyHelper.js | 15 +- .../checkConstraintHelper.js | 17 +-- .../defaultConstraintHelper.js | 9 +- .../alterScriptHelpers/generalHelper.js | 9 +- .../nonNullConstraintHelper.js | 9 +- .../alterScriptHelpers/primaryKeyHelper.js | 23 +-- .../alterScriptHelpers/uniqueKeyHelper.js | 21 +-- forward_engineering/helpers/columnHelper.js | 134 ++++++++++++++---- forward_engineering/helpers/constants.js | 8 ++ .../helpers/constraintHelper.js | 1 + forward_engineering/helpers/generalHelper.js | 8 +- forward_engineering/helpers/tableHelper.js | 14 +- 13 files changed, 174 insertions(+), 96 deletions(-) diff --git a/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js index ecb2d02..9f96826 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js @@ -245,7 +245,7 @@ const getAddColumnsScripts = (definitions, provider) => entity => { const entityData = { ...entity, ..._.omit(entity.role, ['properties']) }; const { columns } = getColumns(entityData, true, definitions); const properties = getEntityProperties(entity); - const columnStatement = getColumnsStatement(columns, null, entityData.disableNoValidate); + const columnStatement = getColumnsStatement({ columns }); const fullCollectionName = generateFullEntityName(entity); const { hydratedAddIndexes, hydratedDropIndexes } = hydrateIndex(entity, properties, definitions); const modifyScript = generateModifyCollectionScript(entity, definitions, provider); diff --git a/forward_engineering/helpers/alterScriptHelpers/alterForeignKeyHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterForeignKeyHelper.js index a50ba40..8dac0cf 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterForeignKeyHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterForeignKeyHelper.js @@ -1,13 +1,4 @@ -const { - getFullEntityName, - generateFullEntityName, - getEntityProperties, - getContainerName, - getEntityData, - getEntityName, - prepareScript, - hydrateProperty, -} = require('./generalHelper'); +const { getFullEntityName } = require('./generalHelper'); const { prepareName, commentDeactivatedStatements } = require('../generalHelper'); const templates = require('./config/templates'); @@ -69,7 +60,7 @@ const canRelationshipBeAdded = relationship => { compMod.child?.bucket, compMod.child?.collection, compMod.child?.collection?.fkFields?.length, - ].every(property => Boolean(property)); + ].every(Boolean); }; const getAddForeignKeyScript = provider => relationship => { @@ -100,7 +91,7 @@ const canRelationshipBeDeleted = relationship => { compMod.code?.old || compMod.name?.old || getRelationshipName(relationship), compMod.child?.bucket, compMod.child?.collection, - ].every(property => Boolean(property)); + ].every(Boolean); }; const getDeleteForeignKeyScripts = provider => deletedRelationships => { diff --git a/forward_engineering/helpers/alterScriptHelpers/checkConstraintHelper.js b/forward_engineering/helpers/alterScriptHelpers/checkConstraintHelper.js index 34b1ac2..f36c79e 100644 --- a/forward_engineering/helpers/alterScriptHelpers/checkConstraintHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/checkConstraintHelper.js @@ -3,8 +3,7 @@ const templates = require('./config/templates'); const { generateFullEntityName, getDefaultConstraintName } = require('./generalHelper'); const { getTypeByProperty } = require('../columnHelper'); const { commentDeactivatedStatements } = require('../generalHelper'); - -const postfix = 'check'; +const { CONSTRAINT_POSTFIX } = require('../constants'); const didCompositeCheckConstraintsChange = collection => { const checkConstraintsDto = collection?.role?.compMod?.chkConstr || {}; @@ -33,7 +32,9 @@ const getDropCompositeCheckConstraintsScripts = ({ collection, provider }) => { const oldCheckConstraints = checkConstraintsDto.old || []; return oldCheckConstraints.map(oldCheckConstraint => { - const constraintName = oldCheckConstraint.constraintName || getDefaultConstraintName(collection, postfix); + const constraintName = + oldCheckConstraint.constraintName || + getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.check }); return provider.assignTemplates(templates.dropConstraint, { tableName, @@ -54,7 +55,9 @@ const getAddCompositeCheckConstraintsScripts = ({ collection, provider }) => { const newCheckConstraints = checkConstraintsDto.new || []; return newCheckConstraints.map(newCheckConstraint => { - const constraintName = newCheckConstraint.constraintName || getDefaultConstraintName(collection, postfix); + const constraintName = + newCheckConstraint.constraintName || + getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.check }); const expression = newCheckConstraint.checkExpression || ''; const enable = newCheckConstraint.enableSpecification ? ` ${newCheckConstraint.enableSpecification}` : ''; const noValidate = newCheckConstraint.noValidateSpecification @@ -82,10 +85,10 @@ const getModifyCompositeCheckConstraintsScripts = ({ collection, provider }) => const getModifyColumnCheckConstraintsScripts = ({ collection, provider, definitions }) => { const tableName = generateFullEntityName(collection); - const constraintName = getDefaultConstraintName(collection, postfix); + const constraintName = getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.check }); const isActivated = collection.role.isActivated; - const addCheckConstraintsScript = _.toPairs(collection.properties).flatMap(([columnName, jsonSchema]) => { + return _.toPairs(collection.properties).flatMap(([columnName, jsonSchema]) => { const oldName = jsonSchema.compMod.oldField.name; const newField = jsonSchema.compMod.newField; @@ -120,8 +123,6 @@ const getModifyColumnCheckConstraintsScripts = ({ collection, provider, definiti return scripts.map(statement => commentDeactivatedStatements(statement, isActivated)); }); - - return addCheckConstraintsScript; }; module.exports = { diff --git a/forward_engineering/helpers/alterScriptHelpers/defaultConstraintHelper.js b/forward_engineering/helpers/alterScriptHelpers/defaultConstraintHelper.js index df74681..e0febc0 100644 --- a/forward_engineering/helpers/alterScriptHelpers/defaultConstraintHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/defaultConstraintHelper.js @@ -3,15 +3,14 @@ const templates = require('./config/templates'); const { generateFullEntityName, getDefaultConstraintName } = require('./generalHelper'); const { getTypeByProperty } = require('../columnHelper'); const { commentDeactivatedStatements } = require('../generalHelper'); - -const postfix = 'default'; +const { CONSTRAINT_POSTFIX } = require('../constants'); const getModifyDefaultValueConstraintsScripts = ({ collection, provider, definitions }) => { const tableName = generateFullEntityName(collection); - const constraintName = getDefaultConstraintName(collection, postfix); + const constraintName = getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.default }); const isActivated = collection.role.isActivated; - const addDefaultConstraintsScript = _.toPairs(collection.properties).flatMap(([columnName, jsonSchema]) => { + return _.toPairs(collection.properties).flatMap(([columnName, jsonSchema]) => { const oldName = jsonSchema.compMod.oldField.name; const newField = jsonSchema.compMod.newField; @@ -46,8 +45,6 @@ const getModifyDefaultValueConstraintsScripts = ({ collection, provider, definit return scripts.map(statement => commentDeactivatedStatements(statement, isActivated)); }); - - return addDefaultConstraintsScript; }; module.exports = { diff --git a/forward_engineering/helpers/alterScriptHelpers/generalHelper.js b/forward_engineering/helpers/alterScriptHelpers/generalHelper.js index 74af434..3032705 100644 --- a/forward_engineering/helpers/alterScriptHelpers/generalHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/generalHelper.js @@ -25,7 +25,7 @@ const generateFullEntityName = entity => { const getEntityProperties = entity => { const propertiesInRole = _.get(entity, 'role.properties', {}); const propertiesInEntity = _.get(entity, 'properties', {}); - return { ...(propertiesInEntity || {}), ...propertiesInRole }; + return { ...propertiesInEntity, ...propertiesInRole }; }; const getEntityName = (compMod = {}, type = 'collectionName') => { @@ -43,13 +43,14 @@ const isEqualProperty = (compMod, nameProperty) => { }; const hydrateProperty = (entity, compMod, nameProperty) => { - return !isEqualProperty(compMod, nameProperty) ? entity?.role?.[nameProperty] : null; + return isEqualProperty(compMod, nameProperty) ? null : entity?.role?.[nameProperty]; }; -const getDefaultConstraintName = (collection, postfix) => { +const getDefaultConstraintName = ({ collection, column = {}, postfix }) => { const entityData = collection?.role || {}; const entityName = prepareName(getName(entityData)); - return `${entityName}_${postfix}`; + const columnName = prepareName(getName(column)); + return [entityName, columnName, postfix].filter(Boolean).join('_'); }; module.exports = { diff --git a/forward_engineering/helpers/alterScriptHelpers/nonNullConstraintHelper.js b/forward_engineering/helpers/alterScriptHelpers/nonNullConstraintHelper.js index 1bc2cbf..6918b7e 100644 --- a/forward_engineering/helpers/alterScriptHelpers/nonNullConstraintHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/nonNullConstraintHelper.js @@ -3,18 +3,17 @@ const templates = require('./config/templates'); const { generateFullEntityName, getDefaultConstraintName } = require('./generalHelper'); const { getTypeByProperty } = require('../columnHelper'); const { commentDeactivatedStatements } = require('../generalHelper'); - -const postfix = 'nn'; +const { CONSTRAINT_POSTFIX } = require('../constants'); const getModifyNonNullColumnsScripts = ({ collection, provider, definitions }) => { const tableName = generateFullEntityName(collection); - const constraintName = getDefaultConstraintName(collection, postfix); + const constraintName = getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.notNull }); const isActivated = collection.role.isActivated; const currentRequiredColumnNames = collection.required || []; const previousRequiredColumnNames = collection.role.required || []; - const addNotNullConstraintsScript = _.toPairs(collection.properties).flatMap(([columnName, jsonSchema]) => { + return _.toPairs(collection.properties).flatMap(([columnName, jsonSchema]) => { const oldName = jsonSchema.compMod.oldField.name; const newField = jsonSchema.compMod.newField; @@ -44,8 +43,6 @@ const getModifyNonNullColumnsScripts = ({ collection, provider, definitions }) = return scripts.map(statement => commentDeactivatedStatements(statement, isActivated)); }); - - return addNotNullConstraintsScript; }; module.exports = { diff --git a/forward_engineering/helpers/alterScriptHelpers/primaryKeyHelper.js b/forward_engineering/helpers/alterScriptHelpers/primaryKeyHelper.js index 9f35bbe..66ca10a 100644 --- a/forward_engineering/helpers/alterScriptHelpers/primaryKeyHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/primaryKeyHelper.js @@ -1,12 +1,11 @@ const _ = require('lodash'); -const { getName, prepareName, commentDeactivatedStatements } = require('../generalHelper'); +const { prepareName, commentDeactivatedStatements } = require('../generalHelper'); const templates = require('./config/templates'); const { generateFullEntityName, getDefaultConstraintName } = require('./generalHelper'); - -const postfix = 'pk'; +const { CONSTRAINT_POSTFIX } = require('../constants'); const getPropertyNameByGuid = (collection, guid) => { - const property = _.toPairs(collection?.role?.properties).find(([name, jsonSchema]) => jsonSchema.GUID === guid); + const property = _.toPairs(collection?.role?.properties).find(([, jsonSchema]) => jsonSchema.GUID === guid); return property?.[0] && prepareName(property[0]); }; @@ -40,7 +39,8 @@ const getDropCompositePkScripts = ({ collection, provider }) => { const oldPrimaryKeys = pkDto.old || []; return oldPrimaryKeys.map(oldPk => { - const pkConstraintName = oldPk.constraintName || getDefaultConstraintName(collection, postfix); + const pkConstraintName = + oldPk.constraintName || getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.primaryKey }); const constraintName = prepareName(pkConstraintName); return provider.assignTemplates(templates.dropConstraint, { @@ -65,7 +65,8 @@ const getAddCompositePkScripts = ({ collection, provider }) => { const compositePrimaryKey = newPk.compositePrimaryKey || []; const guidsOfColumnsInPk = compositePrimaryKey.map(compositePkEntry => compositePkEntry.keyId); const columnNames = getPropertiesNamesByGUIDs(collection, guidsOfColumnsInPk); - const pkConstraintName = newPk.constraintName || getDefaultConstraintName(collection, postfix); + const pkConstraintName = + newPk.constraintName || getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.primaryKey }); const constraintName = prepareName(pkConstraintName); const noValidate = newPk.noValidateSpecification ? ` ${newPk.noValidateSpecification}` : ''; const rely = newPk.rely ? ` ${newPk.rely}` : ''; @@ -89,10 +90,10 @@ const getModifyCompositePkScripts = ({ collection, provider }) => { const getDropPkScripts = ({ collection, provider }) => { const tableName = generateFullEntityName(collection); - const constraintName = getDefaultConstraintName(collection, postfix); + const constraintName = getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.primaryKey }); return _.toPairs(collection.properties) - .filter(([name, jsonSchema]) => { + .filter(([, jsonSchema]) => { const oldName = jsonSchema.compMod.oldField.name; const oldJsonSchema = collection.role.properties[oldName]; const wasTheFieldARegularPrimaryKey = oldJsonSchema?.primaryKey && !oldJsonSchema?.compositePrimaryKey; @@ -100,7 +101,7 @@ const getDropPkScripts = ({ collection, provider }) => { const isNotAPrimaryKey = !jsonSchema.primaryKey && !jsonSchema.compositePrimaryKey; return wasTheFieldARegularPrimaryKey && isNotAPrimaryKey; }) - .map(([name, jsonSchema]) => { + .map(() => { return provider.assignTemplates(templates.dropConstraint, { tableName, constraintName, @@ -110,10 +111,10 @@ const getDropPkScripts = ({ collection, provider }) => { const getAddPkScripts = ({ collection, provider }) => { const tableName = generateFullEntityName(collection); - const constraintName = getDefaultConstraintName(collection, postfix); + const constraintName = getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.primaryKey }); return _.toPairs(collection.properties) - .filter(([name, jsonSchema]) => { + .filter(([, jsonSchema]) => { const isRegularPrimaryKey = jsonSchema.primaryKey && !jsonSchema.compositePrimaryKey; const oldName = jsonSchema.compMod.oldField.name; const wasTheFieldAPrimaryKey = Boolean(collection.role.properties[oldName]?.primaryKey); diff --git a/forward_engineering/helpers/alterScriptHelpers/uniqueKeyHelper.js b/forward_engineering/helpers/alterScriptHelpers/uniqueKeyHelper.js index 4d704bb..ad08a60 100644 --- a/forward_engineering/helpers/alterScriptHelpers/uniqueKeyHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/uniqueKeyHelper.js @@ -1,9 +1,8 @@ const _ = require('lodash'); -const { getName, prepareName, commentDeactivatedStatements } = require('../generalHelper'); +const { prepareName, commentDeactivatedStatements } = require('../generalHelper'); const templates = require('./config/templates'); const { generateFullEntityName, getDefaultConstraintName } = require('./generalHelper'); - -const postfix = 'uk'; +const { CONSTRAINT_POSTFIX } = require('../constants'); const getPropertyNameByGuid = (collection, guid) => { const property = _.toPairs(collection?.role?.properties).find(([name, jsonSchema]) => jsonSchema.GUID === guid); @@ -40,7 +39,8 @@ const getDropCompositeUkScripts = ({ collection, provider }) => { const oldUniqueKeys = pkDto.old || []; return oldUniqueKeys.map(oldUk => { - const pkConstraintName = oldUk.constraintName || getDefaultConstraintName(collection, postfix); + const pkConstraintName = + oldUk.constraintName || getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.uniqueKey }); const constraintName = prepareName(pkConstraintName); return provider.assignTemplates(templates.dropConstraint, { @@ -65,7 +65,8 @@ const getAddCompositeUkScripts = ({ collection, provider }) => { const compositeUniqueKey = newUk.compositeUniqueKey || []; const guidsOfColumnsInUk = compositeUniqueKey.map(compositeUkEntry => compositeUkEntry.keyId); const columnNames = getPropertiesNamesByGUIDs(collection, guidsOfColumnsInUk); - const pkConstraintName = newUk.constraintName || getDefaultConstraintName(collection, postfix); + const pkConstraintName = + newUk.constraintName || getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.uniqueKey }); const constraintName = prepareName(pkConstraintName); const noValidate = newUk.noValidateSpecification ? ` ${newUk.noValidateSpecification}` : ''; const rely = newUk.rely ? ` ${newUk.rely}` : ''; @@ -89,10 +90,10 @@ const getModifyCompositeUkScripts = ({ collection, provider }) => { const getDropUkScripts = ({ collection, provider }) => { const tableName = generateFullEntityName(collection); - const constraintName = getDefaultConstraintName(collection, postfix); + const constraintName = getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.uniqueKey }); return _.toPairs(collection.properties) - .filter(([name, jsonSchema]) => { + .filter(([, jsonSchema]) => { const oldName = jsonSchema.compMod.oldField.name; const oldJsonSchema = collection.role.properties[oldName]; const wasTheFieldARegularUniqueKey = oldJsonSchema?.unique && !oldJsonSchema?.compositeUniqueKey; @@ -100,7 +101,7 @@ const getDropUkScripts = ({ collection, provider }) => { const isNotAUniqueKey = !jsonSchema.unique && !jsonSchema.compositeUniqueKey; return wasTheFieldARegularUniqueKey && isNotAUniqueKey; }) - .map(([name, jsonSchema]) => { + .map(() => { return provider.assignTemplates(templates.dropConstraint, { tableName, constraintName, @@ -110,10 +111,10 @@ const getDropUkScripts = ({ collection, provider }) => { const getAddUkScripts = ({ collection, provider }) => { const tableName = generateFullEntityName(collection); - const constraintName = getDefaultConstraintName(collection, postfix); + const constraintName = getDefaultConstraintName({ collection, postfix: CONSTRAINT_POSTFIX.uniqueKey }); return _.toPairs(collection.properties) - .filter(([name, jsonSchema]) => { + .filter(([, jsonSchema]) => { const isRegularUniqueKey = jsonSchema.unique && !jsonSchema.compositeUniqueKey; const oldName = jsonSchema.compMod.oldField.name; const wasTheFieldAUniqueKey = Boolean(collection.role.properties[oldName]?.unique); diff --git a/forward_engineering/helpers/columnHelper.js b/forward_engineering/helpers/columnHelper.js index f274725..e964768 100644 --- a/forward_engineering/helpers/columnHelper.js +++ b/forward_engineering/helpers/columnHelper.js @@ -6,6 +6,8 @@ const { encodeStringLiteral, } = require('./generalHelper'); const { getConstraintOpts } = require('./constraintHelper'); +const { getDefaultConstraintName } = require('./alterScriptHelpers/generalHelper'); +const { CONSTRAINT_POSTFIX } = require('./constants'); const getStructChild = (name, type, comment) => `${prepareName(name)}: ${type}` + (comment ? ` COMMENT '${encodeStringLiteral(comment)}'` : ''); @@ -73,7 +75,7 @@ const getPropertyByType = type => { return { type, - ...(childTypeDescriptor.defaultValues || {}), + ...childTypeDescriptor.defaultValues, }; }; @@ -102,7 +104,7 @@ const getArray = getTypeByProperty => property => { }; const getMapKey = property => { - if (['char', 'varchar'].indexOf(property.keySubtype) !== -1) { + if (['char', 'varchar'].includes(property.keySubtype)) { return property.keySubtype + '(255)'; } else if (property.keySubtype) { return property.keySubtype; @@ -138,7 +140,7 @@ const getMap = getTypeByProperty => property => { const getText = property => { const mode = property.mode; - if (['char', 'varchar'].indexOf(mode) === -1) { + if (['char', 'varchar'].includes(mode)) { return 'string'; } else if (property.maxLength) { return mode + `(${property.maxLength})`; @@ -237,7 +239,7 @@ const getDefinitionByReference = (definitions, reference) => { const allDefinitions = definitions.reduce( (result, { properties }) => ({ ...result, - ...(properties || {}), + ...properties, }), {}, ); @@ -342,37 +344,113 @@ const getColumns = (jsonSchema, areColumnConstraintsAvailable, definitions) => { return { columns, deactivatedColumnNames }; }; -const getColumnStatement = ({ name, type, comment, constraints, isActivated, isParentActivated }) => { +const getColumnStatementParts = ({ collection, column }) => { + const { name, type, comment, isActivated, isParentActivated } = column; const commentStatement = comment ? ` COMMENT '${encodeStringLiteral(comment)}'` : ''; - const constraintsStatement = constraints ? getColumnConstraintsStatement(constraints) : ''; + const { inline, separate } = getColumnConstraintsStatement({ collection, column }); const isColumnActivated = isParentActivated ? isActivated : true; - return commentDeactivatedStatements(`${name} ${type}${constraintsStatement}${commentStatement}`, isColumnActivated); + + return { + columnStatement: commentDeactivatedStatements(`${name} ${type}${inline}${commentStatement}`, isColumnActivated), + constraintsStatement: separate, + }; }; -const getColumnsStatement = (columns, isParentActivated) => { - return Object.keys(columns) - .map(name => { - return getColumnStatement({ ...columns[name], name, isParentActivated }); - }) - .join(',\n'); +const getColumnsStatement = ({ collection, columns, isParentActivated }) => { + const columnStatements = []; + const constraintStatements = []; + + for (const name of Object.keys(columns)) { + const { columnStatement, constraintsStatement } = getColumnStatementParts({ + collection, + column: { ...columns[name], name, isParentActivated }, + }); + + columnStatements.push(columnStatement); + + if (constraintsStatement) { + constraintStatements.push(constraintsStatement); + } + } + + return [...columnStatements, ...constraintStatements].join(',\n'); }; -const getColumnConstraintsStatement = constraint => { +const getColumnConstraintsStatement = ({ collection, column }) => { + const result = { + inline: '', + separate: '', + }; + + if (!column.constraints) { + return result; + } + const { notNull, unique, check, defaultValue, primaryKey, rely, noValidateSpecification, enableSpecification } = - constraint; - const noValidateStatement = enableSpecification => + column.constraints; + + const getNoValidateStatement = enableSpecification => getConstraintOpts({ rely, enableSpecification, noValidateSpecification }); - const getColStatement = (statement, noValidateStatement) => - statement ? ` ${statement}${noValidateStatement}` : ''; - const constraints = [ - notNull && !unique && !primaryKey ? getColStatement('NOT NULL', noValidateStatement(enableSpecification)) : '', - unique ? getColStatement('UNIQUE', noValidateStatement('DISABLE')) : '', - defaultValue ? getColStatement(`DEFAULT ${defaultValue}`, noValidateStatement(enableSpecification)) : '', - check ? getColStatement(`CHECK ${check}`, noValidateStatement(enableSpecification)) : '', - primaryKey ? getColStatement('PRIMARY KEY', noValidateStatement('DISABLE')) : '', - ].filter(Boolean); - - return constraints[0] || ''; + + const getConstraint = ({ statement, postfix, noValidate, skipName = false }) => { + const constraintName = getDefaultConstraintName({ collection, column, postfix }); + const columnName = skipName ? '' : ` ${column.name}`; + return `CONSTRAINT ${constraintName} ${statement}${columnName} ${noValidate}`; + }; + + const statements = []; + + if (primaryKey) { + statements.push( + getConstraint({ + statement: 'PRIMARY KEY', + postfix: CONSTRAINT_POSTFIX.primaryKey, + noValidate: getNoValidateStatement('DISABLE'), + }), + ); + } + + if (unique) { + statements.push( + getConstraint({ + statement: 'UNIQUE', + postfix: CONSTRAINT_POSTFIX.uniqueKey, + noValidate: getNoValidateStatement('DISABLE'), + }), + ); + } + + if (notNull) { + statements.push( + getConstraint({ + statement: `CHECK (${column.name} IS NOT NULL)`, + skipName: true, + postfix: CONSTRAINT_POSTFIX.notNull, + noValidate: getNoValidateStatement(enableSpecification), + }), + ); + } + + if (defaultValue) { + const value = typeof defaultValue === 'string' ? `'${defaultValue}'` : defaultValue; + result.inline = ` DEFAULT ${value}`; + } + + if (check) { + statements.push( + getConstraint({ + statement: `CHECK (${check})`, + postfix: CONSTRAINT_POSTFIX.check, + noValidate: getNoValidateStatement(enableSpecification), + }), + ); + } + + if (statements.length) { + result.separate = statements.join(',\n'); + } + + return result; }; const getDescription = (definitions, property) => { @@ -408,7 +486,7 @@ const clearComplexStructure = ({ type }) => { module.exports = { getColumns, getColumnsStatement, - getColumnStatement, + getColumnStatementParts, getTypeByProperty, clearComplexStructure, }; diff --git a/forward_engineering/helpers/constants.js b/forward_engineering/helpers/constants.js index dd9b91b..95c84bc 100644 --- a/forward_engineering/helpers/constants.js +++ b/forward_engineering/helpers/constants.js @@ -1,3 +1,11 @@ module.exports = { DROP_STATEMENTS: ['DROP INDEX', 'DROP VIEW', 'DROP TABLE', 'DROP DATABASE', 'DROP MATERIALIZED VIEW'], + CONSTRAINT_POSTFIX: { + primaryKey: 'pk', + foreignKey: 'fk', + uniqueKey: 'uk', + notNull: 'nn', + check: 'check', + default: 'default', + }, }; diff --git a/forward_engineering/helpers/constraintHelper.js b/forward_engineering/helpers/constraintHelper.js index df34866..1ed4c39 100644 --- a/forward_engineering/helpers/constraintHelper.js +++ b/forward_engineering/helpers/constraintHelper.js @@ -49,6 +49,7 @@ const getConstraintOpts = ({ noValidateSpecification, enableSpecification, rely const getUniqueKeyStatement = (jsonSchema, isParentItemActivated) => { const getStatement = ({ keys, name, constraintOptsStatement }) => `CONSTRAINT ${name} UNIQUE (${keys})${constraintOptsStatement}`; + const getColumnsName = columns => columns.map(column => column.name).join(', '); const hydratedUniqueKeys = hydrateUniqueKeys(jsonSchema); diff --git a/forward_engineering/helpers/generalHelper.js b/forward_engineering/helpers/generalHelper.js index 357b8ea..9f8798f 100644 --- a/forward_engineering/helpers/generalHelper.js +++ b/forward_engineering/helpers/generalHelper.js @@ -40,10 +40,10 @@ const isEscaped = name => /\`[\s\S]*\`/.test(name); const checkNameNeedBackticks = name => !/^[a-zA-Z0-9_]*$/.test(name) || name.startsWith('_'); +const isReserved = name => RESERVED_WORDS.includes(name.toLowerCase()); + const prepareName = (name = '') => { - if (checkNameNeedBackticks(name) && !isEscaped(name)) { - return `\`${name}\``; - } else if (RESERVED_WORDS.includes(name.toLowerCase())) { + if ((checkNameNeedBackticks(name) && !isEscaped(name)) || isReserved(name)) { return `\`${name}\``; } return name; @@ -75,7 +75,7 @@ const getTypeDescriptor = typeName => { descriptors[typeName] = require(`../../types/${typeName}.json`); return descriptors[typeName]; - } catch (e) { + } catch { return {}; } }; diff --git a/forward_engineering/helpers/tableHelper.js b/forward_engineering/helpers/tableHelper.js index 9513cae..c7c7cf9 100644 --- a/forward_engineering/helpers/tableHelper.js +++ b/forward_engineering/helpers/tableHelper.js @@ -8,7 +8,7 @@ const { removeRedundantTrailingCommaFromStatement, encodeStringLiteral, } = require('./generalHelper'); -const { getColumnsStatement, getColumnStatement, getColumns } = require('./columnHelper'); +const { getColumnsStatement, getColumnStatementParts, getColumns } = require('./columnHelper'); const keyHelper = require('./keyHelper'); const constraintHelper = require('./constraintHelper'); @@ -129,7 +129,8 @@ const getSortedKeys = (sortedKeys, deactivatedColumnNames, isParentItemActivated }; const getPartitionKeyStatement = (keys, isParentActivated) => { - const getKeysStatement = keys => keys.map(getColumnStatement).join(','); + const getKeysStatement = keys => + keys.map(key => getColumnStatementParts({ column: key }).columnStatement).join(','); if (!Array.isArray(keys) || !keys.length) { return ''; @@ -256,10 +257,11 @@ const getTableStatement = ( tableName, isTemporary: tableData.temporaryTable, isExternal: tableData.externalTable, - columnStatement: getColumnsStatement( - removePartitions(columns, keyNames.compositePartitionKey), - isTableActivated, - ), + columnStatement: getColumnsStatement({ + collection: tableData, + columns: removePartitions(columns, keyNames.compositePartitionKey), + isParentActivated: isTableActivated, + }), primaryKeyStatement: isPkOrFkConstraintAvailable ? getPrimaryKeyStatement(jsonSchema, keyNames.primaryKeys, deactivatedColumnNames, isTableActivated) : null, From 58d82c059c5fe58d65eb2fbab4685d4bf321a73f Mon Sep 17 00:00:00 2001 From: chulanovskyi Date: Wed, 17 Dec 2025 18:24:30 +0200 Subject: [PATCH 2/2] fix: correct notation for column name in constraint --- forward_engineering/helpers/columnHelper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forward_engineering/helpers/columnHelper.js b/forward_engineering/helpers/columnHelper.js index e964768..f05c784 100644 --- a/forward_engineering/helpers/columnHelper.js +++ b/forward_engineering/helpers/columnHelper.js @@ -394,7 +394,7 @@ const getColumnConstraintsStatement = ({ collection, column }) => { const getConstraint = ({ statement, postfix, noValidate, skipName = false }) => { const constraintName = getDefaultConstraintName({ collection, column, postfix }); - const columnName = skipName ? '' : ` ${column.name}`; + const columnName = skipName ? '' : ` (${column.name})`; return `CONSTRAINT ${constraintName} ${statement}${columnName} ${noValidate}`; };