diff --git a/pom.xml b/pom.xml index 310652a..7f21981 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ checkstyle.xml 1.5.5.Final 0.2.0 + 4.28.0 @@ -71,6 +72,12 @@ spring-boot-starter-web + + org.liquibase + liquibase-core + ${liquibase.version} + + @@ -114,6 +121,15 @@ + + org.liquibase + liquibase-maven-plugin + ${liquibase.version} + + src/main/resources/liquibase.properties + + + org.apache.maven.plugins maven-compiler-plugin diff --git a/src/main/java/mate/academy/controller/BookController.java b/src/main/java/mate/academy/controller/BookController.java index be94dfd..ae278f5 100644 --- a/src/main/java/mate/academy/controller/BookController.java +++ b/src/main/java/mate/academy/controller/BookController.java @@ -4,12 +4,17 @@ import lombok.RequiredArgsConstructor; import mate.academy.dto.BookDto; import mate.academy.dto.CreateBookRequestDto; +import mate.academy.dto.UpdateBookRequestDto; import mate.academy.service.BookService; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor @@ -32,4 +37,16 @@ public BookDto save(@RequestBody CreateBookRequestDto requestDto) { public BookDto getBookById(@PathVariable Long id) { return bookService.getBookById(id); } + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping("/{id}") + public void delete(@PathVariable Long id) { + bookService.deleteById(id); + } + + @ResponseStatus(HttpStatus.OK) + @PutMapping("/{id}") + public BookDto updateBook(@PathVariable Long id, @RequestBody UpdateBookRequestDto requestDto) { + return bookService.updateBookDetails(id, requestDto); + } } diff --git a/src/main/java/mate/academy/dto/UpdateBookRequestDto.java b/src/main/java/mate/academy/dto/UpdateBookRequestDto.java new file mode 100644 index 0000000..e444d7c --- /dev/null +++ b/src/main/java/mate/academy/dto/UpdateBookRequestDto.java @@ -0,0 +1,14 @@ +package mate.academy.dto; + +import java.math.BigDecimal; +import lombok.Data; + +@Data +public class UpdateBookRequestDto { + private String title; + private String author; + private String isbn; + private BigDecimal price; + private String description; + private String coverImage; +} diff --git a/src/main/java/mate/academy/mapper/BookMapper.java b/src/main/java/mate/academy/mapper/BookMapper.java index 5d93334..3bd613b 100644 --- a/src/main/java/mate/academy/mapper/BookMapper.java +++ b/src/main/java/mate/academy/mapper/BookMapper.java @@ -3,14 +3,19 @@ import mate.academy.config.MapperConfig; import mate.academy.dto.BookDto; import mate.academy.dto.CreateBookRequestDto; +import mate.academy.dto.UpdateBookRequestDto; import mate.academy.model.Book; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; @Mapper(config = MapperConfig.class) public interface BookMapper { BookDto toDto(Book book); + @Mapping(target = "id", ignore = true) + void updateBookFromDto(UpdateBookRequestDto dto, @MappingTarget Book entity); + @Mapping(target = "id", ignore = true) Book toModel(CreateBookRequestDto requestDto); } diff --git a/src/main/java/mate/academy/model/Book.java b/src/main/java/mate/academy/model/Book.java index a0b6857..fb88fc5 100644 --- a/src/main/java/mate/academy/model/Book.java +++ b/src/main/java/mate/academy/model/Book.java @@ -9,10 +9,14 @@ import java.math.BigDecimal; import lombok.Getter; import lombok.Setter; +import org.hibernate.annotations.SQLDelete; +import org.hibernate.annotations.SQLRestriction; @Entity @Getter @Setter +@SQLDelete(sql = "UPDATE books set is_deleted = true WHERE id=?") +@SQLRestriction("is_deleted=false") @Table(name = "books") public class Book { @Id @@ -28,4 +32,6 @@ public class Book { private BigDecimal price; private String description; private String coverImage; + @Column(nullable = false, name = "is_deleted", columnDefinition = "BIT") + private boolean isDeleted = false; } diff --git a/src/main/java/mate/academy/service/BookService.java b/src/main/java/mate/academy/service/BookService.java index 3e7d5b1..125eda6 100644 --- a/src/main/java/mate/academy/service/BookService.java +++ b/src/main/java/mate/academy/service/BookService.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import mate.academy.dto.BookDto; import mate.academy.dto.CreateBookRequestDto; +import mate.academy.dto.UpdateBookRequestDto; import mate.academy.exception.EntityNotFoundException; import mate.academy.mapper.BookMapper; import mate.academy.model.Book; @@ -34,4 +35,15 @@ public BookDto getBookById(Long id) { () -> new EntityNotFoundException("Book with id " + id + " not found")); return bookMapper.toDto(book); } + + public void deleteById(Long id) { + bookRepository.deleteById(id); + } + + public BookDto updateBookDetails(Long id, UpdateBookRequestDto requestDto) { + Book book = bookRepository.findById(id) + .orElseThrow(() -> new EntityNotFoundException("Book not found with id " + id)); + bookMapper.updateBookFromDto(requestDto,book); + return bookMapper.toDto(bookRepository.save(book)); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2bb012b..f6faea6 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,8 +4,10 @@ spring.datasource.url=jdbc:mysql://localhost:3306/bookStore spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.hibernate.ddl-auto=validate spring.jpa.show-sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect +spring.jpa.properties.hibernate.type=bit + server.servlet.context-path=/api diff --git a/src/main/resources/db/changelog/changes/01-create-books-table.yaml b/src/main/resources/db/changelog/changes/01-create-books-table.yaml new file mode 100644 index 0000000..6551985 --- /dev/null +++ b/src/main/resources/db/changelog/changes/01-create-books-table.yaml @@ -0,0 +1,48 @@ +databaseChangeLog: + - changeSet: + id: create-book-table + author: mate_academy + changes: + - createTable: + tableName: books + columns: + - column: + name: id + type: BIGINT + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: title + type: VARCHAR(255) + constraints: + nullable: false + - column: + name: author + type: VARCHAR(255) + constraints: + nullable: false + - column: + name: isbn + type: VARCHAR(255) + constraints: + nullable: false + unique: true + - column: + name: price + type: DECIMAL(19, 2) + constraints: + nullable: false + - column: + name: description + type: TEXT + - column: + name: cover_image + type: VARCHAR(255) + - column: + name: is_deleted + type: BIT + defaultValueBoolean: false + constraints: + nullable: false diff --git a/src/main/resources/db/changelog/changes/02-modify-is_deleted-column-type.yaml b/src/main/resources/db/changelog/changes/02-modify-is_deleted-column-type.yaml new file mode 100644 index 0000000..91fa103 --- /dev/null +++ b/src/main/resources/db/changelog/changes/02-modify-is_deleted-column-type.yaml @@ -0,0 +1,9 @@ +databaseChangeLog: + - changeSet: + id: modify-is_deleted-column-type + author: mate_academy + changes: + - modifyDataType: + columnName: is_deleted + newDataType: BIT + tableName: books diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml new file mode 100644 index 0000000..dbfe20f --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -0,0 +1,5 @@ +databaseChangeLog: + - include: + file: db/changelog/changes/01-create-books-table.yaml + - include: + file: db/changelog/changes/02-modify-is_deleted-column-type.yaml \ No newline at end of file diff --git a/src/main/resources/liquibase.properties b/src/main/resources/liquibase.properties new file mode 100644 index 0000000..ae8adf3 --- /dev/null +++ b/src/main/resources/liquibase.properties @@ -0,0 +1,4 @@ +url=jdbc:mysql://localhost:3306/BookStore +username=root +password=12345678 +changeLogFile=/db/changelog/db.changelog-master.yaml