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 26, 2024
1 parent 02a96b5 commit 7b177b3
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 25 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
39 changes: 39 additions & 0 deletions generators/base-entity-changes/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const baseChangelog: () => Omit<BaseChangelog, 'changelogDate' | 'entityName' |
addedRelationships: [],
removedRelationships: [],
relationshipsToRecreateForeignKeysOnly: [],
removedDefaultValueFields: [],
addedDefaultValueFields: [],
changelogData: {},
});

Expand Down Expand Up @@ -164,6 +166,33 @@ 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,
),
);

return {
...baseChangelog(),
previousEntity: oldConfig,
Expand All @@ -176,7 +205,17 @@ 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;
};
20 changes: 20 additions & 0 deletions generators/bootstrap-application/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ describe(`generator - ${generator}`, () => {
"createRandexp": Any<Function>,
"dynamic": false,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "Id",
"fieldIsEnum": false,
"fieldName": "id",
Expand Down Expand Up @@ -361,6 +363,8 @@ describe(`generator - ${generator}`, () => {
"columnType": "varchar(50)",
"createRandexp": Any<Function>,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "Login",
"fieldIsEnum": false,
"fieldName": "login",
Expand Down Expand Up @@ -448,6 +452,8 @@ describe(`generator - ${generator}`, () => {
"columnType": "varchar(50)",
"createRandexp": Any<Function>,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "FirstName",
"fieldIsEnum": false,
"fieldName": "firstName",
Expand Down Expand Up @@ -530,6 +536,8 @@ describe(`generator - ${generator}`, () => {
"columnType": "varchar(50)",
"createRandexp": Any<Function>,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "LastName",
"fieldIsEnum": false,
"fieldName": "lastName",
Expand Down Expand Up @@ -612,6 +620,8 @@ describe(`generator - ${generator}`, () => {
"columnType": "varchar(191)",
"createRandexp": Any<Function>,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "Email",
"fieldIsEnum": false,
"fieldName": "email",
Expand Down Expand Up @@ -699,6 +709,8 @@ describe(`generator - ${generator}`, () => {
"columnType": "varchar(256)",
"createRandexp": Any<Function>,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "ImageUrl",
"fieldIsEnum": false,
"fieldName": "imageUrl",
Expand Down Expand Up @@ -782,6 +794,8 @@ describe(`generator - ${generator}`, () => {
"columnType": "boolean",
"createRandexp": Any<Function>,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "Activated",
"fieldIsEnum": false,
"fieldName": "activated",
Expand Down Expand Up @@ -856,6 +870,8 @@ describe(`generator - ${generator}`, () => {
"columnType": "varchar(10)",
"createRandexp": Any<Function>,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "LangKey",
"fieldIsEnum": false,
"fieldName": "langKey",
Expand Down Expand Up @@ -1142,6 +1158,8 @@ describe(`generator - ${generator}`, () => {
"createRandexp": Any<Function>,
"dynamic": false,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "Id",
"fieldIsEnum": false,
"fieldName": "id",
Expand Down Expand Up @@ -1481,6 +1499,8 @@ describe(`generator - ${generator}`, () => {
"createRandexp": Any<Function>,
"dynamic": false,
"entity": Any<Object>,
"fieldDefaultValueDefined": false,
"fieldHasAnyDefaultValue": false,
"fieldInJavaBeanMethod": "Id",
"fieldIsEnum": false,
"fieldName": "id",
Expand Down
63 changes: 51 additions & 12 deletions generators/liquibase/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,25 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
fieldChangelog: true,
addedRelationships: [],
removedRelationships: [],
removedDefaultValueFields: [],
addedDefaultValueFields: [],
relationshipsToRecreateForeignKeysOnly: [],
},
application,
}),
);

console.log('ChangelogAA', this.databaseChangelogs);

Check warning on line 240 in generators/liquibase/generator.ts

View workflow job for this annotation

GitHub Actions / check-npm-test

Unexpected console statement
}
}
// 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.addedRelationships.length > 0 ||
databaseChangelog.removedRelationships.length > 0 ||
databaseChangelog.removedDefaultValueFields.length > 0 ||
databaseChangelog.addedDefaultValueFields.length > 0)
) {
this.databaseChangelogs.push(
this.prepareChangelog({
Expand All @@ -254,6 +261,8 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
application,
}),
);

console.log('ChangelogBB', this.databaseChangelogs);

Check warning on line 265 in generators/liquibase/generator.ts

View workflow job for this annotation

GitHub Actions / check-npm-test

Unexpected console statement
}
}
this.databaseChangelogs = this.databaseChangelogs.filter(Boolean);
Expand Down Expand Up @@ -540,6 +549,9 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator {
hasRelationshipConstraint,
shouldWriteAnyRelationship,
relationshipsToRecreateForeignKeysOnly,
hasDefaultValueChange,
removedDefaultValueFields,
addedDefaultValueFields,
} = changelogData;

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

const promises: Promise<any>[] = [];
promises.push(this.writeFiles({ sections: updateEntityFiles, context }));
if (this._isBasicEntityUpdate(changelogData)) {
promises.push(this.writeFiles({ sections: updateEntityFiles, context }));
}

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

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

private _requiresConstrainUpdates(changelogData: any) {
return changelogData.hasFieldConstraint || changelogData.addedRelationships.length > 0 || changelogData.hasDefaultValueChange;
}

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

private _requiresWritingFakeData(changelogData: any) {
return !changelogData.skipFakeData && (changelogData.addedFields.length || changelogData.addedRelationships.length);
}

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

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

if (changelogData.hasFieldConstraint || changelogData.shouldWriteAnyRelationship) {
if (this._requiresConstrainUpdates(changelogData)) {
source.addLiquibaseIncrementalChangelog({
changelogName: `${databaseChangelog.changelogDate}_updated_entity_constraints_${entity.entityClass}`,
});
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 @@ -700,17 +733,23 @@ 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),
);
entityChanges.shouldWriteAnyRelationship = entityChanges.addedRelationships.some(
relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable,
);
entityChanges.shouldWriteAnyRelationship =
entityChanges.addedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable) ||
entityChanges.removedRelationships.some(relationship => relationship.shouldWriteRelationship || relationship.shouldWriteJoinTable);
}

return databaseChangelog;
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, inline: true}) -%><%- 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,16 @@
<%_ if (inline && (field.defaultValueComputed || field.fieldDefaultValueDefined)) { _%> <% } _%>
<%_ 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 %>"<% -%>
<%_ } _%>
<%_ } _%>
Loading

0 comments on commit 7b177b3

Please sign in to comment.