CreateMany optim - .save -> .updateMany + position (#13704)

fixes : https://github.com/twentyhq/core-team-issues/issues/1312

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Etienne
2025-08-07 00:52:28 +02:00
committed by GitHub
parent 723f1016a6
commit 58d25ebd83
5 changed files with 256 additions and 172 deletions
@@ -27,6 +27,7 @@ import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/typ
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
type PartialObjectRecordWithId = Partial<ObjectRecord> & { id: string };
@Injectable()
export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResolverService<
CreateManyResolverArgs,
@@ -116,13 +117,15 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
objectMetadataItemWithFieldMaps,
});
await this.processRecordsToUpdate({
partialRecordsToUpdate: recordsToUpdate,
repository: executionArgs.repository,
objectMetadataItemWithFieldMaps,
result,
columnsToReturn,
});
if (recordsToUpdate.length > 0) {
await this.processRecordsToUpdate({
partialRecordsToUpdate: recordsToUpdate,
repository: executionArgs.repository,
objectMetadataItemWithFieldMaps,
result,
columnsToReturn,
});
}
await this.processRecordsToInsert({
recordsToInsert,
@@ -181,7 +184,7 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
fullPath: string;
column: string;
}[],
): Promise<Partial<ObjectRecord>[]> {
): Promise<PartialObjectRecordWithId[]> {
const { objectMetadataItemWithFieldMaps } = executionArgs.options;
const queryBuilder = executionArgs.repository.createQueryBuilder(
objectMetadataItemWithFieldMaps.nameSingular,
@@ -208,12 +211,12 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
},
});
return await queryBuilder
return (await queryBuilder
.withDeleted()
.setFindOptions({
select: selectOptions,
})
.getMany();
.getMany()) as PartialObjectRecordWithId[];
}
private getValueFromPath(
@@ -262,16 +265,16 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
fullPath: string;
column: string;
}[],
existingRecords: Partial<ObjectRecord>[],
existingRecords: PartialObjectRecordWithId[],
): {
recordsToUpdate: Partial<ObjectRecord>[];
recordsToUpdate: PartialObjectRecordWithId[];
recordsToInsert: Partial<ObjectRecord>[];
} {
const recordsToUpdate: Partial<ObjectRecord>[] = [];
const recordsToUpdate: PartialObjectRecordWithId[] = [];
const recordsToInsert: Partial<ObjectRecord>[] = [];
for (const record of records) {
let existingRecord: Partial<ObjectRecord> | null = null;
let existingRecord: PartialObjectRecordWithId | null = null;
for (const field of conflictingFields) {
const requestFieldValue = this.getValueFromPath(record, field.fullPath);
@@ -309,9 +312,9 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
repository,
objectMetadataItemWithFieldMaps,
result,
columnsToReturn: _,
columnsToReturn,
}: {
partialRecordsToUpdate: Partial<ObjectRecord>[];
partialRecordsToUpdate: PartialObjectRecordWithId[];
repository: WorkspaceRepository<ObjectLiteral>;
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps;
result: InsertResult;
@@ -322,15 +325,20 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
this.getRecordWithoutCreatedBy(record, objectMetadataItemWithFieldMaps),
);
const savedRecords = await repository.save(
partialRecordsToUpdateWithoutCreatedByUpdate,
const savedRecords = await repository.updateMany(
partialRecordsToUpdateWithoutCreatedByUpdate.map((record) => ({
criteria: record.id,
partialEntity: record,
})),
undefined,
columnsToReturn,
);
result.identifiers.push(
...savedRecords.map((record) => ({ id: record.id })),
...savedRecords.generatedMaps.map((record) => ({ id: record.id })),
);
result.generatedMaps.push(
...savedRecords.map((record) => ({ id: record.id })),
...savedRecords.generatedMaps.map((record) => ({ id: record.id })),
);
}
@@ -436,9 +444,9 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
}
private getRecordWithoutCreatedBy(
record: Partial<ObjectRecord>,
record: PartialObjectRecordWithId,
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps,
) {
): Omit<PartialObjectRecordWithId, 'createdBy'> {
let recordWithoutCreatedByUpdate = record;
const createdByFieldMetadataId =