Fix index renaming (#8771)

Fixes https://github.com/twentyhq/twenty/issues/8760

## Context
Index names are based on table names and column names, which means
renaming an object (or a field) should also trigger a recompute of index
names. As of today it raises a bug where you can't create an object with
a name that was previously used.

I also took the occasion to refactor a bit the part where we create and
update (after renaming) relations. Basically the only relations we want
to affect are standard relations so I've aligned the logic with
sync-metadata which uses standardId as a source of truth to simplify the
code.

Note: We don't create index for custom relations
Next step should be to do that and update that code to update the index
name as well. Also note that we need to update the sync-metadata logic
for that as well
This commit is contained in:
Weiko
2024-11-28 10:21:03 +01:00
committed by GitHub
parent 2fab2266d5
commit c9fd194695
5 changed files with 487 additions and 313 deletions

View File

@ -13,6 +13,7 @@ import { generateDeterministicIndexName } from 'src/engine/metadata-modules/inde
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
import {
WorkspaceMigrationIndexAction,
WorkspaceMigrationIndexActionType,
WorkspaceMigrationTableAction,
WorkspaceMigrationTableActionType,
@ -103,6 +104,55 @@ export class IndexMetadataService {
);
}
async recomputeIndexMetadataForObject(
workspaceId: string,
updatedObjectMetadata: ObjectMetadataEntity,
) {
const indexesToRecompute = await this.indexMetadataRepository.find({
where: {
objectMetadataId: updatedObjectMetadata.id,
workspaceId,
},
relations: ['indexFieldMetadatas.fieldMetadata'],
});
const recomputedIndexes: {
indexMetadata: IndexMetadataEntity;
previousName: string;
newName: string;
}[] = [];
for (const index of indexesToRecompute) {
const previousIndexName = index.name;
const tableName = computeObjectTargetTable(updatedObjectMetadata);
const indexFieldsMetadataOrdered = index.indexFieldMetadatas.sort(
(a, b) => a.order - b.order,
);
const columnNames = indexFieldsMetadataOrdered.map(
(indexFieldMetadata) => indexFieldMetadata.fieldMetadata.name,
);
const newIndexName = `IDX_${generateDeterministicIndexName([
tableName,
...columnNames,
])}`;
await this.indexMetadataRepository.update(index.id, {
name: newIndexName,
});
recomputedIndexes.push({
indexMetadata: index,
previousName: previousIndexName,
newName: newIndexName,
});
}
return recomputedIndexes;
}
async deleteIndexMetadata(
workspaceId: string,
objectMetadata: ObjectMetadataEntity,
@ -179,4 +229,55 @@ export class IndexMetadataService {
[migration],
);
}
async createIndexRecomputeMigrations(
workspaceId: string,
objectMetadata: ObjectMetadataEntity,
recomputedIndexes: {
indexMetadata: IndexMetadataEntity;
previousName: string;
newName: string;
}[],
) {
for (const recomputedIndex of recomputedIndexes) {
const { previousName, newName, indexMetadata } = recomputedIndex;
const tableName = computeObjectTargetTable(objectMetadata);
const indexFieldsMetadataOrdered = indexMetadata.indexFieldMetadatas.sort(
(a, b) => a.order - b.order,
);
const columnNames = indexFieldsMetadataOrdered.map(
(indexFieldMetadata) => indexFieldMetadata.fieldMetadata.name,
);
const migration = {
name: tableName,
action: WorkspaceMigrationTableActionType.ALTER_INDEXES,
indexes: [
{
action: WorkspaceMigrationIndexActionType.DROP,
name: previousName,
columns: [],
isUnique: indexMetadata.isUnique,
} satisfies WorkspaceMigrationIndexAction,
{
action: WorkspaceMigrationIndexActionType.CREATE,
columns: columnNames,
name: newName,
isUnique: indexMetadata.isUnique,
where: indexMetadata.indexWhereClause,
type: indexMetadata.indexType,
} satisfies WorkspaceMigrationIndexAction,
],
} satisfies WorkspaceMigrationTableAction;
await this.workspaceMigrationService.createCustomMigration(
generateMigrationName(`update-${objectMetadata.nameSingular}-index`),
workspaceId,
[migration],
);
}
}
}