X-Git-Url: http://git.euphorik.ch/?p=euphorik.git;a=blobdiff_plain;f=modules%2Ferl%2Feuphorik_bd.erl;h=4e470993240cd4649307dd840e27f0c7d8fbc3a2;hp=b72d7a8c87046d0a66469686f1b7c4d9172488e1;hb=8bede29111bde3481ed8b3d6637c241c8d241544;hpb=650c44a784cabc8a1f2bd1daa7e5e61ccf74ca6f diff --git a/modules/erl/euphorik_bd.erl b/modules/erl/euphorik_bd.erl index b72d7a8..4e47099 100755 --- a/modules/erl/euphorik_bd.erl +++ b/modules/erl/euphorik_bd.erl @@ -30,11 +30,12 @@ connect/1, reset/0, update/0, + restore/1, % users : nouveau_user/2, nouveau_user/3, - set_profile/11, + set_profile/10, update_date_derniere_connexion/1, update_ip/2, update_pseudo_user/2, @@ -189,18 +190,54 @@ update() -> % attention : il est nécessaire de se trouver dans une transaction. update(?VERSION_BD) -> fini; update(Version) -> - patch(Version), - update(Version + 1). + case mnesia:backup(mnesia:system_info(directory) ++ "/backup" ++ integer_to_list(Version)) of + ok -> + case patch(Version) of + ok -> + mnesia:write(#proprietes{nom = version, valeur = Version + 1}), + update(Version + 1); + _ -> + erreur + end; + {error, Raison} -> {error, lists:flatten(io_lib:format("Erreur de création du backup de la version ~w : ~w", [Version, Raison]))} + end. % Applique une modification de la BD pour passer d'une version à la suivante. +% crée un backup avant l'application du patch +% dans BD/backups nommé "backup" où et le numéro de la version. % 1 -> 2 patch(1) -> + % traitement des users + mnesia:transform_table( + user, + fun({user, Id, Cookie, Pseudo, Login, Password, Email, Date_creation, Date_derniere_connexion, Css, Nick_format, View_times, View_tooltips, Indice_flood, _Page_principale, Conversations, Ek_master, Last_ip}) -> + {user, Id, Cookie, Pseudo, Login, Password, Email, Date_creation, Date_derniere_connexion, Css, Nick_format, View_times, View_tooltips, reverse, Indice_flood, lists:map(fun({C, _}) -> C end, Conversations), Ek_master, Last_ip} + end, + record_info(fields, user), + user + ), + mnesia:transform_table( + minichat, + fun({minichat, Id, Auteur_id, Date, Pseudo, Contenu, Troll_id}) -> + {minichat, Id, Auteur_id, Date, Pseudo, Contenu, Troll_id, Id} + end, + record_info(fields, minichat), + minichat + ), + % met à jour les racines des messages + TODO ! -> mnesia:foldl(...) ok. % 2 -> 3 %patch(2) -> +% Reviens à une version précédente de la base de données +% (les données insérées durant les versions plus récentes sont perdues) +restore(N) -> + mnesia:restore(mnesia:system_info(directory) ++ "/backup" ++ integer_to_list(N)). + + % Ajoute un nouveau user et le renvoie nouveau_user(Pseudo, Cookie) -> F = fun() -> @@ -224,7 +261,7 @@ nouveau_user(Login, Password, Cookie) -> % Mise à par Cookie les autres peuvent être undefined ce qui veut dire qu'ils ne seront pas modifié. -set_profile(Cookie, Login, Password, Pseudo, Email, Css, Nick_format, View_times, View_tooltips, Page_principale, Conversations) -> +set_profile(Cookie, Login, Password, Pseudo, Email, Css, Nick_format, View_times, View_tooltips, Conversations) -> if Nick_format =:= nick; Nick_format =:= login; Nick_format =:= nick_login -> resultat_transaction(mnesia:transaction( fun() -> @@ -245,7 +282,6 @@ set_profile(Cookie, Login, Password, Pseudo, Email, Css, Nick_format, View_times nick_format = Nick_format, view_times = View_times, view_tooltips = View_tooltips, - page_principale = if is_integer(Page_principale), Page_principale > 0 -> Page_principale; true -> User#user.page_principale end, conversations = if is_list(Conversations) -> Conversations; true -> User#user.conversations end }, mnesia:write(User_modifie), @@ -460,33 +496,34 @@ nouveau_message(Mess, Auteur_id, Repond_A) -> F = fun() -> Nb_id_trouve = length(e(q([E#minichat.id || E <- mnesia:table(minichat), lists:member(E#minichat.id, Repond_A)]), [{tmpdir, ?KEY_SORT_TEMP_DIR}])), % est-ce que l'auteur existe ? - Auteur = case e(q([E || E <- mnesia:table(user), E#user.id =:= Auteur_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of - [A] -> A; - _ -> {erreur, "L'auteur du message est introuvable"} - end, - if Nb_id_trouve =/= length(Repond_A) -> - {erreur, "Un ou plusieurs messages introuvable"}; - true -> - % comparaison entre la date du dernier poste et maintenant (gestion du flood) - Delta = delta_date_ms(Auteur#user.date_derniere_connexion, now()), - Nouvel_indice_flood = Auteur#user.indice_flood + if Delta =< ?DUREE_SPAM -> 2; true -> -1 end, - Auteur_maj = Auteur#user{ - indice_flood = if Nouvel_indice_flood > ?INDICE_SPAM_MAX -> ?INDICE_SPAM_MAX; Nouvel_indice_flood < 0 -> 0; true -> Nouvel_indice_flood end, - date_derniere_connexion = now() - }, - % est-ce que l'auteur à trop floodé ? - if Auteur#user.indice_flood =/= ?INDICE_SPAM_MAX, Auteur_maj#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM -> - mnesia:write(Auteur#user{indice_flood = Auteur_maj#user.indice_flood}), - nouveau_message_sys("''" ++ Auteur#user.pseudo ++ if Auteur#user.login =/= [] -> " (" ++ Auteur#user.login ++ ")"; true -> "" end ++ "'' est bloqué pour " ++ integer_to_list(trunc(?DUREE_BLOCAGE_SPAM / 1000)) ++ " secondes pour cause de flood."); - Auteur#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM -> - {erreur, "Bloqué pour cause de flood"}; - true -> - mnesia:write(Auteur_maj), - Id = nouvel_id(minichat), - inserer_reponses(Id, Repond_A), - mnesia:write(#minichat{id=Id, auteur_id=Auteur#user.id, date=now(), pseudo=Auteur#user.pseudo, contenu=Mess}), - Id - end + case e(q([E || E <- mnesia:table(user), E#user.id =:= Auteur_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of + [Auteur] -> + if Nb_id_trouve =/= length(Repond_A) -> + {erreur, "Un ou plusieurs messages introuvable"}; + true -> + % comparaison entre la date du dernier poste et maintenant (gestion du flood) + Delta = delta_date_ms(Auteur#user.date_derniere_connexion, now()), + Nouvel_indice_flood = Auteur#user.indice_flood + if Delta =< ?DUREE_SPAM -> 2; true -> -1 end, + Auteur_maj = Auteur#user{ + indice_flood = if Nouvel_indice_flood > ?INDICE_SPAM_MAX -> ?INDICE_SPAM_MAX; Nouvel_indice_flood < 0 -> 0; true -> Nouvel_indice_flood end, + date_derniere_connexion = now() + }, + % est-ce que l'auteur à trop floodé ? + if Auteur#user.indice_flood =/= ?INDICE_SPAM_MAX, Auteur_maj#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM -> + mnesia:write(Auteur#user{indice_flood = Auteur_maj#user.indice_flood}), + nouveau_message_sys("''" ++ Auteur#user.pseudo ++ if Auteur#user.login =/= [] -> " (" ++ Auteur#user.login ++ ")"; true -> "" end ++ "'' est bloqué pour " ++ integer_to_list(trunc(?DUREE_BLOCAGE_SPAM / 1000)) ++ " secondes pour cause de flood."); + Auteur#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM -> + {erreur, "Bloqué pour cause de flood"}; + true -> + mnesia:write(Auteur_maj), + Id = nouvel_id(minichat), + inserer_reponses(Id, Repond_A), + mnesia:write(#minichat{id=Id, auteur_id=Auteur#user.id, date=now(), pseudo=Auteur#user.pseudo, contenu=Mess}), + Id + end + end; + _ -> + {erreur, "L'auteur du message est introuvable"} end end, resultat_transaction(mnesia:transaction(F)). @@ -538,9 +575,9 @@ messages(N, P) -> end, R = qlc:next_answers(C, N), qlc:delete_cursor(C), - lists:reverse(R) + R end, - resultat_transaction(mnesia:transaction(F)). + lists:reverse(resultat_transaction(mnesia:transaction(F))). % Renvoie les messages manquants pour la page P en sachant qu'il y a N message @@ -614,6 +651,19 @@ repond_a(M_id) -> end )). + +% Renvoie les message qui repondent à M_id +reponses(M_id) -> + resultat_transaction(mnesia:transaction( + fun() -> + e(q( + [M || E <- mnesia:table(reponse_minichat), + M <- mnesia:table(minichat), + E#reponse_minichat.cible =:= M_id, + M#minichat.id =:= E#reponse_minichat.repondant]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) + end + )). + % Est-ce que le message Id_mess est une réponse d'une message de Id_user ? est_une_reponse_a_user(Id_user, Id_mess) ->