Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0db63fe
Добавляем базу данных.
andrej1307 Jan 19, 2025
20d0830
исправление стиля.
andrej1307 Jan 19, 2025
a1f5cb0
исправление стиля.
andrej1307 Jan 19, 2025
50c1779
исправление стиля.
andrej1307 Jan 19, 2025
5ded6e4
Обновлена схема базы данных.
andrej1307 Jan 23, 2025
25fd5a1
Обновлена схема базы данных.
andrej1307 Jan 23, 2025
67844a9
Реализована работа с пользователями - UserDbStorage.java
andrej1307 Jan 23, 2025
1bf776b
Оптимизирована работа с фильмами - InMemoryFilmStorage
andrej1307 Jan 24, 2025
334a5bb
Реализована работа с базой данных.
andrej1307 Feb 12, 2025
1b7aecb
Postman - OK
andrej1307 Feb 16, 2025
cdc56f1
Пишем тесты 1
andrej1307 Feb 18, 2025
ba38e62
Пишем тесты 2
andrej1307 Feb 19, 2025
cdf3648
Реализован класс: UserDbStorageTest.java
andrej1307 Feb 20, 2025
8e6bf03
Пишем тесты 3.
andrej1307 Feb 23, 2025
027cfbb
Реализованы тесты.
andrej1307 Feb 24, 2025
96b6cb3
Исправляем ошибки стиля.
andrej1307 Feb 24, 2025
364aa01
Исправляем замечания ревьювера.
andrej1307 Feb 26, 2025
82955eb
Исправляем ошибки стиля.
andrej1307 Feb 26, 2025
2270e02
Добавлена валидация параметра 'count' в методе FilmController.findPop…
andrej1307 Feb 26, 2025
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
58 changes: 54 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,58 @@
Учебный проект.
Созданиие приложений на основе шаблона "Spring"<br>

## Спринт 10
Добавляем контроллеры фильмов и пользователей.<br>
## Спринт 12
Добавляем базу данных.
![схема базы данных](/schema.png)

## Спринт 11
Добавляем работу с "друзьями" и "лайками"
### Описание таблиц базы данных

1. **users** - таблица описания пользователей.<br>
поля:
- первичный ключ *id* - идентификатор подьзователя;
- *email* - адрес электронно почты пользователя;
- *login* - логин пользоателя;
- *name* - имя пользователя;
- *birthday* - дата рождения пользователя;

<br>
2. **friends** - таблица связи с "друзьями" пользователя.<br>
поля:
- *user_id* - идентификатор пользователя (отсылает к таблице *users*) - идентификатор пользователя;
- *friend_id* - идентификатор друга (отсылает к таблице *users*) - идентификатор пользователя;
- *confirmed* - флаг подтвержденной дружбы (если "дружба" двусторонняя);

<br>
3. **genre** - таблица описания жанро фильма.<br>
поля:
- первичный ключ *id* - идентификатор жанра;
- *name* - наименование жанра;

<br>
4. **MPA** - таблица описания рейтингов Ассоциации кинокомпаний (MPA).<br>
поля:
- первичный ключ *id* - идентификатор рейтинга;
- *name* - буквенный код рейтинга (G, PG, PG-13, R, NC-17);
- *description* - описание рейтинга;

<br>
5. **films** - таблица описания фильмов. <br>
поля:
- первичный ключ *id* - идентификатор фильма;
- *name* - название фильма;
- *description* - описание фильма;
- *releaseDAte* - бата выпуска фильма;
- *len_min* - длительность фильма в минутах;
- *MPA_id* -рейтинг MPA. (отсылает к таблице *MPA*) - идентификатор рейтинга;

<br>
6. **film_genre** - таблица определения жанров фильма.<br>
поля:
- *film_id* - идентификатор фильма (отсылает к таблице *films*);
- *genre_id* - идентификатор жанра (отсылает к таблице *genre*);

<br>
7. **likes** - таблица "лайков" пользователей.<br>
поля:
- *user_id* - идентификатор пользователя (отсылает к таблице *users*);
- *film_id* - идентификатор фильма (отсылает к таблице *films*);
24 changes: 19 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<version>3.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>ru.yandex.practicum</groupId>
Expand All @@ -17,26 +17,40 @@
<java.version>21</java.version>
</properties>
<dependencies>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.3.232</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.4.1</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>3.4.1</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>3.4.2</version>
</dependency>

<dependency>
Expand Down
Binary file added schema.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
@SpringBootApplication
public class FilmorateApplication {

/**
* Запуск приложения.
*
* @param args - параметры запуска.
*/
public static void main(final String[] args) {
SpringApplication.run(FilmorateApplication.class, args);
}
/**
* Запуск приложения.
*
* @param args - параметры запуска.
*/
public static void main(final String[] args) {
SpringApplication.run(FilmorateApplication.class, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
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;
import ru.yandex.practicum.filmorate.exception.InternalServerException;
import ru.yandex.practicum.filmorate.exception.NotFoundException;
import ru.yandex.practicum.filmorate.exception.ValidationException;
import ru.yandex.practicum.filmorate.model.ErrorMessage;
import ru.yandex.practicum.filmorate.model.ValidationErrorResponse;
import ru.yandex.practicum.filmorate.model.Violation;
import ru.yandex.practicum.filmorate.validator.ValidationErrorResponse;
import ru.yandex.practicum.filmorate.validator.Violation;

import java.util.List;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -85,6 +87,13 @@ public ErrorMessage notFoundObject(NotFoundException exception) {
return new ErrorMessage(exception.getMessage());
}

@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorMessage notFoundData(DataAccessException exception) {
return new ErrorMessage(exception.getMessage());
}


/**
* Обработка исключения HttpMessageNotReadableException при поступлении пустого запроса
*
Expand All @@ -101,6 +110,14 @@ public ResponseEntity<ErrorMessage> onHttpMessageNotReadableException(
.body(new ErrorMessage("В запросе отсутствуют необходимые данные."));
}


@ExceptionHandler
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorMessage internalException(final InternalServerException e) {
log.warn("Error", e);
return new ErrorMessage(e.getMessage());
}

/**
* Обработка непредвиденного исключения
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package ru.yandex.practicum.filmorate.controller;

import jakarta.validation.constraints.Min;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.model.Marker;
import ru.yandex.practicum.filmorate.service.FilmService;
import ru.yandex.practicum.filmorate.validator.Marker;

import java.util.Collection;
import java.util.Map;
Expand Down Expand Up @@ -52,7 +53,7 @@ public Film findFilm(@PathVariable Integer id) {
}

@GetMapping("/popular")
public Collection<Film> findPopularFilms(@RequestParam(defaultValue = "10") int count) {
public Collection<Film> findPopularFilms(@RequestParam(defaultValue = "10") @Min(1) int count) {
log.info("Ищем популярные {} фильмов.", count);
return service.findPopularFilms(count);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ru.yandex.practicum.filmorate.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.Genre;
import ru.yandex.practicum.filmorate.service.GenreService;

import java.util.Collection;

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

private final GenreService genreService;

public GenreController(GenreService genreService) {
this.genreService = genreService;
}

@GetMapping
@ResponseStatus(HttpStatus.OK)
public Collection<Genre> findAllGenres() {
log.info("Запрашиваем список всех жанров.");
return genreService.getAllGenres();
}

@GetMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public Genre findGenreById(@PathVariable int id) {
log.info("Ищем жанр id={}.", id);
return genreService.getGenreById(id);
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ru.yandex.practicum.filmorate.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.Mpa;
import ru.yandex.practicum.filmorate.service.MpaService;

import java.util.Collection;

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

private final MpaService mpaService;

public MpaController(MpaService mpaService) {
this.mpaService = mpaService;
}

@GetMapping
@ResponseStatus(HttpStatus.OK)
public Collection<Mpa> findAllMpa() {
log.info("Запрашиваем список всех рейтинков MPA.");
return mpaService.filndAllMpa();
}

@GetMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public Mpa findMpaById(@PathVariable int id) {
log.info("Ищем рейтинг id={}.", id);
return mpaService.findMpa(id);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.model.Marker;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.service.UserService;
import ru.yandex.practicum.filmorate.validator.Marker;

import java.util.Collection;

Expand Down Expand Up @@ -59,7 +59,7 @@ public User findUser(@PathVariable Integer id) {
@GetMapping("/{id}/friends")
public Collection<User> findUsersFriends(@PathVariable Integer id) {
log.info("Ищем друзей пользователя id={}.", id);
return service.getUsersFriends(id);
return service.getUserFriends(id);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.yandex.practicum.filmorate.exception;

public class InternalServerException extends RuntimeException {
public InternalServerException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ru.yandex.practicum.filmorate.mapper;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import ru.yandex.practicum.filmorate.model.FilmGenre;

import java.sql.ResultSet;
import java.sql.SQLException;

@Component
public class FilmGenreRowMapper implements RowMapper<FilmGenre> {
@Override
public FilmGenre mapRow(ResultSet resultSet, int rowNum) throws SQLException {
FilmGenre filmGenre = new FilmGenre();
filmGenre.setFilmId(resultSet.getInt("film_id"));
filmGenre.setGenreId(resultSet.getInt("genre_id"));
filmGenre.setGenreName(resultSet.getString("genre_name"));
return filmGenre;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.yandex.practicum.filmorate.mapper;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import ru.yandex.practicum.filmorate.model.Film;

import java.sql.ResultSet;
import java.sql.SQLException;

@Component
public class FilmRowMapper implements RowMapper<Film> {
@Override
public Film mapRow(ResultSet resultSet, int rowNum) throws SQLException {
Film film = new Film();
film.setId(resultSet.getInt("id"));
film.setName(resultSet.getString("name"));
film.setDescription(resultSet.getString("description"));
film.setReleaseDate(resultSet.getDate(4).toLocalDate());
film.setDuration(resultSet.getInt("len_min"));
return film;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.yandex.practicum.filmorate.mapper;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import ru.yandex.practicum.filmorate.model.Genre;

import java.sql.ResultSet;
import java.sql.SQLException;

@Component
public class GenreRowMapper implements RowMapper<Genre> {
@Override
public Genre mapRow(ResultSet resultSet, int rowNum) throws SQLException {
Genre genre = new Genre();
genre.setId(resultSet.getInt("id"));
genre.setName(resultSet.getString("name"));
return genre;
}
}
Loading