Skip to content

Commit

Permalink
wip: default values jhipster#25094
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarHawk committed Mar 22, 2024
1 parent 0248a67 commit 3c86496
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,22 @@ _%>
<%_ for (field of fields) {
const { fieldName, fieldTypeBoolean, fieldTypeTimed, fieldTypeLocalDate } = field;
_%>
<%_ if (field.id) { _%>
<%= fieldName %>: null,
<%_ } else if (fieldTypeBoolean) { _%>
<%= fieldName %>: false,
<%_ } else if (fieldTypeTimed) { _%>
<%= fieldName %>: currentTime,
<%_ if (field.fieldDefaultValueDefined) { _%>
<%_ if (field.fieldTypeCharSequence) { _%>
<%= fieldName %>: '<%= field.defaultValue %>',
<%_ } else if (fieldTypeTimed) { _%>
<%= fieldName %>: dayjs('<%= field.defaultValue %>'),
<%_ } else { _%>
<%= fieldName %>: <%= field.defaultValue %>,
<%_ } _%>
<%_ } else { _%>
<%_ if (field.id) { _%>
<%= fieldName %>: null,
<%_ } else if (fieldTypeBoolean) { _%>
<%= fieldName %>: false,
<%_ } else if (fieldTypeTimed) { _%>
<%= fieldName %>: currentTime,
<%_ } _%>
<%_ } _%>
<%_ } _%>
<%_ for (const relationship of relationships.filter(({ persistableRelationship }) => persistableRelationship)) {
Expand Down
4 changes: 3 additions & 1 deletion generators/base-application/support/prepare-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ function _derivedProperties(field) {
fieldType === INTEGER || fieldType === LONG || fieldType === FLOAT || fieldType === DOUBLE || fieldType === BIG_DECIMAL,
fieldTypeBinary: fieldType === BYTES || fieldType === BYTE_BUFFER,
fieldTypeTimed: fieldType === ZONED_DATE_TIME || fieldType === INSTANT,
fieldTypeCharSequence: fieldType === STRING || fieldType === UUID,
fieldTypeCharSequence: fieldType === STRING || fieldType === UUID || fieldType === TEXT_BLOB,
fieldTypeTemporal: fieldType === ZONED_DATE_TIME || fieldType === INSTANT || fieldType === LOCAL_DATE,
fieldValidationRequired: validationRules.includes(REQUIRED),
fieldValidationMin: validationRules.includes(MIN),
Expand All @@ -254,6 +254,8 @@ function _derivedProperties(field) {
fieldValidationUnique: validationRules.includes(UNIQUE),
fieldValidationMinBytes: validationRules.includes(MINBYTES),
fieldValidationMaxBytes: validationRules.includes(MAXBYTES),
fieldDefaultValueDefined: field.defaultValue !== undefined,
fieldHasAnyDefaultValue: field.defaultValue !== undefined || field.defaultValueComputed !== undefined,
});
}

Expand Down
36 changes: 35 additions & 1 deletion generators/base-entity-changes/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ const baseChangelog: () => Omit<BaseChangelog, 'changelogDate' | 'entityName' |
removedFields: [],
addedRelationships: [],
removedRelationships: [],
relationshipsToRecreateForeignKeysOnly: [],
relationshipsToRecreateForeignKeysOnly: [],
removedDefaultValueFields: [],
addedDefaultValueFields: [],
changelogData: {},
});

Expand Down Expand Up @@ -164,6 +166,27 @@ export default abstract class GeneratorBaseEntityChanges extends GeneratorBaseAp
),
);

const oldFieldsWithDefaultValues = oldFields.filter(field => this.hasAnyDefaultValue(field));
const newFieldsWithDefaultValues = newFields.filter(field => this.hasAnyDefaultValue(field));

// find the old fields that have not been deleted anyway or otherwise where the default value is different on the same new field
const removedDefaultValueFields = oldFieldsWithDefaultValues.filter(
oldField => !removedFieldNames.includes(oldField.fieldName),
).filter(
// field was not removed, so check its default value
oldField => this.doDefaultValuesDiffer(oldField, newFields.find(newField => newField.fieldName === oldField.fieldName))
);

// find the new fields that have not been added newly anyway or otherwise where the old field had a different default value
const addedDefaultValueFields = newFieldsWithDefaultValues.filter(
newField => !addedFieldNames.includes(newField.fieldName)
).filter(
// field was not added newly, so check its default value
newField => this.doDefaultValuesDiffer(oldFields.find(oldField => oldField.fieldName === newField.fieldName), newField)
);

console.log('removedFields', removedFields);

return {
...baseChangelog(),
previousEntity: oldConfig,
Expand All @@ -176,7 +199,18 @@ export default abstract class GeneratorBaseEntityChanges extends GeneratorBaseAp
addedRelationships,
removedRelationships,
relationshipsToRecreateForeignKeysOnly,
removedDefaultValueFields,
addedDefaultValueFields,
};
});
}

private hasAnyDefaultValue(field) {
return field.defaultValue || field.defaultValueComputed;
}

private doDefaultValuesDiffer(field1, field2) {
return field1.defaultValue !== field2.defaultValue || field1.defaultValueComputed !== field2.defaultValueComputed;
}

}
2 changes: 2 additions & 0 deletions generators/base-entity-changes/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ export type BaseChangelog = {
addedRelationships: any[];
removedRelationships: any[];
relationshipsToRecreateForeignKeysOnly: any[];
removedDefaultValueFields: any[];
addedDefaultValueFields: any[];
changelogData: any;
};
59 changes: 50 additions & 9 deletions generators/liquibase/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
fieldChangelog: true,
addedRelationships: [],
removedRelationships: [],
removedDefaultValueFields: [],
addedDefaultValueFields: [],
relationshipsToRecreateForeignKeysOnly: [],
},
application,
Expand All @@ -238,10 +240,15 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
}
// Relationships needs to be added later to make sure every related field is already added.
for (const databaseChangelog of changes) {

console.log('other changelog');
if (
databaseChangelog.incremental &&
(databaseChangelog.addedRelationships.length > 0 || databaseChangelog.removedRelationships.length > 0)
(databaseChangelog.addedRelationships.length > 0 || databaseChangelog.removedRelationships.length > 0|| databaseChangelog.removedDefaultValueFields.length > 0 || databaseChangelog.addedDefaultValueFields.length > 0)
) {

console.log('other changelog added');

this.databaseChangelogs.push(
this.prepareChangelog({
databaseChangelog: {
Expand All @@ -254,9 +261,13 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
application,
}),
);

console.log('All databaseChangelogs B', this.databaseChangelogs);
}
}
this.databaseChangelogs = this.databaseChangelogs.filter(Boolean);

console.log('All databaseChangelogs C', this.databaseChangelogs);
},
});
}
Expand Down Expand Up @@ -540,6 +551,9 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
hasRelationshipConstraint,
shouldWriteAnyRelationship,
relationshipsToRecreateForeignKeysOnly,
hasDefaultValueChange,
removedDefaultValueFields,
addedDefaultValueFields,
} = changelogData;

const context = {
Expand All @@ -556,35 +570,49 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
hasRelationshipConstraint,
shouldWriteAnyRelationship,
relationshipsToRecreateForeignKeysOnly,
hasDefaultValueChange,
removedDefaultValueFields,
addedDefaultValueFields,
};

const isBasicEntityUpdate = this._isBasicEntityUpdate(changelogData);
console.log('doWriteFiles', isBasicEntityUpdate, hasFieldConstraint, shouldWriteAnyRelationship, hasDefaultValueChange);
const promises: Promise<any>[] = [];
promises.push(this.writeFiles({ sections: updateEntityFiles, context }));
if (isBasicEntityUpdate) {
promises.push(this.writeFiles({ sections: updateEntityFiles, context }));
}

if (!changelogData.skipFakeData && (changelogData.addedFields.length > 0 || shouldWriteAnyRelationship)) {
if (!changelogData.skipFakeData && isBasicEntityUpdate) {
promises.push(this.writeFiles({ sections: fakeFiles, context }));
promises.push(this.writeFiles({ sections: updateMigrateFiles, context }));
}

if (hasFieldConstraint || shouldWriteAnyRelationship) {
if (hasFieldConstraint || shouldWriteAnyRelationship || hasDefaultValueChange) {
promises.push(this.writeFiles({ sections: updateConstraintsFiles, context }));
}
return Promise.all(promises);
}

private _isBasicEntityUpdate(changelogData: any) {
return changelogData.addedFields.length > 0 || changelogData.removedFields.length > 0 || changelogData.shouldWriteAnyRelationship;
}

/**
* Write files for updated entities.
*/
_addUpdateFilesReferences({ entity, databaseChangelog, changelogData, source }) {
source.addLiquibaseIncrementalChangelog({ changelogName: `${databaseChangelog.changelogDate}_updated_entity_${entity.entityClass}` });
const isBasicEntityUpdate = this._isBasicEntityUpdate(changelogData);
if (isBasicEntityUpdate) {
source.addLiquibaseIncrementalChangelog({ changelogName: `${databaseChangelog.changelogDate}_updated_entity_${entity.entityClass}` });
}

if (!changelogData.skipFakeData && (changelogData.addedFields.length > 0 || changelogData.shouldWriteAnyRelationship)) {
if (!changelogData.skipFakeData && isBasicEntityUpdate) {
source.addLiquibaseIncrementalChangelog({
changelogName: `${databaseChangelog.changelogDate}_updated_entity_migrate_${entity.entityClass}`,
});
}

if (changelogData.hasFieldConstraint || changelogData.shouldWriteAnyRelationship) {
if (changelogData.hasFieldConstraint || changelogData.shouldWriteAnyRelationship || changelogData.hasDefaultValueChange) {
source.addLiquibaseIncrementalChangelog({
changelogName: `${databaseChangelog.changelogDate}_updated_entity_constraints_${entity.entityClass}`,
});
Expand Down Expand Up @@ -622,8 +650,11 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
if (databaseChangelog.newEntity) {
entityChanges.fields = entityChanges.allFields;
} else {
// FIXME: this overrides in the run for relationship changes also the references produced in the field changes run
console.log('Caluclating added and removed fields ', databaseChangelog.entityName, databaseChangelog.fieldChangelog, databaseChangelog.relationshipChangelog);
entityChanges.addedFields = databaseChangelog.addedFields.filter(field => !field.transient);
entityChanges.removedFields = databaseChangelog.removedFields.filter(field => !field.transient);
console.log('Caluclated added and removed fields ', databaseChangelog.entityName, entityChanges.addedFields.length, entityChanges.removedFields.length);
}

const seed = `${entity.entityClass}-liquibase`;
Expand Down Expand Up @@ -676,6 +707,8 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
entityChanges.addedRelationships = databaseChangelog.addedRelationships;
entityChanges.removedRelationships = databaseChangelog.removedRelationships;
entityChanges.relationshipsToRecreateForeignKeysOnly = databaseChangelog.relationshipsToRecreateForeignKeysOnly;
entityChanges.removedDefaultValueFields = databaseChangelog.removedDefaultValueFields;
entityChanges.addedDefaultValueFields = databaseChangelog.addedDefaultValueFields;
}

/* Required by the templates */
Expand All @@ -692,6 +725,8 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
recreateInitialChangelog: this.recreateInitialChangelog,
};

console.log('databaseChangelog:::', databaseChangelog.entityName, databaseChangelog.changelogData?.addedFields?.length, databaseChangelog.changelogData?.removedFields?.length);

if (databaseChangelog.newEntity) {
return databaseChangelog;
}
Expand All @@ -700,10 +735,13 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
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.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.nullable);
entityChanges.hasFieldConstraint = entityChanges.addedFields.some(field => (field.unique || (field.columnRequired && !field.fieldHasAnyDefaultValue) || 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),
Expand All @@ -713,6 +751,8 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
);
}

console.log('databaseChangelog:::', databaseChangelog.entityName, databaseChangelog.changelogData?.addedFields?.length, databaseChangelog.changelogData?.removedFields?.length);

return databaseChangelog;
}

Expand All @@ -722,6 +762,7 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
return this._writeLiquibaseFiles({ context, changelogData });
}
if (changelogData.requiresUpdateChangelogs) {
console.log('write update files');
return this._writeUpdateFiles({ context, changelogData });
}
return undefined;
Expand Down
2 changes: 1 addition & 1 deletion generators/liquibase/support/prepare-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export default function prepareField(entity, field) {
mutateData(field, {
__override__: false,
columnType: data => parseLiquibaseColumnType(entity, data),
shouldDropDefaultValue: data => data.fieldType === ZONED_DATE_TIME || data.fieldType === INSTANT,
shouldDropDefaultValue: data => !data.fieldHasAnyDefaultValue && (data.fieldType === ZONED_DATE_TIME || data.fieldType === INSTANT),
shouldCreateContentType: data => data.fieldType === BYTES && data.fieldTypeBlobContent !== TEXT,
columnRequired: data => data.nullable === false || (data.fieldValidate === true && data.fieldValidateRules.includes('required')),
nullable: data => !data.columnRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<changeSet id="<%= changelogDate %>-1" author="jhipster">
<createTable tableName="<%= entity.entityTableName %>"<%- this.formatAsLiquibaseRemarks(entity.documentation, true) %>>
<%_ for (field of fields) { _%>
<column name="<%= field.columnName %>" type="<%= field.columnType %>"<%- this.formatAsLiquibaseRemarks(field.documentation, true) %><% if (field.id && field.liquibaseAutoIncrement) { %> autoIncrement="true" startWith="1500"<%_ } %>>
<column name="<%= field.columnName %>" type="<%= field.columnType %>"<%- include('./default-field-value', {field}) -%><%- this.formatAsLiquibaseRemarks(field.documentation, true) %><% if (field.id && field.liquibaseAutoIncrement) { %> autoIncrement="true" startWith="1500"<%_ } %>>
<%_ if (field.id) { _%>
<constraints primaryKey="true" nullable="false"/>
<%_ } else if (field.unique) { _%>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<%_ if (field.defaultValueComputed) { -%>
defaultValueComputed="<%= field.defaultValueComputed %>"<% -%>
<%_ } else if (field.fieldDefaultValueDefined) { -%>
<%_ if (field.fieldTypeCharSequence) { -%>
defaultValue="<%= field.defaultValue %>"<% -%>
<%_ } else if (field.fieldTypeNumeric) { -%>
defaultValueNumeric="<%= field.defaultValue %>"<% -%>
<%_ } else if (field.fieldTypeDateTime) { -%>
defaultValueDate="<%= field.defaultValue %>"<% -%>
<%_ } else if (field.fieldTypeBoolean) { -%>
defaultValueBoolean="<%= field.defaultValue %>"<% -%>
<%_ } else { -%>
defaultValue="<%= field.defaultValue %>"<% -%>
<%_ } -%>
<%_ } -%>
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@
<changeSet id="<%= changelogDate %>-1-add-columns" author="jhipster">
<addColumn tableName="<%= entity.entityTableName %>">
<%_ for (field of addedFields) { _%>
<column name="<%= field.columnName %>" type="<%= field.columnType %>"<%- this.formatAsLiquibaseRemarks(field.documentation, true) %>/>
<column name="<%= field.columnName %>" type="<%= field.columnType %>"<%- include('./default-field-value', {field}) -%><%- this.formatAsLiquibaseRemarks(field.documentation, true) %>/>
<%_ if (field.shouldCreateContentType) { _%>
<column name="<%= field.columnName %>_content_type" type="varchar(255)"/>
<%_ }
} // End for (field of addedFields) _%>
</addColumn>
<%_ for (field of addedFields) {
if (field.fieldType === 'ZonedDateTime' || field.fieldType === 'Instant') { _%>
<dropDefaultValue tableName="<%= entity.entityTableName %>" columnName="<%= field.columnName %>" columnDataType="datetime"/>
if (field.shouldDropDefaultValue) { _%>
<dropDefaultValue tableName="<%= entity.entityTableName %>" columnName="<%= field.columnName %>" columnDataType="${datetimeType}"/>
<%_ } _%>
<%_ } _%>
</changeSet>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ if (hasFieldConstraint) { _%>
constraintName="<%= field.uniqueConstraintName %>"/>
<%_ }
if (field.columnRequired) {
if (!field.fieldHasAnyDefaultValue) {
_%>
<addNotNullConstraint tableName="<%= entityTableName %>"
columnName="<%= field.columnName %>"
columnDataType="<%= field.columnType %>"/>
<%_ } _%>
<%_ if (field.shouldCreateContentType) { _%>
<addNotNullConstraint tableName="<%= entityTableName %>"
columnName="<%= field.columnName %>_content_type"
Expand All @@ -48,6 +50,31 @@ if (hasFieldConstraint) { _%>
} _%>
</changeSet>
<% } _%>
<%_ if (removedDefaultValueFields && removedDefaultValueFields.length) { _%>
<!--
Removed the default value for the fields for entity <%= entityClass %>.
-->
<changeSet id="<%= changelogDate %>-fields-remove-default-value" author="jhipster">
<%_ for (field of removedDefaultValueFields) { _%>
<dropDefaultValue tableName="<%= entityTableName %>"
columnName="<%= field.columnName %>"
columnDataType="<%= field.columnType %>"/>
<%_ } _%>
</changeSet>
<% } _%>
<%_ if (addedDefaultValueFields && addedDefaultValueFields.length) { _%>
<!--
Added the default value for the fields for entity <%= entityClass %>.
-->
<changeSet id="<%= changelogDate %>-fields-add-default-value" author="jhipster">
<%_ for (field of addedDefaultValueFields) { _%>
<addDefaultValue tableName="<%= entityTableName %>"
columnName="<%= field.columnName %>"
columnDataType="<%= field.columnType %>"
<%- include('./default-field-value', {field}) -%>/>
<%_ } _%>
</changeSet>
<% } _%>
<%_ if (hasRelationshipConstraint) { _%>
<!--
Expand Down

0 comments on commit 3c86496

Please sign in to comment.