UNPKG

generator-pyhipster

Version:

Python (Flask) + Angular/React/Vue in one handy generator

407 lines (361 loc) 15.5 kB
/** * Copyright 2013-2022 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. */ const assert = require('assert'); const _ = require('lodash'); const BaseBlueprintGenerator = require('../generator-base-blueprint'); const { LOADING_PRIORITY, PREPARING_PRIORITY, DEFAULT_PRIORITY, WRITING_PRIORITY, PREPARING_RELATIONSHIPS_PRIORITY, POST_WRITING_PRIORITY, } = require('../../lib/constants/priorities.cjs').compat; const { addEntityFiles, updateEntityFiles, updateConstraintsFiles, updateMigrateFiles, fakeFiles } = require('./files'); const { SQL } = require('../../jdl/jhipster/database-types'); const { stringify } = require('../../utils'); const { CommonDBTypes } = require('../../jdl/jhipster/field-types'); const { GENERATOR_DATABASE_CHANGELOG_LIQUIBASE } = require('../generator-list'); const TYPE_LONG = CommonDBTypes.LONG; const constants = require('../generator-constants'); const { LIQUIBASE_DTD_VERSION } = constants; const { prepareFieldForTemplates } = require('../../utils/field'); const { prepareRelationshipForTemplates } = require('../../utils/relationship'); const { prepareFieldForLiquibaseTemplates } = require('../../utils/liquibase'); /* eslint-disable consistent-return */ module.exports = class extends BaseBlueprintGenerator { constructor(args, options, features) { super(args, options, features); if (this.options.help) return; assert(this.options.databaseChangelog, 'Changelog is required'); this.databaseChangelog = this.options.databaseChangelog; if (!this.databaseChangelog.changelogDate) { this.databaseChangelog.changelogDate = this.dateFormatForLiquibase(); } // Set number of rows to be generated this.numberOfRows = 10; } async _postConstruct() { if (!this.fromBlueprint) { await this.composeWithBlueprints(GENERATOR_DATABASE_CHANGELOG_LIQUIBASE); } } _loading() { return { loadSharedConfig() { this.loadAppConfig(); this.loadDerivedAppConfig(); this.loadClientConfig(); this.loadDerivedClientConfig(); this.loadServerConfig(); this.loadTranslationConfig(); this.loadPlatformConfig(); }, }; } get [LOADING_PRIORITY]() { if (this.delegateToBlueprint) return {}; return this._loading(); } _preparing() { return { prepareEntityForTemplates() { const databaseChangelog = this.databaseChangelog; this.entity = this.configOptions.sharedEntities[databaseChangelog.entityName]; if (!this.entity) { throw new Error(`Shared entity ${databaseChangelog.entityName} was not found`); } this.allFields = this.entity.fields .filter(field => !field.transient) .map(field => prepareFieldForLiquibaseTemplates(this.entity, field)); if (databaseChangelog.type === 'entity-new') { this.fields = this.allFields; } else { this.addedFields = this.databaseChangelog.addedFields .map(field => prepareFieldForTemplates(this.entity, field, this)) .filter(field => !field.transient) .map(field => prepareFieldForLiquibaseTemplates(this.entity, field)); this.removedFields = this.databaseChangelog.removedFields .map(field => prepareFieldForTemplates(this.entity, field, this)) .filter(field => !field.transient) .map(field => prepareFieldForLiquibaseTemplates(this.entity, field)); } }, prepareFakeData() { const databaseChangelog = this.databaseChangelog; this.entity.liquibaseFakeData = []; // fakeDataCount must be limited to the size of required unique relationships. Object.defineProperty(this.entity, 'fakeDataCount', { get: () => { const uniqueRelationships = this.entity.relationships.filter(rel => rel.unique && (rel.relationshipRequired || rel.id)); return _.min([this.entity.liquibaseFakeData.length, ...uniqueRelationships.map(rel => rel.otherEntity.fakeDataCount)]); }, }); for (let rowNumber = 0; rowNumber < this.numberOfRows; rowNumber++) { const rowData = {}; const fields = databaseChangelog.type === 'entity-new' ? // generate id fields first to improve reproducibility [...this.fields.filter(f => f.id), ...this.fields.filter(f => !f.id)] : [...this.allFields.filter(f => f.id), ...this.addedFields.filter(f => !f.id)]; fields.forEach((field, idx) => { 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 && field.fieldType === TYPE_LONG) { data = rowNumber + 1; } else { data = field.generateFakeData(); } rowData[field.fieldName] = data; }); this.entity.liquibaseFakeData.push(rowData); } this.configOptions.sharedLiquibaseFakeData = this.configOptions.sharedLiquibaseFakeData || {}; this.configOptions.sharedLiquibaseFakeData[_.upperFirst(this.entity.name)] = this.entity.liquibaseFakeData; }, }; } get [PREPARING_PRIORITY]() { if (this.delegateToBlueprint) return {}; return this._preparing(); } _preparingRelationships() { return { prepareRelationshipsForTemplates() { const databaseChangelog = this.databaseChangelog; if (databaseChangelog.type === 'entity-new') { this.relationships = this.entity.relationships.map(relationship => this._prepareRelationshipForTemplates(this.entity, relationship) ); } else { this.addedRelationships = this.databaseChangelog.addedRelationships .map(relationship => { const otherEntityName = this._.upperFirst(relationship.otherEntityName); relationship.otherEntity = this.configOptions.sharedEntities[otherEntityName]; if (!relationship.otherEntity) { throw new Error( `Error at entity ${this.entity.name}: could not find the entity of the relationship ${stringify(relationship)}` ); } return relationship; }) .map(relationship => prepareRelationshipForTemplates(this.entity, relationship, this)) .map(relationship => this._prepareRelationshipForTemplates(this.entity, relationship)); this.removedRelationships = this.databaseChangelog.removedRelationships .map(relationship => { const otherEntityName = this._.upperFirst(relationship.otherEntityName); relationship.otherEntity = this.configOptions.oldSharedEntities[otherEntityName]; if (!relationship.otherEntity) { throw new Error( `Error at entity ${this.entity.name}: could not find the entity of the relationship ${stringify(relationship)}` ); } return relationship; }) .map(relationship => prepareRelationshipForTemplates(this.entity, relationship, this, true)) .map(relationship => this._prepareRelationshipForTemplates(this.entity, relationship)); } }, }; } get [PREPARING_RELATIONSHIPS_PRIORITY]() { if (this.delegateToBlueprint) return {}; return this._preparingRelationships(); } // Public API method used by the getter and also by Blueprints _default() { return { setupConstants() { // Make constants available in templates this.LIQUIBASE_DTD_VERSION = LIQUIBASE_DTD_VERSION; }, }; } get [DEFAULT_PRIORITY]() { if (this.delegateToBlueprint) return {}; return this._default(); } // Public API method used by the getter and also by Blueprints _writing() { return { writeLiquibaseFiles() { const config = this.jhipsterConfig; if (config.skipServer || this.entity.skipServer || config.databaseType !== SQL) { return undefined; } const databaseChangelog = this.databaseChangelog; /* Required by the templates */ Object.assign(this, { databaseChangelog, changelogDate: databaseChangelog.changelogDate, databaseType: this.entity.databaseType, prodDatabaseType: this.entity.prodDatabaseType, authenticationType: this.entity.authenticationType, jhiPrefix: this.entity.jhiPrefix, skipFakeData: this.entity.skipFakeData || config.skipFakeData, reactive: config.reactive, }); if (databaseChangelog.type === 'entity-new') { return this._writeLiquibaseFiles(); } if ( this.addedFields.length > 0 || this.removedFields.length > 0 || this.addedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) || this.removedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) ) { return this._writeUpdateFiles(); } return undefined; }, }; } get [WRITING_PRIORITY]() { if (this.delegateToBlueprint) return {}; if (this.options.skipWriting) { return {}; } return this._writing(); } // Public API method used by the getter and also by Blueprints _postWriting() { return { writeLiquibaseFiles() { const config = this.jhipsterConfig; if (config.skipServer || this.entity.skipServer || config.databaseType !== SQL) { return undefined; } if (this.databaseChangelog.type === 'entity-new') { return this._addLiquibaseFilesReferences(); } if ( this.addedFields.length > 0 || this.removedFields.length > 0 || this.addedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) || this.removedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) ) { return this._addUpdateFilesReferences(); } return undefined; }, }; } get [POST_WRITING_PRIORITY]() { if (this.delegateToBlueprint) return {}; if (this.options.skipWriting) { return {}; } return this._postWriting(); } /** * Write files for new entities. */ _writeLiquibaseFiles() { const promises = []; // Write initial liquibase files promises.push(this.writeFilesToDisk(addEntityFiles, this, false, this.sourceRoot())); if (!this.skipFakeData) { promises.push(this.writeFilesToDisk(fakeFiles, this, false, this.sourceRoot())); } return Promise.all(promises); } /** * Write files for new entities. */ _addLiquibaseFilesReferences() { const fileName = `${this.changelogDate}_added_entity_${this.entity.entityClass}`; if (this.incremental) { this.addIncrementalChangelogToLiquibase(fileName); } else { this.addChangelogToLiquibase(fileName); } if (this.entity.fieldsContainOwnerManyToMany || this.entity.fieldsContainOwnerOneToOne || this.entity.fieldsContainManyToOne) { const constFileName = `${this.changelogDate}_added_entity_constraints_${this.entity.entityClass}`; if (this.incremental) { this.addIncrementalChangelogToLiquibase(constFileName); } else { this.addConstraintsChangelogToLiquibase(constFileName); } } } /** * Write files for updated entities. */ _writeUpdateFiles() { this.hasFieldConstraint = this.addedFields.some(field => field.unique || !field.nullable); this.hasRelationshipConstraint = this.addedRelationships.some( relationship => (relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) && (relationship.unique || !relationship.nullable) ); this.shouldWriteAnyRelationship = this.addedRelationships.some( relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable ); const promises = []; promises.push(this.writeFilesToDisk(updateEntityFiles, this, false, this.sourceRoot())); if (!this.skipFakeData && (this.addedFields.length > 0 || this.shouldWriteAnyRelationship)) { this.fields = this.addedFields; this.relationships = this.addedRelationships; promises.push(this.writeFilesToDisk(fakeFiles, this, false, this.sourceRoot())); promises.push(this.writeFilesToDisk(updateMigrateFiles, this, false, this.sourceRoot())); } if (this.hasFieldConstraint || this.shouldWriteAnyRelationship) { promises.push(this.writeFilesToDisk(updateConstraintsFiles, this, false, this.sourceRoot())); } return Promise.all(promises); } /** * Write files for updated entities. */ _addUpdateFilesReferences() { this.addIncrementalChangelogToLiquibase(`${this.databaseChangelog.changelogDate}_updated_entity_${this.entity.entityClass}`); if (!this.skipFakeData && (this.addedFields.length > 0 || this.shouldWriteAnyRelationship)) { this.addIncrementalChangelogToLiquibase(`${this.databaseChangelog.changelogDate}_updated_entity_migrate_${this.entity.entityClass}`); } if (this.hasFieldConstraint || this.shouldWriteAnyRelationship) { this.addIncrementalChangelogToLiquibase( `${this.databaseChangelog.changelogDate}_updated_entity_constraints_${this.entity.entityClass}` ); } } _prepareRelationshipForTemplates(entity, relationship) { relationship.shouldWriteRelationship = relationship.relationshipType === 'many-to-one' || (relationship.relationshipType === 'one-to-one' && relationship.ownerSide === true); if (relationship.shouldWriteJoinTable) { const joinTableName = relationship.joinTable.name; const prodDatabaseType = entity.prodDatabaseType; _.defaults(relationship.joinTable, { constraintName: this.getFKConstraintName(joinTableName, entity.entityTableName, prodDatabaseType), otherConstraintName: this.getFKConstraintName(joinTableName, relationship.columnName, prodDatabaseType), }); } relationship.columnDataType = relationship.otherEntity.columnType; return relationship; } };