UNPKG

gen-jhipster

Version:

Spring Boot + Angular/React/Vue in one handy generator

747 lines (743 loc) 39.8 kB
/** * Copyright 2013-2024 the original author or authors from the JHipster project. * * This file is part of the JHipster project, see https://www.jhipster.tech/ * for more information. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import fs from 'fs'; import { escape, min } from 'lodash-es'; import BaseEntityChangesGenerator from '../base-entity-changes/index.js'; import { getFKConstraintName, getUXConstraintName, prepareEntity as prepareEntityForServer } from '../server/support/index.js'; import { loadRequiredConfigIntoEntity, prepareEntity, prepareEntityPrimaryKeyForTemplates, prepareField, prepareRelationship, } from '../base-application/support/index.js'; import { prepareSqlApplicationProperties } from '../spring-data-relational/support/index.js'; import { fieldTypes } from '../../lib/jhipster/index.js'; import { liquibaseFiles } from './files.js'; import { liquibaseComment, postPrepareEntity, prepareField as prepareFieldForLiquibase, prepareRelationshipForLiquibase, } from './support/index.js'; import mavenPlugin from './support/maven-plugin.js'; import { addLiquibaseChangelogCallback, addLiquibaseConstraintsChangelogCallback, addLiquibaseIncrementalChangelogCallback, } from './internal/needles.js'; import { addEntityFiles, fakeFiles, updateConstraintsFiles, updateEntityFiles, updateMigrateFiles } from './changelog-files.js'; const { CommonDBTypes: { LONG: TYPE_LONG, INTEGER: TYPE_INTEGER }, } = fieldTypes; export default class LiquibaseGenerator extends BaseEntityChangesGenerator { recreateInitialChangelog; numberOfRows; databaseChangelogs = []; injectBuildTool = true; injectLogs = true; constructor(args, options, features) { super(args, options, { skipParseOptions: false, ...features }); this.argument('entities', { description: 'Which entities to generate a new changelog', type: Array, required: false, }); this.recreateInitialChangelog = this.options.recreateInitialChangelog ?? false; this.numberOfRows = 10; } async beforeQueue() { if (!this.fromBlueprint) { await this.composeWithBlueprints(); } if (!this.delegateToBlueprint) { await this.dependsOnBootstrapApplicationServer(); } } get preparing() { return this.asPreparingTaskGroup({ preparing({ application }) { application.liquibaseDefaultSchemaName = ''; // Generate h2 properties at master.xml for blueprints that uses h2 for tests or others purposes. application.liquibaseAddH2Properties = application.liquibaseAddH2Properties ?? application.devDatabaseTypeH2Any; }, checkDatabaseCompatibility({ application }) { if (!application.databaseTypeSql && !application.databaseTypeNeo4j) { throw new Error(`Database type ${application.databaseType} is not supported`); } if (!application.databaseTypeSql) { // Add sql related derived properties prepareSqlApplicationProperties({ application }); } }, addNeedles({ source, application }) { source.addLiquibaseChangelog = changelog => this.editFile(`${application.srcMainResources}config/liquibase/master.xml`, addLiquibaseChangelogCallback(changelog)); source.addLiquibaseIncrementalChangelog = changelog => this.editFile(`${application.srcMainResources}config/liquibase/master.xml`, addLiquibaseIncrementalChangelogCallback(changelog)); source.addLiquibaseConstraintsChangelog = changelog => this.editFile(`${application.srcMainResources}config/liquibase/master.xml`, addLiquibaseConstraintsChangelogCallback(changelog)); }, }); } get [BaseEntityChangesGenerator.PREPARING]() { return this.delegateTasksToBlueprint(() => this.preparing); } get preparingEachEntityField() { return this.asPreparingEachEntityFieldTaskGroup({ prepareEntityField({ application, field }) { if (!field.transient) { prepareFieldForLiquibase(application, field); } }, validateConsistencyOfField({ entity, field }) { if (field.columnRequired && field.liquibaseDefaultValueAttributeValue) { this.handleCheckFailure(`The field ${field.fieldName} in entity ${entity.name} has both columnRequired and a defaultValue, this can lead to unexpected behaviors.`); } }, }); } get [BaseEntityChangesGenerator.PREPARING_EACH_ENTITY_FIELD]() { return this.delegateTasksToBlueprint(() => this.preparingEachEntityField); } get preparingEachEntityRelationship() { return this.asPreparingEachEntityRelationshipTaskGroup({ prepareEntityRelationship({ entity, relationship }) { prepareRelationshipForLiquibase(entity, relationship); }, }); } get [BaseEntityChangesGenerator.PREPARING_EACH_ENTITY_RELATIONSHIP]() { return this.delegateTasksToBlueprint(() => this.preparingEachEntityRelationship); } get postPreparingEachEntity() { return this.asPostPreparingEachEntityTaskGroup({ postPrepareEntity, }); } get [BaseEntityChangesGenerator.POST_PREPARING_EACH_ENTITY]() { return this.delegateTasksToBlueprint(() => this.postPreparingEachEntity); } get default() { return this.asDefaultTaskGroup({ async calculateChangelogs({ application, entities, entityChanges }) { if (!application.databaseTypeSql || this.options.skipDbChangelog || !entityChanges) { return; } for (const databaseChangelog of entityChanges) { if (!databaseChangelog.newEntity) { // Previous entities are not prepared using default jhipster priorities. // Prepare them. const { previousEntity: entity } = databaseChangelog; loadRequiredConfigIntoEntity(entity, this.jhipsterConfigWithDefaults); prepareEntity(entity, this, application); prepareEntityForServer(entity, application); if (!entity.embedded && !entity.primaryKey) { prepareEntityPrimaryKeyForTemplates.call(this, { entity, application }); } for (const field of entity.fields ?? []) { prepareField(entity, field, this); prepareFieldForLiquibase(application, field); } } } for (const databaseChangelog of entityChanges) { if (!databaseChangelog.newEntity) { // Previous entities are not prepared using default jhipster priorities. // Prepare them. const { previousEntity: entity } = databaseChangelog; for (const relationship of entity.relationships ?? []) { prepareRelationship(entity, relationship, this, true); prepareRelationshipForLiquibase(entity, relationship); } postPrepareEntity.call(this, { application, entity }); } } const entitiesToWrite = this.options.entities ?? entities.filter(entity => !entity.builtIn && !entity.skipServer).map(entity => entity.name); // Write only specified entities changelogs. const changes = entityChanges.filter(databaseChangelog => entitiesToWrite.length === 0 || entitiesToWrite.includes(databaseChangelog.entityName)); for (const databaseChangelog of changes) { if (databaseChangelog.newEntity) { this.databaseChangelogs.push(this.prepareChangelog({ databaseChangelog: { ...databaseChangelog, changelogData: { ...databaseChangelog.changelogData }, }, application, })); } else if (databaseChangelog.addedFields.length > 0 || databaseChangelog.removedFields.length > 0) { this.databaseChangelogs.push(this.prepareChangelog({ databaseChangelog: { ...databaseChangelog, changelogData: { ...databaseChangelog.changelogData }, fieldChangelog: true, addedRelationships: [], removedRelationships: [], removedDefaultValueFields: [], addedDefaultValueFields: [], relationshipsToRecreateForeignKeysOnly: [], }, application, })); } } // Relationships needs to be added later to make sure every related field is already added. for (const databaseChangelog of changes) { if (databaseChangelog.incremental && (databaseChangelog.addedRelationships.length > 0 || databaseChangelog.removedRelationships.length > 0 || databaseChangelog.removedDefaultValueFields.length > 0 || databaseChangelog.addedDefaultValueFields.length > 0)) { this.databaseChangelogs.push(this.prepareChangelog({ databaseChangelog: { ...databaseChangelog, changelogData: { ...databaseChangelog.changelogData }, relationshipChangelog: true, addedFields: [], removedFields: [], }, application, })); } } this.databaseChangelogs = this.databaseChangelogs.filter(Boolean); }, }); } get [BaseEntityChangesGenerator.DEFAULT]() { return this.delegateTasksToBlueprint(() => this.default); } get writing() { return this.asWritingTaskGroup({ async writing({ application }) { const context = { ...application, recreateInitialChangelog: this.recreateInitialChangelog, }; await this.writeFiles({ sections: liquibaseFiles, context, }); }, }); } get [BaseEntityChangesGenerator.WRITING]() { return this.delegateTasksToBlueprint(() => this.writing); } get writingEntities() { return this.asWritingEntitiesTaskGroup({ writeChangelogs() { return Promise.all(this.databaseChangelogs.map(databaseChangelog => this.writeChangelog({ databaseChangelog }))); }, }); } get [BaseEntityChangesGenerator.WRITING_ENTITIES]() { return this.delegateTasksToBlueprint(() => this.writingEntities); } get postWriting() { return this.asPostWritingTaskGroup({ customizeSpringLogs({ source }) { if (!this.injectLogs) return; source.addLogbackMainLog?.({ name: 'liquibase', level: 'WARN' }); source.addLogbackMainLog?.({ name: 'LiquibaseSchemaResolver', level: 'INFO' }); source.addLogbackTestLog?.({ name: 'liquibase', level: 'WARN' }); source.addLogbackTestLog?.({ name: 'LiquibaseSchemaResolver', level: 'INFO' }); }, customizeApplicationProperties({ source, application }) { if (application.databaseTypeSql && !application.reactive) { source.addApplicationPropertiesContent?.({ property: 'private final Liquibase liquibase = new Liquibase();\n', propertyGetter: `public Liquibase getLiquibase() { return liquibase; } `, propertyClass: `public static class Liquibase { private Boolean asyncStart = true; public Boolean getAsyncStart() { return asyncStart; } public void setAsyncStart(Boolean asyncStart) { this.asyncStart = asyncStart; } } `, }); } }, customizeMaven({ source, application }) { if (!application.buildToolMaven || !this.injectBuildTool) return; if (!application.javaDependencies) { throw new Error('Some application fields are be mandatory'); } const { javaDependencies } = application; const shouldAddProperty = (property, value) => { return value && !source.hasJavaProperty?.(property) && application.javaManagedProperties[property] !== value; }; const checkProperty = (property) => { if (!source.hasJavaManagedProperty?.(property) && !source.hasJavaProperty?.(property)) { const message = `${property} is required by maven-liquibase-plugin, make sure to add it to your pom.xml`; if (this.skipChecks) { this.log.warn(message); } else { throw new Error(message); } } }; const { 'jakarta-validation': validationVersion, h2: h2Version, liquibase: liquibaseVersion } = javaDependencies; const applicationAny = application; const databaseTypeProfile = applicationAny.devDatabaseTypeH2Any ? 'prod' : undefined; let liquibasePluginHibernateDialect; let liquibasePluginJdbcDriver; const mavenProperties = []; if (applicationAny.devDatabaseTypeH2Any) { // eslint-disable-next-line no-template-curly-in-string liquibasePluginHibernateDialect = '${liquibase-plugin.hibernate-dialect}'; // eslint-disable-next-line no-template-curly-in-string liquibasePluginJdbcDriver = '${liquibase-plugin.driver}'; if (shouldAddProperty('h2.version', h2Version)) { mavenProperties.push({ property: 'h2.version', value: h2Version }); } else { checkProperty('h2.version'); } mavenProperties.push({ property: 'liquibase-plugin.hibernate-dialect' }, { property: 'liquibase-plugin.driver' }, { inProfile: 'dev', property: 'liquibase-plugin.hibernate-dialect', value: applicationAny.devHibernateDialect }, { inProfile: 'prod', property: 'liquibase-plugin.hibernate-dialect', value: applicationAny.prodHibernateDialect }, { inProfile: 'dev', property: 'liquibase-plugin.driver', value: applicationAny.devJdbcDriver }, { inProfile: 'prod', property: 'liquibase-plugin.driver', value: applicationAny.prodJdbcDriver }); } else { liquibasePluginHibernateDialect = applicationAny.prodHibernateDialect; liquibasePluginJdbcDriver = applicationAny.prodJdbcDriver; } if (shouldAddProperty('jakarta-validation.version', validationVersion)) { mavenProperties.push({ property: 'jakarta-validation.version', value: validationVersion }); } else { checkProperty('jakarta-validation.version'); } if (shouldAddProperty('liquibase.version', liquibaseVersion)) { mavenProperties.push({ property: 'liquibase.version', value: liquibaseVersion }); } else { checkProperty('liquibase.version'); } source.addMavenDefinition?.({ properties: [ ...mavenProperties, { inProfile: 'no-liquibase', property: 'profile.no-liquibase', value: ',no-liquibase' }, { property: 'profile.no-liquibase' }, { property: 'liquibase-plugin.url' }, { property: 'liquibase-plugin.username' }, { property: 'liquibase-plugin.password' }, { inProfile: 'dev', property: 'liquibase-plugin.url', value: applicationAny.devLiquibaseUrl }, { inProfile: 'dev', property: 'liquibase-plugin.username', value: applicationAny.devDatabaseUsername }, { inProfile: 'dev', property: 'liquibase-plugin.password', value: applicationAny.devDatabasePassword }, { inProfile: 'prod', property: 'liquibase-plugin.url', value: applicationAny.prodLiquibaseUrl }, { inProfile: 'prod', property: 'liquibase-plugin.username', value: applicationAny.prodDatabaseUsername }, { inProfile: 'prod', property: 'liquibase-plugin.password', value: applicationAny.prodDatabasePassword }, ], pluginManagement: [ { groupId: 'org.liquibase', artifactId: 'liquibase-maven-plugin', // eslint-disable-next-line no-template-curly-in-string version: '${liquibase.version}', additionalContent: mavenPlugin({ backendTypeSpringBoot: application.backendTypeSpringBoot, reactive: application.reactive, packageName: application.packageName, srcMainResources: application.srcMainResources, authenticationTypeOauth2: application.authenticationTypeOauth2, devDatabaseTypeH2Any: applicationAny.devDatabaseTypeH2Any, driver: liquibasePluginJdbcDriver, hibernateDialect: liquibasePluginHibernateDialect, defaultSchemaName: application.liquibaseDefaultSchemaName, // eslint-disable-next-line no-template-curly-in-string url: '${liquibase-plugin.url}', // eslint-disable-next-line no-template-curly-in-string username: '${liquibase-plugin.username}', // eslint-disable-next-line no-template-curly-in-string password: '${liquibase-plugin.password}', }), }, ], dependencies: [ { groupId: 'org.liquibase', artifactId: 'liquibase-core', // eslint-disable-next-line no-template-curly-in-string version: '${liquibase.version}', }, ], }); if (applicationAny.prodDatabaseTypeMssql) { source.addMavenDependency?.({ inProfile: databaseTypeProfile, groupId: 'org.liquibase.ext', artifactId: 'liquibase-mssql', // eslint-disable-next-line no-template-curly-in-string version: '${liquibase.version}', }); } if (applicationAny.databaseTypeNeo4j) { if (applicationAny.backendTypeSpringBoot) { source.addMavenDependency?.([{ groupId: 'org.springframework', artifactId: 'spring-jdbc' }]); } source.addMavenDependency?.([ { groupId: 'org.liquibase.ext', artifactId: 'liquibase-neo4j', // eslint-disable-next-line no-template-curly-in-string version: '${liquibase.version}', // Exclude current neo4j driver and use the one provided by spring-data // See: https://github.com/jhipster/gen-jhipster/pull/24241 additionalContent: ` <exclusions> <exclusion> <groupId>org.neo4j.driver</groupId> <artifactId>neo4j-java-driver</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>*</artifactId> </exclusion> </exclusions>`, }, ]); } }, injectGradle({ source, application }) { if (!application.buildToolGradle || !this.injectBuildTool) return; if (!application.javaDependencies) { throw new Error('Some application fields are be mandatory'); } const { liquibase: liquibaseVersion, 'gradle-liquibase': gradleLiquibaseVersion } = application.javaDependencies; if (!liquibaseVersion) { this.log.warn('liquibaseVersion is required by gradle-liquibase-plugin, make sure to add it to your dependencies'); } else { source.addGradleProperty?.({ property: 'liquibaseVersion', value: liquibaseVersion }); } source.addGradleProperty?.({ property: 'liquibaseTaskPrefix', value: 'liquibase' }); source.addGradleProperty?.({ property: 'liquibasePluginVersion', value: gradleLiquibaseVersion }); source.applyFromGradle?.({ script: 'gradle/liquibase.gradle' }); source.addGradlePlugin?.({ id: 'org.liquibase.gradle' }); // eslint-disable-next-line no-template-curly-in-string source.addGradlePluginManagement?.({ id: 'org.liquibase.gradle', version: '${liquibasePluginVersion}' }); if (application.databaseTypeSql && !application.reactive) { source.addGradleDependency?.({ scope: 'liquibaseRuntime', groupId: 'org.liquibase.ext', artifactId: 'liquibase-hibernate6', // eslint-disable-next-line no-template-curly-in-string version: liquibaseVersion ? '${liquibaseVersion}' : "${dependencyManagement.importedProperties['liquibase.version']}", }, { gradleFile: 'gradle/liquibase.gradle' }); } }, nativeHints({ source, application }) { if (!application.graalvmSupport) return; // Latest liquibase version supported by Reachability Repository is 4.23.0 // Hints may be dropped if newer version is supported // https://github.com/oracle/graalvm-reachability-metadata/blob/master/metadata/org.liquibase/liquibase-core/index.json source.addNativeHint({ resources: ['config/liquibase/*'], declaredConstructors: [ 'liquibase.database.LiquibaseTableNamesFactory.class', 'liquibase.report.ShowSummaryGeneratorFactory.class', 'liquibase.changelog.FastCheckService.class', 'liquibase.changelog.visitor.ValidatingVisitorGeneratorFactory.class', ], publicConstructors: ['liquibase.ui.LoggerUIService.class'], }); }, }); } get [BaseEntityChangesGenerator.POST_WRITING]() { return this.delegateTasksToBlueprint(() => this.postWriting); } get postWritingEntities() { return this.asPostWritingEntitiesTaskGroup({ postWriteChangelogs({ source }) { return Promise.all(this.databaseChangelogs.map(databaseChangelog => this.postWriteChangelog({ source, databaseChangelog }))); }, }); } get [BaseEntityChangesGenerator.POST_WRITING_ENTITIES]() { return this.delegateTasksToBlueprint(() => this.postWritingEntities); } /* ======================================================================== */ /* private methods use within generator */ /* ======================================================================== */ isChangelogNew({ entityName, changelogDate }) { return !fs.existsSync(this.destinationPath(`src/main/resources/config/liquibase/changelog/${changelogDate}_added_entity_${entityName}.xml`)); } /** * Write files for new entities. */ _writeLiquibaseFiles({ context: writeContext, changelogData }) { const promises = []; const context = { ...writeContext, skipFakeData: changelogData.skipFakeData, fields: changelogData.allFields, allFields: changelogData.allFields, relationships: changelogData.relationships, }; // Write initial liquibase files promises.push(this.writeFiles({ sections: addEntityFiles, context })); if (!changelogData.skipFakeData) { promises.push(this.writeFiles({ sections: fakeFiles, context })); } return Promise.all(promises); } /** * Write files for new entities. */ _addLiquibaseFilesReferences({ entity, databaseChangelog, source }) { const fileName = `${databaseChangelog.changelogDate}_added_entity_${entity.entityClass}`; source.addLiquibaseChangelog({ changelogName: fileName, section: entity.incremental ? 'incremental' : 'base' }); if (entity.anyRelationshipIsOwnerSide) { const constFileName = `${databaseChangelog.changelogDate}_added_entity_constraints_${entity.entityClass}`; source.addLiquibaseChangelog({ changelogName: constFileName, section: entity.incremental ? 'incremental' : 'constraints' }); } } /** * Write files for updated entities. */ _writeUpdateFiles({ context: writeContext, changelogData }) { const { addedFields, allFields, removedFields, addedRelationships, removedRelationships, hasFieldConstraint, hasRelationshipConstraint, shouldWriteAnyRelationship, relationshipsToRecreateForeignKeysOnly, hasDefaultValueChange, removedDefaultValueFields, addedDefaultValueFields, } = changelogData; const context = { ...writeContext, skipFakeData: changelogData.skipFakeData, addedFields, removedFields, fields: addedFields, allFields, hasFieldConstraint, addedRelationships, removedRelationships, relationships: addedRelationships, hasRelationshipConstraint, shouldWriteAnyRelationship, relationshipsToRecreateForeignKeysOnly, hasDefaultValueChange, removedDefaultValueFields, addedDefaultValueFields, }; const promises = []; if (this._isBasicEntityUpdate(changelogData)) { promises.push(this.writeFiles({ sections: updateEntityFiles, context })); } if (this._requiresWritingFakeData(changelogData)) { promises.push(this.writeFiles({ sections: fakeFiles, context })); promises.push(this.writeFiles({ sections: updateMigrateFiles, context })); } if (this._requiresConstraintUpdates(changelogData)) { promises.push(this.writeFiles({ sections: updateConstraintsFiles, context })); } return Promise.all(promises); } _requiresConstraintUpdates(changelogData) { return changelogData.hasFieldConstraint || changelogData.addedRelationships.length > 0 || changelogData.hasDefaultValueChange; } _isBasicEntityUpdate(changelogData) { return changelogData.addedFields.length > 0 || changelogData.removedFields.length > 0 || changelogData.shouldWriteAnyRelationship; } _requiresWritingFakeData(changelogData) { return !changelogData.skipFakeData && (changelogData.addedFields.length || changelogData.addedRelationships.length); } /** * Write files for updated entities. */ _addUpdateFilesReferences({ entity, databaseChangelog, changelogData, source }) { if (this._isBasicEntityUpdate(changelogData)) { source.addLiquibaseIncrementalChangelog({ changelogName: `${databaseChangelog.changelogDate}_updated_entity_${entity.entityClass}` }); } if (this._requiresWritingFakeData(changelogData)) { source.addLiquibaseIncrementalChangelog({ changelogName: `${databaseChangelog.changelogDate}_updated_entity_migrate_${entity.entityClass}`, }); } if (this._requiresConstraintUpdates(changelogData)) { source.addLiquibaseIncrementalChangelog({ changelogName: `${databaseChangelog.changelogDate}_updated_entity_constraints_${entity.entityClass}`, }); } } /** * @private * Format As Liquibase Remarks * * @param {string} text - text to format * @param {boolean} addRemarksTag - add remarks tag * @returns formatted liquibase remarks */ formatAsLiquibaseRemarks(text, addRemarksTag = false) { return liquibaseComment(text, addRemarksTag); } /** * @private * Create the fitting liquibase default value attribute for a field. * @param field * @param leadingWhitespace * @returns */ createDefaultValueLiquibaseAttribute(field, leadingWhitespace = false) { if (field.liquibaseDefaultValueAttributeValue === undefined) { return ''; } return `${leadingWhitespace ? ' ' : ''}${field.liquibaseDefaultValueAttributeName}="${escape(field.liquibaseDefaultValueAttributeValue)}"`; } prepareChangelog({ databaseChangelog, application }) { if (!databaseChangelog.changelogDate) { databaseChangelog.changelogDate = this.dateFormatForLiquibase(); } const entity = databaseChangelog.entity; if (entity.skipServer) { return undefined; } const entityChanges = databaseChangelog.changelogData; entityChanges.skipFakeData = application.skipFakeData || entity.skipFakeData; entityChanges.allFields = entity.fields.filter(field => !field.transient); if (databaseChangelog.newEntity) { entityChanges.fields = entityChanges.allFields; } else { entityChanges.addedFields = databaseChangelog.addedFields.filter(field => !field.transient); entityChanges.removedFields = databaseChangelog.removedFields.filter(field => !field.transient); } const seed = `${entity.entityClass}-liquibase`; this.resetEntitiesFakeData(seed); entity.liquibaseFakeData = []; // fakeDataCount must be limited to the size of required unique relationships. Object.defineProperty(entity, 'fakeDataCount', { get: () => { const uniqueRelationships = entity.relationships.filter(rel => rel.unique && (rel.columnRequired || rel.id)); return min([entity.liquibaseFakeData.length, ...uniqueRelationships.map(rel => rel.otherEntity.fakeDataCount)]); }, configurable: true, }); for (let rowNumber = 0; rowNumber < this.numberOfRows; rowNumber++) { const rowData = {}; const fields = databaseChangelog.newEntity ? // generate id fields first to improve reproducibility [...entityChanges.fields.filter(f => f.id), ...entityChanges.fields.filter(f => !f.id)] : [...entityChanges.allFields.filter(f => f.id), ...entityChanges.addedFields.filter(f => !f.id)]; fields.forEach(field => { if (field.derived) { Object.defineProperty(rowData, field.fieldName, { get: () => { if (!field.derivedEntity.liquibaseFakeData || rowNumber >= field.derivedEntity.liquibaseFakeData.length) { return undefined; } return field.derivedEntity.liquibaseFakeData[rowNumber][field.fieldName]; }, }); return; } let data; if (field.id && [TYPE_INTEGER, TYPE_LONG].includes(field.fieldType)) { data = rowNumber + 1; } else { data = field.generateFakeData(); } rowData[field.fieldName] = data; }); entity.liquibaseFakeData.push(rowData); } if (databaseChangelog.newEntity) { entityChanges.relationships = entity.relationships; } else { entityChanges.addedRelationships = databaseChangelog.addedRelationships; entityChanges.removedRelationships = databaseChangelog.removedRelationships; entityChanges.relationshipsToRecreateForeignKeysOnly = databaseChangelog.relationshipsToRecreateForeignKeysOnly; entityChanges.removedDefaultValueFields = databaseChangelog.removedDefaultValueFields; entityChanges.addedDefaultValueFields = databaseChangelog.addedDefaultValueFields; } /* Required by the templates */ databaseChangelog.writeContext = { entity, databaseChangelog, changelogDate: databaseChangelog.changelogDate, databaseType: entity.databaseType, prodDatabaseType: entity.prodDatabaseType, authenticationType: entity.authenticationType, jhiPrefix: entity.jhiPrefix, reactive: application.reactive, incrementalChangelog: application.incrementalChangelog, recreateInitialChangelog: this.recreateInitialChangelog, }; if (databaseChangelog.newEntity) { return databaseChangelog; } entityChanges.requiresUpdateChangelogs = entityChanges.addedFields.length > 0 || entityChanges.removedFields.length > 0 || entityChanges.addedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) || entityChanges.removedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) || entityChanges.addedDefaultValueFields.length > 0 || entityChanges.removedDefaultValueFields.length > 0; if (entityChanges.requiresUpdateChangelogs) { entityChanges.hasFieldConstraint = entityChanges.addedFields.some(field => field.unique || (field.columnRequired && !field.liquibaseDefaultValueAttributeValue) || field.shouldCreateContentType); entityChanges.hasDefaultValueChange = entityChanges.addedDefaultValueFields.length > 0 || entityChanges.removedDefaultValueFields.length > 0; entityChanges.hasRelationshipConstraint = entityChanges.addedRelationships.some(relationship => (relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) && (relationship.unique || !relationship.nullable)); entityChanges.shouldWriteAnyRelationship = entityChanges.addedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) || entityChanges.removedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable); } return databaseChangelog; } writeChangelog({ databaseChangelog }) { const { writeContext: context, changelogData } = databaseChangelog; if (databaseChangelog.newEntity) { return this._writeLiquibaseFiles({ context, changelogData }); } if (changelogData.requiresUpdateChangelogs) { return this._writeUpdateFiles({ context, changelogData }); } return undefined; } postWriteChangelog({ databaseChangelog, source }) { const { entity, changelogData } = databaseChangelog; if (entity.skipServer) { return undefined; } if (databaseChangelog.newEntity) { return this._addLiquibaseFilesReferences({ entity, databaseChangelog, source }); } if (changelogData.requiresUpdateChangelogs) { return this._addUpdateFilesReferences({ entity, databaseChangelog, changelogData, source }); } return undefined; } /** * @private * get a foreign key constraint name for tables in JHipster preferred style. * * @param {string} entityName - name of the entity * @param {string} relationshipName - name of the related entity * @param {string} prodDatabaseType - database type * @param {boolean} noSnakeCase - do not convert names to snakecase */ getFKConstraintName(entityName, relationshipName, prodDatabaseType, noSnakeCase) { const result = getFKConstraintName(entityName, relationshipName, { prodDatabaseType, noSnakeCase }); this.validateResult(result); return result.value; } /** * @private * get a unique constraint name for tables in JHipster preferred style. * * @param {string} entityName - name of the entity * @param {string} columnName - name of the column * @param {string} prodDatabaseType - database type * @param {boolean} noSnakeCase - do not convert names to snakecase */ getUXConstraintName(entityName, columnName, prodDatabaseType, noSnakeCase) { const result = getUXConstraintName(entityName, columnName, { prodDatabaseType, noSnakeCase }); this.validateResult(result); return result.value; } }