Skip to content

Commit

Permalink
Merge pull request #118 from hufscheer/feature/#109-games
Browse files Browse the repository at this point in the history
[FEAT] 경기 목록 조회 라운드, 팀 아이디로도 조회할 수 있도록 수정
  • Loading branch information
Jin409 authored Mar 1, 2024
2 parents 1a15a82 + eb0349d commit d67b0a7
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 117 deletions.
22 changes: 16 additions & 6 deletions src/main/java/com/sports/server/command/game/domain/Game.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
package com.sports.server.command.game.domain;

import com.sports.server.command.league.domain.League;
import com.sports.server.command.member.domain.Member;
import com.sports.server.command.sport.domain.Sport;
import com.sports.server.command.league.domain.League;
import com.sports.server.common.domain.BaseEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
Expand Down Expand Up @@ -52,4 +59,7 @@ public class Game extends BaseEntity<Game> {
@Column(name = "state", nullable = false)
@Enumerated(EnumType.STRING)
private GameState state;

@Column(name = "round", nullable = false)
private Integer round;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ public class GamesQueryRequestDto {
private Long leagueId;
private String stateValue;
private List<Long> sportIds;
private List<Long> leagueTeamIds;
private Integer round;

public GamesQueryRequestDto(Long league_id, String status, List<Long> sport_id) {
public GamesQueryRequestDto(Long league_id, String state, List<Long> sport_id, List<Long> league_team_id,
Integer round) {
this.leagueId = league_id;
this.stateValue = status;
this.stateValue = state;
this.sportIds = sport_id;
this.leagueTeamIds = league_team_id;
this.round = round;
}

public String getStateValue() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package com.sports.server.query.repository;

import static com.sports.server.command.game.domain.QGame.game;
import static com.sports.server.command.sport.domain.QSport.sport;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.sports.server.command.game.domain.Game;
import com.sports.server.query.dto.request.GamesQueryRequestDto;
import com.sports.server.common.dto.PageRequestDto;
import com.sports.server.query.dto.request.GamesQueryRequestDto;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

import static com.sports.server.command.game.domain.QGame.game;
import static com.sports.server.command.sport.domain.QSport.sport;

@Repository
@RequiredArgsConstructor
public class GameDynamicRepositoryImpl implements GameDynamicRepository {
Expand All @@ -26,7 +25,7 @@ public List<Game> findAllByLeagueAndStateAndSports(final GamesQueryRequestDto ga
.selectFrom(game)
.join(game.sport, sport).fetchJoin()
.where(conditionMapper.mapBooleanCondition(gameQueryRequestDto, pageRequestDto))
.orderBy(conditionMapper.mapOrderCondition(gameQueryRequestDto))
.orderBy(game.startTime.asc(), game.id.asc())
.limit(pageRequestDto.size())
.fetch();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.sports.server.query.repository;

import static com.sports.server.command.game.domain.QGameTeam.gameTeam;

import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

@Repository
@RequiredArgsConstructor
public class GameTeamDynamicRepository {

private final JPAQueryFactory jpaQueryFactory;

public List<Long> findAllByLeagueTeamIds(final List<Long> leagueTeamIds) {
return jpaQueryFactory
.selectFrom(gameTeam)
.select(gameTeam.game.id)
.where(gameTeam.leagueTeam.id.in(leagueTeamIds))
.fetch();
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package com.sports.server.query.repository;

import static com.sports.server.command.game.domain.QGame.game;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.sports.server.command.game.domain.GameState;
import com.sports.server.common.dto.PageRequestDto;
import com.sports.server.query.dto.request.GamesQueryRequestDto;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

import static com.sports.server.command.game.domain.QGame.game;

@Component
@RequiredArgsConstructor
public class GamesQueryConditionMapper {
Expand All @@ -21,6 +20,7 @@ public class GamesQueryConditionMapper {
private static final OrderSpecifier<?>[] NOT_FINISHED_ORDER = {game.startTime.asc(), game.id.asc()};

private final JPAQueryFactory jpaQueryFactory;
private final GameTeamDynamicRepository gameTeamDynamicRepository;

public OrderSpecifier<?>[] mapOrderCondition(GamesQueryRequestDto request) {
GameState state = GameState.from(request.getStateValue());
Expand All @@ -38,13 +38,10 @@ public BooleanBuilder mapBooleanCondition(GamesQueryRequestDto gamesQueryRequest
DynamicBooleanBuilder booleanBuilder = DynamicBooleanBuilder.builder()
.and(() -> game.league.id.eq(gamesQueryRequestDto.getLeagueId()))
.and(() -> game.state.eq(state))
.and(() -> game.sport.id.in(gamesQueryRequestDto.getSportIds()));
if (state == GameState.FINISHED) {
return booleanBuilder
.and(() -> game.startTime.eq(cursorStartTime).and(game.id.lt(cursor))
.or(game.startTime.lt(cursorStartTime)))
.build();
}
.and(() -> game.sport.id.in(gamesQueryRequestDto.getSportIds()))
.and(() -> game.round.in(gamesQueryRequestDto.getRound()))
.and(() -> game.id.in(
gameTeamDynamicRepository.findAllByLeagueTeamIds(gamesQueryRequestDto.getLeagueTeamIds())));
return booleanBuilder
.and(() -> game.startTime.eq(cursorStartTime).and(game.id.gt(cursor))
.or(game.startTime.gt(cursorStartTime)))
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/db/migration/V8__game-round.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE games
ADD COLUMN round INT;
14 changes: 11 additions & 3 deletions src/main/resources/static/docs/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ <h3 id="_게임_목록_조회"><a class="link" href="#_게임_목록_조회">게
<h4 id="_게임_목록_조회_http_request"><a class="link" href="#_게임_목록_조회_http_request">HTTP request</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">GET /games?league_id=1&amp;status=PLAYING&amp;sport_id=1&amp;sport_id=2&amp;cursor=12&amp;size=10 HTTP/1.1
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">GET /games?league_id=1&amp;state=PLAYING&amp;sport_id=1&amp;sport_id=2&amp;round=4&amp;league_team_id=1&amp;cursor=12&amp;size=10 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Host: www.api.hufstreaming.site</code></pre>
</div>
Expand All @@ -948,7 +948,7 @@ <h4 id="_게임_목록_조회_query_parameters"><a class="link" href="#_게임_
<td class="tableblock halign-left valign-top"><p class="tableblock">대회의 ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>status</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>state</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">게임의 상태</p></td>
</tr>
<tr>
Expand All @@ -963,6 +963,14 @@ <h4 id="_게임_목록_조회_query_parameters"><a class="link" href="#_게임_
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>size</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">페이징 사이즈</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>league_team_id</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">리그팀의 ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>round</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">라운드</p></td>
</tr>
</tbody>
</table>
</div>
Expand Down Expand Up @@ -1953,7 +1961,7 @@ <h4 id="_스포츠_전체_조회_response_fields"><a class="link" href="#_스포
<div id="footer">
<div id="footer-text">
Version 0.0.1-SNAPSHOT<br>
Last updated 2024-02-26 00:13:51 +0900
Last updated 2024-02-28 21:38:25 UTC
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,11 @@ public class GameQueryAcceptanceTest extends AcceptanceTest {

// when
ExtractableResponse<Response> response = RestAssured.given()
.queryParam("status", "SCHEDULED")
.queryParam("state", "SCHEDULED")
.queryParam("league_id", 1L)
.queryParam("round", 4)
.queryParam("league_team_id", 1L)
.queryParam("league_team_id", 2L)
.log().all()
.when()
.contentType(MediaType.APPLICATION_JSON_VALUE)
Expand All @@ -80,7 +83,7 @@ public class GameQueryAcceptanceTest extends AcceptanceTest {
//then
List<GameResponseDto> games = toResponses(response, GameResponseDto.class);
assertAll(
() -> assertThat(games).hasSize(defaultSizeOfData),
() -> assertThat(games).hasSize(9),
() -> assertThat(games)
.filteredOn(game -> game.id().equals(1L))
.containsExactly(
Expand Down Expand Up @@ -122,7 +125,7 @@ public class GameQueryAcceptanceTest extends AcceptanceTest {
// when
int lastPkOfFixtureFromFirstLeague = 13;
ExtractableResponse<Response> response = RestAssured.given()
.queryParam("status", "SCHEDULED")
.queryParam("state", "SCHEDULED")
.queryParam("league_id", 1L)
.queryParam("size", lastPkOfFixtureFromFirstLeague)
.queryParam("sport_id", 1L)
Expand Down
Loading

0 comments on commit d67b0a7

Please sign in to comment.