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:
@ -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],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user