diff --git a/forward_engineering/api.js b/forward_engineering/api.js index 349d9e3..1dfc1ff 100644 --- a/forward_engineering/api.js +++ b/forward_engineering/api.js @@ -20,16 +20,33 @@ module.exports = { ); } + const modelDefinitions = JSON.parse(data.modelDefinitions); + const internalDefinitions = JSON.parse(data.internalDefinitions); + const externalDefinitions = JSON.parse(data.externalDefinitions); const dbVersion = data.modelData[0]?.dbVersion; const containersScripts = getAlterContainersScripts(collection); - const collectionsScripts = getAlterCollectionsScripts(collection, app, dbVersion); + const collectionsScripts = getAlterCollectionsScripts({ + collection, + app, + dbVersion, + modelDefinitions, + internalDefinitions, + externalDefinitions, + }); const viewScripts = getAlterViewScripts(collection, app); - const modelDefinitionsScripts = getAlterModelDefinitionsScripts(collection, app); + const modelDefinitionsScripts = getAlterModelDefinitionsScripts({ + collection, + app, + dbVersion, + modelDefinitions, + internalDefinitions, + externalDefinitions, + }); const script = [ ...containersScripts, + ...modelDefinitionsScripts, ...collectionsScripts, ...viewScripts, - ...modelDefinitionsScripts, ].join('\n\n'); const applyDropStatements = data.options?.additionalOptions?.some( @@ -49,6 +66,7 @@ module.exports = { generateContainerScript(data, logger, callback, app) { try { data.jsonSchema = data.collections[0]; + data.internalDefinitions = Object.values(data.internalDefinitions)[0]; this.generateScript(data, logger, callback, app); } catch (error) { logger.log('error', { message: error.message, stack: error.stack }, 'Oracle Forward-Engineering Error'); diff --git a/forward_engineering/ddlProvider.js b/forward_engineering/ddlProvider.js index f5090ff..47afd89 100644 --- a/forward_engineering/ddlProvider.js +++ b/forward_engineering/ddlProvider.js @@ -110,7 +110,7 @@ module.exports = (baseProvider, options, app) => { return schemaStatement; }, - hydrateColumn({ columnDefinition, jsonSchema, schemaData, definitionJsonSchema }) { + hydrateColumn({ columnDefinition, jsonSchema, schemaData, definitionJsonSchema = {} }) { const dbVersion = schemaData.dbVersion; const type = jsonSchema.$ref ? columnDefinition.type : _.toUpper(jsonSchema.mode || jsonSchema.type); return { diff --git a/forward_engineering/helpers/alterScriptFromDeltaHelper.js b/forward_engineering/helpers/alterScriptFromDeltaHelper.js index 4e094f5..8f8c623 100644 --- a/forward_engineering/helpers/alterScriptFromDeltaHelper.js +++ b/forward_engineering/helpers/alterScriptFromDeltaHelper.js @@ -31,13 +31,20 @@ const getAlterContainersScripts = collection => { return [].concat(addContainersScripts).concat(deleteContainersScripts); }; -const getAlterCollectionsScripts = (collection, app, dbVersion) => { +const getAlterCollectionsScripts = ({ + collection, + app, + dbVersion, + modelDefinitions, + internalDefinitions, + externalDefinitions, +}) => { const createCollectionsScripts = [] .concat(collection.properties?.entities?.properties?.added?.items) .filter(Boolean) .map(item => Object.values(item.properties)[0]) .filter(collection => collection.compMod?.created) - .map(getAddCollectionScript(app, dbVersion)); + .map(getAddCollectionScript({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions })); const deleteCollectionScripts = [] .concat(collection.properties?.entities?.properties?.deleted?.items) .filter(Boolean) @@ -49,7 +56,7 @@ const getAlterCollectionsScripts = (collection, app, dbVersion) => { .filter(Boolean) .map(item => Object.values(item.properties)[0]) .filter(collection => !collection.compMod) - .flatMap(getAddColumnScript(app)); + .flatMap(getAddColumnScript({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions })); const deleteColumnScripts = [] .concat(collection.properties?.entities?.properties?.deleted?.items) .filter(Boolean) @@ -92,14 +99,21 @@ const getAlterViewScripts = (collection, app) => { return [...deleteViewsScripts, ...createViewsScripts].map(script => script.trim()); }; -const getAlterModelDefinitionsScripts = (collection, app, dbVersion) => { +const getAlterModelDefinitionsScripts = ({ + collection, + app, + dbVersion, + modelDefinitions, + internalDefinitions, + externalDefinitions, +}) => { const createUdtScripts = [] .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) - .map(getCreateUdtScript(app, dbVersion)); + .map(getCreateUdtScript({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions })); const deleteUdtScripts = [] .concat(collection.properties?.modelDefinitions?.properties?.deleted?.items) .filter(Boolean) @@ -114,7 +128,9 @@ const getAlterModelDefinitionsScripts = (collection, app, dbVersion) => { .filter(item => !item.compMod) .map(item => ({ ...item, ...(app.require('lodash').omit(item.role, 'properties') || {}) })) .filter(item => item.childType === 'object_udt') - .flatMap(getAddColumnToTypeScript(app)); + .flatMap( + getAddColumnToTypeScript({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions }), + ); const deleteColumnScripts = [] .concat(collection.properties?.modelDefinitions?.properties?.deleted?.items) .filter(Boolean) @@ -139,7 +155,9 @@ const getAlterModelDefinitionsScripts = (collection, app, dbVersion) => { ...addColumnScripts, ...deleteColumnScripts, ...modifyColumnScripts, - ].map(script => script.trim()); + ] + .filter(Boolean) + .map(script => script.trim()); }; module.exports = { diff --git a/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js index 2970050..22dcf31 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterEntityHelper.js @@ -1,38 +1,49 @@ const { checkFieldPropertiesChanged } = require('./common'); -const getAddCollectionScript = (app, dbVersion) => collection => { - const _ = app.require('lodash'); - const { getEntityName } = require('../../utils/general')(_); - const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_); - const ddlProvider = require('../../ddlProvider')(null, null, app); - - const schemaName = collection.compMod.keyspaceName; - const schemaData = { schemaName, dbVersion }; - const jsonSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; - const columnDefinitions = _.toPairs(jsonSchema.properties).map(([name, column]) => - createColumnDefinitionBySchema({ - name, - jsonSchema: column, - parentJsonSchema: jsonSchema, - ddlProvider, +const getAddCollectionScript = + ({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions }) => + collection => { + const _ = app.require('lodash'); + const { getEntityName } = require('../../utils/general')(_); + const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(app); + const ddlProvider = require('../../ddlProvider')(null, null, app); + const { getDefinitionByReference } = app.require('@hackolade/ddl-fe-utils'); + + const schemaName = collection.compMod.keyspaceName; + const schemaData = { schemaName, dbVersion }; + const jsonSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; + const columnDefinitions = _.toPairs(jsonSchema.properties).map(([name, column]) => { + const definitionJsonSchema = getDefinitionByReference({ + propertySchema: column, + modelDefinitions, + internalDefinitions, + externalDefinitions, + }); + + return createColumnDefinitionBySchema({ + name, + jsonSchema: column, + parentJsonSchema: jsonSchema, + ddlProvider, + schemaData, + definitionJsonSchema, + }); + }); + const checkConstraints = (jsonSchema.chkConstr || []).map(check => + ddlProvider.createCheckConstraint(ddlProvider.hydrateCheckConstraint(check)), + ); + const tableData = { + name: getEntityName(jsonSchema), + columns: columnDefinitions.map(data => ddlProvider.convertColumnDefinition(data)), + checkConstraints: checkConstraints, + foreignKeyConstraints: [], schemaData, - }), - ); - const checkConstraints = (jsonSchema.chkConstr || []).map(check => - ddlProvider.createCheckConstraint(ddlProvider.hydrateCheckConstraint(check)), - ); - const tableData = { - name: getEntityName(jsonSchema), - columns: columnDefinitions.map(data => ddlProvider.convertColumnDefinition(data)), - checkConstraints: checkConstraints, - foreignKeyConstraints: [], - schemaData, - columnDefinitions, - }; - const hydratedTable = ddlProvider.hydrateTable({ tableData, entityData: [jsonSchema], jsonSchema }); + columnDefinitions, + }; + const hydratedTable = ddlProvider.hydrateTable({ tableData, entityData: [jsonSchema], jsonSchema }); - return ddlProvider.createTable(hydratedTable, jsonSchema.isActivated); -}; + return ddlProvider.createTable(hydratedTable, jsonSchema.isActivated); + }; const getDeleteCollectionScript = app => collection => { const _ = app.require('lodash'); @@ -47,33 +58,44 @@ const getDeleteCollectionScript = app => collection => { return `DROP TABLE ${fullName};`; }; -const getAddColumnScript = (app, dbVersion) => collection => { - const _ = app.require('lodash'); - const { getEntityName } = require('../../utils/general')(_); - const { getNamePrefixedWithSchemaName } = require('../general')({ _ }); - const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_); - const ddlProvider = require('../../ddlProvider')(null, null, app); - - const collectionSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; - const tableName = getEntityName(collectionSchema); - const schemaName = collectionSchema.compMod?.keyspaceName; - const fullName = getNamePrefixedWithSchemaName(tableName, schemaName); - const schemaData = { schemaName, dbVersion }; - - return _.toPairs(collection.properties) - .filter(([name, jsonSchema]) => !jsonSchema.compMod) - .map(([name, jsonSchema]) => - createColumnDefinitionBySchema({ - name, - jsonSchema, - parentJsonSchema: collectionSchema, - ddlProvider, - schemaData, - }), - ) - .map(data => ddlProvider.convertColumnDefinition(data)) - .map(script => `ALTER TABLE ${fullName} ADD (${script});`); -}; +const getAddColumnScript = + ({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions }) => + collection => { + const _ = app.require('lodash'); + const { getEntityName } = require('../../utils/general')(_); + const { getNamePrefixedWithSchemaName } = require('../general')({ _ }); + const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(app); + const ddlProvider = require('../../ddlProvider')(null, null, app); + const { getDefinitionByReference } = app.require('@hackolade/ddl-fe-utils'); + + const collectionSchema = { ...collection, ...(_.omit(collection?.role, 'properties') || {}) }; + const tableName = getEntityName(collectionSchema); + const schemaName = collectionSchema.compMod?.keyspaceName; + const fullName = getNamePrefixedWithSchemaName(tableName, schemaName); + const schemaData = { schemaName, dbVersion }; + + return _.toPairs(collection.properties) + .filter(([name, jsonSchema]) => !jsonSchema.compMod) + .map(([name, jsonSchema]) => { + const definitionJsonSchema = getDefinitionByReference({ + propertySchema: jsonSchema, + modelDefinitions, + internalDefinitions, + externalDefinitions, + }); + + return createColumnDefinitionBySchema({ + name, + jsonSchema, + parentJsonSchema: collectionSchema, + ddlProvider, + schemaData, + definitionJsonSchema, + }); + }) + .map(data => ddlProvider.convertColumnDefinition(data)) + .map(script => `ALTER TABLE ${fullName} ADD (${script});`); + }; const getDeleteColumnScript = app => collection => { const _ = app.require('lodash'); @@ -112,9 +134,9 @@ const getModifyColumnScript = app => collection => { .filter(([name, jsonSchema]) => checkFieldPropertiesChanged(jsonSchema.compMod, ['type', 'mode'])) .map( ([name, jsonSchema]) => - `ALTER TABLE ${fullName} MODIFY (${wrapInQuotes(name)} ${ - _.toUpper(jsonSchema.compMod.newField.mode || jsonSchema.compMod.newField.type) - });`, + `ALTER TABLE ${fullName} MODIFY (${wrapInQuotes(name)} ${_.toUpper( + jsonSchema.compMod.newField.mode || jsonSchema.compMod.newField.type, + )});`, ); return [...renameColumnScripts, ...changeTypeScripts]; diff --git a/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js b/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js index 8ec55da..b44740f 100644 --- a/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js +++ b/forward_engineering/helpers/alterScriptHelpers/alterUdtHelper.js @@ -1,35 +1,46 @@ const { checkFieldPropertiesChanged } = require('./common'); const templates = require('../../configs/templates'); - -const getCreateUdtScript = (app, dbVersion) => jsonSchema => { - const _ = app.require('lodash'); - const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_); - const ddlProvider = require('../../ddlProvider')(null, null, app); - - const schemaData = { dbVersion }; - - const columnDefinitions = _.toPairs(jsonSchema.properties || {}).map(([name, column]) => - createColumnDefinitionBySchema({ - name, - jsonSchema: column, - parentJsonSchema: jsonSchema, +const getCreateUdtScript = + ({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions }) => + jsonSchema => { + const _ = app.require('lodash'); + const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(app); + const ddlProvider = require('../../ddlProvider')(null, null, app); + const { getDefinitionByReference } = app.require('@hackolade/ddl-fe-utils'); + + const schemaData = { dbVersion }; + + const columnDefinitions = _.toPairs(jsonSchema.properties || {}).map(([name, column]) => { + const definitionJsonSchema = getDefinitionByReference({ + propertySchema: column, + modelDefinitions, + internalDefinitions, + externalDefinitions, + }); + + return createColumnDefinitionBySchema({ + name, + jsonSchema: column, + parentJsonSchema: jsonSchema, + ddlProvider, + schemaData, + definitionJsonSchema, + }); + }); + + const updatedUdt = createColumnDefinitionBySchema({ + name: jsonSchema.code || jsonSchema.name, + jsonSchema: jsonSchema, + parentJsonSchema: { required: [] }, + definitionJsonSchema: {}, ddlProvider, schemaData, - }), - ); - - const updatedUdt = createColumnDefinitionBySchema({ - name: jsonSchema.code || jsonSchema.name, - jsonSchema: jsonSchema, - parentJsonSchema: { required: [] }, - ddlProvider, - schemaData, - }); - - const udt = { ...updatedUdt, properties: columnDefinitions }; - return ddlProvider.createUdt(udt); -}; + }); + + const udt = { ...updatedUdt, properties: columnDefinitions }; + return ddlProvider.createUdt(udt); + }; const getDeleteUdtScript = app => udt => { const _ = app.require('lodash'); @@ -38,29 +49,40 @@ const getDeleteUdtScript = app => udt => { return `DROP TYPE ${wrapInQuotes(udt.code || udt.name)};`; }; -const getAddColumnToTypeScript = (app, dbVersion) => udt => { - const _ = app.require('lodash'); - const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(_); - const { wrapInQuotes } = require('../general')({ _ }); - const ddlProvider = require('../../ddlProvider')(null, null, app); - - const fullName = wrapInQuotes(udt.code || udt.name); - const schemaData = { dbVersion }; - - return _.toPairs(udt.properties) - .filter(([name, jsonSchema]) => !jsonSchema.compMod) - .map(([name, jsonSchema]) => - createColumnDefinitionBySchema({ - name, - jsonSchema, - parentJsonSchema: { required: [] }, - ddlProvider, - schemaData, - }), - ) - .map(data => ddlProvider.convertColumnDefinition(data, templates.objectTypeColumnDefinition)) - .map(script => `ALTER TYPE ${fullName} ADD ATTRIBUTE ${script};`); -}; +const getAddColumnToTypeScript = + ({ app, dbVersion, modelDefinitions, internalDefinitions, externalDefinitions }) => + udt => { + const _ = app.require('lodash'); + const { createColumnDefinitionBySchema } = require('./createColumnDefinition')(app); + const { wrapInQuotes } = require('../general')({ _ }); + const ddlProvider = require('../../ddlProvider')(null, null, app); + const { getDefinitionByReference } = app.require('@hackolade/ddl-fe-utils'); + + const fullName = wrapInQuotes(udt.code || udt.name); + const schemaData = { dbVersion }; + + return _.toPairs(udt.properties) + .filter(([name, jsonSchema]) => !jsonSchema.compMod) + .map(([name, jsonSchema]) => { + const definitionJsonSchema = getDefinitionByReference({ + propertySchema: jsonSchema, + modelDefinitions, + internalDefinitions, + externalDefinitions, + }); + + return createColumnDefinitionBySchema({ + name, + jsonSchema, + parentJsonSchema: { required: [] }, + ddlProvider, + schemaData, + definitionJsonSchema, + }); + }) + .map(data => ddlProvider.convertColumnDefinition(data, templates.objectTypeColumnDefinition)) + .map(script => `ALTER TYPE ${fullName} ADD ATTRIBUTE ${script};`); + }; const getDeleteColumnFromTypeScript = app => udt => { const _ = app.require('lodash'); @@ -91,9 +113,9 @@ const getModifyColumnOfTypeScript = app => udt => { .filter(([name, jsonSchema]) => checkFieldPropertiesChanged(jsonSchema.compMod, ['type', 'mode'])) .map( ([name, jsonSchema]) => - `ALTER TYPE ${fullName} MODIFY ATTRIBUTE ${wrapInQuotes(name)} ${ - _.toUpper(jsonSchema.compMod.newField.mode || jsonSchema.compMod.newField.type) - };`, + `ALTER TYPE ${fullName} MODIFY ATTRIBUTE ${wrapInQuotes(name)} ${_.toUpper( + jsonSchema.compMod.newField.mode || jsonSchema.compMod.newField.type, + )};`, ); return [...renameColumnScripts, ...changeTypeScripts]; diff --git a/forward_engineering/helpers/alterScriptHelpers/createColumnDefinition.js b/forward_engineering/helpers/alterScriptHelpers/createColumnDefinition.js index cf5da4e..e77e6f5 100644 --- a/forward_engineering/helpers/alterScriptHelpers/createColumnDefinition.js +++ b/forward_engineering/helpers/alterScriptHelpers/createColumnDefinition.js @@ -1,42 +1,6 @@ -module.exports = _ => { - const createColumnDefinition = data => { - return Object.assign( - { - name: '', - type: '', - nullable: true, - primaryKey: false, - default: '', - length: '', - scale: '', - precision: '', - comment: '', - }, - data, - ); - }; - - const isNullable = (parentSchema, propertyName) => { - if (!Array.isArray(parentSchema.required)) { - return true; - } - - return !parentSchema.required.includes(propertyName); - }; - - const getLength = jsonSchema => { - if (_.isNumber(jsonSchema.length)) { - return jsonSchema.length; - } else if (_.isNumber(jsonSchema.maxLength)) { - return jsonSchema.maxLength; - } else { - return ''; - } - }; - - const getNumber = val => _.isNumber(val) ? val : ''; - - const getObject = val => _.isPlainObject(val) && !_.isEmpty(val) ? val : ''; +module.exports = app => { + const _ = app.require('lodash'); + const { createColumnDefinition } = app.require('@hackolade/ddl-fe-utils'); const getType = jsonSchema => { if (jsonSchema.$ref) { @@ -46,36 +10,22 @@ module.exports = _ => { return _.toUpper(jsonSchema.mode || jsonSchema.childType || jsonSchema.type); }; - const createColumnDefinitionBySchema = ({ name, jsonSchema, parentJsonSchema, ddlProvider, schemaData }) => { - const columnDefinition = createColumnDefinition({ - name: name, - type: getType(jsonSchema), - ofType: jsonSchema.ofType, - nullable: isNullable(parentJsonSchema, name), - default: jsonSchema.default, - primaryKey: jsonSchema.primaryKey, - unique: jsonSchema.unique, - length: getLength(jsonSchema), - scale: getNumber(jsonSchema.scale), - precision: getNumber(jsonSchema.precision), - comment: jsonSchema.description, - fractSecPrecision: getNumber(jsonSchema.fractSecPrecision), - withTimeZone: getNumber(jsonSchema.withTimeZone), - localTimeZone: getNumber(jsonSchema.localTimeZone), - yearPrecision: getNumber(jsonSchema.yearPrecision), - dayPrecision: getNumber(jsonSchema.dayPrecision), - lengthSemantics: jsonSchema.lengthSemantics, - encryption: getObject(jsonSchema.encryption), - isActivated: jsonSchema.isActivated, - }); - - return ddlProvider.hydrateColumn({ - columnDefinition, - jsonSchema: { - ...jsonSchema, - type: columnDefinition.type, - }, + const createColumnDefinitionBySchema = ({ + name, + jsonSchema, + parentJsonSchema, + ddlProvider, + schemaData, + definitionJsonSchema, + }) => { + return createColumnDefinition({ + name, + jsonSchema, + parentJsonSchema, + ddlProvider, schemaData, + definitionJsonSchema, + getType, }); }; diff --git a/package.json b/package.json index 2c9b547..99712b3 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "versionDate": "2022-05-06", "author": "hackolade", "engines": { - "hackolade": "6.0.7", + "hackolade": "6.0.8", "hackoladePlugin": "1.2.0" }, "contributes": {