Fix relation deletion (#12008)
## What This PR fixes a regression tied to the new relation format refactoring. I'm also slightly improving the performance by decreasing the number of queries. ## Considerations 1. I've started adding an integration test to cover relation creation and deletion but we are still using the r`elation-metadata.service` to create a relation and the `field-metadata.service` to delete it. As we plan to fully deprecate the `relation-metadata.service`, I did not want to invest into writing test tooling to change it in a few weeks so I've reverted the test 2. We are still maintaining relationMetadata table up-to-date (so deleting them when we delete the field). relationMetadata full deprecation is up coming but I'm waiting a bit so we don't have breaking changes in 0.53
This commit is contained in:
@ -318,31 +318,30 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
id: input.id,
|
id: input.id,
|
||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
},
|
},
|
||||||
|
relations: [
|
||||||
|
'object',
|
||||||
|
'relationTargetFieldMetadata',
|
||||||
|
'relationTargetObjectMetadata',
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!fieldMetadata) {
|
if (!isDefined(fieldMetadata)) {
|
||||||
throw new FieldMetadataException(
|
throw new FieldMetadataException(
|
||||||
'Field does not exist',
|
'Field does not exist',
|
||||||
FieldMetadataExceptionCode.FIELD_METADATA_NOT_FOUND,
|
FieldMetadataExceptionCode.FIELD_METADATA_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [objectMetadata] = await this.objectMetadataRepository.find({
|
if (!isDefined(fieldMetadata.object)) {
|
||||||
where: {
|
|
||||||
id: fieldMetadata.objectMetadataId,
|
|
||||||
},
|
|
||||||
relations: ['fields'],
|
|
||||||
order: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!objectMetadata) {
|
|
||||||
throw new FieldMetadataException(
|
throw new FieldMetadataException(
|
||||||
'Object metadata does not exist',
|
'Object metadata does not exist',
|
||||||
FieldMetadataExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
FieldMetadataExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectMetadata.labelIdentifierFieldMetadataId === fieldMetadata.id) {
|
if (
|
||||||
|
fieldMetadata.object.labelIdentifierFieldMetadataId === fieldMetadata.id
|
||||||
|
) {
|
||||||
throw new FieldMetadataException(
|
throw new FieldMetadataException(
|
||||||
'Cannot delete, please update the label identifier field first',
|
'Cannot delete, please update the label identifier field first',
|
||||||
FieldMetadataExceptionCode.FIELD_MUTATION_NOT_ALLOWED,
|
FieldMetadataExceptionCode.FIELD_MUTATION_NOT_ALLOWED,
|
||||||
@ -359,41 +358,56 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
(fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>)
|
(fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>)
|
||||||
.settings?.relationType === RelationType.MANY_TO_ONE;
|
.settings?.relationType === RelationType.MANY_TO_ONE;
|
||||||
|
|
||||||
const targetFieldMetadata =
|
if (!isDefined(fieldMetadata.relationTargetFieldMetadata)) {
|
||||||
await this.fieldMetadataRepository.findOneBy({
|
throw new FieldMetadataException(
|
||||||
id: fieldMetadata.relationTargetFieldMetadataId,
|
'Target field metadata does not exist',
|
||||||
});
|
FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
|
||||||
|
|
||||||
if (targetFieldMetadata) {
|
|
||||||
await this.relationMetadataRepository.delete({
|
|
||||||
fromFieldMetadataId: In([fieldMetadata.id, targetFieldMetadata.id]),
|
|
||||||
});
|
|
||||||
await this.relationMetadataRepository.delete({
|
|
||||||
toFieldMetadataId: In([fieldMetadata.id, targetFieldMetadata.id]),
|
|
||||||
});
|
|
||||||
await fieldMetadataRepository.delete({
|
|
||||||
id: In([fieldMetadata.id, targetFieldMetadata.id]),
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.workspaceMigrationService.createCustomMigration(
|
|
||||||
generateMigrationName(`delete-${fieldMetadata.name}`),
|
|
||||||
workspaceId,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: computeObjectTargetTable(objectMetadata),
|
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
action: WorkspaceMigrationColumnActionType.DROP,
|
|
||||||
columnName: isManyToOneRelation
|
|
||||||
? `${(fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}`
|
|
||||||
: `${(targetFieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}`,
|
|
||||||
} satisfies WorkspaceMigrationColumnDrop,
|
|
||||||
],
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this once we have deleted the relation metadata table
|
||||||
|
await this.relationMetadataRepository.delete({
|
||||||
|
fromFieldMetadataId: In([
|
||||||
|
fieldMetadata.id,
|
||||||
|
fieldMetadata.relationTargetFieldMetadata.id,
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
await this.relationMetadataRepository.delete({
|
||||||
|
toFieldMetadataId: In([
|
||||||
|
fieldMetadata.id,
|
||||||
|
fieldMetadata.relationTargetFieldMetadata.id,
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
|
||||||
|
await fieldMetadataRepository.delete({
|
||||||
|
id: In([
|
||||||
|
fieldMetadata.id,
|
||||||
|
fieldMetadata.relationTargetFieldMetadata.id,
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.workspaceMigrationService.createCustomMigration(
|
||||||
|
generateMigrationName(`delete-${fieldMetadata.name}`),
|
||||||
|
workspaceId,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: isManyToOneRelation
|
||||||
|
? computeObjectTargetTable(fieldMetadata.object)
|
||||||
|
: computeObjectTargetTable(
|
||||||
|
fieldMetadata.relationTargetObjectMetadata,
|
||||||
|
),
|
||||||
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.DROP,
|
||||||
|
columnName: isManyToOneRelation
|
||||||
|
? `${(fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}`
|
||||||
|
: `${(fieldMetadata.relationTargetFieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}`,
|
||||||
|
} satisfies WorkspaceMigrationColumnDrop,
|
||||||
|
],
|
||||||
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
|
],
|
||||||
|
);
|
||||||
} else if (isCompositeFieldMetadataType(fieldMetadata.type)) {
|
} else if (isCompositeFieldMetadataType(fieldMetadata.type)) {
|
||||||
await fieldMetadataRepository.delete(fieldMetadata.id);
|
await fieldMetadataRepository.delete(fieldMetadata.id);
|
||||||
const compositeType = compositeTypeDefinitions.get(fieldMetadata.type);
|
const compositeType = compositeTypeDefinitions.get(fieldMetadata.type);
|
||||||
@ -411,7 +425,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(objectMetadata),
|
name: computeObjectTargetTable(fieldMetadata.object),
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
columns: compositeType.properties.map((property) => {
|
columns: compositeType.properties.map((property) => {
|
||||||
return {
|
return {
|
||||||
@ -432,7 +446,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(objectMetadata),
|
name: computeObjectTargetTable(fieldMetadata.object),
|
||||||
action: WorkspaceMigrationTableActionType.ALTER,
|
action: WorkspaceMigrationTableActionType.ALTER,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user