diff --git a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java new file mode 100644 index 0000000000000000000000000000000000000000..a950fc9846908df7655d8e9d907bcc5b430eb793 --- /dev/null +++ b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java @@ -0,0 +1,28 @@ +package cz.muni.pa165.common_library.dtos; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Data; + +/** + * Dto fro DriverCar entity. + */ +@Data +@Builder +public class RaceDriverCarDto { + + @NotNull + @Schema(description = "driver id", example = "1") + Long driverId; + + @NotNull + @Schema(description = "car id", example = "1") + Long carId; + + @Schema(description = "driver name", example = "Charles Leclerc") + String driverName; + + @Schema(description = "drivers position in the race", example = "1") + int position; +} diff --git a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDto.java b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDto.java index 0c26d22f1c58fe482b699a76774f55941f91fe34..b56ebfb297430cb017e879a3d4cc60543ec2d7cc 100644 --- a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDto.java +++ b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDto.java @@ -1,6 +1,7 @@ package cz.muni.pa165.common_library.dtos; import cz.muni.pa165.common_library.racecomponents.Location; +import cz.muni.pa165.common_library.racecomponents.Race; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; @@ -21,17 +22,35 @@ public class RaceDto { Long id; @NotNull - @Schema(description = "race location", example = "Monaco") - private Location location; - - @NotNull - @Schema(description = "race name", example = "Monaco Grand Prix 2023") - private String name; + @Schema(description = "race information") + private RaceDto.RaceInfo raceInfo; @Schema(description = "driver one", example = "{1, 1, Charles Leclerc}") - private DriverCarDto driverOne; + private RaceDriverCarDto driverOne; @Schema(description = "driver two", example = "{2, 2, Carlos Sainz}") - private DriverCarDto driverTwo; + private RaceDriverCarDto driverTwo; + + /** + * Race information. + */ + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class RaceInfo { + + @NotNull + @Schema(description = "race location", example = "Monaco") + private Location location; + + @NotNull + @Schema(description = "race name", example = "Monaco Grand Prix 2023") + private String name; + + @NotNull + @Schema(description = "race prize pool", example = "30000000") + private long prizePool; + } } diff --git a/common_library/src/main/java/cz/muni/pa165/common_library/racecomponents/Race.java b/common_library/src/main/java/cz/muni/pa165/common_library/racecomponents/Race.java index 81e9a9c3fb55d4f6757211beeaf2c2335ab880b1..b0fd1569706d574cb861497f02561a614c0baf78 100644 --- a/common_library/src/main/java/cz/muni/pa165/common_library/racecomponents/Race.java +++ b/common_library/src/main/java/cz/muni/pa165/common_library/racecomponents/Race.java @@ -1,5 +1,6 @@ package cz.muni.pa165.common_library.racecomponents; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -9,10 +10,16 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -33,28 +40,71 @@ public class Race implements Serializable { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @NotNull - @Enumerated(EnumType.STRING) - private Location location; + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "race_info_id") + private RaceInfo raceInfo; - @NotNull - @Column(length = 100, nullable = false) - private String name; + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "driver_info_one_id") + private RaceDriverinfo driver1; - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "driver_one_id") - private Driver driver1; + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "driver_info_two_id") + private RaceDriverinfo driver2; - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "car_one_id") - private Car car1; + /** + * Information about race driver. + */ + @Entity + @Table(name = "racedriverinfo") + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + public static class RaceDriverinfo implements Serializable { - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "driver_two_id") - private Driver driver2; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "car_two_id") - private Car car2; + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "driver_one_id") + private Driver driver; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "car_one_id") + private Car car; + + @Min(1) + @Max(20) + private int finalPosition; + } + + /** + * Information about race. + */ + @Entity + @Table(name = "raceinfo") + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + public static class RaceInfo implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @Enumerated(EnumType.STRING) + private Location location; + + @NotNull + @Column(length = 100, nullable = false) + private String name; + + @NotNull + private Long prizePool; + } } diff --git a/race/src/main/java/cz/muni/pa165/race/RestExceptionHandler.java b/race/src/main/java/cz/muni/pa165/race/RestExceptionHandler.java deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/race/src/main/java/cz/muni/pa165/race/data/repository/RaceRepository.java b/race/src/main/java/cz/muni/pa165/race/data/repository/RaceRepository.java index e44aa669d259496c14e9516ee60c4e19a302a1ed..cc5689af7a03444cbf25101a1c86251cf6b73e18 100644 --- a/race/src/main/java/cz/muni/pa165/race/data/repository/RaceRepository.java +++ b/race/src/main/java/cz/muni/pa165/race/data/repository/RaceRepository.java @@ -1,14 +1,24 @@ package cz.muni.pa165.race.data.repository; +import cz.muni.pa165.common_library.racecomponents.Location; import cz.muni.pa165.common_library.racecomponents.Race; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; /** * Race repository. */ @Repository -// TODO queries na assignovanie driverov public interface RaceRepository extends JpaRepository<Race, Long> { + @Query("SELECT r FROM Race r" + + " JOIN r.raceInfo ri " + + " JOIN r.driver1 do " + + " JOIN r.driver2 dt " + + "WHERE ri.location = :location AND (do.id = :driverId OR dt.id = :driverId)") + List<Race> findAllRacesOfDriverInLocation(@Param("location") Location raceLocation, + @Param("driverId") long driverId); } diff --git a/race/src/main/java/cz/muni/pa165/race/service/RaceService.java b/race/src/main/java/cz/muni/pa165/race/service/RaceService.java index 882afe57722efb2fae1869ee5c2c0d53a5343a71..85043c484b5a4fe51274825a9527522a5a6afcf3 100644 --- a/race/src/main/java/cz/muni/pa165/race/service/RaceService.java +++ b/race/src/main/java/cz/muni/pa165/race/service/RaceService.java @@ -1,5 +1,6 @@ package cz.muni.pa165.race.service; +import cz.muni.pa165.common_library.dtos.RaceDriverCarDto; import cz.muni.pa165.common_library.dtos.RaceDto; import cz.muni.pa165.common_library.exception.DatabaseException; import cz.muni.pa165.common_library.racecomponents.Car; @@ -58,7 +59,7 @@ public class RaceService { .orElseThrow(() -> new DatabaseException("Driver not found")); var race = raceRepository.findById(raceId) .orElseThrow(() -> new DatabaseException("Race not found")); - race.setDriver1(driver); + race.getDriver1().setDriver(driver); raceRepository.save(race); return "Driver with id: " + driverId + "was succesfully assigned to race with id: " + raceId + " as driver one"; @@ -72,7 +73,7 @@ public class RaceService { .orElseThrow(() -> new DatabaseException("Driver not found")); var race = raceRepository.findById(raceId) .orElseThrow(() -> new DatabaseException("Race not found")); - race.setDriver2(driver); + race.getDriver2().setDriver(driver); raceRepository.save(race); return "Driver with id: " + driverId + "was succesfully assigned to race with id: " + raceId + " as driver two"; @@ -102,18 +103,31 @@ public class RaceService { private Race convertRaceDto(RaceDto raceDto) { var race = Race.builder() .id(raceDto.getId()) - .location(raceDto.getLocation()) - .name(raceDto.getName()) .build(); + var raceInfo = Race.RaceInfo + .builder() + .id(raceDto.getId()) + .name(raceDto.getRaceInfo().getName()) + .location(raceDto.getRaceInfo().getLocation()) + .prizePool(raceDto.getRaceInfo().getPrizePool()) + .build(); + race.setRaceInfo(raceInfo); + if (raceDto.getDriverOne() != null) { - race.setDriver1(getDriver(raceDto.getDriverOne())); - race.setCar1(getCar(raceDto.getDriverOne())); + race.setDriver1(Race.RaceDriverinfo + .builder() + .driver(getDriver(raceDto.getDriverOne())) + .car(getCar(raceDto.getDriverOne())) + .build()); } if (raceDto.getDriverTwo() != null) { - race.setDriver2(getDriver(raceDto.getDriverTwo())); - race.setCar2(getCar(raceDto.getDriverTwo())); + race.setDriver2(Race.RaceDriverinfo + .builder() + .driver(getDriver(raceDto.getDriverTwo())) + .car(getCar(raceDto.getDriverTwo())) + .build()); } return race; @@ -122,36 +136,39 @@ public class RaceService { private RaceDto convertRace(Race race) { var raceDto = RaceDto.builder() .id(race.getId()) - .name(race.getName()) - .location(race.getLocation()) + .raceInfo(RaceDto.RaceInfo.builder() + .name(race.getRaceInfo().getName()) + .location(race.getRaceInfo().getLocation()) + .prizePool(race.getRaceInfo().getPrizePool()) + .build()) .build(); - if (race.getCar1() != null && race.getDriver1() != null) { - raceDto.setDriverOne(DriverCarDto.builder() - .carId(race.getCar1().getId()) + if (race.getDriver1() != null && race.getDriver1().getCar() != null) { + raceDto.setDriverOne(RaceDriverCarDto.builder() + .carId(race.getDriver1().getCar().getId()) .driverId(race.getDriver1().getId()) - .driverName(race.getDriver1().getName() - + " " + race.getDriver1().getSurname()) + .driverName(race.getDriver1().getDriver().getName() + + " " + race.getDriver1().getDriver().getSurname()) .build()); } - if (race.getCar2() != null && race.getDriver2() != null) { - raceDto.setDriverTwo(DriverCarDto.builder() - .carId(race.getCar2().getId()) + if (race.getDriver2() != null && race.getDriver2().getCar() != null) { + raceDto.setDriverTwo(RaceDriverCarDto.builder() + .carId(race.getDriver2().getCar().getId()) .driverId(race.getDriver2().getId()) - .driverName(race.getDriver2().getName() - + " " + race.getDriver2().getSurname()) + .driverName(race.getDriver2().getDriver().getName() + + " " + race.getDriver2().getDriver().getSurname()) .build()); } return raceDto; } - private Driver getDriver(DriverCarDto driverCarDto) { + private Driver getDriver(RaceDriverCarDto driverCarDto) { return driverRepository.findById(driverCarDto.getDriverId()).orElseThrow( () -> new DatabaseException("Something went wrong when" + "finding the driver with id: " + driverCarDto.getDriverId() + " in the database.")); } - private Car getCar(DriverCarDto driverCarDto) { + private Car getCar(RaceDriverCarDto driverCarDto) { return carRepository.findById(driverCarDto.getCarId()).orElseThrow( () -> new DatabaseException("Something went wrong when" + "finding the car with id: " + driverCarDto.getCarId() + " in the database.")); diff --git a/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java b/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java index 0519d94d6f23dc6021de6caea1c15e4f2fbe2c5a..06d43d76fb4ab289699aa3fd30747ecfab2d1e24 100644 --- a/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java +++ b/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java @@ -5,8 +5,6 @@ import cz.muni.pa165.common_library.dtos.SeasonDto; import cz.muni.pa165.common_library.exception.DatabaseException; import cz.muni.pa165.common_library.racecomponents.Race; import cz.muni.pa165.common_library.racecomponents.Season; -import cz.muni.pa165.race.api.RaceNameDto; -import cz.muni.pa165.race.api.SeasonDto; import cz.muni.pa165.race.data.repository.RaceRepository; import cz.muni.pa165.race.data.repository.SeasonRepository; import java.util.List; @@ -109,7 +107,7 @@ public class SeasonService implements SeasonServiceInterface { .races(season.getRaces() .stream() .map(x -> RaceNameDto.builder() - .name(x.getName()) + .name(x.getRaceInfo().getName()) .id(x.getId()) .build()) .toList())