sequenceDiagram participant Vue participant Service participant Dao participant BDD Note over Vue: MenuJoueurVue Vue->>Vue: Choice "S'inscrire à un tournoi" Note over Vue: InscriptionTournoiVue Vue->>Service: TournoiService.lister_tous() Note over Service: TournoiService Service->>Dao: TournoiDao.lister_tous() Dao->>BDD: SELECT * FROM tournoi BDD-->>Dao: tournois JSON Dao-->>Service: list[Tournoi] Service-->>Vue: list[Tournoi] Vue->>Vue: Affiche la liste, option Retour<br> Attend une sélection Vue->>Service: JoueurService.s_inscrire_tournoi(tournoi) Note over Service: JoueurService Service->>Dao: InscriptionDao.est_inscrit(joueur,tournoi) Dao->>BDD: SELECT COUNT(*)<br> FROM inscription<br> WHERE id_joueur=? <br>AND id_tournoi=? BDD-->>Dao: true/false Dao-->>Service: true/false Service-->>Vue: if true, back to MenuJoueurVue Service->>Dao: TournoiDao.est_complet(tournoi) Dao->>BDD: SELECT FROM tournoi, inscription BDD-->>Dao: true/false Dao-->>Service: true/false Service-->>Vue: if false, back to MenuJoueurVue Service-->>Dao: InscriptionDao.creer(tournoi, joueur) Dao->>BDD: INSERT INTO inscription BDD-->>Dao: true/false Dao-->>Service: true/false Service-->>Vue: back to MenuJoueurVue
Bonus: revise layer programming
Objectives
For the moment, this application simply contains a list of players.
The aim will be to create a feature that will allow players to register for tournaments.
We will proceed step by step.
Before you start
You will work on a fork or a copy of the repo ENSAI-2A-projet-info-template.
1 Initialisation of views
If this item is selected, you must now access the list of tournaments in a new view.
It will display the list of tournaments and allow the user to choose which one they want to register for.
- You will need a service method that returns the list of all tournaments
- TournoiService.lister_tous() -> list[Tournoi]
- The list of tournaments will be available in the database
- a service method should not communicate directly with a database; that is the role of a DAO
- The dao method TournoiDao.lister_tous() -> list[Tournoi] will communicate with the database to transfer the list of tournaments to the service method
- To transfer tournament lists, you must also create Tournoi business object
Now we are beginning to get an idea of the methods and objects to create.
2 Create the business object
Let us begin by creating the Tournoi business object.
Business objects mainly contain attributes and few methods. They are primarily used to transfer information between layers.
-
- attributes: id_tournoi, nom, ville, capacite_max
- add a constructor with all attributes
3 Map it with a database table
Usually, the business object class and its attributes correspond to the table and columns in the database.
Assuming that a player can participate in several tournaments and that a tournament can have several players, it is therefore necessary to create a table to keep track of which player is participating in which tournament.
CREATE TABLE tournoi (
PRIMARY KEY,
id_tournoi SERIAL VARCHAR(100) NOT NULL,
nom VARCHAR(100) NOT NULL,
ville INT CHECK (capacite_max > 0)
capacite_max
);
CREATE TABLE inscription (
PRIMARY KEY,
id_inscription SERIAL INT NOT NULL REFERENCES tournoi(id_tournoi),
id_tournoi INT NOT NULL REFERENCES joueur(id_joueur),
id_joueur UNIQUE(id_tournoi, id_joueur) -- un joueur ne peut pas s inscrire deux fois au meme tournoi
);
4 DAO
We now need the DAO method, which allows us to retrieve the list of tournaments from the database.
5 Service
The view does not communicate directly with the DAO. It must request the service class.
Even though in this case, the service method simply flat passes: it receives a tournament list and returns that same list.
6 Back to the view
Great, we now have a service method that allows us to obtain a list of all tournaments. We will display it so that players can choose.
In view InscriptionTournoiVue:
If they change their mind, players can also return to the previous menu without registering for any tournament.
You will need to manage the registration:
- JoueurService.s_inscrire_tournoi(tournoi) -> bool
- This service must verify that the registration is valid
- If so, a row will be created in the inscription table
- Therefore, the service will need to use the dao method InscriptionDao.creer(joueur, tournoi) -> bool
7 Methods needed
In this method we will call InscriptionDao.creer(joueur, tournoi) -> bool.
This method requires two parameters:
- tournoi: easy to get it, it is a parameter of calling method s_inscrire_tournoi(tournoi)
- joueur: how to get it?
joueur_service.py
class JoueurService:
...
def s_inscrire_tournoi(self, tournoi) -> bool:
...
= InscriptionDao.creer(joueur, tournoi) succes
This is where the Session class comes into play.
7.1 Session
When a player is logged in, we must have access to their information at all times.
This is the role of the Session class.
So we can get the player using Session().joueur
7.2 Back to service method s_inscrire_tournoi()
joueur_service.py
from view.session import Session
class JoueurService:
...
def s_inscrire_tournoi(self, tournoi) -> bool:
...
= Session().joueur
joueur = InscriptionDao.creer(joueur, tournoi) succes
Great, we have everything we need to call the dao method to create an Inscription, but aren’t there a few things we should check first?
What if the player is already registered?
Now let’s check that the tournament is not already full:
8 Let’s finish the view
To summarise the flows
The principle would be broadly the same. You will need the same services, but instead of going through views:
- create a endpoint
GET /tournament
to display the list - create a endpoint
POST /registration body: {player_id: ?, tournament_id: ?}