Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 14x 14x 14x 14x 14x 22x 1x 1x 1x 3x 2x 2x 1x 2x 3x 3x 3x 3x 3x 1x 3x 1x 3x 2x 1x 3x 3x 5x 3x 3x 3x 3x 3x 3x 1x | import { InjectRepository } from '@nestjs/typeorm'; import { CommunityCursorPaginationHelper } from 'src/commons/helpers/community.cursor.helper'; import { ApiCommunityGetRequestQueryDto } from 'src/community/dto/api-community-get-request-query.dto'; import { CommunityEntity } from 'src/entities/community.entity'; import { UserDto } from 'src/user/dto/user.dto'; import { IsNull, Repository } from 'typeorm'; export class CommunityQueryRepository { constructor( @InjectRepository(CommunityEntity) private repository: Repository<CommunityEntity>, ) {} async save(communityEntity: CommunityEntity): Promise<CommunityEntity> { return this.repository.save(communityEntity); } async findOne(uuid: string): Promise<CommunityEntity> { return this.repository.findOne({ where: { uuid, archived_at: IsNull() }, }); } async myCommunity(user: UserDto): Promise<CommunityEntity[]> { return this.repository.find({ where: { user_uuid: user.uuid, archived_at: IsNull() }, order: { created_at: 'DESC' }, }); } async findCommunityByCourse(uuid: string, user: UserDto): Promise<CommunityEntity> { return this.repository.findOne({ where: { course_uuid: uuid, user_uuid: user.uuid, archived_at: IsNull() }, }); } async countTotalCommunity(dto: ApiCommunityGetRequestQueryDto, user: UserDto): Promise<number> { const qb = this.repository .createQueryBuilder('community') .where('community.archived_at IS NULL'); if (dto.me) { qb.andWhere('community.user_uuid = :userUuid', { userUuid: user.uuid }); } return qb.getCount(); } async findCommunityList( dto: ApiCommunityGetRequestQueryDto, user: UserDto, ): Promise<{ communityList: CommunityEntity[]; nextCursor: string | null }> { const qb = this.repository.createQueryBuilder('community'); // 1. 서브쿼리 생성 const likeCountSub = CommunityCursorPaginationHelper.buildLikeCountSub(qb); const isLikedSub = CommunityCursorPaginationHelper.buildIsLikedSub(qb); // 2. SELECT에 서브쿼리 추가 qb.addSelect(`${likeCountSub}`, 'like_count') .addSelect(`${isLikedSub}`, 'is_liked') .where('community.archived_at IS NULL') .setParameter('userUuid', user.uuid); if (dto.me) { qb.andWhere('community.user_uuid = :userUuid', { userUuid: user.uuid }); } // 3. 커서 필터 if (dto.next_page) { CommunityCursorPaginationHelper.applyCursor(qb, dto.order, dto.next_page, likeCountSub); } // 4. 정렬 및 페이징 if (dto.order === 'latest') { qb.orderBy('community.created_at', 'DESC').addOrderBy('community.id', 'DESC'); } else { qb.orderBy('like_count', 'DESC') .addOrderBy('community.created_at', 'DESC') .addOrderBy('community.id', 'DESC'); } qb.take(dto.size + 1); // 5. 실행 후 매핑 const { entities, raw } = await qb.getRawAndEntities(); const updated = entities.map((c, i) => ({ ...c, like_count: parseInt(raw[i].like_count, 10), is_liked: raw[i].is_liked === '1', })); // 6. nextCursor 계산 const hasNext = updated.length > dto.size; const pageItems = hasNext ? updated.slice(0, dto.size) : updated; const nextCursor = hasNext ? CommunityCursorPaginationHelper.generateCursor(pageItems[pageItems.length - 1], dto.order) : null; return { communityList: pageItems, nextCursor }; } async findExistingCourse(courseUuids: string[]) { const result = await this.repository .createQueryBuilder('community') .leftJoin('community.reactions', 'reaction', 'reaction.like = 1') .select('community.course_uuid', 'course_uuid') .addSelect('MIN(community.uuid)', 'community_uuid') .addSelect('community.score', 'score') .addSelect('COUNT(reaction.id)', 'like_count') .where('community.course_uuid IN (:...courseUuids)', { courseUuids }) .andWhere('community.archived_at IS NULL') .groupBy('community.course_uuid') .addGroupBy('community.score') .getRawMany(); return result.map((row) => ({ community_uuid: row.community_uuid, course_uuid: row.course_uuid, score: row.score, like_count: parseInt(row.like_count, 10), })); } async findCourse(uuid: string): Promise<CommunityEntity> { return this.repository.findOne({ where: { course_uuid: uuid, archived_at: IsNull() }, }); } } |