Skip to content

Commit

Permalink
Merge branch 'develop' into add-search
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderB777 authored Aug 27, 2024
2 parents 67340ed + 3c38c7c commit 932e77d
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ public ResponseEntity<FilmDto> update(@Valid @RequestBody FilmDto film) {
return ResponseEntity.ok(filmService.updateFilm(film));
}

@GetMapping("/popular")
public ResponseEntity<List<FilmDto>> getPopularFilms(@RequestParam(defaultValue = "10") int count) {
log.debug("Получен запрос на получение списка популярный фильмов в количестве {}", count);
return ResponseEntity.ok(filmService.getPopularFilms(count));
}

@PutMapping("/{id}/like/{userId}")
public ResponseEntity<?> putLike(@PathVariable Long id, @PathVariable Long userId) {
log.debug("Получен запрос на создание лайка фильму с id={} пользователем с Id={}", id, userId);
Expand All @@ -62,6 +56,16 @@ public ResponseEntity<?> deleteLike(@PathVariable Long id, @PathVariable Long us
return ResponseEntity.noContent().build();
}

@GetMapping("/popular")
public List<FilmDto> getPopularFilmsOfGenreAndYear(
@RequestParam(defaultValue = "10") int count,
@RequestParam(defaultValue = "0") int genreId,
@RequestParam(defaultValue = "0") int year) {
log.info("Поступил запрос на получение списка популярных фильмов по годам и жанрам.");
log.info("count {}, genre {} , year {}", count, genreId, year);
return filmService.getBestFilmsOfGenreAndYear(count, genreId, year);
}

@GetMapping("/director/{directorId}")
public List<FilmDto> getFilmByDirectorId(@PathVariable int directorId, @RequestParam String sortBy) {
return filmService.getFilmsByDirectorId(directorId, sortBy);
Expand All @@ -72,4 +76,18 @@ public List<FilmDto> getSearchResults(@RequestParam String query, @RequestParam
log.info("Поступил запрос на получение результатов поиска по фильмам.");
return filmService.getSearchResults(query, by);
}

@GetMapping("/common")
public ResponseEntity<List<FilmDto>> getCommonFilms(
@RequestParam long userId,
@RequestParam long friendId) {
log.debug("Получен запрос на получение общих фильмов для пользователей {} и {}", userId, friendId);
return ResponseEntity.ok(filmService.findCommonFilms(userId, friendId));
}

@DeleteMapping("/{filmId}")
public void deleteFilm(@PathVariable Long filmId) {
log.debug("Получен запрос на удаление фильма с ID: {}", filmId);
filmService.removeFilm(filmId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,16 @@ public ResponseEntity<List<UserDto>> showCommonFriends(@PathVariable Long id, @P
"пользователя с id {}, и пользователя с id {} ", id, friendId);
return ResponseEntity.ok(userService.getCommonFriends(id, friendId));
}

@DeleteMapping("/{userId}")
public void deleteUser(@PathVariable Long userId) {
log.debug("Получен запрос на удаление пользователя с ID: {}", userId);
userService.removeUser(userId);
}

@GetMapping("/{userId}")
public UserDto getUser(@PathVariable Long userId) {
log.debug("Получен запрос на получение пользователя с ID: {}", userId);
return userService.getUserById(userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
public interface FilmStorage {
Film save(Film film);

void remove(Long id);

Film update(Film film);

List<Film> findAll();
Expand All @@ -21,4 +23,6 @@ public interface FilmStorage {
void deleteLike(long filmId, long userId);

List<Film> findFilmsByDirectorId(int directorId);

List<Film> findCommonFilms(long userId, long friendId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ public interface FriendshipStorage {
void createFriendship(long userId, long friendId);

void deleteFriendship(long userId, long friendId);

void deleteUser(long userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ public interface UserStorage {
void removeFriendship(long userId, long friendId);

void createFriendship(long userId, long friendId);

void remove(Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import ru.yandex.practicum.filmorate.dao.mappers.FilmRowMapper;
import ru.yandex.practicum.filmorate.dao.mappers.UserIdRowMapper;
import ru.yandex.practicum.filmorate.model.Director;
import ru.yandex.practicum.filmorate.dto.FilmDto;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.model.Genre;
import ru.yandex.practicum.filmorate.model.Mpa;
Expand Down Expand Up @@ -39,10 +40,22 @@ public class FilmDbStorage extends BaseDbStorage<Film> implements FilmStorage {
private static final String PUT_LIKE_QUERY = "INSERT INTO likes (film_id, user_id) VALUES(?, ?)";
private static final String DELETE_LIKE_QUERY = "DELETE FROM likes WHERE film_id = ? AND user_id = ?";
private static final String GET_LIKES_FROM_FILM_QUERY = "SELECT user_id FROM likes WHERE film_id = ?";

private static final String INSERT_DIRECTORS_QUERY = "MERGE INTO director_films (film_id, director_id) KEY (film_id, director_id) VALUES (?, ?)";
private static final String SELECT_FILMS_BY_DIRECTOR_ID = "SELECT * FROM films WHERE id in (SELECT film_id FROM director_films WHERE director_id = ?)";

private static final String INSERT_DIRECTORS_QUERY = "MERGE INTO director_films (film_id, director_id) KEY (film_id, director_id) VALUES (?, ?)";
private static final String SELECT_FILMS_BY_DIRECTOR_ID = "SELECT * FROM films WHERE id in (SELECT film_id FROM director_films WHERE director_id = ?)";
private static final String FIND_COMMON_FILMS_QUERY = "SELECT f.* " +
"FROM films f " +
"JOIN likes l1 ON f.id = l1.film_id " +
"JOIN likes l2 ON f.id = l2.film_id " +
"WHERE l1.user_id = ? AND l2.user_id = ? " +
"GROUP BY f.id " +
"ORDER BY COUNT(l1.user_id) DESC";

private static final String DELETE_FILM_QUERY = "DELETE FROM films WHERE id = ?";
private static final String DELETE_FILM_FROM_GENRES_QUERY = "DELETE FROM film_genres WHERE film_id = ?";
private static final String DELETE_FILM_FROM_LIKES_QUERY = "DELETE FROM likes WHERE film_id = ?";

public FilmDbStorage(JdbcTemplate jdbcTemplate,
RowMapper<Film> rowMapper,
MpaStorage mpaDbStorage,
Expand Down Expand Up @@ -149,6 +162,14 @@ public void deleteLike(long filmId, long userId) {
log.debug("Удаление лайка для фильма с id={}, пользователем с id={}", filmId, userId);
delete(DELETE_LIKE_QUERY, filmId, userId);
}

public List<Film> findCommonFilms(long userId, long friendId) {
List<Film> commonFilms = findMany(FIND_COMMON_FILMS_QUERY, userId, friendId);
for (Film film : commonFilms) {
film.setGenres(genresDbStorage.findByFilmId(film.getId()));
}
return commonFilms;
}

public List<Long> getLikesFromFilm(long id) {
log.debug("Поиск лайков для фильма с id: {}", id);
Expand All @@ -158,5 +179,12 @@ public List<Long> getLikesFromFilm(long id) {
@Override
public List<Film> findFilmsByDirectorId(int directorId) {
return jdbcTemplate.query(SELECT_FILMS_BY_DIRECTOR_ID, filmRowMapper, directorId);
}

public void remove(Long id) {
log.debug("Удаление фильма с id={}", id);
delete(DELETE_FILM_FROM_LIKES_QUERY, id);
delete(DELETE_FILM_FROM_GENRES_QUERY, id);
delete(DELETE_FILM_QUERY, id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class FriendshipDbStorage extends BaseDbStorage implements FriendshipStor
private static final String CREATE_FRIENDSHIP_QUERY = "INSERT INTO friendship (user1_id, user2_id) VALUES (?, ?)";
private static final String DELETE_FRIENDSHIP_QUERY = "DELETE FROM friendship WHERE user1_id = ? AND user2_id = ?";
private static final String CHECK_FRIENDSHIP_QUERY = "SELECT * FROM friendship WHERE user1_id = ? AND user2_id = ?";
private static final String DELETE_USER_QUERY = "DELETE FROM friendship WHERE user2_id = ?";

public FriendshipDbStorage(JdbcTemplate jdbcTemplate, RowMapper<Friendship> rowMapper) {
super(jdbcTemplate, rowMapper);
Expand All @@ -39,4 +40,9 @@ public void createFriendship(long userId, long friendId) {
public void deleteFriendship(long userId, long friendId) {
delete(DELETE_FRIENDSHIP_QUERY, userId, friendId);
}

@Override
public void deleteUser(long userId) {
delete(DELETE_USER_QUERY, userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,15 @@ public void deleteLike(long filmId, long userId) {
public List<Film> findFilmsByDirectorId(int directorId) {
return List.of();
}

@Override
public List<Film> findCommonFilms(long userId, long friendId) {
return List.of();
}

@Override
public void remove(Long id) {
log.info("Удаление фильма с id{}", id);
films.remove(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,10 @@ public void removeFriendship(long userId, long friendId) {
public void createFriendship(long userId, long friendId) {
users.get(userId).getFriends().add(friendId);
}

@Override
public void remove(Long id) {
log.info("Удаление пользователя с id{}", id);
users.remove(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class UserDbStorage extends BaseDbStorage<User> implements UserStorage {
private static final String FIND_ALL_QUERY = "SELECT * FROM users";
private static final String FIND_BY_ID_QUERY = "SELECT * FROM users WHERE id = ?";
private static final String USER_MAX_ID_QUERY = "SELECT MAX(id) FROM users";
private static final String DELETE_USER_QUERY = "DELETE FROM users WHERE id = ?";

public UserDbStorage(JdbcTemplate jdbcTemplate, RowMapper<User> rowMapper, FriendshipStorage friendshipStorage) {
super(jdbcTemplate, rowMapper);
Expand Down Expand Up @@ -83,4 +84,12 @@ public void removeFriendship(long userId, long friendId) {
public void createFriendship(long userId, long friendId) {
friendshipStorage.createFriendship(userId, friendId);
}

@Override
public void remove(Long id) {
log.debug("Удаление пользователя с id={}", id);
Object[] args = new Object[] {id};
friendshipStorage.deleteUser(id);
delete(DELETE_USER_QUERY, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.yandex.practicum.filmorate.dao.mappers;

import org.mapstruct.Mapper;
import ru.yandex.practicum.filmorate.dto.DirectorDto;
import ru.yandex.practicum.filmorate.model.Director;

import java.util.List;

@Mapper(componentModel = "spring")
public interface DirectorMapper {

DirectorDto toDto(Director director);

List<DirectorDto> toDto(List<Director> directors);

Director toEntity(DirectorDto directorDto);

List<Director> toEntity(List<DirectorDto> directorsDto);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import ru.yandex.practicum.filmorate.dao.DirectorMapper;
import ru.yandex.practicum.filmorate.dao.FilmStorage;
import ru.yandex.practicum.filmorate.dao.UserStorage;
import ru.yandex.practicum.filmorate.dao.impl.GenresDbStorage;
import ru.yandex.practicum.filmorate.dao.mappers.DirectorMapper;
import ru.yandex.practicum.filmorate.dao.mappers.FilmMapper;
import ru.yandex.practicum.filmorate.dao.mappers.MpaMapper;
import ru.yandex.practicum.filmorate.dto.DirectorDto;
Expand All @@ -16,7 +18,11 @@
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.utils.FilmByLikeComparator;

import java.util.*;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Optional;

@Service
@Slf4j
Expand All @@ -28,6 +34,7 @@ public class FilmService {
private final UserStorage userStorage;
private final FilmMapper filmMapper;
private final MpaMapper mpaMapper;
private final GenresDbStorage genresDbStorage;
private final DirectorMapper directorMapper;

public Collection<FilmDto> findAll() {
Expand Down Expand Up @@ -90,6 +97,21 @@ public FilmDto getFilmById(Long id) {
return filmMapper.toDto(film);
}

public List<FilmDto> getBestFilmsOfGenreAndYear(int count, int genreId, int year) {
List<FilmDto> films = getPopularFilms(count).stream().map(filmDto -> getFilmById(filmDto.getId())).toList();

if (genreId == 0 && year == 0) return films;

if (genreId == 0) return films.stream().filter(film -> film.getReleaseDate().getYear() == year).toList();

if (year != 0) return films.stream()
.filter(film -> film.getReleaseDate().getYear() == year
&& film.getGenres().stream().anyMatch(genre -> genre.getId() == genreId))
.collect(Collectors.toList());

return films.stream().filter(film -> film.getGenres().stream().anyMatch(gen -> gen.getId() == genreId)).toList();
}

public List<FilmDto> getFilmsByDirectorId(int directorId, String sortBy) {
List<Film> films = filmStorage.findFilmsByDirectorId(directorId);
return switch (sortBy) {
Expand Down Expand Up @@ -128,4 +150,18 @@ public List<FilmDto> getSearchResults(String query, String by) {
default -> new ArrayList<>();
};
}

public List<FilmDto> findCommonFilms(long userId, long friendId) {
log.info("Поиск общих фильмов для пользователей {} и {}", userId, friendId);
List<Film> commonFilms = filmStorage.findCommonFilms(userId, friendId);
return filmMapper.toDto(commonFilms);
}

public void removeFilm(Long id) {
log.info("Получен запрос на удаление фильма с ID: {}", id);
filmStorage.findById(id)
.orElseThrow(() -> new FilmNotFoundException(id));
log.info("Фильм с id={} найден", id);
filmStorage.remove(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public List<UserDto> getAllFriendsFromUser(Long id) {
log.info("Пользователь с id = {} найден", id);
Set<Long> friends = user.getFriends();
if (friends.isEmpty()) return Collections.emptyList();
return user.getFriends().stream()

return friends.stream()
.map(userStorage::findById)
.map(Optional::orElseThrow)
.map(userMapper::toDto)
Expand All @@ -104,4 +105,20 @@ public List<UserDto> getCommonFriends(Long id, Long friendId) {
.map(userMapper::toDto)
.toList();
}

public void removeUser(Long id) {
log.info("Получен запрос на удаление пользователя с ID: {}", id);
userStorage.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
log.info("Пользователь с id={} найден", id);
userStorage.remove(id);
}

public UserDto getUserById(long id) {
log.info("Получен запрос на получение пользователя с ID: {}", id);
User user = userStorage.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
log.info("Пользователь с id={} найден", id);
return userMapper.toDto(user);
}
}
1 change: 0 additions & 1 deletion src/main/resources/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,3 @@ CREATE TABLE IF NOT EXISTS director_films
FOREIGN KEY (film_id) REFERENCES films (id),
FOREIGN KEY (director_id) REFERENCES directors (director_id) ON DELETE CASCADE
);

0 comments on commit 932e77d

Please sign in to comment.