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..7643b28 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java
@@ -39,13 +39,13 @@ public Film getById(@PathVariable Integer id) {
}
@PutMapping("/{id}/like/{userId}")
- public Film 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 Film 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
new file mode 100644
index 0000000..f86f18e
--- /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.service.GenreService;
+import ru.yandex.practicum.filmorate.model.Genres;
+
+import java.util.List;
+
+@RequestMapping("/genres")
+@RestController
+@RequiredArgsConstructor
+public class GenreController {
+
+ private final GenreService genreService;
+
+ @GetMapping()
+ public List findAllGenres() {
+ return genreService.findAll();
+ }
+
+ @GetMapping("/{id}")
+ public Genres getGenresById(@PathVariable Integer 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
new file mode 100644
index 0000000..56eec6c
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/controller/MPAController.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.model.MPA;
+import ru.yandex.practicum.filmorate.service.MpaService;
+
+import java.util.List;
+
+@RequestMapping("/mpa")
+@RestController
+@RequiredArgsConstructor
+public class MPAController {
+
+ private final MpaService mpaService;
+
+ @GetMapping()
+ public List findAllMpa() {
+ return mpaService.findAll();
+ }
+
+ @GetMapping("/{id}")
+ public MPA getByIdMpa(@PathVariable Integer 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 855edd8..825b121 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java
@@ -40,13 +40,13 @@ public User findById(@PathVariable Integer id) {
}
@PutMapping("/{id}/friends/{friendId}")
- public User 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 User 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
new file mode 100644
index 0000000..59ccb44
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/dao/FriendsDao.java
@@ -0,0 +1,9 @@
+package ru.yandex.practicum.filmorate.dao;
+
+public interface FriendsDao {
+
+ int addToFriends(int idUser, int idFriend);
+
+ int removeToFriends(int idUser, int idFriend);
+
+}
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..19e7358
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/dao/LikesDao.java
@@ -0,0 +1,8 @@
+package ru.yandex.practicum.filmorate.dao;
+
+public interface LikesDao {
+ int addLike(int idFilm, int idUser);
+
+ int removeLike(int idFilm, int idUser);
+
+}
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..8856af6
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/FriendsDaoImpl.java
@@ -0,0 +1,30 @@
+package ru.yandex.practicum.filmorate.dao.impl;
+
+import lombok.AllArgsConstructor;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Component;
+import ru.yandex.practicum.filmorate.dao.FriendsDao;
+
+
+@Component
+@AllArgsConstructor
+public class FriendsDaoImpl implements FriendsDao {
+
+ private final JdbcTemplate jdbcTemplate;
+
+ @Override
+ public int addToFriends(int idUser, int idFriend) {
+
+ return jdbcTemplate.update("INSERT INTO friends (id_user,id_friend) VALUES (?,?)", idUser, idFriend);
+
+ }
+
+ @Override
+ public int removeToFriends(int idUser, int idFriend) {
+
+ return jdbcTemplate.update("DELETE FROM friends WHERE id_user = ? AND id_friend = ?", idUser, idFriend);
+
+
+ }
+
+}
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..2c7198b
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/dao/impl/LikesDaoImpl.java
@@ -0,0 +1,35 @@
+package ru.yandex.practicum.filmorate.dao.impl;
+
+import lombok.AllArgsConstructor;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Component;
+import ru.yandex.practicum.filmorate.dao.LikesDao;
+
+@Component
+@AllArgsConstructor
+public class LikesDaoImpl implements LikesDao {
+
+ private final JdbcTemplate jdbcTemplate;
+
+
+ @Override
+ 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 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 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/storageimpl/FilmDbStorage.java b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java
new file mode 100644
index 0000000..0240f10
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/dao/storageimpl/FilmDbStorage.java
@@ -0,0 +1,170 @@
+package ru.yandex.practicum.filmorate.dao.storageimpl;
+
+import lombok.AllArgsConstructor;
+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.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.*;
+
+@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() {
+ 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());
+ }
+ }
+ return film;
+ }
+
+ @Override
+ 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());
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean contains(int 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 ?";
+ return new ArrayList<>(jdbcTemplate.query(sqlQuery, extractor(), limit).values());
+ }
+
+ @Override
+ 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