Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Функциональность «Общие фильмы». #13

Closed
wants to merge 198 commits into from
Closed
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
198 commits
Select commit Hold shift + click to select a range
49e36c7
feat: Создать Review
vvbakhanovich Jan 30, 2024
fb23b56
feat: Создать ReviewDto
vvbakhanovich Jan 30, 2024
64caaca
feat: Создать ReviewMapper
vvbakhanovich Jan 30, 2024
a052ee1
refactor: Использовать wrapper class
vvbakhanovich Jan 30, 2024
2f84fdd
test: Написать тесты валидации ReviewDto
vvbakhanovich Jan 30, 2024
cf48bfb
refactor: Использовать Boolean для isPositive
vvbakhanovich Jan 30, 2024
c1b9153
feat: Добавить таблицу Review
vvbakhanovich Jan 30, 2024
8b549dd
feat: Создать ReviewStorage
vvbakhanovich Jan 30, 2024
9ab12f5
feat: Реализовать ReviewStorage
vvbakhanovich Jan 30, 2024
4783c65
feat: Создать ReviewService
vvbakhanovich Jan 30, 2024
7c8f4cf
feat: Реализовать ReviewService
vvbakhanovich Jan 30, 2024
b311651
feat: Создать ReviewController
vvbakhanovich Jan 30, 2024
3c41f3d
feat: Добавить ON DELETE CASCADE для Review
vvbakhanovich Jan 30, 2024
aa85a1f
feat: Реализовать update
vvbakhanovich Jan 30, 2024
cc72524
feat: Реализовать delete
vvbakhanovich Jan 30, 2024
c64df2d
feat: Реализовать getReviewsByFilmId
vvbakhanovich Jan 30, 2024
aab721a
fix: Не использовать useful при update
vvbakhanovich Jan 30, 2024
1ea1dc3
refactor: Заменить filmId на Long
vvbakhanovich Jan 30, 2024
6921722
feat: Реализовать findAllLimitBy
vvbakhanovich Jan 30, 2024
5b11817
feat: Реализовать addLikeToReview
vvbakhanovich Jan 30, 2024
6c411aa
feat: Сортировать отзывы по полезности
vvbakhanovich Jan 30, 2024
2fc382a
feat: Реализовать addDislikeToReview
vvbakhanovich Jan 30, 2024
2592f5b
feat: Реализовать удаление лайков и дизлайков
vvbakhanovich Jan 30, 2024
3047e39
fix: Добавить сортировку по id
vvbakhanovich Jan 30, 2024
5f2f5f5
test: Написать тесты для ReviewDbStorage
vvbakhanovich Jan 30, 2024
9d4cecf
javadoc
vvbakhanovich Jan 30, 2024
69fc158
feat: Добавить таблицу review_like
vvbakhanovich Jan 30, 2024
81c47a0
feat: Создать ReviewLikeStorage
vvbakhanovich Jan 30, 2024
1395559
feat: Реализовать ReviewLikeStorage
vvbakhanovich Jan 30, 2024
353fcf8
feat: Создать enum ReviewLike
vvbakhanovich Jan 30, 2024
d6ce899
feat: Внедрить ReviewLikeStorage
vvbakhanovich Jan 30, 2024
f4b5e18
refactor: Добавить проверку при удалениии
vvbakhanovich Jan 30, 2024
6e6813f
refactor: Удалить из параметров userId
vvbakhanovich Jan 30, 2024
54b39fe
refactor: Не использовать дополнительные поля
vvbakhanovich Jan 30, 2024
d2de999
refactor: Добавить параметр reviewId в delete
vvbakhanovich Jan 30, 2024
c0a096b
refactor: Добавить параметр userId при работе лайками
vvbakhanovich Jan 30, 2024
0a194d7
refactor: Поправить методы работы с лайками
vvbakhanovich Jan 30, 2024
08f4044
style: Удалить неиспользуемый импорт
vvbakhanovich Jan 30, 2024
de4f098
checkstyle
vvbakhanovich Jan 30, 2024
8efe735
feat: added film recommendations to users controller and tests for th…
elenabokhan13 Jan 31, 2024
59f1783
feat: Добавить Transactional
vvbakhanovich Jan 31, 2024
8e15aa2
feat: Реализован вывод общих с другом фильмов с сортировкой по их поп…
Kazantsevyury Jan 31, 2024
196e6fa
checkstyle
Kazantsevyury Jan 31, 2024
55226c2
fix: refractored methods to move business logic into UserService
elenabokhan13 Jan 31, 2024
6d437de
Merge pull request #10 from vvbakhanovich/add-reviews
vvbakhanovich Jan 31, 2024
1cf30fd
feat: Удаление фильмов и пользователей
Jan 31, 2024
eb17e62
feat: Добавить метод findGenresInIdList
vvbakhanovich Jan 31, 2024
722ea42
feat: Добавить extractToFilmListWithoutGenres
vvbakhanovich Jan 31, 2024
dcc6e71
refactor: Исправить findMostLikedFilmsLimitBy
vvbakhanovich Jan 31, 2024
1d5a347
refactor: Использовать LinkedHashSet
vvbakhanovich Jan 31, 2024
2cd0944
refactor: Использовать в качестве параметра Set вместо List
vvbakhanovich Jan 31, 2024
98a3d20
refactor: Маппить жанры отдельным запросом
vvbakhanovich Jan 31, 2024
ae2b7be
feat: Использовать mapToFilm
vvbakhanovich Jan 31, 2024
8a72284
feat: Добавить ID для FILM_GENRE и создать уникальный индекс
vvbakhanovich Jan 31, 2024
701e81b
feat: Создать Review
vvbakhanovich Jan 30, 2024
2a1dc27
feat: Создать ReviewDto
vvbakhanovich Jan 30, 2024
8844abd
feat: Создать ReviewMapper
vvbakhanovich Jan 30, 2024
2ae3b38
refactor: Использовать wrapper class
vvbakhanovich Jan 30, 2024
e617e53
test: Написать тесты валидации ReviewDto
vvbakhanovich Jan 30, 2024
3b79221
refactor: Использовать Boolean для isPositive
vvbakhanovich Jan 30, 2024
6f693d3
feat: Добавить таблицу Review
vvbakhanovich Jan 30, 2024
26ac111
feat: Создать ReviewStorage
vvbakhanovich Jan 30, 2024
94166cb
feat: Реализовать ReviewStorage
vvbakhanovich Jan 30, 2024
9a5d460
feat: Создать ReviewService
vvbakhanovich Jan 30, 2024
28c1d67
feat: Реализовать ReviewService
vvbakhanovich Jan 30, 2024
8e8d8a3
feat: Создать ReviewController
vvbakhanovich Jan 30, 2024
341d62b
feat: Добавить ON DELETE CASCADE для Review
vvbakhanovich Jan 30, 2024
ca851c0
feat: Реализовать update
vvbakhanovich Jan 30, 2024
f65d0f9
feat: Реализовать delete
vvbakhanovich Jan 30, 2024
7d8f437
feat: Реализовать getReviewsByFilmId
vvbakhanovich Jan 30, 2024
2f57998
fix: Не использовать useful при update
vvbakhanovich Jan 30, 2024
cea22e1
refactor: Заменить filmId на Long
vvbakhanovich Jan 30, 2024
56a95dc
feat: Реализовать findAllLimitBy
vvbakhanovich Jan 30, 2024
8961325
feat: Реализовать addLikeToReview
vvbakhanovich Jan 30, 2024
f9f76e3
feat: Сортировать отзывы по полезности
vvbakhanovich Jan 30, 2024
85262cd
feat: Реализовать addDislikeToReview
vvbakhanovich Jan 30, 2024
bbaf3db
feat: Реализовать удаление лайков и дизлайков
vvbakhanovich Jan 30, 2024
bede5bd
fix: Добавить сортировку по id
vvbakhanovich Jan 30, 2024
2138933
test: Написать тесты для ReviewDbStorage
vvbakhanovich Jan 30, 2024
74dea04
javadoc
vvbakhanovich Jan 30, 2024
18997e3
feat: Добавить таблицу review_like
vvbakhanovich Jan 30, 2024
fb5a940
feat: Создать ReviewLikeStorage
vvbakhanovich Jan 30, 2024
155a2b2
feat: Реализовать ReviewLikeStorage
vvbakhanovich Jan 30, 2024
b14c72f
feat: Создать enum ReviewLike
vvbakhanovich Jan 30, 2024
9daf150
feat: Внедрить ReviewLikeStorage
vvbakhanovich Jan 30, 2024
c7e8cb0
refactor: Добавить проверку при удалениии
vvbakhanovich Jan 30, 2024
2da3bc0
refactor: Удалить из параметров userId
vvbakhanovich Jan 30, 2024
747fc30
refactor: Не использовать дополнительные поля
vvbakhanovich Jan 30, 2024
f64bd8d
refactor: Добавить параметр reviewId в delete
vvbakhanovich Jan 30, 2024
eee2fb5
refactor: Добавить параметр userId при работе лайками
vvbakhanovich Jan 30, 2024
0babcb7
refactor: Поправить методы работы с лайками
vvbakhanovich Jan 30, 2024
5604cdb
style: Удалить неиспользуемый импорт
vvbakhanovich Jan 30, 2024
060d430
checkstyle
vvbakhanovich Jan 30, 2024
d9306f0
feat: Добавить Transactional
vvbakhanovich Jan 31, 2024
3da9f77
feat: Метод getCommonFilms теперь использует findFilmsByIds для извле…
Kazantsevyury Jan 31, 2024
d864974
Checkstyle
Kazantsevyury Jan 31, 2024
3edfc80
Checkstyle
Kazantsevyury Jan 31, 2024
3969fb4
Checkstyle
Kazantsevyury Jan 31, 2024
16e01ee
Merge pull request #16 from vvbakhanovich/fix-popular-films
vvbakhanovich Feb 1, 2024
15e048e
feat: Удаление фильмов и пользователей
Jan 31, 2024
f7b8069
refactor: resolve merge conflict
Feb 1, 2024
a06bd92
Merge remote-tracking branch 'origin/add-remove-endpoint' into add-re…
Feb 1, 2024
e90a394
refactor: fix tests
Feb 1, 2024
e3a0a74
feat: Создать Review
vvbakhanovich Jan 30, 2024
054f655
feat: Создать ReviewDto
vvbakhanovich Jan 30, 2024
439a1b1
feat: Создать ReviewMapper
vvbakhanovich Jan 30, 2024
7ecb974
refactor: Использовать wrapper class
vvbakhanovich Jan 30, 2024
2926829
test: Написать тесты валидации ReviewDto
vvbakhanovich Jan 30, 2024
958704f
refactor: Использовать Boolean для isPositive
vvbakhanovich Jan 30, 2024
beebd65
feat: Добавить таблицу Review
vvbakhanovich Jan 30, 2024
def7997
feat: Создать ReviewStorage
vvbakhanovich Jan 30, 2024
4d1cea8
feat: Реализовать ReviewStorage
vvbakhanovich Jan 30, 2024
70d374f
feat: Создать ReviewService
vvbakhanovich Jan 30, 2024
d7dedd4
feat: Реализовать ReviewService
vvbakhanovich Jan 30, 2024
1eab287
feat: Создать ReviewController
vvbakhanovich Jan 30, 2024
e4f9596
feat: Добавить ON DELETE CASCADE для Review
vvbakhanovich Jan 30, 2024
fc1e242
feat: Реализовать update
vvbakhanovich Jan 30, 2024
9e02089
feat: Реализовать delete
vvbakhanovich Jan 30, 2024
e8285c1
feat: Реализовать getReviewsByFilmId
vvbakhanovich Jan 30, 2024
4e00d15
fix: Не использовать useful при update
vvbakhanovich Jan 30, 2024
daabff3
refactor: Заменить filmId на Long
vvbakhanovich Jan 30, 2024
6d2691b
feat: Реализовать findAllLimitBy
vvbakhanovich Jan 30, 2024
c7a2035
feat: Реализовать addLikeToReview
vvbakhanovich Jan 30, 2024
1db8e6d
feat: Сортировать отзывы по полезности
vvbakhanovich Jan 30, 2024
f268b03
feat: Реализовать addDislikeToReview
vvbakhanovich Jan 30, 2024
c860ab1
feat: Реализовать удаление лайков и дизлайков
vvbakhanovich Jan 30, 2024
4fd9b7e
fix: Добавить сортировку по id
vvbakhanovich Jan 30, 2024
40ebb6b
test: Написать тесты для ReviewDbStorage
vvbakhanovich Jan 30, 2024
051d3dc
javadoc
vvbakhanovich Jan 30, 2024
6dea36e
feat: Добавить таблицу review_like
vvbakhanovich Jan 30, 2024
eb59e2b
feat: Создать ReviewLikeStorage
vvbakhanovich Jan 30, 2024
25e7e86
feat: Реализовать ReviewLikeStorage
vvbakhanovich Jan 30, 2024
d4da16f
feat: Создать enum ReviewLike
vvbakhanovich Jan 30, 2024
f760b04
feat: Внедрить ReviewLikeStorage
vvbakhanovich Jan 30, 2024
3b01b62
refactor: Добавить проверку при удалениии
vvbakhanovich Jan 30, 2024
e85bc8d
refactor: Удалить из параметров userId
vvbakhanovich Jan 30, 2024
49cf73a
refactor: Не использовать дополнительные поля
vvbakhanovich Jan 30, 2024
1573821
refactor: Добавить параметр reviewId в delete
vvbakhanovich Jan 30, 2024
57df230
refactor: Добавить параметр userId при работе лайками
vvbakhanovich Jan 30, 2024
5143a1b
refactor: Поправить методы работы с лайками
vvbakhanovich Jan 30, 2024
001122f
style: Удалить неиспользуемый импорт
vvbakhanovich Jan 30, 2024
eb8a580
checkstyle
vvbakhanovich Jan 30, 2024
57925e0
feat: Добавить Transactional
vvbakhanovich Jan 31, 2024
1dc80d4
feat: Добавить метод findGenresInIdList
vvbakhanovich Jan 31, 2024
55693b2
feat: Добавить extractToFilmListWithoutGenres
vvbakhanovich Jan 31, 2024
bfad941
refactor: Исправить findMostLikedFilmsLimitBy
vvbakhanovich Jan 31, 2024
3423a26
refactor: Использовать LinkedHashSet
vvbakhanovich Jan 31, 2024
d909221
refactor: Использовать в качестве параметра Set вместо List
vvbakhanovich Jan 31, 2024
a27e02e
refactor: Маппить жанры отдельным запросом
vvbakhanovich Jan 31, 2024
69894fa
feat: Использовать mapToFilm
vvbakhanovich Jan 31, 2024
d833d00
feat: Добавить ID для FILM_GENRE и создать уникальный индекс
vvbakhanovich Jan 31, 2024
dccdb39
fix: moved extracting users-likes map to FilmLikeStorage, refractored…
elenabokhan13 Feb 1, 2024
e1d4e98
Merge branch 'develop' into add-recommendations
elenabokhan13 Feb 1, 2024
d6740bf
fix: moved extracting users-likes map to FilmLikeStorage, refractored…
elenabokhan13 Feb 1, 2024
f271f6c
fix: moved extracting users-likes map to FilmLikeStorage, refractored…
elenabokhan13 Feb 1, 2024
35a870d
Merge pull request #12 from vvbakhanovich/add-recommendations
elenabokhan13 Feb 1, 2024
4766475
refactor: resolve conflicts
Feb 1, 2024
eeb1ecc
Merge pull request #15 from vvbakhanovich/add-remove-endpoint
ayzatmr Feb 1, 2024
52341fe
feat: Создать Director, dto и mapper
vvbakhanovich Feb 1, 2024
dd4fa95
test: Написать тесты валидации Director
vvbakhanovich Feb 1, 2024
1f3d51f
feat: Добавить список режиссеров в качестве поля
vvbakhanovich Feb 1, 2024
dce6ca3
feat: Создать таблицы Director, FILM_DIRECTOR
vvbakhanovich Feb 1, 2024
d70c4d4
fix: Переименовать toModel
vvbakhanovich Feb 1, 2024
21f727e
feat: Реализовать DirectorController
vvbakhanovich Feb 1, 2024
30f9251
feat: Создать и реализовать DirectorService
vvbakhanovich Feb 1, 2024
c8aa291
feat: Создать DirectorStorage
vvbakhanovich Feb 1, 2024
1348fba
feat: Добавить ON DELETE CASCADE
vvbakhanovich Feb 1, 2024
54a4274
feat: Реализовать DirectorDbStorage
vvbakhanovich Feb 1, 2024
2f5bd2e
test: Написать тесты для DirectorDbStorage
vvbakhanovich Feb 1, 2024
1b960c8
feat: Реализовать FilmDirectorStorage
vvbakhanovich Feb 1, 2024
8d5b9bc
feat: Добавить заполнение режиссеров
vvbakhanovich Feb 1, 2024
8c5ee35
fix: Добавить FilmDirectorStorage
vvbakhanovich Feb 1, 2024
f513ece
feat: Добавить Directors
vvbakhanovich Feb 1, 2024
6c6b7c9
feat: Добавить getFilmsFromDirector
vvbakhanovich Feb 1, 2024
e93ee85
feat: Реализовать getFilmsFromDirector и Transactional
vvbakhanovich Feb 1, 2024
9e246b0
feat: Добавить findFilmsByDirectorId
vvbakhanovich Feb 1, 2024
3ac1aa6
feat: Реализовать findFilmsByDirectorId
vvbakhanovich Feb 1, 2024
dd382c0
feat: Добавить findFilmsFromDirector
vvbakhanovich Feb 1, 2024
5e46f83
feat: Реализовать findFilmsFromDirector
vvbakhanovich Feb 1, 2024
61474a2
fix: Добавить FilmDirectorStorage
vvbakhanovich Feb 1, 2024
56ee826
fix: Добавить FilmDirectorStorage
vvbakhanovich Feb 1, 2024
7aafefb
test: Добавить тесты получения фильмов режиссера
vvbakhanovich Feb 1, 2024
9cf064c
refactor: Использовать queryForList
vvbakhanovich Feb 2, 2024
ba99643
refactor: Перенести валидацию сортировки в сервис
vvbakhanovich Feb 2, 2024
62f63c9
refactor: Добавить методы с сортировкой
vvbakhanovich Feb 2, 2024
47f842f
refactor: Перенести логику выбора методов в сервис
vvbakhanovich Feb 2, 2024
5d4e2a3
checkstyle
vvbakhanovich Feb 2, 2024
ab14a96
refactor: Использовать один метод для сортировок
vvbakhanovich Feb 2, 2024
5514d80
Merge pull request #17 from vvbakhanovich/add-director
vvbakhanovich Feb 2, 2024
84b982e
feat: Реализован вывод общих с другом фильмов с сортировкой по их поп…
Kazantsevyury Jan 31, 2024
9bdf2d7
checkstyle
Kazantsevyury Jan 31, 2024
209243d
feat: Метод getCommonFilms теперь использует findFilmsByIds для извле…
Kazantsevyury Jan 31, 2024
13d2c6a
Rename
Kazantsevyury Feb 2, 2024
95a0cdc
Checkstyle
Kazantsevyury Jan 31, 2024
f03310b
Merge branch 'add-common-films' of https://github.com/vvbakhanovich/j…
Kazantsevyury Feb 2, 2024
57d6a84
merging
Kazantsevyury Feb 2, 2024
564f7c5
check style
Kazantsevyury Feb 2, 2024
7b96901
fixing
Kazantsevyury Feb 2, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ public FilmDto removeLike(@PathVariable long id, @PathVariable long userId) {
return filmService.removeLike(id, userId);
}

@GetMapping("/common")
public Collection<FilmDto> getCommonFilms(
@RequestParam long userId,
@RequestParam long friendId) {
return filmService.getCommonFilms(userId, friendId);

}

@GetMapping("/popular")
public Collection<FilmDto> getMostPopularFilms(@RequestParam(required = false, defaultValue = "10") int count) {
return filmService.getMostPopularFilms(count);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ru.yandex.practicum.filmorate.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.dto.ReviewDto;
import ru.yandex.practicum.filmorate.service.ReviewService;

import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/reviews")
@RequiredArgsConstructor
public class ReviewController {

private final ReviewService reviewService;

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public ReviewDto addReview(@Valid @RequestBody ReviewDto reviewDto) {
return reviewService.addReview(reviewDto);
}

@PutMapping
public ReviewDto updateReview(@Valid @RequestBody ReviewDto updatedReviewDto) {
return reviewService.updateReview(updatedReviewDto);
}

@DeleteMapping("/{id}")
public void deleteReview(@PathVariable long id) {
reviewService.deleteReview(id);
}

@GetMapping("/{id}")
public ReviewDto getReviewById(@PathVariable long id) {
return reviewService.getReviewById(id);
}

@GetMapping
public List<ReviewDto> getReviewsByFilmId(@RequestParam(required = false) Long filmId,
@RequestParam(required = false, defaultValue = "10") int count) {
return reviewService.getReviewsByFilmId(filmId, count);
}

@PutMapping("/{id}/like/{userId}")
public ReviewDto addLikeToReview(@PathVariable long id, @PathVariable long userId) {
return reviewService.addLikeToReview(id, userId);
}

@PutMapping("/{id}/dislike/{userId}")
public ReviewDto addDislikeToReview(@PathVariable long id, @PathVariable long userId) {
return reviewService.addDislikeToReview(id, userId);
}

@DeleteMapping("/{id}/like/{userId}")
public ReviewDto deleteLikeFromReview(@PathVariable long id, @PathVariable long userId) {
return reviewService.deleteLikeFromReview(id, userId);
}

@DeleteMapping("/{id}/dislike/{userId}")
public ReviewDto deleteDislikeFromReview(@PathVariable long id, @PathVariable long userId) {
return reviewService.deleteDislikeFromReview(id, userId);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ru.yandex.practicum.filmorate.dao;

import java.util.Map;
import java.util.Set;

public interface FilmLikeStorage {
void add(long filmId, long userId);
Expand All @@ -10,4 +11,7 @@ public interface FilmLikeStorage {
Map<Long, Long> findAll();

void remove(long filmId, long userId);

Set<Long> findLikedFilmsByUser(long userId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
import ru.yandex.practicum.filmorate.model.Film;

import java.util.Collection;
import java.util.List;
import java.util.Set;

public interface FilmStorage extends Dao<Film> {

Collection<Film> findMostLikedFilmsLimitBy(int count);

List<Film> findFilmsByIds(Set<Long> filmIds);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.yandex.practicum.filmorate.dao;

public interface ReviewLikeStorage {
void add(long reviewId, long userId, String type);

void delete(long reviewId, long userId, String type);
}
15 changes: 15 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/dao/ReviewStorage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.yandex.practicum.filmorate.dao;

import ru.yandex.practicum.filmorate.model.Review;

import java.util.List;

public interface ReviewStorage extends Dao<Review> {
List<Review> findByFilmIdLimitBy(long filmId, int count);

List<Review> findAllLimitBy(int count);

void addLikeToReview(long id);

void addDislikeToReview(long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
Expand Down Expand Up @@ -192,4 +193,40 @@ private Collection<Film> extractToFilmList(ResultSet rs) throws SQLException, Da

return filmIdMap.values();
}

@Override
public List<Film> findFilmsByIds(Set<Long> filmIds) {
if (filmIds.isEmpty()) {
return Collections.emptyList();
}

String placeholders = String.join(",", Collections.nCopies(filmIds.size(), "?"));

String sql = "SELECT f.ID, f.TITLE, f.DESCRIPTION, f.RELEASE_DATE, f.DURATION, f.MPA_ID, " +
"m.RATING_NAME, COUNT(fl.USER_ID) AS LIKES " +
"FROM FILM f " +
"LEFT JOIN MPA m ON f.MPA_ID = m.ID " +
"LEFT JOIN film_like fl ON f.ID = fl.FILM_ID " +
"WHERE f.ID IN (" + placeholders + ") " +
"GROUP BY f.ID, m.RATING_NAME " +
"ORDER BY LIKES DESC";
Comment on lines +248 to +255
Copy link
Owner

Choose a reason for hiding this comment

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

Здесь можно использовать String.format, чтобы соединить два стринга

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

можно, но это менее безопасно так как это может привести к sql инъекциям, по этому я оставлю свое решение

Copy link
Owner

Choose a reason for hiding this comment

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

Видимо ты меня неправильно понял. Я предложил тебе также присоединить твой placeholders, поэтому в плане инъекции безопасность не поменяется. Просто немного лаконичнее смотрится, если речь не идет о производительности. В случае одной переменной это не так критично, можешь оставить свой вариант)


Object[] idsArray = filmIds.toArray(new Object[0]);

return jdbcTemplate.query(sql, idsArray, new RowMapper<Film>() {
@Override
public Film mapRow(ResultSet rs, int rowNum) throws SQLException {
Film film = new Film();
film.setId(rs.getLong("ID"));
film.setName(rs.getString("TITLE"));
film.setDescription(rs.getString("DESCRIPTION"));
film.setReleaseDate(rs.getDate("RELEASE_DATE").toLocalDate());
film.setDuration(rs.getInt("DURATION"));
film.setMpa(new Mpa(rs.getInt("MPA_ID"), rs.getString("RATING_NAME")));
film.setLikes(rs.getLong("LIKES"));
return film;
}
});
Comment on lines +257 to +272
Copy link
Owner

Choose a reason for hiding this comment

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

Попробуй использовать query с немого другой сигнатурой: query(String sql, RowMapper<?> rm, Object ... args). Тогда не нужна будет 214 строка и в качестве аргумента можно использовать filmIds.toArray(). Получится лаконичнее)
После того как подтянешь изменения сможешь использовать уже написанный маппер. И не забудь приклеить жанры к фильмам, для этого тоже был создан подходящий метод)

Copy link
Owner

Choose a reason for hiding this comment

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

Насколько я понимаю этот метод ты больше не используешь? Если да, то его стоит удалить)

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.*;

@Repository
@RequiredArgsConstructor
Expand Down Expand Up @@ -49,11 +48,20 @@ public void remove(long filmId, long userId) {
jdbcTemplate.update(sql, filmId, userId);
}

@Override
public Set<Long> findLikedFilmsByUser(long userId) {
final String sql = "SELECT film_id FROM film_like WHERE user_id = ?";
List<Long> filmIds = jdbcTemplate.queryForList(sql, Long.class, userId);
return new HashSet<>(filmIds);
}


private Map<Long, Long> mapRowToIdCount(ResultSet rs) throws SQLException {
final Map<Long, Long> result = new LinkedHashMap<>();
while (rs.next()) {
result.put(rs.getLong("film_id"), rs.getLong("likes"));
}
return result;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package ru.yandex.practicum.filmorate.dao.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import ru.yandex.practicum.filmorate.dao.ReviewStorage;
import ru.yandex.practicum.filmorate.exception.NotFoundException;
import ru.yandex.practicum.filmorate.model.Review;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

@Repository
@RequiredArgsConstructor
@Slf4j
public class ReviewDbStorage implements ReviewStorage {

private final JdbcTemplate jdbcTemplate;

@Override
public Review add(final Review review) {
final KeyHolder keyHolder = new GeneratedKeyHolder();
final String sql = "INSERT INTO review (review_content, is_positive, useful, user_id, film_id) VALUES (?, ?, ?, ?, ?)";
jdbcTemplate.update(con -> {
PreparedStatement stmt = con.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, review.getContent());
stmt.setBoolean(2, review.isPositive());
stmt.setLong(3, review.getUseful());
stmt.setLong(4, review.getUserId());
stmt.setLong(5, review.getFilmId());
return stmt;
}, keyHolder);

review.setReviewId(Objects.requireNonNull(keyHolder.getKey(), "Не удалось добавить отзыв.").longValue());

return review;
}

@Override
public void remove(final long id) {
final String sql = "DELETE FROM review WHERE id = ?";
int update = jdbcTemplate.update(sql, id);
if (update != 1) {
throw new NotFoundException("Отзыв с id '" + id + "' не найден.");
}
}

@Override
public void update(final Review review) {
final String sql = "UPDATE review SET review_content = ?, is_positive = ? WHERE id = ?";
final int update = jdbcTemplate.update(sql, review.getContent(), review.isPositive(), review.getReviewId());
if (update != 1) {
throw new NotFoundException("Отзыв с id '" + review.getReviewId() + "' не найден.");
}
}

@Override
public Collection<Review> findAll() {
final String sql = "SELECT id, review_content, is_positive, useful, user_id, film_id " +
"FROM review ORDER BY useful DESC, id";
return jdbcTemplate.query(sql, this::mapReview);
}

@Override
public Review findById(final long id) {
final String sql = "SELECT id, review_content, is_positive, useful, user_id, film_id " +
"FROM review WHERE id = ?";
try {
return jdbcTemplate.queryForObject(sql, this::mapReview, id);
} catch (EmptyResultDataAccessException e) {
throw new NotFoundException("Отзыв с id '" + id + "' не найден.");
}
}

@Override
public List<Review> findByFilmIdLimitBy(final long filmId, final int count) {
final String sql = "SELECT id, review_content, is_positive, useful, user_id, film_id " +
"FROM review WHERE film_id = ? ORDER BY useful DESC, id LIMIT ?";
return jdbcTemplate.query(sql, this::mapReview, filmId, count);
}

@Override
public List<Review> findAllLimitBy(final int count) {
final String sql = "SELECT id, review_content, is_positive, useful, user_id, film_id " +
"FROM review ORDER BY useful DESC, id LIMIT ?";
return jdbcTemplate.query(sql, this::mapReview, count);
}

@Override
public void addLikeToReview(final long id) {
final String sql = "UPDATE review SET useful = useful + 1 WHERE id = ?";
jdbcTemplate.update(sql, id);
}

@Override
public void addDislikeToReview(long id) {
final String sql = "UPDATE review SET useful = useful - 1 WHERE id = ?";
jdbcTemplate.update(sql, id);
}

private Review mapReview(final ResultSet rs, final int rowNum) throws SQLException {
return Review.builder()
.reviewId(rs.getLong("id"))
.content(rs.getString("review_content"))
.isPositive(rs.getBoolean("is_positive"))
.useful(rs.getLong("useful"))
.userId(rs.getLong("user_id"))
.filmId(rs.getLong("film_id"))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.yandex.practicum.filmorate.dao.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import ru.yandex.practicum.filmorate.dao.ReviewLikeStorage;

@Repository
@RequiredArgsConstructor
@Slf4j
public class ReviewLikeDbStorage implements ReviewLikeStorage {

private final JdbcTemplate jdbcTemplate;

@Override
public void add(final long reviewId, final long userId, final String type) {
final String sql = "INSERT INTO review_like VALUES (?, ?, ?)";
jdbcTemplate.update(sql, reviewId, userId, type);
}

@Override
public void delete(final long reviewId, final long userId, final String type) {
final String sql = "DELETE FROM review_like WHERE review_id = ? AND user_id = ? AND like_type = ?";
jdbcTemplate.update(sql, userId, type);
}
}
26 changes: 26 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/dto/ReviewDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ru.yandex.practicum.filmorate.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ReviewDto {
private long reviewId;
@NotBlank(message = "Содержание отзыва не может быть пустым.")
private String content;
@NotNull(message = "Не указана полезность отзыва.")
private Boolean isPositive;
private long useful;
@NotNull(message = "Не указан идентификатор пользователя.")
private Long userId;
@NotNull(message = "Не указан идентификатор фильма.")
private Long filmId;
}
Loading
Loading