diff --git a/pom.xml b/pom.xml
index 0c428fa..4f7f5f6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,6 +43,7 @@
org.projectlombok
lombok
+ 1.18.30
true
@@ -81,6 +82,7 @@
org.projectlombok
lombok
+ 1.18.30
diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java
index 79be9ce..5fdc2e3 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java
@@ -63,8 +63,10 @@ public void deleteLikeToFilm(@PathVariable long filmId, @PathVariable long userI
}
@GetMapping("/popular")
- public List getTopFilms(@RequestParam(defaultValue = "10") @Positive(message = "Count must be positive") int count) {
- log.info("Received GET /films/popular?count={} request", count);
- return filmService.getTopFilms(count);
+ public List getTopFilms(@RequestParam(defaultValue = "10") @Positive(message = "Count must be positive") int count,
+ @RequestParam(defaultValue = "-1") int genreId,
+ @RequestParam(defaultValue = "-1") int year) {
+ log.info("Received GET /films/popular?count={}&genreId={}&year={} request", count, genreId, year);
+ return filmService.getTopFilms(count, genreId, year);
}
}
\ No newline at end of file
diff --git a/src/main/java/ru/yandex/practicum/filmorate/dal/FilmRepository.java b/src/main/java/ru/yandex/practicum/filmorate/dal/FilmRepository.java
index 4adda28..0ddf60e 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/dal/FilmRepository.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/dal/FilmRepository.java
@@ -93,7 +93,7 @@ public Optional findById(long id) {
if (films.isEmpty()) {
return Optional.empty();
} else {
- Film film = films.get(0);
+ Film film = films.getFirst();
setGenresForFilms(List.of(film));
return Optional.of(film);
}
@@ -206,4 +206,32 @@ public void addLike(long filmId, long userId) {
public void removeLike(long filmId, long userId) {
jdbc.update(REMOVE_LIKE_QUERY, filmId, userId);
}
-}
\ No newline at end of file
+
+ public List getTopFilms(int count, Integer genreId, Integer year) {
+
+ StringBuilder queryBuilder = new StringBuilder("SELECT f.*, r.rating_id AS mpa_id, r.rating_name AS mpa_name " +
+ "FROM films AS f JOIN rating AS r on f.rating_id = r.rating_id " +
+ "JOIN film_genre AS fg ON f.id = fg.film_id " +
+ "JOIN likes AS l ON f.id = l.film_id WHERE 1=1");
+
+ List filterParams = new ArrayList<>();
+
+ if (genreId != -1) {
+ queryBuilder.append(" AND fg.genre_id = ?");
+ filterParams.add(genreId);
+ }
+
+ if (year != -1) {
+ queryBuilder.append(" AND EXTRACT(YEAR FROM f.release_date) = ?");
+ filterParams.add(year);
+ }
+
+ queryBuilder.append(" GROUP BY f.id, r.rating_id, r.rating_name ORDER BY COUNT(l.user_id) DESC LIMIT ?;");
+ filterParams.add(count);
+
+ List films = jdbc.query(queryBuilder.toString(), filmWithRatingMapper, filterParams.toArray());
+ setGenresForFilms(films);
+ return films;
+ }
+
+}
diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/film/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/film/FilmService.java
index 4f83d6e..39d8629 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/service/film/FilmService.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/service/film/FilmService.java
@@ -22,7 +22,6 @@
import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -89,23 +88,19 @@ public void deleteLikeToFilm(long filmId, long userId) {
log.info("Like removed successfully");
}
- public List getTopFilms(int count) {
- log.info("Getting top {} popular films", count);
+ public List getTopFilms(int count, int genreId, int year) {
+ log.info("Getting top {} popular films with genreId = {} and release year = {}", count, genreId, year);
if (count <= 0) {
throw new ValidationException("Count parameter must be positive.");
}
- Collection allFilms = filmStorage.getFilms();
- return allFilms.stream()
+ return filmStorage.getTopFilms(count, genreId, year)
+ .stream()
.map(film -> {
Set likes = filmStorage.getLikes(film.getId());
- return Map.entry(film, likes.size());
+ return FilmMapper.mapToFilmDto(film, likes);
})
- .sorted(Map.Entry.comparingByValue().reversed())
- .limit(count)
- .map(Map.Entry::getKey)
- .map(film -> FilmMapper.mapToFilmDto(film, filmStorage.getLikes(film.getId())))
- .collect(Collectors.toList());
+ .toList();
}
public Collection getGenres() {
diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmDbStorage.java
index 5cb7f56..a654a66 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmDbStorage.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmDbStorage.java
@@ -92,6 +92,10 @@ public Rating getRatingById(int id) {
.orElseThrow(() -> new NotFoundException("Rating with id " + id + " not found"));
}
+ public List getTopFilms(int count, int genreId, int year) {
+ return filmRepository.getTopFilms(count, genreId, year);
+ }
+
private void validateRatingExists(Rating mpa) {
if (mpa == null || mpa.getId() == 0) {
throw new IllegalArgumentException("Film Rating (MPA) is required.");
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 1730186..73fd17b 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,7 @@
-logging.level.org.zalando.logbook:ERROR
\ No newline at end of file
+logging.level.org.zalando.logbook=TRACE
+logging.level.ru.yandex.practicum.filmorate=INFO
+spring.sql.init.mode=always
+spring.datasource.url=jdbc:h2:file:./db/filmorate
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=password
\ No newline at end of file