Skip to content

Commit

Permalink
[BE -#168] 벌크 삭제 로직 책임 분리 (#169)
Browse files Browse the repository at this point in the history
* refactor: 서비스 레이어에서의 벌크 삭제 로직 역할 분리

* refactor: quiz 테이블 명시

* refactor: 분리된 벌크 삭제 메서드를 트랜잭션과 함께 구현
  • Loading branch information
glaxyt authored Dec 12, 2024
1 parent e2ec59d commit e4bb68d
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 47 deletions.
22 changes: 11 additions & 11 deletions packages/server/src/module/quiz/quizzes/entities/quiz.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { QuizType } from '../utils/quiz-type.enum';
import { Choice } from './choice.entity';
import { Class } from './class.entity';

@Entity()
@Entity('quiz')
export class Quiz {
@PrimaryGeneratedColumn()
id: number;
Expand All @@ -15,10 +15,10 @@ export class Quiz {
content: string;

@Column({
name: 'quiz_type',
type: 'enum',
enum: QuizType,
default: QuizType.TF,
name: 'quiz_type',
type: 'enum',
enum: QuizType,
default: QuizType.TF,
})
quizType: QuizType;

Expand All @@ -29,18 +29,18 @@ export class Quiz {
point: number;

@Column()
position: number
position: number;

@Column({ name: 'created_at' })
createdAt: Date;

@OneToMany(() => Choice, choice => choice.quiz, {
@OneToMany(() => Choice, (choice) => choice.quiz, {
cascade: true,
eager: false
eager: false,
})
choices: Choice[];

@ManyToOne(() => Class, cls => cls.quizzes)
@JoinColumn({ name: 'class_id' })
@ManyToOne(() => Class, (cls) => cls.quizzes)
@JoinColumn([{ name: 'class_id', referencedColumnName: 'id' }])
class: Class;
}
}
7 changes: 6 additions & 1 deletion packages/server/src/module/quiz/quizzes/quiz.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ export class QuizService {
}

async deleteClass(id: number): Promise<void> {
await this.classRepository.deleteWithRelations(id);
return this.dataSource.transaction(async (manager) => {
await this.classRepository.findClassById(id);
await this.choiceRepository.deleteByClassId(id, manager);
await this.quizRepository.deleteByClassId(id, manager);
await this.classRepository.delete(id, manager);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ export class ChoiceRepository {
private readonly repository: Repository<Choice>,
) {}

async create(
quizId: number,
choiceData: CreateChoiceRequestDto,
manager?: EntityManager,
): Promise<Choice> {
async create(quizId: number, choiceData: CreateChoiceRequestDto): Promise<Choice> {
const { content, isCorrect, position } = choiceData;
const choiceEntity = this.repository.create({
quizId,
Expand Down Expand Up @@ -72,12 +68,10 @@ export class ChoiceRepository {
}
}

async deleteByQuizId(quizId: number, manager?: EntityManager): Promise<void> {
const repo = manager ? manager.getRepository(Choice) : this.repository;
try {
await repo.delete({ quizId });
} catch (error) {
throw new InternalServerErrorException('Failed to delete choices');
}
async deleteByClassId(classId: number, manager: EntityManager): Promise<void> {
await manager.query(
'DELETE FROM choice WHERE quiz_id IN (SELECT id FROM quiz WHERE class_id = ?)',
[classId],
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { DataSource, EntityManager, Repository } from 'typeorm';
import { Class } from '../entities/class.entity';

@Injectable()
Expand Down Expand Up @@ -128,27 +128,7 @@ export class ClassRepository {
}
}

async deleteWithRelations(id: number): Promise<void> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();

try {
await queryRunner.query(
`DELETE FROM choice WHERE quiz_id IN (SELECT id FROM quiz WHERE class_id = ?)`,
[id],
);

await queryRunner.query(`DELETE FROM quiz WHERE class_id = ?`, [id]);

await queryRunner.query(`DELETE FROM class WHERE id = ?`, [id]);

await queryRunner.commitTransaction();
} catch (error) {
await queryRunner.rollbackTransaction();
throw new InternalServerErrorException('Failed to delete');
} finally {
await queryRunner.release();
}
async delete(id: number, manager: EntityManager): Promise<void> {
await manager.delete(Class, { id });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,8 @@ export class QuizRepository {
await queryRunner.release();
}
}

async deleteByClassId(classId: number, manager: EntityManager): Promise<void> {
await manager.query('DELETE FROM quiz WHERE class_id = ?', [classId]);
}
}

0 comments on commit e4bb68d

Please sign in to comment.