From 75b59cb4ce74aa10a3b240cf19b3092646b2f1b1 Mon Sep 17 00:00:00 2001 From: vs Date: Thu, 17 Jul 2025 08:39:07 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=2012.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- img/schema-database.png | Bin 51146 -> 85857 bytes pom.xml | 9 +- .../filmorate/controller/FilmController.java | 5 + .../filmorate/controller/GenreController.java | 28 +++ .../controller/RatingController.java | 28 +++ .../filmorate/controller/UserController.java | 2 +- .../filmorate/exception/ErrorResponse.java | 1 - .../practicum/filmorate/model/Film.java | 9 +- .../practicum/filmorate/model/Genre.java | 17 ++ .../practicum/filmorate/model/Rating.java | 19 ++ .../practicum/filmorate/model/User.java | 3 +- .../filmorate/service/FilmService.java | 50 +++++- .../filmorate/service/GenreService.java | 24 +++ .../filmorate/service/RatingService.java | 24 +++ .../filmorate/service/UserService.java | 1 - .../storage/dal/dao/FilmDbStorage.java | 143 +++++++++++++++ .../storage/dal/dao/FilmGenreDbStorage.java | 33 ++++ .../storage/dal/dao/GenreDbStorage.java | 40 +++++ .../storage/dal/dao/RatingDbStorage.java | 40 +++++ .../storage/dal/dao/UserDbStorage.java | 127 ++++++++++++++ .../storage/dal/extractors/FilmExtractor.java | 31 ++++ .../storage/dal/extractors/FilmMapsUtil.java | 39 +++++ .../dal/extractors/FilmsExtractor.java | 34 ++++ .../storage/dal/mappers/FilmRowMapper.java | 31 ++++ .../storage/dal/mappers/GenreRowMapper.java | 20 +++ .../storage/dal/mappers/RatingRowMapper.java | 20 +++ .../storage/dal/mappers/UserRowMapper.java | 26 +++ src/main/resources/application.properties | 7 +- src/main/resources/data.sql | 11 ++ src/main/resources/schema.sql | 42 +++++ .../filmorate/dao/FilmDbStorageTest.java | 163 ++++++++++++++++++ .../filmorate/dao/GenreDbStorageTest.java | 41 +++++ .../filmorate/dao/RatingDbStorageTest.java | 42 +++++ .../filmorate/dao/UserDbStorageTest.java | 123 +++++++++++++ 34 files changed, 1223 insertions(+), 10 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/RatingController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/Genre.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/Rating.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/RatingService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmGenreDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/GenreDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/RatingDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/UserDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmExtractor.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmMapsUtil.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmsExtractor.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/FilmRowMapper.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/GenreRowMapper.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/RatingRowMapper.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/UserRowMapper.java create mode 100644 src/main/resources/data.sql create mode 100644 src/main/resources/schema.sql create mode 100644 src/test/java/ru/yandex/practicum/filmorate/dao/FilmDbStorageTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/dao/GenreDbStorageTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/dao/RatingDbStorageTest.java create mode 100644 src/test/java/ru/yandex/practicum/filmorate/dao/UserDbStorageTest.java diff --git a/img/schema-database.png b/img/schema-database.png index 473408b89f9f5580069363b92fd4b01ec7c1cfa4..5854b0d258ebe4ef06385909561390d8f956378f 100644 GIT binary patch literal 85857 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

re%RH)@gSoL|^gRas+K6t?G_ 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%0Dxhzc0p|pnz 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 NOiWrdU*wJVe*rl!m5~4d diff --git a/pom.xml b/pom.xml index 6ad9433..065620c 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,6 @@ org.springframework.boot spring-boot-starter-web - org.projectlombok lombok @@ -41,6 +40,14 @@ logbook-spring-boot-starter 3.7.2 + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-data-jdbc + 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 ed7be62..6c7700c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -49,4 +49,9 @@ public List getPopularFilms(@Positive @RequestParam(defaultValue = "10") i return filmService.getPopularFilms(count); } + @GetMapping("/{id}") + public Film getFilm(@PathVariable Long id) { + return filmService.getFilmById(id); + } + } diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java new file mode 100644 index 0000000..7dbd3f2 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java @@ -0,0 +1,28 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.service.GenreService; + +import java.util.Collection; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/genres") +public class GenreController { + private final GenreService genreService; + + @GetMapping("{id}") + public Genre getGenre(@PathVariable Long id) { + return genreService.getGenreById(id); + } + + @GetMapping + public Collection getGenres() { + return genreService.getGenres(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/RatingController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/RatingController.java new file mode 100644 index 0000000..86449c6 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/RatingController.java @@ -0,0 +1,28 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import ru.yandex.practicum.filmorate.model.Rating; +import ru.yandex.practicum.filmorate.service.RatingService; + +import java.util.Collection; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/mpa") +public class RatingController { + private final RatingService ratingService; + + @GetMapping("{id}") + public Rating getRating(@PathVariable Long id) { + return ratingService.getRatingById(id); + } + + @GetMapping + public Collection getRating() { + return ratingService.getRatings(); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index 189c38e..4e7e84f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -22,7 +22,7 @@ public Collection getUsers() { } @PostMapping - public User createFilm(@Valid @RequestBody User user) { + public User createUser(@Valid @RequestBody User user) { return userService.createUser(user); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/ErrorResponse.java b/src/main/java/ru/yandex/practicum/filmorate/exception/ErrorResponse.java index e04a4ac..c5fcbfd 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/ErrorResponse.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ErrorResponse.java @@ -11,5 +11,4 @@ public ErrorResponse(String error, String description) { this.error = error; this.description = description; } - } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index f5cf2c0..88f5669 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,7 +1,9 @@ package ru.yandex.practicum.filmorate.model; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; import ru.yandex.practicum.filmorate.json.DeserializerDuration; @@ -13,6 +15,7 @@ import java.time.Duration; import java.time.LocalDate; import java.util.HashSet; +import java.util.List; import java.util.Set; @Data @@ -30,5 +33,9 @@ public class Film { @JsonDeserialize(using = DeserializerDuration.class) private Duration duration; private final Set likes = new HashSet<>(); - + @JsonProperty("mpa") + @Valid + private Rating rating; + @Valid + private List genres; } diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Genre.java b/src/main/java/ru/yandex/practicum/filmorate/model/Genre.java new file mode 100644 index 0000000..bab0def --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Genre.java @@ -0,0 +1,17 @@ +package ru.yandex.practicum.filmorate.model; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class Genre { + @NotNull + private Long id; + private String name; +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Rating.java b/src/main/java/ru/yandex/practicum/filmorate/model/Rating.java new file mode 100644 index 0000000..2ce9d76 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Rating.java @@ -0,0 +1,19 @@ +package ru.yandex.practicum.filmorate.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@Getter +@JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor +@AllArgsConstructor +public class Rating { + @NotNull + private Long id; + private String name; +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java index 4e90863..716ae6c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -24,5 +24,4 @@ public class User { @PastOrPresent private LocalDate birthday; private final Set friends = new HashSet<>(); - -} +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java index 8d54f38..f698d25 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -2,12 +2,18 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import ru.yandex.practicum.filmorate.exception.ExceptionNotFound; import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.model.Rating; +import ru.yandex.practicum.filmorate.storage.dal.dao.FilmGenreDbStorage; import ru.yandex.practicum.filmorate.storage.film.FilmStorage; import java.util.Collection; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; @RequiredArgsConstructor @Service @@ -15,18 +21,34 @@ public class FilmService { private final FilmStorage filmStorage; private final UserService userService; + private final GenreService genreService; + private final RatingService ratingService; + private final FilmGenreDbStorage filmGenreDbStorage; public Collection getFilms() { return filmStorage.getFilms(); } + @Transactional public Film createFilm(Film film) { - return filmStorage.createFilm(film); + validateFilm(film); + Film createdFilm = filmStorage.createFilm(film); + if (film.getGenres() != null && !film.getGenres().isEmpty()) { + filmGenreDbStorage.saveFilmGenres(createdFilm.getId(), film.getGenres()); + } + return createdFilm; } + @Transactional public Film updateFilm(Film film) { - return filmStorage.updateFilm(film) + validateFilm(film); + Film updatedFilm = filmStorage.updateFilm(film) .orElseThrow(() -> new ExceptionNotFound("Фильм с идентификатором '%d' не найден".formatted(film.getId()))); + filmGenreDbStorage.deleteFilmGenresForFilmId(updatedFilm.getId()); + if (film.getGenres() != null && !film.getGenres().isEmpty()) { + filmGenreDbStorage.saveFilmGenres(updatedFilm.getId(), film.getGenres()); + } + return updatedFilm; } public void addLike(Long filmId, Long userId) { @@ -50,4 +72,28 @@ public Film getFilmById(Long id) { .orElseThrow(() -> new ExceptionNotFound("Фильм с идентификатором '%d' не найден".formatted(id))); } + private void validateFilm(Film film) { + if (film.getGenres() != null) { + Set allGenreId = genreService.getGenres() + .stream() + .map(Genre::getId) + .collect(Collectors.toSet()); + Set allGenreIdFilm = film.getGenres() + .stream() + .map(Genre::getId) + .collect(Collectors.toSet()); + if (!allGenreId.containsAll(allGenreIdFilm)) { + throw new ExceptionNotFound("Один или несколько жанров не существует."); + } + } + if (film.getRating() != null && film.getRating().getId() != null) { + Set ratingId = ratingService.getRatings() + .stream() + .map(Rating::getId) + .collect(Collectors.toSet()); + if (!ratingId.contains(film.getRating().getId())) { + throw new ExceptionNotFound("Рейтинг с идентификатором %d не найден".formatted(film.getRating().getId())); + } + } + } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java b/src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java new file mode 100644 index 0000000..a088cd1 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java @@ -0,0 +1,24 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.ExceptionNotFound; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.storage.dal.dao.GenreDbStorage; + +import java.util.Collection; + +@RequiredArgsConstructor +@Service +public class GenreService { + private final GenreDbStorage genreDbStorage; + + public Genre getGenreById(Long id) { + return genreDbStorage.getGenreById(id) + .orElseThrow(() -> new ExceptionNotFound("Жанр с идентификатором '%d' не найден".formatted(id))); + } + + public Collection getGenres() { + return genreDbStorage.getGenres(); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/RatingService.java b/src/main/java/ru/yandex/practicum/filmorate/service/RatingService.java new file mode 100644 index 0000000..6ac4ef5 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/RatingService.java @@ -0,0 +1,24 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.ExceptionNotFound; +import ru.yandex.practicum.filmorate.model.Rating; +import ru.yandex.practicum.filmorate.storage.dal.dao.RatingDbStorage; + +import java.util.Collection; + +@RequiredArgsConstructor +@Service +public class RatingService { + private final RatingDbStorage ratingDbStorage; + + public Rating getRatingById(Long id) { + return ratingDbStorage.getRatingById(id) + .orElseThrow(() -> new ExceptionNotFound("Рейтинг с идентификатором '%d' не найден".formatted(id))); + } + + public Collection getRatings() { + return ratingDbStorage.getRatings(); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java index 3107cda..3eb57aa 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -13,7 +13,6 @@ @RequiredArgsConstructor @Service public class UserService { - private final UserStorage userStorage; public Collection getUsers() { diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmDbStorage.java new file mode 100644 index 0000000..f6f20bf --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmDbStorage.java @@ -0,0 +1,143 @@ +package ru.yandex.practicum.filmorate.storage.dal.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.film.FilmStorage; + +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +@Primary +@Repository +@RequiredArgsConstructor +public class FilmDbStorage implements FilmStorage { + private final JdbcTemplate jdbcTemplate; + private final RowMapper filmRowMapper; + private final ResultSetExtractor filmExtractor; + private final ResultSetExtractor> filmsExtractor; + + @Override + public Collection getFilms() { + String query = """ + SELECT + f.film_id AS film_id, + f.name AS film_name, + f.description AS description, + f.release_date AS release_date, + f.duration AS duration, + f.rating_id AS rating_id, + r.name AS rating_name, + g.genre_id AS genre_id, + g.name AS genre_name + FROM films f + JOIN ratings r ON f.rating_id = r.rating_id + LEFT JOIN film_genres fg ON f.film_id = fg.film_id + LEFT JOIN genres g ON fg.genre_id = g.genre_id + ORDER BY f.film_id + """; + return jdbcTemplate.query(query, filmsExtractor); + } + + @Override + public Film createFilm(Film film) { + KeyHolder keyHolder = new GeneratedKeyHolder(); + String query = "INSERT INTO films (name, description, release_date, duration, rating_id) VALUES (?, ?, ?, ?, ?)"; + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); + ps.setString(1, film.getName()); + ps.setString(2, film.getDescription()); + ps.setDate(3, java.sql.Date.valueOf(film.getReleaseDate())); + ps.setLong(4, film.getDuration().toMinutes()); + ps.setLong(5, film.getRating().getId()); + return ps; + }, keyHolder); + Long id = keyHolder.getKeyAs(Long.class); + if (id == null) { + throw new IllegalStateException("Не удалось сгенерировать идентификатор фильма"); + } + film.setId(id); + return film; + } + + @Override + public Optional updateFilm(Film film) { + String query = """ + UPDATE films + SET name = ?, description = ?, release_date = ?, duration = ?, rating_id = ? + WHERE film_id = ?; + """; + int countRows = jdbcTemplate.update(query, + film.getName(), + film.getDescription(), + film.getReleaseDate(), + film.getDuration(), + film.getRating().getId(), + film.getId() + ); + if (countRows > 0) { + return Optional.of(film); + } + return Optional.empty(); + } + + @Override + public Optional getFilmById(Long id) { + String query = """ + SELECT + f.film_id AS film_id, + f.name AS film_name, + f.description AS description, + f.release_date AS release_date, + f.duration AS duration, + f.rating_id AS rating_id, + r.name AS rating_name, + g.genre_id AS genre_id, + g.name AS genre_name + FROM films f + JOIN ratings r ON f.rating_id = r.rating_id + LEFT JOIN film_genres fg ON f.film_id = fg.film_id + LEFT JOIN genres g ON fg.genre_id = g.genre_id + WHERE f.film_id = ? + """; + return Optional.ofNullable(jdbcTemplate.query(query, filmExtractor, id)); + } + + @Override + public void addLike(Long filmId, Long userId) { + String query = "INSERT INTO film_likes(user_id, film_id) VALUES (?, ?)"; + jdbcTemplate.update(query, userId, filmId); + } + + @Override + public void removeLike(Long filmId, Long userId) { + String query = "DELETE FROM film_likes WHERE user_id = ? AND film_id = ?"; + jdbcTemplate.update(query, userId, filmId); + } + + @Override + public List getPopularFilms(int count) { + String query = """ + SELECT f.film_id, f.name, f.description, f.release_date, f.duration, f.rating_id + FROM films f + LEFT JOIN ( + SELECT film_id, COUNT(user_id) AS count_like + FROM film_likes + GROUP BY film_id + ) fl ON f.film_id = fl.film_id + ORDER BY fl.count_like DESC + LIMIT ? + """; + return jdbcTemplate.query(query, filmRowMapper, count); + } + +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmGenreDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmGenreDbStorage.java new file mode 100644 index 0000000..127d349 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/FilmGenreDbStorage.java @@ -0,0 +1,33 @@ +package ru.yandex.practicum.filmorate.storage.dal.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.Genre; + +import java.util.List; + +@Repository +@RequiredArgsConstructor +public class FilmGenreDbStorage { + private final JdbcTemplate jdbcTemplate; + + public void saveFilmGenres(Long filmId, List genres) { + String query = """ + INSERT INTO film_genres(film_id, genre_id) + VALUES (?, ?) + """; + List params = genres + .stream() + .map(Genre::getId) + .distinct() + .map(genreId -> new Object[]{filmId, genreId}) + .toList(); + jdbcTemplate.batchUpdate(query, params); + } + + public void deleteFilmGenresForFilmId(Long filmId) { + String query = "DELETE FROM film_genres WHERE film_id = ?"; + jdbcTemplate.update(query, filmId); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/GenreDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/GenreDbStorage.java new file mode 100644 index 0000000..29c6728 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/GenreDbStorage.java @@ -0,0 +1,40 @@ +package ru.yandex.practicum.filmorate.storage.dal.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.yandex.practicum.filmorate.model.Genre; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +@Repository +@RequiredArgsConstructor +public class GenreDbStorage { + private final JdbcTemplate jdbcTemplate; + private final RowMapper genreRowMapper; + + public Optional getGenreById(Long id) { + String query = """ + SELECT genre_id, name + FROM genres + WHERE genre_id = ? + """; + List genres = jdbcTemplate.query(query, genreRowMapper, id); + if (genres.isEmpty()) { + return Optional.empty(); + } + return Optional.of(genres.getFirst()); + } + + public Collection getGenres() { + String query = """ + SELECT genre_id, name + FROM genres + ORDER BY genre_id + """; + return jdbcTemplate.query(query, genreRowMapper); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/RatingDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/RatingDbStorage.java new file mode 100644 index 0000000..d5a8507 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/RatingDbStorage.java @@ -0,0 +1,40 @@ +package ru.yandex.practicum.filmorate.storage.dal.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.Rating; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +@Repository +@RequiredArgsConstructor +public class RatingDbStorage { + private final JdbcTemplate jdbcTemplate; + private final RowMapper ratingRowMapper; + + public Optional getRatingById(Long id) { + String query = """ + SELECT rating_id, name + FROM ratings + WHERE rating_id = ? + """; + List ratings = jdbcTemplate.query(query, ratingRowMapper, id); + if (ratings.isEmpty()) { + return Optional.empty(); + } + return Optional.of(ratings.getFirst()); + } + + public Collection getRatings() { + String query = """ + SELECT rating_id, name + FROM ratings + ORDER BY rating_id + """; + return jdbcTemplate.query(query, ratingRowMapper); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/UserDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/UserDbStorage.java new file mode 100644 index 0000000..2dad8bf --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/dao/UserDbStorage.java @@ -0,0 +1,127 @@ +package ru.yandex.practicum.filmorate.storage.dal.dao; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.user.UserStorage; + +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.util.*; +import java.util.stream.Collectors; + +@Primary +@Repository +@RequiredArgsConstructor +public class UserDbStorage implements UserStorage { + private final JdbcTemplate jdbcTemplate; + private final RowMapper userRowMapper; + + @Override + public Collection getUsers() { + String query = """ + SELECT user_id, email, login, name, birthday + FROM users + """; + return jdbcTemplate.query(query, userRowMapper); + } + + @Override + public User createUser(User user) { + KeyHolder keyHolder = new GeneratedKeyHolder(); + String query = "INSERT INTO users (email, login, name, birthday) VALUES (?, ?, ?, ?)"; + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); + ps.setString(1, user.getEmail()); + ps.setString(2, user.getLogin()); + ps.setString(3, user.getName()); + ps.setObject(4, user.getBirthday()); + return ps; + }, keyHolder); + //log.trace("keyHolder - "+keyHolder.getKeyAs(Long.class)); + Long id = keyHolder.getKeyAs(Long.class); + if (id == null) { + throw new IllegalStateException("Не удалось сгенерировать идентификатор пользователя"); + } + user.setId(id); + return user; + } + + @Override + public Optional updateUser(User user) { + String query = """ + UPDATE users + SET email = ?, login = ?, name = ?, birthday = ? + WHERE user_id = ? + """; + int countRows = jdbcTemplate.update(query, + user.getEmail(), + user.getLogin(), + user.getName(), + user.getBirthday(), + user.getId() + ); + if (countRows > 0) { + return Optional.of(user); + } + return Optional.empty(); + } + + @Override + public Optional getUserById(Long id) { + String query = """ + SELECT user_id, email, login, name, birthday + FROM users + WHERE user_id = ? + """; + List users = jdbcTemplate.query(query, userRowMapper, id); + if (users.isEmpty()) { + return Optional.empty(); + } + return Optional.of(users.getFirst()); + } + + @Override + public void addFriend(Long userId, Long friendId) { + String query = "INSERT INTO friendships(user_id, user_id_friend) VALUES (?, ?)"; + jdbcTemplate.update(query, userId, friendId); + } + + @Override + public void removeFriend(Long userId, Long friendId) { + String query = "DELETE FROM friendships WHERE user_id = ? AND user_id_friend = ?"; + jdbcTemplate.update(query, userId, friendId); + } + + @Override + public Set> getCommonFriends(Long userIdOne, Long userIdTwo) { + String query = """ + SELECT u.user_id, u.email, u.login, u.name, u.birthday + FROM friendships f1 + JOIN friendships f2 ON f1.user_id_friend = f2.user_id_friend + JOIN users u ON u.user_id = f1.user_id_friend + WHERE f1.user_id = ? AND f2.user_id = ? + """; + return jdbcTemplate.query(query, userRowMapper, userIdOne, userIdTwo) + .stream() + .map(Optional::ofNullable) + .collect(Collectors.toSet()); + } + + @Override + public Set getFriends(Long userId) { + String query = """ + SELECT u.user_id, u.email, u.login, u.name, u.birthday + FROM friendships f + JOIN users u ON u.user_id = f.user_id_friend + WHERE f.user_id = ? + """; + return new HashSet<>(jdbcTemplate.query(query, userRowMapper, userId)); + } + +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmExtractor.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmExtractor.java new file mode 100644 index 0000000..209a962 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmExtractor.java @@ -0,0 +1,31 @@ +package ru.yandex.practicum.filmorate.storage.dal.extractors; + +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genre; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; + +@Component +public class FilmExtractor implements ResultSetExtractor { + + @Override + public Film extractData(ResultSet resultSet) throws SQLException { + Film film = null; + while (resultSet.next()) { + if (film == null) { + film = FilmMapsUtil.mapFilm(resultSet); + film.setRating(FilmMapsUtil.mapRating(resultSet)); + film.setGenres(new ArrayList<>()); + } + Genre genre = FilmMapsUtil.mapGenre(resultSet); + if (genre != null) { + film.getGenres().add(genre); + } + } + return film; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmMapsUtil.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmMapsUtil.java new file mode 100644 index 0000000..2fca1c4 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmMapsUtil.java @@ -0,0 +1,39 @@ +package ru.yandex.practicum.filmorate.storage.dal.extractors; + +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.model.Rating; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.Duration; + +public class FilmMapsUtil { + public static Film mapFilm(ResultSet resultSet) throws SQLException { + Film film = new Film(); + film.setId(resultSet.getLong("film_id")); + film.setName(resultSet.getString("film_name")); + film.setDescription(resultSet.getString("description")); + film.setReleaseDate(resultSet.getDate("release_date").toLocalDate()); + film.setDuration(Duration.ofMinutes(resultSet.getInt("duration"))); + return film; + } + + public static Rating mapRating(ResultSet resultSet) throws SQLException { + Rating rating = new Rating(); + rating.setId(resultSet.getLong("rating_id")); + rating.setName(resultSet.getString("rating_name")); + return rating; + } + + public static Genre mapGenre(ResultSet resultSet) throws SQLException { + long genreId = resultSet.getLong("genre_id"); + if (genreId <= 0) { + return null; + } + Genre genre = new Genre(); + genre.setId(genreId); + genre.setName(resultSet.getString("genre_name")); + return genre; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmsExtractor.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmsExtractor.java new file mode 100644 index 0000000..d11c8c9 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/extractors/FilmsExtractor.java @@ -0,0 +1,34 @@ +package ru.yandex.practicum.filmorate.storage.dal.extractors; + +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genre; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +@Component +public class FilmsExtractor implements ResultSetExtractor> { + + @Override + public List extractData(ResultSet resultSet) throws SQLException { + Map films = new HashMap<>(); + while (resultSet.next()) { + long filmId = resultSet.getLong("film_id"); + Film film = films.get(filmId); + if (film == null) { + film = FilmMapsUtil.mapFilm(resultSet); + film.setRating(FilmMapsUtil.mapRating(resultSet)); + film.setGenres(new ArrayList<>()); + films.put(filmId, film); + } + Genre genre = FilmMapsUtil.mapGenre(resultSet); + if (genre != null) { + film.getGenres().add(genre); + } + } + return new ArrayList<>(films.values()); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/FilmRowMapper.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/FilmRowMapper.java new file mode 100644 index 0000000..26d270c --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/FilmRowMapper.java @@ -0,0 +1,31 @@ +package ru.yandex.practicum.filmorate.storage.dal.mappers; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Rating; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.Duration; + +@Component +public class FilmRowMapper implements RowMapper { + + @Override + public Film mapRow(ResultSet resultSet, int rowNum) throws SQLException { + Film film = new Film(); + film.setId(resultSet.getLong("film_id")); + film.setName(resultSet.getString("name")); + film.setDescription(resultSet.getString("description")); + film.setReleaseDate(resultSet.getDate("release_date").toLocalDate()); + film.setDuration(Duration.ofMinutes(resultSet.getInt("duration"))); + long ratingId = resultSet.getLong("rating_id"); + if (!resultSet.wasNull()) { + Rating rating = new Rating(); + rating.setId(ratingId); + film.setRating(rating); + } + return film; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/GenreRowMapper.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/GenreRowMapper.java new file mode 100644 index 0000000..36ff83e --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/GenreRowMapper.java @@ -0,0 +1,20 @@ +package ru.yandex.practicum.filmorate.storage.dal.mappers; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.Genre; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@Component +public class GenreRowMapper implements RowMapper { + + @Override + public Genre mapRow(ResultSet resultSet, int rowNum) throws SQLException { + Genre genre = new Genre(); + genre.setId(resultSet.getLong("genre_id")); + genre.setName(resultSet.getString("name")); + return genre; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/RatingRowMapper.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/RatingRowMapper.java new file mode 100644 index 0000000..16b7b19 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/RatingRowMapper.java @@ -0,0 +1,20 @@ +package ru.yandex.practicum.filmorate.storage.dal.mappers; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.Rating; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@Component +public class RatingRowMapper implements RowMapper { + + @Override + public Rating mapRow(ResultSet resultSet, int rowNum) throws SQLException { + Rating rating = new Rating(); + rating.setId(resultSet.getLong("rating_id")); + rating.setName(resultSet.getString("name")); + return rating; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/UserRowMapper.java b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/UserRowMapper.java new file mode 100644 index 0000000..6a24fed --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/dal/mappers/UserRowMapper.java @@ -0,0 +1,26 @@ +package ru.yandex.practicum.filmorate.storage.dal.mappers; + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.User; + +import java.sql.Date; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Component +public class UserRowMapper implements RowMapper { + @Override + public User mapRow(ResultSet resultSet, int rowNum) throws SQLException { + User user = new User(); + user.setId(resultSet.getLong("user_id")); + user.setEmail(resultSet.getString("email")); + user.setLogin(resultSet.getString("login")); + user.setName(resultSet.getString("name")); + Date birthday = resultSet.getDate("birthday"); + if (birthday != null) { + user.setBirthday(birthday.toLocalDate()); + } + return user; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cc392b5..d365592 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,6 @@ -logging.level.org.zalando.logbook=TRACE \ No newline at end of file +logging.level.org.zalando.logbook=TRACE +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 diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..6772c1e --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,11 @@ +MERGE INTO ratings (name) KEY (name) VALUES ('G'); +MERGE INTO ratings (name) KEY (name) VALUES ('PG'); +MERGE INTO ratings (name) KEY (name) VALUES ('PG-13'); +MERGE INTO ratings (name) KEY (name) VALUES ('R'); +MERGE INTO ratings (name) KEY (name) VALUES ('NC-17'); +MERGE INTO genres (genre_id, name) KEY (genre_id) VALUES (1, 'Комедия'); +MERGE INTO genres (genre_id, name) KEY (genre_id) VALUES (2, 'Драма'); +MERGE INTO genres (genre_id, name) KEY (genre_id) VALUES (3, 'Мультфильм'); +MERGE INTO genres (genre_id, name) KEY (genre_id) VALUES (4, 'Триллер'); +MERGE INTO genres (genre_id, name) KEY (genre_id) VALUES (5, 'Документальный'); +MERGE INTO genres (genre_id, name) KEY (genre_id) VALUES (6, 'Боевик') \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000..b24e000 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,42 @@ +CREATE TABLE IF NOT EXISTS users( +user_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, +email varchar NOT NULL, +login varchar NOT NULL, +name varchar, +birthday date); + +CREATE TABLE IF NOT EXISTS ratings( +rating_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, +name varchar UNIQUE NOT NULL); + +CREATE TABLE IF NOT EXISTS films( +film_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, +name varchar NOT NULL, +description varchar(200), +release_date date, +duration bigint, +rating_id bigint, +FOREIGN KEY (rating_id) REFERENCES ratings (rating_id)); + +CREATE TABLE IF NOT EXISTS friendships( +user_id bigint NOT NULL, +user_id_friend bigint NOT NULL, +FOREIGN KEY (user_id) REFERENCES users (user_id), +FOREIGN KEY (user_id_friend) REFERENCES users (user_id), +CONSTRAINT not_equal_to_himself CHECK (user_id <> user_id_friend)); + +CREATE TABLE IF NOT EXISTS film_likes( +user_id bigint NOT NULL, +film_id bigint NOT NULL, +FOREIGN KEY (user_id) REFERENCES users (user_id), +FOREIGN KEY (film_id) REFERENCES films (film_id)); + +CREATE TABLE IF NOT EXISTS genres( +genre_id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, +name varchar UNIQUE NOT NULL); + +CREATE TABLE IF NOT EXISTS film_genres( +film_id bigint NOT NULL, +genre_id bigint NOT NULL, +FOREIGN KEY (genre_id) REFERENCES genres (genre_id), +FOREIGN KEY (film_id) REFERENCES films (film_id)); \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/dao/FilmDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/dao/FilmDbStorageTest.java new file mode 100644 index 0000000..a1c6cea --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/dao/FilmDbStorageTest.java @@ -0,0 +1,163 @@ +package ru.yandex.practicum.filmorate.dao; + +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.jdbc.core.JdbcTemplate; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Rating; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.dal.dao.FilmDbStorage; +import ru.yandex.practicum.filmorate.storage.dal.dao.UserDbStorage; + +import java.time.Duration; +import java.time.LocalDate; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@JdbcTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@ComponentScan(basePackages = {"ru.yandex.practicum.filmorate.storage"}) +class FilmDbStorageTest { + private final FilmDbStorage filmDbStorage; + private final UserDbStorage userDbStorage; + private final JdbcTemplate jdbcTemplate; + + private Film createFilm(String name, String description) { + Film film = new Film(); + film.setName(name); + film.setDescription(description); + film.setReleaseDate(LocalDate.of(1990, 2, 5)); + film.setDuration(Duration.ofMinutes(120)); + film.setRating(new Rating(5L, "NC-17")); + film.setGenres(List.of()); + return film; + } + + private User createUser(String login, String name) { + User user = new User(); + user.setEmail("email@mail.ru"); + user.setLogin(login); + user.setName(name); + user.setBirthday(LocalDate.of(1990, 2, 5)); + return user; + } + + @Test + void createFilm() { + Film film = createFilm("Название фильма №1", "Описание фильма №1"); + Film savedFilm = filmDbStorage.createFilm(film); + Optional loadedFilm = filmDbStorage.getFilmById(savedFilm.getId()); + + assertThat(savedFilm.getId()).isNotNull(); + assertThat(loadedFilm).isPresent(); + assertThat(loadedFilm.get().getName()).isEqualTo("Название фильма №1"); + assertThat(loadedFilm.get().getDescription()).isEqualTo("Описание фильма №1"); + } + + @Test + void findFilm() { + Film film2 = createFilm("Название фильма №2", "Описание фильма №2"); + filmDbStorage.createFilm(film2); + Optional findFilmYes = filmDbStorage.getFilmById(film2.getId()); + assertThat(findFilmYes).isPresent(); + Optional findFilmNot = filmDbStorage.getFilmById(999L); + assertThat(findFilmNot).isEmpty(); + + Film film3 = createFilm("Название фильма №3", "Описание фильма №3"); + Film film4 = createFilm("Название фильма №4", "Описание фильма №4"); + filmDbStorage.createFilm(film3); + filmDbStorage.createFilm(film4); + + Collection films = filmDbStorage.getFilms(); + assertThat(films).hasSize(3); + } + + @Test + void updateFilm() { + Film film5 = createFilm("Название фильма №5", "Описание фильма №5"); + filmDbStorage.createFilm(film5); + film5.setName("Название фильма №5 новое"); + film5.setDescription("Описание фильма №5 новое"); + Optional updatedFilm = filmDbStorage.updateFilm(film5); + + assertThat(updatedFilm).isPresent(); + assertThat(updatedFilm.get().getName()).isEqualTo("Название фильма №5 новое"); + assertThat(updatedFilm.get().getDescription()).isEqualTo("Описание фильма №5 новое"); + + Optional loadedFilm = filmDbStorage.getFilmById(film5.getId()); + assertThat(loadedFilm).isPresent(); + assertThat(loadedFilm.get().getName()).isEqualTo(updatedFilm.get().getName()); + assertThat(loadedFilm.get().getDescription()).isEqualTo(updatedFilm.get().getDescription()); + + Film film6 = createFilm("Название фильма №6", "Описание фильма №6"); + film6.setId(7L); + + Optional updateFilm = filmDbStorage.updateFilm(film6); + assertThat(updateFilm).isEmpty(); + } + + @Test + void addAndDeleteLike() { + Film film7 = createFilm("Название фильма №7", "Описание фильма №7"); + filmDbStorage.createFilm(film7); + Film film8 = createFilm("Название фильма №8", "Описание фильма №8"); + filmDbStorage.createFilm(film8); + User user1 = createUser("Логин №1", "Имя №1"); + userDbStorage.createUser(user1); + User user2 = createUser("Логин №2", "Имя №2"); + userDbStorage.createUser(user2); + filmDbStorage.addLike(film7.getId(), user1.getId()); + filmDbStorage.addLike(film8.getId(), user1.getId()); + filmDbStorage.addLike(film8.getId(), user2.getId()); + + int countOneLike = jdbcTemplate.queryForObject( + "SELECT COUNT(*) FROM film_likes WHERE user_id = ? AND film_id = ?", + Integer.class, user1.getId(), film7.getId() + ); + assertThat(countOneLike).isEqualTo(1); + int countAllLikeOneUser = jdbcTemplate.queryForObject( + "SELECT COUNT(*) FROM film_likes WHERE user_id = ?", + Integer.class, user1.getId() + ); + assertThat(countAllLikeOneUser).isEqualTo(2); + int countAllLikeAllUser = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM film_likes", Integer.class); + assertThat(countAllLikeAllUser).isEqualTo(3); + + filmDbStorage.removeLike(film7.getId(), user1.getId()); + + Integer countDeleteLike = jdbcTemplate.queryForObject( + "SELECT COUNT(*) FROM film_likes WHERE user_id = ? AND film_id = ?", + Integer.class, film7.getId(), user1.getId() + ); + assertThat(countDeleteLike).isZero(); + } + + @Test + void findTopFilmsByLikes() { + User user3 = createUser("Логин №3", "Имя №3"); + userDbStorage.createUser(user3); + User user4 = createUser("Логин №4", "Имя №4"); + userDbStorage.createUser(user4); + Film film9 = createFilm("Название фильма №9", "Описание фильма №9"); + filmDbStorage.createFilm(film9); + Film film10 = createFilm("Название фильма №10", "Описание фильма №10"); + filmDbStorage.createFilm(film10); + jdbcTemplate.update("INSERT INTO film_likes (user_id, film_id) VALUES (?, ?)", user3.getId(), film9.getId()); + jdbcTemplate.update("INSERT INTO film_likes (user_id, film_id) VALUES (?, ?)", user4.getId(), film9.getId()); + jdbcTemplate.update("INSERT INTO film_likes (user_id, film_id) VALUES (?, ?)", user3.getId(), film10.getId()); + + List resultListPopularFilms = filmDbStorage.getPopularFilms(10); + + assertThat(resultListPopularFilms).hasSize(2); + assertThat(resultListPopularFilms.get(0).getId()).isEqualTo(1L); + assertThat(resultListPopularFilms.get(1).getId()).isEqualTo(2L); + } +} \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/dao/GenreDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/dao/GenreDbStorageTest.java new file mode 100644 index 0000000..d2e7447 --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/dao/GenreDbStorageTest.java @@ -0,0 +1,41 @@ +package ru.yandex.practicum.filmorate.dao; + +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.ComponentScan; +import ru.yandex.practicum.filmorate.model.Genre; +import ru.yandex.practicum.filmorate.storage.dal.dao.GenreDbStorage; + +import java.util.Collection; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@JdbcTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@ComponentScan(basePackages = {"ru.yandex.practicum.filmorate.storage"}) +public class GenreDbStorageTest { + private final GenreDbStorage genreDbStorage; + + @Test + void getGenreById() { + Optional genre = genreDbStorage.getGenreById(1L); + assertThat(genre).isPresent(); + assertThat(genre.get().getName()).isEqualTo("Комедия"); + + Optional genreNot = genreDbStorage.getGenreById(100L); + assertThat(genreNot).isEmpty(); + } + + @Test + void getGenres() { + Collection genres = genreDbStorage.getGenres(); + assertThat(genres).hasSize(6); + assertThat(genres).extracting(Genre::getName) + .containsExactlyInAnyOrder("Комедия", "Драма", "Мультфильм", "Триллер", "Документальный", "Боевик"); + } +} diff --git a/src/test/java/ru/yandex/practicum/filmorate/dao/RatingDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/dao/RatingDbStorageTest.java new file mode 100644 index 0000000..37046b9 --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/dao/RatingDbStorageTest.java @@ -0,0 +1,42 @@ +package ru.yandex.practicum.filmorate.dao; + +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.ComponentScan; +import ru.yandex.practicum.filmorate.model.Rating; +import ru.yandex.practicum.filmorate.storage.dal.dao.RatingDbStorage; + +import java.util.Collection; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@JdbcTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@ComponentScan(basePackages = {"ru.yandex.practicum.filmorate.storage"}) +public class RatingDbStorageTest { + private final RatingDbStorage ratingDbStorage; + + @Test + void getRatingById() { + Optional rating = ratingDbStorage.getRatingById(1L); + assertThat(rating).isPresent(); + assertThat(rating.get().getName()).isEqualTo("G"); + + Optional ratingNot = ratingDbStorage.getRatingById(100L); + assertThat(ratingNot).isEmpty(); + } + + @Test + void getRatings() { + Collection ratings = ratingDbStorage.getRatings(); + assertThat(ratings).hasSize(5); + assertThat(ratings).extracting(Rating::getName) + .containsExactlyInAnyOrder("G", "PG", "PG-13", "R", "NC-17"); + } + +} diff --git a/src/test/java/ru/yandex/practicum/filmorate/dao/UserDbStorageTest.java b/src/test/java/ru/yandex/practicum/filmorate/dao/UserDbStorageTest.java new file mode 100644 index 0000000..1445ba6 --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/dao/UserDbStorageTest.java @@ -0,0 +1,123 @@ +package ru.yandex.practicum.filmorate.dao; + +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.context.annotation.ComponentScan; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.dal.dao.UserDbStorage; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +@JdbcTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@ComponentScan(basePackages = {"ru.yandex.practicum.filmorate.storage"}) +class UserDbStorageTest { + private final UserDbStorage userDbStorage; + + private User createUser(String login, String name) { + User user = new User(); + user.setEmail("email@mail.ru"); + user.setLogin(login); + user.setName(name); + user.setBirthday(LocalDate.of(1990, 2, 5)); + return user; + } + + @Test + void addAndFindUser() { + User user1 = createUser("Логин №1", "Имя №1"); + User savedUser = userDbStorage.createUser(user1); + Optional getUserfromDb = userDbStorage.getUserById(savedUser.getId()); + + assertThat(savedUser.getId()).isNotNull(); + assertThat(getUserfromDb).isPresent(); + assertThat(getUserfromDb.get().getLogin()).isEqualTo("Логин №1"); + assertThat(getUserfromDb.get().getName()).isEqualTo("Имя №1"); + + Optional user = userDbStorage.getUserById(100L); + assertThat(user).isEmpty(); + } + + @Test + void findAllUsers() { + User user2 = createUser("Логин №2", "Имя №2"); + userDbStorage.createUser(user2); + User user3 = createUser("Логин №3", "Имя №3"); + userDbStorage.createUser(user3); + User user4 = createUser("Логин №4", "Имя №4"); + userDbStorage.createUser(user4); + + Collection users = userDbStorage.getUsers(); + assertThat(users).hasSize(3); + } + + @Test + void updateUser() { + User user5 = createUser("Логин №5", "Имя №5"); + userDbStorage.createUser(user5); + user5.setLogin("Логин №5 новый"); + user5.setName("Имя №5 новое"); + Optional updatedUser = userDbStorage.updateUser(user5); + Optional loadedUser = userDbStorage.getUserById(user5.getId()); + + assertThat(updatedUser).isPresent(); + assertThat(updatedUser.get().getLogin()).isEqualTo("Логин №5 новый"); + assertThat(updatedUser.get().getName()).isEqualTo("Имя №5 новое"); + assertThat(loadedUser).isPresent(); + assertThat(loadedUser.get().getLogin()).isEqualTo("Логин №5 новый"); + assertThat(loadedUser.get().getName()).isEqualTo("Имя №5 новое"); + + User user6 = createUser("Логин №6", "Имя №6"); + userDbStorage.createUser(user6); + user6.setId(200L); + Optional result = userDbStorage.updateUser(user6); + assertThat(result).isEmpty(); + } + + @Test + void addAndDeleteFriendship() { + User user7 = createUser("Логин №7", "Имя №7"); + userDbStorage.createUser(user7); + User user8 = createUser("Логин №8", "Имя №8"); + userDbStorage.createUser(user8); + User user9 = createUser("Логин №9", "Имя №9"); + userDbStorage.createUser(user9); + userDbStorage.addFriend(user7.getId(), user8.getId()); + userDbStorage.addFriend(user9.getId(), user8.getId()); + userDbStorage.addFriend(user7.getId(), user9.getId()); + + Set friendsOfOne = userDbStorage.getFriends(user7.getId()); + assertThat(friendsOfOne.size()).isEqualTo(2L); + + userDbStorage.removeFriend(user7.getId(), user8.getId()); + + Set friendsOfOneNewSet = userDbStorage.getFriends(user7.getId()); + assertThat(friendsOfOneNewSet.size()).isEqualTo(1L); + } + + @Test + void findCommonFriends() { + User user10 = createUser("Логин №10", "Имя №10"); + userDbStorage.createUser(user10); + User user11 = createUser("Логин №11", "Имя №11"); + userDbStorage.createUser(user11); + User user12 = createUser("Логин №12", "Имя №12"); + userDbStorage.createUser(user12); + userDbStorage.addFriend(user10.getId(), user11.getId()); + userDbStorage.addFriend(user12.getId(), user11.getId()); + userDbStorage.addFriend(user10.getId(), user12.getId()); + + Set> commonFriends = userDbStorage.getCommonFriends(user10.getId(), user12.getId()); + assertThat(commonFriends.size()).isEqualTo(1L); + } + +}