-- ! Tracer les suppressions.
-- ? Q1). Que fait la commande suivante ?
SELECT current_role , current_catalog;

-- Elle recupere et affiche le Role actuel (la personne qui est sur cette base de donnée) et la base de donnée actuel

-- ? Q2). Créer la table Log(quand, qui, quoi) où quand est un timestamp, qui est une chaîne de 20 caractères et quoi est une chaîne d’au plus 800 caractères.

DROP TABLE IF EXISTS Log CASCADE;

CREATE TABLE Log (
    quand timestamp,
    qui char(20),
    quoi varchar(800)
);


-- ? Q3 ). Ajouter les faux joueurs suivants : 
-- ? 1001, Todd Jackson, USA
-- ? 1002, Michael Matthews, USA
-- ? 1003, Jamie Griffith, USA
-- ? 1004, Iloy Roberts, Belgium 
-- ? 1005, Erin Kolthof, Belgium

INSERT INTO Player VALUES(1001, 'Todd Jackson', 'USA');
INSERT INTO Player VALUES(1002, 'Michael Matthews', 'USA');
INSERT INTO Player VALUES(1003, 'Jamie Griffith', 'USA');
INSERT INTO Player VALUES(1004, 'Iloy Roberts', 'Belgium');
INSERT INTO Player VALUES(1005, 'Erin Kolthof', 'Belgium');



-- ? Q4 ). Créer un trigger qui permette de tracer dans la table Log la suppression d’un joueur afin
-- ? de connaître l’utilisateur qui a réalisé la suppression, quand la suppression a été réalisée et quelles informations ont été supprimées.

-- DROP FUNCTION trig_trace_delete CASCADE;
-- CREATE OR REPLACE FUNCTION trig_trace_delete() RETURNS trigger AS $$
-- BEGIN 
--     INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'suppression de l''id :' || OLD.id || ', avec le nom : ' || OLD.name);
--     RETURN OLD;
-- END;
-- $$ LANGUAGE plpgsql;

-- CREATE OR REPLACE trigger tracerLog BEFORE DELETE ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_delete();


-- ? Q5). Supprimer le joueur Michael Matthews, puis tous les joueurs belges et vérifier que votre trigger fonctionne.

DELETE FROM Player WHERE name = 'Michael Matthews';
DELETE FROM Player WHERE country = 'Belgium';

SELECT * FROM Log;

--            quand            |         qui          |                           quoi                            
-- ----------------------------+----------------------+-----------------------------------------------------------
--  2023-12-06 08:43:58.474339 | Perederii            | suppression de l'id :1002, avec le nom : Michael Matthews
--  2023-12-06 08:44:49.91823  | Perederii            | suppression de l'id :1004, avec le nom : Iloy Roberts
--  2023-12-06 08:44:49.91823  | Perederii            | suppression de l'id :1005, avec le nom : Erin Kolthof
-- (3 rows)


-- ? Q6). Nous voulons désormais tracer tous les changements fait dans la table Player (ajout, suppres- sion et modification de ligne). Comme précédemment, toutes les informations concernant ces change- ments sont stockées dans la table Log.
-- ? Proposez deux façons différentes permettant de stocker un message différent dans la colonne quoi en fonction du type de changement réalisé.

-- ! Premiere maniere :
-- DROP FUNCTION trig_trace_delete CASCADE;
-- DROP FUNCTION trig_trace_insert CASCADE;
-- DROP FUNCTION trig_trace_update CASCADE;
-- CREATE OR REPLACE FUNCTION trig_trace_delete() RETURNS trigger AS $$
-- BEGIN 
--     INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'suppression de l''id :' || OLD.id || ', avec le nom : ' || OLD.name || ' et le pays : ' || OLD.country);
--     RETURN OLD;
-- END;
-- $$ LANGUAGE plpgsql;

-- CREATE OR REPLACE trigger tracerLogDelete BEFORE DELETE ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_delete();

-- CREATE OR REPLACE FUNCTION trig_trace_update() RETURNS trigger AS $$
-- BEGIN 
--     INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'update de l''id :' || OLD.id || ', en : ' || NEW.id || ', avec le nom : ' || OLD.name
--                                                 || ', en : ' || NEW.name || ' et le pays : ' || OLD.country || ', en ' || NEW.country);
--     RETURN NEW;
-- END;
-- $$ LANGUAGE plpgsql;

-- CREATE OR REPLACE trigger tracerLogUpdate AFTER UPDATE ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_update();

-- CREATE OR REPLACE FUNCTION trig_trace_insert() RETURNS trigger AS $$
-- BEGIN 
--     INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'insert de l''id :' || NEW.id || ', avec le nom : ' || NEW.name || ' et le pays : ' || NEW.country);
--     RETURN NEW;
-- END;
-- $$ LANGUAGE plpgsql;

-- CREATE OR REPLACE trigger tracerLogInsert BEFORE INSERT ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_insert();

-- ! Deuxieme maniere :

CREATE OR REPLACE FUNCTION trig_trace() RETURNS trigger AS $$
BEGIN 
    IF TG_OP = 'DELETE' THEN
        INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'suppression de l''id :' || OLD.id || ', avec le nom : ' || OLD.name || ' et le pays : ' || OLD.country);
        RETURN OLD;
    ELSIF TG_OP = 'INSERT' THEN
        INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'insert de l''id :' || NEW.id || ', avec le nom : ' || NEW.name || ' et le pays : ' || NEW.country);
        RETURN NEW;
    ELSE 
        INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'update de l''id :' || OLD.id || ', en : ' || NEW.id || ', avec le nom : ' || OLD.name
                                                        || ', en : ' || NEW.name || ' et le pays : ' || OLD.country || ', en ' || NEW.country);
        RETURN NEW;
    END IF;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE trigger tracerLogAll BEFORE INSERT OR UPDATE OR DELETE ON Player
FOR EACH ROW
EXECUTE FUNCTION trig_trace();

-- ? Q7). Vérifier que cela fonctionne.

-- C'est OK

-- ! Meilleur marqueur.
-- ? Q8). Créer la table BestScorer qui contient le maximum de points marqués par un joueur lors d’un match, l’id du joueur ayant réalisé ce record et l’id du match.

CREATE TABLE BestScorer(
    maxPts integer,
    idPlayer integer,
    idGame integer
);

-- ? Q9). Créer un trigger permettant de mettre à jour cette table lors de l’insertion de nouveaux résultats de match.

SELECT gd.points, gd.idPlayer, gd.idGame INTO maxPts, Pid, GdId
FROM GameDetail gd
WHERE gd.points >= ALL(SELECT points FROM GameDetail WHERE idGame = gd.idGame);
INSERT INTO BestScorer(maxPts, idPlayer, idGame) SELECT gd.points, gd.idPlayer, gd.idGame INTO maxPts, Pid, GdId
                                                    FROM GameDetail gd
                                                    WHERE gd.points >= ALL(SELECT points FROM GameDetail WHERE idGame = gd.idGame);


CREATE OR REPLACE FUNCTION fctMatch() RETURNS trigger AS $$
DECLARE 
    maxPts integer;
    Pid integer;
    GdId integer;
BEGIN 
-- ! Verifie si dans BestScorer si pas, on, insert, si >, on insert sinon on fait rien
    -- SELECT gd.points, gd.idPlayer, gd.idGame INTO maxPts, Pid, GdId
    -- FROM GameDetail gd
    -- WHERE gd.idGame = NEW.idGame AND gd.points >= ALL(SELECT points FROM GameDetail WHERE idGame = gd.idGame);
    -- INSERT INTO BestScorer VALUES(maxPts, Pid, GdId);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE trigger trigTraceMatch BEFORE INSERT ON GameDetail
EXECUTE FUNCTION fctMatch();


-- ? Q10). Tester votre trigger en ajoutant de fausses lignes dans la table GameDetail. Pensez bien à vérifier chaque cas possible !



-- ? Q11). Intégrer la création de la table BestScorer et votre trigger au script de création de la base de données NBA. Puis lancer le script pour remplir la table BestScorer pour tous les matchs de la base.



-- ? Q12). Quel joueur a marqué le plus de points et combien pendant le match du 22 janvier 2006 où les Lakers ont affronté à domicile l’équipe de Toronto ?



-- ! Détection et correction d’erreurs.

-- * Comme nous l’avons déjà vu dans de précédents TPs, il y a des incohérences ou des données manquantes dans la base de données. 
-- * Nous ne voulons pas modifier les données existantes car, même si nous sommes capables de détecter des incohérences, il n’est pas possible de savoir 
-- * (sans vérifier chaque match un à un) quelles données sont erronées et quelles données sont exactes. Nous allons plutôt mettre en place des méchanismes permettant 
-- * d’empêcher ces erreurs de se produire lors de l’ajout de nouvelles données.

-- ? Q13). Créer un trigger qui vérifie la cohérence des données d’une ligne de GameDetail, et les corrigent si nécessaire lors de l’ajout ou de la modification de celle-ci.
-- ? Plus précisément, ce trigger devra s’assurer que :
-- ? — fieldGoalsPrctage est cohérent avec fieldGoalsMade et fieldGoalsAttempted et corriger sa valeur si nécessaire.
-- ? — threePointsPrctage est cohérent avec threePointsMade et threePointsAttempted et corriger sa valeur si nécessaire.
-- ? — freeThrowsPrctage est cohérent avec freeThrowsMade et freeThrowsAttempted et corriger sa valeur si nécessaire.
-- ? — rebounds est cohérent avec offensiveRebounds et defensiveRebounds et corriger sa valeur si nécessaire.
-- ? — points est cohérent avec fieldGoalsMade, threePointsMade, et freeThrowsMade et corriger sa valeur si nécessaire.
-- ? Notez qu’un lancer franc (freeThrow) vaut 1 point. Un field goal vaut 2 ou 3 points selon la distance du lancer.
-- ? Pour que ces modifications ne se fasse pas sans que l’utilisateur n’en soit informé, toute modification des valeurs entrées par l’utilisateur devra 
-- ? être signalée par l’affichage d’un message de niveau WARNING.



-- ? Q14). Vérifier que votre trigger fonctionne.
