diff --git a/src/main/kotlin/com/project/movienight/adapters/persistence/FilmLibraryRepository.kt b/src/main/kotlin/com/project/movienight/adapters/persistence/FilmLibraryRepository.kt new file mode 100644 index 0000000..4f5c6e8 --- /dev/null +++ b/src/main/kotlin/com/project/movienight/adapters/persistence/FilmLibraryRepository.kt @@ -0,0 +1,87 @@ +package com.project.movienight.adapters.persistence + +import com.project.movienight.domain.model.FilmLibrary +import org.springframework.jdbc.core.JdbcTemplate +import org.springframework.stereotype.Repository + +@Repository +class FilmLibraryRepository(private val jdbc: JdbcTemplate) { + + fun findById(id: Int): FilmLibrary? = + jdbc.queryForObject( + "SELECT * FROM favorites WHERE id = ?", + { rs, _ -> + FilmLibrary( + id = rs.getInt("id"), + userId = rs.getInt("userid"), + filmId = rs.getInt("film_id"), + comment = rs.getString("comment"), + isViewed = rs.getBoolean("is_viewed"), + ) + }, + id + ) + + fun findAllByUserId(userId: Int): List = + jdbc.query( + "SELECT * FROM favorites WHERE userid = ?", + { rs, _ -> + FilmLibrary( + id = rs.getInt("id"), + userId = rs.getInt("userid"), + filmId = rs.getInt("film_id"), + comment = rs.getString("comment"), + isViewed = rs.getBoolean("is_viewed"), + ) + }, + userId + ) + + fun findAll(): List = + jdbc.query( + "SELECT * FROM favorites" + ) { rs, _ -> + FilmLibrary( + id = rs.getInt("id"), + userId = rs.getInt("userid"), + filmId = rs.getInt("film_id"), + comment = rs.getString("comment"), + isViewed = rs.getBoolean("is_viewed"), + ) + } + + fun findTopN(limit: Int, sortBy: String = "id"): List = + jdbc.query( + "SELECT * FROM favorites ORDER BY $sortBy LIMIT ?", + { rs, _ -> + FilmLibrary( + id = rs.getInt("id"), + userId = rs.getInt("userid"), + filmId = rs.getInt("film_id"), + comment = rs.getString("comment"), + isViewed = rs.getBoolean("is_viewed"), + ) + }, + limit + ) + + fun save(library: FilmLibrary) { + jdbc.update( + """ + INSERT INTO favorites (userid, film_id, comment, is_viewed) + VALUES (?, ?, ?, ?) + ON CONFLICT (id) DO UPDATE + SET comment = ?, is_viewed = ? + """, + library.userId, library.filmId, library.comment, library.isViewed, + library.comment, library.isViewed + ) + } + + fun deleteById(id: Int) { + jdbc.update( + "DELETE FROM favorites WHERE id = ?", + id + ) + } +} diff --git a/src/main/kotlin/com/project/movienight/adapters/persistence/FilmRepository.kt b/src/main/kotlin/com/project/movienight/adapters/persistence/FilmRepository.kt new file mode 100644 index 0000000..5c9b209 --- /dev/null +++ b/src/main/kotlin/com/project/movienight/adapters/persistence/FilmRepository.kt @@ -0,0 +1,70 @@ +package com.project.movienight.adapters.persistence + +import com.project.movienight.domain.model.Film +import org.springframework.jdbc.core.JdbcTemplate +import org.springframework.stereotype.Repository +import java.time.LocalDate + +@Repository +class FilmRepository(private val jdbc: JdbcTemplate) { + + fun findById(id: Int): Film? = + jdbc.queryForObject( + "SELECT * FROM films WHERE id = ?", + { rs, _ -> + Film( + id = rs.getInt("id"), + title = rs.getString("title"), + genreId = rs.getInt("genre_id"), + issueDate = rs.getDate("issue_date")?.toLocalDate(), + ) + }, + id + ) + + fun findAll(): List = + jdbc.query( + "SELECT * FROM films" + ) { rs, _ -> + Film( + id = rs.getInt("id"), + title = rs.getString("title"), + genreId = rs.getInt("genre_id"), + issueDate = rs.getDate("issue_date")?.toLocalDate(), + ) + } + + fun findTopN(limit: Int, sortBy: String = "title"): List = + jdbc.query( + "SELECT * FROM films ORDER BY $sortBy LIMIT ?", + { rs, _ -> + Film( + id = rs.getInt("id"), + title = rs.getString("title"), + genreId = rs.getInt("genre_id"), + issueDate = rs.getDate("issue_date")?.toLocalDate(), + ) + }, + limit + ) + + fun save(film: Film) { + jdbc.update( + """ + INSERT INTO films (title, genre_id, issue_date) + VALUES (?, ?, ?) + ON CONFLICT (id) DO UPDATE + SET title = ?, genre_id = ?, issue_date = ? + """, + film.title, film.genreId, film.issueDate, + film.title, film.genreId, film.issueDate + ) + } + + fun deleteById(id: Int) { + jdbc.update( + "DELETE FROM films WHERE id = ?", + id + ) + } +} diff --git a/src/main/kotlin/com/project/movienight/adapters/persistence/UserRepository.kt b/src/main/kotlin/com/project/movienight/adapters/persistence/UserRepository.kt new file mode 100644 index 0000000..e453043 --- /dev/null +++ b/src/main/kotlin/com/project/movienight/adapters/persistence/UserRepository.kt @@ -0,0 +1,83 @@ +package com.project.movienight.adapters.persistence + +import com.project.movienight.domain.model.Film +import com.project.movienight.domain.model.User +import org.springframework.jdbc.core.JdbcTemplate +import org.springframework.stereotype.Repository +import java.util.UUID + +@Repository +class UserRepository(private val jdbc: JdbcTemplate) { + + fun findById(id: UUID): User? = + jdbc.queryForObject( + "SELECT * FROM users WHERE id = ?", + {rs, _ -> + User( + id = UUID.fromString(rs.getString("id")), + name = rs.getString("name"), + email = rs.getString("email"), + library = null // брать библиотеку пользователя лучше отдельным запросом, + // который будет в FilmLibraryRepository + ) + }, + id.toString() + ) + + fun save(user: User) { + jdbc.update( + """ + INSERT INTO users(id, name, email, library) + VALUES (:id, :name, :email, :library) + ON CONFLICT (id) + DO UPDATE SET name = :name, email = :email, library = :library + """, + user.id.toString(), user.name, user.email, user.library, + user.name, user.email, user.library + ) + } + + fun deleteById(id: UUID) { + jdbc.update( + "DELETE FROM users WHERE id = ?", + id.toString() + ) + } + + fun findByEmail(email: String): User? = + jdbc.queryForObject( + "SELECT * FROM users WHERE email = ?", + {rs, _ -> + User( + id = UUID.fromString(rs.getString("id")), + name = rs.getString("name"), + email = rs.getString("email"), + library = null + ) + }, + + ) + fun findTopN(limit: Int, sortBy: String = "name"): List = + jdbc.query( + "SELECT * FROM users ORDER BY $sortBy LIMIT ?", + { rs, _ -> + User( + id = UUID.fromString(rs.getString("id")), + name = rs.getString("name"), + email = rs.getString("email"), + library = null + ) + }, + limit + ) + + fun existsByEmail(email: String): Boolean { + val count = jdbc.queryForObject( + "SELECT COUNT(*) FROM users WHERE email = ?", + Int::class.java, + email + ) ?: 0 + return count > 0 + } + +} diff --git a/src/main/kotlin/com/project/movienight/domain/model/Film.kt b/src/main/kotlin/com/project/movienight/domain/model/Film.kt index 32122de..d1e6319 100644 --- a/src/main/kotlin/com/project/movienight/domain/model/Film.kt +++ b/src/main/kotlin/com/project/movienight/domain/model/Film.kt @@ -1,9 +1,10 @@ package com.project.movienight.domain.model -import java.util.UUID +import java.time.LocalDate data class Film( - val id: UUID, + val id: Int, val title: String, - val description: String, + val genreId: Int, + val issueDate: LocalDate?, ) diff --git a/src/main/kotlin/com/project/movienight/domain/model/FilmLibrary.kt b/src/main/kotlin/com/project/movienight/domain/model/FilmLibrary.kt index 2f6a724..040a474 100644 --- a/src/main/kotlin/com/project/movienight/domain/model/FilmLibrary.kt +++ b/src/main/kotlin/com/project/movienight/domain/model/FilmLibrary.kt @@ -1,8 +1,9 @@ package com.project.movienight.domain.model -import java.util.UUID - data class FilmLibrary( - val id: UUID, - val userId: UUID, + val id: Int, + val userId: Int, + val filmId: Int, + val comment: String?, + val isViewed: Boolean, ) diff --git a/src/main/resources/db/migration/.gitkeep b/src/main/resources/db/migration/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/resources/db/migration/V1__init.sql b/src/main/resources/db/migration/V1__init.sql new file mode 100644 index 0000000..da677c4 --- /dev/null +++ b/src/main/resources/db/migration/V1__init.sql @@ -0,0 +1,59 @@ +-- DROP SCHEMA public; +-- CREATE SCHEMA public AUTHORIZATION pg_database_owner; +-- COMMENT ON SCHEMA public IS 'standard public schema'; + +-- public.genres определение +-- Drop table +DROP TABLE if exists public.genres; +CREATE TABLE public.genres ( + id int4 GENERATED ALWAYS AS IDENTITY NOT NULL, + "name" varchar NULL, + CONSTRAINT genres_unique PRIMARY KEY (id) +); + + +-- public.users определение +-- Drop table +DROP TABLE if exists public.users; +CREATE TABLE public.users ( + id int4 GENERATED ALWAYS AS IDENTITY NOT NULL, + login varchar NOT NULL, + "password" varchar NOT NULL, + CONSTRAINT users_unique UNIQUE (id) +); + + +-- public.films определение +-- Drop table +DROP TABLE if exists public.films; +CREATE TABLE public.films ( + id int4 GENERATED ALWAYS AS IDENTITY NOT NULL, + title varchar NOT NULL, + genre_id int4 NOT NULL, + issue_date date NULL, + CONSTRAINT films_unique UNIQUE(id) +); + +DROP TABLE if exists public.film_genres; +CREATE TABLE public.film_genres ( + id int4 GENERATED ALWAYS AS IDENTITY NOT NULL, + genre_id int4 NOT NULL, + film_id int4 NOT NULL, + CONSTRAINT film_genres_genre_fk FOREIGN KEY (genre_id) REFERENCES public.genres(id), + CONSTRAINT film_genres_film_fk FOREIGN KEY (film_id) REFERENCES public.films(id) +); + + +-- Drop table +DROP TABLE if exists public.favorites; +CREATE TABLE public.favorites ( + id int4 GENERATED ALWAYS AS IDENTITY NOT NULL, + userid int4 NULL, + film_id int4 NULL, + "comment" varchar NULL, + is_viewed bool NULL, + CONSTRAINT favorites_unique PRIMARY KEY (id), + CONSTRAINT favorites_films_fk FOREIGN KEY (film_id) REFERENCES public.films(id), + CONSTRAINT favorites_users_fk FOREIGN KEY (user_id) REFERENCES public.users(id) +); +