Skip to content

Commit

Permalink
refactor: DB를 사용하는 코드로 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
splitCoding committed Sep 20, 2023
1 parent 2583129 commit 5cc8cf8
Show file tree
Hide file tree
Showing 15 changed files with 817 additions and 660 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
import shook.shook.member.exception.MemberException;
import shook.shook.member.exception.MemberException.MemberNotExistException;
import shook.shook.song.application.dto.LikedKillingPartResponse;
import shook.shook.song.domain.killingpart.KillingPart;
import shook.shook.song.domain.killingpart.KillingPartLike;
import shook.shook.song.domain.killingpart.repository.KillingPartLikeRepository;
import shook.shook.song.domain.killingpart.repository.dto.SongKillingPartDto;

@RequiredArgsConstructor
@Transactional(readOnly = true)
Expand All @@ -33,14 +32,17 @@ public List<LikedKillingPartResponse> findLikedKillingPartByMemberId(
final Member member = memberRepository.findById(memberInfo.getMemberId())
.orElseThrow(MemberNotExistException::new);

final List<KillingPartLike> likes =
killingPartLikeRepository.findAllByMemberAndIsDeleted(member, false);
final List<SongKillingPartDto> likedKillingPartAndSongByMember =
killingPartLikeRepository.findLikedKillingPartAndSongByMember(member);

return likes.stream()
.sorted(Comparator.comparing(KillingPartLike::getUpdatedAt).reversed())
.map(killingPartLike -> {
final KillingPart killingPart = killingPartLike.getKillingPart();
return LikedKillingPartResponse.of(killingPart.getSong(), killingPart);
}).toList();
return likedKillingPartAndSongByMember.stream()
.sorted(Comparator.comparing(
songKillingPart -> songKillingPart.getKillingPart().getCreatedAt())
).map(
songKillingPart -> LikedKillingPartResponse.of(
songKillingPart.getSong(),
songKillingPart.getKillingPart()
)
).toList();
}
}
104 changes: 85 additions & 19 deletions backend/src/main/java/shook/shook/song/application/SongService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package shook.shook.song.application;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,11 +16,12 @@
import shook.shook.song.application.dto.SongSwipeResponse;
import shook.shook.song.application.dto.SongWithKillingPartsRegisterRequest;
import shook.shook.song.application.killingpart.dto.HighLikedSongResponse;
import shook.shook.song.domain.InMemorySongs;
import shook.shook.song.domain.Song;
import shook.shook.song.domain.SongTitle;
import shook.shook.song.domain.killingpart.repository.KillingPartLikeRepository;
import shook.shook.song.domain.killingpart.repository.KillingPartRepository;
import shook.shook.song.domain.repository.SongRepository;
import shook.shook.song.domain.repository.dto.SongTotalLikeCountDto;
import shook.shook.song.exception.SongException;

@RequiredArgsConstructor
Expand All @@ -29,12 +31,11 @@ public class SongService {

private static final int AFTER_SONGS_COUNT = 10;
private static final int BEFORE_SONGS_COUNT = 10;
private static final int TOP_COUNT = 100;

private final SongRepository songRepository;
private final KillingPartRepository killingPartRepository;
private final MemberRepository memberRepository;
private final InMemorySongs inMemorySongs;
private final KillingPartLikeRepository killingPartLikeRepository;
private final SongDataExcelReader songDataExcelReader;

@Transactional
Expand All @@ -54,39 +55,92 @@ private Song saveSong(final Song song) {
}

public List<HighLikedSongResponse> showHighLikedSongs() {
final List<Song> songs = inMemorySongs.getSongs();
final List<Song> top100Songs = songs.subList(0, Math.min(TOP_COUNT, songs.size()));
final List<SongTotalLikeCountDto> songsWithLikeCount = songRepository.findAllWithTotalLikeCount();
return HighLikedSongResponse.ofSongTotalLikeCounts(
sortByHighestLikeCountAndId(songsWithLikeCount)
);
}

return HighLikedSongResponse.ofSongs(top100Songs);
private List<SongTotalLikeCountDto> sortByHighestLikeCountAndId(
final List<SongTotalLikeCountDto> songWithLikeCounts
) {
return songWithLikeCounts.stream()
.sorted(
Comparator.comparing(
SongTotalLikeCountDto::getTotalLikeCount,
Comparator.reverseOrder()
).thenComparing(dto -> dto.getSong().getId(), Comparator.reverseOrder())
).toList();
}

public SongSwipeResponse findSongByIdForFirstSwipe(
final Long songId,
final MemberInfo memberInfo
) {
final Song currentSong = inMemorySongs.getSongById(songId);

final List<Song> beforeSongs = inMemorySongs.getPrevLikedSongs(currentSong, BEFORE_SONGS_COUNT);
final List<Song> afterSongs = inMemorySongs.getNextLikedSongs(currentSong, AFTER_SONGS_COUNT);
final List<Song> sortedSong = getSongsSortedByTotalLikeCount();
final Song currentSong = findSongById(songId);
final int currentSongIndex = sortedSong.indexOf(currentSong);
final List<Song> beforeSongs = getPrevSongsForSwipe(sortedSong, currentSongIndex);
final List<Song> afterSongs = getNextSongsForSwipe(sortedSong, currentSongIndex);

return convertToSongSwipeResponse(memberInfo, currentSong, beforeSongs, afterSongs);
}

private Song findSongById(final Long songId) {
return songRepository.findById(songId)
.orElseThrow(() -> new SongException.SongNotExistException(
Map.of("SongId", String.valueOf(songId))
));
}

private List<Song> getSongsSortedByTotalLikeCount() {
final List<Song> allSongWithKillingParts = songRepository.findAllSongWithKillingParts();
allSongWithKillingParts.sort(
Comparator.comparing(Song::getTotalLikeCount, Comparator.reverseOrder())
.thenComparing(Song::getId, Comparator.reverseOrder()));

return allSongWithKillingParts;
}

private List<Song> getPrevSongsForSwipe(final List<Song> songList, final int songIndex) {
if (songIndex == -1) {
throw new SongException.SongNotExistException();
}
final int validStartIndex = Math.max(0, songIndex - BEFORE_SONGS_COUNT);

return songList.subList(validStartIndex, songIndex);
}

private List<Song> getNextSongsForSwipe(final List<Song> songList, final int songIndex) {
if (songIndex == -1) {
throw new SongException.SongNotExistException();
}
final int validStartIndex = Math.min(songList.size(), songIndex + 1);
final int validEndIndex = Math.min(songList.size(), songIndex + AFTER_SONGS_COUNT + 1);

return songList.subList(validStartIndex, validEndIndex);
}

private SongSwipeResponse convertToSongSwipeResponse(
final MemberInfo memberInfo,
final Song currentSong,
final List<Song> beforeSongs,
final List<Song> afterSongs
) {
final Authority authority = memberInfo.getAuthority();

if (authority.isAnonymous()) {
return SongSwipeResponse.ofUnauthorizedUser(currentSong, beforeSongs, afterSongs);
}

final Member member = findMemberById(memberInfo.getMemberId());

return SongSwipeResponse.of(member, currentSong, beforeSongs, afterSongs);
final List<Long> likedKillingPartIds =
killingPartLikeRepository.findLikedKillingPartIdsByMember(member);

return SongSwipeResponse.of(
currentSong,
beforeSongs,
afterSongs,
likedKillingPartIds
);
}

private Member findMemberById(final Long memberId) {
Expand All @@ -102,8 +156,13 @@ public List<SongResponse> findSongByIdForBeforeSwipe(
final Long songId,
final MemberInfo memberInfo
) {
final Song currentSong = inMemorySongs.getSongById(songId);
final List<Song> beforeSongs = inMemorySongs.getPrevLikedSongs(currentSong, BEFORE_SONGS_COUNT);
final Song currentSong = findSongById(songId);
final List<Song> songsSortedByTotalLikeCount = getSongsSortedByTotalLikeCount();
final int currentSongIndex = songsSortedByTotalLikeCount.indexOf(currentSong);
final List<Song> beforeSongs = getPrevSongsForSwipe(
songsSortedByTotalLikeCount,
currentSongIndex
);

return convertToSongResponses(memberInfo, beforeSongs);
}
Expand All @@ -121,18 +180,25 @@ private List<SongResponse> convertToSongResponses(
}

final Member member = findMemberById(memberInfo.getMemberId());
final List<Long> likedKillingPartIds =
killingPartLikeRepository.findLikedKillingPartIdsByMember(member);

return songs.stream()
.map(song -> SongResponse.of(song, member))
.map(song -> SongResponse.of(song, likedKillingPartIds))
.toList();
}

public List<SongResponse> findSongByIdForAfterSwipe(
final Long songId,
final MemberInfo memberInfo
) {
final Song currentSong = inMemorySongs.getSongById(songId);
final List<Song> afterSongs = inMemorySongs.getNextLikedSongs(currentSong, AFTER_SONGS_COUNT);
final Song currentSong = findSongById(songId);
final List<Song> songsSortedByTotalLikeCount = getSongsSortedByTotalLikeCount();
final int currentSongIndex = songsSortedByTotalLikeCount.indexOf(currentSong);
final List<Song> afterSongs = getNextSongsForSwipe(
songsSortedByTotalLikeCount,
currentSongIndex
);

return convertToSongResponses(memberInfo, afterSongs);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import shook.shook.member.domain.Member;
import shook.shook.song.domain.Song;
import shook.shook.song.domain.killingpart.KillingPart;

Expand Down Expand Up @@ -41,7 +40,7 @@ public static KillingPartResponse of(
final Song song,
final KillingPart killingPart,
final int rank,
final Member member
final boolean isLiked
) {
return new KillingPartResponse(
killingPart.getId(),
Expand All @@ -51,7 +50,7 @@ public static KillingPartResponse of(
killingPart.getEndSecond(),
song.getPartVideoUrl(killingPart),
killingPart.getLength(),
killingPart.isLikedByMember(member)
isLiked
);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package shook.shook.song.application.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import shook.shook.member.domain.Member;
import shook.shook.song.domain.Song;
import shook.shook.song.domain.killingpart.KillingPart;

Expand Down Expand Up @@ -37,29 +36,43 @@ public class SongResponse {
@Schema(description = "킬링파트 3개")
private final List<KillingPartResponse> killingParts;

public static SongResponse of(final Song song, final Member member) {
public static SongResponse of(
final Song song,
final List<Long> likedKillingPartIds
) {
return new SongResponse(
song.getId(),
song.getTitle(),
song.getSinger(),
song.getLength(),
song.getVideoId(),
song.getAlbumCoverUrl(),
toKillingPartResponses(song, member)
toKillingPartResponses(song, likedKillingPartIds)
);
}

public static SongResponse fromUnauthorizedUser(final Song song) {
return SongResponse.of(song, null);
return SongResponse.of(song, Collections.emptyList());
}

private static List<KillingPartResponse> toKillingPartResponses(final Song song,
final Member member) {
private static List<KillingPartResponse> toKillingPartResponses(
final Song song,
final List<Long> likedKillingPartIds
) {
final List<KillingPart> songKillingParts = song.getLikeCountSortedKillingParts();

return IntStream.range(0, songKillingParts.size())
.mapToObj(index ->
KillingPartResponse.of(song, songKillingParts.get(index), index + 1, member))
.collect(Collectors.toList());
{
final KillingPart killingPart = songKillingParts.get(index);
final int killingPartRank = index + 1;
return KillingPartResponse.of(
song,
killingPart,
killingPartRank,
likedKillingPartIds.contains(killingPart.getId())
);
})
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import shook.shook.member.domain.Member;
import shook.shook.song.domain.Song;

@Schema(description = "첫 스와이프 시, 현재 노래와 이전, 이후 노래 리스트 조회 응답")
Expand All @@ -23,20 +22,21 @@ public class SongSwipeResponse {
private final List<SongResponse> nextSongs;

public static SongSwipeResponse of(
final Member member,
final Song currentSong,
final List<Song> prevSongs,
final List<Song> nextSongs
final List<Song> nextSongs,
final List<Long> likedKillingPartIds
) {
final SongResponse currentResponse = SongResponse.of(currentSong, member);
final SongResponse currentResponse = SongResponse.of(currentSong, likedKillingPartIds);
final List<SongResponse> prevResponses = prevSongs.stream()
.map(song -> SongResponse.of(song, member))
.map(song -> SongResponse.of(song, likedKillingPartIds))
.toList();
final List<SongResponse> nextResponses = nextSongs.stream()
.map(song -> SongResponse.of(song, member))
.map(song -> SongResponse.of(song, likedKillingPartIds))
.toList();

return new SongSwipeResponse(prevResponses, currentResponse, nextResponses);
return new SongSwipeResponse(prevResponses,
currentResponse, nextResponses);
}

public static SongSwipeResponse ofUnauthorizedUser(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package shook.shook.song.application.killingpart.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import shook.shook.song.domain.Song;
import java.util.List;
import shook.shook.song.domain.repository.dto.SongTotalLikeCountDto;

@Schema(description = "좋아요 순 노래 응답")
@AllArgsConstructor(access = AccessLevel.PRIVATE)
Expand All @@ -27,17 +27,19 @@ public class HighLikedSongResponse {
@Schema(description = "총 좋아요 개수", example = "40")
private final long totalLikeCount;

private static HighLikedSongResponse from(final Song song) {
private static HighLikedSongResponse from(final SongTotalLikeCountDto songTotalVoteCountDto) {
return new HighLikedSongResponse(
song.getId(),
song.getTitle(),
song.getSinger(),
song.getAlbumCoverUrl(),
song.getTotalLikeCount()
songTotalVoteCountDto.getSong().getId(),
songTotalVoteCountDto.getSong().getTitle(),
songTotalVoteCountDto.getSong().getSinger(),
songTotalVoteCountDto.getSong().getAlbumCoverUrl(),
songTotalVoteCountDto.getTotalLikeCount()
);
}

public static List<HighLikedSongResponse> ofSongs(final List<Song> songs) {
public static List<HighLikedSongResponse> ofSongTotalLikeCounts(
final List<SongTotalLikeCountDto> songs
) {
return songs.stream()
.map(HighLikedSongResponse::from)
.toList();
Expand Down
Loading

0 comments on commit 5cc8cf8

Please sign in to comment.