Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Filmorate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
<description>filmorate</description>
<properties>
<java.version>21</java.version>
<maven-checkstyle-plugin.version>3.3.1</maven-checkstyle-plugin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -49,6 +51,23 @@
<artifactId>logbook-spring-boot-starter</artifactId>
<version>3.7.2</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -57,6 +76,28 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>

<configuration>
<failOnViolation>true</failOnViolation>
<logViolationsToConsole>true</logViolationsToConsole>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<configLocation>checkstyle.xml</configLocation>
</configuration>

<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,67 +1,68 @@
package ru.yandex.practicum.filmorate.controller;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.service.FilmService;
import ru.yandex.practicum.filmorate.storage.FilmStorage;

import java.util.Collection;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/films")
public class FilmController {

private final FilmStorage inMemoryFilmStorage;
private final FilmService filmService;

@Autowired
public FilmController(FilmStorage inMemoryFilmStorage, FilmService filmService) {
this.inMemoryFilmStorage = inMemoryFilmStorage;
this.filmService = filmService;
}
private final FilmService service;

@GetMapping
public Collection<Film> findAll() {
log.info("Список фильмов выведен");
return inMemoryFilmStorage.findAll();
return service.findAll();
}

@GetMapping("/{id}")
public Film findById(@PathVariable("id") int filmId) {
log.info("Фильм с id: {} выведен", filmId);
return inMemoryFilmStorage.findFilmById(filmId);
public Film findById(@PathVariable @Positive int id) {
log.info("Фильм с id: {} выведен", id);
return service.findFilmById(id);
}

@GetMapping("/popular")
public Collection<Film> getPopular(@RequestParam(defaultValue = "10") int count) {
public Collection<Film> getPopular(@RequestParam(defaultValue = "10") @Positive int count) {
log.info("Список популярных фильмов выведен");
return filmService.getPopular(count);
return service.getPopular(count);
}

@PostMapping
public Film create(@RequestBody Film film) {
public Film create(@Valid @RequestBody Film film) {
log.info("Фильм: {} добавлен в базу", film);
return inMemoryFilmStorage.create(film);
return service.create(film);
}

@PutMapping
public Film update(@RequestBody Film newFilm) {
public Film update(@Valid @RequestBody Film newFilm) {
log.info("Данные о фильме: {} обновлены", newFilm);
return inMemoryFilmStorage.update(newFilm);
return service.update(newFilm);
}

@PutMapping("/{id}/like/{userId}")
public void addLike(@PathVariable int id, @PathVariable int userId) {
public Film addLike(@Positive @PathVariable int id, @Positive @PathVariable int userId) {
log.info("Фильму с id: {} поставил лайк пользователь с id: {}", id, userId);
filmService.addLike(id, userId);
return service.addLike(id, userId);
}

@DeleteMapping("/{id}/like/{userId}")
public void deleteLike(@PathVariable int id, @PathVariable int userId) {
public Film deleteLike(@Positive @PathVariable int id, @Positive @PathVariable int userId) {
log.info("У фильма с id: {} убрал лайк пользователь с id: {}", id, userId);
filmService.deleteLike(id, userId);
return service.deleteLike(id, userId);
}

@DeleteMapping("/{id}")
public void remove(@PathVariable @Positive int id) {
log.info("Фильм с id: {} удален", id);
service.remove(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ru.yandex.practicum.filmorate.controller;

import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.model.Genre;
import ru.yandex.practicum.filmorate.service.GenreService;

import java.util.Collection;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/genres")
public class GenreController {

private final GenreService service;

@GetMapping
public Collection<Genre> findAll() {
log.info("Список жанров выведен");
return service.findAll();
}

@GetMapping("/{id}")
public Genre findGenreById(@Positive @PathVariable("id") int id) {
log.info("Жанр с id: {} выведен", id);
return service.findGenreById(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ru.yandex.practicum.filmorate.controller;

import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.yandex.practicum.filmorate.model.Rating;
import ru.yandex.practicum.filmorate.service.RatingService;

import java.util.Collection;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/mpa")
public class RatingController {

private final RatingService service;

@GetMapping
public Collection<Rating> findAll() {
log.info("Список рейтингов выведен");
return service.findAll();
}

@GetMapping("/{id}")
public Rating findRatingById(@Positive @PathVariable("id") int id) {
log.info("Рейтинг с id: {} выведен", id);
return service.findRatingById(id);
}
}
Original file line number Diff line number Diff line change
@@ -1,71 +1,74 @@
package ru.yandex.practicum.filmorate.controller;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.service.UserService;
import ru.yandex.practicum.filmorate.storage.InMemoryUserStorage;

import java.util.Collection;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/users")
public class UserController {

private final InMemoryUserStorage inMemoryUserStorage;
private final UserService userService;

public UserController(InMemoryUserStorage inMemoryUserStorage, UserService userService) {
this.inMemoryUserStorage = inMemoryUserStorage;
this.userService = userService;
}
private final UserService service;

@GetMapping
public Collection<User> findAll() {
log.info("Список пользователей выведен");
return inMemoryUserStorage.findAll();
return service.findAll();
}

@GetMapping("/{id}")
public User findUserById(@PathVariable("id") int userId) {
log.info("Пользователь с id: {} выведен", userId);
return inMemoryUserStorage.findUserById(userId);
public User findUserById(@Positive @PathVariable int id) {
log.info("Пользователь с id: {} выведен", id);
return service.findUserById(id);
}

@GetMapping("/{id}/friends")
public Collection<User> findAllFriends(@PathVariable("id") int userId) {
public Collection<User> findAllFriends(@Positive @PathVariable("id") int userId) {
log.info("Список друзей пользователя с id: {} выведен", userId);
return userService.getFriendList(userId);
return service.getFriendList(userId);
}

@GetMapping("/{id}/friends/common/{otherId}")
public Collection<User> findAllCommonFriends(@PathVariable int id, @PathVariable int otherId) {
public Collection<User> findAllCommonFriends(@Positive @PathVariable int id, @Positive @PathVariable int otherId) {
log.info("Список общих друзей пользователей с id: {} и {} выведен", id, otherId);
return userService.getCommonFriendList(id, otherId);
return service.getCommonFriendList(id, otherId);
}

@PostMapping
public User create(@RequestBody User user) {
public User create(@Valid @RequestBody User user) {
log.info("Пользоввтель: {} создан и добавлен", user);
return inMemoryUserStorage.create(user);
return service.create(user);
}

@PutMapping
public User update(@RequestBody User newUser) {
public User update(@Valid @RequestBody User newUser) {
log.info("Данные о пользователе: {} обновлены", newUser);
return inMemoryUserStorage.update(newUser);
return service.update(newUser);
}

@PutMapping("/{id}/friends/{friendId}")
public void addFriend(@PathVariable("id") int userId, @PathVariable int friendId) {
log.info("Пользователь с id: {} добавил пользователя с id: {} в друзья", userId, friendId);
userService.addFriend(userId, friendId);
service.addFriend(userId, friendId);
}

@DeleteMapping("/{id}/friends/{friendId}")
public void deleteFriend(@PathVariable("id") int userId, @PathVariable int friendId) {
log.info("Пользователь с id: {} удалил пользователя с id: {} из друзей", userId, friendId);
userService.deleteFriend(userId, friendId);
service.deleteFriend(userId, friendId);
}

@DeleteMapping("/{id}")
public void remove(@Positive @PathVariable int id) {
log.info("Пользователь с id: {} удален", id);
service.remove(id);
}
}
69 changes: 69 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/dao/BaseDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package ru.yandex.practicum.filmorate.dao;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import ru.yandex.practicum.filmorate.exception.InternalServerException;

import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.List;

public abstract class BaseDao<T> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отлично, что сделал базовый абстрактный класс, @Repository лишний на нем, т.к. экземпляр не будет никогда создаваться.

protected final JdbcTemplate jdbc;
protected final NamedParameterJdbcTemplate namedJdbc;
protected final RowMapper<T> mapper;

public BaseDao(JdbcTemplate jdbc, RowMapper<T> mapper) {
this.jdbc = jdbc;
this.namedJdbc = new NamedParameterJdbcTemplate(jdbc);
this.mapper = mapper;
}

protected T get(String query, Object... params) {
return jdbc.queryForObject(query, mapper, params);
}

public List<T> getAll(String query, Object... params) {
return jdbc.query(query, mapper, params);
}

public void delete(String query, Integer id) {
jdbc.update(query, id);
}

public void update(String query, Object...params) {
int rowsUpdated = jdbc.update(query, params);
if (rowsUpdated == 0) {
try {
throw new InternalServerException("Не удалось обновить данные");
} catch (InternalServerException e) {
throw new RuntimeException(e);
}
}
}

public int insert(String query, Object... params) {
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
jdbc.update(connection -> {
PreparedStatement ps = connection
.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
for (int idx = 0; idx < params.length; idx++) {
ps.setObject(idx + 1, params[idx]);
}
return ps; }, keyHolder);

Integer id = keyHolder.getKeyAs(Integer.class);

if (id != null) {
return id;
} else {
try {
throw new InternalServerException("Не удалось сохранить данные");
} catch (InternalServerException e) {
throw new RuntimeException(e);
}
}
}
}
Loading