From 76e0c36ed889604201a590f840b9838935e94169 Mon Sep 17 00:00:00 2001 From: Marat Date: Wed, 3 May 2023 23:43:41 +0500 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=D1=83=D0=B1=D1=80=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=83?= =?UTF-8?q?=D0=B5=D0=BC=D1=8B=D0=B5=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE?= =?UTF-8?q?=D1=82=D0=B5=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 10 + .../filmorate/controller/FilmController.java | 5 +- .../filmorate/controller/GenreController.java | 29 ++ .../filmorate/controller/MPAController.java | 30 ++ .../filmorate/controller/UserController.java | 5 +- .../practicum/filmorate/dao/FriendsDao.java | 8 + .../practicum/filmorate/dao/GenreDao.java | 10 + .../practicum/filmorate/dao/LikesDao.java | 8 + .../practicum/filmorate/dao/MpaDao.java | 11 + .../filmorate/dao/impl/FriendsDaoImpl.java | 62 ++++ .../filmorate/dao/impl/GenreDaoImpl.java | 44 +++ .../filmorate/dao/impl/LikesDaoImpl.java | 61 ++++ .../filmorate/dao/impl/MpaDaoImpl.java | 49 +++ .../dao/storageimpl/FilmDbStorage.java | 183 ++++++++++ .../dao/storageimpl/UserDbStorage.java | 151 ++++++++ .../exception/EntityNotFoundException.java | 14 + .../FilmAndUserExceptionHandler.java | 16 +- .../exception/FilmNotFoundException.java | 14 - .../IncorrectArgumentsException.java | 8 +- .../exception/UserNotFoundException.java | 14 - .../practicum/filmorate/model/Film.java | 20 +- .../practicum/filmorate/model/Genres.java | 34 ++ .../yandex/practicum/filmorate/model/MPA.java | 14 + .../practicum/filmorate/model/User.java | 16 +- .../filmorate/service/FilmService.java | 67 +--- .../filmorate/service/UserService.java | 46 +-- .../filmorate/storage/FilmStorage.java | 10 +- .../storage/InMemoryFilmStorage.java | 77 ----- .../storage/InMemoryUserStorage.java | 109 ------ .../filmorate/storage/UserStorage.java | 9 +- src/main/resources/application.properties | 7 +- src/main/resources/data.sql | 15 + src/main/resources/schema.sql | 61 ++++ .../filmorate/FilmorateApplicationTests.java | 326 +++++++++++++++++- 34 files changed, 1192 insertions(+), 351 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/MPAController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/FilmNotFoundException.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/UserNotFoundException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/Genres.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/MPA.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java create mode 100644 src/main/resources/data.sql create mode 100644 src/main/resources/schema.sql diff --git a/pom.xml b/pom.xml index 50a2ff5..e3ee927 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,16 @@ commons-lang3 + + org.springframework.boot + spring-boot-starter-data-jdbc + + + com.h2database + h2 + runtime + + org.springframework.boot spring-boot-starter-test 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 4b970a0..74da814 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,6 +1,7 @@ package ru.yandex.practicum.filmorate.controller; import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.Film; @@ -39,12 +40,12 @@ public Film getById(@PathVariable Integer id) { } @PutMapping("/{id}/like/{userId}") - public Film addLike(@PathVariable Integer id, @PathVariable Integer userId) { + public ResponseEntity addLike(@PathVariable Integer id, @PathVariable Integer userId) { return filmService.addLike(id, userId); } @DeleteMapping("/{id}/like/{userId}") - public Film removeLike(@PathVariable Integer id, @PathVariable Integer userId) { + public ResponseEntity removeLike(@PathVariable Integer id, @PathVariable Integer userId) { return filmService.removeLike(id, userId); } 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..279a347 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java @@ -0,0 +1,29 @@ +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.dao.GenreDao; +import ru.yandex.practicum.filmorate.model.Genres; + +import java.util.List; + +@RequestMapping("/genres") +@RestController +@RequiredArgsConstructor +public class GenreController { + + private final GenreDao genreDao; + + @GetMapping() + public List findAllGenres() { + return genreDao.getAll(); + } + + @GetMapping("/{id}") + public Genres getGenresById(@PathVariable Integer id) { + return genreDao.getById(id); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java new file mode 100644 index 0000000..6be1dd8 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java @@ -0,0 +1,30 @@ +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.dao.impl.MpaDaoImpl; +import ru.yandex.practicum.filmorate.model.MPA; + +import java.util.List; + +@RequestMapping("/mpa") +@RestController +@RequiredArgsConstructor +public class MPAController { + + private final MpaDaoImpl mpaDao; + + + @GetMapping() + public List findAllMpa() { + return mpaDao.getAll(); + } + + @GetMapping("/{id}") + public MPA getByIdMpa(@PathVariable Integer id) { + return mpaDao.getById(id); + } +} 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 855edd8..d4f64dc 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -1,6 +1,7 @@ package ru.yandex.practicum.filmorate.controller; import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.User; @@ -40,12 +41,12 @@ public User findById(@PathVariable Integer id) { } @PutMapping("/{id}/friends/{friendId}") - public User addToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { + public ResponseEntity addToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { return userService.addToFriends(id, friendId); } @DeleteMapping("/{id}/friends/{friendId}") - public User removeToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { + public ResponseEntity removeToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { return userService.removeToFriends(id, friendId); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java new file mode 100644 index 0000000..2d86d41 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java @@ -0,0 +1,8 @@ +package ru.yandex.practicum.filmorate.dao; + +import org.springframework.http.ResponseEntity; + +public interface FriendsDao { + ResponseEntity addToFriends(int idUser, int idFriend); + ResponseEntity removeToFriends (int idUser, int idFriend); +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java new file mode 100644 index 0000000..22ea36a --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java @@ -0,0 +1,10 @@ +package ru.yandex.practicum.filmorate.dao; + +import ru.yandex.practicum.filmorate.model.Genres; + +import java.util.List; + +public interface GenreDao { + List getAll(); + Genres getById(Integer id); +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java new file mode 100644 index 0000000..7ef1072 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java @@ -0,0 +1,8 @@ +package ru.yandex.practicum.filmorate.dao; + +import org.springframework.http.ResponseEntity; + +public interface LikesDao { + ResponseEntity addLike(int idFilm, int idUser); + ResponseEntity removeLike(int idFilm, int idUser); +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java new file mode 100644 index 0000000..b4f6d6c --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java @@ -0,0 +1,11 @@ +package ru.yandex.practicum.filmorate.dao; + +import ru.yandex.practicum.filmorate.model.MPA; + +import java.util.List; + +public interface MpaDao { + + List getAll (); + MPA getById (Integer id); +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java new file mode 100644 index 0000000..c309baa --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java @@ -0,0 +1,62 @@ +package ru.yandex.practicum.filmorate.dao.impl; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.dao.FriendsDao; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; +import ru.yandex.practicum.filmorate.storage.UserStorage; + + +@Slf4j +@Component +@AllArgsConstructor +public class FriendsDaoImpl implements FriendsDao { + + private final JdbcTemplate jdbcTemplate; + private final UserStorage userStorage; + + @Override + public ResponseEntity addToFriends(int idUser, int idFriend) { + if (idUser == idFriend || contains(idUser, idFriend)) { + throw new IncorrectArgumentsException(FriendsDaoImpl.class); + } + if (!userStorage.contains(idUser) || !userStorage.contains(idFriend)) { + throw new EntityNotFoundException(FriendsDaoImpl.class); + } + + jdbcTemplate.update("INSERT INTO friends (id_user,id_friend) VALUES (?,?)", idUser, idFriend); + log.info("Пользователь c id={} успешно добавлен в друзья пользователю c id={}",idFriend,idUser); + + return new ResponseEntity<>(HttpStatus.OK); + } + + @Override + public ResponseEntity removeToFriends(int idUser, int idFriend) { + if (idUser == idFriend || !contains(idUser, idFriend)) { + throw new IncorrectArgumentsException(FriendsDaoImpl.class); + } + + if (!userStorage.contains(idUser) || !userStorage.contains(idFriend)) { + throw new EntityNotFoundException(FriendsDaoImpl.class); + } + + jdbcTemplate.update("DELETE FROM friends WHERE id_user = ? AND id_friend = ?", idUser, idFriend); + log.info("Пользователь c id={} успешно удален из друзей пользователя c id={}",idFriend,idUser); + + return new ResponseEntity<>(HttpStatus.OK); + } + + private boolean contains(int idUser, int idFriend) { + SqlRowSet friendsRow = jdbcTemplate.queryForRowSet("SELECT 1 FROM friends " + + "WHERE id_user = ? AND id_friend = ?", + idUser, idFriend); + return friendsRow.next(); + } + +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java new file mode 100644 index 0000000..20ec17a --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java @@ -0,0 +1,44 @@ +package ru.yandex.practicum.filmorate.dao.impl; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.dao.GenreDao; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.model.Genres; + +import java.util.List; + +@Slf4j +@Component +@AllArgsConstructor +public class GenreDaoImpl implements GenreDao { + private final JdbcTemplate jdbcTemplate; + + @Override + public List getAll() { + String sq = "SELECT * FROM genres"; + log.info("Список жанров получен"); + return jdbcTemplate.query(sq, genreRowMapper()); + } + + @Override + public Genres getById(Integer id) { + SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select * from genres where id = ?", id); + if (filmRows.next()) { + String sq = "SELECT * FROM genres WHERE id = ?"; + log.info("Жанр с id={} получен",id); + return jdbcTemplate.queryForObject(sq, genreRowMapper(), id); + } else { + throw new EntityNotFoundException(Genres.class); + } + } + + private RowMapper genreRowMapper() { + return (rs, rowNum) -> new Genres(rs.getInt("id"), + rs.getString("name_genre")); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java new file mode 100644 index 0000000..c12da64 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java @@ -0,0 +1,61 @@ +package ru.yandex.practicum.filmorate.dao.impl; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.dao.LikesDao; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; +import ru.yandex.practicum.filmorate.storage.FilmStorage; +import ru.yandex.practicum.filmorate.storage.UserStorage; + +@Slf4j +@Component +@AllArgsConstructor +public class LikesDaoImpl implements LikesDao { + + private final JdbcTemplate jdbcTemplate; + private final UserStorage userStorage; + private final FilmStorage filmStorage; + + + @Override + public ResponseEntity addLike(int idFilm, int idUser) { + if (contains(idFilm, idUser)) { + throw new IncorrectArgumentsException(LikesDaoImpl.class); + } + if (!filmStorage.contains(idFilm) || !userStorage.contains(idUser)) { + throw new EntityNotFoundException(LikesDaoImpl.class); + } + jdbcTemplate.update("INSERT INTO likes (id_user,id_film) VALUES (?,?)", idUser, idFilm); + jdbcTemplate.update("UPDATE films SET likes = likes + 1 WHERE id = ?", idFilm); + log.info("Пользователь c id={} оценил фильм c id={}",idUser,idFilm); + + return new ResponseEntity<>(HttpStatus.OK); + + } + + @Override + public ResponseEntity removeLike(int idFilm, int idUser) { + if (!userStorage.contains(idUser) || !filmStorage.contains(idFilm) || !contains(idFilm, idUser)) { + throw new EntityNotFoundException(LikesDaoImpl.class); + } + jdbcTemplate.update("DELETE FROM likes WHERE id_user = ? AND id_film = ?", idUser, idFilm); + jdbcTemplate.update("UPDATE films SET likes = likes - 1 WHERE id = ?", idFilm); + log.info("Пользователь c id={} удалил оценку с фильма c id={}",idUser,idFilm); + + return new ResponseEntity<>(HttpStatus.OK); + + } + + private boolean contains(int idFilm, int idUser) { + SqlRowSet likesRow = jdbcTemplate.queryForRowSet("SELECT 1 FROM likes " + + "WHERE id_user = ? AND id_film = ?", + idUser, idFilm); + return likesRow.next(); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java new file mode 100644 index 0000000..7e1c293 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java @@ -0,0 +1,49 @@ +package ru.yandex.practicum.filmorate.dao.impl; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.dao.MpaDao; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.model.MPA; + +import java.util.List; + +@Slf4j +@Component +@AllArgsConstructor +public class MpaDaoImpl implements MpaDao { + + private final JdbcTemplate jdbcTemplate; + + @Override + public List getAll() { + String sq = "SELECT * FROM mpa"; + log.info("Список возрастных рейтингов получен"); + return jdbcTemplate.query(sq, mpaRowMapper()); + } + + @Override + public MPA getById(Integer id) { + SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select * from mpa where id = ?", id); + if (filmRows.next()) { + String sq = "SELECT * FROM mpa WHERE id = ?"; + log.info("Возрастной рейтинг с id={} получен",id); + return jdbcTemplate.queryForObject(sq, mpaRowMapper(), id); + } else { + throw new EntityNotFoundException(MPA.class); + } + } + + private RowMapper mpaRowMapper() { + return (rs, rowNum) -> { + MPA mpa = new MPA(); + mpa.setId(rs.getInt("id")); + mpa.setName(rs.getString("name_mpa")); + return mpa; + }; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java new file mode 100644 index 0000000..4974376 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java @@ -0,0 +1,183 @@ +package ru.yandex.practicum.filmorate.dao.storageimpl; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genres; +import ru.yandex.practicum.filmorate.model.MPA; +import ru.yandex.practicum.filmorate.storage.FilmStorage; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.util.*; + +@Slf4j +@Component +@AllArgsConstructor +public class FilmDbStorage implements FilmStorage { + + private final JdbcTemplate jdbcTemplate; + + private final String sq = "SELECT fgm.id,fgm.name,fgm.description,fgm.release_date,fgm.duration,fgm.likes," + + "fgm.mpa,m.name_mpa,fgm.id_genre,fgm.name_genre " + + "FROM mpa AS m RIGHT JOIN (SELECT * FROM films AS f LEFT JOIN " + + "(SELECT fg.id_film,fg.id_genre,g.name_genre " + + "FROM films_genres AS fg LEFT JOIN genres AS g " + + "ON g.id=fg.id_genre) " + + "ON f.id=id_film) AS fgm ON m.id=mpa "; + + @Override + public List getAll() { + log.info("Список фильмов получен"); + return new ArrayList<>(jdbcTemplate.query(sq, extractor()).values()); + } + + @Override + public Film create(Film film) { + + String sqlQuery = "INSERT INTO films (name," + + "description," + + "release_date," + + "duration," + + "likes," + + "mpa) " + + "VALUES (?,?,?,?,?,?)"; + + GeneratedKeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(connection -> { + PreparedStatement psst = connection.prepareStatement(sqlQuery, new String[]{"id"}); + psst.setString(1, film.getName()); + psst.setString(2, film.getDescription()); + psst.setDate(3, Date.valueOf(film.getReleaseDate())); + psst.setInt(4, film.getDuration()); + psst.setInt(5, film.getLikes()); + psst.setInt(6, film.getMpa().getId()); + return psst; + }, keyHolder); + + film.setId(keyHolder.getKey().intValue()); + + if (!film.getGenres().isEmpty()) { + for (Genres gen : film.getGenres()) { + String sQuery = "INSERT INTO films_genres (id_film,id_genre) " + + "VALUES (?,?)"; + + jdbcTemplate.update(sQuery, + film.getId(), + gen.getId()); + } + } + log.info("Фильм с id={} успешно добавлен",film.getId()); + return film; + } + + @Override + public Film upDate(Film film) { + SqlRowSet filmsRows = jdbcTemplate.queryForRowSet("select * from films where id = ?", film.getId()); + if (filmsRows.next()) { + String sqlQuery = "UPDATE films SET name = ?," + + "description = ?," + + "release_date = ?," + + "duration = ?," + + "likes = ?," + + "mpa = ?" + + " WHERE id = ?"; + + jdbcTemplate.update(sqlQuery, + film.getName(), + film.getDescription(), + film.getReleaseDate(), + film.getDuration(), + film.getLikes(), + film.getMpa().getId(), + film.getId()); + + jdbcTemplate.update("DELETE FROM films_genres WHERE id_film = ?", film.getId()); + + if (!film.getGenres().isEmpty()) { + for (Genres gen : film.getGenres()) { + String sQuery = "INSERT INTO films_genres (id_film,id_genre) " + + "VALUES (?,?)"; + + jdbcTemplate.update(sQuery, + film.getId(), + gen.getId()); + } + } + } else { + throw new EntityNotFoundException(FilmDbStorage.class); + } + log.info("Фильм с id={} успешно изменен",film.getId()); + return film; + } + + @Override + public boolean contains(Integer id) { + SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select 1 from films where id = ?", id); + return filmRows.next(); + } + + @Override + public List getTopFilms(int limit) { + String sqlQuery = sq + "ORDER BY likes DESC LIMIT ?"; + log.info("Получены {} наиболее популярных фильмов",limit); + return new ArrayList<>(jdbcTemplate.query(sqlQuery, extractor(), limit).values()); + } + + @Override + public Film getById(Integer id) { + if (contains(id)) { + String sqq = "SELECT fgm.id,fgm.name,fgm.description,fgm.release_date,fgm.duration,fgm.likes," + + "fgm.mpa,m.name_mpa,fgm.id_genre,fgm.name_genre " + + "FROM mpa AS m RIGHT JOIN (SELECT * FROM films AS f LEFT JOIN " + + "(SELECT fg.id_film,fg.id_genre,g.name_genre " + + "FROM films_genres AS fg LEFT JOIN genres AS g " + + "ON g.id=fg.id_genre ) " + + "ON f.id=id_film where f.id = ?) AS fgm ON m.id=mpa "; + Film film = jdbcTemplate.query(sqq, extractor(), id).get(id); + log.info("Фильм с id={} получен",film.getId()); + return film; + } else { + throw new EntityNotFoundException(FilmDbStorage.class); + } + } + + private ResultSetExtractor> extractor() { + return rs -> { + + Map films = new HashMap<>(); + while (rs.next()) { + int id = rs.getInt("id"); + int idGenre = rs.getInt("id_genre"); + String nameGenre = rs.getString("name_genre"); + if (films.containsKey(id)) { + if (idGenre != 0) films.get(id).getGenres().add(new Genres(idGenre, nameGenre)); + } else { + Film film = new Film(); + films.put(id, film); + film.setId(id); + film.setName(rs.getString("name")); + film.setDescription(rs.getString("description")); + film.setReleaseDate(rs.getDate("release_date").toLocalDate()); + film.setDuration(rs.getInt("duration")); + film.setLikes(rs.getInt("likes")); + + if (idGenre != 0) films.get(id).getGenres().add(new Genres(idGenre, nameGenre)); + + int idMpa = rs.getInt("mpa"); + String nameMpa = rs.getString("name_mpa"); + + film.setMpa(new MPA(idMpa, nameMpa)); + + } + } + return films; + }; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java new file mode 100644 index 0000000..bf2a16b --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java @@ -0,0 +1,151 @@ +package ru.yandex.practicum.filmorate.dao.storageimpl; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.UserStorage; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.util.*; + +@Slf4j +@Component +@AllArgsConstructor +public class UserDbStorage implements UserStorage { + + private final JdbcTemplate jdbcTemplate; + + @Override + public List getAll() { + log.info("Список пользователей получен"); + return jdbcTemplate.query("SELECT * FROM mov_users", userRowMapper()); + } + + @Override + public User create(User user) { + + String sqlQuery = "INSERT INTO mov_users (email," + + "login," + + "name," + + "birthday) " + + "VALUES (?,?,?,?)"; + + GeneratedKeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(connection -> { + PreparedStatement psst = connection.prepareStatement(sqlQuery, new String[]{"id"}); + psst.setString(1, user.getEmail()); + psst.setString(2, user.getLogin()); + psst.setString(3, user.getName()); + psst.setDate(4, Date.valueOf(user.getBirthday())); + return psst; + }, keyHolder); + + user.setId(keyHolder.getKey().intValue()); + + log.info("Пользователь с id={} добавлен",user.getId()); + return user; + } + + @Override + public User upDate(User user) { + SqlRowSet usersRows = jdbcTemplate.queryForRowSet("SELECT * FROM mov_users WHERE id = ?", user.getId()); + if (usersRows.next()) { + String sqlQuery = "UPDATE mov_users SET " + + "email = ?," + + "login = ?," + + "name = ?," + + "birthday = ?" + + " WHERE id = ?"; + + jdbcTemplate.update(sqlQuery, + user.getEmail(), + user.getLogin(), + user.getName(), + user.getBirthday(), + user.getId()); + + log.info("Пользователь c id={} успешно изменен",user.getId()); + return user; + } else { + throw new EntityNotFoundException(UserDbStorage.class); + } + } + + @Override + public User getById(Integer id) { + if (contains(id)) { + String sql = "SELECT * FROM mov_users WHERE id = ?"; + User user = jdbcTemplate.queryForObject(sql, userRowMapper(), id); + log.info("Пользователь с id={} получен",id); + return user; + } else { + throw new EntityNotFoundException(UserDbStorage.class); + } + } + + @Override + public boolean contains(Integer id) { + SqlRowSet userRows = jdbcTemplate.queryForRowSet("select 1 from mov_users where id = ?", id); + return userRows.next(); + } + + @Override + public List getAllFriends(Integer id) { + if (contains(id)) { + + String sql = "SELECT * FROM mov_users WHERE id IN (SELECT id_friend FROM friends WHERE id_user = ?)"; + + log.info("Список друзей пользователя c id={} получен",id); + return jdbcTemplate.query(sql, userRowMapper(), id); + } else { + throw new EntityNotFoundException(UserDbStorage.class); + } + } + + @Override + public List getMutualFriends(Integer idUser, Integer otherIdUser) { + if (idUser.equals(otherIdUser)) { + throw new IncorrectArgumentsException(UserDbStorage.class); + } + if (!contains(idUser)) { + throw new EntityNotFoundException(UserDbStorage.class); + } + if (!contains(otherIdUser)) { + throw new EntityNotFoundException(UserDbStorage.class); + } + + String sqlQuery = "SELECT * FROM mov_users WHERE id IN (SELECT id_friend FROM friends " + + "WHERE id_user=" + otherIdUser + " AND id_friend IN (SELECT id_friend " + + "FROM friends " + + "WHERE id_user =" + idUser + "))"; + + log.info("Список общих друзей пользователей c id={} и c id={} получен",idUser,otherIdUser); + return jdbcTemplate.query(sqlQuery, userRowMapper()); + } + + private RowMapper userRowMapper() { + return (rs, rowNum) -> { + User user = new User(); + user.setId(rs.getInt("id")); + user.setEmail(rs.getString("email")); + user.setLogin(rs.getString("login")); + user.setName(rs.getString("name")); + user.setBirthday(rs.getDate("birthday").toLocalDate()); + + return user; + }; + } + + private RowMapper mapper(String nameColumn) { + return (rs, rowNum) -> rs.getInt(nameColumn); + } + +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java new file mode 100644 index 0000000..570e3ad --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java @@ -0,0 +1,14 @@ +package ru.yandex.practicum.filmorate.exception; + +public class EntityNotFoundException extends RuntimeException { + private Class clazz; + + public EntityNotFoundException (Class clazz){ + this.clazz = clazz; + } + + @Override + public String getMessage() { + return clazz.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/FilmAndUserExceptionHandler.java b/src/main/java/ru/yandex/practicum/filmorate/exception/FilmAndUserExceptionHandler.java index c12dcc4..4b8f8c4 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/FilmAndUserExceptionHandler.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/FilmAndUserExceptionHandler.java @@ -1,6 +1,8 @@ package ru.yandex.practicum.filmorate.exception; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -8,36 +10,42 @@ import javax.validation.ValidationException; import java.util.Map; +@Slf4j @RestControllerAdvice("ru.yandex.practicum.filmorate.controller") public class FilmAndUserExceptionHandler { @ExceptionHandler @ResponseStatus(HttpStatus.NOT_FOUND) - public Map handleFilmNotFound(FilmNotFoundException e) { + public Map handleFilmNotFound(EntityNotFoundException e) { + log.warn("Получен статус 404 Not found {}", e.getMessage(), e); return Map.of("message", e.getMessage()); } @ExceptionHandler - @ResponseStatus(HttpStatus.NOT_FOUND) - public Map handleUserNotFound(UserNotFoundException e) { + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Map handleValidation(MethodArgumentNotValidException e) { + log.warn("Получен статус 400 Bad request {}", e.getMessage(), e); return Map.of("message", e.getMessage()); } @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public Map handleValidation(ValidationException e) { + log.warn("Получен статус 400 Bad request {}", e.getMessage(), e); return Map.of("message", e.getMessage()); } @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public Map handleIncorrectArguments(IncorrectArgumentsException e) { + log.warn("Получен статус 400 Bad request {}", e.getMessage(), e); return Map.of("message", e.getMessage()); } @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public Map handleIncorrectArguments(RuntimeException e) { + public Map handleIncorrectArguments(Throwable e) { + log.warn("Получен статус 500 Internal Server Error {}", e.getMessage(), e); return Map.of("message", e.getMessage()); } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/FilmNotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/FilmNotFoundException.java deleted file mode 100644 index ffa6980..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/FilmNotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.yandex.practicum.filmorate.exception; - -public class FilmNotFoundException extends RuntimeException { - - String message; - - public FilmNotFoundException(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } -} diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/IncorrectArgumentsException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/IncorrectArgumentsException.java index 15676df..697cfe7 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/IncorrectArgumentsException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/IncorrectArgumentsException.java @@ -2,13 +2,13 @@ public class IncorrectArgumentsException extends RuntimeException { - String message; + private Class clazz; - public IncorrectArgumentsException(String message) { - this.message = message; + public IncorrectArgumentsException(Class clazz) { + this.clazz = clazz; } public String getMessage() { - return message; + return clazz.getName(); } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/UserNotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/UserNotFoundException.java deleted file mode 100644 index 7fc17a7..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/UserNotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.yandex.practicum.filmorate.exception; - -public class UserNotFoundException extends RuntimeException { - - String message; - - public UserNotFoundException(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } -} 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 c9c5417..ae0df61 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,21 +1,20 @@ package ru.yandex.practicum.filmorate.model; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import ru.yandex.practicum.filmorate.validators.timevalidator.TimeAfterDate; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import javax.validation.constraints.*; import java.time.LocalDate; +import java.util.*; @Data public class Film { private int id; - @NotEmpty + @NotBlank private String name; @NotNull @@ -27,10 +26,15 @@ public class Film { @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate releaseDate; - @NotNull @Min(value = 1) - int duration; + private int duration; + + @JsonIgnore + private int likes; - int likes; + Set genres = new TreeSet<>(); + + @NotNull + MPA mpa; } diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Genres.java b/src/main/java/ru/yandex/practicum/filmorate/model/Genres.java new file mode 100644 index 0000000..3a48688 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Genres.java @@ -0,0 +1,34 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.*; + +import java.util.Objects; + + +@Getter +@Setter +@AllArgsConstructor +public class Genres implements Comparable { + + private int id; + private String name; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Genres genres = (Genres) o; + return id == genres.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public int compareTo(Genres g) { + return this.getId() - g.getId(); + } +} + diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/MPA.java b/src/main/java/ru/yandex/practicum/filmorate/model/MPA.java new file mode 100644 index 0000000..68c48b3 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/MPA.java @@ -0,0 +1,14 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class MPA { + private int id; + private String name; + + public MPA() { + } +} 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 b31c45f..12bfc29 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -3,31 +3,27 @@ import com.fasterxml.jackson.annotation.JsonFormat; import lombok.*; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Past; +import javax.validation.constraints.*; import java.time.LocalDate; -import java.util.HashSet; -import java.util.Set; @Data public class User { + private int id; + @NotEmpty @Email private String email; @NotBlank + @Pattern(regexp = "^[a-zA-Z0-9!@#$%^&*]{6,12}$") private String login; private String name; + @NotNull @JsonFormat(pattern = "yyyy-MM-dd") - @Past + @PastOrPresent private LocalDate birthday; - private Set friends = new HashSet<>(); - - private Set likes = new HashSet<>(); - } 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 401b855..5604360 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -1,29 +1,24 @@ package ru.yandex.practicum.filmorate.service; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import ru.yandex.practicum.filmorate.exception.FilmNotFoundException; -import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; -import ru.yandex.practicum.filmorate.exception.UserNotFoundException; +import ru.yandex.practicum.filmorate.dao.LikesDao; import ru.yandex.practicum.filmorate.model.Film; -import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.storage.FilmStorage; -import ru.yandex.practicum.filmorate.storage.UserStorage; -import java.util.ArrayList; import java.util.List; -@Slf4j @Service @RequiredArgsConstructor public class FilmService { private final FilmStorage filmStorage; - private final UserStorage userStorage; + + private final LikesDao likesDao; public List findAll() { - return new ArrayList(filmStorage.getAll().values()); + return filmStorage.getAll(); } public Film findById(Integer id) { @@ -35,7 +30,7 @@ public List findTopFilms(int limit) { } public Film create(Film film) { - return filmStorage.create (film); + return filmStorage.create(film); } @@ -43,53 +38,11 @@ public Film upDate(Film film) { return filmStorage.upDate(film); } - public Film addLike(Integer idFilm, Integer idUser) { - - if (!userStorage.contains(idUser)) { - log.warn("Пользватель с id " + idUser + " отсутствует"); - throw new UserNotFoundException("Пользватель с id " + idUser + " отсутствует"); - } - if (!filmStorage.contains(idFilm)) { - log.warn("Фильм с id " + idFilm + " отсутствует"); - throw new FilmNotFoundException("Фильм с id " + idFilm + " отсутствует"); - } - - User user = userStorage.getById(idUser); - Film film = findById(idFilm); - - if (user.getLikes().contains(film.getId())) { - log.warn("Пользователь " + idUser + " уже оценивал фильм " + idFilm); - throw new IncorrectArgumentsException("Пользователь " + idUser + " уже оценивал фильм " + idFilm); - } - - user.getLikes().add(film.getId()); - film.setLikes(film.getLikes() + 1); - log.info("Пользователь " + idUser + " оценил фильм " + idFilm); - return filmStorage.getById(idFilm); - + public ResponseEntity addLike(Integer idFilm, Integer idUser) { + return likesDao.addLike(idFilm, idUser); } - public Film removeLike(Integer idFilm, Integer idUser) { - if (!userStorage.contains(idUser)) { - log.warn("Пользватель с id " + idUser + " отсутствует"); - throw new UserNotFoundException("Пользватель с id " + idUser + " отсутствует"); - } - if (!filmStorage.contains(idFilm)) { - log.warn("Фильм с id " + idFilm + " отсутствует"); - throw new FilmNotFoundException("Фильм с id " + idFilm + " отсутствует"); - } - - User user = userStorage.getById(idUser); - Film film = findById(idFilm); - - if (!user.getLikes().contains(idFilm)) { - log.warn("Пользватель " + idUser + " еще не оценивал фильм " + idFilm); - throw new IncorrectArgumentsException("Пользватель " + idUser + " еще не оценивал фильм " + idFilm); - } - film.setLikes(film.getLikes() - 1); - user.getLikes().remove(film.getId()); - log.info("Пользователь " + idUser + " удалил оценку с фильма " + idFilm); - return film; + public ResponseEntity removeLike(Integer idFilm, Integer idUser) { + return likesDao.removeLike(idFilm, idUser); } - } 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 6435fae..4f6f6ac 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -3,9 +3,9 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; -import ru.yandex.practicum.filmorate.exception.UserNotFoundException; +import ru.yandex.practicum.filmorate.dao.FriendsDao; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.storage.UserStorage; @@ -16,10 +16,12 @@ @RequiredArgsConstructor public class UserService { + private final UserStorage userStorage; + private final FriendsDao friendsDao; public List findAll() { - return new ArrayList(userStorage.getAll().values()); + return userStorage.getAll(); } public User findById(Integer id) { @@ -35,41 +37,13 @@ public List findMutualFriends(Integer idUser, Integer otherIdUser) { return userStorage.getMutualFriends(idUser, otherIdUser); } - public User addToFriends(Integer idUser, Integer idFriend) { - if (idUser.equals(idFriend)) { - log.warn("Значения не должны быть одинаковыми"); - throw new IncorrectArgumentsException("Значения не должны быть одинаковыми"); - } - if (!userStorage.contains(idUser)) { - log.warn("Пользователь с id " + idUser + " отсутствует"); - throw new UserNotFoundException("Пользователь с id " + idUser + " отсутствует"); - } - if (!userStorage.contains(idFriend)) { - log.warn("Пользователь с id " + idUser + " отсутствует"); - throw new UserNotFoundException("Пользователь с id " + idFriend + " отсутствует"); - } - findById(idUser).getFriends().add(idFriend); - findById(idFriend).getFriends().add(idUser); - - log.info("Пользователь успешно добавлен в друзья"); + public ResponseEntity addToFriends(Integer idUser, Integer idFriend) { - return findById(idUser); + return friendsDao.addToFriends(idUser, idFriend); } - public User removeToFriends(Integer idUser, Integer idFriend) { - if (findById(idUser).getFriends().contains(idFriend)) { - findById(idFriend).getFriends().remove(idUser); - findById(idUser).getFriends().remove(idFriend); - - log.info("Пользователь успешно удален из друзей"); - - return findById(idUser); - } else { - - log.warn("Пользователь с id " + idFriend + " отсутствует"); - - throw new UserNotFoundException("Пользователь с id " + idFriend + " отсутствует"); - } + public ResponseEntity removeToFriends(Integer idUser, Integer idFriend) { + return friendsDao.removeToFriends(idUser, idFriend); } public User create(User user) { @@ -85,6 +59,4 @@ public User upDate(User user) { } return userStorage.upDate(user); } - - } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java index 39c090a..55dda3e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -1,17 +1,18 @@ package ru.yandex.practicum.filmorate.storage; import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genres; +import ru.yandex.practicum.filmorate.model.MPA; import java.util.List; -import java.util.Map; public interface FilmStorage { - Map getAll(); + List getAll(); - Film create (Film film); + Film create(Film film); - Film upDate (Film film); + Film upDate(Film film); boolean contains(Integer id); @@ -19,4 +20,5 @@ public interface FilmStorage { Film getById(Integer id); + } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java deleted file mode 100644 index 36bf3c1..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java +++ /dev/null @@ -1,77 +0,0 @@ -package ru.yandex.practicum.filmorate.storage; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.exception.FilmNotFoundException; -import ru.yandex.practicum.filmorate.model.Film; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Slf4j -@Component -public class InMemoryFilmStorage implements FilmStorage { - - private int idGenerator = 0; - - private final Map films = new HashMap<>(); - - - @Override - public Map getAll() { - log.info("Список фильмов получен"); - return films; - } - - @Override - public Film create (Film film){ - idGenerator++; - film.setId(idGenerator); - films.put(idGenerator, film); - log.info("Фильм успешно добавлен"); - return film; - } - - @Override - public Film upDate (Film film){ - if (contains(film.getId())) { - films.put(film.getId(), film); - } else { - log.warn("Фильм с id " + film.getId() + " отсутствует"); - throw new FilmNotFoundException("Фильм с id " + film.getId() + " отсутствует"); - } - log.info("Фильм успешно изменен"); - return film; - } - - @Override - public List getTopFilms(int limit) { - log.info("Получены " + limit + " наиболее популярных фильмов"); - return films.values().stream().sorted((f1, f2) -> { - return -1 * (f1.getLikes() - f2.getLikes()); - }) - .limit(limit) - .collect(Collectors.toList()); - } - - - @Override - public boolean contains(Integer id) { - return films.containsKey(id); - } - - @Override - public Film getById(Integer id) { - if (films.containsKey(id)) { - log.info("Фильм с id " + id + " получен"); - return films.get(id); - } else { - log.warn("Фильм с id " + id + " отсутствует"); - throw new FilmNotFoundException("Фильм с id " + id + " отсутствует"); - } - } - - -} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java deleted file mode 100644 index cd4817c..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java +++ /dev/null @@ -1,109 +0,0 @@ -package ru.yandex.practicum.filmorate.storage; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; -import ru.yandex.practicum.filmorate.exception.UserNotFoundException; -import ru.yandex.practicum.filmorate.model.User; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Slf4j -@Component -public class InMemoryUserStorage implements UserStorage { - - private int idGenerator = 0; - private final Map users = new HashMap<>(); - - @Override - public Map getAll() { - log.info("Вывод списка пользователей"); - return users; - } - - @Override - public User create (User user) { - idGenerator++; - user.setId(idGenerator); - users.put(idGenerator, user); - log.info("Пользователь добавлен"); - return user; - } - - @Override - public User upDate (User user){ - if (contains(user.getId())) { - users.put(user.getId(), user); - log.info("Пользователь изменен"); - } else { - log.warn("Пользователь с id " + user.getId() + " отсутствует"); - throw new UserNotFoundException("Пользватель с id " + user.getId() + " отсутствует"); - } - return user; - } - - @Override - public boolean contains(Integer id) { - return users.containsKey(id); - } - - @Override - public User getById(Integer id) { - if (contains(id)) { - log.info("Пользователь с id " + id + " получен"); - return users.get(id); - } else { - log.warn("Пользователь с id " + id + " отсутствует"); - throw new UserNotFoundException("Пользователь с id " + id + " отсутствует"); - } - } - - @Override - public List getAllFriends(Integer id) { - if (contains(id)) { - ArrayList allFriends = new ArrayList<>(); - for (Integer idFriends : getById(id).getFriends()) { - allFriends.add(getById(idFriends)); - } - - log.info("Список друзей пользователя " + id + " получен"); - - return allFriends; - } else { - - log.warn("Пользователь с id " + id + " отсутствует"); - - throw new UserNotFoundException("Пользователь с id " + id + " отсутствует"); - } - } - - @Override - public List getMutualFriends(Integer idUser, Integer otherIdUser) { - if (idUser.equals(otherIdUser)) { - log.warn("Значения не должны быть одинаковыми"); - throw new IncorrectArgumentsException("Значения не должны быть одинаковыми"); - } - if (!contains(idUser)) { - log.warn("Пользователь с id " + idUser + " отсутствует"); - throw new UserNotFoundException("Пользователь с id " + idUser + " отсутствует"); - } - if (!contains(otherIdUser)) { - log.warn("Пользователь с id " + otherIdUser + " отсутствует"); - throw new UserNotFoundException("Пользователь с id " + otherIdUser + " отсутствует"); - } - - ArrayList mutualFriends = new ArrayList<>(); - for (Integer id : getById(idUser).getFriends()) { - if (getById(otherIdUser).getFriends().contains(id)) { - mutualFriends.add(getById(id)); - } - } - log.info("Список общих друзей пользователей получен"); - return mutualFriends; - } -} - diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java index a26f9fb..6a1f0ac 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -3,19 +3,18 @@ import ru.yandex.practicum.filmorate.model.User; import java.util.List; -import java.util.Map; public interface UserStorage { - Map getAll(); + List getAll(); - User create (User user); + User create(User user); - User upDate (User user); + User upDate(User user); User getById(Integer id); - boolean contains (Integer id); + boolean contains(Integer id); List getAllFriends(Integer id); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 72f5316..73d861b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,6 @@ -logging.level.ru.yandex.practicum.filmorate.controller=info +logging.level.ru.yandex.practicum.filmorate.controller=debug +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 diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..e890c49 --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,15 @@ +INSERT INTO genres (id, name_genre) +VALUES (1, 'Комедия'), + (2, 'Драма'), + (3, 'Мультфильм'), + (4, 'Триллер'), + (5, 'Документальный'), + (6, 'Боевик'); + +INSERT INTO mpa (id, name_mpa) +VALUES (1, 'G'), + (2, 'PG'), + (3, 'PG-13'), + (4, 'R'), + (5, 'NC-17'); + diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000..6b2e947 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,61 @@ +drop table if exists FILMS cascade; +drop table if exists mov_users cascade; +drop table if exists mpa cascade; +drop table if exists likes cascade; +drop table if exists genres cascade; +drop table if exists friends cascade; +drop table if exists films_genres cascade; + +CREATE TABLE IF NOT EXISTS genres +( + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name_genre varchar NOT NULL +); + +CREATE TABLE IF NOT EXISTS mpa +( + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name_mpa varchar NOT NULL +); + +CREATE TABLE IF NOT EXISTS films +( + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name varchar NOT NULL, + description varchar NOT NULL, + release_date date, + duration integer, + likes integer, + mpa integer REFERENCES mpa (id) +); + +CREATE TABLE IF NOT EXISTS films_genres +( + id_film integer REFERENCES films (id), + id_genre integer REFERENCES genres (id), + CONSTRAINT film_genre PRIMARY KEY (id_film,id_genre) +); + +CREATE TABLE IF NOT EXISTS mov_users +( + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + email varchar NOT NULL UNIQUE, + login varchar NOT NULL UNIQUE, + name varchar, + birthday date +); + +CREATE TABLE IF NOT EXISTS friends +( + id_user integer REFERENCES mov_users (id), + id_friend integer REFERENCES mov_users (id), + CONSTRAINT user_friend PRIMARY KEY (id_user,id_friend) +); + +CREATE TABLE IF NOT EXISTS likes +( + id_user integer REFERENCES mov_users (id), + id_film integer REFERENCES films (id), + CONSTRAINT user_film PRIMARY KEY (id_user,id_film) +); + diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 660412e..086e841 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -1,13 +1,333 @@ package ru.yandex.practicum.filmorate; +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.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import ru.yandex.practicum.filmorate.dao.GenreDao; +import ru.yandex.practicum.filmorate.dao.MpaDao; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.Genres; +import ru.yandex.practicum.filmorate.model.MPA; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.service.FilmService; +import ru.yandex.practicum.filmorate.service.UserService; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @SpringBootTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) class FilmorateApplicationTests { - @Test - void contextLoads() { - } + private final UserService userService; + private final FilmService filmService; + + private final GenreDao genreDao; + + private final MpaDao mpaDao; + + private User newUser(Integer n) { + User user = new User(); + user.setEmail("email@email" + n + ".ru"); + user.setLogin("login" + n); + user.setName("name" + n); + user.setBirthday(LocalDate.of(2000, 12, 15)); + return user; + } + + @Test + public void testFindUserById() { + + userService.create(newUser(1)); + userService.create(newUser(2)); + userService.create(newUser(3)); + + User resultUser1 = userService.findById(1); + User resultUser2 = userService.findById(2); + User resultUser3 = userService.findById(3); + + assertThat(resultUser1).isNotNull(); + assertThat(resultUser1.getId()).isEqualTo(1); + assertThat(resultUser1.getName()).isEqualTo("name1"); + assertThat(resultUser2.getId()).isEqualTo(2); + assertThat(resultUser3.getId()).isEqualTo(3); + } + + @Test + public void testFindAllUser() { + + userService.create(newUser(1)); + userService.create(newUser(2)); + userService.create(newUser(3)); + + List users = userService.findAll(); + + assertThat(users.size()).isEqualTo(3); + } + + @Test + public void testUpdateUser() { + userService.create(newUser(1)); + userService.create(newUser(2)); + userService.create(newUser(3)); + + User updateUser = newUser(4); + updateUser.setId(2); + + User resultUser = userService.upDate(updateUser); + + assertThat(resultUser).isNotNull(); + assertThat(resultUser.getId()).isEqualTo(2); + assertThat(resultUser.getName()).isEqualTo("name4"); + assertThat(resultUser.getLogin()).isEqualTo("login4"); + assertThat(resultUser.getEmail()).isEqualTo("email@email4.ru"); + } + + @Test + public void testGetAllFriends() { + User user = newUser(1); + User friend1 = newUser(2); + User friend2 = newUser(3); + User friend3 = newUser(4); + + userService.create(user); + userService.create(friend1); + userService.create(friend2); + userService.create(friend3); + + userService.addToFriends(1, 2); + userService.addToFriends(1, 3); + userService.addToFriends(1, 4); + + List friends = userService.findAllFriends(1); + assertThat(friends.size()).isEqualTo(3); + + userService.removeToFriends(1, 4); + friends = userService.findAllFriends(1); + assertThat(friends.size()).isEqualTo(2); + + List idFriend = new ArrayList<>(); + for (User userr : friends) { + idFriend.add(userr.getId()); + } + assertThat(idFriend.contains(3)).isTrue(); + assertThat(idFriend.contains(2)).isTrue(); + } + + @Test + public void testGetMutualFriends() { + User user1 = newUser(1); + User user2 = newUser(2); + User friend1 = newUser(3); + User friend2 = newUser(4); + User friend3 = newUser(5); + + userService.create(user1); + userService.create(user2); + userService.create(friend1); + userService.create(friend2); + userService.create(friend3); + + userService.addToFriends(1, 3); + userService.addToFriends(1, 4); + userService.addToFriends(1, 5); + userService.addToFriends(2, 3); + userService.addToFriends(2, 5); + + List friends = userService.findMutualFriends(1, 2); + assertThat(friends.size()).isEqualTo(2); + + List idFriend = new ArrayList<>(); + for (User user : friends) { + idFriend.add(user.getId()); + } + assertThat(idFriend.contains(3)).isTrue(); + assertThat(idFriend.contains(5)).isTrue(); + } + + private Film newFilm(Integer num) { + Film film = new Film(); + film.setName("name" + num); + film.setDescription("description" + num); + film.setReleaseDate(LocalDate.of(2005, 12, 15)); + film.setDuration(150); + film.setMpa(new MPA(1, "PG")); + return film; + } + + @Test + public void testFindAllFilms() { + filmService.create(newFilm(1)); + filmService.create(newFilm(2)); + filmService.create(newFilm(3)); + + List films = filmService.findAll(); + assertThat(films.size()).isEqualTo(3); + } + + @Test + public void testFindFilmById() { + filmService.create(newFilm(1)); + filmService.create(newFilm(2)); + filmService.create(newFilm(3)); + + Film resultFilm = filmService.findById(3); + + assertThat(resultFilm.getId()).isEqualTo(3); + assertThat(resultFilm.getName()).isEqualTo("name3"); + } + + @Test + public void testUpdateFilm() { + filmService.create(newFilm(1)); + filmService.create(newFilm(2)); + filmService.create(newFilm(3)); + + Film upDateFilm = newFilm(4); + upDateFilm.setId(2); + + filmService.upDate(upDateFilm); + + assertThat(upDateFilm.getName()).isEqualTo("name4"); + assertThat(upDateFilm.getDescription()).isEqualTo("description4"); + assertThat(upDateFilm.getLikes()).isEqualTo(0); + } + + @Test + public void testAddLikes() { + filmService.create(newFilm(1)); + userService.create(newUser(1)); + userService.create(newUser(2)); + userService.create(newUser(3)); + + filmService.addLike(1, 1); + filmService.addLike(1, 2); + filmService.addLike(1, 3); + + Film filmWithLikes = filmService.findById(1); + User userWithLikes = userService.findById(2); + + assertThat(filmWithLikes.getLikes()).isEqualTo(3); + } + + @Test + public void testRemoveLike() { + filmService.create(newFilm(1)); + userService.create(newUser(1)); + userService.create(newUser(2)); + userService.create(newUser(3)); + + filmService.addLike(1, 1); + filmService.addLike(1, 2); + filmService.addLike(1, 3); + + filmService.removeLike(1, 2); + + Film filmWithoutLikes = filmService.findById(1); + User userWithoutLikes = userService.findById(2); + + assertThat(filmWithoutLikes.getLikes()).isEqualTo(2); + } + + @Test + public void testFindTopFilms() { + filmService.create(newFilm(1)); + filmService.create(newFilm(2)); + filmService.create(newFilm(3)); + filmService.create(newFilm(4)); + filmService.create(newFilm(5)); + + userService.create(newUser(1)); + userService.create(newUser(2)); + userService.create(newUser(3)); + userService.create(newUser(4)); + userService.create(newUser(5)); + userService.create(newUser(6)); + + filmService.addLike(1, 1); + filmService.addLike(1, 2); + filmService.addLike(1, 3); + filmService.addLike(1, 4); + filmService.addLike(1, 5); + filmService.addLike(1, 6); + + filmService.addLike(4, 1); + filmService.addLike(4, 2); + filmService.addLike(4, 3); + filmService.addLike(4, 4); + filmService.addLike(4, 5); + + List top = filmService.findTopFilms(2); + assertThat(top.size()).isEqualTo(2); + + ArrayList idTop = new ArrayList<>(); + for (Film film : top) { + idTop.add(film.getId()); + } + + assertThat(idTop.contains(1)).isTrue(); + assertThat(idTop.contains(4)).isTrue(); + } + + @Test + public void testGetAllGenres() { + List genres = genreDao.getAll(); + + ArrayList idGenres = new ArrayList<>(); + ArrayList namesGenres = new ArrayList<>(); + for (Genres genre : genres) { + idGenres.add(genre.getId()); + namesGenres.add(genre.getName()); + } + assertThat(idGenres.size()).isEqualTo(6); + assertThat(idGenres.contains(1)).isTrue(); + assertThat(idGenres.contains(6)).isTrue(); + assertThat(idGenres.contains(7)).isFalse(); + assertThat(namesGenres.contains("Комедия")).isTrue(); + assertThat(namesGenres.contains("Триллер")).isTrue(); + assertThat(namesGenres.contains("Пуп")).isFalse(); + } + + @Test + public void testGetGenreById() { + Genres genre = genreDao.getById(3); + + assertThat(genre.getId()).isEqualTo(3); + assertThat(genre.getName()).isEqualTo("Мультфильм"); + } + + @Test + public void testGetAllMPA() { + List mpa = mpaDao.getAll(); + + ArrayList idMpa = new ArrayList<>(); + ArrayList namesMpa = new ArrayList<>(); + for (MPA mp : mpa) { + idMpa.add(mp.getId()); + namesMpa.add(mp.getName()); + } + assertThat(idMpa.size()).isEqualTo(5); + assertThat(idMpa.contains(1)).isTrue(); + assertThat(idMpa.contains(5)).isTrue(); + assertThat(idMpa.contains(6)).isFalse(); + assertThat(namesMpa.contains("PG")).isTrue(); + assertThat(namesMpa.contains("G")).isTrue(); + assertThat(namesMpa.contains("PGG")).isFalse(); + } + + @Test + public void testGetMPAById() { + MPA mpa = mpaDao.getById(1); + assertThat(mpa.getId()).isEqualTo(1); + assertThat(mpa.getName()).isEqualTo("G"); + } } From cd9205f7c13809ba9b7e4b874d14f469aec02ba1 Mon Sep 17 00:00:00 2001 From: Marat Date: Wed, 3 May 2023 23:54:56 +0500 Subject: [PATCH 2/3] fix: codestyle --- .../yandex/practicum/filmorate/controller/MPAController.java | 1 - .../java/ru/yandex/practicum/filmorate/dao/FriendsDao.java | 4 +++- .../java/ru/yandex/practicum/filmorate/dao/GenreDao.java | 1 + .../java/ru/yandex/practicum/filmorate/dao/LikesDao.java | 1 + src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java | 5 +++-- .../yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java | 4 ++-- .../ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java | 2 +- .../ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java | 4 ++-- .../ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java | 2 +- .../filmorate/exception/EntityNotFoundException.java | 2 +- .../ru/yandex/practicum/filmorate/storage/FilmStorage.java | 3 +-- 11 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java index 6be1dd8..b568c5f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java @@ -17,7 +17,6 @@ public class MPAController { private final MpaDaoImpl mpaDao; - @GetMapping() public List findAllMpa() { return mpaDao.getAll(); diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java index 2d86d41..9858114 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java @@ -3,6 +3,8 @@ import org.springframework.http.ResponseEntity; public interface FriendsDao { + ResponseEntity addToFriends(int idUser, int idFriend); - ResponseEntity removeToFriends (int idUser, int idFriend); + + ResponseEntity removeToFriends(int idUser, int idFriend); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java index 22ea36a..43cbdb6 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java @@ -6,5 +6,6 @@ public interface GenreDao { List getAll(); + Genres getById(Integer id); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java index 7ef1072..f4f8752 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java @@ -4,5 +4,6 @@ public interface LikesDao { ResponseEntity addLike(int idFilm, int idUser); + ResponseEntity removeLike(int idFilm, int idUser); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java index b4f6d6c..d00982c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java @@ -6,6 +6,7 @@ public interface MpaDao { - List getAll (); - MPA getById (Integer id); + List getAll(); + + MPA getById(Integer id); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java index c309baa..bc9d343 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java @@ -31,7 +31,7 @@ public ResponseEntity addToFriends(int idUser, int idFriend) { } jdbcTemplate.update("INSERT INTO friends (id_user,id_friend) VALUES (?,?)", idUser, idFriend); - log.info("Пользователь c id={} успешно добавлен в друзья пользователю c id={}",idFriend,idUser); + log.info("Пользователь c id={} успешно добавлен в друзья пользователю c id={}", idFriend, idUser); return new ResponseEntity<>(HttpStatus.OK); } @@ -47,7 +47,7 @@ public ResponseEntity removeToFriends(int idUser, int idFriend) { } jdbcTemplate.update("DELETE FROM friends WHERE id_user = ? AND id_friend = ?", idUser, idFriend); - log.info("Пользователь c id={} успешно удален из друзей пользователя c id={}",idFriend,idUser); + log.info("Пользователь c id={} успешно удален из друзей пользователя c id={}", idFriend, idUser); return new ResponseEntity<>(HttpStatus.OK); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java index 20ec17a..eac23ab 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java @@ -30,7 +30,7 @@ public Genres getById(Integer id) { SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select * from genres where id = ?", id); if (filmRows.next()) { String sq = "SELECT * FROM genres WHERE id = ?"; - log.info("Жанр с id={} получен",id); + log.info("Жанр с id={} получен", id); return jdbcTemplate.queryForObject(sq, genreRowMapper(), id); } else { throw new EntityNotFoundException(Genres.class); diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java index c12da64..1baed8a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java @@ -33,7 +33,7 @@ public ResponseEntity addLike(int idFilm, int idUser) { } jdbcTemplate.update("INSERT INTO likes (id_user,id_film) VALUES (?,?)", idUser, idFilm); jdbcTemplate.update("UPDATE films SET likes = likes + 1 WHERE id = ?", idFilm); - log.info("Пользователь c id={} оценил фильм c id={}",idUser,idFilm); + log.info("Пользователь c id={} оценил фильм c id={}", idUser, idFilm); return new ResponseEntity<>(HttpStatus.OK); @@ -46,7 +46,7 @@ public ResponseEntity removeLike(int idFilm, int idUser) { } jdbcTemplate.update("DELETE FROM likes WHERE id_user = ? AND id_film = ?", idUser, idFilm); jdbcTemplate.update("UPDATE films SET likes = likes - 1 WHERE id = ?", idFilm); - log.info("Пользователь c id={} удалил оценку с фильма c id={}",idUser,idFilm); + log.info("Пользователь c id={} удалил оценку с фильма c id={}", idUser, idFilm); return new ResponseEntity<>(HttpStatus.OK); diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java index 7e1c293..2875220 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java @@ -31,7 +31,7 @@ public MPA getById(Integer id) { SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select * from mpa where id = ?", id); if (filmRows.next()) { String sq = "SELECT * FROM mpa WHERE id = ?"; - log.info("Возрастной рейтинг с id={} получен",id); + log.info("Возрастной рейтинг с id={} получен", id); return jdbcTemplate.queryForObject(sq, mpaRowMapper(), id); } else { throw new EntityNotFoundException(MPA.class); diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java index 570e3ad..669fae7 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/EntityNotFoundException.java @@ -3,7 +3,7 @@ public class EntityNotFoundException extends RuntimeException { private Class clazz; - public EntityNotFoundException (Class clazz){ + public EntityNotFoundException(Class clazz) { this.clazz = clazz; } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java index 55dda3e..8f34844 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -1,8 +1,7 @@ package ru.yandex.practicum.filmorate.storage; import ru.yandex.practicum.filmorate.model.Film; -import ru.yandex.practicum.filmorate.model.Genres; -import ru.yandex.practicum.filmorate.model.MPA; + import java.util.List; From b047ad99ad3cf8075206ccc25129e0d61c6001a2 Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 5 May 2023 02:28:32 +0500 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B8=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B0=20=D1=83=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D0=BD=D1=8C=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8?= =?UTF-8?q?=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filmorate/controller/FilmController.java | 9 +- .../filmorate/controller/GenreController.java | 8 +- .../filmorate/controller/MPAController.java | 8 +- .../filmorate/controller/UserController.java | 9 +- .../practicum/filmorate/dao/FriendsDao.java | 7 +- .../practicum/filmorate/dao/GenreDao.java | 11 -- .../practicum/filmorate/dao/LikesDao.java | 7 +- .../practicum/filmorate/dao/MpaDao.java | 12 --- .../filmorate/dao/impl/FriendsDaoImpl.java | 44 ++------ .../filmorate/dao/impl/LikesDaoImpl.java | 48 ++------- .../filmorate/dao/impl/MpaDaoImpl.java | 49 --------- .../dao/storageimpl/FilmDbStorage.java | 101 ++++++++---------- .../GenreDbStorage.java} | 28 +++-- .../dao/storageimpl/MpaDbStorage.java | 42 ++++++++ .../dao/storageimpl/UserDbStorage.java | 88 +++++---------- .../practicum/filmorate/model/Film.java | 4 +- .../yandex/practicum/filmorate/model/MPA.java | 3 - .../filmorate/service/FilmService.java | 47 ++++++-- .../filmorate/service/GenreService.java | 32 ++++++ .../filmorate/service/MpaService.java | 31 ++++++ .../filmorate/service/UserService.java | 75 ++++++++++--- .../filmorate/storage/FilmStorage.java | 6 +- .../filmorate/storage/GenreStorage.java | 13 +++ .../filmorate/storage/MpaStorage.java | 14 +++ .../filmorate/storage/UserStorage.java | 10 +- .../filmorate/FilmorateApplicationTests.java | 8 +- 26 files changed, 370 insertions(+), 344 deletions(-) delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java delete mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java rename src/main/java/ru/yandex/practicum/filmorate/dao/{impl/GenreDaoImpl.java => storageimpl/GenreDbStorage.java} (55%) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/MpaDbStorage.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/MpaService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java 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 74da814..7643b28 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,7 +1,6 @@ package ru.yandex.practicum.filmorate.controller; import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.Film; @@ -40,13 +39,13 @@ public Film getById(@PathVariable Integer id) { } @PutMapping("/{id}/like/{userId}") - public ResponseEntity addLike(@PathVariable Integer id, @PathVariable Integer userId) { - return filmService.addLike(id, userId); + public void addLike(@PathVariable Integer id, @PathVariable Integer userId) { + filmService.addLike(id, userId); } @DeleteMapping("/{id}/like/{userId}") - public ResponseEntity removeLike(@PathVariable Integer id, @PathVariable Integer userId) { - return filmService.removeLike(id, userId); + public void removeLike(@PathVariable Integer id, @PathVariable Integer userId) { + filmService.removeLike(id, userId); } @GetMapping("/popular") diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java index 279a347..f86f18e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/GenreController.java @@ -5,7 +5,7 @@ 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.dao.GenreDao; +import ru.yandex.practicum.filmorate.service.GenreService; import ru.yandex.practicum.filmorate.model.Genres; import java.util.List; @@ -15,15 +15,15 @@ @RequiredArgsConstructor public class GenreController { - private final GenreDao genreDao; + private final GenreService genreService; @GetMapping() public List findAllGenres() { - return genreDao.getAll(); + return genreService.findAll(); } @GetMapping("/{id}") public Genres getGenresById(@PathVariable Integer id) { - return genreDao.getById(id); + return genreService.findById(id); } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java index b568c5f..56eec6c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.java @@ -5,8 +5,8 @@ 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.dao.impl.MpaDaoImpl; import ru.yandex.practicum.filmorate.model.MPA; +import ru.yandex.practicum.filmorate.service.MpaService; import java.util.List; @@ -15,15 +15,15 @@ @RequiredArgsConstructor public class MPAController { - private final MpaDaoImpl mpaDao; + private final MpaService mpaService; @GetMapping() public List findAllMpa() { - return mpaDao.getAll(); + return mpaService.findAll(); } @GetMapping("/{id}") public MPA getByIdMpa(@PathVariable Integer id) { - return mpaDao.getById(id); + return mpaService.findById(id); } } 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 d4f64dc..825b121 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -1,7 +1,6 @@ package ru.yandex.practicum.filmorate.controller; import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.User; @@ -41,13 +40,13 @@ public User findById(@PathVariable Integer id) { } @PutMapping("/{id}/friends/{friendId}") - public ResponseEntity addToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { - return userService.addToFriends(id, friendId); + public void addToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { + userService.addToFriends(id, friendId); } @DeleteMapping("/{id}/friends/{friendId}") - public ResponseEntity removeToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { - return userService.removeToFriends(id, friendId); + public void removeToFriends(@PathVariable Integer id, @PathVariable Integer friendId) { + userService.removeToFriends(id, friendId); } @GetMapping("/{id}/friends") diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java index 9858114..59ccb44 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java @@ -1,10 +1,9 @@ package ru.yandex.practicum.filmorate.dao; -import org.springframework.http.ResponseEntity; - public interface FriendsDao { - ResponseEntity addToFriends(int idUser, int idFriend); + int addToFriends(int idUser, int idFriend); + + int removeToFriends(int idUser, int idFriend); - ResponseEntity removeToFriends(int idUser, int idFriend); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java deleted file mode 100644 index 43cbdb6..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/GenreDao.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.yandex.practicum.filmorate.dao; - -import ru.yandex.practicum.filmorate.model.Genres; - -import java.util.List; - -public interface GenreDao { - List getAll(); - - Genres getById(Integer id); -} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java index f4f8752..19e7358 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java @@ -1,9 +1,8 @@ package ru.yandex.practicum.filmorate.dao; -import org.springframework.http.ResponseEntity; - public interface LikesDao { - ResponseEntity addLike(int idFilm, int idUser); + int addLike(int idFilm, int idUser); + + int removeLike(int idFilm, int idUser); - ResponseEntity removeLike(int idFilm, int idUser); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java b/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java deleted file mode 100644 index d00982c..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/MpaDao.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.yandex.practicum.filmorate.dao; - -import ru.yandex.practicum.filmorate.model.MPA; - -import java.util.List; - -public interface MpaDao { - - List getAll(); - - MPA getById(Integer id); -} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java index bc9d343..8856af6 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java @@ -1,62 +1,30 @@ package ru.yandex.practicum.filmorate.dao.impl; import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.stereotype.Component; import ru.yandex.practicum.filmorate.dao.FriendsDao; -import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; -import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; -import ru.yandex.practicum.filmorate.storage.UserStorage; -@Slf4j @Component @AllArgsConstructor public class FriendsDaoImpl implements FriendsDao { private final JdbcTemplate jdbcTemplate; - private final UserStorage userStorage; @Override - public ResponseEntity addToFriends(int idUser, int idFriend) { - if (idUser == idFriend || contains(idUser, idFriend)) { - throw new IncorrectArgumentsException(FriendsDaoImpl.class); - } - if (!userStorage.contains(idUser) || !userStorage.contains(idFriend)) { - throw new EntityNotFoundException(FriendsDaoImpl.class); - } - - jdbcTemplate.update("INSERT INTO friends (id_user,id_friend) VALUES (?,?)", idUser, idFriend); - log.info("Пользователь c id={} успешно добавлен в друзья пользователю c id={}", idFriend, idUser); - - return new ResponseEntity<>(HttpStatus.OK); + public int addToFriends(int idUser, int idFriend) { + + return jdbcTemplate.update("INSERT INTO friends (id_user,id_friend) VALUES (?,?)", idUser, idFriend); + } @Override - public ResponseEntity removeToFriends(int idUser, int idFriend) { - if (idUser == idFriend || !contains(idUser, idFriend)) { - throw new IncorrectArgumentsException(FriendsDaoImpl.class); - } + public int removeToFriends(int idUser, int idFriend) { - if (!userStorage.contains(idUser) || !userStorage.contains(idFriend)) { - throw new EntityNotFoundException(FriendsDaoImpl.class); - } + return jdbcTemplate.update("DELETE FROM friends WHERE id_user = ? AND id_friend = ?", idUser, idFriend); - jdbcTemplate.update("DELETE FROM friends WHERE id_user = ? AND id_friend = ?", idUser, idFriend); - log.info("Пользователь c id={} успешно удален из друзей пользователя c id={}", idFriend, idUser); - - return new ResponseEntity<>(HttpStatus.OK); - } - private boolean contains(int idUser, int idFriend) { - SqlRowSet friendsRow = jdbcTemplate.queryForRowSet("SELECT 1 FROM friends " + - "WHERE id_user = ? AND id_friend = ?", - idUser, idFriend); - return friendsRow.next(); } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java index 1baed8a..2c7198b 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java @@ -1,61 +1,35 @@ package ru.yandex.practicum.filmorate.dao.impl; import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.stereotype.Component; import ru.yandex.practicum.filmorate.dao.LikesDao; -import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; -import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; -import ru.yandex.practicum.filmorate.storage.FilmStorage; -import ru.yandex.practicum.filmorate.storage.UserStorage; -@Slf4j @Component @AllArgsConstructor public class LikesDaoImpl implements LikesDao { private final JdbcTemplate jdbcTemplate; - private final UserStorage userStorage; - private final FilmStorage filmStorage; @Override - public ResponseEntity addLike(int idFilm, int idUser) { - if (contains(idFilm, idUser)) { - throw new IncorrectArgumentsException(LikesDaoImpl.class); - } - if (!filmStorage.contains(idFilm) || !userStorage.contains(idUser)) { - throw new EntityNotFoundException(LikesDaoImpl.class); - } - jdbcTemplate.update("INSERT INTO likes (id_user,id_film) VALUES (?,?)", idUser, idFilm); - jdbcTemplate.update("UPDATE films SET likes = likes + 1 WHERE id = ?", idFilm); - log.info("Пользователь c id={} оценил фильм c id={}", idUser, idFilm); - - return new ResponseEntity<>(HttpStatus.OK); + public int addLike(int idFilm, int idUser) { + int result = jdbcTemplate.update("INSERT INTO likes (id_user,id_film) VALUES (?,?)", idUser, idFilm); + if (result != 0) upDateLikesFromFilm(idFilm); + return result; } @Override - public ResponseEntity removeLike(int idFilm, int idUser) { - if (!userStorage.contains(idUser) || !filmStorage.contains(idFilm) || !contains(idFilm, idUser)) { - throw new EntityNotFoundException(LikesDaoImpl.class); - } - jdbcTemplate.update("DELETE FROM likes WHERE id_user = ? AND id_film = ?", idUser, idFilm); - jdbcTemplate.update("UPDATE films SET likes = likes - 1 WHERE id = ?", idFilm); - log.info("Пользователь c id={} удалил оценку с фильма c id={}", idUser, idFilm); - - return new ResponseEntity<>(HttpStatus.OK); + public int removeLike(int idFilm, int idUser) { + int result = jdbcTemplate.update("DELETE FROM likes WHERE id_user = ? AND id_film = ?", idUser, idFilm); + if (result != 0) upDateLikesFromFilm(idFilm); + return result; } - private boolean contains(int idFilm, int idUser) { - SqlRowSet likesRow = jdbcTemplate.queryForRowSet("SELECT 1 FROM likes " + - "WHERE id_user = ? AND id_film = ?", - idUser, idFilm); - return likesRow.next(); + private void upDateLikesFromFilm(int idFilm) { + String sqlQuery = "UPDATE films SET likes = (SELECT COUNT (id_user) FROM likes WHERE id_film = ?) where id = ?"; + jdbcTemplate.update(sqlQuery, idFilm, idFilm); } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java deleted file mode 100644 index 2875220..0000000 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/MpaDaoImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.yandex.practicum.filmorate.dao.impl; - -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.support.rowset.SqlRowSet; -import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.dao.MpaDao; -import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; -import ru.yandex.practicum.filmorate.model.MPA; - -import java.util.List; - -@Slf4j -@Component -@AllArgsConstructor -public class MpaDaoImpl implements MpaDao { - - private final JdbcTemplate jdbcTemplate; - - @Override - public List getAll() { - String sq = "SELECT * FROM mpa"; - log.info("Список возрастных рейтингов получен"); - return jdbcTemplate.query(sq, mpaRowMapper()); - } - - @Override - public MPA getById(Integer id) { - SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select * from mpa where id = ?", id); - if (filmRows.next()) { - String sq = "SELECT * FROM mpa WHERE id = ?"; - log.info("Возрастной рейтинг с id={} получен", id); - return jdbcTemplate.queryForObject(sq, mpaRowMapper(), id); - } else { - throw new EntityNotFoundException(MPA.class); - } - } - - private RowMapper mpaRowMapper() { - return (rs, rowNum) -> { - MPA mpa = new MPA(); - mpa.setId(rs.getInt("id")); - mpa.setName(rs.getString("name_mpa")); - return mpa; - }; - } -} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java index 4974376..0240f10 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java @@ -1,13 +1,11 @@ package ru.yandex.practicum.filmorate.dao.storageimpl; import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.model.Genres; import ru.yandex.practicum.filmorate.model.MPA; @@ -17,7 +15,6 @@ import java.sql.PreparedStatement; import java.util.*; -@Slf4j @Component @AllArgsConstructor public class FilmDbStorage implements FilmStorage { @@ -34,7 +31,6 @@ public class FilmDbStorage implements FilmStorage { @Override public List getAll() { - log.info("Список фильмов получен"); return new ArrayList<>(jdbcTemplate.query(sq, extractor()).values()); } @@ -73,52 +69,49 @@ public Film create(Film film) { gen.getId()); } } - log.info("Фильм с id={} успешно добавлен",film.getId()); return film; } @Override - public Film upDate(Film film) { - SqlRowSet filmsRows = jdbcTemplate.queryForRowSet("select * from films where id = ?", film.getId()); - if (filmsRows.next()) { - String sqlQuery = "UPDATE films SET name = ?," + - "description = ?," + - "release_date = ?," + - "duration = ?," + - "likes = ?," + - "mpa = ?" + - " WHERE id = ?"; - - jdbcTemplate.update(sqlQuery, - film.getName(), - film.getDescription(), - film.getReleaseDate(), - film.getDuration(), - film.getLikes(), - film.getMpa().getId(), - film.getId()); - - jdbcTemplate.update("DELETE FROM films_genres WHERE id_film = ?", film.getId()); - - if (!film.getGenres().isEmpty()) { - for (Genres gen : film.getGenres()) { - String sQuery = "INSERT INTO films_genres (id_film,id_genre) " + - "VALUES (?,?)"; - - jdbcTemplate.update(sQuery, - film.getId(), - gen.getId()); - } + public int upDate(Film film) { + String sqlQuery = "UPDATE films SET name = ?," + + "description = ?," + + "release_date = ?," + + "duration = ?," + + "likes = ?," + + "mpa = ?" + + " WHERE id = ?"; + + int result = jdbcTemplate.update(sqlQuery, + film.getName(), + film.getDescription(), + film.getReleaseDate(), + film.getDuration(), + film.getLikes(), + film.getMpa().getId(), + film.getId()); + + if (result == 0) { + return result; + } + + jdbcTemplate.update("DELETE FROM films_genres WHERE id_film = ?", film.getId()); + + if (!film.getGenres().isEmpty()) { + for (Genres gen : film.getGenres()) { + String sQuery = "INSERT INTO films_genres (id_film,id_genre) " + + "VALUES (?,?)"; + + jdbcTemplate.update(sQuery, + film.getId(), + gen.getId()); } - } else { - throw new EntityNotFoundException(FilmDbStorage.class); } - log.info("Фильм с id={} успешно изменен",film.getId()); - return film; + return result; } @Override - public boolean contains(Integer id) { + public boolean contains(int id) { SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select 1 from films where id = ?", id); return filmRows.next(); } @@ -126,26 +119,20 @@ public boolean contains(Integer id) { @Override public List getTopFilms(int limit) { String sqlQuery = sq + "ORDER BY likes DESC LIMIT ?"; - log.info("Получены {} наиболее популярных фильмов",limit); return new ArrayList<>(jdbcTemplate.query(sqlQuery, extractor(), limit).values()); } @Override - public Film getById(Integer id) { - if (contains(id)) { - String sqq = "SELECT fgm.id,fgm.name,fgm.description,fgm.release_date,fgm.duration,fgm.likes," + - "fgm.mpa,m.name_mpa,fgm.id_genre,fgm.name_genre " + - "FROM mpa AS m RIGHT JOIN (SELECT * FROM films AS f LEFT JOIN " + - "(SELECT fg.id_film,fg.id_genre,g.name_genre " + - "FROM films_genres AS fg LEFT JOIN genres AS g " + - "ON g.id=fg.id_genre ) " + - "ON f.id=id_film where f.id = ?) AS fgm ON m.id=mpa "; - Film film = jdbcTemplate.query(sqq, extractor(), id).get(id); - log.info("Фильм с id={} получен",film.getId()); - return film; - } else { - throw new EntityNotFoundException(FilmDbStorage.class); - } + public Film getById(int id) { + String sqq = "SELECT fgm.id,fgm.name,fgm.description,fgm.release_date,fgm.duration,fgm.likes," + + "fgm.mpa,m.name_mpa,fgm.id_genre,fgm.name_genre " + + "FROM mpa AS m RIGHT JOIN (SELECT * FROM films AS f LEFT JOIN " + + "(SELECT fg.id_film,fg.id_genre,g.name_genre " + + "FROM films_genres AS fg LEFT JOIN genres AS g " + + "ON g.id=fg.id_genre ) " + + "ON f.id=id_film where f.id = ?) AS fgm ON m.id=mpa "; + Film film = jdbcTemplate.query(sqq, extractor(), id).get(id); + return film; } private ResultSetExtractor> extractor() { diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/GenreDbStorage.java similarity index 55% rename from src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java rename to src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/GenreDbStorage.java index eac23ab..d36427d 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/impl/GenreDaoImpl.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/GenreDbStorage.java @@ -1,40 +1,38 @@ -package ru.yandex.practicum.filmorate.dao.impl; +package ru.yandex.practicum.filmorate.dao.storageimpl; import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.dao.GenreDao; -import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.storage.GenreStorage; import ru.yandex.practicum.filmorate.model.Genres; import java.util.List; -@Slf4j @Component @AllArgsConstructor -public class GenreDaoImpl implements GenreDao { +public class GenreDbStorage implements GenreStorage { private final JdbcTemplate jdbcTemplate; @Override public List getAll() { String sq = "SELECT * FROM genres"; - log.info("Список жанров получен"); return jdbcTemplate.query(sq, genreRowMapper()); } @Override - public Genres getById(Integer id) { + public Genres getById(int id) { + + String sq = "SELECT * FROM genres WHERE id = ?"; + return jdbcTemplate.queryForObject(sq, genreRowMapper(), id); + + } + + @Override + public boolean contains(int id) { SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select * from genres where id = ?", id); - if (filmRows.next()) { - String sq = "SELECT * FROM genres WHERE id = ?"; - log.info("Жанр с id={} получен", id); - return jdbcTemplate.queryForObject(sq, genreRowMapper(), id); - } else { - throw new EntityNotFoundException(Genres.class); - } + return filmRows.next(); } private RowMapper genreRowMapper() { diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/MpaDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/MpaDbStorage.java new file mode 100644 index 0000000..7587df8 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/MpaDbStorage.java @@ -0,0 +1,42 @@ +package ru.yandex.practicum.filmorate.dao.storageimpl; + +import lombok.AllArgsConstructor; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.storage.MpaStorage; +import ru.yandex.practicum.filmorate.model.MPA; + +import java.util.List; + +@Component +@AllArgsConstructor +public class MpaDbStorage implements MpaStorage { + + private final JdbcTemplate jdbcTemplate; + + @Override + public List getAll() { + String sq = "SELECT * FROM mpa"; + return jdbcTemplate.query(sq, mpaRowMapper()); + } + + @Override + public MPA getById(int id) { + String sq = "SELECT * FROM mpa WHERE id = ?"; + return jdbcTemplate.queryForObject(sq, mpaRowMapper(), id); + + } + + @Override + public boolean contains(int id) { + SqlRowSet filmRows = jdbcTemplate.queryForRowSet("select * from mpa where id = ?", id); + return filmRows.next(); + } + + private RowMapper mpaRowMapper() { + return (rs, rowNum) -> new MPA(rs.getInt("id"), + rs.getString("name_mpa")); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java index bf2a16b..faa8782 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/UserDbStorage.java @@ -1,14 +1,11 @@ package ru.yandex.practicum.filmorate.dao.storageimpl; import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.stereotype.Component; -import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; -import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.storage.UserStorage; @@ -16,7 +13,6 @@ import java.sql.PreparedStatement; import java.util.*; -@Slf4j @Component @AllArgsConstructor public class UserDbStorage implements UserStorage { @@ -25,7 +21,6 @@ public class UserDbStorage implements UserStorage { @Override public List getAll() { - log.info("Список пользователей получен"); return jdbcTemplate.query("SELECT * FROM mov_users", userRowMapper()); } @@ -50,84 +45,58 @@ public User create(User user) { user.setId(keyHolder.getKey().intValue()); - log.info("Пользователь с id={} добавлен",user.getId()); return user; } @Override - public User upDate(User user) { - SqlRowSet usersRows = jdbcTemplate.queryForRowSet("SELECT * FROM mov_users WHERE id = ?", user.getId()); - if (usersRows.next()) { - String sqlQuery = "UPDATE mov_users SET " + - "email = ?," + - "login = ?," + - "name = ?," + - "birthday = ?" + - " WHERE id = ?"; - - jdbcTemplate.update(sqlQuery, - user.getEmail(), - user.getLogin(), - user.getName(), - user.getBirthday(), - user.getId()); - - log.info("Пользователь c id={} успешно изменен",user.getId()); - return user; - } else { - throw new EntityNotFoundException(UserDbStorage.class); - } + public int upDate(User user) { + String sqlQuery = "UPDATE mov_users SET " + + "email = ?," + + "login = ?," + + "name = ?," + + "birthday = ?" + + " WHERE id = ?"; + + int result = jdbcTemplate.update(sqlQuery, + user.getEmail(), + user.getLogin(), + user.getName(), + user.getBirthday(), + user.getId()); + return result; } + @Override - public User getById(Integer id) { - if (contains(id)) { - String sql = "SELECT * FROM mov_users WHERE id = ?"; - User user = jdbcTemplate.queryForObject(sql, userRowMapper(), id); - log.info("Пользователь с id={} получен",id); - return user; - } else { - throw new EntityNotFoundException(UserDbStorage.class); - } + public User getById(int id) { + String sql = "SELECT * FROM mov_users WHERE id = ?"; + User user = jdbcTemplate.queryForObject(sql, userRowMapper(), id); + return user; + } @Override - public boolean contains(Integer id) { + public boolean contains(int id) { SqlRowSet userRows = jdbcTemplate.queryForRowSet("select 1 from mov_users where id = ?", id); return userRows.next(); } @Override - public List getAllFriends(Integer id) { - if (contains(id)) { + public List getAllFriends(int id) { - String sql = "SELECT * FROM mov_users WHERE id IN (SELECT id_friend FROM friends WHERE id_user = ?)"; + String sql = "SELECT * FROM mov_users WHERE id IN (SELECT id_friend FROM friends WHERE id_user = ?)"; - log.info("Список друзей пользователя c id={} получен",id); - return jdbcTemplate.query(sql, userRowMapper(), id); - } else { - throw new EntityNotFoundException(UserDbStorage.class); - } + return jdbcTemplate.query(sql, userRowMapper(), id); } @Override - public List getMutualFriends(Integer idUser, Integer otherIdUser) { - if (idUser.equals(otherIdUser)) { - throw new IncorrectArgumentsException(UserDbStorage.class); - } - if (!contains(idUser)) { - throw new EntityNotFoundException(UserDbStorage.class); - } - if (!contains(otherIdUser)) { - throw new EntityNotFoundException(UserDbStorage.class); - } + public List getMutualFriends(int idUser, int otherIdUser) { String sqlQuery = "SELECT * FROM mov_users WHERE id IN (SELECT id_friend FROM friends " + "WHERE id_user=" + otherIdUser + " AND id_friend IN (SELECT id_friend " + "FROM friends " + "WHERE id_user =" + idUser + "))"; - log.info("Список общих друзей пользователей c id={} и c id={} получен",idUser,otherIdUser); return jdbcTemplate.query(sqlQuery, userRowMapper()); } @@ -143,9 +112,4 @@ private RowMapper userRowMapper() { return user; }; } - - private RowMapper mapper(String nameColumn) { - return (rs, rowNum) -> rs.getInt(nameColumn); - } - } 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 ae0df61..4306f1c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -32,9 +32,9 @@ public class Film { @JsonIgnore private int likes; - Set genres = new TreeSet<>(); + private Set genres = new TreeSet<>(); @NotNull - MPA mpa; + private MPA mpa; } diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/MPA.java b/src/main/java/ru/yandex/practicum/filmorate/model/MPA.java index 68c48b3..9959e8f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/MPA.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/MPA.java @@ -8,7 +8,4 @@ public class MPA { private int id; private String name; - - public MPA() { - } } 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 5604360..02a5ca1 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -1,48 +1,79 @@ package ru.yandex.practicum.filmorate.service; import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import ru.yandex.practicum.filmorate.dao.LikesDao; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.storage.FilmStorage; +import ru.yandex.practicum.filmorate.storage.UserStorage; import java.util.List; +@Slf4j @Service @RequiredArgsConstructor public class FilmService { private final FilmStorage filmStorage; + private final UserStorage userStorage; + private final LikesDao likesDao; public List findAll() { + log.info("Список фильмов получен"); return filmStorage.getAll(); } - public Film findById(Integer id) { - return filmStorage.getById(id); + public Film findById(int id) { + if (filmStorage.contains(id)) { + log.info("Фильм с id={} получен", id); + return filmStorage.getById(id); + } else { + throw new EntityNotFoundException(FilmService.class); + } } public List findTopFilms(int limit) { + log.info("Получены {} наиболее популярных фильмов", limit); return filmStorage.getTopFilms(limit); } public Film create(Film film) { + log.info("Фильм с id={} успешно добавлен", film.getId()); return filmStorage.create(film); } public Film upDate(Film film) { - return filmStorage.upDate(film); + int result = filmStorage.upDate(film); + if (result == 0) { + throw new EntityNotFoundException(FilmService.class); + } else { + log.info("Фильм с id={} успешно изменен", film.getId()); + return film; + } } - public ResponseEntity addLike(Integer idFilm, Integer idUser) { - return likesDao.addLike(idFilm, idUser); + public void addLike(int idFilm, int idUser) { + int result = likesDao.addLike(idFilm, idUser); + if (result == 0) { + throw new IncorrectArgumentsException(FilmService.class); + } + if (!filmStorage.contains(idFilm) || !userStorage.contains(idUser)) { + throw new EntityNotFoundException(FilmService.class); + } + log.info("Пользователь c id={} оценил фильм c id={}", idUser, idFilm); } - public ResponseEntity removeLike(Integer idFilm, Integer idUser) { - return likesDao.removeLike(idFilm, idUser); + public void removeLike(int idFilm, int idUser) { + int result = likesDao.removeLike(idFilm, idUser); + if (!userStorage.contains(idUser) || !filmStorage.contains(idFilm) || result == 0) { + throw new EntityNotFoundException(FilmService.class); + } + log.info("Пользователь c id={} удалил оценку с фильма c id={}", idUser, idFilm); } } 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..c88eb92 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/GenreService.java @@ -0,0 +1,32 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.storage.GenreStorage; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.model.Genres; + +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class GenreService { + + private final GenreStorage genreStorage; + + public List findAll() { + log.info("Список жанров получен"); + return genreStorage.getAll(); + } + + public Genres findById(int id) { + if (genreStorage.contains(id)) { + log.info("Жанр с id={} получен", id); + return genreStorage.getById(id); + } else { + throw new EntityNotFoundException(GenreService.class); + } + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/MpaService.java b/src/main/java/ru/yandex/practicum/filmorate/service/MpaService.java new file mode 100644 index 0000000..f087fec --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/MpaService.java @@ -0,0 +1,31 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.storage.MpaStorage; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.model.MPA; + +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class MpaService { + private final MpaStorage mpaStorage; + + public List findAll() { + log.info("Список возрастных рейтингов получен"); + return mpaStorage.getAll(); + } + + public MPA findById(int id) { + if (mpaStorage.contains(id)) { + log.info("Возрастной рейтинг с id={} получен", id); + return mpaStorage.getById(id); + } else { + throw new EntityNotFoundException(MpaService.class); + } + } +} 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 4f6f6ac..bdf302c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -3,9 +3,11 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import ru.yandex.practicum.filmorate.dao.FriendsDao; +import ru.yandex.practicum.filmorate.dao.storageimpl.UserDbStorage; +import ru.yandex.practicum.filmorate.exception.EntityNotFoundException; +import ru.yandex.practicum.filmorate.exception.IncorrectArgumentsException; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.storage.UserStorage; @@ -21,35 +23,77 @@ public class UserService { private final FriendsDao friendsDao; public List findAll() { + log.info("Список пользователей получен"); return userStorage.getAll(); } - public User findById(Integer id) { - - return userStorage.getById(id); + public User findById(int id) { + if (userStorage.contains(id)) { + log.info("Пользователь с id={} получен", id); + return userStorage.getById(id); + } else { + throw new EntityNotFoundException(UserDbStorage.class); + } } - public List findAllFriends(Integer id) { - return userStorage.getAllFriends(id); + public List findAllFriends(int id) { + if (userStorage.contains(id)) { + log.info("Список друзей пользователя c id={} получен", id); + return userStorage.getAllFriends(id); + } else { + throw new EntityNotFoundException(UserDbStorage.class); + } } - public List findMutualFriends(Integer idUser, Integer otherIdUser) { + public List findMutualFriends(int idUser, int otherIdUser) { + if (idUser == otherIdUser) { + throw new IncorrectArgumentsException(UserService.class); + } + if (!userStorage.contains(idUser)) { + throw new EntityNotFoundException(UserService.class); + } + if (!userStorage.contains(otherIdUser)) { + throw new EntityNotFoundException(UserService.class); + } + log.info("Список общих друзей пользователей c id={} и c id={} получен", idUser, otherIdUser); return userStorage.getMutualFriends(idUser, otherIdUser); } - public ResponseEntity addToFriends(Integer idUser, Integer idFriend) { + public void addToFriends(int idUser, int idFriend) { + if (!userStorage.contains(idUser) || !userStorage.contains(idFriend)) { + throw new EntityNotFoundException(UserService.class); + } + + int result = friendsDao.addToFriends(idUser, idFriend); + + if (idUser == idFriend || result == 0) { + throw new IncorrectArgumentsException(UserService.class); + } - return friendsDao.addToFriends(idUser, idFriend); + log.info("Пользователь c id={} успешно добавлен в друзья пользователю c id={}", idFriend, idUser); } - public ResponseEntity removeToFriends(Integer idUser, Integer idFriend) { - return friendsDao.removeToFriends(idUser, idFriend); + public void removeToFriends(int idUser, int idFriend) { + + if (!userStorage.contains(idUser) || !userStorage.contains(idFriend)) { + throw new EntityNotFoundException(UserService.class); + } + + int result = friendsDao.removeToFriends(idUser, idFriend); + + if (idUser == idFriend || result == 0) { + throw new IncorrectArgumentsException(UserService.class); + } + + log.info("Пользователь c id={} успешно удален из друзей пользователя c id={}", idFriend, idUser); + } public User create(User user) { if (StringUtils.isEmpty(user.getName())) { user.setName(user.getLogin()); } + log.info("Пользователь с id={} добавлен", user.getId()); return userStorage.create(user); } @@ -57,6 +101,13 @@ public User upDate(User user) { if (StringUtils.isEmpty(user.getName())) { user.setName(user.getLogin()); } - return userStorage.upDate(user); + + int result = userStorage.upDate(user); + + if (result == 0) { + throw new EntityNotFoundException(UserService.class); + } + log.info("Пользователь c id={} успешно изменен", user.getId()); + return user; } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java index 8f34844..4c913aa 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -11,13 +11,13 @@ public interface FilmStorage { Film create(Film film); - Film upDate(Film film); + int upDate(Film film); - boolean contains(Integer id); + boolean contains(int id); List getTopFilms(int limit); - Film getById(Integer id); + Film getById(int id); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java new file mode 100644 index 0000000..4912a49 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/GenreStorage.java @@ -0,0 +1,13 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.Genres; + +import java.util.List; + +public interface GenreStorage { + List getAll(); + + Genres getById(int id); + + boolean contains(int id); +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java new file mode 100644 index 0000000..65cc92b --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/MpaStorage.java @@ -0,0 +1,14 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.MPA; + +import java.util.List; + +public interface MpaStorage { + + List getAll(); + + MPA getById(int id); + + boolean contains(int id); +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java index 6a1f0ac..37bc22d 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -10,13 +10,13 @@ public interface UserStorage { User create(User user); - User upDate(User user); + int upDate(User user); - User getById(Integer id); + User getById(int id); - boolean contains(Integer id); + boolean contains(int id); - List getAllFriends(Integer id); + List getAllFriends(int id); - List getMutualFriends(Integer idUser, Integer otherIdUser); + List getMutualFriends(int idUser, int otherIdUser); } diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 086e841..84f8470 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -6,8 +6,8 @@ import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; -import ru.yandex.practicum.filmorate.dao.GenreDao; -import ru.yandex.practicum.filmorate.dao.MpaDao; +import ru.yandex.practicum.filmorate.storage.GenreStorage; +import ru.yandex.practicum.filmorate.storage.MpaStorage; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.model.Genres; import ru.yandex.practicum.filmorate.model.MPA; @@ -30,9 +30,9 @@ class FilmorateApplicationTests { private final UserService userService; private final FilmService filmService; - private final GenreDao genreDao; + private final GenreStorage genreDao; - private final MpaDao mpaDao; + private final MpaStorage mpaDao; private User newUser(Integer n) { User user = new User();