Optimize metadata queries (#7013)
In this PR: 1. Refactor guards to avoid duplicated queries: WorkspaceAuthGuard and UserAuthGuard only check for existence of workspace and user in the request without querying the database
This commit is contained in:
committed by
Charles Bochet
parent
cf8b1161cc
commit
523df5398a
@ -4,7 +4,7 @@ import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
||||
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { DataSource, FindOneOptions, Repository } from 'typeorm';
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
import { v4 as uuidV4, v4 } from 'uuid';
|
||||
|
||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
@ -72,6 +72,8 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
private readonly metadataDataSource: DataSource,
|
||||
@InjectRepository(FieldMetadataEntity, 'metadata')
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||
@ -87,6 +89,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
override async createOne(
|
||||
fieldMetadataInput: CreateFieldInput,
|
||||
): Promise<FieldMetadataEntity> {
|
||||
console.time('createOne');
|
||||
const queryRunner = this.metadataDataSource.createQueryRunner();
|
||||
|
||||
await queryRunner.connect();
|
||||
@ -97,20 +100,23 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
queryRunner.manager.getRepository<FieldMetadataEntity>(
|
||||
FieldMetadataEntity,
|
||||
);
|
||||
const objectMetadata =
|
||||
await this.objectMetadataService.findOneWithinWorkspace(
|
||||
fieldMetadataInput.workspaceId,
|
||||
{
|
||||
where: {
|
||||
id: fieldMetadataInput.objectMetadataId,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
console.time('createOne query');
|
||||
const [objectMetadata] = await this.objectMetadataRepository.find({
|
||||
where: {
|
||||
id: fieldMetadataInput.objectMetadataId,
|
||||
workspaceId: fieldMetadataInput.workspaceId,
|
||||
},
|
||||
relations: ['fields'],
|
||||
order: {},
|
||||
});
|
||||
|
||||
console.timeEnd('createOne query');
|
||||
|
||||
if (!objectMetadata) {
|
||||
throw new FieldMetadataException(
|
||||
'Object metadata does not exist',
|
||||
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
|
||||
FieldMetadataExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
@ -155,22 +161,11 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
objectMetadata,
|
||||
);
|
||||
|
||||
const fieldAlreadyExists = await fieldMetadataRepository.findOne({
|
||||
where: {
|
||||
name: fieldMetadataInput.name,
|
||||
objectMetadataId: fieldMetadataInput.objectMetadataId,
|
||||
workspaceId: fieldMetadataInput.workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (fieldAlreadyExists) {
|
||||
throw new FieldMetadataException(
|
||||
'Field already exists',
|
||||
FieldMetadataExceptionCode.FIELD_ALREADY_EXISTS,
|
||||
);
|
||||
}
|
||||
|
||||
console.time('createOne save');
|
||||
const createdFieldMetadata = await fieldMetadataRepository.save({
|
||||
id: v4(),
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
...fieldMetadataInput,
|
||||
isNullable: generateNullable(
|
||||
fieldMetadataInput.type,
|
||||
@ -190,7 +185,10 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
isCustom: true,
|
||||
});
|
||||
|
||||
console.timeEnd('createOne save');
|
||||
|
||||
if (!fieldMetadataInput.isRemoteCreation) {
|
||||
console.time('createOne migration create');
|
||||
await this.workspaceMigrationService.createCustomMigration(
|
||||
generateMigrationName(`create-${createdFieldMetadata.name}`),
|
||||
fieldMetadataInput.workspaceId,
|
||||
@ -206,11 +204,16 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
],
|
||||
);
|
||||
|
||||
console.timeEnd('createOne migration create');
|
||||
|
||||
console.time('createOne migration run');
|
||||
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
||||
fieldMetadataInput.workspaceId,
|
||||
);
|
||||
console.timeEnd('createOne migration run');
|
||||
}
|
||||
|
||||
console.time('createOne workspace viewField');
|
||||
// TODO: Move viewField creation to a cdc scheduler
|
||||
const dataSourceMetadata =
|
||||
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||
@ -270,8 +273,11 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
);
|
||||
}
|
||||
}
|
||||
console.timeEnd('createOne workspace viewField');
|
||||
|
||||
console.time('createOne internal commit');
|
||||
await workspaceQueryRunner.commitTransaction();
|
||||
console.timeEnd('createOne internal commit');
|
||||
} catch (error) {
|
||||
await workspaceQueryRunner.rollbackTransaction();
|
||||
throw error;
|
||||
@ -279,7 +285,9 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
await workspaceQueryRunner.release();
|
||||
}
|
||||
|
||||
console.time('createOne commit');
|
||||
await queryRunner.commitTransaction();
|
||||
console.timeEnd('createOne commit');
|
||||
|
||||
return createdFieldMetadata;
|
||||
} catch (error) {
|
||||
@ -287,9 +295,12 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
console.time('createOne increment');
|
||||
await this.workspaceMetadataVersionService.incrementMetadataVersion(
|
||||
fieldMetadataInput.workspaceId,
|
||||
);
|
||||
console.timeEnd('createOne increment');
|
||||
console.timeEnd('createOne');
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,7 +319,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
FieldMetadataEntity,
|
||||
);
|
||||
|
||||
const existingFieldMetadata = await fieldMetadataRepository.findOne({
|
||||
const [existingFieldMetadata] = await fieldMetadataRepository.find({
|
||||
where: {
|
||||
id,
|
||||
workspaceId: fieldMetadataInput.workspaceId,
|
||||
@ -322,15 +333,14 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
);
|
||||
}
|
||||
|
||||
const objectMetadata =
|
||||
await this.objectMetadataService.findOneWithinWorkspace(
|
||||
fieldMetadataInput.workspaceId,
|
||||
{
|
||||
where: {
|
||||
id: existingFieldMetadata?.objectMetadataId,
|
||||
},
|
||||
},
|
||||
);
|
||||
const [objectMetadata] = await this.objectMetadataRepository.find({
|
||||
where: {
|
||||
id: existingFieldMetadata.objectMetadataId,
|
||||
workspaceId: fieldMetadataInput.workspaceId,
|
||||
},
|
||||
relations: ['fields'],
|
||||
order: {},
|
||||
});
|
||||
|
||||
if (!objectMetadata) {
|
||||
throw new FieldMetadataException(
|
||||
@ -475,7 +485,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
FieldMetadataEntity,
|
||||
);
|
||||
|
||||
const fieldMetadata = await fieldMetadataRepository.findOne({
|
||||
const [fieldMetadata] = await fieldMetadataRepository.find({
|
||||
where: {
|
||||
id: input.id,
|
||||
workspaceId: workspaceId,
|
||||
@ -489,12 +499,13 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
);
|
||||
}
|
||||
|
||||
const objectMetadata =
|
||||
await this.objectMetadataService.findOneWithinWorkspace(workspaceId, {
|
||||
where: {
|
||||
id: fieldMetadata?.objectMetadataId,
|
||||
},
|
||||
});
|
||||
const [objectMetadata] = await this.objectMetadataRepository.find({
|
||||
where: {
|
||||
id: fieldMetadata.objectMetadataId,
|
||||
},
|
||||
relations: ['fields'],
|
||||
order: {},
|
||||
});
|
||||
|
||||
if (!objectMetadata) {
|
||||
throw new FieldMetadataException(
|
||||
@ -583,7 +594,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
id: string,
|
||||
options?: FindOneOptions<FieldMetadataEntity>,
|
||||
) {
|
||||
const fieldMetadata = await this.fieldMetadataRepository.findOne({
|
||||
const [fieldMetadata] = await this.fieldMetadataRepository.find({
|
||||
...options,
|
||||
where: {
|
||||
...options?.where,
|
||||
@ -605,13 +616,15 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
workspaceId: string,
|
||||
options: FindOneOptions<FieldMetadataEntity>,
|
||||
) {
|
||||
return this.fieldMetadataRepository.findOne({
|
||||
const [fieldMetadata] = await this.fieldMetadataRepository.find({
|
||||
...options,
|
||||
where: {
|
||||
...options.where,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
return fieldMetadata;
|
||||
}
|
||||
|
||||
private buildUpdatableStandardFieldInput(
|
||||
|
||||
Reference in New Issue
Block a user