Add indexes to custom relations (#7156)
TODO: command to retro-actively create indexes to existing custom objects
This commit is contained in:
@ -2,10 +2,15 @@ import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { IndexMetadataService } from 'src/engine/metadata-modules/index-metadata/index-metadata.service';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([IndexMetadataEntity], 'metadata')],
|
||||
providers: [],
|
||||
exports: [],
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([IndexMetadataEntity], 'metadata'),
|
||||
WorkspaceMigrationModule,
|
||||
],
|
||||
providers: [IndexMetadataService],
|
||||
exports: [IndexMetadataService],
|
||||
})
|
||||
export class IndexMetadataModule {}
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { generateDeterministicIndexName } from 'src/engine/metadata-modules/index-metadata/utils/generate-deterministic-index-name';
|
||||
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 {
|
||||
WorkspaceMigrationIndexActionType,
|
||||
WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
|
||||
@Injectable()
|
||||
export class IndexMetadataService {
|
||||
constructor(
|
||||
@InjectRepository(IndexMetadataEntity, 'metadata')
|
||||
private readonly indexMetadataRepository: Repository<IndexMetadataEntity>,
|
||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||
) {}
|
||||
|
||||
async createIndex(
|
||||
workspaceId: string,
|
||||
objectMetadata: ObjectMetadataEntity,
|
||||
fieldMetadataToIndex: Partial<FieldMetadataEntity>[],
|
||||
) {
|
||||
const tableName = computeObjectTargetTable(objectMetadata);
|
||||
|
||||
const columnNames: string[] = fieldMetadataToIndex.map(
|
||||
(fieldMetadata) => fieldMetadata.name as string,
|
||||
);
|
||||
|
||||
const indexName = `IDX_${generateDeterministicIndexName([tableName, ...columnNames])}`;
|
||||
|
||||
let savedIndexMetadata: IndexMetadataEntity;
|
||||
|
||||
try {
|
||||
savedIndexMetadata = await this.indexMetadataRepository.save({
|
||||
name: indexName,
|
||||
tableName,
|
||||
indexFieldMetadatas: fieldMetadataToIndex.map(
|
||||
(fieldMetadata, index) => {
|
||||
return {
|
||||
fieldMetadataId: fieldMetadata.id,
|
||||
order: index,
|
||||
};
|
||||
},
|
||||
),
|
||||
workspaceId,
|
||||
objectMetadataId: objectMetadata.id,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to create index ${indexName} on object metadata ${objectMetadata.nameSingular}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!savedIndexMetadata) {
|
||||
throw new Error(
|
||||
`Failed to return saved index ${indexName} on object metadata ${objectMetadata.nameSingular}`,
|
||||
);
|
||||
}
|
||||
|
||||
const migration = {
|
||||
name: tableName,
|
||||
action: WorkspaceMigrationTableActionType.ALTER_INDEXES,
|
||||
indexes: [
|
||||
{
|
||||
action: WorkspaceMigrationIndexActionType.CREATE,
|
||||
columns: columnNames,
|
||||
name: indexName,
|
||||
},
|
||||
],
|
||||
} satisfies WorkspaceMigrationTableAction;
|
||||
|
||||
await this.workspaceMigrationService.createCustomMigration(
|
||||
generateMigrationName(`create-${objectMetadata.nameSingular}-index`),
|
||||
workspaceId,
|
||||
[migration],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user