diff --git a/forward_engineering/dbtProvider.js b/forward_engineering/dbtProvider.js index 4f5f6bdb..0d9ce99e 100644 --- a/forward_engineering/dbtProvider.js +++ b/forward_engineering/dbtProvider.js @@ -52,7 +52,9 @@ class DbtProvider { * @returns {boolean} */ hasType(type) { - return Object.keys(types).map(toLower).includes(toLower(type)); + return Object.keys(types) + .map(element => toLower(element)) + .includes(toLower(type)); } /** diff --git a/forward_engineering/ddlProvider.js b/forward_engineering/ddlProvider.js index 99a178ec..9d9eba05 100644 --- a/forward_engineering/ddlProvider.js +++ b/forward_engineering/ddlProvider.js @@ -1,47 +1,62 @@ +const _ = require('lodash'); const defaultTypes = require('./configs/defaultTypes'); const types = require('./configs/types'); const templates = require('./configs/templates'); const { commentIfDeactivated } = require('./helpers/commentIfDeactivated'); const { joinActivatedAndDeactivatedStatements } = require('./utils/joinActivatedAndDeactivatedStatements'); - -module.exports = (baseProvider, options, app) => { - const _ = app.require('lodash'); - const { assignTemplates } = app.require('@hackolade/ddl-fe-utils'); - const { checkAllKeysDeactivated, divideIntoActivatedAndDeactivated, getEntityName } = - app.require('@hackolade/ddl-fe-utils').general; - const { wrapInBrackets } = require('./utils/general')(_); - - const { decorateType, getIdentity, getEncryptedWith, getColumnsComments, canHaveIdentity } = - require('./helpers/columnDefinitionHelper')(app); - const { - createIndex, - hydrateIndex, - getMemoryOptimizedIndexes, - createMemoryOptimizedIndex, - hydrateTableIndex, - createTableIndex, - } = require('./helpers/indexHelper')(app); - const { - getTableName, - getTableOptions, - hasType, - foreignKeysToString, - checkIndexActivated, - getDefaultValue, - getTempTableTime, - foreignActiveKeysToString, - additionalPropertiesForForeignKey, - getFKConstraintName, - } = require('./helpers/general')(app); - const keyHelper = require('./helpers/keyHelper')(app); - const { getTerminator } = require('./helpers/optionsHelper'); - const { createPKConstraint, createUKConstraint, createDefaultConstraint, generateConstraintsString } = - require('./helpers/constraintsHelper')(app); - const { wrapIfNotExistSchema, wrapIfNotExistDatabase, wrapIfNotExistTable, wrapIfNotExistView } = - require('./helpers/ifNotExistStatementHelper')(app); - const { getPartitionedTables, getCreateViewData } = require('./helpers/viewHelper')(app); - const { getFullTableName, escapeSpecialCharacters, wrapInBracketsIfNecessary } = require('./utils/general')(_); - +const { assignTemplates } = require('./utils/assignTemplates'); +const { + wrapInBrackets, + escapeSpecialCharacters, + wrapInBracketsIfNecessary, + checkAllKeysDeactivated, + divideIntoActivatedAndDeactivated, + getEntityName, +} = require('./utils/general'); +const { + decorateType, + getIdentity, + getEncryptedWith, + getColumnsComments, + canHaveIdentity, +} = require('./helpers/columnDefinitionHelper'); +const { + createIndex, + hydrateIndex, + getMemoryOptimizedIndexes, + createMemoryOptimizedIndex, + hydrateTableIndex, + createTableIndex, +} = require('./helpers/indexHelper'); +const { + getTableName, + getTableOptions, + hasType, + foreignKeysToString, + checkIndexActivated, + getDefaultValue, + getTempTableTime, + foreignActiveKeysToString, + additionalPropertiesForForeignKey, + getFKConstraintName, +} = require('./helpers/general'); +const keyHelper = require('./helpers/keyHelper'); +const { getTerminator } = require('./helpers/optionsHelper'); +const { + createPKConstraint, + createUKConstraint, + createDefaultConstraint, + generateConstraintsString, +} = require('./helpers/constraintsHelper'); +const { + wrapIfNotExistSchema, + wrapIfNotExistDatabase, + wrapIfNotExistTable, + wrapIfNotExistView, +} = require('./helpers/ifNotExistStatementHelper'); +const { getPartitionedTables, getCreateViewData } = require('./helpers/viewHelper'); + +const ddlProvider = (baseProvider, options, app) => { const terminator = getTerminator(options); return { @@ -206,9 +221,9 @@ module.exports = (baseProvider, options, app) => { ? ` MASKED WITH (FUNCTION='${columnDefinition.maskedWithFunction}')` : ''; const identityContainer = columnDefinition.identity && { identity: getIdentity(columnDefinition.identity) }; - const encryptedWith = !_.isEmpty(columnDefinition.encryption) - ? getEncryptedWith(columnDefinition.encryption[0]) - : ''; + const encryptedWith = _.isEmpty(columnDefinition.encryption) + ? '' + : getEncryptedWith(columnDefinition.encryption[0]); const unique = columnDefinition.unique ? ' ' + createUKConstraint(templates, terminator, true)(columnDefinition.uniqueKeyOptions).statement : ''; @@ -250,7 +265,7 @@ module.exports = (baseProvider, options, app) => { createIndex(tableName, index, dbData, isParentActivated = true) { const isActivated = checkIndexActivated(index); if (!isParentActivated) { - return createTableIndex(terminator, tableName, index, isActivated && isParentActivated); + return createTableIndex(terminator, tableName, index, isActivated); } return createTableIndex(terminator, tableName, index, isActivated && isParentActivated); }, @@ -446,6 +461,15 @@ module.exports = (baseProvider, options, app) => { return hasType(type); }, + hydrateJsonSchemaColumn(jsonSchema, definitionJsonSchema) { + if (!jsonSchema.$ref || _.isEmpty(definitionJsonSchema)) { + return jsonSchema; + } + + jsonSchema = _.omit(jsonSchema, '$ref'); + return { ...definitionJsonSchema, ...jsonSchema }; + }, + hydrateColumn({ columnDefinition, jsonSchema, schemaData, parentJsonSchema }) { let encryption = []; @@ -476,7 +500,8 @@ module.exports = (baseProvider, options, app) => { const isTempTableEndTimeColumnHidden = _.get(parentJsonSchema, 'periodForSystemTime[0].startTime[0].type', '') === 'hidden'; - return Object.assign({}, columnDefinition, { + return { + ...columnDefinition, defaultConstraint: { name: jsonSchema.defaultConstraintName, value: columnDefinition.default, @@ -513,7 +538,7 @@ module.exports = (baseProvider, options, app) => { increment: Number(_.get(jsonSchema, 'identity.identityIncrement', 0)), }, }), - }); + }; }, hydrateIndex(indexData, tableData, schemaData) { @@ -557,7 +582,8 @@ module.exports = (baseProvider, options, app) => { idToNameHashTable[_.get(jsonSchema, 'periodForSystemTime[0].startTime[0].keyId', '')]; const temporalTableTimeEndColumnName = idToNameHashTable[_.get(jsonSchema, 'periodForSystemTime[0].endTime[0].keyId', '')]; - return Object.assign({}, tableData, { + return { + ...tableData, foreignKeyConstraints: tableData.foreignKeyConstraints || [], keyConstraints: keyHelper.getTableKeyConstraints({ jsonSchema }), ifNotExist: jsonSchema.ifNotExist, @@ -587,7 +613,7 @@ module.exports = (baseProvider, options, app) => { memoryOptimizedIndexes: isMemoryOptimized ? getMemoryOptimizedIndexes(entityData, tableData.schemaData) : [], - }); + }; }, hydrateViewColumn(data) { @@ -1071,3 +1097,5 @@ module.exports = (baseProvider, options, app) => { }, }; }; + +module.exports = ddlProvider; diff --git a/forward_engineering/helpers/alterScriptFromDeltaHelper.js b/forward_engineering/helpers/alterScriptFromDeltaHelper.js index a9604d68..bf259d87 100644 --- a/forward_engineering/helpers/alterScriptFromDeltaHelper.js +++ b/forward_engineering/helpers/alterScriptFromDeltaHelper.js @@ -1,507 +1,500 @@ -'use strict'; - -module.exports = _ => { - const { buildScript, commentDeactivatedStatements } = require('../utils/general')(_); - - /** - * @typedef {import('./alterScriptHelpers/types/AlterScriptDto').AlterScriptDto} AlterScriptDto - * */ - - /** - * @param scripts {Array} - * @return {Array} - * */ - const assertNoEmptyStatements = scripts => { - return scripts - .filter(Boolean) - .map(script => { - return script.trim(); - }) - .filter(Boolean); - }; - - const getComparisonModelCollection = collections => { - return collections - .map(collection => JSON.parse(collection)) - .find(collection => collection.collectionName === 'comparisonModelCollection'); - }; - - /** - * @return {{ [key: string]: Array}}} - * */ - const getAlterContainersScriptsDtos = (collection, app, options) => { - const { getAddContainerScriptDto, getDeleteContainerScriptDto } = - require('./alterScriptHelpers/alterContainerHelper')(app, options); - - const addedContainers = collection.properties?.containers?.properties?.added?.items; - const deletedContainers = collection.properties?.containers?.properties?.deleted?.items; - - const addContainersScriptsDtos = [] - .concat(addedContainers) - .filter(Boolean) - .map(container => ({ - ...Object.values(container.properties)[0], - name: Object.keys(container.properties)[0], - })) - .flatMap(getAddContainerScriptDto); - const deleteContainersScriptsDtos = [] - .concat(deletedContainers) - .filter(Boolean) - .flatMap(container => getDeleteContainerScriptDto(Object.keys(container.properties)[0])); - - return { addContainersScriptsDtos, deleteContainersScriptsDtos }; - }; +const { buildScript, commentDeactivatedStatements } = require('../utils/general'); + +/** + * @typedef {import('./alterScriptHelpers/types/AlterScriptDto').AlterScriptDto} AlterScriptDto + * */ + +/** + * @param scripts {Array} + * @return {Array} + * */ +const assertNoEmptyStatements = scripts => { + return scripts + .filter(Boolean) + .map(script => { + return script.trim(); + }) + .filter(Boolean); +}; - const sortCollectionsByRelationships = (collections, relationships) => { - const collectionToChildren = new Map(); // Map of collection IDs to their children - const collectionParentCount = new Map(); // Track how many parents each collection has +const getComparisonModelCollection = collections => { + return collections + .map(collection => JSON.parse(collection)) + .find(collection => collection.collectionName === 'comparisonModelCollection'); +}; - // Initialize maps - for (const collection of collections) { - collectionToChildren.set(collection.role.id, []); - collectionParentCount.set(collection.role.id, 0); - } +/** + * @return {{ [key: string]: Array}}} + * */ +const getAlterContainersScriptsDtos = (collection, app, options) => { + const { getAddContainerScriptDto, getDeleteContainerScriptDto } = + require('./alterScriptHelpers/alterContainerHelper')(app, options); + + const addedContainers = collection.properties?.containers?.properties?.added?.items; + const deletedContainers = collection.properties?.containers?.properties?.deleted?.items; + + const addContainersScriptsDtos = [addedContainers] + .flat() + .filter(Boolean) + .map(container => ({ + ...Object.values(container.properties)[0], + name: Object.keys(container.properties)[0], + })) + .flatMap(getAddContainerScriptDto); + const deleteContainersScriptsDtos = [deletedContainers] + .flat() + .filter(Boolean) + .flatMap(container => getDeleteContainerScriptDto(Object.keys(container.properties)[0])); + + return { addContainersScriptsDtos, deleteContainersScriptsDtos }; +}; - for (const relationship of relationships) { - const parent = relationship.role.parentCollection; - const child = relationship.role.childCollection; - if (collectionToChildren.has(parent)) { - collectionToChildren.get(parent).push(child); - } - collectionParentCount.set(child, (collectionParentCount.get(child) || 0) + 1); +const sortCollectionsByRelationships = (collections, relationships) => { + const collectionToChildren = new Map(); // Map of collection IDs to their children + const collectionParentCount = new Map(); // Track how many parents each collection has + + // Initialize maps + for (const collection of collections) { + collectionToChildren.set(collection.role.id, []); + collectionParentCount.set(collection.role.id, 0); + } + + for (const relationship of relationships) { + const parent = relationship.role.parentCollection; + const child = relationship.role.childCollection; + if (collectionToChildren.has(parent)) { + collectionToChildren.get(parent).push(child); } + collectionParentCount.set(child, (collectionParentCount.get(child) || 0) + 1); + } - // Find collections with no parents - const queue = collections - .filter(collection => collectionParentCount.get(collection.role.id) === 0) - .map(collection => collection.role.id); + // Find collections with no parents + const queue = collections + .filter(collection => collectionParentCount.get(collection.role.id) === 0) + .map(collection => collection.role.id); - const sortedIds = []; + const sortedIds = []; - // Sort collections - while (queue.length > 0) { - const current = queue.shift(); - sortedIds.push(current); + // Sort collections + while (queue.length > 0) { + const current = queue.shift(); + sortedIds.push(current); - for (const child of collectionToChildren.get(current) || []) { - collectionParentCount.set(child, collectionParentCount.get(child) - 1); - if (collectionParentCount.get(child) <= 0) { - queue.push(child); - } + for (const child of collectionToChildren.get(current) || []) { + collectionParentCount.set(child, collectionParentCount.get(child) - 1); + if (collectionParentCount.get(child) <= 0) { + queue.push(child); } } + } - // Add any unvisited collection - for (const collection of collections) { - if (!sortedIds.includes(collection.role.id)) { - sortedIds.unshift(collection.role.id); - } + // Add any unvisited collection + for (const collection of collections) { + if (!sortedIds.includes(collection.role.id)) { + sortedIds.unshift(collection.role.id); } + } - // Map back to collection objects in sorted order - const idToCollection = Object.fromEntries(collections.map(c => [c.role.id, c])); - return sortedIds.map(id => idToCollection[id]); - }; + // Map back to collection objects in sorted order + const idToCollection = Object.fromEntries(collections.map(c => [c.role.id, c])); + return sortedIds.map(id => idToCollection[id]); +}; - /** - * @return {{ [key: string]: Array}}} - * */ - const getAlterCollectionsScriptsDtos = (collection, app, options, inlineDeltaRelationships = []) => { - const { - getAddCollectionScriptDto, - getDeleteCollectionScriptDto, - getAddColumnScriptDto, - getDeleteColumnScriptDto, - getModifyColumnScriptDto, - getModifyCollectionScriptDto, - } = require('./alterScriptHelpers/alterEntityHelper')(app, options); - - const createScriptsData = [] - .concat(collection.properties?.entities?.properties?.added?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]); - - const deleteScriptsData = [] - .concat(collection.properties?.entities?.properties?.deleted?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]); - - const modifyScriptsData = [] - .concat(collection.properties?.entities?.properties?.modified?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]); - - const createCollectionsScriptsDtos = sortCollectionsByRelationships( - createScriptsData.filter(collection => collection.compMod?.created), - inlineDeltaRelationships, - ).flatMap(collection => getAddCollectionScriptDto(collection, inlineDeltaRelationships)); - const deleteCollectionScriptsDtos = deleteScriptsData - .filter(collection => collection.compMod?.deleted) - .flatMap(getDeleteCollectionScriptDto); - const modifyCollectionScriptsDtos = modifyScriptsData.flatMap(getModifyCollectionScriptDto); - const addColumnScriptsDtos = createScriptsData - .filter(collection => !collection.compMod?.created) - .flatMap(getAddColumnScriptDto); - const deleteColumnScriptsDtos = deleteScriptsData - .filter(collection => !collection.compMod?.deleted) - .flatMap(getDeleteColumnScriptDto); - const modifyColumnScriptDtos = modifyScriptsData.flatMap(getModifyColumnScriptDto); - - return { - createCollectionsScriptsDtos, - deleteCollectionScriptsDtos, - modifyCollectionScriptsDtos, - addColumnScriptsDtos, - deleteColumnScriptsDtos, - modifyColumnScriptDtos, - }; - }; +/** + * @return {{ [key: string]: Array}}} + * */ +const getAlterCollectionsScriptsDtos = (collection, app, options, inlineDeltaRelationships = []) => { + const { + getAddCollectionScriptDto, + getDeleteCollectionScriptDto, + getAddColumnScriptDto, + getDeleteColumnScriptDto, + getModifyColumnScriptDto, + getModifyCollectionScriptDto, + } = require('./alterScriptHelpers/alterEntityHelper')(app, options); + + const createScriptsData = [collection.properties?.entities?.properties?.added?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]); + + const deleteScriptsData = [collection.properties?.entities?.properties?.deleted?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]); + + const modifyScriptsData = [collection.properties?.entities?.properties?.modified?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]); + + const createCollectionsScriptsDtos = sortCollectionsByRelationships( + createScriptsData.filter(collection => collection.compMod?.created), + inlineDeltaRelationships, + ).flatMap(collection => getAddCollectionScriptDto(collection, inlineDeltaRelationships)); + const deleteCollectionScriptsDtos = deleteScriptsData + .filter(collection => collection.compMod?.deleted) + .flatMap(getDeleteCollectionScriptDto); + const modifyCollectionScriptsDtos = modifyScriptsData.flatMap(getModifyCollectionScriptDto); + const addColumnScriptsDtos = createScriptsData + .filter(collection => !collection.compMod?.created) + .flatMap(getAddColumnScriptDto); + const deleteColumnScriptsDtos = deleteScriptsData + .filter(collection => !collection.compMod?.deleted) + .flatMap(getDeleteColumnScriptDto); + const modifyColumnScriptDtos = modifyScriptsData.flatMap(getModifyColumnScriptDto); - /** - * @return {{ [key: string]: Array}}} - * */ - const getAlterViewScriptsDtos = (collection, app, options) => { - const { getAddViewScriptDto, getDeleteViewScriptDto, getModifiedViewScriptDto } = - require('./alterScriptHelpers/alterViewHelper')(app, options); - - const checkIfOnlyDescriptionChanged = view => { - const changedProps = Object.entries(view.role?.compMod).filter(([_, value]) => value.new !== value.old); - - // If the only change is the description, we ignore it - // descriptions are handled in separate methods - return !(changedProps.length === 1 && changedProps[0][0] === 'description'); - }; - - const createViewsScriptsDtos = [] - .concat(collection.properties?.views?.properties?.added?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .map(view => ({ ...view, ...(view.role || {}) })) - .filter(view => view.compMod?.created) - .flatMap(getAddViewScriptDto); - - const deleteViewsScriptsDtos = [] - .concat(collection.properties?.views?.properties?.deleted?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .map(view => ({ ...view, ...(view.role || {}) })) - .filter(view => view.compMod?.deleted) - .flatMap(getDeleteViewScriptDto); - - const modifiedViewsScriptsDtos = [] - .concat(collection.properties?.views?.properties?.modified?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .map(view => ({ ...view, ...(view.role || {}) })) - .filter(view => !view.compMod?.created && !view.compMod?.deleted) - .filter(checkIfOnlyDescriptionChanged) - .flatMap(getModifiedViewScriptDto); - - return { deleteViewsScriptsDtos, createViewsScriptsDtos, modifiedViewsScriptsDtos }; + return { + createCollectionsScriptsDtos, + deleteCollectionScriptsDtos, + modifyCollectionScriptsDtos, + addColumnScriptsDtos, + deleteColumnScriptsDtos, + modifyColumnScriptDtos, }; +}; - /** - * @return {{ [key: string]: Array}}} - * */ - const getAlterModelDefinitionsScriptsDtos = (collection, app, options) => { - const { getCreateUdtScriptDto, getDeleteUdtScriptDto } = require('./alterScriptHelpers/alterUdtHelper')( - app, - options, - ); +/** + * @return {{ [key: string]: Array}}} + * */ +const getAlterViewScriptsDtos = (collection, app, options) => { + const { getAddViewScriptDto, getDeleteViewScriptDto, getModifiedViewScriptDto } = + require('./alterScriptHelpers/alterViewHelper')(app, options); + + const checkIfOnlyDescriptionChanged = view => { + const changedProps = Object.entries(view.role?.compMod).filter(([_, value]) => value.new !== value.old); - const createUdtScriptsDtos = [] - .concat(collection.properties?.modelDefinitions?.properties?.added?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .map(item => ({ ...item, ...(app.require('lodash').omit(item.role, 'properties') || {}) })) - .filter(item => item.compMod?.created) - .flatMap(getCreateUdtScriptDto); - const deleteUdtScriptsDtos = [] - .concat(collection.properties?.modelDefinitions?.properties?.deleted?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .map(item => ({ ...item, ...(app.require('lodash').omit(item.role, 'properties') || {}) })) - .filter(collection => collection.compMod?.deleted) - .flatMap(getDeleteUdtScriptDto); - - return { deleteUdtScriptsDtos, createUdtScriptsDtos }; + // If the only change is the description, we ignore it + // descriptions are handled in separate methods + return !(changedProps.length === 1 && changedProps[0][0] === 'description'); }; - const getAlterRelationshipsScriptDtos = (collection, app, ignoreRelationshipIDs = []) => { - const _ = app.require('lodash'); - const ddlProvider = require('../ddlProvider')(null, null, app); - const { - getModifyForeignKeyScriptDtos, - getAddForeignKeyScriptDtos, - getDeleteForeignKeyScriptDtos, - } = require('./alterScriptHelpers/alterRelationshipsHelper'); - - const addedRelationships = [] - .concat(collection.properties?.relationships?.properties?.added?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .filter( - relationship => - relationship?.role?.compMod?.created && !ignoreRelationshipIDs.includes(relationship?.role?.id), - ); - const deletedRelationships = [] - .concat(collection.properties?.relationships?.properties?.deleted?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .filter( - relationship => - relationship?.role?.compMod?.deleted && !ignoreRelationshipIDs.includes(relationship?.role?.id), - ); - const modifiedRelationships = [] - .concat(collection.properties?.relationships?.properties?.modified?.items) - .filter(Boolean) - .map(item => Object.values(item.properties)[0]) - .filter( - relationship => - relationship?.role?.compMod?.modified && !ignoreRelationshipIDs.includes(relationship?.role?.id), - ); + const createViewsScriptsDtos = [collection.properties?.views?.properties?.added?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .map(view => ({ ...view, ...view.role })) + .filter(view => view.compMod?.created) + .flatMap(getAddViewScriptDto); + + const deleteViewsScriptsDtos = [collection.properties?.views?.properties?.deleted?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .map(view => ({ ...view, ...view.role })) + .filter(view => view.compMod?.deleted) + .flatMap(getDeleteViewScriptDto); + + const modifiedViewsScriptsDtos = [collection.properties?.views?.properties?.modified?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .map(view => ({ ...view, ...view.role })) + .filter(view => !view.compMod?.created && !view.compMod?.deleted) + .filter(checkIfOnlyDescriptionChanged) + .flatMap(getModifiedViewScriptDto); + + return { deleteViewsScriptsDtos, createViewsScriptsDtos, modifiedViewsScriptsDtos }; +}; - const deleteFkScriptDtos = getDeleteForeignKeyScriptDtos(ddlProvider, _)(deletedRelationships); - const addFkScriptDtos = getAddForeignKeyScriptDtos(ddlProvider, _)(addedRelationships); - const modifiedFkScriptDtos = getModifyForeignKeyScriptDtos(ddlProvider, _)(modifiedRelationships); +/** + * @return {{ [key: string]: Array}}} + * */ +const getAlterModelDefinitionsScriptsDtos = (collection, app, options) => { + const { getCreateUdtScriptDto, getDeleteUdtScriptDto } = require('./alterScriptHelpers/alterUdtHelper')( + app, + options, + ); + + const createUdtScriptsDtos = [collection.properties?.modelDefinitions?.properties?.added?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .map(item => ({ ...item, ...app.require('lodash').omit(item.role, 'properties') })) + .filter(item => item.compMod?.created) + .flatMap(getCreateUdtScriptDto); + const deleteUdtScriptsDtos = [collection.properties?.modelDefinitions?.properties?.deleted?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .map(item => ({ ...item, ...app.require('lodash').omit(item.role, 'properties') })) + .filter(collection => collection.compMod?.deleted) + .flatMap(getDeleteUdtScriptDto); + + return { deleteUdtScriptsDtos, createUdtScriptsDtos }; +}; - return { - deleteFkScriptDtos, - addFkScriptDtos, - modifiedFkScriptDtos, - }; +const getAlterRelationshipsScriptDtos = (collection, app, ignoreRelationshipIDs = []) => { + const ddlProvider = require('../ddlProvider')(null, null, app); + const { + getModifyForeignKeyScriptDtos, + getAddForeignKeyScriptDtos, + getDeleteForeignKeyScriptDtos, + } = require('./alterScriptHelpers/alterRelationshipsHelper'); + + const addedRelationships = [collection.properties?.relationships?.properties?.added?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .filter( + relationship => + relationship?.role?.compMod?.created && !ignoreRelationshipIDs.includes(relationship?.role?.id), + ); + const deletedRelationships = [collection.properties?.relationships?.properties?.deleted?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .filter( + relationship => + relationship?.role?.compMod?.deleted && !ignoreRelationshipIDs.includes(relationship?.role?.id), + ); + const modifiedRelationships = [collection.properties?.relationships?.properties?.modified?.items] + .flat() + .filter(Boolean) + .map(item => Object.values(item.properties)[0]) + .filter( + relationship => + relationship?.role?.compMod?.modified && !ignoreRelationshipIDs.includes(relationship?.role?.id), + ); + + const deleteFkScriptDtos = getDeleteForeignKeyScriptDtos(ddlProvider)(deletedRelationships); + const addFkScriptDtos = getAddForeignKeyScriptDtos(ddlProvider)(addedRelationships); + const modifiedFkScriptDtos = getModifyForeignKeyScriptDtos(ddlProvider)(modifiedRelationships); + + return { + deleteFkScriptDtos, + addFkScriptDtos, + modifiedFkScriptDtos, }; +}; - const getContainersCommentsAlterScriptsDtos = (collection, app, options) => { - const { getSchemasDropCommentsAlterScriptsDto, getSchemasModifyCommentsAlterScriptsDto } = - require('./alterScriptHelpers/alterContainerHelper')(app, options); - const modifiedSchemas = collection.properties?.containers?.properties?.modified?.items; - const deletedSchemas = collection.properties?.containers?.properties?.deleted?.items; +const getContainersCommentsAlterScriptsDtos = (collection, app, options) => { + const { getSchemasDropCommentsAlterScriptsDto, getSchemasModifyCommentsAlterScriptsDto } = + require('./alterScriptHelpers/alterContainerHelper')(app, options); - //There is no need for separate added schemas comments creation because it is already done in generation of ddl (just like in FE) and this method is called - let addSchemasModifyCommentsScriptsDtos = []; - let addSchemasDropCommentsScriptsDtos = []; + const modifiedSchemas = collection.properties?.containers?.properties?.modified?.items; + const deletedSchemas = collection.properties?.containers?.properties?.deleted?.items; - if (modifiedSchemas) { - addSchemasModifyCommentsScriptsDtos = Array.isArray(modifiedSchemas) - ? modifiedSchemas.map(schema => getSchemasModifyCommentsAlterScriptsDto(schema?.properties)).flat() - : getSchemasModifyCommentsAlterScriptsDto(modifiedSchemas?.properties); - } + //There is no need for separate added schemas comments creation because it is already done in generation of ddl (just like in FE) and this method is called + let addSchemasModifyCommentsScriptsDtos = []; + let addSchemasDropCommentsScriptsDtos = []; - if (deletedSchemas) { - addSchemasDropCommentsScriptsDtos = Array.isArray(deletedSchemas) - ? deletedSchemas.map(schema => getSchemasDropCommentsAlterScriptsDto(schema?.properties)).flat() - : getSchemasDropCommentsAlterScriptsDto(deletedSchemas?.properties); - } + if (modifiedSchemas) { + addSchemasModifyCommentsScriptsDtos = Array.isArray(modifiedSchemas) + ? modifiedSchemas.flatMap(schema => getSchemasModifyCommentsAlterScriptsDto(schema?.properties)) + : getSchemasModifyCommentsAlterScriptsDto(modifiedSchemas?.properties); + } - return { - addSchemasModifyCommentsScriptsDtos, - addSchemasDropCommentsScriptsDtos, - }; - }; + if (deletedSchemas) { + addSchemasDropCommentsScriptsDtos = Array.isArray(deletedSchemas) + ? deletedSchemas.flatMap(schema => getSchemasDropCommentsAlterScriptsDto(schema?.properties)) + : getSchemasDropCommentsAlterScriptsDto(deletedSchemas?.properties); + } - const getCollectionsCommentsAlterScriptsDtos = (collection, app, options) => { - const { - getTablesDropCommentAlterScriptsDto, - getTablesModifyCommentsAlterScriptsDto, - getColumnsCreateCommentAlterScriptsDto, - getColumnsDropCommentAlterScriptsDto, - getColumnsModifyCommentAlterScriptsDto, - } = require('./alterScriptHelpers/alterEntityHelper')(app, options); - const modifiedTables = collection.properties?.entities?.properties?.modified?.items; - const deletedTables = collection.properties?.entities?.properties?.deleted?.items; - - //Added tables comments creation is already done in generation of ddl - let addTablesModifyCommentsScriptsDtos = []; - let addTablesDropCommentsScriptsDtos = []; - - // Columns create scripts added for case with modification of tables with new fields with comments - let addColumnCreateCommentsScripsDtos = []; - let addColumnModifyCommentsScriptsDtos = []; - let addColumnDropCommentsScriptsDtos = []; - - if (modifiedTables) { - addColumnCreateCommentsScripsDtos = Array.isArray(modifiedTables) - ? modifiedTables.map(schema => getColumnsCreateCommentAlterScriptsDto(schema?.properties)).flat() - : getColumnsCreateCommentAlterScriptsDto(modifiedTables?.properties); - addTablesModifyCommentsScriptsDtos = Array.isArray(modifiedTables) - ? modifiedTables.map(schema => getTablesModifyCommentsAlterScriptsDto(schema?.properties)).flat() - : getTablesModifyCommentsAlterScriptsDto(modifiedTables?.properties); - addColumnModifyCommentsScriptsDtos = Array.isArray(modifiedTables) - ? modifiedTables.map(schema => getColumnsModifyCommentAlterScriptsDto(schema?.properties)).flat() - : getColumnsModifyCommentAlterScriptsDto(modifiedTables?.properties); - } + return { + addSchemasModifyCommentsScriptsDtos, + addSchemasDropCommentsScriptsDtos, + }; +}; - if (deletedTables) { - addTablesDropCommentsScriptsDtos = Array.isArray(deletedTables) - ? deletedTables.map(schema => getTablesDropCommentAlterScriptsDto(schema?.properties)).flat() - : getTablesDropCommentAlterScriptsDto(deletedTables?.properties); - addColumnDropCommentsScriptsDtos = Array.isArray(deletedTables) - ? deletedTables.map(schema => getColumnsDropCommentAlterScriptsDto(schema?.properties)).flat() - : getColumnsDropCommentAlterScriptsDto(deletedTables?.properties); - } +const getCollectionsCommentsAlterScriptsDtos = (collection, app, options) => { + const { + getTablesDropCommentAlterScriptsDto, + getTablesModifyCommentsAlterScriptsDto, + getColumnsCreateCommentAlterScriptsDto, + getColumnsDropCommentAlterScriptsDto, + getColumnsModifyCommentAlterScriptsDto, + } = require('./alterScriptHelpers/alterEntityHelper')(app, options); + const modifiedTables = collection.properties?.entities?.properties?.modified?.items; + const deletedTables = collection.properties?.entities?.properties?.deleted?.items; + + //Added tables comments creation is already done in generation of ddl + let addTablesModifyCommentsScriptsDtos = []; + let addTablesDropCommentsScriptsDtos = []; + + // Columns create scripts added for case with modification of tables with new fields with comments + let addColumnCreateCommentsScripsDtos = []; + let addColumnModifyCommentsScriptsDtos = []; + let addColumnDropCommentsScriptsDtos = []; + + if (modifiedTables) { + addColumnCreateCommentsScripsDtos = Array.isArray(modifiedTables) + ? modifiedTables.flatMap(schema => getColumnsCreateCommentAlterScriptsDto(schema?.properties)) + : getColumnsCreateCommentAlterScriptsDto(modifiedTables?.properties); + addTablesModifyCommentsScriptsDtos = Array.isArray(modifiedTables) + ? modifiedTables.flatMap(schema => getTablesModifyCommentsAlterScriptsDto(schema?.properties)) + : getTablesModifyCommentsAlterScriptsDto(modifiedTables?.properties); + addColumnModifyCommentsScriptsDtos = Array.isArray(modifiedTables) + ? modifiedTables.flatMap(schema => getColumnsModifyCommentAlterScriptsDto(schema?.properties)) + : getColumnsModifyCommentAlterScriptsDto(modifiedTables?.properties); + } + + if (deletedTables) { + addTablesDropCommentsScriptsDtos = Array.isArray(deletedTables) + ? deletedTables.flatMap(schema => getTablesDropCommentAlterScriptsDto(schema?.properties)) + : getTablesDropCommentAlterScriptsDto(deletedTables?.properties); + addColumnDropCommentsScriptsDtos = Array.isArray(deletedTables) + ? deletedTables.flatMap(schema => getColumnsDropCommentAlterScriptsDto(schema?.properties)) + : getColumnsDropCommentAlterScriptsDto(deletedTables?.properties); + } - return { - addTablesModifyCommentsScriptsDtos, - addTablesDropCommentsScriptsDtos, - addColumnCreateCommentsScripsDtos, - addColumnModifyCommentsScriptsDtos, - addColumnDropCommentsScriptsDtos, - }; + return { + addTablesModifyCommentsScriptsDtos, + addTablesDropCommentsScriptsDtos, + addColumnCreateCommentsScripsDtos, + addColumnModifyCommentsScriptsDtos, + addColumnDropCommentsScriptsDtos, }; +}; - const getViewsCommentsAlterScriptsDtos = (collection, app, options) => { - const { getViewsDropCommentAlterScriptsDto, getViewsModifyCommentsAlterScriptsDto } = - require('./alterScriptHelpers/alterViewHelper')(app, options); +const getViewsCommentsAlterScriptsDtos = (collection, app, options) => { + const { getViewsDropCommentAlterScriptsDto, getViewsModifyCommentsAlterScriptsDto } = + require('./alterScriptHelpers/alterViewHelper')(app, options); - //Added views comments creation is already done in generation of ddl - const modifiedViews = collection.properties?.views?.properties?.modified?.items; - const deletedViews = collection.properties?.views?.properties?.deleted?.items; + //Added views comments creation is already done in generation of ddl + const modifiedViews = collection.properties?.views?.properties?.modified?.items; + const deletedViews = collection.properties?.views?.properties?.deleted?.items; - let addViewsModifyCommentsScriptsDtos = []; - let addViewsDropCommentsScriptsDtos = []; + let addViewsModifyCommentsScriptsDtos = []; + let addViewsDropCommentsScriptsDtos = []; - if (modifiedViews) { - addViewsModifyCommentsScriptsDtos = Array.isArray(modifiedViews) - ? modifiedViews.map(schema => getViewsModifyCommentsAlterScriptsDto(schema?.properties)).flat() - : getViewsModifyCommentsAlterScriptsDto(modifiedViews?.properties); - } + if (modifiedViews) { + addViewsModifyCommentsScriptsDtos = Array.isArray(modifiedViews) + ? modifiedViews.flatMap(schema => getViewsModifyCommentsAlterScriptsDto(schema?.properties)) + : getViewsModifyCommentsAlterScriptsDto(modifiedViews?.properties); + } - if (deletedViews) { - addViewsDropCommentsScriptsDtos = Array.isArray(deletedViews) - ? deletedViews.map(schema => getViewsDropCommentAlterScriptsDto(schema?.properties)).flat() - : getViewsDropCommentAlterScriptsDto(deletedViews?.properties); - } + if (deletedViews) { + addViewsDropCommentsScriptsDtos = Array.isArray(deletedViews) + ? deletedViews.flatMap(schema => getViewsDropCommentAlterScriptsDto(schema?.properties)) + : getViewsDropCommentAlterScriptsDto(deletedViews?.properties); + } - return { - addViewsModifyCommentsScriptsDtos, - addViewsDropCommentsScriptsDtos, - }; + return { + addViewsModifyCommentsScriptsDtos, + addViewsDropCommentsScriptsDtos, }; +}; - /** - * @param scriptDtos {Array}, - * @param data {{ - * options: { - * id: string, - * value: any, - * }, - * }} - * @return {Array} - * */ - const getAlterStatementsWithCommentedUnwantedDDL = (scriptDtos, data) => { - const { additionalOptions = [] } = data.options || {}; - const applyDropStatements = (additionalOptions.find(option => option.id === 'applyDropStatements') || {}).value; - - const scripts = scriptDtos.flatMap(dto => { - if (dto.isActivated === false) { - return dto.scripts.map(scriptDto => commentDeactivatedStatements(scriptDto.script, false)); - } +/** + * @param scriptDtos {Array}, + * @param data {{ + * options: { + * id: string, + * value: any, + * }, + * }} + * @return {Array} + * */ +const getAlterStatementsWithCommentedUnwantedDDL = (scriptDtos, data) => { + const { additionalOptions = [] } = data.options || {}; + const applyDropStatements = additionalOptions.find(option => option.id === 'applyDropStatements')?.value; + + const scripts = scriptDtos.flatMap(dto => { + if (dto.isActivated === false) { + return dto.scripts.map(scriptDto => commentDeactivatedStatements(scriptDto.script, false)); + } - if (!applyDropStatements) { - return dto.scripts.map(scriptDto => - commentDeactivatedStatements(scriptDto.script, !scriptDto.isDropScript), - ); - } + if (!applyDropStatements) { + return dto.scripts.map(scriptDto => + commentDeactivatedStatements(scriptDto.script, !scriptDto.isDropScript), + ); + } - return dto.scripts.map(scriptDto => scriptDto.script); - }); + return dto.scripts.map(scriptDto => scriptDto.script); + }); - return assertNoEmptyStatements(scripts); - }; + return assertNoEmptyStatements(scripts); +}; - const getInlineRelationships = ({ collection, options }) => { - if (options?.scriptGenerationOptions?.feActiveOptions?.foreignKeys !== 'inline') { - return []; - } +const getInlineRelationships = ({ collection, options }) => { + if (options?.scriptGenerationOptions?.feActiveOptions?.foreignKeys !== 'inline') { + return []; + } - const addedCollectionIDs = [] - .concat(collection.properties?.entities?.properties?.added?.items) + const addedCollectionIDs = new Set( + [collection.properties?.entities?.properties?.added?.items] + .flat() .filter(item => item && Object.values(item.properties)?.[0]?.compMod?.created) - .map(item => Object.values(item.properties)[0].role.id); + .map(item => Object.values(item.properties)[0].role.id), + ); - const addedRelationships = [] - .concat(collection.properties?.relationships?.properties?.added?.items) - .map(item => item && Object.values(item.properties)[0]) - .filter(r => r?.role?.compMod?.created && addedCollectionIDs.includes(r?.role?.childCollection)); - - return addedRelationships; - }; + return [collection.properties?.relationships?.properties?.added?.items] + .flat() + .map(item => item && Object.values(item.properties)[0]) + .filter(r => r?.role?.compMod?.created && addedCollectionIDs.has(r?.role?.childCollection)); +}; - /** - * @return Array - * */ - const getAlterScriptDtos = (collection, app, options) => { - const inlineDeltaRelationships = getInlineRelationships({ collection, options }); - const ignoreRelationshipIDs = inlineDeltaRelationships.map(relationship => relationship.role.id); - const script = { - ...getAlterCollectionsScriptsDtos(collection, app, options, inlineDeltaRelationships), - ...getAlterContainersScriptsDtos(collection, app, options), - ...getAlterViewScriptsDtos(collection, app, options), - ...getAlterModelDefinitionsScriptsDtos(collection, app, options), - ...getContainersCommentsAlterScriptsDtos(collection, app, options), - ...getCollectionsCommentsAlterScriptsDtos(collection, app, options), - ...getViewsCommentsAlterScriptsDtos(collection, app, options), - ...getAlterRelationshipsScriptDtos(collection, app, ignoreRelationshipIDs), - }; - - return [ - 'addContainersScriptsDtos', - 'addViewsDropCommentsScriptsDtos', - 'deleteViewsScriptsDtos', - 'addColumnDropCommentsScriptsDtos', - 'addTablesDropCommentsScriptsDtos', - 'deleteColumnScriptsDtos', - 'deleteCollectionScriptsDtos', - 'deleteUdtScriptsDtos', - 'createUdtScriptsDtos', - 'createCollectionsScriptsDtos', - 'addColumnScriptsDtos', - 'modifyCollectionScriptsDtos', - 'modifyColumnScriptDtos', - 'createViewsScriptsDtos', - 'modifiedViewsScriptsDtos', - 'addSchemasDropCommentsScriptsDtos', - 'deleteContainersScriptsDtos', - 'addColumnCreateCommentsScripsDtos', - 'addColumnModifyCommentsScriptsDtos', - 'addSchemasModifyCommentsScriptsDtos', - 'addTablesModifyCommentsScriptsDtos', - 'addViewsModifyCommentsScriptsDtos', - 'deleteFkScriptDtos', - 'addFkScriptDtos', - 'modifiedFkScriptDtos', - ] - .flatMap(name => script[name]) - .filter(Boolean); +/** + * @return Array + * */ +const getAlterScriptDtos = (collection, app, options) => { + const inlineDeltaRelationships = getInlineRelationships({ collection, options }); + const ignoreRelationshipIDs = inlineDeltaRelationships.map(relationship => relationship.role.id); + const script = { + ...getAlterCollectionsScriptsDtos(collection, app, options, inlineDeltaRelationships), + ...getAlterContainersScriptsDtos(collection, app, options), + ...getAlterViewScriptsDtos(collection, app, options), + ...getAlterModelDefinitionsScriptsDtos(collection, app, options), + ...getContainersCommentsAlterScriptsDtos(collection, app, options), + ...getCollectionsCommentsAlterScriptsDtos(collection, app, options), + ...getViewsCommentsAlterScriptsDtos(collection, app, options), + ...getAlterRelationshipsScriptDtos(collection, app, ignoreRelationshipIDs), }; - /** - * @param alterScriptDtos {Array} - * @param data {{ - * options: { - * id: string, - * value: any, - * }, - * }} - * @return {string} - * */ - const joinAlterScriptDtosIntoAlterScript = (alterScriptDtos, data) => { - const scriptAsStringsWithCommentedUnwantedDDL = getAlterStatementsWithCommentedUnwantedDDL( - alterScriptDtos, - data, - ); + return [ + 'addContainersScriptsDtos', + 'addViewsDropCommentsScriptsDtos', + 'deleteViewsScriptsDtos', + 'addColumnDropCommentsScriptsDtos', + 'addTablesDropCommentsScriptsDtos', + 'deleteColumnScriptsDtos', + 'deleteCollectionScriptsDtos', + 'deleteUdtScriptsDtos', + 'createUdtScriptsDtos', + 'createCollectionsScriptsDtos', + 'addColumnScriptsDtos', + 'modifyCollectionScriptsDtos', + 'modifyColumnScriptDtos', + 'createViewsScriptsDtos', + 'modifiedViewsScriptsDtos', + 'addSchemasDropCommentsScriptsDtos', + 'deleteContainersScriptsDtos', + 'addColumnCreateCommentsScripsDtos', + 'addColumnModifyCommentsScriptsDtos', + 'addSchemasModifyCommentsScriptsDtos', + 'addTablesModifyCommentsScriptsDtos', + 'addViewsModifyCommentsScriptsDtos', + 'deleteFkScriptDtos', + 'addFkScriptDtos', + 'modifiedFkScriptDtos', + ] + .flatMap(name => script[name]) + .filter(Boolean); +}; - return buildScript(scriptAsStringsWithCommentedUnwantedDDL); - }; +/** + * @param alterScriptDtos {Array} + * @param data {{ + * options: { + * id: string, + * value: any, + * }, + * }} + * @return {string} + * */ +const joinAlterScriptDtosIntoAlterScript = (alterScriptDtos, data) => { + const scriptAsStringsWithCommentedUnwantedDDL = getAlterStatementsWithCommentedUnwantedDDL(alterScriptDtos, data); + + return buildScript(scriptAsStringsWithCommentedUnwantedDDL); +}; - return { - getAlterScriptDtos, - getComparisonModelCollection, - getAlterContainersScriptsDtos, - getAlterCollectionsScriptsDtos, - getAlterViewScriptsDtos, - getAlterModelDefinitionsScriptsDtos, - joinAlterScriptDtosIntoAlterScript, - }; +module.exports = { + getAlterScriptDtos, + getComparisonModelCollection, + getAlterContainersScriptsDtos, + getAlterCollectionsScriptsDtos, + getAlterViewScriptsDtos, + getAlterModelDefinitionsScriptsDtos, + joinAlterScriptDtosIntoAlterScript, }; diff --git a/forward_engineering/helpers/alterScriptHelpers/alterContainerHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterContainerHelper.js index 293eb70e..c51938e2 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterContainerHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterContainerHelper.js @@ -1,8 +1,9 @@ -module.exports = (app, options) => { - const _ = app.require('lodash'); +const _ = require('lodash'); +const { AlterScriptDto } = require('./types/AlterScriptDto'); +const { getDbData } = require('../../utils/general'); + +const alterContainerHelper = (app, options) => { const ddlProvider = require('../../ddlProvider')(null, options, app); - const { getDbData } = app.require('@hackolade/ddl-fe-utils').general; - const { AlterScriptDto } = require('./types/AlterScriptDto'); const getAddContainerScriptDto = containerData => { const constructedDbData = getDbData([containerData]); @@ -55,13 +56,13 @@ module.exports = (app, options) => { return undefined; } - if (!oldComment) { + if (oldComment) { + script = getUpdateSchemaCommentScript({ schemaName, comment: newComment }); + } else { script = ddlProvider.createSchemaComment({ schemaName, comment: newComment, }); - } else { - script = getUpdateSchemaCommentScript({ schemaName, comment: newComment }); } return AlterScriptDto.getInstance([script], true, false); @@ -75,3 +76,5 @@ module.exports = (app, options) => { getSchemasModifyCommentsAlterScriptsDto, }; }; + +module.exports = alterContainerHelper; diff --git a/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js index dee40dae..da899931 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js @@ -1,36 +1,35 @@ -'use strict'; - -module.exports = (app, options) => { - const _ = app.require('lodash'); - const { createColumnDefinitionBySchema } = require('./columnHelpers/createColumnDefinition')(_); - const { getTableName } = require('../general')(app); - const { getFullTableName, getEntityName } = require('../../utils/general')(app.require('lodash')); +const _ = require('lodash'); +const { AlterScriptDto } = require('./types/AlterScriptDto'); +const { getRelationshipName } = require('./alterRelationshipsHelper'); +const { getEntityName, getFullTableName } = require('../../utils/general'); +const { createColumnDefinitionBySchema } = require('./columnHelpers/createColumnDefinition'); +const { modifyGroupItems, setIndexKeys } = require('./common'); +const { getTableName } = require('../general'); + +const alterEntityHelper = (app, options) => { const ddlProvider = require('../../ddlProvider')(null, options, app); + const { generateIdToNameHashTable, generateIdToActivatedHashTable } = app.require('@hackolade/ddl-fe-utils'); - const { setIndexKeys, modifyGroupItems } = require('./common')(app); - const { getRenameColumnScriptsDto } = require('./columnHelpers/renameColumnHelpers')(app, ddlProvider); - const { getDefaultValueChangeDto } = require('./columnHelpers/defaultValueColumnHelper')(app, ddlProvider); - const { getChangedComputedColumnsScriptsDto } = require('./columnHelpers/alterComputedColumnHelpr')( - app, - ddlProvider, - ); - const { getChangeTypeScriptsDto } = require('./columnHelpers/alterTypeHelper')(app, ddlProvider); - const { AlterScriptDto } = require('./types/AlterScriptDto'); + + const { getRenameColumnScriptsDto } = require('./columnHelpers/renameColumnHelpers')(ddlProvider); + const { getDefaultValueChangeDto } = require('./columnHelpers/defaultValueColumnHelper')(ddlProvider); + const { getChangedComputedColumnsScriptsDto } = require('./columnHelpers/alterComputedColumnHelper')(ddlProvider); + const { getChangeTypeScriptsDto } = require('./columnHelpers/alterTypeHelper')(ddlProvider); const { getModifyCheckConstraintScriptDtos } = require('./entityHelpers/checkConstraintHelper'); const { getModifyPkConstraintsScriptDtos } = require('./entityHelpers/primaryKeyHelper'); const { getModifyNonNullColumnsScriptDtos } = require('./columnHelpers/notNullConstraintsHelper'); const { getModifyUniqueConstraintsScriptDtos } = require('./entityHelpers/uniqueConstraintHelper'); - const { getRelationshipName } = require('./alterRelationshipsHelper'); /** * @param {Collection} collection + * @param inlineDeltaRelationships * @return Array * */ const getAddCollectionScriptDto = (collection, inlineDeltaRelationships) => { //done but need clean up const schemaName = collection.compMod.keyspaceName; const schemaData = { schemaName }; - const jsonSchema = { ...collection, ...(collection?.role || {}) }; + const jsonSchema = { ...collection, ...collection?.role }; const tableName = getEntityName(jsonSchema); const idToNameHashTable = generateIdToNameHashTable(jsonSchema); const idToActivatedHashTable = generateIdToActivatedHashTable(jsonSchema); @@ -115,14 +114,14 @@ module.exports = (app, options) => { * @return {Array} * */ const getModifyCollectionScriptDto = collection => { - const jsonSchema = { ...collection, ...(collection?.role || {}) }; + const jsonSchema = { ...collection, ...collection?.role }; const schemaName = collection.compMod?.keyspaceName; const schemaData = { schemaName }; const idToNameHashTable = generateIdToNameHashTable(jsonSchema); const idToActivatedHashTable = generateIdToActivatedHashTable(jsonSchema); - const modifyCheckConstraintScriptDtos = getModifyCheckConstraintScriptDtos(_, ddlProvider)(collection); - const modifyUniqueConstraintsScriptDtos = getModifyUniqueConstraintsScriptDtos(app, _, ddlProvider)(collection); - const modifyPKConstraintDtos = getModifyPkConstraintsScriptDtos(app, _, ddlProvider)(collection); + const modifyCheckConstraintScriptDtos = getModifyCheckConstraintScriptDtos(ddlProvider)(collection); + const modifyUniqueConstraintsScriptDtos = getModifyUniqueConstraintsScriptDtos(ddlProvider)(collection); + const modifyPKConstraintDtos = getModifyPkConstraintsScriptDtos(ddlProvider)(collection); const indexesScriptsDtos = modifyGroupItems({ data: jsonSchema, key: 'Indxs', @@ -157,7 +156,7 @@ module.exports = (app, options) => { * @return {Array | undefined} * */ const getAddColumnScriptDto = collection => { - const collectionSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; + const collectionSchema = { ...collection, ..._.omit(collection?.role, 'properties') }; const tableName = collectionSchema?.code || collectionSchema?.collectionName || collectionSchema?.name; const schemaName = collectionSchema.compMod?.keyspaceName; const fullName = getTableName(tableName, schemaName); @@ -186,7 +185,7 @@ module.exports = (app, options) => { * @return {Array | undefined} * */ const getDeleteColumnScriptDto = collection => { - const collectionSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; + const collectionSchema = { ...collection, ..._.omit(collection?.role, 'properties') }; const tableName = collectionSchema?.code || collectionSchema?.collectionName || collectionSchema?.name; const schemaName = collectionSchema.compMod?.keyspaceName; const fullName = getTableName(tableName, schemaName); @@ -206,7 +205,7 @@ module.exports = (app, options) => { * @return {Array | undefined} * */ const getModifyColumnScriptDto = collection => { - const collectionSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; + const collectionSchema = { ...collection, ..._.omit(collection?.role, 'properties') }; const tableName = collectionSchema?.code || collectionSchema?.collectionName || collectionSchema?.name; const schemaName = collectionSchema.compMod?.keyspaceName; const fullName = getTableName(tableName, schemaName); @@ -218,7 +217,7 @@ module.exports = (app, options) => { collectionSchema, schemaName, ); - const modifyNotNullScriptDtos = getModifyNonNullColumnsScriptDtos(_, ddlProvider)( + const modifyNotNullScriptDtos = getModifyNonNullColumnsScriptDtos(ddlProvider)( collection, collectionSchema, schemaName, @@ -296,14 +295,14 @@ module.exports = (app, options) => { return undefined; } - if (!oldComment) { + if (oldComment) { + script = getTableUpdateCommentScript({ schemaName, tableName, comment: newComment }); + } else { script = ddlProvider.createTableComment({ schemaName, tableName, comment: newComment, }); - } else { - script = getTableUpdateCommentScript({ schemaName, tableName, comment: newComment }); } return AlterScriptDto.getInstance([script], true, false); @@ -330,7 +329,7 @@ module.exports = (app, options) => { const getColumnsCreateCommentAlterScriptsDto = tables => { return Object.keys(tables) - .map(tableName => { + .flatMap(tableName => { const columns = tables[tableName].properties; if (!columns) { return []; @@ -352,13 +351,12 @@ module.exports = (app, options) => { return AlterScriptDto.getInstance([script], true, false); }); }) - .flat() .filter(Boolean); }; const getColumnsDropCommentAlterScriptsDto = tables => { return Object.keys(tables) - .map(tableName => { + .flatMap(tableName => { const columns = tables[tableName].properties; if (!columns) { @@ -375,13 +373,12 @@ module.exports = (app, options) => { return AlterScriptDto.getInstance([script], true, true); }); }) - .flat() .filter(Boolean); }; const getColumnsModifyCommentAlterScriptsDto = tables => { return Object.keys(tables) - .map(tableName => { + .flatMap(tableName => { const columns = tables[tableName].properties; if (!columns) { return undefined; @@ -403,15 +400,15 @@ module.exports = (app, options) => { return undefined; } - if (!oldComment) { - script = getColumnCreateCommentScript({ + if (oldComment) { + script = getColumnUpdateCommentScript({ schemaName, tableName, columnName, comment: newComment, }); } else { - script = getColumnUpdateCommentScript({ + script = getColumnCreateCommentScript({ schemaName, tableName, columnName, @@ -422,7 +419,6 @@ module.exports = (app, options) => { return AlterScriptDto.getInstance([script], true, false); }); }) - .flat() .filter(Boolean); }; @@ -440,3 +436,5 @@ module.exports = (app, options) => { getColumnsModifyCommentAlterScriptsDto, }; }; + +module.exports = alterEntityHelper; diff --git a/forward_engineering/helpers/alterScriptHelpers/alterRelationshipsHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterRelationshipsHelper.js index 02989d8e..15a1802f 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterRelationshipsHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterRelationshipsHelper.js @@ -1,6 +1,5 @@ -'use strict'; - const { AlterScriptDto } = require('./types/AlterScriptDto'); +const { getNamePrefixedWithSchemaName, wrapInBrackets } = require('../../utils/general'); /** * @param relationship {AlterRelationshipDto} @@ -13,8 +12,7 @@ const getRelationshipName = relationship => { /** * @return {(relationship: AlterRelationshipDto) => string} * */ -const getFullChildTableName = _ => relationship => { - const { getNamePrefixedWithSchemaName } = require('../../utils/general')(_); +const getFullChildTableName = relationship => { const compMod = relationship.role.compMod; const childBucketName = compMod.child.bucket.name; @@ -28,7 +26,7 @@ const getFullChildTableName = _ => relationship => { * statement: string, * }} * */ -const getAddSingleForeignKeyStatementDto = (ddlProvider, _) => relationship => { +const getAddSingleForeignKeyStatementDto = ddlProvider => relationship => { const compMod = relationship.role.compMod; const relationshipName = compMod.code?.new || compMod.name?.new || getRelationshipName(relationship) || ''; @@ -69,17 +67,17 @@ const canRelationshipBeAdded = relationship => { compMod.child?.bucket, compMod.child?.collection, compMod.child?.collection?.fkFields?.length, - ].every(property => Boolean(property)); + ].every(Boolean); }; /** * @return {(addedRelationships: Array) => Array} * */ -const getAddForeignKeyScriptDtos = (ddlProvider, _) => addedRelationships => { +const getAddForeignKeyScriptDtos = ddlProvider => addedRelationships => { return addedRelationships .filter(relationship => canRelationshipBeAdded(relationship)) .map(relationship => { - const scriptDto = getAddSingleForeignKeyStatementDto(ddlProvider, _)(relationship); + const scriptDto = getAddSingleForeignKeyStatementDto(ddlProvider)(relationship); return AlterScriptDto.getInstance([scriptDto.statement], scriptDto.isActivated, false); }) .filter(Boolean) @@ -92,11 +90,10 @@ const getAddForeignKeyScriptDtos = (ddlProvider, _) => addedRelationships => { * statement: string, * }} * */ -const getDeleteSingleForeignKeyStatementDto = (ddlProvider, _) => relationship => { - const { wrapInBrackets } = require('../../utils/general')(_); +const getDeleteSingleForeignKeyStatementDto = ddlProvider => relationship => { const compMod = relationship.role.compMod; - const ddlChildEntityName = getFullChildTableName(_)(relationship); + const ddlChildEntityName = getFullChildTableName(relationship); const relationshipName = compMod.code?.old || compMod.name?.old || getRelationshipName(relationship) || ''; const ddlRelationshipName = wrapInBrackets(relationshipName); @@ -123,17 +120,17 @@ const canRelationshipBeDeleted = relationship => { compMod.code?.old || compMod.name?.old || getRelationshipName(relationship), compMod.child?.bucket, compMod.child?.collection, - ].every(property => Boolean(property)); + ].every(Boolean); }; /** * @return {(deletedRelationships: Array) => Array} * */ -const getDeleteForeignKeyScriptDtos = (ddlProvider, _) => deletedRelationships => { +const getDeleteForeignKeyScriptDtos = ddlProvider => deletedRelationships => { return deletedRelationships .filter(relationship => canRelationshipBeDeleted(relationship)) .map(relationship => { - const scriptDto = getDeleteSingleForeignKeyStatementDto(ddlProvider, _)(relationship); + const scriptDto = getDeleteSingleForeignKeyStatementDto(ddlProvider)(relationship); return AlterScriptDto.getInstance([scriptDto.statement], scriptDto.isActivated, true); }) .filter(Boolean) @@ -143,12 +140,12 @@ const getDeleteForeignKeyScriptDtos = (ddlProvider, _) => deletedRelationships = /** * @return {(modifiedRelationships: Array) => Array} * */ -const getModifyForeignKeyScriptDtos = (ddlProvider, _) => modifiedRelationships => { +const getModifyForeignKeyScriptDtos = ddlProvider => modifiedRelationships => { return modifiedRelationships .filter(relationship => canRelationshipBeAdded(relationship) && canRelationshipBeDeleted(relationship)) .map(relationship => { - const deleteScriptDto = getDeleteSingleForeignKeyStatementDto(ddlProvider, _)(relationship); - const addScriptDto = getAddSingleForeignKeyStatementDto(ddlProvider, _)(relationship); + const deleteScriptDto = getDeleteSingleForeignKeyStatementDto(ddlProvider)(relationship); + const addScriptDto = getAddSingleForeignKeyStatementDto(ddlProvider)(relationship); const isActivated = addScriptDto.isActivated && deleteScriptDto.isActivated; return AlterScriptDto.getDropAndRecreateInstance( deleteScriptDto.statement, diff --git a/forward_engineering/helpers/alterScriptHelpers/alterScriptBuilder.js b/forward_engineering/helpers/alterScriptHelpers/alterScriptBuilder.js index 6574932d..7da24576 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterScriptBuilder.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterScriptBuilder.js @@ -1,5 +1,3 @@ -'use strict'; - /** * @typedef {import('./helpers/alterScriptHelpers/types/AlterScriptDto').AlterScriptDto} AlterScriptDto * @typedef {import('./types/coreApplicationTypes').App} App @@ -24,13 +22,15 @@ * }} ContainerLevelAlterScriptData * */ +const _ = require('lodash'); +const { getAlterScriptDtos } = require('../alterScriptFromDeltaHelper'); +const { joinAlterScriptDtosIntoAlterScript } = require('../alterScriptFromDeltaHelper'); + const parseEntities = (entities, serializedItems) => { return entities.reduce((result, entityId) => { try { - return Object.assign({}, result, { - [entityId]: JSON.parse(serializedItems[entityId]), - }); - } catch (e) { + return { ...result, [entityId]: JSON.parse(serializedItems[entityId]) }; + } catch { return result; } }, {}); @@ -38,7 +38,6 @@ const parseEntities = (entities, serializedItems) => { /** * @param data {CoreData} - * @param app {App} * @return {{ * jsonSchema: unknown, * modelDefinitions: ModelDefinitions | unknown, @@ -48,9 +47,7 @@ const parseEntities = (entities, serializedItems) => { * entityData: unknown, * }} * */ -const parseDataForEntityLevelScript = (data, app) => { - const _ = app.require('lodash'); - +const parseDataForEntityLevelScript = data => { const jsonSchema = JSON.parse(data.jsonSchema); const modelDefinitions = JSON.parse(data.modelDefinitions); const internalDefinitions = _.isObject(data.internalDefinitions) @@ -77,10 +74,7 @@ const parseDataForEntityLevelScript = (data, app) => { * */ const getEntityLevelAlterScriptDtos = (data, app) => - ({ externalDefinitions, modelDefinitions, jsonSchema, internalDefinitions }) => { - const { getAlterScriptDtos } = require('../alterScriptFromDeltaHelper')(app.require('lodash')); - const definitions = [modelDefinitions, internalDefinitions, externalDefinitions]; - + ({ jsonSchema }) => { return getAlterScriptDtos(jsonSchema, app, data.options); }; @@ -90,7 +84,6 @@ const getEntityLevelAlterScriptDtos = * @return {(dto: EntityLevelAlterScriptData) => string} * */ const buildEntityLevelAlterScript = (data, app) => entityLevelAlterScriptDto => { - const { joinAlterScriptDtosIntoAlterScript } = require('../alterScriptFromDeltaHelper')(app.require('lodash')); const alterScriptDtos = getEntityLevelAlterScriptDtos(data, app)(entityLevelAlterScriptDto); return joinAlterScriptDtosIntoAlterScript(alterScriptDtos, data); diff --git a/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js index 5ca31fc8..d6de8344 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js @@ -1,14 +1,15 @@ -module.exports = (app, options) => { - const _ = app.require('lodash'); - const { createColumnDefinitionBySchema } = require('./columnHelpers/createColumnDefinition')(_); +const _ = require('lodash'); +const { AlterScriptDto } = require('./types/AlterScriptDto'); +const { createColumnDefinitionBySchema } = require('./columnHelpers/createColumnDefinition'); + +const alterUdtHelper = (app, options) => { const ddlProvider = require('../../ddlProvider')(null, options, app); - const { AlterScriptDto } = require('./types/AlterScriptDto'); const DEFAULT_KEY_SPACE = { 'Default_Keyspace': [] }; const getSchemaNames = udt => { const schemaNames = udt.compMod?.bucketsWithCurrentDefinition; - return !_.isEmpty(schemaNames) ? schemaNames : DEFAULT_KEY_SPACE; + return _.isEmpty(schemaNames) ? DEFAULT_KEY_SPACE : schemaNames; }; const getCreateUdtScriptDto = jsonSchema => { @@ -43,3 +44,5 @@ module.exports = (app, options) => { getDeleteUdtScriptDto, }; }; + +module.exports = alterUdtHelper; diff --git a/forward_engineering/helpers/alterScriptHelpers/alterViewHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterViewHelper.js index 6143089e..14d395f2 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterViewHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterViewHelper.js @@ -1,15 +1,17 @@ -module.exports = (app, options) => { - const _ = app.require('lodash'); - const { mapProperties } = app.require('@hackolade/ddl-fe-utils'); - const { checkCompModEqual, setIndexKeys, modifyGroupItems } = require('./common')(app); - const { generateIdToNameHashTable, generateIdToActivatedHashTable } = app.require('@hackolade/ddl-fe-utils'); +const _ = require('lodash'); +const { getTableName } = require('../general'); +const { checkCompModEqual, setIndexKeys, modifyGroupItems } = require('./common'); +const { AlterScriptDto } = require('./types/AlterScriptDto'); + +const alterViewHelper = (app, options) => { + const { generateIdToNameHashTable, generateIdToActivatedHashTable, mapProperties } = + app.require('@hackolade/ddl-fe-utils'); + const ddlProvider = require('../../ddlProvider')(null, options, app); - const { getTableName } = require('../general')(app); - const { AlterScriptDto } = require('./types/AlterScriptDto'); const getAddViewScriptDto = view => { const viewName = getTableName(view.code || view.name, view?.role?.compMod?.keyspaceName); - const viewSchema = { ...view, ...(view.role ?? {}) }; + const viewSchema = { ...view, ...view.role }; const idToNameHashTable = generateRefToNameHashTable(viewSchema); const idToActivatedHashTable = generateRefToActivatedHashTable(viewSchema); const schemaData = { schemaName: viewSchema.compMod.keyspaceName }; @@ -40,7 +42,7 @@ module.exports = (app, options) => { }; const getModifiedViewScriptDto = view => { - const viewSchema = { ...view, ...(view.role ?? {}) }; + const viewSchema = { ...view, ...view.role }; const idToNameHashTable = generateIdToNameHashTable(viewSchema); const idToActivatedHashTable = generateIdToActivatedHashTable(viewSchema); const schemaData = { schemaName: viewSchema.compMod.keyspaceName }; @@ -185,14 +187,14 @@ module.exports = (app, options) => { return undefined; } - if (!oldComment) { + if (oldComment) { + script = getViewUpdateCommentScript({ schemaName, viewName, comment: newComment }); + } else { script = ddlProvider.createViewComment({ schemaName, viewName, comment: newComment, }); - } else { - script = getViewUpdateCommentScript({ schemaName, viewName, comment: newComment }); } return AlterScriptDto.getInstance([script], true, false); @@ -228,3 +230,5 @@ module.exports = (app, options) => { getViewsModifyCommentsAlterScriptsDto, }; }; + +module.exports = alterViewHelper; diff --git a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterComputedColumnHelpr.js b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterComputedColumnHelper.js similarity index 78% rename from forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterComputedColumnHelpr.js rename to forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterComputedColumnHelper.js index 7874d357..9c13eb67 100644 --- a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterComputedColumnHelpr.js +++ b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterComputedColumnHelper.js @@ -1,12 +1,9 @@ -'use strict'; - const _ = require('lodash'); +const { createColumnDefinitionBySchema } = require('./createColumnDefinition'); +const { AlterScriptDto } = require('../types/AlterScriptDto'); +const { compareObjectsByProperties } = require('../../../utils/general'); -module.exports = (app, ddlProvider) => { - const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_); - const { AlterScriptDto } = require('../types/AlterScriptDto'); - const { compareObjectsByProperties } = require('../../../utils/general')(_); - +const alterComputedColumnHelper = ddlProvider => { const changeToComputed = (fullName, columnName, columnDefinition) => { return [ AlterScriptDto.getInstance([ddlProvider.dropColumn(fullName, columnName)], true, true), @@ -69,17 +66,19 @@ module.exports = (app, ddlProvider) => { }; const getChangedComputedColumnsScriptsDto = ({ collection, fullName, collectionSchema, schemaName }) => { - return _.flatten( - _.toPairs(collection.properties).reduce((result, [columnName, jsonSchema]) => { + return _.toPairs(collection.properties) + .reduce((result, [columnName, jsonSchema]) => { const oldJsonSchema = _.omit(collection.role?.properties?.[columnName], ['compMod']); const currentRequiredColumnNames = collection.required || []; const previousRequiredColumnNames = collection.role.required || []; - const toAddNotNull = - _.difference(currentRequiredColumnNames, previousRequiredColumnNames).indexOf(columnName) !== -1; - const toRemoveNotNull = - _.difference(previousRequiredColumnNames, currentRequiredColumnNames).indexOf(columnName) !== -1; + const toAddNotNull = _.difference(currentRequiredColumnNames, previousRequiredColumnNames).includes( + columnName, + ); + const toRemoveNotNull = _.difference(previousRequiredColumnNames, currentRequiredColumnNames).includes( + columnName, + ); result.push( generateSqlAlterScript({ @@ -95,11 +94,13 @@ module.exports = (app, ddlProvider) => { ); return result; - }, []), - ); + }, []) + .flat(); }; return { getChangedComputedColumnsScriptsDto, }; }; + +module.exports = alterComputedColumnHelper; diff --git a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterTypeHelper.js b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterTypeHelper.js index 41e632d0..3130ecf5 100644 --- a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterTypeHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/alterTypeHelper.js @@ -1,11 +1,9 @@ -'use strict'; - -module.exports = (app, ddlProvider) => { - const _ = app.require('lodash'); - const { checkFieldPropertiesChanged } = require('../common')(app); - const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_); - const { AlterScriptDto } = require('../types/AlterScriptDto'); +const _ = require('lodash'); +const { AlterScriptDto } = require('../types/AlterScriptDto'); +const { checkFieldPropertiesChanged } = require('../common'); +const { createColumnDefinitionBySchema } = require('./createColumnDefinition'); +const alterTypeHelper = ddlProvider => { const getChangeTypeScriptsDto = (collectionProperties, fullName, collectionSchema, schemaName) => { const schemaData = { schemaName }; @@ -28,3 +26,5 @@ module.exports = (app, ddlProvider) => { getChangeTypeScriptsDto, }; }; + +module.exports = alterTypeHelper; diff --git a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/createColumnDefinition.js b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/createColumnDefinition.js index ff206e46..944acf0c 100644 --- a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/createColumnDefinition.js +++ b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/createColumnDefinition.js @@ -1,107 +1,105 @@ -module.exports = _ => { - const createColumnDefinition = data => { - return Object.assign( - { - name: '', - type: '', - nullable: true, - primaryKey: false, - default: '', - length: '', - scale: '', - precision: '', - hasMaxLength: false, - }, - data, - ); +const _ = require('lodash'); + +const createColumnDefinition = data => { + return { + name: '', + type: '', + nullable: true, + primaryKey: false, + default: '', + length: '', + scale: '', + precision: '', + hasMaxLength: false, + ...data, }; +}; - const isNullable = (parentSchema, propertyName) => { - if (!Array.isArray(parentSchema.required)) { - return true; - } +const isNullable = (parentSchema, propertyName) => { + if (!Array.isArray(parentSchema.required)) { + return true; + } - return !parentSchema.required.includes(propertyName); - }; + return !parentSchema.required.includes(propertyName); +}; - const getDefault = jsonSchema => { - const defaultValue = jsonSchema.default; +const getDefault = jsonSchema => { + const defaultValue = jsonSchema.default; - if (_.isBoolean(defaultValue)) { - return defaultValue; - } else if (jsonSchema.default === null) { - return 'NULL'; - } else { - return defaultValue; - } - }; + if (_.isBoolean(defaultValue)) { + return defaultValue; + } else if (jsonSchema.default === null) { + return 'NULL'; + } else { + return defaultValue; + } +}; - const getLength = jsonSchema => { - if (_.isNumber(jsonSchema.length)) { - return jsonSchema.length; - } else if (_.isNumber(jsonSchema.maxLength)) { - return jsonSchema.maxLength; - } else { - return ''; - } - }; +const getLength = jsonSchema => { + if (_.isNumber(jsonSchema.length)) { + return jsonSchema.length; + } else if (_.isNumber(jsonSchema.maxLength)) { + return jsonSchema.maxLength; + } else { + return ''; + } +}; - const getScale = jsonSchema => { - if (_.isNumber(jsonSchema.scale)) { - return jsonSchema.scale; - } else { - return ''; - } - }; +const getScale = jsonSchema => { + if (_.isNumber(jsonSchema.scale)) { + return jsonSchema.scale; + } else { + return ''; + } +}; - const getPrecision = jsonSchema => { - if (_.isNumber(jsonSchema.precision)) { - return jsonSchema.precision; - } else if (_.isNumber(jsonSchema.fractSecPrecision)) { - return jsonSchema.fractSecPrecision; - } else { - return ''; - } - }; +const getPrecision = jsonSchema => { + if (_.isNumber(jsonSchema.precision)) { + return jsonSchema.precision; + } else if (_.isNumber(jsonSchema.fractSecPrecision)) { + return jsonSchema.fractSecPrecision; + } else { + return ''; + } +}; - const hasMaxLength = jsonSchema => { - if (jsonSchema.hasMaxLength) { - return jsonSchema.hasMaxLength; - } else { - return ''; - } - }; +const hasMaxLength = jsonSchema => { + if (jsonSchema.hasMaxLength) { + return jsonSchema.hasMaxLength; + } else { + return ''; + } +}; - const getType = jsonSchema => { - if (jsonSchema.$ref) { - return jsonSchema.$ref.split('/').pop(); - } +const getType = jsonSchema => { + if (jsonSchema.$ref) { + return jsonSchema.$ref.split('/').pop(); + } - return jsonSchema.mode || jsonSchema.childType || jsonSchema.type; - }; + return jsonSchema.mode || jsonSchema.childType || jsonSchema.type; +}; - const createColumnDefinitionBySchema = ({ name, jsonSchema, parentJsonSchema, ddlProvider, schemaData }) => { - const columnDefinition = createColumnDefinition({ - name: name, - type: getType(jsonSchema), - nullable: isNullable(parentJsonSchema, name), - default: getDefault(jsonSchema), - primaryKey: jsonSchema.primaryKey, - length: getLength(jsonSchema), - scale: getScale(jsonSchema), - precision: getPrecision(jsonSchema), - hasMaxLength: hasMaxLength(jsonSchema), - isActivated: jsonSchema.isActivated, - }); +const createColumnDefinitionBySchema = ({ name, jsonSchema, parentJsonSchema, ddlProvider, schemaData }) => { + const columnDefinition = createColumnDefinition({ + name: name, + type: getType(jsonSchema), + nullable: isNullable(parentJsonSchema, name), + default: getDefault(jsonSchema), + primaryKey: jsonSchema.primaryKey, + length: getLength(jsonSchema), + scale: getScale(jsonSchema), + precision: getPrecision(jsonSchema), + hasMaxLength: hasMaxLength(jsonSchema), + isActivated: jsonSchema.isActivated, + }); - return ddlProvider.hydrateColumn({ - columnDefinition, - jsonSchema, - schemaData, - }); - }; + return ddlProvider.hydrateColumn({ + columnDefinition, + jsonSchema, + schemaData, + }); +}; - return { - createColumnDefinitionBySchema, - }; +module.exports = { + createColumnDefinitionBySchema, }; diff --git a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/defaultValueColumnHelper.js b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/defaultValueColumnHelper.js index ab473a37..92ad895a 100644 --- a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/defaultValueColumnHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/defaultValueColumnHelper.js @@ -1,9 +1,9 @@ -module.exports = (app, ddlProvider) => { - const _ = app.require('lodash'); - const { AlterScriptDto } = require('../types/AlterScriptDto'); - const { sanitizeConstraintName, hasType, getTableName } = require('../../../helpers/general')(app); - const { decorateDefault } = require('../../columnDefinitionHelper')(app); +const _ = require('lodash'); +const { AlterScriptDto } = require('../types/AlterScriptDto'); +const { sanitizeConstraintName, hasType, getTableName } = require('../../../helpers/general'); +const { decorateDefault } = require('../../columnDefinitionHelper'); +const defaultValueColumnHelper = ddlProvider => { const getDefaultValueChangeDto = (collection, fullName) => { const scripts = []; @@ -101,3 +101,5 @@ module.exports = (app, ddlProvider) => { getDefaultValueChangeDto, }; }; + +module.exports = defaultValueColumnHelper; diff --git a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/notNullConstraintsHelper.js b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/notNullConstraintsHelper.js index cade0d82..a56491ed 100644 --- a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/notNullConstraintsHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/notNullConstraintsHelper.js @@ -1,13 +1,12 @@ -'use strict'; - +const _ = require('lodash'); const { AlterScriptDto } = require('../types/AlterScriptDto'); +const { getFullTableName, wrapInBrackets } = require('../../../utils/general'); +const { createColumnDefinitionBySchema } = require('./createColumnDefinition'); /** * @return {(collection: Collection) => AlterScriptDto[]} * */ -const getModifyNonNullColumnsScriptDtos = (_, ddlProvider) => (collection, collectionSchema, schemaName) => { - const { getFullTableName, wrapInBrackets } = require('../../../utils/general')(_); - const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_); +const getModifyNonNullColumnsScriptDtos = ddlProvider => (collection, collectionSchema, schemaName) => { const fullTableName = getFullTableName(collection); const schemaData = { schemaName }; diff --git a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/renameColumnHelpers.js b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/renameColumnHelpers.js index 508701a9..d87846af 100644 --- a/forward_engineering/helpers/alterScriptHelpers/columnHelpers/renameColumnHelpers.js +++ b/forward_engineering/helpers/alterScriptHelpers/columnHelpers/renameColumnHelpers.js @@ -1,10 +1,8 @@ -'use strict'; - -module.exports = (app, ddlProvider) => { - const _ = app.require('lodash'); - const { checkFieldPropertiesChanged } = require('../common')(app); - const { AlterScriptDto } = require('../types/AlterScriptDto'); +const _ = require('lodash'); +const { checkFieldPropertiesChanged } = require('../common'); +const { AlterScriptDto } = require('../types/AlterScriptDto'); +const renameColumnHelpers = ddlProvider => { const getRenameColumnScriptsDto = (collectionProperties, fullName) => { return _.values(collectionProperties) .filter(jsonSchema => checkFieldPropertiesChanged(jsonSchema.compMod, ['name'])) @@ -23,3 +21,5 @@ module.exports = (app, ddlProvider) => { getRenameColumnScriptsDto, }; }; + +module.exports = renameColumnHelpers; diff --git a/forward_engineering/helpers/alterScriptHelpers/common.js b/forward_engineering/helpers/alterScriptHelpers/common.js index 69faf70d..45385e09 100644 --- a/forward_engineering/helpers/alterScriptHelpers/common.js +++ b/forward_engineering/helpers/alterScriptHelpers/common.js @@ -1,93 +1,91 @@ -module.exports = app => { - const _ = app.require('lodash'); +const _ = require('lodash'); - const checkFieldPropertiesChanged = (compMod, propertiesToCheck) => { - return propertiesToCheck.some(prop => compMod?.oldField[prop] !== compMod?.newField[prop]); - }; +const checkFieldPropertiesChanged = (compMod, propertiesToCheck) => { + return propertiesToCheck.some(prop => compMod?.oldField[prop] !== compMod?.newField[prop]); +}; - const modifyGroupItems = ({ data, key, hydrate, drop, create }) => { - const compMod = getCompMod(data); - const parentName = data.code || data.name || data.collectionName; +const modifyGroupItems = ({ data, key, hydrate, drop, create }) => { + const compMod = getCompMod(data); + const parentName = data.code || data.name || data.collectionName; - const { removed, added, modified } = getModifiedGroupItems(compMod[key] || {}, hydrate); + const { removed, added, modified } = getModifiedGroupItems(compMod[key] || {}, hydrate); - const removedScripts = removed.map(item => drop(parentName, item)); - const addedScripts = added.map(item => create(parentName, item)); - const modifiedScripts = modified.map(item => create(parentName, { ...item, orReplace: true })); + const removedScripts = removed.map(item => drop(parentName, item)); + const addedScripts = added.map(item => create(parentName, item)); + const modifiedScripts = modified.map(item => create(parentName, { ...item, orReplace: true })); - return [].concat(modifiedScripts).concat(removedScripts).concat(addedScripts); - }; + return [modifiedScripts].flat().concat(removedScripts).concat(addedScripts); +}; - const getModifiedGroupItems = ({ new: newItems = [], old: oldItems = [] }, hydrate) => { - const oldHydrated = oldItems.map(hydrate).filter(Boolean); - const newHydrated = newItems.map(hydrate).filter(Boolean); - - const { removed, added, modified } = oldHydrated.reduce( - (accumulator, oldItem) => { - const newItem = newHydrated.find(item => item.name === oldItem.name); - const itemsAreNotEqual = !isGroupItemsEqual(newItem, oldItem); - - if (!newItem) { - return { - removed: [...accumulator.removed, oldItem], - modified: accumulator.modified, - added: accumulator.added, - }; - } - - if (itemsAreNotEqual) { - return { - removed: accumulator.removed, - modified: [...accumulator.modified, newItem], - added: accumulator.added, - }; - } - - return accumulator; - }, - { - removed: [], - modified: [], - added: newHydrated.filter(newItem => !oldHydrated.some(item => item.name === newItem.name)), - }, - ); - - return { removed, added, modified }; - }; +const getModifiedGroupItems = ({ new: newItems = [], old: oldItems = [] }, hydrate) => { + const oldHydrated = oldItems.map(element => hydrate(element)).filter(Boolean); + const newHydrated = newItems.map(element => hydrate(element)).filter(Boolean); + + const { removed, added, modified } = oldHydrated.reduce( + (accumulator, oldItem) => { + const newItem = newHydrated.find(item => item.name === oldItem.name); + const itemsAreNotEqual = !isGroupItemsEqual(newItem, oldItem); + + if (!newItem) { + return { + removed: [...accumulator.removed, oldItem], + modified: accumulator.modified, + added: accumulator.added, + }; + } + + if (itemsAreNotEqual) { + return { + removed: accumulator.removed, + modified: [...accumulator.modified, newItem], + added: accumulator.added, + }; + } + + return accumulator; + }, + { + removed: [], + modified: [], + added: newHydrated.filter(newItem => !oldHydrated.some(item => item.name === newItem.name)), + }, + ); + + return { removed, added, modified }; +}; - const isGroupItemsEqual = (leftItem, rightItem) => _.isEqual(leftItem, rightItem); +const isGroupItemsEqual = (leftItem, rightItem) => _.isEqual(leftItem, rightItem); - const getCompMod = containerData => containerData.role?.compMod ?? {}; +const getCompMod = containerData => containerData.role?.compMod ?? {}; - const checkCompModEqual = ({ new: newItem, old: oldItem } = {}) => _.isEqual(newItem, oldItem); +const checkCompModEqual = ({ new: newItem, old: oldItem } = {}) => _.isEqual(newItem, oldItem); - const setIndexKeys = (idToNameHashTable, idToActivatedHashTable, index) => { - return { - ...index, - indxKey: - index.indxKey?.map(key => ({ - ...key, - name: idToNameHashTable[key.keyId], - isActivated: idToActivatedHashTable[key.keyId], - })) || [], - indxInclude: index.indxInclude?.map(key => ({ - ...key, - name: idToNameHashTable[key.keyId], - isActivated: idToActivatedHashTable[key.keyId], - })), - indxIncludedColumn: index.indxIncludedColumn?.map(key => ({ +const setIndexKeys = (idToNameHashTable, idToActivatedHashTable, index) => { + return { + ...index, + indxKey: + index.indxKey?.map(key => ({ ...key, name: idToNameHashTable[key.keyId], isActivated: idToActivatedHashTable[key.keyId], - })), - }; + })) || [], + indxInclude: index.indxInclude?.map(key => ({ + ...key, + name: idToNameHashTable[key.keyId], + isActivated: idToActivatedHashTable[key.keyId], + })), + indxIncludedColumn: index.indxIncludedColumn?.map(key => ({ + ...key, + name: idToNameHashTable[key.keyId], + isActivated: idToActivatedHashTable[key.keyId], + })), }; +}; - return { - checkFieldPropertiesChanged, - getCompMod, - modifyGroupItems, - checkCompModEqual, - setIndexKeys, - }; +module.exports = { + checkFieldPropertiesChanged, + getCompMod, + modifyGroupItems, + checkCompModEqual, + setIndexKeys, }; diff --git a/forward_engineering/helpers/alterScriptHelpers/entityHelpers/checkConstraintHelper.js b/forward_engineering/helpers/alterScriptHelpers/entityHelpers/checkConstraintHelper.js index eef16c56..f27454f8 100644 --- a/forward_engineering/helpers/alterScriptHelpers/entityHelpers/checkConstraintHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/entityHelpers/checkConstraintHelper.js @@ -1,6 +1,6 @@ -'use strict'; - +const _ = require('lodash'); const { AlterScriptDto } = require('../types/AlterScriptDto'); +const { getFullTableName, wrapInBrackets } = require('../../../utils/general'); /** * @typedef {{ @@ -18,7 +18,7 @@ const { AlterScriptDto } = require('../types/AlterScriptDto'); /** * @return {(collection: AlterCollectionDto) => Array} * */ -const mapCheckConstraintNamesToChangeHistory = _ => collection => { +const mapCheckConstraintNamesToChangeHistory = collection => { const checkConstraintHistory = collection?.compMod?.chkConstr; if (!checkConstraintHistory) { return []; @@ -41,9 +41,7 @@ const mapCheckConstraintNamesToChangeHistory = _ => collection => { /** * @return {(constraintHistory: Array, fullTableName: string) => Array} * */ -const getDropCheckConstraintScriptDtos = (_, ddlProvider) => (constraintHistory, fullTableName) => { - const { wrapInBrackets } = require('../../../utils/general')(_); - +const getDropCheckConstraintScriptDtos = ddlProvider => (constraintHistory, fullTableName) => { return constraintHistory .filter(historyEntry => historyEntry.old && !historyEntry.new) .map(historyEntry => { @@ -60,9 +58,7 @@ const getDropCheckConstraintScriptDtos = (_, ddlProvider) => (constraintHistory, /** * @return {(constraintHistory: Array, fullTableName: string) => Array} * */ -const getAddCheckConstraintScriptDtos = (_, ddlProvider) => (constraintHistory, fullTableName) => { - const { wrapInBrackets } = require('../../../utils/general')(_); - +const getAddCheckConstraintScriptDtos = ddlProvider => (constraintHistory, fullTableName) => { return constraintHistory .filter(historyEntry => historyEntry.new && !historyEntry.old) .map(historyEntry => { @@ -80,9 +76,7 @@ const getAddCheckConstraintScriptDtos = (_, ddlProvider) => (constraintHistory, /** * @return {(constraintHistory: Array, fullTableName: string) => Array} * */ -const getUpdateCheckConstraintScriptDtos = (_, ddlProvider) => (constraintHistory, fullTableName) => { - const { wrapInBrackets } = require('../../../utils/general')(_); - +const getUpdateCheckConstraintScriptDtos = ddlProvider => (constraintHistory, fullTableName) => { return constraintHistory .filter(historyEntry => { if (historyEntry.old && historyEntry.new) { @@ -97,7 +91,7 @@ const getUpdateCheckConstraintScriptDtos = (_, ddlProvider) => (constraintHistor } return false; }) - .map(historyEntry => { + .flatMap(historyEntry => { const { chkConstrName: oldConstrainName } = historyEntry.old; const dropConstraintScript = ddlProvider.dropConstraint(fullTableName, wrapInBrackets(oldConstrainName)); const { @@ -116,24 +110,19 @@ const getUpdateCheckConstraintScriptDtos = (_, ddlProvider) => (constraintHistor AlterScriptDto.getInstance([dropConstraintScript], true, true), AlterScriptDto.getInstance([addConstraintScript], true, false), ]; - }) - .flat(); + }); }; /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getModifyCheckConstraintScriptDtos = (_, ddlProvider) => collection => { - const { getFullTableName } = require('../../../utils/general')(_); +const getModifyCheckConstraintScriptDtos = ddlProvider => collection => { const fullTableName = getFullTableName(collection); - const constraintHistory = mapCheckConstraintNamesToChangeHistory(_)(collection); + const constraintHistory = mapCheckConstraintNamesToChangeHistory(collection); - const addCheckConstraintScripts = getAddCheckConstraintScriptDtos(_, ddlProvider)(constraintHistory, fullTableName); - const dropCheckConstraintScripts = getDropCheckConstraintScriptDtos(_, ddlProvider)( - constraintHistory, - fullTableName, - ); - const updateCheckConstraintScripts = getUpdateCheckConstraintScriptDtos(_, ddlProvider)( + const addCheckConstraintScripts = getAddCheckConstraintScriptDtos(ddlProvider)(constraintHistory, fullTableName); + const dropCheckConstraintScripts = getDropCheckConstraintScriptDtos(ddlProvider)(constraintHistory, fullTableName); + const updateCheckConstraintScripts = getUpdateCheckConstraintScriptDtos(ddlProvider)( constraintHistory, fullTableName, ); diff --git a/forward_engineering/helpers/alterScriptHelpers/entityHelpers/primaryKeyHelper.js b/forward_engineering/helpers/alterScriptHelpers/entityHelpers/primaryKeyHelper.js index d17b1861..e61f4e74 100644 --- a/forward_engineering/helpers/alterScriptHelpers/entityHelpers/primaryKeyHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/entityHelpers/primaryKeyHelper.js @@ -1,6 +1,13 @@ -'use strict'; - +const _ = require('lodash'); const { AlterScriptDto } = require('../types/AlterScriptDto'); +const { getCompositePrimaryKeys, hydratePrimaryKeyOptions } = require('../../keyHelper'); +const { + wrapInBrackets, + getSchemaOfAlterCollection, + getFullCollectionName, + getEntityName, + buildDefaultPKName, +} = require('../../../utils/general'); const amountOfColumnsInRegularPk = 1; @@ -130,7 +137,7 @@ const getCustomPropertiesOfCompositePkForComparisonWithRegularPkOptions = compos /** * @return {(collection: AlterCollectionDto) => PkTransitionDto} * */ -const wasCompositePkChangedInTransitionFromCompositeToRegular = _ => collection => { +const wasCompositePkChangedInTransitionFromCompositeToRegular = collection => { /** * @type {AlterCollectionRoleCompModPrimaryKey} * */ @@ -172,7 +179,7 @@ const wasCompositePkChangedInTransitionFromCompositeToRegular = _ => collection /** * @return {(collection: AlterCollectionDto) => PkTransitionDto} * */ -const wasCompositePkChangedInTransitionFromRegularToComposite = _ => collection => { +const wasCompositePkChangedInTransitionFromRegularToComposite = collection => { /** * @type {AlterCollectionRoleCompModPrimaryKey} * */ @@ -211,23 +218,11 @@ const wasCompositePkChangedInTransitionFromRegularToComposite = _ => collection return PkTransitionDto.transition(!areOptionsEqual); }; -/** - * @param primaryKey {AlterCollectionRoleCompModPKDto} - * @param entityName {string} - * @return {string} - * */ -const getConstraintNameForCompositePk = (primaryKey, entityName) => { - if (primaryKey.constraintName) { - return primaryKey.constraintName; - } - return getDefaultConstraintName(entityName); -}; - const checkCompositePKsOnTransition = transitionToCompositeDto => { return !!(transitionToCompositeDto.didTransitionHappen && !transitionToCompositeDto.wasPkChangedInTransition); }; -const checkCompositePKsOnEquality = (_, newPrimaryKeys, oldPrimaryKeys) => { +const checkCompositePKsOnEquality = (newPrimaryKeys, oldPrimaryKeys) => { if (newPrimaryKeys.length === oldPrimaryKeys.length) { const areKeyArraysEqual = _(oldPrimaryKeys).differenceWith(newPrimaryKeys, _.isEqual).isEmpty(); @@ -239,16 +234,14 @@ const checkCompositePKsOnEquality = (_, newPrimaryKeys, oldPrimaryKeys) => { return false; }; -const checkCompositePKsOnTransitionOrEquality = (transitionToCompositeDto, _, newPrimaryKeys, oldPrimaryKeys) => { +const checkCompositePKsOnTransitionOrEquality = (transitionToCompositeDto, newPrimaryKeys, oldPrimaryKeys) => { return ( checkCompositePKsOnTransition(transitionToCompositeDto) || - checkCompositePKsOnEquality(_, newPrimaryKeys, oldPrimaryKeys) + checkCompositePKsOnEquality(newPrimaryKeys, oldPrimaryKeys) ); }; -const getCollectionNames = (_, collection) => { - const { getFullCollectionName, getSchemaOfAlterCollection, getEntityName } = require('../../../utils/general')(_); - +const getCollectionNames = collection => { const collectionSchema = getSchemaOfAlterCollection(collection); const fullTableName = getFullCollectionName(collectionSchema); const entityName = getEntityName(collectionSchema); @@ -259,14 +252,10 @@ const getCollectionNames = (_, collection) => { }; }; -const checkIsColumnsInCompositePKChanged = (newPKs, oldPKs) => { - const idx = []; -}; /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getAddCompositePkScriptDtos = (app, _, ddlProvider) => collection => { - const { getCompositePrimaryKeys } = require('../../keyHelper')(app); +const getAddCompositePkScriptDtos = ddlProvider => collection => { /** * @type {AlterCollectionRoleCompModPrimaryKey} * */ @@ -276,16 +265,16 @@ const getAddCompositePkScriptDtos = (app, _, ddlProvider) => collection => { if (newPrimaryKeys.length === 0 && oldPrimaryKeys.length === 0) { return []; } - const transitionToCompositeDto = wasCompositePkChangedInTransitionFromRegularToComposite(_)(collection); + const transitionToCompositeDto = wasCompositePkChangedInTransitionFromRegularToComposite(collection); - if (checkCompositePKsOnTransitionOrEquality(transitionToCompositeDto, _, newPrimaryKeys, oldPrimaryKeys)) { + if (checkCompositePKsOnTransitionOrEquality(transitionToCompositeDto, newPrimaryKeys, oldPrimaryKeys)) { return []; } - const { fullTableName } = getCollectionNames(_, collection); + const { fullTableName } = getCollectionNames(collection); return newPrimaryKeys - .map(_ => getCompositePrimaryKeys({ ...collection, ...(collection?.role || {}) }, true)[0]) + .map(_ => getCompositePrimaryKeys({ ...collection, ...collection?.role }, true)[0]) .filter(Boolean) .map(keyData => { const statementDto = ddlProvider.addPKConstraint( @@ -303,22 +292,20 @@ const getAddCompositePkScriptDtos = (app, _, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getDropCompositePkScriptDtos = (app, _, ddlProvider) => collection => { - const { wrapInBrackets } = require('../../../utils/general')(_); - +const getDropCompositePkScriptDtos = ddlProvider => collection => { const pkDto = collection?.role?.compMod?.primaryKey || {}; const newPrimaryKeys = pkDto.new || []; const oldPrimaryKeys = pkDto.old || []; if (newPrimaryKeys.length === 0 && oldPrimaryKeys.length === 0) { return []; } - const transitionToCompositeDto = wasCompositePkChangedInTransitionFromCompositeToRegular(_)(collection); + const transitionToCompositeDto = wasCompositePkChangedInTransitionFromCompositeToRegular(collection); - if (checkCompositePKsOnTransitionOrEquality(transitionToCompositeDto, _, newPrimaryKeys, oldPrimaryKeys)) { + if (checkCompositePKsOnTransitionOrEquality(transitionToCompositeDto, newPrimaryKeys, oldPrimaryKeys)) { return []; } - const { fullTableName, entityName } = getCollectionNames(_, collection); + const { fullTableName, entityName } = getCollectionNames(collection); return oldPrimaryKeys .map(oldPk => { @@ -336,9 +323,9 @@ const getDropCompositePkScriptDtos = (app, _, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getModifyCompositePkScriptDtos = (app, _, ddlProvider) => collection => { - const dropCompositePkScriptDtos = getDropCompositePkScriptDtos(app, _, ddlProvider)(collection); - const addCompositePkScriptDtos = getAddCompositePkScriptDtos(app, _, ddlProvider)(collection); +const getModifyCompositePkScriptDtos = ddlProvider => collection => { + const dropCompositePkScriptDtos = getDropCompositePkScriptDtos(ddlProvider)(collection); + const addCompositePkScriptDtos = getAddCompositePkScriptDtos(ddlProvider)(collection); return [...dropCompositePkScriptDtos, ...addCompositePkScriptDtos].filter(Boolean); }; @@ -365,7 +352,7 @@ const getConstraintNameForRegularPk = (columnJsonSchema, entityName) => { /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => boolean} * */ -const wasFieldChangedToBeARegularPk = _ => (columnJsonSchema, collection) => { +const wasFieldChangedToBeARegularPk = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldColumnJsonSchema = collection.role.properties[oldName]; @@ -378,7 +365,7 @@ const wasFieldChangedToBeARegularPk = _ => (columnJsonSchema, collection) => { /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => PkTransitionDto} * */ -const wasRegularPkChangedInTransitionFromCompositeToRegular = _ => (columnJsonSchema, collection) => { +const wasRegularPkChangedInTransitionFromCompositeToRegular = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldColumnJsonSchema = collection.role.properties[oldName]; @@ -429,7 +416,7 @@ const wasRegularPkChangedInTransitionFromCompositeToRegular = _ => (columnJsonSc /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => PkTransitionDto} * */ -const wasRegularPkChangedInTransitionFromRegularToComposite = _ => (columnJsonSchema, collection) => { +const wasRegularPkChangedInTransitionFromRegularToComposite = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldColumnJsonSchema = collection.role.properties[oldName]; @@ -480,7 +467,7 @@ const wasRegularPkChangedInTransitionFromRegularToComposite = _ => (columnJsonSc /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => boolean} * */ -const isFieldNoLongerARegularPk = _ => (columnJsonSchema, collection) => { +const isFieldNoLongerARegularPk = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldJsonSchema = collection.role.properties[oldName]; @@ -493,7 +480,7 @@ const isFieldNoLongerARegularPk = _ => (columnJsonSchema, collection) => { /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => boolean} * */ -const wasRegularPkModified = _ => (columnJsonSchema, collection) => { +const wasRegularPkModified = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldJsonSchema = collection.role.properties[oldName] || {}; @@ -512,28 +499,24 @@ const wasRegularPkModified = _ => (columnJsonSchema, collection) => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getAddPkScriptDtos = (app, _, ddlProvider) => collection => { - const { getFullCollectionName, getSchemaOfAlterCollection, getEntityName, wrapInBrackets, buildDefaultPKName } = - require('../../../utils/general')(_); - const { hydratePrimaryKeyOptions } = require('../../keyHelper')(app); - +const getAddPkScriptDtos = ddlProvider => collection => { const collectionSchema = getSchemaOfAlterCollection(collection); const fullTableName = getFullCollectionName(collectionSchema); const entityName = getEntityName(collectionSchema); return _.toPairs(collection.properties) .filter(([name, jsonSchema]) => { - if (wasFieldChangedToBeARegularPk(_)(jsonSchema, collection)) { + if (wasFieldChangedToBeARegularPk(jsonSchema, collection)) { return true; } - const transitionToRegularDto = wasRegularPkChangedInTransitionFromCompositeToRegular(_)( + const transitionToRegularDto = wasRegularPkChangedInTransitionFromCompositeToRegular( jsonSchema, collection, ); if (transitionToRegularDto.didTransitionHappen) { return transitionToRegularDto.wasPkChangedInTransition; } - return wasRegularPkModified(_)(jsonSchema, collection); + return wasRegularPkModified(jsonSchema, collection); }) .map(([name, jsonSchema]) => { let keyData = { @@ -561,27 +544,24 @@ const getAddPkScriptDtos = (app, _, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getDropPkScriptDto = (_, ddlProvider) => collection => { - const { getFullCollectionName, getSchemaOfAlterCollection, getEntityName, wrapInBrackets } = - require('../../../utils/general')(_); - +const getDropPkScriptDto = ddlProvider => collection => { const collectionSchema = getSchemaOfAlterCollection(collection); const fullTableName = getFullCollectionName(collectionSchema); const entityName = getEntityName(collectionSchema); return _.toPairs(collection.properties) .filter(([name, jsonSchema]) => { - if (isFieldNoLongerARegularPk(_)(jsonSchema, collection)) { + if (isFieldNoLongerARegularPk(jsonSchema, collection)) { return true; } - const transitionToRegularDto = wasRegularPkChangedInTransitionFromRegularToComposite(_)( + const transitionToRegularDto = wasRegularPkChangedInTransitionFromRegularToComposite( jsonSchema, collection, ); if (transitionToRegularDto.didTransitionHappen) { return transitionToRegularDto.wasPkChangedInTransition; } - return wasRegularPkModified(_)(jsonSchema, collection); + return wasRegularPkModified(jsonSchema, collection); }) .map(([name, jsonSchema]) => { const oldName = jsonSchema.compMod.oldField.name; @@ -597,9 +577,9 @@ const getDropPkScriptDto = (_, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getModifyPkScriptDtos = (app, _, ddlProvider) => collection => { - const dropPkScriptDtos = getDropPkScriptDto(_, ddlProvider)(collection); - const addPkScriptDtos = getAddPkScriptDtos(app, _, ddlProvider)(collection); +const getModifyPkScriptDtos = ddlProvider => collection => { + const dropPkScriptDtos = getDropPkScriptDto(ddlProvider)(collection); + const addPkScriptDtos = getAddPkScriptDtos(ddlProvider)(collection); return [...dropPkScriptDtos, ...addPkScriptDtos].filter(Boolean); }; @@ -624,9 +604,9 @@ const sortModifyPkConstraints = constraintDtos => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getModifyPkConstraintsScriptDtos = (app, _, ddlProvider) => collection => { - const modifyCompositePkScriptDtos = getModifyCompositePkScriptDtos(app, _, ddlProvider)(collection); - const modifyPkScriptDtos = getModifyPkScriptDtos(app, _, ddlProvider)(collection); +const getModifyPkConstraintsScriptDtos = ddlProvider => collection => { + const modifyCompositePkScriptDtos = getModifyCompositePkScriptDtos(ddlProvider)(collection); + const modifyPkScriptDtos = getModifyPkScriptDtos(ddlProvider)(collection); const allDtos = [...modifyCompositePkScriptDtos, ...modifyPkScriptDtos]; const sortedAllDtos = sortModifyPkConstraints(allDtos); diff --git a/forward_engineering/helpers/alterScriptHelpers/entityHelpers/uniqueConstraintHelper.js b/forward_engineering/helpers/alterScriptHelpers/entityHelpers/uniqueConstraintHelper.js index 78ae69ff..a7f3c152 100644 --- a/forward_engineering/helpers/alterScriptHelpers/entityHelpers/uniqueConstraintHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/entityHelpers/uniqueConstraintHelper.js @@ -1,4 +1,12 @@ +const _ = require('lodash'); const { AlterScriptDto } = require('../types/AlterScriptDto'); +const { + getFullCollectionName, + getSchemaOfAlterCollection, + getEntityName, + wrapInBrackets, +} = require('../../../utils/general'); +const { getCompositeUniqueKeys, hydrateUniqueOptions } = require('../../keyHelper'); class UniqueConstraintScriptModificationDto { /** @@ -48,9 +56,7 @@ const getDefaultUniqueConstraintName = (entityName, constraintName) => { * @param collection {AlterCollectionDto} * @return {object} * */ -const getCollectionNames = (_, collection) => { - const { getFullCollectionName, getSchemaOfAlterCollection, getEntityName } = require('../../../utils/general')(_); - +const getCollectionNames = collection => { const collectionSchema = getSchemaOfAlterCollection(collection); const fullTableName = getFullCollectionName(collectionSchema); const entityName = getEntityName(collectionSchema); @@ -66,7 +72,7 @@ const getCollectionNames = (_, collection) => { * @param oldConstraints {Array} * @return {boolean} * */ -const areUniqueConstraintsEqual = (_, newConstraints, oldConstraints) => { +const areUniqueConstraintsEqual = (newConstraints, oldConstraints) => { if (newConstraints.length !== oldConstraints.length) { return false; } @@ -76,9 +82,7 @@ const areUniqueConstraintsEqual = (_, newConstraints, oldConstraints) => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getAddCompositeUKScriptDtos = (app, _, ddlProvider) => collection => { - const { getCompositeUniqueKeys } = require('../../keyHelper')(app); - +const getAddCompositeUKScriptDtos = ddlProvider => collection => { const uniqueDto = collection?.role?.compMod?.uniqueKey || {}; const newUniqueConstraints = uniqueDto.new || []; const oldUniqueConstraints = uniqueDto.old || []; @@ -87,14 +91,14 @@ const getAddCompositeUKScriptDtos = (app, _, ddlProvider) => collection => { return []; } - if (areUniqueConstraintsEqual(_, newUniqueConstraints, oldUniqueConstraints)) { + if (areUniqueConstraintsEqual(newUniqueConstraints, oldUniqueConstraints)) { return []; } - const { fullTableName } = getCollectionNames(_, collection); + const { fullTableName } = getCollectionNames(collection); return newUniqueConstraints - .map(_ => getCompositeUniqueKeys({ ...collection, ...(collection?.role || {}) }, true)[0]) + .map(_ => getCompositeUniqueKeys({ ...collection, ...collection?.role }, true)[0]) .filter(Boolean) .map(keyData => { const statementDto = ddlProvider.addUniqueConstraint( @@ -118,9 +122,7 @@ const getAddCompositeUKScriptDtos = (app, _, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getDropCompositeUKScriptDtos = (app, _, ddlProvider) => collection => { - const { wrapInBrackets } = require('../../../utils/general')(_); - +const getDropCompositeUKScriptDtos = ddlProvider => collection => { const uniqueDto = collection?.role?.compMod?.uniqueKey || {}; const newUniqueConstraints = uniqueDto.new || []; const oldUniqueConstraints = uniqueDto.old || []; @@ -129,11 +131,11 @@ const getDropCompositeUKScriptDtos = (app, _, ddlProvider) => collection => { return []; } - if (areUniqueConstraintsEqual(_, newUniqueConstraints, oldUniqueConstraints)) { + if (areUniqueConstraintsEqual(newUniqueConstraints, oldUniqueConstraints)) { return []; } - const { fullTableName, entityName } = getCollectionNames(_, collection); + const { fullTableName, entityName } = getCollectionNames(collection); return oldUniqueConstraints .map(oldConstraint => { @@ -149,9 +151,9 @@ const getDropCompositeUKScriptDtos = (app, _, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getModifyCompositeUKScriptDtos = (app, _, ddlProvider) => collection => { - const dropUniqueConstraintScriptDtos = getDropCompositeUKScriptDtos(app, _, ddlProvider)(collection); - const addUniqueConstraintScriptDtos = getAddCompositeUKScriptDtos(app, _, ddlProvider)(collection); +const getModifyCompositeUKScriptDtos = ddlProvider => collection => { + const dropUniqueConstraintScriptDtos = getDropCompositeUKScriptDtos(ddlProvider)(collection); + const addUniqueConstraintScriptDtos = getAddCompositeUKScriptDtos(ddlProvider)(collection); return [...dropUniqueConstraintScriptDtos, ...addUniqueConstraintScriptDtos].filter(Boolean); }; @@ -200,7 +202,7 @@ const getConstraintNameForRegularUK = (columnJsonSchema, entityName, columnName) /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => boolean} * */ -const wasFieldChangedToBeARegularUK = _ => (columnJsonSchema, collection) => { +const wasFieldChangedToBeARegularUK = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldColumnJsonSchema = collection.role.properties[oldName]; @@ -213,7 +215,7 @@ const wasFieldChangedToBeARegularUK = _ => (columnJsonSchema, collection) => { /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => boolean} * */ -const isFieldNoLongerARegularUK = _ => (columnJsonSchema, collection) => { +const isFieldNoLongerARegularUK = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldJsonSchema = collection.role.properties[oldName]; @@ -226,7 +228,7 @@ const isFieldNoLongerARegularUK = _ => (columnJsonSchema, collection) => { /** * @return {(columnJsonSchema: AlterCollectionColumnDto, collection: AlterCollectionDto) => boolean} * */ -const wasRegularUKModified = _ => (columnJsonSchema, collection) => { +const wasRegularUKModified = (columnJsonSchema, collection) => { const oldName = columnJsonSchema.compMod.oldField.name; const oldJsonSchema = collection.role.properties[oldName] || {}; @@ -248,21 +250,17 @@ const wasRegularUKModified = _ => (columnJsonSchema, collection) => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getAddUKScriptDtos = (app, _, ddlProvider) => collection => { - const { getFullCollectionName, getSchemaOfAlterCollection, getEntityName, wrapInBrackets } = - require('../../../utils/general')(_); - const { hydrateUniqueOptions } = require('../../keyHelper')(app); - +const getAddUKScriptDtos = ddlProvider => collection => { const collectionSchema = getSchemaOfAlterCollection(collection); const fullTableName = getFullCollectionName(collectionSchema); const entityName = getEntityName(collectionSchema); return _.toPairs(collection.properties) .filter(([name, jsonSchema]) => { - if (wasFieldChangedToBeARegularUK(_)(jsonSchema, collection)) { + if (wasFieldChangedToBeARegularUK(jsonSchema, collection)) { return true; } - return wasRegularUKModified(_)(jsonSchema, collection); + return wasRegularUKModified(jsonSchema, collection); }) .map(([name, jsonSchema]) => { let keyData = { @@ -295,20 +293,17 @@ const getAddUKScriptDtos = (app, _, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getDropUKScriptDtos = (_, ddlProvider) => collection => { - const { getFullCollectionName, getSchemaOfAlterCollection, getEntityName, wrapInBrackets } = - require('../../../utils/general')(_); - +const getDropUKScriptDtos = ddlProvider => collection => { const collectionSchema = getSchemaOfAlterCollection(collection); const fullTableName = getFullCollectionName(collectionSchema); const entityName = getEntityName(collectionSchema); return _.toPairs(collection.properties) .filter(([name, jsonSchema]) => { - if (isFieldNoLongerARegularUK(_)(jsonSchema, collection)) { + if (isFieldNoLongerARegularUK(jsonSchema, collection)) { return true; } - return wasRegularUKModified(_)(jsonSchema, collection); + return wasRegularUKModified(jsonSchema, collection); }) .map(([name, jsonSchema]) => { const oldName = jsonSchema.compMod.oldField.name; @@ -324,9 +319,9 @@ const getDropUKScriptDtos = (_, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getModifyUKScriptDtos = (app, _, ddlProvider) => collection => { - const dropUKScriptDtos = getDropUKScriptDtos(_, ddlProvider)(collection); - const addUKScriptDtos = getAddUKScriptDtos(app, _, ddlProvider)(collection); +const getModifyUKScriptDtos = ddlProvider => collection => { + const dropUKScriptDtos = getDropUKScriptDtos(ddlProvider)(collection); + const addUKScriptDtos = getAddUKScriptDtos(ddlProvider)(collection); return [...dropUKScriptDtos, ...addUKScriptDtos].filter(Boolean); }; @@ -334,9 +329,9 @@ const getModifyUKScriptDtos = (app, _, ddlProvider) => collection => { /** * @return {(collection: AlterCollectionDto) => Array} * */ -const getModifyUniqueConstraintsScriptDtos = (app, _, ddlProvider) => collection => { - const modifyCompositeUKScriptDtos = getModifyCompositeUKScriptDtos(app, _, ddlProvider)(collection); - const modifyUKScriptDtos = getModifyUKScriptDtos(app, _, ddlProvider)(collection); +const getModifyUniqueConstraintsScriptDtos = ddlProvider => collection => { + const modifyCompositeUKScriptDtos = getModifyCompositeUKScriptDtos(ddlProvider)(collection); + const modifyUKScriptDtos = getModifyUKScriptDtos(ddlProvider)(collection); const allDtos = [...modifyCompositeUKScriptDtos, ...modifyUKScriptDtos]; const sortedDtos = sortModifyUniqueConstraints(allDtos); diff --git a/forward_engineering/helpers/applyToInstanceHelper.js b/forward_engineering/helpers/applyToInstanceHelper.js index 8b89bba5..db5cfb1b 100644 --- a/forward_engineering/helpers/applyToInstanceHelper.js +++ b/forward_engineering/helpers/applyToInstanceHelper.js @@ -1,3 +1,4 @@ +const _ = require('lodash'); const { connect } = require('../../reverse_engineering/api'); const { filterDeactivatedQuery, queryIsDeactivated } = require('./commentIfDeactivated'); @@ -11,7 +12,7 @@ const applyToInstance = async (connectionInfo, logger, app) => { if (!client.config.database) { throw new Error('No database specified'); } - const queries = getQueries(app, connectionInfo.script); + const queries = getQueries(connectionInfo.script); await async.mapSeries(queries, async query => { const message = `Query: ${query.split('\n').shift().substring(0, 150)}`; @@ -26,8 +27,7 @@ const applyToInstance = async (connectionInfo, logger, app) => { } }; -const getQueries = (app, script = '') => { - const _ = app.require('lodash'); +const getQueries = (script = '') => { script = filterDeactivatedQuery(script); return script .split('\n\n') diff --git a/forward_engineering/helpers/columnDefinitionHelper.js b/forward_engineering/helpers/columnDefinitionHelper.js index a9a75828..f6fb13ad 100644 --- a/forward_engineering/helpers/columnDefinitionHelper.js +++ b/forward_engineering/helpers/columnDefinitionHelper.js @@ -1,156 +1,152 @@ +const _ = require('lodash'); const templates = require('../configs/templates'); +const { assignTemplates } = require('../utils/assignTemplates'); +const { wrapInBrackets, escapeSpecialCharacters } = require('../utils/general'); -module.exports = app => { - const { assignTemplates } = app.require('@hackolade/ddl-fe-utils'); - const _ = app.require('lodash'); - const { wrapInBrackets, escapeSpecialCharacters } = require('../utils/general')(_); +const addLength = (type, length) => { + return `${type}(${length})`; +}; - const addLength = (type, length) => { - return `${type}(${length})`; - }; +const addMaxLength = type => { + return `${type}(MAX)`; +}; - const addMaxLength = type => { - return `${type}(MAX)`; - }; +const addScalePrecision = (type, precision, scale) => { + if (_.isNumber(scale)) { + return `${type}(${precision},${scale})`; + } - const addScalePrecision = (type, precision, scale) => { - if (_.isNumber(scale)) { - return `${type}(${precision},${scale})`; - } + return `${type}(${precision})`; +}; - return `${type}(${precision})`; - }; +const addPrecision = (type, precision) => { + return `${type}(${precision})`; +}; - const addPrecision = (type, precision) => { - return `${type}(${precision})`; - }; +const addXmlProperties = (type, constraint, schemaCollection) => { + if (!schemaCollection) { + return type; + } - const addXmlProperties = (type, constraint, schemaCollection) => { - if (!schemaCollection) { - return type; - } + if (constraint) { + return `${type}(${constraint} ${schemaCollection})`; + } - if (constraint) { - return `${type}(${constraint} ${schemaCollection})`; - } + return `${type}(${schemaCollection})`; +}; - return `${type}(${schemaCollection})`; - }; +const canHaveLength = type => ['CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR', 'BINARY', 'VARBINARY'].includes(type); - const canHaveLength = type => ['CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR', 'BINARY', 'VARBINARY'].includes(type); +const canHaveMax = type => ['VARCHAR', 'NVARCHAR', 'VARBINARY'].includes(type); - const canHaveMax = type => ['VARCHAR', 'NVARCHAR', 'VARBINARY'].includes(type); +const canHavePrecision = type => ['DECIMAL', 'NUMERIC', 'DATETIME2', 'DATETIMEOFFSET', 'TIME'].includes(type); - const canHavePrecision = type => ['DECIMAL', 'NUMERIC', 'DATETIME2', 'DATETIMEOFFSET', 'TIME'].includes(type); +const canHaveScale = type => ['DECIMAL', 'NUMERIC'].includes(type); - const canHaveScale = type => ['DECIMAL', 'NUMERIC'].includes(type); +const decorateType = (type, columnDefinition) => { + if (canHaveMax(type) && columnDefinition.hasMaxLength) { + return addMaxLength(type); + } else if (canHaveLength(type) && _.isNumber(columnDefinition.length)) { + return addLength(type, columnDefinition.length); + } else if (canHavePrecision(type) && canHaveScale(type) && _.isNumber(columnDefinition.precision)) { + return addScalePrecision(type, columnDefinition.precision, columnDefinition.scale); + } else if (canHavePrecision(type) && _.isNumber(columnDefinition.precision)) { + return addPrecision(type, columnDefinition.precision); + } else if (type === 'XML') { + return addXmlProperties(type, columnDefinition.xmlConstraint, columnDefinition.xmlSchemaCollection); + } - const decorateType = (type, columnDefinition) => { - if (canHaveMax(type) && columnDefinition.hasMaxLength) { - return addMaxLength(type); - } else if (canHaveLength(type) && _.isNumber(columnDefinition.length)) { - return addLength(type, columnDefinition.length); - } else if (canHavePrecision(type) && canHaveScale(type) && _.isNumber(columnDefinition.precision)) { - return addScalePrecision(type, columnDefinition.precision, columnDefinition.scale); - } else if (canHavePrecision(type) && _.isNumber(columnDefinition.precision)) { - return addPrecision(type, columnDefinition.precision); - } else if (type === 'XML') { - return addXmlProperties(type, columnDefinition.xmlConstraint, columnDefinition.xmlSchemaCollection); - } + return type; +}; - return type; - }; - - const isString = type => ['CHAR', 'VARCHAR', 'NCHAR', 'NVARCHAR', 'TEXT', 'NTEXT'].includes(_.toUpper(type)); - - /** - * Escape only inner single quotes. - * @param {string} str - * @returns {string} - */ - const escapeQuotes = str => _.trim(str).replace(/(\')+/g, "'$1"); - - const decorateDefault = (type, defaultValue) => { - if (type === 'XML') { - return `CAST(N'${defaultValue}' AS xml)`; - } - - return defaultValue; - }; - - const getIdentity = identity => { - if (!identity.seed || !identity.increment) { - return ''; - } - - return ` IDENTITY(${identity.seed}, ${identity.increment})`; - }; - - const addClustered = (statement, columnDefinition) => { - if (!columnDefinition.primaryKey && !columnDefinition.unique) { - return ''; - } - - if (!columnDefinition.clustered) { - return statement + ' NONCLUSTERED'; - } - - return statement + ' CLUSTERED'; - }; - - const getEncryptedWith = encryption => { - return ( - ' ENCRYPTED WITH (\n' + - '\t\tCOLUMN_ENCRYPTION_KEY=' + - encryption.key + - ',\n' + - '\t\tENCRYPTION_TYPE=' + - encryption.type + - ',\n' + - "\t\tALGORITHM='" + - encryption.algorithm + - "'\n" + - '\t)' - ); - }; - - const getColumnsComments = (tableName, terminator, columnDefinitions) => { - return columnDefinitions - .filter(({ comment }) => Boolean(comment)) - .map(({ comment, schemaName, name }) => { - if (!schemaName || !tableName) { - return ''; - } - const commentStatement = assignTemplates(templates.createColumnComment, { - value: escapeSpecialCharacters(comment), - schemaName: wrapInBrackets(schemaName), - tableName: wrapInBrackets(tableName), - columnName: wrapInBrackets(name), - terminator, - }); - - return commentStatement; - }) - .join('\n'); - }; - - /** - * - * @param {string} type - * @returns {boolean} - */ - const canHaveIdentity = type => { - const typesAllowedToHaveAutoIncrement = ['tinyint', 'smallint', 'int', 'bigint']; - return typesAllowedToHaveAutoIncrement.includes(type); - }; - - return { - decorateType, - decorateDefault, - getIdentity, - getEncryptedWith, - addClustered, - getColumnsComments, - canHaveIdentity, - }; +const isString = type => ['CHAR', 'VARCHAR', 'NCHAR', 'NVARCHAR', 'TEXT', 'NTEXT'].includes(_.toUpper(type)); + +/** + * Escape only inner single quotes. + * @param {string} str + * @returns {string} + */ +const escapeQuotes = str => _.trim(str).replace(/(\')+/g, "'$1"); + +const decorateDefault = (type, defaultValue) => { + if (type === 'XML') { + return `CAST(N'${defaultValue}' AS xml)`; + } + + return defaultValue; +}; + +const getIdentity = identity => { + if (!identity.seed || !identity.increment) { + return ''; + } + + return ` IDENTITY(${identity.seed}, ${identity.increment})`; +}; + +const addClustered = (statement, columnDefinition) => { + if (!columnDefinition.primaryKey && !columnDefinition.unique) { + return ''; + } + + if (!columnDefinition.clustered) { + return statement + ' NONCLUSTERED'; + } + + return statement + ' CLUSTERED'; +}; + +const getEncryptedWith = encryption => { + return ( + ' ENCRYPTED WITH (\n' + + '\t\tCOLUMN_ENCRYPTION_KEY=' + + encryption.key + + ',\n' + + '\t\tENCRYPTION_TYPE=' + + encryption.type + + ',\n' + + "\t\tALGORITHM='" + + encryption.algorithm + + "'\n" + + '\t)' + ); +}; + +const getColumnsComments = (tableName, terminator, columnDefinitions) => { + return columnDefinitions + .filter(({ comment }) => Boolean(comment)) + .map(({ comment, schemaName, name }) => { + if (!schemaName || !tableName) { + return ''; + } + + return assignTemplates(templates.createColumnComment, { + value: escapeSpecialCharacters(comment), + schemaName: wrapInBrackets(schemaName), + tableName: wrapInBrackets(tableName), + columnName: wrapInBrackets(name), + terminator, + }); + }) + .join('\n'); +}; + +/** + * + * @param {string} type + * @returns {boolean} + */ +const canHaveIdentity = type => { + const typesAllowedToHaveAutoIncrement = ['tinyint', 'smallint', 'int', 'bigint']; + return typesAllowedToHaveAutoIncrement.includes(type); +}; + +module.exports = { + decorateType, + decorateDefault, + getIdentity, + getEncryptedWith, + addClustered, + getColumnsComments, + canHaveIdentity, }; diff --git a/forward_engineering/helpers/commentIfDeactivated.js b/forward_engineering/helpers/commentIfDeactivated.js index 5bf38214..e5df0a87 100644 --- a/forward_engineering/helpers/commentIfDeactivated.js +++ b/forward_engineering/helpers/commentIfDeactivated.js @@ -1,5 +1,5 @@ const BEFORE_DEACTIVATED_STATEMENT = '-- '; -const REG_FOR_MULTYLINE_COMMENT = /(\n\/\*\n[\s\S]*?\n\s\*\/\n)|((\n\/\*\n[\s\S]*?\n\s\*\/)$)/gi; +const REG_FOR_MULTILINE_COMMENT = /(\n\/\*\n[\s\S]*?\n\s\*\/\n)|((\n\/\*\n[\s\S]*?\n\s\*\/)$)/gi; const commentIfDeactivated = (statement, data, isPartOfLine) => { if (data.isActivated === false) { @@ -14,7 +14,7 @@ const commentIfDeactivated = (statement, data, isPartOfLine) => { return statement; }; -const filterDeactivatedQuery = query => query.replace(REG_FOR_MULTYLINE_COMMENT, ''); +const filterDeactivatedQuery = query => query.replace(REG_FOR_MULTILINE_COMMENT, ''); const queryIsDeactivated = (query = '') => query.startsWith(BEFORE_DEACTIVATED_STATEMENT); diff --git a/forward_engineering/helpers/constraintsHelper.js b/forward_engineering/helpers/constraintsHelper.js index 346a237b..d494f2d2 100644 --- a/forward_engineering/helpers/constraintsHelper.js +++ b/forward_engineering/helpers/constraintsHelper.js @@ -1,168 +1,147 @@ +const _ = require('lodash'); const { commentIfDeactivated } = require('./commentIfDeactivated'); +const { checkAllKeysDeactivated, clean, divideIntoActivatedAndDeactivated } = require('../utils/general'); +const { assignTemplates } = require('../utils/assignTemplates'); +const { getRelationOptionsIndex } = require('./indexHelper'); +const { trimBraces } = require('./general'); -module.exports = app => { - const _ = app.require('lodash'); - const { assignTemplates } = app.require('@hackolade/ddl-fe-utils'); - const { checkAllKeysDeactivated, divideIntoActivatedAndDeactivated, clean } = - app.require('@hackolade/ddl-fe-utils').general; - const { getRelationOptionsIndex } = require('./indexHelper')(app); - const { trimBraces } = require('./general')(app); - - const createPKConstraint = - (templates, terminator, isParentActivated, isPKWithOptions, isAlterScript) => keyData => { - const isAllColumnsDeactivated = checkAllKeysDeactivated(keyData.columns || []); - - if (!isPKWithOptions && isAlterScript) { - return { - statement: assignTemplates(templates.createRegularPrimaryKeyConstraint, { - constraintName: keyData.constraintName, - columnName: keyData.columnName, - }), - isActivated: !isAllColumnsDeactivated, - }; - } - - return createKeyConstraint( - templates, - terminator, - isParentActivated, - isPKWithOptions, - isAlterScript, - )(keyData); - }; +const createPKConstraint = (templates, terminator, isParentActivated, isPKWithOptions, isAlterScript) => keyData => { + const isAllColumnsDeactivated = checkAllKeysDeactivated(keyData.columns || []); - const createUKConstraint = - (templates, terminator, isParentActivated, isUKWithOptions, isAlterScript) => keyData => { - const isAllColumnsDeactivated = checkAllKeysDeactivated(keyData.columns || []); - - if (!isUKWithOptions && isAlterScript) { - return { - statement: assignTemplates(templates.createRegularUniqueKeyConstraint, { - constraintName: keyData.constraintName, - columnName: keyData.columnName, - }), - isActivated: !isAllColumnsDeactivated, - }; - } - - return createKeyConstraint( - templates, - terminator, - isParentActivated, - isUKWithOptions, - isAlterScript, - )(keyData); + if (!isPKWithOptions && isAlterScript) { + return { + statement: assignTemplates(templates.createRegularPrimaryKeyConstraint, { + constraintName: keyData.constraintName, + columnName: keyData.columnName, + }), + isActivated: !isAllColumnsDeactivated, }; + } - const createKeyConstraint = - (templates, terminator, isParentActivated, isPKWithOptions, isAlterScript) => keyData => { - const isAllColumnsDeactivated = checkAllKeysDeactivated(keyData.columns || []); - const columns = getKeyColumns(isAllColumnsDeactivated, isParentActivated, keyData.columns); - const additionalConstraintStatement = isAlterScript ? '' : 'CONSTRAINT'; - - if (!keyDataHasOptions(keyData)) { - return { - statement: assignTemplates(templates.createKeyConstraint, { - constraintName: keyData.name ? `${additionalConstraintStatement}[${keyData.name}]` : '', - keyType: keyData.keyType, - clustered: '', - columns: '', - options: '', - partition: '', - terminator: '', - }), - isActivated: !isAllColumnsDeactivated, - }; - } - - const indexOptions = getRelationOptionsIndex(adaptIndexOptions(keyData.indexOption)); - const partition = keyData.partition ? ` ON [${keyData.partition}]` : ''; - - return { - statement: assignTemplates(templates.createKeyConstraint, { - constraintName: keyData.name ? `${additionalConstraintStatement} [${keyData.name}] ` : '', - keyType: keyData.keyType, - clustered: keyData.clustered ? ' CLUSTERED' : ' NONCLUSTERED', - columns, - options: indexOptions.length ? ' WITH (\n\t\t' + indexOptions.join(',\n\t\t') + '\n\t)' : '', - partition, - terminator, - }), - isActivated: !isAllColumnsDeactivated, - }; - }; + return createKeyConstraint(templates, terminator, isParentActivated, isPKWithOptions, isAlterScript)(keyData); +}; - const keyDataHasOptions = keyData => { - const indexOption = clean(keyData.indexOption); +const createUKConstraint = (templates, terminator, isParentActivated, isUKWithOptions, isAlterScript) => keyData => { + const isAllColumnsDeactivated = checkAllKeysDeactivated(keyData.columns || []); - if (!_.isEmpty(indexOption)) { - return true; - } + if (!isUKWithOptions && isAlterScript) { + return { + statement: assignTemplates(templates.createRegularUniqueKeyConstraint, { + constraintName: keyData.constraintName, + columnName: keyData.columnName, + }), + isActivated: !isAllColumnsDeactivated, + }; + } - const cleaned = clean(_.omit(keyData, 'keyType', 'indexOption', 'columns')); + return createKeyConstraint(templates, terminator, isParentActivated, isUKWithOptions, isAlterScript)(keyData); +}; - return !_.isEmpty(cleaned) || keyData.columns?.length; - }; +const createKeyConstraint = (templates, terminator, isParentActivated, isPKWithOptions, isAlterScript) => keyData => { + const isAllColumnsDeactivated = checkAllKeysDeactivated(keyData.columns || []); + const columns = getKeyColumns(isAllColumnsDeactivated, isParentActivated, keyData.columns); + const additionalConstraintStatement = isAlterScript ? '' : 'CONSTRAINT'; - const adaptIndexOptions = indexOption => { + if (!keyDataHasOptions(keyData)) { return { - ...indexOption, - allowRowLocks: Boolean(indexOption.allowRowLocks), - allowPageLocks: Boolean(indexOption.allowPageLocks), + statement: assignTemplates(templates.createKeyConstraint, { + constraintName: keyData.name ? `${additionalConstraintStatement}[${keyData.name}]` : '', + keyType: keyData.keyType, + clustered: '', + columns: '', + options: '', + partition: '', + terminator: '', + }), + isActivated: !isAllColumnsDeactivated, }; - }; + } - const createDefaultConstraint = (templates, terminator) => (constraintData, tableName) => { - return assignTemplates(templates.createDefaultConstraint, { - tableName, - constraintName: constraintData.constraintName, - columnName: constraintData.columnName, - default: trimBraces(constraintData.value), + const indexOptions = getRelationOptionsIndex(adaptIndexOptions(keyData.indexOption)); + const partition = keyData.partition ? ` ON [${keyData.partition}]` : ''; + + return { + statement: assignTemplates(templates.createKeyConstraint, { + constraintName: keyData.name ? `${additionalConstraintStatement} [${keyData.name}] ` : '', + keyType: keyData.keyType, + clustered: keyData.clustered ? ' CLUSTERED' : ' NONCLUSTERED', + columns, + options: indexOptions.length ? ' WITH (\n\t\t' + indexOptions.join(',\n\t\t') + '\n\t)' : '', + partition, terminator, - }); + }), + isActivated: !isAllColumnsDeactivated, }; +}; - const generateConstraintsString = (dividedConstraints, isParentActivated) => { - const deactivatedItemsAsString = commentIfDeactivated( - dividedConstraints.deactivatedItems.join(',\n\t'), - { isActivated: !isParentActivated }, - true, - ); - const activatedConstraints = dividedConstraints.activatedItems.length - ? ',\n\t' + dividedConstraints.activatedItems.join(',\n\t') - : ''; - - const deactivatedConstraints = dividedConstraints.deactivatedItems.length - ? '\n\t' + deactivatedItemsAsString - : ''; - - return activatedConstraints + deactivatedConstraints; - }; +const keyDataHasOptions = keyData => { + const indexOption = clean(keyData.indexOption); - const getKeyColumns = (isAllColumnsDeactivated, isParentActivated, columns) => { - if (!columns || columns.length === 0) { - return ''; - } - - const columnMapToString = ({ name, order }) => `[${name}] ${order}`.trim(); - const dividedColumns = divideIntoActivatedAndDeactivated(columns, columnMapToString); - const deactivatedColumnsAsString = dividedColumns?.deactivatedItems?.length - ? commentIfDeactivated(dividedColumns.deactivatedItems.join(', '), { - isActivated: false, - isPartOfLine: true, - }) - : ''; - - return !isAllColumnsDeactivated && isParentActivated - ? ' (' + dividedColumns.activatedItems.join(', ') + deactivatedColumnsAsString + ')' - : ' (' + columns.map(columnMapToString).join(', ') + ')'; - }; + if (!_.isEmpty(indexOption)) { + return true; + } + const cleaned = clean(_.omit(keyData, 'keyType', 'indexOption', 'columns')); + + return !_.isEmpty(cleaned) || keyData.columns?.length; +}; + +const adaptIndexOptions = indexOption => { return { - createDefaultConstraint, - createKeyConstraint, - createPKConstraint, - createUKConstraint, - generateConstraintsString, + ...indexOption, + allowRowLocks: Boolean(indexOption.allowRowLocks), + allowPageLocks: Boolean(indexOption.allowPageLocks), }; }; + +const createDefaultConstraint = (templates, terminator) => (constraintData, tableName) => { + return assignTemplates(templates.createDefaultConstraint, { + tableName, + constraintName: constraintData.constraintName, + columnName: constraintData.columnName, + default: trimBraces(constraintData.value), + terminator, + }); +}; + +const generateConstraintsString = (dividedConstraints, isParentActivated) => { + const deactivatedItemsAsString = commentIfDeactivated( + dividedConstraints.deactivatedItems.join(',\n\t'), + { isActivated: !isParentActivated }, + true, + ); + const activatedConstraints = dividedConstraints.activatedItems.length + ? ',\n\t' + dividedConstraints.activatedItems.join(',\n\t') + : ''; + + const deactivatedConstraints = dividedConstraints.deactivatedItems.length ? '\n\t' + deactivatedItemsAsString : ''; + + return activatedConstraints + deactivatedConstraints; +}; + +const getKeyColumns = (isAllColumnsDeactivated, isParentActivated, columns) => { + if (!columns || columns.length === 0) { + return ''; + } + + const columnMapToString = ({ name, order }) => `[${name}] ${order}`.trim(); + const dividedColumns = divideIntoActivatedAndDeactivated(columns, columnMapToString); + const deactivatedColumnsAsString = dividedColumns?.deactivatedItems?.length + ? commentIfDeactivated(dividedColumns.deactivatedItems.join(', '), { + isActivated: false, + isPartOfLine: true, + }) + : ''; + + return !isAllColumnsDeactivated && isParentActivated + ? ' (' + dividedColumns.activatedItems.join(', ') + deactivatedColumnsAsString + ')' + : ' (' + columns.map(columnMapToString).join(', ') + ')'; +}; + +module.exports = { + createDefaultConstraint, + createKeyConstraint, + createPKConstraint, + createUKConstraint, + generateConstraintsString, +}; diff --git a/forward_engineering/helpers/general.js b/forward_engineering/helpers/general.js index 257973fd..262e152e 100644 --- a/forward_engineering/helpers/general.js +++ b/forward_engineering/helpers/general.js @@ -1,285 +1,273 @@ +const _ = require('lodash'); const { commentIfDeactivated } = require('./commentIfDeactivated'); const types = require('../configs/types'); +const { checkAllKeysDeactivated, hasType: generalHasType } = require('../utils/general'); +const { decorateDefault } = require('./columnDefinitionHelper'); -module.exports = app => { - const _ = app.require('lodash'); - const generalHasType = app.require('@hackolade/ddl-fe-utils').general.hasType; - const { decorateDefault } = require('./columnDefinitionHelper')(app); - const { checkAllKeysDeactivated } = app.require('@hackolade/ddl-fe-utils').general; +const getTableName = (tableName, schemaName, brackets = true) => { + const withBrackets = name => (brackets ? `[${name}]` : name); - const getTableName = (tableName, schemaName, brackets = true) => { - const withBrackets = name => (brackets ? `[${name}]` : name); + if (schemaName) { + return `${withBrackets(schemaName)}.${withBrackets(tableName)}`; + } - if (schemaName) { - return `${withBrackets(schemaName)}.${withBrackets(tableName)}`; - } + return withBrackets(tableName); +}; - return withBrackets(tableName); - }; +const getDefaultValue = (defaultConstraint, type) => { + if (_.isUndefined(defaultConstraint.value)) { + return ''; + } - const getDefaultValue = (defaultConstraint, type) => { - if (_.isUndefined(defaultConstraint.value)) { - return ''; - } + const value = decorateDefault(type, defaultConstraint.value); - const value = decorateDefault(type, defaultConstraint.value); + if (!_.isUndefined(defaultConstraint.name)) { + return ` CONSTRAINT ${defaultConstraint.name} DEFAULT ${value}`; + } - if (!_.isUndefined(defaultConstraint.name)) { - return ` CONSTRAINT ${defaultConstraint.name} DEFAULT ${value}`; - } + return ` DEFAULT ${value}`; +}; - return ` DEFAULT ${value}`; - }; +const sanitizeConstraintName = str => { + return str ? str.replace(/\[|\]/g, '').replace(/\./g, '_') : str; +}; - const sanitizeConstraintName = str => { - return str ? str.replace(/\[|\]/g, '').replace(/\./g, '_') : str; - }; +const getKeyWithAlias = key => { + if (!key) { + return ''; + } - const getKeyWithAlias = key => { - if (!key) { - return ''; - } + if (key.alias) { + return `[${key.name}] as [${key.alias}]`; + } else { + return `[${key.name}]`; + } +}; - if (key.alias) { - return `[${key.name}] as [${key.alias}]`; - } else { - return `[${key.name}]`; - } - }; +const getSystemVersioning = options => { + let systemVersioning = 'SYSTEM_VERSIONING=ON'; - const getSystemVersioning = options => { - let systemVersioning = 'SYSTEM_VERSIONING=ON'; + if (!options.historyTable) { + return systemVersioning; + } - if (!options.historyTable) { - return systemVersioning; - } + let historyTable = `HISTORY_TABLE=${options.historyTable}`; - let historyTable = `HISTORY_TABLE=${options.historyTable}`; + if (options.dataConsistencyCheck) { + historyTable += ', DATA_CONSISTENCY_CHECK=ON'; + } - if (options.dataConsistencyCheck) { - historyTable += ', DATA_CONSISTENCY_CHECK=ON'; - } + return `${systemVersioning} (${historyTable})`; +}; - return `${systemVersioning} (${historyTable})`; - }; +const getLedger = options => { + let ledger = 'LEDGER=ON'; - const getLedger = options => { - let ledger = 'LEDGER=ON'; + if (!options.ledger_view && !options.append_only) { + return ledger; + } - if (!options.ledger_view && !options.append_only) { - return ledger; - } + let optionsStrings = []; - let optionsStrings = []; + if (options.ledger_view) { + optionsStrings.push(`${getLedgerView(options)}`); + } - if (options.ledger_view) { - optionsStrings.push(`${getLedgerView(options)}`); - } + if (options.append_only) { + optionsStrings.push('APPEND_ONLY=ON'); + } - if (options.append_only) { - optionsStrings.push('APPEND_ONLY=ON'); - } + return `${ledger} (\n\t\t${optionsStrings.join(',\n\t\t')}\n\t)`; +}; - return `${ledger} (\n\t\t${optionsStrings.join(',\n\t\t')}\n\t)`; - }; +const getLedgerView = options => { + let viewOptions = []; + if (options.transaction_id_column_name) { + viewOptions.push(`\n\t\t\tTRANSACTION_ID_COLUMN_NAME=${options.transaction_id_column_name}`); + } + if (options.sequence_number_column_name) { + viewOptions.push(`\n\t\t\tSEQUENCE_NUMBER_COLUMN_NAME=${options.sequence_number_column_name}`); + } + if (options.operation_type_id_column_name) { + viewOptions.push(`\n\t\t\tOPERATION_TYPE_COLUMN_NAME=${options.operation_type_id_column_name}`); + } + if (options.operation_type_desc_column_name) { + viewOptions.push(`\n\t\t\tOPERATION_TYPE_DESC_COLUMN_NAME=${options.operation_type_desc_column_name}`); + } + const optionsString = _.isEmpty(viewOptions) ? '' : ` (${viewOptions.join(',')}\n\t\t)`; + return `LEDGER_VIEW=${options.ledger_view}${optionsString}`; +}; - const getLedgerView = options => { - let viewoptions = []; - if (options.transaction_id_column_name) { - viewoptions.push(`\n\t\t\tTRANSACTION_ID_COLUMN_NAME=${options.transaction_id_column_name}`); - } - if (options.sequence_number_column_name) { - viewoptions.push(`\n\t\t\tSEQUENCE_NUMBER_COLUMN_NAME=${options.sequence_number_column_name}`); - } - if (options.operation_type_id_column_name) { - viewoptions.push(`\n\t\t\tOPERATION_TYPE_COLUMN_NAME=${options.operation_type_id_column_name}`); - } - if (options.operation_type_desc_column_name) { - viewoptions.push(`\n\t\t\tOPERATION_TYPE_DESC_COLUMN_NAME=${options.operation_type_desc_column_name}`); +const getTableOptions = options => { + if (!options) { + return ''; + } + + if (options.memory_optimized) { + let withOptions = ' WITH (\n\tMEMORY_OPTIMIZED=ON'; + + if (options.durability) { + withOptions += ',\n\tDURABILITY=' + options.durability; } - const optionsString = !_.isEmpty(viewoptions) ? ` (${viewoptions.join(',')}\n\t\t)` : ''; - return `LEDGER_VIEW=${options.ledger_view}${optionsString}`; - }; - const getTableOptions = options => { - if (!options) { - return ''; + if (options.systemVersioning) { + withOptions += ',\n\t' + getSystemVersioning(options); } - if (options.memory_optimized) { - let withOptions = ' WITH (\n\tMEMORY_OPTIMIZED=ON'; + return withOptions + '\n)'; + } - if (options.durability) { - withOptions += ',\n\tDURABILITY=' + options.durability; - } + if (!options.temporal) { + return ''; + } - if (options.systemVersioning) { - withOptions += ',\n\t' + getSystemVersioning(options); - } + let optionsStrings = `WITH (\n\t${getSystemVersioning(options)}`; - return withOptions + '\n)'; - } + if (options.ledger) { + optionsStrings += ',\n\t' + getLedger(options); + } - if (!options.temporal) { - return ''; - } + return `${optionsStrings}\n)`; +}; - let optionsStrings = `WITH (\n\t${getSystemVersioning(options)}`; +const hasType = type => { + return generalHasType(types, type); +}; - if (options.ledger) { - optionsStrings += ',\n\t' + getLedger(options); - } +const getViewData = (keys, schemaData) => { + if (!Array.isArray(keys)) { + return { tables: [], columns: [] }; + } - return `${optionsStrings}\n)`; - }; + return keys.reduce( + (result, key) => { + if (!key.tableName) { + result.columns.push(getKeyWithAlias(key)); - const hasType = type => { - return generalHasType(types, type); - }; + return result; + } - const getViewData = (keys, schemaData) => { - if (!Array.isArray(keys)) { - return { tables: [], columns: [] }; + let tableName = getTableName(key.tableName, key.schemaName); + + if (key.dbName && key.dbName !== schemaData.databaseName) { + tableName = `[${key.dbName}].` + tableName; + } + + if (!result.tables.includes(tableName)) { + result.tables.push(tableName); + } + + result.columns.push({ + statement: `${tableName}.${getKeyWithAlias(key)}`, + isActivated: key.isActivated, + }); + + return result; + }, + { + tables: [], + columns: [], + }, + ); +}; + +const filterColumnStoreProperties = index => { + if (index.type !== 'columnstore') { + return index; + } + const unsupportedProperties = new Set([ + 'allowRowLocks', + 'allowPageLocks', + 'padIndex', + 'fillFactor', + 'ignoreDuplicateKey', + ]); + + return Object.keys(index).reduce((result, property) => { + if (unsupportedProperties.has(property)) { + return result; + } else { + return { ...result, [property]: index[property] }; } + }, {}); +}; - return keys.reduce( - (result, key) => { - if (!key.tableName) { - result.columns.push(getKeyWithAlias(key)); +const foreignKeysToString = keys => { + if (Array.isArray(keys)) { + const activatedKeys = keys.filter(key => _.get(key, 'isActivated', true)).map(key => `[${key.name.trim()}]`); + const deactivatedKeys = keys.filter(key => !_.get(key, 'isActivated', true)).map(key => `[${key.name.trim()}]`); + const deactivatedKeysAsString = deactivatedKeys.length + ? commentIfDeactivated(deactivatedKeys, { isActivated: false }, true) + : ''; + + return activatedKeys.join(', ') + deactivatedKeysAsString; + } + return keys; +}; - return result; - } +const foreignActiveKeysToString = keys => { + return keys.map(key => key.name.trim()).join(', '); +}; - let tableName = getTableName(key.tableName, key.schemaName); +const additionalPropertiesForForeignKey = relationship => { + const foreignOnDelete = _.get(relationship, 'relationshipOnDelete', ''); + const foreignOnUpdate = _.get(relationship, 'relationshipOnUpdate', ''); + return { foreignOnDelete, foreignOnUpdate }; +}; - if (key.dbName && key.dbName !== schemaData.databaseName) { - tableName = `[${key.dbName}].` + tableName; - } +const trimBraces = expression => + /^\(([\s\S]+?)\)$/i.test(_.trim(expression)) ? _.trim(expression).replace(/^\(([\s\S]+?)\)$/i, '$1') : expression; - if (!result.tables.includes(tableName)) { - result.tables.push(tableName); - } +const checkIndexActivated = index => { + if (index.isActivated === false) { + return false; + } - result.columns.push({ - statement: `${tableName}.${getKeyWithAlias(key)}`, - isActivated: key.isActivated, - }); + const isAllKeysDeactivated = checkAllKeysDeactivated(_.get(index, 'keys', [])); + const isAllIncludesDeactivated = checkAllKeysDeactivated(_.get(index, 'include', [])); + const isColumnDeactivated = !_.get(index, 'column.isActivated', true); - return result; - }, - { - tables: [], - columns: [], - }, - ); - }; - - const filterColumnStoreProperties = index => { - if (index.type !== 'columnstore') { - return index; - } - const unsupportedProperties = [ - 'allowRowLocks', - 'allowPageLocks', - 'padIndex', - 'fillFactor', - 'ignoreDuplicateKey', - ]; - - return Object.keys(index).reduce((result, property) => { - if (unsupportedProperties.includes(property)) { - return result; - } else { - return Object.assign({}, result, { - [property]: index[property], - }); - } - }, {}); - }; - - const foreignKeysToString = keys => { - if (Array.isArray(keys)) { - const activatedKeys = keys - .filter(key => _.get(key, 'isActivated', true)) - .map(key => `[${key.name.trim()}]`); - const deactivatedKeys = keys - .filter(key => !_.get(key, 'isActivated', true)) - .map(key => `[${key.name.trim()}]`); - const deactivatedKeysAsString = deactivatedKeys.length - ? commentIfDeactivated(deactivatedKeys, { isActivated: false }, true) - : ''; - - return activatedKeys.join(', ') + deactivatedKeysAsString; - } - return keys; - }; - - const foreignActiveKeysToString = keys => { - return keys.map(key => key.name.trim()).join(', '); - }; - - const additionalPropertiesForForeignKey = relationship => { - const foreignOnDelete = _.get(relationship, 'relationshipOnDelete', ''); - const foreignOnUpdate = _.get(relationship, 'relationshipOnUpdate', ''); - return { foreignOnDelete, foreignOnUpdate }; - }; - - const trimBraces = expression => - /^\(([\s\S]+?)\)$/i.test(_.trim(expression)) - ? _.trim(expression).replace(/^\(([\s\S]+?)\)$/i, '$1') - : expression; - - const checkIndexActivated = index => { - if (index.isActivated === false) { - return false; - } + return !isAllKeysDeactivated && !isAllIncludesDeactivated && !isColumnDeactivated; +}; - const isAllKeysDeactivated = checkAllKeysDeactivated(_.get(index, 'keys', [])); - const isAllIncludesDeactivated = checkAllKeysDeactivated(_.get(index, 'include', [])); - const isColumnDeactivated = !_.get(index, 'column.isActivated', true); +const getTempTableTime = (isTempTableStartTimeColumn, isTempTableEndTimeColumn, isHidden) => { + if (isTempTableStartTimeColumn) { + return ` GENERATED ALWAYS AS ROW START${isHidden ? ' HIDDEN' : ''}`; + } + if (isTempTableEndTimeColumn) { + return ` GENERATED ALWAYS AS ROW END${isHidden ? ' HIDDEN' : ''}`; + } + return ''; +}; - return !isAllKeysDeactivated && !isAllIncludesDeactivated && !isColumnDeactivated; - }; +/** + * @param {Object} params + * @param {string} params.primaryTableName + * @param {string} params.foreignTableName + * @param {Array} params.primaryTableColumns + * @param {Array} params.foreignTableColumns + * @returns {string} + */ +const getFKConstraintName = ({ primaryTableName, foreignTableName, primaryTableColumns, foreignTableColumns }) => { + return sanitizeConstraintName( + `FK_${[primaryTableName, foreignTableColumns.map(k => k.name).join('_'), foreignTableName, primaryTableColumns.map(k => k.name).join('_')].filter(Boolean).join('_')}`, + ); +}; - const getTempTableTime = (isTempTableStartTimeColumn, isTempTableEndTimeColumn, isHidden) => { - if (isTempTableStartTimeColumn) { - return ` GENERATED ALWAYS AS ROW START${isHidden ? ' HIDDEN' : ''}`; - } - if (isTempTableEndTimeColumn) { - return ` GENERATED ALWAYS AS ROW END${isHidden ? ' HIDDEN' : ''}`; - } - return ''; - }; - - /** - * @param {Object} params - * @param {string} params.primaryTableName - * @param {string} params.foreignTableName - * @param {Array} params.primaryTableColumns - * @param {Array} params.foreignTableColumns - * @returns {string} - */ - const getFKConstraintName = ({ primaryTableName, foreignTableName, primaryTableColumns, foreignTableColumns }) => { - return sanitizeConstraintName( - `FK_${[primaryTableName, foreignTableColumns.map(k => k.name).join('_'), foreignTableName, primaryTableColumns.map(k => k.name).join('_')].filter(Boolean).join('_')}`, - ); - }; - - return { - filterColumnStoreProperties, - getKeyWithAlias, - getTableName, - getTableOptions, - hasType, - getViewData, - foreignKeysToString, - additionalPropertiesForForeignKey, - trimBraces, - sanitizeConstraintName, - checkIndexActivated, - foreignActiveKeysToString, - getDefaultValue, - getTempTableTime, - getFKConstraintName, - }; +module.exports = { + filterColumnStoreProperties, + getKeyWithAlias, + getTableName, + getTableOptions, + hasType, + getViewData, + foreignKeysToString, + additionalPropertiesForForeignKey, + trimBraces, + sanitizeConstraintName, + checkIndexActivated, + foreignActiveKeysToString, + getDefaultValue, + getTempTableTime, + getFKConstraintName, }; diff --git a/forward_engineering/helpers/ifNotExistStatementHelper.js b/forward_engineering/helpers/ifNotExistStatementHelper.js index e255078b..f339358d 100644 --- a/forward_engineering/helpers/ifNotExistStatementHelper.js +++ b/forward_engineering/helpers/ifNotExistStatementHelper.js @@ -1,44 +1,42 @@ -module.exports = app => { - const _ = app.require('lodash'); - const { assignTemplates } = app.require('@hackolade/ddl-fe-utils'); - const { tab } = app.require('@hackolade/ddl-fe-utils').general; +const _ = require('lodash'); +const { assignTemplates } = require('../utils/assignTemplates'); +const { tab } = require('../utils/general'); - const wrapIfNotExistSchema = ({ templates, schemaStatement, schemaName, terminator }) => { - return assignTemplates(templates.ifNotExistSchema, { - statement: _.trim(tab(schemaStatement)), - schemaName, - terminator, - }); - }; +const wrapIfNotExistSchema = ({ templates, schemaStatement, schemaName, terminator }) => { + return assignTemplates(templates.ifNotExistSchema, { + statement: _.trim(tab(schemaStatement)), + schemaName, + terminator, + }); +}; - const wrapIfNotExistDatabase = ({ templates, databaseStatement, databaseName, terminator }) => { - return assignTemplates(templates.ifNotExistDatabase, { - statement: tab(databaseStatement), - databaseName, - terminator, - }); - }; +const wrapIfNotExistDatabase = ({ templates, databaseStatement, databaseName, terminator }) => { + return assignTemplates(templates.ifNotExistDatabase, { + statement: tab(databaseStatement), + databaseName, + terminator, + }); +}; - const wrapIfNotExistTable = ({ templates, tableStatement, tableName, terminator }) => { - return assignTemplates(templates.ifNotExistTable, { - statement: tab(tableStatement), - tableName, - terminator, - }); - }; +const wrapIfNotExistTable = ({ templates, tableStatement, tableName, terminator }) => { + return assignTemplates(templates.ifNotExistTable, { + statement: tab(tableStatement), + tableName, + terminator, + }); +}; - const wrapIfNotExistView = ({ templates, viewStatement, viewName, terminator }) => { - return assignTemplates(templates.ifNotExistView, { - statement: tab(viewStatement), - viewName, - terminator, - }); - }; +const wrapIfNotExistView = ({ templates, viewStatement, viewName, terminator }) => { + return assignTemplates(templates.ifNotExistView, { + statement: tab(viewStatement), + viewName, + terminator, + }); +}; - return { - wrapIfNotExistSchema, - wrapIfNotExistDatabase, - wrapIfNotExistTable, - wrapIfNotExistView, - }; +module.exports = { + wrapIfNotExistSchema, + wrapIfNotExistDatabase, + wrapIfNotExistTable, + wrapIfNotExistView, }; diff --git a/forward_engineering/helpers/indexHelper.js b/forward_engineering/helpers/indexHelper.js index 57de3404..94364482 100644 --- a/forward_engineering/helpers/indexHelper.js +++ b/forward_engineering/helpers/indexHelper.js @@ -1,467 +1,460 @@ +const _ = require('lodash'); const templates = require('../configs/templates'); const { commentIfDeactivated } = require('./commentIfDeactivated'); +const { filterColumnStoreProperties, getTableName } = require('./general'); +const { assignTemplates } = require('../utils/assignTemplates'); +const { divideIntoActivatedAndDeactivated, checkAllKeysDeactivated } = require('../utils/general'); + const BOUNDING_BOX_LABEL = ['XMIN', 'YMIN', 'XMAX', 'YMAX']; -module.exports = app => { - const _ = app.require('lodash'); - const { filterColumnStoreProperties, getTableName } = require('./general')(app); - const { assignTemplates } = app.require('@hackolade/ddl-fe-utils'); - const { divideIntoActivatedAndDeactivated, checkAllKeysDeactivated } = - app.require('@hackolade/ddl-fe-utils').general; +const trimBraces = expression => + /^\(([\s\S]+?)\)$/i.test(_.trim(expression)) ? _.trim(expression).replace(/^\(([\s\S]+?)\)$/i, '$1') : expression; - const trimBraces = expression => - /^\(([\s\S]+?)\)$/i.test(_.trim(expression)) - ? _.trim(expression).replace(/^\(([\s\S]+?)\)$/i, '$1') - : expression; +const getRelationOptionsIndex = index => { + let result = []; - const getRelationOptionsIndex = index => { - let result = []; + if (index.padIndex) { + result.push('PAD_INDEX = ON'); + } - if (index.padIndex) { - result.push('PAD_INDEX = ON'); - } + if (index.fillFactor) { + result.push('FILLFACTOR = ' + index.fillFactor); + } - if (index.fillFactor) { - result.push('FILLFACTOR = ' + index.fillFactor); - } + if (index.ignoreDuplicateKey) { + result.push('IGNORE_DUP_KEY = ON'); + } - if (index.ignoreDuplicateKey) { - result.push('IGNORE_DUP_KEY = ON'); - } + if (index.statisticsNoRecompute) { + result.push('STATISTICS_NORECOMPUTE = ON'); + } - if (index.statisticsNoRecompute) { - result.push('STATISTICS_NORECOMPUTE = ON'); - } + if (index.statisticsIncremental) { + result.push('STATISTICS_INCREMENTAL = ON'); + } - if (index.statisticsIncremental) { - result.push('STATISTICS_INCREMENTAL = ON'); - } + if (index.allowRowLocks === false) { + result.push('ALLOW_ROW_LOCKS = OFF'); + } - if (index.allowRowLocks === false) { - result.push('ALLOW_ROW_LOCKS = OFF'); - } + if (index.allowPageLocks === false) { + result.push('ALLOW_PAGE_LOCKS = OFF'); + } - if (index.allowPageLocks === false) { - result.push('ALLOW_PAGE_LOCKS = OFF'); - } + if (index.optimizeForSequentialKey) { + result.push('OPTIMIZE_FOR_SEQUENTIAL_KEY = ON'); + } - if (index.optimizeForSequentialKey) { - result.push('OPTIMIZE_FOR_SEQUENTIAL_KEY = ON'); - } + if (index.type === 'columnstore' && index.compressionDelay) { + result.push('COMPRESSION_DELAY = ' + index.compressionDelay); + } - if (index.type === 'columnstore' && index.compressionDelay) { - result.push('COMPRESSION_DELAY = ' + index.compressionDelay); - } + if (index.dataCompression && index.dataCompression !== 'NONE') { + result.push('DATA_COMPRESSION = ' + index.dataCompression); + } - if (index.dataCompression && index.dataCompression !== 'NONE') { - result.push('DATA_COMPRESSION = ' + index.dataCompression); - } + return result; +}; - return result; - }; +const createIndex = (terminator, tableName, index, isParentActivated = true) => { + const isInvalidColumnStore = index.type !== 'columnstore' || (index.type === 'columnstore' && !index.clustered); - const createIndex = (terminator, tableName, index, isParentActivated = true) => { - const isInvalidColumnStore = index.type !== 'columnstore' || (index.type === 'columnstore' && !index.clustered); + if ((_.isEmpty(index.keys) && isInvalidColumnStore) || !index.name) { + return ''; + } - if ((_.isEmpty(index.keys) && isInvalidColumnStore) || !index.name) { - return ''; - } - - const include = - Array.isArray(index.include) && !_.isEmpty(index.include) - ? `\n\tINCLUDE (${_.concat(index.include, index.includedColumn).map(key => - isParentActivated ? commentIfDeactivated(`[${key.name}]`, key, true) : `[${key.name}]`, - )})` - : ''; - const relationalIndexOption = getRelationOptionsIndex(index); - - const dividedKeys = divideIntoActivatedAndDeactivated( - index.keys, - key => `[${key.name}]` + (_.toLower(key.type) === 'descending' ? ' DESC' : ''), - ); - const commentedKeys = dividedKeys.deactivatedItems.length - ? commentIfDeactivated(dividedKeys.deactivatedItems.join(', '), { isActivated: false }, true) + const include = + Array.isArray(index.include) && !_.isEmpty(index.include) + ? `\n\tINCLUDE (${_.concat(index.include, index.includedColumn).map(key => + isParentActivated ? commentIfDeactivated(`[${key.name}]`, key, true) : `[${key.name}]`, + )})` : ''; + const relationalIndexOption = getRelationOptionsIndex(index); + + const dividedKeys = divideIntoActivatedAndDeactivated( + index.keys, + key => `[${key.name}]` + (_.toLower(key.type) === 'descending' ? ' DESC' : ''), + ); + const commentedKeys = dividedKeys.deactivatedItems.length + ? commentIfDeactivated(dividedKeys.deactivatedItems.join(', '), { isActivated: false }, true) + : ''; + + const activatedKeys = dividedKeys.activatedItems.join(', '); + const deactivatedKeys = dividedKeys.deactivatedItems.join(', '); + + let keys = activatedKeys + commentedKeys; + + if (!isParentActivated) { + keys = activatedKeys + (activatedKeys && deactivatedKeys ? ', ' : '') + deactivatedKeys; + } + + return assignTemplates(templates.index, { + name: index.name, + unique: index.unique ? ' UNIQUE' : '', + clustered: index.clustered ? ' CLUSTERED' : '', + table: getTableName(tableName, index.schemaName), + keys: dividedKeys.activatedItems.length || commentedKeys.length ? ` ( ${keys} )` : '', + columnstore: index.type === 'columnstore' ? ' COLUMNSTORE' : '', + relational_index_option: relationalIndexOption.length + ? '\n\tWITH (\n\t\t' + relationalIndexOption.join(',\n\t\t') + '\n\t)' + : '', + include, + expression: index.filterExpression ? `\n\tWHERE ${trimBraces(index.filterExpression)}\n` : '', + terminator, + }); +}; - const activatedKeys = dividedKeys.activatedItems.join(', '); - const deactivatedKeys = dividedKeys.deactivatedItems.join(', '); +const getFulltextCatalog = ({ catalogName, fileGroup }) => { + if (catalogName && fileGroup) { + return `(${catalogName}, FILEGROUP ${fileGroup})`; + } else if (catalogName) { + return catalogName; + } else if (fileGroup) { + return `(FILEGROUP ${fileGroup})`; + } else { + return ''; + } +}; - let keys = activatedKeys + commentedKeys; +const getFullTextOptions = ({ changeTracking, stopList, searchPropertyList }) => { + let options = []; - if (!isParentActivated) { - keys = activatedKeys + (activatedKeys && deactivatedKeys ? ', ' : '') + deactivatedKeys; - } + if (changeTracking) { + options.push(`CHANGE_TRACKING=${changeTracking}`); + } - return assignTemplates(templates.index, { - name: index.name, - unique: index.unique ? ' UNIQUE' : '', - clustered: index.clustered ? ' CLUSTERED' : '', - table: getTableName(tableName, index.schemaName), - keys: dividedKeys.activatedItems.length || commentedKeys.length ? ` ( ${keys} )` : '', - columnstore: index.type === 'columnstore' ? ' COLUMNSTORE' : '', - relational_index_option: relationalIndexOption.length - ? '\n\tWITH (\n\t\t' + relationalIndexOption.join(',\n\t\t') + '\n\t)' - : '', - include, - expression: index.filterExpression ? `\n\tWHERE ${trimBraces(index.filterExpression)}\n` : '', - terminator, - }); - }; + if (stopList) { + options.push(`STOPLIST=${stopList}`); + } - const getFulltextCatalog = ({ catalogName, fileGroup }) => { - if (catalogName && fileGroup) { - return `(${catalogName}, FILEGROUP ${fileGroup})`; - } else if (catalogName) { - return catalogName; - } else if (fileGroup) { - return `(FILEGROUP ${fileGroup})`; - } else { - return ''; - } - }; + if (searchPropertyList) { + options.push(`SEARCH PROPERTY LIST=${searchPropertyList}`); + } - const getFullTextOptions = ({ changeTracking, stopList, searchPropertyList }) => { - let options = []; + return options.join(',\n\t'); +}; - if (changeTracking) { - options.push(`CHANGE_TRACKING=${changeTracking}`); - } +const createFullTextIndex = (terminator, tableName, index, isParentActivated) => { + if (!index.keyIndex) { + return ''; + } + const catalog = getFulltextCatalog(index); + const options = getFullTextOptions(index); - if (stopList) { - options.push(`STOPLIST=${stopList}`); - } + const keys = index.keys + .map(key => { + let column = `[${key.name}]`; - if (searchPropertyList) { - options.push(`SEARCH PROPERTY LIST=${searchPropertyList}`); - } + if (key.columnType) { + column += ` TYPE COLUMN ${key.columnType}`; + } - return options.join(',\n\t'); - }; + if (key.languageTerm) { + column += ` LANGUAGE ${key.languageTerm}`; + } - const createFullTextIndex = (terminator, tableName, index, isParentActivated) => { - if (!index.keyIndex) { - return ''; - } - const catalog = getFulltextCatalog(index); - const options = getFullTextOptions(index); - - const keys = index.keys - .map(key => { - let column = `[${key.name}]`; - - if (key.columnType) { - column += ` TYPE COLUMN ${key.columnType}`; - } - - if (key.languageTerm) { - column += ` LANGUAGE ${key.languageTerm}`; - } - - if (key.statisticalSemantics) { - column += ` STATISTICAL_SEMANTICS`; - } - - return isParentActivated ? commentIfDeactivated(column, key) : column; - }) - .join(',\n\t'); - - return assignTemplates(templates.fullTextIndex, { - table: getTableName(tableName, index.schemaName), - keys: keys ? ` (\n\t${keys}\n)` : '', - indexName: index.keyIndex, - catalog: catalog ? `ON ${catalog}\n` : '', - options: options ? `WITH (\n\t${options}\n)` : '', - terminator, - }); - }; + if (key.statisticalSemantics) { + column += ` STATISTICAL_SEMANTICS`; + } - const getSpatialOptions = indexData => { - const general = getRelationOptionsIndex(indexData); - const createBoundingGrids = (keys, data = {}) => - keys - .filter(key => Boolean(data[key]) || data[key] === 0) - .map(key => `${key} = ${data[key]}`) - .join(', '); + return isParentActivated ? commentIfDeactivated(column, key) : column; + }) + .join(',\n\t'); + + return assignTemplates(templates.fullTextIndex, { + table: getTableName(tableName, index.schemaName), + keys: keys ? ` (\n\t${keys}\n)` : '', + indexName: index.keyIndex, + catalog: catalog ? `ON ${catalog}\n` : '', + options: options ? `WITH (\n\t${options}\n)` : '', + terminator, + }); +}; - if (indexData.cellsPerObject) { - general.unshift(`CELLS_PER_OBJECT = ${indexData.cellsPerObject}`); - } +const getSpatialOptions = indexData => { + const general = getRelationOptionsIndex(indexData); + const createBoundingGrids = (keys, data = {}) => + keys + .filter(key => Boolean(data[key]) || data[key] === 0) + .map(key => `${key} = ${data[key]}`) + .join(', '); + + if (indexData.cellsPerObject) { + general.unshift(`CELLS_PER_OBJECT = ${indexData.cellsPerObject}`); + } + + if (indexData.sortInTempdb) { + general.unshift(`SORT_IN_TEMPDB = ON`); + } + + if (indexData.dropExisting) { + general.unshift(`DROP_EXISTING = ON`); + } + + if (indexData.maxdop) { + general.unshift(`MAXDOP = ${indexData.maxdop}`); + } + + if (!_.isEmpty(indexData.boundingBox)) { + general.unshift(`BOUNDING_BOX = (\n\t\t${createBoundingGrids(BOUNDING_BOX_LABEL, indexData.boundingBox)}\n\t)`); + } + + if (!_.isEmpty(indexData.grids)) { + general.unshift( + `GRIDS = (\n\t\t${createBoundingGrids(['LEVEL_1', 'LEVEL_2', 'LEVEL_3', 'LEVEL_4'], indexData.grids)}\n\t)`, + ); + } - if (indexData.sortInTempdb) { - general.unshift(`SORT_IN_TEMPDB = ON`); - } + return general; +}; - if (indexData.dropExisting) { - general.unshift(`DROP_EXISTING = ON`); - } +const createSpatialIndex = (terminator, tableName, index) => { + if (!index.column || !index.name) { + return ''; + } + const options = getSpatialOptions(index); + + return assignTemplates(templates.spatialIndex, { + name: index.name, + table: getTableName(tableName, index.schemaName), + column: `[${index.column.name}]`, + using: index.using ? `\nUSING ${index.using}` : '', + options: options.length ? 'WITH (\n\t' + options.join(',\n\t') + '\n)' : '', + terminator, + }); +}; - if (indexData.maxdop) { - general.unshift(`MAXDOP = ${indexData.maxdop}`); - } +const createTableIndex = (terminator, tableName, index, isParentActivated) => { + if (index.type === 'spatial') { + return createSpatialIndex(terminator, tableName, index); + } else if (index.type === 'fulltext') { + return createFullTextIndex(terminator, tableName, index); + } - if (!_.isEmpty(indexData.boundingBox)) { - general.unshift( - `BOUNDING_BOX = (\n\t\t${createBoundingGrids(BOUNDING_BOX_LABEL, indexData.boundingBox)}\n\t)`, - ); - } + return createIndex(terminator, tableName, index, isParentActivated); +}; - if (!_.isEmpty(indexData.grids)) { - general.unshift( - `GRIDS = (\n\t\t${createBoundingGrids(['LEVEL_1', 'LEVEL_2', 'LEVEL_3', 'LEVEL_4'], indexData.grids)}\n\t)`, - ); - } +const createMemoryOptimizedClusteredIndex = indexData => { + let index = 'CLUSTERED COLUMNSTORE'; - return general; - }; + if (indexData.compressionDelay) { + index += ` WITH (COMPRESSION_DELAY = ${indexData.compressionDelay})`; + } - const createSpatialIndex = (terminator, tableName, index) => { - if (!index.column || !index.name) { - return ''; - } - const options = getSpatialOptions(index); - - return assignTemplates(templates.spatialIndex, { - name: index.name, - table: getTableName(tableName, index.schemaName), - column: `[${index.column.name}]`, - using: index.using ? `\nUSING ${index.using}` : '', - options: options.length ? 'WITH (\n\t' + options.join(',\n\t') + '\n)' : '', - terminator, - }); - }; + if (indexData.fileGroupName) { + index += ` ON ${indexData.fileGroupName}`; + } - const createTableIndex = (terminator, tableName, index, isParentActivated) => { - if (index.type === 'spatial') { - return createSpatialIndex(terminator, tableName, index); - } else if (index.type === 'fulltext') { - return createFullTextIndex(terminator, tableName, index); - } + return index; +}; - return createIndex(terminator, tableName, index, isParentActivated); - }; +const createMemoryOptimizedIndex = isParentActivated => indexData => { + let index = `INDEX ${indexData.name}`; - const createMemoryOptimizedClusteredIndex = indexData => { - let index = 'CLUSTERED COLUMNSTORE'; + if (indexData.clustered) { + return { statement: index + ' ' + createMemoryOptimizedClusteredIndex(indexData), isActivated: true }; + } - if (indexData.compressionDelay) { - index += ` WITH (COMPRESSION_DELAY = ${indexData.compressionDelay})`; - } + const isAllKeysDeactivated = checkAllKeysDeactivated(indexData.keys); - if (indexData.fileGroupName) { - index += ` ON ${indexData.fileGroupName}`; - } + index += ' NONCLUSTERED'; - return index; - }; + if (indexData.unique) { + index += ' UNIQUE'; + } - const createMemoryOptimizedIndex = isParentActivated => indexData => { - let index = `INDEX ${indexData.name}`; + if (indexData.hash) { + const keys = divideIntoActivatedAndDeactivated(indexData.keys, key => `[${key.name}]`); + const activatedKeys = keys.activatedItems.join(', '); + const deactivatedKeys = keys.deactivatedItems.length + ? commentIfDeactivated( + keys.deactivatedItems.join(', '), + { + isActivated: !isParentActivated, + }, + true, + ) + : ''; + index += ` HASH (${activatedKeys}${ + activatedKeys.length && deactivatedKeys.length && !deactivatedKeys.startsWith('/*') ? ', ' : '' + }${deactivatedKeys})`; - if (indexData.clustered) { - return { statement: index + ' ' + createMemoryOptimizedClusteredIndex(indexData), isActivated: true }; + if (indexData.bucketCount) { + index += ` WITH (BUCKET_COUNT=${indexData.bucketCount})`; } + } else { + const keys = divideIntoActivatedAndDeactivated( + indexData.keys, + key => `[${key.name}]${_.toLower(key.type) === 'descending' ? ' DESC' : ''}`, + ); + const activatedKeys = keys.activatedItems.join(', '); + const deactivatedKeys = keys.deactivatedItems.length + ? commentIfDeactivated( + keys.deactivatedItems.join(', '), + { + isActivated: !isParentActivated, + }, + true, + ) + : ''; - const isAllKeysDeactivated = checkAllKeysDeactivated(indexData.keys); - - index += ' NONCLUSTERED'; + index += ` (${activatedKeys}${ + activatedKeys.length && deactivatedKeys.length && !deactivatedKeys.startsWith('/*') ? ', ' : '' + }${deactivatedKeys})`; - if (indexData.unique) { - index += ' UNIQUE'; + if (indexData.fileGroupName) { + index += ` ON ${indexData.fileGroupName}`; } + } - if (indexData.hash) { - const keys = divideIntoActivatedAndDeactivated(indexData.keys, key => `[${key.name}]`); - const activatedKeys = keys.activatedItems.join(', '); - const deactivatedKeys = keys.deactivatedItems.length - ? commentIfDeactivated( - keys.deactivatedItems.join(', '), - { - isActivated: !isParentActivated, - }, - true, - ) - : ''; - index += ` HASH (${activatedKeys}${ - activatedKeys.length && deactivatedKeys.length && !deactivatedKeys.startsWith('/*') ? ', ' : '' - }${deactivatedKeys})`; - - if (indexData.bucketCount) { - index += ` WITH (BUCKET_COUNT=${indexData.bucketCount})`; - } - } else { - const keys = divideIntoActivatedAndDeactivated( - indexData.keys, - key => `[${key.name}]${_.toLower(key.type) === 'descending' ? ' DESC' : ''}`, - ); - const activatedKeys = keys.activatedItems.join(', '); - const deactivatedKeys = keys.deactivatedItems.length - ? commentIfDeactivated( - keys.deactivatedItems.join(', '), - { - isActivated: !isParentActivated, - }, - true, - ) - : ''; - - index += ` (${activatedKeys}${ - activatedKeys.length && deactivatedKeys.length && !deactivatedKeys.startsWith('/*') ? ', ' : '' - }${deactivatedKeys})`; - - if (indexData.fileGroupName) { - index += ` ON ${indexData.fileGroupName}`; - } - } + return { statement: index, isActivated: !isAllKeysDeactivated }; +}; - return { statement: index, isActivated: !isAllKeysDeactivated }; - }; +const hydrateIndex = (indexData, schemaData) => { + const toArray = value => (Array.isArray(value) ? value : []); + + return filterColumnStoreProperties({ + name: indexData.indxName, + isActivated: indexData.isActivated, + type: _.toLower(indexData.indxType), + unique: indexData.uniqueIndx, + clustered: indexData.clusteredIndx, + keys: toArray(indexData.indxKey), + include: toArray(indexData.indxInclude), + filterExpression: indexData.indxFilterExpression, + padIndex: indexData.PAD_INDEX, + fillFactor: indexData.FILLFACTOR, + ignoreDuplicateKey: indexData.IGNORE_DUP_KEY, + includedColumn: toArray(indexData.indxIncludedColumn), + statisticsNoRecompute: indexData.STATISTICS_NORECOMPUTE, + statisticsIncremental: indexData.STATISTICS_INCREMENTAL, + allowRowLocks: indexData.ALLOW_ROW_LOCKS, + allowPageLocks: indexData.ALLOW_PAGE_LOCKS, + optimizeForSequentialKey: indexData.OPTIMIZE_FOR_SEQUENTIAL_KEY, + compressionDelay: indexData.COMPRESSION_DELAY, + dataCompression: indexData.DATA_COMPRESSION, + schemaName: schemaData.schemaName, + }); +}; - const hydrateIndex = (indexData, schemaData) => { - const toArray = value => (Array.isArray(value) ? value : []); - - return filterColumnStoreProperties({ - name: indexData.indxName, - isActivated: indexData.isActivated, - type: _.toLower(indexData.indxType), - unique: indexData.uniqueIndx, - clustered: indexData.clusteredIndx, - keys: toArray(indexData.indxKey), - include: toArray(indexData.indxInclude), - filterExpression: indexData.indxFilterExpression, - padIndex: indexData.PAD_INDEX, - fillFactor: indexData.FILLFACTOR, - ignoreDuplicateKey: indexData.IGNORE_DUP_KEY, - includedColumn: toArray(indexData.indxIncludedColumn), - statisticsNoRecompute: indexData.STATISTICS_NORECOMPUTE, - statisticsIncremental: indexData.STATISTICS_INCREMENTAL, - allowRowLocks: indexData.ALLOW_ROW_LOCKS, - allowPageLocks: indexData.ALLOW_PAGE_LOCKS, - optimizeForSequentialKey: indexData.OPTIMIZE_FOR_SEQUENTIAL_KEY, - compressionDelay: indexData.COMPRESSION_DELAY, - dataCompression: indexData.DATA_COMPRESSION, - schemaName: schemaData.schemaName, - }); - }; +const hydrateMemoryOptimizedIndex = schemaData => indexData => { + let index = hydrateIndex(indexData, schemaData); - const hydrateMemoryOptimizedIndex = schemaData => indexData => { - let index = hydrateIndex(indexData, schemaData); - - return { - name: index.name, - isActivated: index.isActivated, - clustered: index.clustered, - hash: indexData.indxHash, - unique: index.unique, - keys: index.keys, - bucketCount: !isNaN(indexData.indxBucketCount) ? indexData.indxBucketCount : -1, - fileGroupName: indexData.indxFileGroupName, - compressionDelay: index.compressionDelay, - }; + return { + name: index.name, + isActivated: index.isActivated, + clustered: index.clustered, + hash: indexData.indxHash, + unique: index.unique, + keys: index.keys, + bucketCount: Number.isNaN(indexData.indxBucketCount) ? -1 : indexData.indxBucketCount, + fileGroupName: indexData.indxFileGroupName, + compressionDelay: index.compressionDelay, }; +}; - const hydrateFullTextIndex = (indexData, schemaData) => { - const generalIndex = hydrateIndex(indexData, schemaData); - - return { - type: 'fulltext', - isActivated: indexData.isActivated, - keys: Array.isArray(indexData.indxFullTextKeysProperties) - ? generalIndex.keys.map((item, i) => { - const properties = indexData.indxFullTextKeysProperties[i]; - - if (!properties) { - return item; - } else { - return { - ...item, - columnType: properties.columnType, - languageTerm: properties.languageTerm, - statisticalSemantics: properties.statisticalSemantics, - }; - } - }) - : generalIndex.keys, - keyIndex: indexData.indxFullTextKeyIndex, - catalogName: indexData.indxFullTextCatalogName, - fileGroup: indexData.indxFullTextFileGroup, - changeTracking: - indexData.indxFullTextChangeTracking === 'OFF' && indexData.indxFullTextNoPopulation - ? 'OFF, NO POPULATION' - : indexData.indxFullTextChangeTracking, - stopList: - indexData.indxFullTextStopList === 'Stoplist name' - ? indexData.indxFullTextStopListName - : indexData.indxFullTextStopList, - searchPropertyList: indexData.indxFullTextSearchPropertyList, - schemaName: schemaData.schemaName, - }; - }; +const hydrateFullTextIndex = (indexData, schemaData) => { + const generalIndex = hydrateIndex(indexData, schemaData); - const hydrateSpatialIndex = (indexData, schemaData) => { - const generalIndex = hydrateIndex(indexData, schemaData); - const isAllBoundingBoxValue = data => - BOUNDING_BOX_LABEL.every(bounding => Boolean(data?.[bounding]) || data?.[bounding] === 0); - - return { - ..._.pick(generalIndex, [ - 'name', - 'type', - 'padIndex', - 'fillFactor', - 'ignoreDuplicateKey', - 'statisticsNoRecompute', - 'allowRowLocks', - 'allowPageLocks', - 'dataCompression', - 'isActivated', - ]), - column: generalIndex.keys[0], - using: indexData.indxUsing, - boundingBox: - isAllBoundingBoxValue(indexData.indxBoundingBox) && - ['GEOMETRY_AUTO_GRID', 'GEOMETRY_GRID'].includes(indexData.indxUsing) - ? indexData.indxBoundingBox - : {}, - grids: - !_.isEmpty(indexData.indxGrids) && ['GEOMETRY_GRID', 'GEOGRAPHY_GRID'].includes(indexData.indxUsing) - ? indexData.indxGrids - : [], - cellsPerObject: indexData.CELLS_PER_OBJECT, - sortInTempdb: indexData.SORT_IN_TEMPDB, - dropExisting: indexData.DROP_EXISTING, - maxdop: indexData.MAXDOP, - schemaName: schemaData.schemaName, - }; + return { + type: 'fulltext', + isActivated: indexData.isActivated, + keys: Array.isArray(indexData.indxFullTextKeysProperties) + ? generalIndex.keys.map((item, i) => { + const properties = indexData.indxFullTextKeysProperties[i]; + + if (properties) { + return { + ...item, + columnType: properties.columnType, + languageTerm: properties.languageTerm, + statisticalSemantics: properties.statisticalSemantics, + }; + } else { + return item; + } + }) + : generalIndex.keys, + keyIndex: indexData.indxFullTextKeyIndex, + catalogName: indexData.indxFullTextCatalogName, + fileGroup: indexData.indxFullTextFileGroup, + changeTracking: + indexData.indxFullTextChangeTracking === 'OFF' && indexData.indxFullTextNoPopulation + ? 'OFF, NO POPULATION' + : indexData.indxFullTextChangeTracking, + stopList: + indexData.indxFullTextStopList === 'Stoplist name' + ? indexData.indxFullTextStopListName + : indexData.indxFullTextStopList, + searchPropertyList: indexData.indxFullTextSearchPropertyList, + schemaName: schemaData.schemaName, }; +}; - const hydrateTableIndex = (indexData, schemaData) => { - if (indexData.indxType === 'Spatial') { - return hydrateSpatialIndex(indexData, schemaData); - } else if (indexData.indxType === 'FullText') { - return hydrateFullTextIndex(indexData, schemaData); - } else { - return hydrateIndex(indexData, schemaData); - } +const hydrateSpatialIndex = (indexData, schemaData) => { + const generalIndex = hydrateIndex(indexData, schemaData); + const isAllBoundingBoxValue = data => + BOUNDING_BOX_LABEL.every(bounding => Boolean(data?.[bounding]) || data?.[bounding] === 0); + + return { + ..._.pick(generalIndex, [ + 'name', + 'type', + 'padIndex', + 'fillFactor', + 'ignoreDuplicateKey', + 'statisticsNoRecompute', + 'allowRowLocks', + 'allowPageLocks', + 'dataCompression', + 'isActivated', + ]), + column: generalIndex.keys[0], + using: indexData.indxUsing, + boundingBox: + isAllBoundingBoxValue(indexData.indxBoundingBox) && + ['GEOMETRY_AUTO_GRID', 'GEOMETRY_GRID'].includes(indexData.indxUsing) + ? indexData.indxBoundingBox + : {}, + grids: + !_.isEmpty(indexData.indxGrids) && ['GEOMETRY_GRID', 'GEOGRAPHY_GRID'].includes(indexData.indxUsing) + ? indexData.indxGrids + : [], + cellsPerObject: indexData.CELLS_PER_OBJECT, + sortInTempdb: indexData.SORT_IN_TEMPDB, + dropExisting: indexData.DROP_EXISTING, + maxdop: indexData.MAXDOP, + schemaName: schemaData.schemaName, }; +}; - const getMemoryOptimizedIndexes = (tableData, schemaData) => { - const indexTab = tableData.find(tab => _.has(tab, 'Indxs')); +const hydrateTableIndex = (indexData, schemaData) => { + if (indexData.indxType === 'Spatial') { + return hydrateSpatialIndex(indexData, schemaData); + } else if (indexData.indxType === 'FullText') { + return hydrateFullTextIndex(indexData, schemaData); + } else { + return hydrateIndex(indexData, schemaData); + } +}; - if (!indexTab) { - return []; - } +const getMemoryOptimizedIndexes = (tableData, schemaData) => { + const indexTab = tableData.find(tab => _.has(tab, 'Indxs')); - return indexTab.Indxs.map(hydrateMemoryOptimizedIndex(schemaData)); - }; + if (!indexTab) { + return []; + } - return { - getRelationOptionsIndex, - createIndex, - hydrateIndex, - hydrateMemoryOptimizedIndex, - createMemoryOptimizedIndex, - hydrateTableIndex, - createTableIndex, - getMemoryOptimizedIndexes, - }; + return indexTab.Indxs.map(hydrateMemoryOptimizedIndex(schemaData)); +}; + +module.exports = { + getRelationOptionsIndex, + createIndex, + hydrateIndex, + hydrateMemoryOptimizedIndex, + createMemoryOptimizedIndex, + hydrateTableIndex, + createTableIndex, + getMemoryOptimizedIndexes, }; diff --git a/forward_engineering/helpers/keyHelper.js b/forward_engineering/helpers/keyHelper.js index 5dc61dc1..89e0f7bb 100644 --- a/forward_engineering/helpers/keyHelper.js +++ b/forward_engineering/helpers/keyHelper.js @@ -4,280 +4,278 @@ * @typedef {import('../types').ConstraintDto} ConstraintDto */ -module.exports = app => { - const _ = app.require('lodash'); - const { clean } = app.require('@hackolade/ddl-fe-utils').general; - - const mapProperties = (jsonSchema, iteratee) => { - return Object.entries(jsonSchema.properties).map(iteratee); - }; - - const isInlineUnique = column => { - return ( - isUnique(column) && - ((column.uniqueKeyOptions?.length === 1 && !_.first(column.uniqueKeyOptions)?.constraintName) || - _.isEmpty(column.uniqueKeyOptions)) - ); - }; - - const isInlinePrimaryKey = column => { - return isPrimaryKey(column) && !column.primaryKeyOptions?.constraintName; - }; - - const isUnique = column => { - if (column.compositeUniqueKey) { - return false; - } else if (!column.unique) { - return false; - } else { - return true; - } - }; - - const isPrimaryKey = column => { - if (column.compositeUniqueKey) { - return false; - } else if (column.compositePrimaryKey) { - return false; - } else if (!column.primaryKey) { - return false; - } else { - return true; - } - }; +const _ = require('lodash'); +const { clean } = require('../utils/general'); - const getOrder = order => { - if (_.toLower(order) === 'asc') { - return 'ASC'; - } else if (_.toLower(order) === 'desc') { - return 'DESC'; - } else { - return ''; - } - }; - - const hydrateUniqueOptions = (options, columnName, isActivated) => - clean({ - keyType: 'UNIQUE', - name: options['constraintName'], - columns: [ - { - name: columnName, - order: getOrder(options['order']), - isActivated: isActivated, - }, - ], - partition: options['partitionName'], - clustered: options['clustered'], - indexOption: clean({ - statisticsNoRecompute: options['staticticsNorecompute'], - statisticsIncremental: options['statisticsIncremental'], - ignoreDuplicateKey: options['ignoreDuplicate'], - fillFactor: options['fillFactor'], - allowRowLocks: options['allowRowLocks'], - allowPageLocks: options['allowPageLocks'], - optimizeForSequentialKey: options['isOptimizedForSequentialKey'], - padIndex: options['isPadded'], - dataCompression: options['dataCompression'], - }), - }); - - const hydratePrimaryKeyOptions = (options, columnName, isActivated) => - clean({ - keyType: 'PRIMARY KEY', - name: options['constraintName'], - columns: [ - { - name: columnName, - order: getOrder(options['order']), - isActivated: isActivated, - }, - ], - partition: options['partitionName'], - clustered: options['clustered'], - indexOption: clean({ - statisticsNoRecompute: options['staticticsNorecompute'], - statisticsIncremental: options['statisticsIncremental'], - ignoreDuplicateKey: options['ignoreDuplicate'], - fillFactor: options['fillFactor'], - allowRowLocks: options['allowRowLocks'], - allowPageLocks: options['allowPageLocks'], - optimizeForSequentialKey: options['isOptimizedForSequentialKey'], - padIndex: options['isPadded'], - dataCompression: options['dataCompression'], - }), - }); - - const findName = (keyId, properties) => { - return Object.keys(properties).find(name => properties[name].GUID === keyId); - }; - - const checkIfActivated = (keyId, properties) => { - return _.get( - Object.values(properties).find(prop => prop.GUID === keyId), - 'isActivated', - true, - ); - }; - - const getKeys = (keys, jsonSchema) => { - const newProperties = getSchemaNewProperties(jsonSchema); - const properties = { ...newProperties, ...jsonSchema.properties }; - - return keys.map(key => { - return { - name: findName(key.keyId, properties), - order: key.type === 'descending' ? 'DESC' : 'ASC', - isActivated: checkIfActivated(key.keyId, properties), - }; - }); - }; - - const getCompositePrimaryKeys = (jsonSchema, isModifiedPK) => { - if (!Array.isArray(jsonSchema.primaryKey) && !isModifiedPK) { - return []; - } +const mapProperties = (jsonSchema, iteratee) => { + return Object.entries(jsonSchema.properties).map(iteratee); +}; - const primaryKey = isModifiedPK ? jsonSchema.compMod.primaryKey.new : jsonSchema.primaryKey; +const isInlineUnique = column => { + return ( + isUnique(column) && + ((column.uniqueKeyOptions?.length === 1 && !_.first(column.uniqueKeyOptions)?.constraintName) || + _.isEmpty(column.uniqueKeyOptions)) + ); +}; - return primaryKey - .filter(primaryKey => !_.isEmpty(primaryKey.compositePrimaryKey)) - .map(primaryKey => ({ - ...hydratePrimaryKeyOptions(primaryKey), - columns: getKeys(primaryKey.compositePrimaryKey, jsonSchema), - })); - }; +const isInlinePrimaryKey = column => { + return isPrimaryKey(column) && !column.primaryKeyOptions?.constraintName; +}; - const getCompositeUniqueKeys = (jsonSchema, isModifiedUK) => { - if (!Array.isArray(jsonSchema.uniqueKey)) { - return []; - } +const isUnique = column => { + if (column.compositeUniqueKey) { + return false; + } else if (!column.unique) { + return false; + } else { + return true; + } +}; + +const isPrimaryKey = column => { + if (column.compositeUniqueKey) { + return false; + } else if (column.compositePrimaryKey) { + return false; + } else if (!column.primaryKey) { + return false; + } else { + return true; + } +}; + +const getOrder = order => { + if (_.toLower(order) === 'asc') { + return 'ASC'; + } else if (_.toLower(order) === 'desc') { + return 'DESC'; + } else { + return ''; + } +}; + +const hydrateUniqueOptions = (options, columnName, isActivated) => + clean({ + keyType: 'UNIQUE', + name: options['constraintName'], + columns: [ + { + name: columnName, + order: getOrder(options['order']), + isActivated: isActivated, + }, + ], + partition: options['partitionName'], + clustered: options['clustered'], + indexOption: clean({ + statisticsNoRecompute: options['staticticsNorecompute'], + statisticsIncremental: options['statisticsIncremental'], + ignoreDuplicateKey: options['ignoreDuplicate'], + fillFactor: options['fillFactor'], + allowRowLocks: options['allowRowLocks'], + allowPageLocks: options['allowPageLocks'], + optimizeForSequentialKey: options['isOptimizedForSequentialKey'], + padIndex: options['isPadded'], + dataCompression: options['dataCompression'], + }), + }); + +const hydratePrimaryKeyOptions = (options, columnName, isActivated) => + clean({ + keyType: 'PRIMARY KEY', + name: options['constraintName'], + columns: [ + { + name: columnName, + order: getOrder(options['order']), + isActivated: isActivated, + }, + ], + partition: options['partitionName'], + clustered: options['clustered'], + indexOption: clean({ + statisticsNoRecompute: options['staticticsNorecompute'], + statisticsIncremental: options['statisticsIncremental'], + ignoreDuplicateKey: options['ignoreDuplicate'], + fillFactor: options['fillFactor'], + allowRowLocks: options['allowRowLocks'], + allowPageLocks: options['allowPageLocks'], + optimizeForSequentialKey: options['isOptimizedForSequentialKey'], + padIndex: options['isPadded'], + dataCompression: options['dataCompression'], + }), + }); + +const findName = (keyId, properties) => { + return Object.keys(properties).find(name => properties[name].GUID === keyId); +}; + +const checkIfActivated = (keyId, properties) => { + return _.get( + Object.values(properties).find(prop => prop.GUID === keyId), + 'isActivated', + true, + ); +}; + +const getKeys = (keys, jsonSchema) => { + const newProperties = getSchemaNewProperties(jsonSchema); + const properties = { ...newProperties, ...jsonSchema.properties }; + + return keys.map(key => { + return { + name: findName(key.keyId, properties), + order: key.type === 'descending' ? 'DESC' : 'ASC', + isActivated: checkIfActivated(key.keyId, properties), + }; + }); +}; + +const getCompositePrimaryKeys = (jsonSchema, isModifiedPK) => { + if (!Array.isArray(jsonSchema.primaryKey) && !isModifiedPK) { + return []; + } + + const primaryKey = isModifiedPK ? jsonSchema.compMod.primaryKey.new : jsonSchema.primaryKey; + + return primaryKey + .filter(primaryKey => !_.isEmpty(primaryKey.compositePrimaryKey)) + .map(primaryKey => ({ + ...hydratePrimaryKeyOptions(primaryKey), + columns: getKeys(primaryKey.compositePrimaryKey, jsonSchema), + })); +}; + +const getCompositeUniqueKeys = (jsonSchema, isModifiedUK) => { + if (!Array.isArray(jsonSchema.uniqueKey)) { + return []; + } + + const uniqueKey = isModifiedUK ? jsonSchema.compMod.uniqueKey.new : jsonSchema.uniqueKey; - const uniqueKey = isModifiedUK ? jsonSchema.compMod.uniqueKey.new : jsonSchema.uniqueKey; + return uniqueKey + .filter(uniqueKey => !_.isEmpty(uniqueKey.compositeUniqueKey)) + .map(uniqueKey => ({ + ...hydrateUniqueOptions(uniqueKey), + columns: getKeys(uniqueKey.compositeUniqueKey, jsonSchema), + })); +}; - return uniqueKey - .filter(uniqueKey => !_.isEmpty(uniqueKey.compositeUniqueKey)) - .map(uniqueKey => ({ - ...hydrateUniqueOptions(uniqueKey), - columns: getKeys(uniqueKey.compositeUniqueKey, jsonSchema), - })); - }; +const getTableKeyConstraints = ({ jsonSchema }) => { + if (!jsonSchema.properties) { + return []; + } - const getTableKeyConstraints = ({ jsonSchema }) => { - if (!jsonSchema.properties) { + const uniqueConstraints = mapProperties(jsonSchema, ([name, columnSchema]) => { + if (!isUnique(columnSchema) || isInlineUnique(columnSchema)) { return []; + } else { + return columnSchema.uniqueKeyOptions.map(options => + hydrateUniqueOptions(options, name, columnSchema.isActivated), + ); } - - const uniqueConstraints = _.flatten( - mapProperties(jsonSchema, ([name, columnSchema]) => { - if (!isUnique(columnSchema) || isInlineUnique(columnSchema)) { - return []; - } else { - return columnSchema.uniqueKeyOptions.map(options => - hydrateUniqueOptions(options, name, columnSchema.isActivated), - ); - } - }), - ).filter(Boolean); - const primaryKeyConstraints = mapProperties(jsonSchema, ([name, columnSchema]) => { - if (!isPrimaryKey(columnSchema) || isInlinePrimaryKey(columnSchema)) { - return; - } else { - return hydratePrimaryKeyOptions(columnSchema.primaryKeyOptions, name, columnSchema.isActivated); - } - }).filter(Boolean); - - return [ - ...getCompositePrimaryKeys(jsonSchema), - ...primaryKeyConstraints, - ...getCompositeUniqueKeys(jsonSchema), - ...uniqueConstraints, - ]; - }; - - /** - * @param {{ jsonSchema: JsonSchema }} - * @returns {ConstraintDto[]} - */ - const getCompositeKeyConstraints = ({ jsonSchema }) => { - const compositePrimaryKeys = getCompositePrimaryKeys(jsonSchema); - const compositeUniqueKeys = getCompositeUniqueKeys(jsonSchema); - - return [...compositePrimaryKeys, ...compositeUniqueKeys]; - }; - - /** - * @param {{ columnDefinition: ColumnDefinition }} - * @returns {ConstraintDto | undefined} - */ - const getPrimaryKeyConstraint = ({ columnDefinition }) => { - if (!isPrimaryKey(columnDefinition)) { + }) + .flat() + .filter(Boolean); + const primaryKeyConstraints = mapProperties(jsonSchema, ([name, columnSchema]) => { + if (!isPrimaryKey(columnSchema) || isInlinePrimaryKey(columnSchema)) { return; + } else { + return hydratePrimaryKeyOptions(columnSchema.primaryKeyOptions, name, columnSchema.isActivated); } + }).filter(Boolean); + + return [ + ...getCompositePrimaryKeys(jsonSchema), + ...primaryKeyConstraints, + ...getCompositeUniqueKeys(jsonSchema), + ...uniqueConstraints, + ]; +}; - return hydratePrimaryKeyOptions(columnDefinition.primaryKeyOptions ?? {}, '', columnDefinition.isActivated); - }; +/** + * @param {{ jsonSchema: JsonSchema }} + * @returns {ConstraintDto[]} + */ +const getCompositeKeyConstraints = ({ jsonSchema }) => { + const compositePrimaryKeys = getCompositePrimaryKeys(jsonSchema); + const compositeUniqueKeys = getCompositeUniqueKeys(jsonSchema); - /** - * @param {{ columnDefinition: ColumnDefinition }} - * @returns {ConstraintDto[]} - */ - const getUniqueKeyConstraints = ({ columnDefinition }) => { - if (!isUnique(columnDefinition)) { - return []; - } + return [...compositePrimaryKeys, ...compositeUniqueKeys]; +}; - if (isInlineUnique(columnDefinition)) { - const constraint = hydrateUniqueOptions({}, '', columnDefinition.isActivated); +/** + * @param {{ columnDefinition: ColumnDefinition }} + * @returns {ConstraintDto | undefined} + */ +const getPrimaryKeyConstraint = ({ columnDefinition }) => { + if (!isPrimaryKey(columnDefinition)) { + return; + } - return [constraint]; - } + return hydratePrimaryKeyOptions(columnDefinition.primaryKeyOptions ?? {}, '', columnDefinition.isActivated); +}; - return columnDefinition.uniqueKeyOptions.map(uniqueKeyOption => { - return hydrateUniqueOptions(uniqueKeyOption, '', columnDefinition.isActivated); - }); - }; - - /** - * @param {{ columnDefinition: ColumnDefinition }} - * @returns {ConstraintDto[]} - */ - const getColumnConstraints = ({ columnDefinition }) => { - const primaryKeyConstraint = getPrimaryKeyConstraint({ columnDefinition }); - const uniqueKeyConstraints = getUniqueKeyConstraints({ columnDefinition }); - - return [primaryKeyConstraint, ...uniqueKeyConstraints].filter(Boolean); - }; - - /** - * @param {JsonSchema} jsonSchema - * @returns {JsonSchema} - */ - const getSchemaNewProperties = jsonSchema => { - if (!Array.isArray(jsonSchema.compMod?.newProperties)) { - return {}; - } +/** + * @param {{ columnDefinition: ColumnDefinition }} + * @returns {ConstraintDto[]} + */ +const getUniqueKeyConstraints = ({ columnDefinition }) => { + if (!isUnique(columnDefinition)) { + return []; + } + + if (isInlineUnique(columnDefinition)) { + const constraint = hydrateUniqueOptions({}, '', columnDefinition.isActivated); + + return [constraint]; + } + + return columnDefinition.uniqueKeyOptions.map(uniqueKeyOption => { + return hydrateUniqueOptions(uniqueKeyOption, '', columnDefinition.isActivated); + }); +}; + +/** + * @param {{ columnDefinition: ColumnDefinition }} + * @returns {ConstraintDto[]} + */ +const getColumnConstraints = ({ columnDefinition }) => { + const primaryKeyConstraint = getPrimaryKeyConstraint({ columnDefinition }); + const uniqueKeyConstraints = getUniqueKeyConstraints({ columnDefinition }); + + return [primaryKeyConstraint, ...uniqueKeyConstraints].filter(Boolean); +}; + +/** + * @param {JsonSchema} jsonSchema + * @returns {JsonSchema} + */ +const getSchemaNewProperties = jsonSchema => { + if (!Array.isArray(jsonSchema.compMod?.newProperties)) { + return {}; + } + + return jsonSchema.compMod.newProperties.reduce((properties, property) => { + return { + ...properties, + [property.code || property.name]: { + ...property, + GUID: property.id, + }, + }; + }, {}); +}; - return jsonSchema.compMod.newProperties.reduce((properties, property) => { - return { - ...properties, - [property.code || property.name]: { - ...property, - GUID: property.id, - }, - }; - }, {}); - }; - - return { - getTableKeyConstraints, - isInlineUnique, - isInlinePrimaryKey, - hydratePrimaryKeyOptions, - hydrateUniqueOptions, - getCompositeUniqueKeys, - getCompositePrimaryKeys, - getCompositeKeyConstraints, - getColumnConstraints, - }; +module.exports = { + getTableKeyConstraints, + isInlineUnique, + isInlinePrimaryKey, + hydratePrimaryKeyOptions, + hydrateUniqueOptions, + getCompositeUniqueKeys, + getCompositePrimaryKeys, + getCompositeKeyConstraints, + getColumnConstraints, }; diff --git a/forward_engineering/helpers/viewHelper.js b/forward_engineering/helpers/viewHelper.js index db9e7993..344cc252 100644 --- a/forward_engineering/helpers/viewHelper.js +++ b/forward_engineering/helpers/viewHelper.js @@ -1,135 +1,131 @@ +const _ = require('lodash'); const { commentIfDeactivated } = require('./commentIfDeactivated'); const templates = require('../configs/templates'); +const { divideIntoActivatedAndDeactivated, tab } = require('../utils/general'); +const { assignTemplates } = require('../utils/assignTemplates'); +const { getViewData, getTableName } = require('./general'); + +const createViewSelectStatement = ({ terminator, keys, tables, selectStatement, isParentActivated }) => { + const mapKeys = key => (key.alias ? `[${key.name}] AS [${key.alias}]` : `[${key.name}]`); + let selectKeys = keys.map(mapKeys).join(','); + + if (isParentActivated) { + const dividedKeys = divideIntoActivatedAndDeactivated(keys, mapKeys); + const activatedKeys = dividedKeys.activatedItems.join(','); + const deactivatedKeys = dividedKeys.deactivatedItems.length + ? commentIfDeactivated(dividedKeys.deactivatedItems.join(','), { isActivated: false }, true) + : ''; + selectKeys = activatedKeys + deactivatedKeys || '*'; + } + + return tables + .map(table => { + return selectStatement + ? assignTemplates(selectStatement, { tableName: getFullTableName(table), terminator }) + : `SELECT ${selectKeys}\nFROM ${getFullTableName(table)}`; + }) + .join('\nUNION ALL\n'); +}; -module.exports = app => { - const _ = app.require('lodash'); - const { assignTemplates } = app.require('@hackolade/ddl-fe-utils'); - const { divideIntoActivatedAndDeactivated, tab } = app.require('@hackolade/ddl-fe-utils').general; - const { getViewData, getTableName } = require('./general')(app); - - const createViewSelectStatement = ({ terminator, keys, tables, selectStatement, isParentActivated }) => { - const mapKeys = key => (key.alias ? `[${key.name}] AS [${key.alias}]` : `[${key.name}]`); - let selectKeys = keys.map(mapKeys).join(','); - - if (isParentActivated) { - const dividedKeys = divideIntoActivatedAndDeactivated(keys, mapKeys); - const activatedKeys = dividedKeys.activatedItems.join(','); - const deactivatedKeys = dividedKeys.deactivatedItems.length - ? commentIfDeactivated(dividedKeys.deactivatedItems.join(','), { isActivated: false }, true) - : ''; - selectKeys = activatedKeys + deactivatedKeys || '*'; - } - - return tables - .map(table => { - return selectStatement - ? assignTemplates(selectStatement, { tableName: getFullTableName(table), terminator }) - : `SELECT ${selectKeys}\nFROM ${getFullTableName(table)}`; - }) - .join('\nUNION ALL\n'); - }; - - const getFullTableName = table => { - let name = `[${table.name}]`; +const getFullTableName = table => { + let name = `[${table.name}]`; - if (table.schemaName) { - name = `[${table.schemaName}].` + name; - } + if (table.schemaName) { + name = `[${table.schemaName}].` + name; + } - if (table.databaseName) { - name = `[${table.databaseName}].` + name; - } + if (table.databaseName) { + name = `[${table.databaseName}].` + name; + } - return name; - }; + return name; +}; - const getPartitionedTables = (partitionedTables, relatedSchemas = {}, relatedContainers = {}) => { - const schemaIds = partitionedTables.map(item => item.table); - const names = schemaIds - .map(id => relatedSchemas[id]) - .filter(Boolean) - .map(schema => { - let schemaName = ''; - let databaseName = ''; - - if (relatedContainers[schema.bucketId]) { - const db = _.first(relatedContainers[schema.bucketId]) || {}; - schemaName = db.code || db.name || ''; - databaseName = db.databaseName || ''; - } - - return { - name: schema.code || schema.collectionName, - databaseName, - schemaName, - }; - }); - - return names; - }; +const getPartitionedTables = (partitionedTables, relatedSchemas = {}, relatedContainers = {}) => { + const schemaIds = partitionedTables.map(item => item.table); + + return schemaIds + .map(id => relatedSchemas[id]) + .filter(Boolean) + .map(schema => { + let schemaName = ''; + let databaseName = ''; + + if (relatedContainers[schema.bucketId]) { + const db = _.first(relatedContainers[schema.bucketId]) || {}; + schemaName = db.code || db.name || ''; + databaseName = db.databaseName || ''; + } + + return { + name: schema.code || schema.collectionName, + databaseName, + schemaName, + }; + }); +}; - const getCreateViewData = ({ - name, - keys, - partitionedTables, - partitioned, - viewAttrbute: viewAttribute, - withCheckOption, - selectStatement, - schemaData, - ifNotExist, - terminator, - isActivated, - }) => { - const viewTerminator = ifNotExist ? ';' : terminator; - const viewData = getViewData(keys, schemaData); - - if (partitioned) { - selectStatement = createViewSelectStatement({ - tables: partitionedTables, - selectStatement, - keys, - terminator: viewTerminator, - isParentActivated: isActivated, - }); - } - - if ((_.isEmpty(viewData.tables) || _.isEmpty(viewData.columns)) && !selectStatement) { - return null; - } - - let columnsAsString = viewData.columns.map(column => column.statement).join(',\n\t\t'); - - if (isActivated) { - const dividedColumns = divideIntoActivatedAndDeactivated(viewData.columns, column => column.statement); - const deactivatedColumnsString = dividedColumns.deactivatedItems.length - ? commentIfDeactivated(dividedColumns.deactivatedItems.join(',\n\t\t'), { isActivated: false }, true) - : ''; - columnsAsString = dividedColumns.activatedItems.join(',\n\t\t') + deactivatedColumnsString; - } - - const viewName = getTableName(name, schemaData.schemaName); - const viewNameIfNotExist = getTableName(name, schemaData.schemaName, false); - - return { - viewName, - viewNameIfNotExist, - viewAttribute: viewAttribute ? `WITH ${viewAttribute}\n` : '', - checkOption: withCheckOption ? `WITH CHECK OPTION` : '', - selectStatement: _.trim(selectStatement) - ? _.trim(tab(selectStatement)) + '\n' - : assignTemplates(templates.viewSelectStatement, { - tableName: viewData.tables.join(', '), - keys: columnsAsString, - terminator: viewTerminator, - }), +const getCreateViewData = ({ + name, + keys, + partitionedTables, + partitioned, + viewAttrbute: viewAttribute, + withCheckOption, + selectStatement, + schemaData, + ifNotExist, + terminator, + isActivated, +}) => { + const viewTerminator = ifNotExist ? ';' : terminator; + const viewData = getViewData(keys, schemaData); + + if (partitioned) { + selectStatement = createViewSelectStatement({ + tables: partitionedTables, + selectStatement, + keys, terminator: viewTerminator, - }; - }; + isParentActivated: isActivated, + }); + } + + if ((_.isEmpty(viewData.tables) || _.isEmpty(viewData.columns)) && !selectStatement) { + return null; + } + + let columnsAsString = viewData.columns.map(column => column.statement).join(',\n\t\t'); + + if (isActivated) { + const dividedColumns = divideIntoActivatedAndDeactivated(viewData.columns, column => column.statement); + const deactivatedColumnsString = dividedColumns.deactivatedItems.length + ? commentIfDeactivated(dividedColumns.deactivatedItems.join(',\n\t\t'), { isActivated: false }, true) + : ''; + columnsAsString = dividedColumns.activatedItems.join(',\n\t\t') + deactivatedColumnsString; + } + + const viewName = getTableName(name, schemaData.schemaName); + const viewNameIfNotExist = getTableName(name, schemaData.schemaName, false); return { - createViewSelectStatement, - getPartitionedTables, - getCreateViewData, + viewName, + viewNameIfNotExist, + viewAttribute: viewAttribute ? `WITH ${viewAttribute}\n` : '', + checkOption: withCheckOption ? `WITH CHECK OPTION` : '', + selectStatement: _.trim(selectStatement) + ? _.trim(tab(selectStatement)) + '\n' + : assignTemplates(templates.viewSelectStatement, { + tableName: viewData.tables.join(', '), + keys: columnsAsString, + terminator: viewTerminator, + }), + terminator: viewTerminator, }; }; + +module.exports = { + createViewSelectStatement, + getPartitionedTables, + getCreateViewData, +}; diff --git a/forward_engineering/utils/assignTemplates.js b/forward_engineering/utils/assignTemplates.js new file mode 100644 index 00000000..95bd1bc2 --- /dev/null +++ b/forward_engineering/utils/assignTemplates.js @@ -0,0 +1,15 @@ +const template = (modifiers = '') => new RegExp('\\$\\{(.*?)}', modifiers); +const getAllTemplates = str => str.match(template('gi')) || []; +const parseTemplate = str => (str.match(template('i')) || [])[1]; + +const assignTemplates = (str, templates) => { + return getAllTemplates(str).reduce((result, item) => { + const templateName = parseTemplate(item); + + return result.replace(item, () => { + return templates[templateName] || templates[templateName] === 0 ? templates[templateName] : ''; + }); + }, str); +}; + +module.exports = { assignTemplates }; diff --git a/forward_engineering/utils/general.js b/forward_engineering/utils/general.js index b8701c25..3906ee02 100644 --- a/forward_engineering/utils/general.js +++ b/forward_engineering/utils/general.js @@ -1,246 +1,273 @@ -'use strict'; +const _ = require('lodash'); +const sqlFormatter = require('sql-formatter'); +const { RESERVED_WORDS_AS_ARRAY } = require('../enums/reservedWords'); + +/** + * @typedef {((args: any) => string) | ((args: any) => ChainFunction)} ChainFunction + * */ + +/** + * @return {ChainFunction} + * */ +const buildStatement = (mainStatement, isActivated) => { + let composeStatements = (...statements) => { + return statements.reduce((result, statement) => result + statement, mainStatement); + }; -module.exports = _ => { - const sqlFormatter = require('sql-formatter'); - const { RESERVED_WORDS_AS_ARRAY } = require('../enums/reservedWords'); + const chain = (...args) => { + if (args.length) { + composeStatements = composeStatements.bind(null, getStatement(...args)); - /** - * @typedef {((args: any) => string) | ((args: any) => ChainFunction)} ChainFunction - * */ + return chain; + } + + return commentDeactivatedStatements(composeStatements(), isActivated); + }; /** - * @return {ChainFunction} + * @param condition {boolean} + * @param statement {string} + * @return {string} * */ - const buildStatement = (mainStatement, isActivated) => { - let composeStatements = (...statements) => { - return statements.reduce((result, statement) => result + statement, mainStatement); - }; - - const chain = (...args) => { - if (args.length) { - composeStatements = composeStatements.bind(null, getStatement(...args)); - - return chain; - } - - return commentDeactivatedStatements(composeStatements(), isActivated); - }; - - /** - * @param condition {boolean} - * @param statement {string} - * @return {string} - * */ - const getStatement = (condition, statement) => { - if (condition && statement === ')') { - return '\n)'; - } - if (statement === ';') { - return statement; - } - - if (condition) { - return '\n' + indentString(statement); - } - - return ''; - }; - - return chain; - }; + const getStatement = (condition, statement) => { + if (condition && statement === ')') { + return '\n)'; + } + if (statement === ';') { + return statement; + } - const isEscaped = name => /`[\s\S]*`/.test(name); - - const prepareName = (name = '') => { - const containSpaces = /[\s-]/g; - if (containSpaces.test(name) && !isEscaped(name)) { - return `\`${name}\``; - } else if (RESERVED_WORDS_AS_ARRAY.includes(name.toUpperCase())) { - return `\`${name}\``; - } else if (name === '') { - return ''; - } else if (!isNaN(name)) { - return `\`${name}\``; + if (condition) { + return '\n' + indentString(statement); } - return name; - }; - const replaceSpaceWithUnderscore = (name = '') => { - return name.replace(/\s/g, '_'); + return ''; }; - const getFullTableName = collection => { - const collectionSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; - const tableName = getEntityName(collectionSchema); - const schemaName = collectionSchema.compMod?.keyspaceName; + return chain; +}; - return getNamePrefixedWithSchemaName(tableName, schemaName); - }; +const isEscaped = name => /`[\s\S]*`/.test(name); + +const prepareName = (name = '') => { + const containSpaces = /[\s-]/g; + if (containSpaces.test(name) && !isEscaped(name)) { + return `\`${name}\``; + } else if (RESERVED_WORDS_AS_ARRAY.includes(name.toUpperCase())) { + return `\`${name}\``; + } else if (name === '') { + return ''; + } else if (!Number.isNaN(name)) { + return `\`${name}\``; + } + + return name; +}; - const getFullCollectionName = collectionSchema => { - const collectionName = getEntityName(collectionSchema); - const bucketName = collectionSchema.compMod?.keyspaceName; +const replaceSpaceWithUnderscore = (name = '') => { + return name.replace(/\s/g, '_'); +}; - return getNamePrefixedWithSchemaName(collectionName, bucketName); - }; +const getFullTableName = collection => { + const collectionSchema = { ...collection, ..._.omit(collection?.role, 'properties') }; + const tableName = getEntityName(collectionSchema); + const schemaName = collectionSchema.compMod?.keyspaceName; - const getName = entity => entity.code || entity.collectionName || entity.name || ''; + return getNamePrefixedWithSchemaName(tableName, schemaName); +}; - const getRelationshipName = relationship => relationship.name || ''; +const getFullCollectionName = collectionSchema => { + const collectionName = getEntityName(collectionSchema); + const bucketName = collectionSchema.compMod?.keyspaceName; - const getTab = (tabNum, configData) => (Array.isArray(configData) ? configData[tabNum] || {} : {}); - const indentString = (str, tab = 4) => - (str || '') + return getNamePrefixedWithSchemaName(collectionName, bucketName); +}; + +const getName = entity => entity.code || entity.collectionName || entity.name || ''; + +const getRelationshipName = relationship => relationship.name || ''; + +const getTab = (tabNum, configData) => (Array.isArray(configData) ? configData[tabNum] || {} : {}); + +const indentString = (str, tab = 4) => + (str || '') + .split('\n') + .map(s => ' '.repeat(tab) + s) + .join('\n'); + +const descriptors = {}; +const getTypeDescriptor = typeName => { + if (descriptors[typeName]) { + return descriptors[typeName]; + } + + try { + descriptors[typeName] = require(`../../types/${typeName}.json`); + + return descriptors[typeName]; + } catch { + return {}; + } +}; + +const getNamePrefixedWithSchemaName = (name, schemaName) => { + if (schemaName) { + return `${wrapInBrackets(schemaName)}.${wrapInBrackets(name)}`; + } + + return wrapInBrackets(name); +}; + +/** + * @param statement {string} + * @param isActivated {boolean} + * @return {string} + * */ +const commentDeactivatedStatements = (statement, isActivated = true) => { + if (isActivated) { + return statement; + } + const insertBeforeEachLine = (statement, insertValue) => + statement .split('\n') - .map(s => ' '.repeat(tab) + s) + .map(line => `${insertValue}${line}`) .join('\n'); - const descriptors = {}; - const getTypeDescriptor = typeName => { - if (descriptors[typeName]) { - return descriptors[typeName]; - } + return insertBeforeEachLine(statement, '-- '); +}; - try { - descriptors[typeName] = require(`../../types/${typeName}.json`); +const commentDeactivatedInlineKeys = (keys, deactivatedKeyNames) => { + const [activatedKeys, deactivatedKeys] = _.partition( + keys, + key => !(deactivatedKeyNames.has(key) || deactivatedKeyNames.has(key.slice(1, -1))), + ); + if (activatedKeys.length === 0) { + return { isAllKeysDeactivated: true, keysString: deactivatedKeys.join(', ') }; + } + if (deactivatedKeys.length === 0) { + return { isAllKeysDeactivated: false, keysString: activatedKeys.join(', ') }; + } - return descriptors[typeName]; - } catch (e) { - return {}; - } + return { + isAllKeysDeactivated: false, + keysString: `${activatedKeys.join(', ')} /*, ${deactivatedKeys.join(', ')} */`, }; +}; - const getNamePrefixedWithSchemaName = (name, schemaName) => { - if (schemaName) { - return `${wrapInBrackets(schemaName)}.${wrapInBrackets(name)}`; - } +const wrapInBrackets = name => { + return `[${name}]`; +}; - return wrapInBrackets(name); - }; +const wrapInBracketsIfNecessary = name => { + return name.replace(/^(?!\().*?(? { - if (isActivated) { - return statement; - } - const insertBeforeEachLine = (statement, insertValue) => - statement - .split('\n') - .map(line => `${insertValue}${line}`) - .join('\n'); +const escapeSpecialCharacters = (name = '') => { + return name.replace(/'/g, "''"); +}; - return insertBeforeEachLine(statement, '-- '); - }; +const skipSqlCommentsPattern = /^\s*(EXEC\b|.*\bMS_DESCRIPTION\b)/i; - const commentDeactivatedInlineKeys = (keys, deactivatedKeyNames) => { - const [activatedKeys, deactivatedKeys] = _.partition( - keys, - key => !(deactivatedKeyNames.has(key) || deactivatedKeyNames.has(key.slice(1, -1))), +const buildScript = statements => { + const formattedScripts = statements + .filter(Boolean) + .map(script => + skipSqlCommentsPattern.test(script) + ? script + : sqlFormatter.format(script, { indent: ' ' }).replace(/\{ \{ (.+?) } }/g, '{{$1}}'), ); - if (activatedKeys.length === 0) { - return { isAllKeysDeactivated: true, keysString: deactivatedKeys.join(', ') }; - } - if (deactivatedKeys.length === 0) { - return { isAllKeysDeactivated: false, keysString: activatedKeys.join(', ') }; - } - return { - isAllKeysDeactivated: false, - keysString: `${activatedKeys.join(', ')} /*, ${deactivatedKeys.join(', ')} */`, - }; - }; - - const wrapInBrackets = name => { - return `[${name}]`; - }; + return formattedScripts.join('\n\n') + '\n\n'; +}; - const wrapInBracketsIfNecessary = name => { - return name.replace(/^(?!\().*?(? compMod.keyspaceName; - const escapeSpecialCharacters = (name = '') => { - return name.replace(/'/g, "''"); - }; +const getFullEntityName = (dbName, entityName) => (dbName ? `${dbName}.${entityName}` : entityName); - const skipSqlCommentsPattern = /^\s*(EXEC\b|.*\bMS_DESCRIPTION\b)/i; +const getEntityName = entityData => { + return (entityData && (entityData.code || entityData.collectionName)) || ''; +}; - const buildScript = statements => { - const formattedScripts = statements - .filter(Boolean) - .map(script => - skipSqlCommentsPattern.test(script) - ? script - : sqlFormatter.format(script, { indent: ' ' }).replace(/\{ \{ (.+?) } }/g, '{{$1}}'), - ); +/** + * @return {Array} + * */ +const filterEmptyScripts = (...scripts) => scripts.filter(Boolean); - return formattedScripts.join('\n\n') + '\n\n'; - }; +const compareObjectsByProperties = (obj1, obj2, properties) => { + return properties.some(prop => obj1[prop] !== obj2[prop]); +}; - const getContainerName = compMod => compMod.keyspaceName; +const getSchemaOfAlterCollection = collection => { + return { ...collection, ..._.omit(collection?.role, 'properties') }; +}; - const getFullEntityName = (dbName, entityName) => (dbName ? `${dbName}.${entityName}` : entityName); +const buildDefaultPKName = (tableName, columnName) => { + const PKName = `PK_${tableName}_${columnName}`; - const getEntityName = entityData => { - return (entityData && (entityData.code || entityData.collectionName)) || ''; - }; + return wrapInBrackets(PKName); +}; - /** - * @return {Array} - * */ - const filterEmptyScripts = (...scripts) => scripts.filter(Boolean); +const checkAllKeysDeactivated = keys => (keys.length ? keys.every(key => !_.get(key, 'isActivated', true)) : false); - const compareProperties = - _ => - ({ new: newProperty, old: oldProperty }) => { - if (!newProperty && !oldProperty) { - return; - } +const divideIntoActivatedAndDeactivated = (items, mapFunction) => { + const activatedItems = items.filter(item => _.get(item, 'isActivated', true)).map(mapFunction); + const deactivatedItems = items.filter(item => !_.get(item, 'isActivated', true)).map(mapFunction); + return { activatedItems, deactivatedItems }; +}; - return !_.isEqual(newProperty, oldProperty); - }; +const hasType = (types, type) => + Object.keys(types) + .map(element => _.toLower(element)) + .includes(_.toLower(type)); - const compareObjectsByProperties = (obj1, obj2, properties) => { - return properties.some(prop => obj1[prop] !== obj2[prop]); - }; +const clean = obj => + Object.entries(obj) + .filter(([name, value]) => !_.isNil(value)) + .reduce((result, [name, value]) => ({ ...result, [name]: value }), {}); - const getSchemaOfAlterCollection = collection => { - return { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; - }; +const tab = (text, tab = '\t') => + text + .split('\n') + .map(line => tab + line) + .join('\n'); - const buildDefaultPKName = (tableName, columnName) => { - const PKName = `PK_${tableName}_${columnName}`; +const getDbName = containerData => { + return _.get(containerData, '[0].code') || _.get(containerData, '[0].name', ''); +}; - return wrapInBrackets(PKName); - }; +const getDbData = containerData => { + return { ..._.get(containerData, '[0]', {}), name: getDbName(containerData) }; +}; - return { - buildStatement, - getName, - getTab, - indentString, - getTypeDescriptor, - getRelationshipName, - prepareName, - replaceSpaceWithUnderscore, - commentDeactivatedStatements, - commentDeactivatedInlineKeys, - buildScript, - wrapInBrackets, - wrapInBracketsIfNecessary, - escapeSpecialCharacters, - getFullEntityName, - getFullTableName, - getFullCollectionName, - getContainerName, - getEntityName, - filterEmptyScripts, - getSchemaOfAlterCollection, - getNamePrefixedWithSchemaName, - buildDefaultPKName, - compareObjectsByProperties, - }; +module.exports = { + buildStatement, + getName, + getTab, + indentString, + getTypeDescriptor, + getRelationshipName, + prepareName, + replaceSpaceWithUnderscore, + commentDeactivatedStatements, + commentDeactivatedInlineKeys, + buildScript, + wrapInBrackets, + wrapInBracketsIfNecessary, + escapeSpecialCharacters, + getFullEntityName, + getFullTableName, + getFullCollectionName, + getContainerName, + getEntityName, + filterEmptyScripts, + getSchemaOfAlterCollection, + getNamePrefixedWithSchemaName, + buildDefaultPKName, + compareObjectsByProperties, + checkAllKeysDeactivated, + divideIntoActivatedAndDeactivated, + hasType, + clean, + tab, + getDbData, };