diff --git a/pom.xml b/pom.xml index 982a8de..1e922bd 100644 --- a/pom.xml +++ b/pom.xml @@ -30,10 +30,6 @@ 21 - - org.springframework.boot - spring-boot-starter-data-jpa - org.springframework.boot spring-boot-starter-data-rest @@ -58,6 +54,10 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-data-jdbc + diff --git a/src/main/java/com/guams/review/ReViewApplication.java b/src/main/java/com/guams/review/ReViewApplication.java index 7f0787d..496fcac 100644 --- a/src/main/java/com/guams/review/ReViewApplication.java +++ b/src/main/java/com/guams/review/ReViewApplication.java @@ -1,7 +1,5 @@ package com.guams.review; -import com.guams.review.modele.Post; -import com.guams.review.modele.User; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/com/guams/review/configuration/Advice.java b/src/main/java/com/guams/review/configuration/Advice.java new file mode 100644 index 0000000..e835bbd --- /dev/null +++ b/src/main/java/com/guams/review/configuration/Advice.java @@ -0,0 +1,16 @@ +package com.guams.review.configuration; + +import com.guams.review.exception.NotFoundException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class Advice { + + @ExceptionHandler(value = NotFoundException.class) + public ResponseEntity handleNotFound(NotFoundException exception) { + return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); + } +} diff --git a/src/main/java/com/guams/review/controller/PostController.java b/src/main/java/com/guams/review/controller/PostController.java index 9d9890e..9982f4f 100644 --- a/src/main/java/com/guams/review/controller/PostController.java +++ b/src/main/java/com/guams/review/controller/PostController.java @@ -1,82 +1,62 @@ package com.guams.review.controller; -import com.guams.review.modele.Post; -import com.guams.review.modele.User; -import com.guams.review.repository.PostRepository; -import com.guams.review.repository.UserRepository; +import com.guams.review.exception.NotFoundException; +import com.guams.review.modele.dao.Post; import com.guams.review.service.PostService; -import org.springframework.http.*; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.time.LocalDate; import java.util.List; -import java.util.Optional; +@RequiredArgsConstructor @RestController @RequestMapping("/api/posts") -public class PostController -{ +public class PostController { + private final PostService postService; - private final PostRepository postRepository; - private final UserRepository userRepository; - - - public PostController(PostService postService, PostRepository postRepository, UserRepository userRepository) { - this.postService = postService; - this.postRepository = postRepository; - this.userRepository = userRepository; - } @GetMapping - public ResponseEntity> getPosts() - { - return new ResponseEntity<>(postRepository.findAll(), new HttpHeaders(), HttpStatus.OK); + public List listPosts() { + return postService.list(); } - @GetMapping("{post-id}") - public ResponseEntity getPost(@PathVariable("post-id") Long id) - { - Optional post = postRepository.findById(id); - if (post.isPresent()) { - return new ResponseEntity<>(post.get(), new HttpHeaders(), HttpStatus.OK); - } - return new ResponseEntity<>(HttpStatus.NOT_FOUND); + @GetMapping("/{id}") + public Post findPost(@PathVariable Long id) { + return postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); + } + + @PutMapping("/{id}") + public void updatePost(@PathVariable Long id, @RequestBody Post updatedPost) { + Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); + postService.insert(updatedPost + .setId(postToUpdate.getId()) + .setIllustration(postToUpdate.getIllustration()) + .setPublicationDate(postToUpdate.getPublicationDate())); + } + + @PutMapping(value = "{id}/illustration", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) + public void updateIllustration(@PathVariable Long id, @RequestPart MultipartFile illustration) throws IOException { + Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); + postService.insert(postToUpdate.setIllustration(illustration.getBytes())); } @PostMapping - public ResponseEntity getPost(@RequestBody Post post, @RequestParam Long userId) - { - Optional userExists = userRepository.findById(userId); - if (userExists.isPresent()) { - post.setUser(userExists.get()); - postRepository.save(post); - return new ResponseEntity<>("Created", HttpStatus.CREATED); - } - return new ResponseEntity<>("Erreur", HttpStatus.INTERNAL_SERVER_ERROR); + public ResponseEntity addPost(@RequestBody Post postToCreate) { + Assert.isNull(postToCreate.getId(), "Post id must be null"); + return new ResponseEntity<>(postService.insert(postToCreate.setPublicationDate(LocalDate.now())), HttpStatus.CREATED); } - @PutMapping("{post-id}") - public ResponseEntity updatePost(@PathVariable("post-id") Long id, @RequestBody Post post) - { - Optional postExists = postRepository.findById(id); - if (postExists.isPresent()) { - Post newPost = postExists.get(); - newPost.setTitle(post.getTitle()); - newPost.setBody(post.getBody()); - newPost.setImage(post.getImage()); - postRepository.save(newPost); - return new ResponseEntity<>("Updated", HttpStatus.OK); - } - return new ResponseEntity<>("Erreur", HttpStatus.NOT_FOUND); + @DeleteMapping("{id}") + public void deletePost(@PathVariable Long id) { + Post postToDelete = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); + postService.delete(postToDelete.getId()); } - @DeleteMapping("{post-id}") - public ResponseEntity deletePost(@PathVariable("post-id") Long id) - { - Optional postExists = postRepository.findById(id); - if (postExists.isPresent()) { - postRepository.delete(postExists.get()); - return new ResponseEntity<>("Deleted", HttpStatus.OK); - } - return new ResponseEntity<>("Erreur", HttpStatus.NOT_FOUND); - } } diff --git a/src/main/java/com/guams/review/controller/UserController.java b/src/main/java/com/guams/review/controller/UserController.java index e4c82ed..de02bc7 100644 --- a/src/main/java/com/guams/review/controller/UserController.java +++ b/src/main/java/com/guams/review/controller/UserController.java @@ -1,81 +1,14 @@ package com.guams.review.controller; -import com.guams.review.modele.User; -import com.guams.review.repository.UserRepository; import com.guams.review.service.UserService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; +import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; -import java.util.List; -import java.util.Optional; - @RestController @RequestMapping(path = "api/users") +@RequiredArgsConstructor public class UserController { + private final UserService userService; - private final UserRepository userRepository; - - @Autowired - public UserController(UserService userService, UserRepository userRepository) { - this.userService = userService; - this.userRepository = userRepository; - } - - @GetMapping - public ResponseEntity> getUsers() { - List users = userService.getUsers(); - return new ResponseEntity<>(users, new HttpHeaders(), HttpStatus.OK); - }; - - @GetMapping("/{user-id}") - public ResponseEntity getUser(@PathVariable("user-id") Long id) { - Optional exists = userRepository.findById(id); - if (exists.isPresent()) { - return new ResponseEntity<>(exists.get(), new HttpHeaders(), HttpStatus.OK); - } - return new ResponseEntity<>(null, new HttpHeaders(), HttpStatus.NOT_FOUND); - } - - @PostMapping - public ResponseEntity saveUser(@RequestBody User user) { - userService.saveUser(user); - Optional exists = userService.findById(user.getId()); - if (exists.isPresent()) { - return new ResponseEntity<>("Created", new HttpHeaders(), HttpStatus.CREATED); - } - return new ResponseEntity<>("Error", new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); - } - - @PutMapping("/{user-id}") - public ResponseEntity updateUser(@PathVariable("user-id") Long id, @RequestBody User user) - { - Optional exists = userService.findById(id); - if (exists.isPresent()) { - User newUser = exists.get(); - newUser.setLogin(user.getLogin()); - newUser.setPassword(user.getPassword()); - newUser.setPosts(user.getPosts()); - userService.saveUser(newUser); - return new ResponseEntity<>("Updated", new HttpHeaders(), HttpStatus.OK); - } - return new ResponseEntity<>("User not found", new HttpHeaders(), HttpStatus.NOT_FOUND); - } - - @DeleteMapping("{user-id}") - public ResponseEntity deleteUser(@PathVariable("user-id") Long id) - { - Optional exists = userService.findById(id); - if (exists.isPresent()) { - userRepository.delete(exists.get()); - return new ResponseEntity<>("Deleted", new HttpHeaders(), HttpStatus.OK); - - } - return new ResponseEntity<>("User not found", new HttpHeaders(), HttpStatus.NOT_FOUND); - - } } diff --git a/src/main/java/com/guams/review/exception/NotFoundException.java b/src/main/java/com/guams/review/exception/NotFoundException.java new file mode 100644 index 0000000..a521163 --- /dev/null +++ b/src/main/java/com/guams/review/exception/NotFoundException.java @@ -0,0 +1,7 @@ +package com.guams.review.exception; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/com/guams/review/modele/Post.java b/src/main/java/com/guams/review/modele/Post.java deleted file mode 100644 index 2841427..0000000 --- a/src/main/java/com/guams/review/modele/Post.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.guams.review.modele; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.*; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -@Entity -@Getter -@Table(name = "POST") -public class Post -{ - @Id() - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - @Column(name = "TITLE", nullable = false) - private String title; - @Column(name = "BODY", nullable = false) - private String body; - @Column(name = "IMAGE") - private String image; - @ManyToOne - @JoinColumn(name = "USER_ID", nullable = false) - @JsonIgnore // Pour pas avoir un json infini - private User user; - - public Post() - {} - - - public Post setId(Long id) { - this.id = id; - return this; - } - - public Post setTitle(String title) { - this.title = title; - return this; - } - - public Post setBody(String body) { - this.body = body; - return this; - } - - public Post setImage(String image) { - this.image = image; - return this; - } - - public Post setUser(User user) { - this.user = user; - return this; - } -} diff --git a/src/main/java/com/guams/review/modele/PostRepository.java b/src/main/java/com/guams/review/modele/PostRepository.java new file mode 100644 index 0000000..491693c --- /dev/null +++ b/src/main/java/com/guams/review/modele/PostRepository.java @@ -0,0 +1,12 @@ +package com.guams.review.modele; + +import com.guams.review.modele.dao.Post; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface PostRepository extends CrudRepository { + List findAll(); +} diff --git a/src/main/java/com/guams/review/modele/User.java b/src/main/java/com/guams/review/modele/User.java deleted file mode 100644 index 09fab99..0000000 --- a/src/main/java/com/guams/review/modele/User.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.guams.review.modele; - - -import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.*; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.util.List; - - -@Entity -@Getter -@Table(name = "USERS") -public class User { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "LOGIN", nullable = false, unique = true) - private String login; - - @Column(name = "PASSWORD", nullable = false) - private String password; - - @OneToMany(mappedBy = "user") - private List posts; - - - public User setId(Long id) { - this.id = id; - return this; - } - - public User setLogin(String login) { - this.login = login; - return this; - } - - public User setPassword(String password) { - this.password = password; - return this; - } - - public User setPosts(List posts) { - this.posts = posts; - return this; - } -} \ No newline at end of file diff --git a/src/main/java/com/guams/review/modele/UserRepository.java b/src/main/java/com/guams/review/modele/UserRepository.java new file mode 100644 index 0000000..23d9242 --- /dev/null +++ b/src/main/java/com/guams/review/modele/UserRepository.java @@ -0,0 +1,9 @@ +package com.guams.review.modele; + +import com.guams.review.modele.dao.User; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository extends CrudRepository { +} diff --git a/src/main/java/com/guams/review/modele/dao/Post.java b/src/main/java/com/guams/review/modele/dao/Post.java new file mode 100644 index 0000000..ed7d8a8 --- /dev/null +++ b/src/main/java/com/guams/review/modele/dao/Post.java @@ -0,0 +1,32 @@ +package com.guams.review.modele.dao; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDate; + +@Getter +@Setter +@Accessors(chain = true) +@Table(name = "post") +public class Post { + @Id + Long id; + @Column("description") + String description; + @Column("illustration") + byte[] illustration; + @Column("title") + String title; + @Column("body") + String body; + @Column("category") + String category; + @Column("publication_date") + LocalDate publicationDate; + +} diff --git a/src/main/java/com/guams/review/modele/dao/User.java b/src/main/java/com/guams/review/modele/dao/User.java new file mode 100644 index 0000000..06dd681 --- /dev/null +++ b/src/main/java/com/guams/review/modele/dao/User.java @@ -0,0 +1,27 @@ +package com.guams.review.modele.dao; + + +import lombok.Getter; +import lombok.experimental.Accessors; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + + +@Getter +@Accessors(chain = true) +@Table(name = "author") +public class User { + + @Id + Long id; + + @Column("name") + String name; + + @Column("password") + String password; + + @Column("profile_picture") + byte[] profilePicture; +} \ No newline at end of file diff --git a/src/main/java/com/guams/review/repository/PostRepository.java b/src/main/java/com/guams/review/repository/PostRepository.java deleted file mode 100644 index f20a051..0000000 --- a/src/main/java/com/guams/review/repository/PostRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.guams.review.repository; - -import com.guams.review.modele.Post; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface PostRepository extends JpaRepository { -} diff --git a/src/main/java/com/guams/review/repository/UserRepository.java b/src/main/java/com/guams/review/repository/UserRepository.java deleted file mode 100644 index 761a7a5..0000000 --- a/src/main/java/com/guams/review/repository/UserRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.guams.review.repository; - -import com.guams.review.modele.User; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface UserRepository extends JpaRepository -{ -} diff --git a/src/main/java/com/guams/review/service/PostService.java b/src/main/java/com/guams/review/service/PostService.java index 14933c6..92c5b9c 100644 --- a/src/main/java/com/guams/review/service/PostService.java +++ b/src/main/java/com/guams/review/service/PostService.java @@ -1,19 +1,35 @@ package com.guams.review.service; -import com.guams.review.repository.PostRepository; -import org.springframework.beans.factory.annotation.Autowired; +import com.guams.review.exception.NotFoundException; +import com.guams.review.modele.dao.Post; +import com.guams.review.modele.PostRepository; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Optional; + @Service +@RequiredArgsConstructor public class PostService { - public PostRepository postRepository; + private final PostRepository postRepository; - @Autowired - public PostService(PostRepository postRepository) - { - this.postRepository = postRepository; + public List list() { + return postRepository.findAll(); + } + + public Optional findById(Long id) { + return postRepository.findById(id); + } + + public Post insert(Post post) { + return postRepository.save(post); + } + + public void delete(Long id) { + postRepository.deleteById(id); } } diff --git a/src/main/java/com/guams/review/service/UserService.java b/src/main/java/com/guams/review/service/UserService.java index 2709826..80fd082 100644 --- a/src/main/java/com/guams/review/service/UserService.java +++ b/src/main/java/com/guams/review/service/UserService.java @@ -1,37 +1,16 @@ package com.guams.review.service; -import com.guams.review.modele.Post; -import com.guams.review.modele.User; -import com.guams.review.repository.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; +import com.guams.review.modele.dao.User; +import com.guams.review.modele.UserRepository; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import java.util.List; import java.util.Optional; @Service +@RequiredArgsConstructor public class UserService { private final UserRepository userRepository; - @Autowired - public UserService(UserRepository userRepository) { - this.userRepository = userRepository; - } - - public List getUsers() - { - return userRepository.findAll(); - } - - public void saveUser(User user) - { - userRepository.save(user); - } - - public Optional findById(Long id) - { - return userRepository.findById(id); - } - } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f8afed5..d6d3e00 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,4 @@ spring.application.name=reView -spring.datasource.url=jdbc:postgresql://localhost:5432/review +spring.datasource.url=jdbc:postgresql://localhost:5432/reviewDB spring.datasource.username=postgres -spring.datasource.password=Azerty1234 -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.show-sql=true \ No newline at end of file +spring.datasource.password=Azerty1234 \ No newline at end of file diff --git a/src/main/resources/script.sql b/src/main/resources/script.sql new file mode 100644 index 0000000..7ee4925 --- /dev/null +++ b/src/main/resources/script.sql @@ -0,0 +1,36 @@ +drop extension if exists pgcrypto; +drop table if exists publication; +drop table if exists post; +drop table if exists author; + +create extension if not exists pgcrypto; + +create table author +( + id uuid default gen_random_uuid() primary key, + name varchar(255) not null, + password text not null, + profile_picture bytea +); + +create table post +( + id serial primary key, + description varchar(512) not null, + illustration bytea, + title varchar(50) not null, + body text not null, + category varchar(50) not null, + publication_date date not null +); + +create table publication +( + author_fk uuid, + post_fk serial, + foreign key (author_fk) references author (id), + foreign key (post_fk) references post (id) +); + +-- insert into author (name, password, profile_picture) +-- values ('John Doe', crypt('your_password', gen_salt('bf')), null);