correction creation partie, ajout dto correspondant

Springboot
Victor SOULIER 1 year ago
parent d519ef3554
commit cbebbe2cf2

@ -3,20 +3,30 @@ package fr.iut.sciencequest.sae.controllers;
import fr.iut.sciencequest.sae.assemblers.PartieModelAssembler; import fr.iut.sciencequest.sae.assemblers.PartieModelAssembler;
import fr.iut.sciencequest.sae.controllers.request.PartieRequest; import fr.iut.sciencequest.sae.controllers.request.PartieRequest;
import fr.iut.sciencequest.sae.dto.partie.PartieDTO; import fr.iut.sciencequest.sae.dto.partie.PartieDTO;
import fr.iut.sciencequest.sae.entities.Joueur;
import fr.iut.sciencequest.sae.entities.Partie; import fr.iut.sciencequest.sae.entities.Partie;
import fr.iut.sciencequest.sae.services.JeuService;
import fr.iut.sciencequest.sae.services.JoueurService;
import fr.iut.sciencequest.sae.services.PartieService; import fr.iut.sciencequest.sae.services.PartieService;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.modelmapper.ModelMapper; import org.modelmapper.ModelMapper;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@RestController @RestController
@AllArgsConstructor @AllArgsConstructor
@RequestMapping("/api/v1/partie") @RequestMapping("/api/v1/partie")
public class PartieController { public class PartieController {
private final PartieModelAssembler partieModelAssembler; private final PartieModelAssembler partieModelAssembler;
private final PartieService partieService; private final PartieService partieService;
private final JoueurService joueurService;
private final JeuService jeuService;
private final ModelMapper modelMapper; private final ModelMapper modelMapper;
@RequestMapping(value = "/{id}",method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/{id}",method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ -27,8 +37,12 @@ public class PartieController {
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
public Partie createPartie(@RequestBody PartieRequest request) { public PartieDTO createPartie(@RequestBody @Valid PartieRequest request) {
return this.partieService.create(request.getIdJeu(), request.getPseudo(), request.getThematiques(), request.getIdDifficulte()); Partie partie = new Partie();
partie.setJeu(this.jeuService.findById(request.getIdJeu()));
partie.setJoueurs(List.of(this.joueurService.findById(request.getIdJoueur())));
partie = this.partieService.create(partie);
return this.modelMapper.map(partie, PartieDTO.class);
} }
} }

@ -7,7 +7,7 @@ import java.util.List;
@Data @Data
public class PartieRequest { public class PartieRequest {
private Integer idJeu; private Integer idJeu;
private String pseudo; private int idJoueur;
private List<Integer> thematiques; private List<Integer> thematiques;
private Integer idDifficulte; private Integer idDifficulte;
} }

@ -0,0 +1,23 @@
package fr.iut.sciencequest.sae.dto.joueur;
import com.fasterxml.jackson.annotation.JsonInclude;
import fr.iut.sciencequest.sae.dto.partie.PartieDTO;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.springframework.hateoas.RepresentationModel;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class JoueurSimpleDTO extends RepresentationModel<JoueurSimpleDTO> {
@NotNull
private Integer id;
@NotBlank
private String pseudo;
}

@ -1,13 +1,14 @@
package fr.iut.sciencequest.sae.dto.partie; package fr.iut.sciencequest.sae.dto.partie;
import fr.iut.sciencequest.sae.dto.jeu.JeuDTO; import fr.iut.sciencequest.sae.dto.jeu.JeuDTO;
import fr.iut.sciencequest.sae.dto.joueur.JoueurDTO; import fr.iut.sciencequest.sae.dto.joueur.JoueurSimpleDTO;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.*; import lombok.*;
import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.RepresentationModel;
import java.util.List; import java.util.List;
import java.util.Set;
@Data @Data
@ -21,7 +22,7 @@ public class PartieDTO extends RepresentationModel<PartieDTO> {
@NotEmpty @NotEmpty
private String codeInvitation; private String codeInvitation;
@NotEmpty @NotEmpty
private List<JoueurDTO> joueurs; private List<JoueurSimpleDTO> joueurs;
@NotNull @NotNull
private JeuDTO jeu; private JeuDTO jeu;
} }

@ -1,10 +1,13 @@
package fr.iut.sciencequest.sae.entities; package fr.iut.sciencequest.sae.entities;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ -20,8 +23,9 @@ public class Joueur {
@Column(unique = true) @Column(unique = true)
private String pseudo; private String pseudo;
@JsonBackReference
@ManyToOne @ManyToOne
@JoinColumn(name = "idpartie") @JoinColumn(name = "idpartie")
@JsonIgnore @Fetch(FetchMode.JOIN)
private Partie partie; private Partie partie;
} }

@ -1,5 +1,7 @@
package fr.iut.sciencequest.sae.entities; package fr.iut.sciencequest.sae.entities;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
@ -18,19 +20,21 @@ public class Partie {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; private Integer id;
@Column(name = "codeinvitation", unique = true, nullable = false) @Column(name = "codeinvitation", unique = true, nullable = false) //default value : see Schema.sql
private String codeInvitation; private String codeInvitation;
@OneToMany(mappedBy = "partie", fetch = FetchType.EAGER) @JsonManagedReference
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
@JoinColumn(name = "idpartie")
private List<Joueur> joueurs; private List<Joueur> joueurs;
@ManyToOne @ManyToOne
@JoinColumn(name="idjeu", nullable = false) @JoinColumn(name="idjeu", nullable = false)
private Jeu jeu; private Jeu jeu;
@Column(name = "status") @Column(name = "status") //default value : see Schema.sql
private String status; private String status;
@Column(name = "datecreation") @Column(name = "datecreation") //default value : see Schema.sql
private Date dateCreation; private Date dateCreation;
} }

@ -1,5 +1,9 @@
package fr.iut.sciencequest.sae.exceptions.notFound; package fr.iut.sciencequest.sae.exceptions.notFound;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class JeuNotFoundException extends EntityNotFoundException{ public class JeuNotFoundException extends EntityNotFoundException{
public JeuNotFoundException(int id) { public JeuNotFoundException(int id) {
super("Jeu", id); super("Jeu", id);

@ -0,0 +1,11 @@
package fr.iut.sciencequest.sae.exceptions.notFound;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class JoueurNotFoundException extends EntityNotFoundException{
public JoueurNotFoundException(int id) {
super("Joueur", id);
}
}

@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND) @ResponseStatus(HttpStatus.NOT_FOUND)
public class PartieNotFoundException extends EntityNotFoundException{ public class PartieNotFoundException extends EntityNotFoundException{
public PartieNotFoundException(String message, int id) { public PartieNotFoundException(int id) {
super(message, id); super("partie", id);
} }
} }

@ -0,0 +1,22 @@
package fr.iut.sciencequest.sae.services;
import fr.iut.sciencequest.sae.entities.Jeu;
import fr.iut.sciencequest.sae.entities.Joueur;
import fr.iut.sciencequest.sae.exceptions.notFound.JeuNotFoundException;
import fr.iut.sciencequest.sae.exceptions.notFound.JoueurNotFoundException;
import fr.iut.sciencequest.sae.repositories.JeuRepository;
import fr.iut.sciencequest.sae.repositories.JoueurRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@AllArgsConstructor
@Service
public class JeuService {
private final JeuRepository jeuRepository;
public Jeu findById(int id) {
return this.jeuRepository.findById(id).orElseThrow(() ->
new JeuNotFoundException(id)
);
}
}

@ -0,0 +1,21 @@
package fr.iut.sciencequest.sae.services;
import fr.iut.sciencequest.sae.entities.Joueur;
import fr.iut.sciencequest.sae.entities.Thematique;
import fr.iut.sciencequest.sae.exceptions.notFound.JoueurNotFoundException;
import fr.iut.sciencequest.sae.exceptions.notFound.ThematiqueNotFoundException;
import fr.iut.sciencequest.sae.repositories.JoueurRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@AllArgsConstructor
@Service
public class JoueurService {
private final JoueurRepository joueurRepository;
public Joueur findById(int id) {
return this.joueurRepository.findById(id).orElseThrow(() ->
new JoueurNotFoundException(id)
);
}
}

@ -1,10 +1,11 @@
package fr.iut.sciencequest.sae.services; package fr.iut.sciencequest.sae.services;
import fr.iut.sciencequest.sae.entities.Joueur; import fr.iut.sciencequest.sae.entities.*;
import fr.iut.sciencequest.sae.entities.Partie; import fr.iut.sciencequest.sae.exceptions.DuplicatedIdException;
import fr.iut.sciencequest.sae.exceptions.MalformedPartyException; import fr.iut.sciencequest.sae.exceptions.MalformedPartyException;
import fr.iut.sciencequest.sae.exceptions.notFound.JeuNotFoundException; import fr.iut.sciencequest.sae.exceptions.notFound.JeuNotFoundException;
import fr.iut.sciencequest.sae.exceptions.notFound.PartieNotFoundException; import fr.iut.sciencequest.sae.exceptions.notFound.PartieNotFoundException;
import fr.iut.sciencequest.sae.exceptions.notFound.ThematiqueNotFoundException;
import fr.iut.sciencequest.sae.repositories.*; import fr.iut.sciencequest.sae.repositories.*;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext; import jakarta.persistence.PersistenceContext;
@ -24,47 +25,31 @@ public class PartieService {
private final UtilisateurRepository utilisateurRepository; private final UtilisateurRepository utilisateurRepository;
private final ThematiqueRepository thematiqueRepository; private final ThematiqueRepository thematiqueRepository;
private final DifficulteRepository difficulteRepository; private final DifficulteRepository difficulteRepository;
private final JoueurService joueurService;
@PersistenceContext @PersistenceContext
private EntityManager entityManager; private EntityManager entityManager;
public Partie findById(int id) { public Partie findById(int id) {
return this.partieRepository.findById(id).orElseThrow(() -> return this.partieRepository.findById(id).orElseThrow(() ->
new PartieNotFoundException("Partie", id) new PartieNotFoundException(id)
); );
} }
@Transactional public Partie update(Partie partie){
public Partie create(Integer idJeu, String pseudo, List<Integer> thematiques, Integer idDifficulte) { if(!this.partieRepository.existsById(partie.getId())){
// Création du joueur throw new PartieNotFoundException(partie.getId());
Joueur joueur = new Joueur(); }
joueur.setPseudo(pseudo); Partie savedPartie = this.partieRepository.save(partie);
return this.findById(savedPartie.getId());
// Sauvegarder le joueur }
joueur = joueurRepository.save(joueur);
// Création de la partie
Partie partie = new Partie(
0,
entityManager.createNativeQuery("SELECT make_uid()").getSingleResult().toString(),
List.of(joueur),
jeuRepository.findById(idJeu).orElseThrow(() -> new JeuNotFoundException(idJeu)),
"pending",
new Date()
);
// Sauvegarder la partie pour générer le codeInvitation
partie = partieRepository.save(partie);
// Modification du joueur pour ajouter la partie
entityManager.createNativeQuery("UPDATE joueur SET idpartie = ? WHERE id = ?")
.setParameter(1, partie.getId())
.setParameter(2, joueur.getId())
.executeUpdate();
// Récupérer la partie mise à jour avec le joueur public Partie create(Partie partie){
return partieRepository.findById(partie.getId()) if(partie.getId() != null && this.partieRepository.existsById(partie.getId())){
.orElseThrow(MalformedPartyException::new); throw new DuplicatedIdException();
}
Partie savedPartie = this.partieRepository.save(partie);
return this.findById(savedPartie.getId());
} }
} }

@ -111,10 +111,10 @@ CREATE OR REPLACE FUNCTION make_uid() RETURNS text AS
CREATE TABLE Partie( CREATE TABLE Partie(
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
codeInvitation varchar(5) NOT NULL UNIQUE, codeInvitation varchar(5) UNIQUE DEFAULT make_uid(),
idJeu integer REFERENCES Jeu(id), idJeu integer REFERENCES Jeu(id),
status varchar(128) NOT NULL DEFAULT 'pending', status varchar(128) DEFAULT 'pending',
dateCreation timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP dateCreation timestamp DEFAULT CURRENT_TIMESTAMP
); );
-- JOUEUR -- JOUEUR
@ -150,6 +150,35 @@ CREATE TABLE Decouvrir(
PRIMARY KEY (idUtilisateur, idScientifique) PRIMARY KEY (idUtilisateur, idScientifique)
); );
-- TRIGGERS
CREATE OR REPLACE FUNCTION force_default_partie()
RETURNS TRIGGER
AS '
DECLARE
BEGIN
IF OLD.codeInvitation IS NULL THEN
NEW.codeInvitation = make_uid();
END IF;
IF OLD.status IS NULL THEN
NEW.status = ''pending'';
END IF;
IF OLD.dateCreation IS NULL THEN
NEW.dateCreation = CURRENT_TIMESTAMP;
END IF;
RETURN NEW;
END;
'
LANGUAGE plpgsql;
CREATE TRIGGER check_force_default_partie
BEFORE INSERT
ON Partie
FOR EACH ROW
EXECUTE PROCEDURE force_default_partie();
-- INSERTS -- INSERTS
@ -184,8 +213,12 @@ VALUES
('Albert Einstein', 2, 2), ('Albert Einstein', 2, 2),
('Sophie Germain', 3, 3); ('Sophie Germain', 3, 3);
-- Partie
INSERT INTO Partie(codeInvitation, idJeu) VALUES ('abcde', 1);
-- Utilisateurs -- Utilisateurs
INSERT INTO Joueur(pseudo) VALUES ('moi, le meilleur joueur du monde'); --id = 1 INSERT INTO Joueur(pseudo, idPartie) VALUES ('moi, le meilleur joueur du monde', 1); --id = 1
INSERT INTO Utilisateur(idJoueur,email,password) VALUES (1, 'joueur','$2y$10$juGnlWC9cS19popEKLZsYeir0Jl39k6hDl0dpaCix00FDcdiEbtmS'); INSERT INTO Utilisateur(idJoueur,email,password) VALUES (1, 'joueur','$2y$10$juGnlWC9cS19popEKLZsYeir0Jl39k6hDl0dpaCix00FDcdiEbtmS');
-- mdp = test -- mdp = test
@ -195,6 +228,3 @@ INSERT INTO decouvrir(idUtilisateur,idScientifique) VALUES (1,1);
-- Admin -- Admin
INSERT INTO Admin(id,email,password) VALUES (1, 'admin','$2y$10$juGnlWC9cS19popEKLZsYeir0Jl39k6hDl0dpaCix00FDcdiEbtmS'); INSERT INTO Admin(id,email,password) VALUES (1, 'admin','$2y$10$juGnlWC9cS19popEKLZsYeir0Jl39k6hDl0dpaCix00FDcdiEbtmS');
-- mdp = test -- mdp = test
-- Partie
INSERT INTO Partie(codeInvitation, idJeu) VALUES ('abcde', 1);
Loading…
Cancel
Save