Skip to content

Commit d27494b

Browse files
authored
Merge pull request #1122 from david-roper/improve-upload
Refactor creation of subject ids in upload csv code.
2 parents 76146ae + 55d1939 commit d27494b

File tree

3 files changed

+53
-29
lines changed

3 files changed

+53
-29
lines changed

apps/api/src/instrument-records/instrument-records.service.ts

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type { EntityOperationOptions } from '@/core/types';
2020
import { GroupsService } from '@/groups/groups.service';
2121
import { InstrumentsService } from '@/instruments/instruments.service';
2222
import { SessionsService } from '@/sessions/sessions.service';
23-
import type { CreateSubjectDto } from '@/subjects/dto/create-subject.dto';
23+
import { CreateSubjectDto } from '@/subjects/dto/create-subject.dto';
2424
import { SubjectsService } from '@/subjects/subjects.service';
2525

2626
import { InstrumentMeasuresService } from './instrument-measures.service';
@@ -276,6 +276,14 @@ export class InstrumentRecordsService {
276276
const createdSessionsArray: Session[] = [];
277277

278278
try {
279+
const subjectIdList = records.map(({ subjectId }) => {
280+
const subjectToAdd: CreateSubjectDto = { id: subjectId };
281+
282+
return subjectToAdd;
283+
});
284+
285+
await this.subjectsService.createMany(subjectIdList);
286+
279287
const preProcessedRecords = await Promise.all(
280288
records.map(async (record) => {
281289
const { data: rawData, date, subjectId } = record;
@@ -289,9 +297,6 @@ export class InstrumentRecordsService {
289297
);
290298
}
291299

292-
// Ensure subject exists
293-
await this.createSubjectIfNotFound(subjectId);
294-
295300
const session = await this.sessionsService.create({
296301
date: date,
297302
groupId: groupId ?? null,
@@ -316,7 +321,6 @@ export class InstrumentRecordsService {
316321
};
317322
})
318323
);
319-
320324
await this.instrumentRecordModel.createMany({
321325
data: preProcessedRecords
322326
});
@@ -333,30 +337,6 @@ export class InstrumentRecordsService {
333337
}
334338
}
335339

336-
private async createSubjectIfNotFound(subjectId: string) {
337-
try {
338-
return await this.subjectsService.findById(subjectId);
339-
} catch (exception) {
340-
if (exception instanceof NotFoundException) {
341-
const addedSubject: CreateSubjectDto = {
342-
id: subjectId
343-
};
344-
try {
345-
return await this.subjectsService.create(addedSubject);
346-
} catch (prismaError) {
347-
if (prismaError instanceof Prisma.PrismaClientKnownRequestError && prismaError.code === 'P2002') {
348-
console.error(prismaError);
349-
return await this.subjectsService.findById(subjectId);
350-
} else {
351-
throw prismaError;
352-
}
353-
}
354-
} else {
355-
throw exception;
356-
}
357-
}
358-
}
359-
360340
private parseJson(data: unknown) {
361341
return JSON.parse(JSON.stringify(data), reviver) as unknown;
362342
}

apps/api/src/subjects/subjects.service.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,47 @@ export class SubjectsService {
4141
});
4242
}
4343

44+
async createMany(data: CreateSubjectDto[], { ability }: EntityOperationOptions = {}) {
45+
//filter out all duplicate ids that are planned to be created via a set
46+
const noDuplicatesSet = new Set(
47+
data.map((record) => {
48+
return record.id;
49+
})
50+
);
51+
52+
const subjectIds = Array.from(noDuplicatesSet);
53+
54+
//find the list of subject ids that already exist
55+
const existingSubjects = await this.subjectModel.findMany({
56+
select: { id: true },
57+
where: {
58+
id: { in: subjectIds },
59+
AND: [accessibleQuery(ability, 'read', 'Subject')]
60+
}
61+
});
62+
63+
//create a set of existing ids in the database to filter our to-be-created ids with
64+
const existingIds = new Set(existingSubjects.map((subj) => subj.id));
65+
66+
//Filter out records whose IDs already exist
67+
const subjectsToCreateIds = subjectIds.filter((record) => !existingIds.has(record));
68+
69+
const subjectsToCreate: CreateSubjectDto[] = subjectsToCreateIds.map((record) => {
70+
return {
71+
id: record
72+
};
73+
});
74+
75+
//if there are none left to create do not follow through with the command
76+
if (subjectsToCreate.length < 1) {
77+
return subjectsToCreate;
78+
}
79+
return this.subjectModel.createMany({
80+
data: subjectsToCreate,
81+
...accessibleQuery(ability, 'create', 'Subject')
82+
});
83+
}
84+
4485
async deleteById(id: string, { ability }: EntityOperationOptions = {}) {
4586
const subject = await this.findById(id);
4687
return this.subjectModel.delete({

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)