connect/0,
connect/1,
reset/0,
+ update/0,
% users :
nouveau_user/2,
user_by_login_password/2,
user_by_mess/1,
toggle_ek_master/1,
+ css_from_user_cookie/1,
% messages :
nouveau_message/3,
messages/2,\r
messages/3,
message_by_id/1,
+ message_by_id_sans_transaction/1,
messages_by_ids/1,
message_existe/1,
reponses/0,
% utiles :
resultat_transaction/1\r
]).
--import(qlc, [e/1, e/2, q/1, cursor/1]).\r
+-import(qlc, [e/2, q/1, cursor/2]).\r
-include("../include/euphorik_bd.hrl").
-include("../include/euphorik_defines.hrl").\r
-include_lib("stdlib/include/qlc.hrl").\r
mnesia:start(),
create_tables(),
reset().
+
create_tables() ->
mnesia:create_table(counter, [
{attributes, record_info(fields, counter)},
{disc_copies, [node()]}
]),
+ mnesia:create_table(proprietes, [
+ {attributes, record_info(fields, proprietes)},
+ {disc_copies, [node()]}
+ ]),
mnesia:create_table(minichat, [
{attributes, record_info(fields, minichat)},
{index, [auteur_id, troll_id]},
% Efface tous les users, minichat_reponse et minichat.\r
reset() ->\r
- mnesia:clear_table(counter),\r
+ mnesia:clear_table(counter),
+ mnesia:clear_table(proprietes),\r
mnesia:clear_table(user),\r
mnesia:clear_table(reponse_minichat),\r
mnesia:clear_table(minichat),
mnesia:clear_table(troll),
mnesia:clear_table(ip_table),\r
% crée l'utilisateur root\r
- mnesia:transaction(fun() ->\r
+ mnesia:transaction(fun() ->
+ mnesia:write(#proprietes{nom = version, valeur = ?VERSION_BD}),\r
User = #user{id = 0, pseudo = "Sys", login = "Sys", date_creation = now(), date_derniere_connexion = now(), ek_master = true},\r
mnesia:write(User),\r
User\r
end).
+% Met à jour la bd, compare ?VERSION_BD avec la version dans la table 'proprietes'
+% et exécute les patchs nécessaires.
+update() ->
+ mnesia:transaction(
+ fun() ->
+ case mnesia:read({proprietes, version}) of
+ [#proprietes{nom = Version}] ->
+ update(Version);
+ _ ->
+ erreur
+ end
+ end
+ ).
+
+
+% Mise à jour de la BD.
+% attention : il est nécessaire de se trouver dans une transaction.
+update(?VERSION_BD) -> fini;
+update(Version) ->
+ patch(Version),
+ update(Version + 1).
+
+
+% Applique une modification de la BD pour passer d'une version à la suivante.
+% 1 -> 2
+patch(1) ->
+ ok.
+% 2 -> 3
+%patch(2) ->
+
+
% Ajoute un nouveau user et le renvoie
nouveau_user(Pseudo, Cookie) ->
F = fun() ->
% Affiche N user trié par leur date de dernière connexion.
-% Attention : pas d'index sur ce champs (la date)
print_users(N) ->
resultat_transaction(mnesia:transaction(fun() ->
- C = cursor(q([E || E <- qlc:keysort(9, mnesia:table(user), [{order, descending}])])),
+ C = cursor(
+ qlc:keysort(
+ 9,
+ q([E || E <- mnesia:table(user)]),
+ [{order, descending}]
+ ),
+ [{tmpdir, ?KEY_SORT_TEMP_DIR}]
+ ),
Users = qlc:next_answers(C, N),
lists:foreach(
fun(U) ->
user_by_cookie(Cookie) ->
resultat_transaction(mnesia:transaction(
fun() ->
- case e(q([E || E <- mnesia:table(user), E#user.cookie =:= Cookie])) of
+ case e(q([E || E <- mnesia:table(user), E#user.cookie =:= Cookie]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[User] -> {ok, User};
_ -> erreur
end
user_by_id(ID) ->
resultat_transaction(mnesia:transaction(
fun() ->
- case e(q([E || E <- mnesia:table(user), E#user.id =:= ID])) of
+ case e(q([E || E <- mnesia:table(user), E#user.id =:= ID]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[User] -> {ok, User};
_ -> erreur
end
user_by_login(Login) ->\r
resultat_transaction(mnesia:transaction(\r
fun() ->\r
- Users = e(q([E || E <- mnesia:table(user), E#user.login =:= Login])),\r
+ Users = e(q([E || E <- mnesia:table(user), E#user.login =:= Login]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]),\r
case Users of\r
[User] -> {ok, User};\r
_ -> erreur\r
toggle_ek_master(User_id) ->
resultat_transaction(mnesia:transaction(
fun() ->
- Users = e(q([E || E <- mnesia:table(user), E#user.id =:= User_id])),
+ Users = e(q([E || E <- mnesia:table(user), E#user.id =:= User_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]),
case Users of
[User] ->
mnesia:write(User#user{ek_master = not User#user.ek_master});
end
)).
+
+% Renvoie une chaine représentant le cookie ou undefined si pas trouvé.
+css_from_user_cookie(Cookie) ->
+ case user_by_cookie(Cookie) of
+ {ok, User} ->
+ User#user.css;
+ _ ->
+ undefined
+ end.
+
user_by_login_password(Login, Password) ->
resultat_transaction(mnesia:transaction(
fun() ->
- case e(q([E || E <- mnesia:table(user), E#user.login =:= Login, E#user.password =:= Password])) of
+ case e(q([E || E <- mnesia:table(user), E#user.login =:= Login, E#user.password =:= Password]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[User | _] -> {ok, User};
_ -> erreur
end
user_by_mess(Id) ->
resultat_transaction(mnesia:transaction(
fun() ->
- case e(q([U || U <- mnesia:table(user), M <- mnesia:table(minichat), M#minichat.id =:= Id, M#minichat.auteur_id =:= U#user.id])) of
+ case e(q([U || U <- mnesia:table(user), M <- mnesia:table(minichat), M#minichat.id =:= Id, M#minichat.auteur_id =:= U#user.id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[User | _] -> {ok, User};
_ -> erreur
end
nouveau_message(Mess, Auteur_id, Repond_A) ->
% regarde si les id 'Repond_A' existent
F = fun() ->
- Nb_id_trouve = length(e(q([E#minichat.id || E <- mnesia:table(minichat), lists:member(E#minichat.id, Repond_A)]))),
+ 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])) of
+ 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,
% Renvoie N messages se trouvant sur la page P
-messages(N, P) ->
+messages(N, P) ->
F = fun() ->
- C = cursor(q([
- E#minichat{contenu = contenu_message(E)} ||
- E <- qlc:keysort(2, mnesia:table(minichat), [{order, descending}])
- ])),
+ C = cursor(
+ qlc:keysort(
+ 2,
+ q([E#minichat{contenu = contenu_message(E)} || E <- mnesia:table(minichat)]),
+ [{order, descending}]
+ ),
+ [{tmpdir, ?KEY_SORT_TEMP_DIR}]
+ ),
if P > 1 -> qlc:next_answers(C, N * (P - 1));
true -> ok
end,
qlc:delete_cursor(C),
lists:reverse(R)
end,
- resultat_transaction(mnesia:transaction(F)).
+ resultat_transaction(mnesia:transaction(F)).
% Renvoie les messages manquants pour la page P en sachant qu'il y a N message
% Renvoie {ok, #minichat} (voir #minichat de euphorik_bd.hrl) à partir de son id.
message_by_id(Id) ->
- case resultat_transaction(mnesia:transaction(
+ resultat_transaction(mnesia:transaction(
fun() ->
- e(q([E#minichat{contenu = contenu_message(E)} || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), Id =:= E#minichat.id]))
+ message_by_id_sans_transaction(Id)
end
- )) of
- [M] -> {ok, M};
- _ -> erreur
+ )).
+message_by_id_sans_transaction(Id) ->
+ case mnesia:read({minichat, Id}) of
+ [] -> erreur;
+ [M] ->
+ {ok, M#minichat{contenu = contenu_message(M)}}
end.
% Renvoie le contenu d'un message donnée, à utiliser à l'intérieur d'une transaction.
% TODO : Cette fonction pourrait être remplacé par un "outer-join", est-ce possible avec qlc ?
contenu_message(E) ->
- lists:flatten(E#minichat.contenu ++ e(q([T#troll.content || T <- mnesia:table(troll), T#troll.id =:= E#minichat.troll_id]))).
+ case mnesia:read({troll, E#minichat.troll_id}) of
+ [] -> E#minichat.contenu;
+ [T] -> E#minichat.contenu ++ T#troll.content
+ end.
% Renvoie une liste de message (voir #minichat de euphorik_bd.hrl) à partir d'une liste d'id (Ids).
resultat_transaction(mnesia:transaction(
fun() ->
% TODO : optimisations ? serait-ce du O(n) ?
- Query = q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), lists:any(fun(Id) -> Id =:= E#minichat.id end, Ids)]),
- e(Query)
+ e(qlc:keysort(
+ 2,
+ q([E || E <- mnesia:table(minichat), lists:any(fun(Id) -> Id =:= E#minichat.id end, Ids)]),
+ [{order, ascending}]
+ ),[{tmpdir, ?KEY_SORT_TEMP_DIR}])
end
)).
% TODO : ya pas plus simple ?
message_existe(Id) ->
resultat_transaction(mnesia:transaction(fun() ->
- length(e(q([E#minichat.id || E <- mnesia:table(minichat), E#minichat.id =:= Id]))) =:= 1
+ length(e(q([E#minichat.id || E <- mnesia:table(minichat), E#minichat.id =:= Id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}])) =:= 1
end)).
% Renvoie les reponses (utilisé normalement uniquement pendant le debug).
reponses() ->
F = fun() ->
- e(q([E || E <- mnesia:table(reponse_minichat)]))
+ e(q([E || E <- mnesia:table(reponse_minichat)]), [{tmpdir, ?KEY_SORT_TEMP_DIR}])
end,
resultat_transaction(mnesia:transaction(F)).
[M || E <- mnesia:table(reponse_minichat),
M <- mnesia:table(minichat),
E#reponse_minichat.repondant =:= M_id,
- M#minichat.id =:= E#reponse_minichat.cible]))
+ M#minichat.id =:= E#reponse_minichat.cible]), [{tmpdir, ?KEY_SORT_TEMP_DIR}])
end
)).
e(q([
M#minichat.auteur_id || M <- mnesia:table(minichat), R <- mnesia:table(reponse_minichat),
M#minichat.auteur_id =:= Id_user, M#minichat.id =:= R#reponse_minichat.cible, R#reponse_minichat.repondant =:= Id_mess
- ]), [{unique_all, true}])
+ ]), [{unique_all, true}, {tmpdir, ?KEY_SORT_TEMP_DIR}])
end
) of
{atomic, [_]} -> true;
e(q([
M#minichat.auteur_id || M <- mnesia:table(minichat), R <- mnesia:table(reponse_minichat),
R#reponse_minichat.cible =:= Id_mess, R#reponse_minichat.repondant =:= M#minichat.id, M#minichat.auteur_id =:= Id_user
- ]), [{unique_all, true}])
+ ]), [{unique_all, true}, {tmpdir, ?KEY_SORT_TEMP_DIR}])
end
) of
{atomic, [_]} -> true;
possede_message(Id_user, Id_mess) ->
case mnesia:transaction(
fun() ->
- e(q([E#minichat.auteur_id || E <- mnesia:table(minichat), E#minichat.id =:= Id_mess]))
+ e(q([E#minichat.auteur_id || E <- mnesia:table(minichat), E#minichat.id =:= Id_mess]), [{tmpdir, ?KEY_SORT_TEMP_DIR}])
end
) of
{atomic, [Id_user | []]} -> true;
resultat_transaction(mnesia:transaction(
fun() ->
Now = now(),
- e(q([
+ e(qlc:keysort(1, q([
{
IP#ip_table.ip,
delta_date_minute(date_plus_minutes(IP#ip_table.ban, IP#ip_table.ban_duration), Now),
- e(q([{U#user.pseudo, U#user.login} || U <- mnesia:table(user), U#user.last_ip =:= IP#ip_table.ip]))
+ e(q([{U#user.pseudo, U#user.login} || U <- mnesia:table(user), U#user.last_ip =:= IP#ip_table.ip]), [{tmpdir, ?KEY_SORT_TEMP_DIR}])
} ||
- IP <- qlc:keysort(2, mnesia:table(ip_table)),
+ IP <- mnesia:table(ip_table),
if IP#ip_table.ban =:= undefined -> false; true -> date_plus_minutes(IP#ip_table.ban, IP#ip_table.ban_duration) > Now end
- ]))
+ ])), [{tmpdir, ?KEY_SORT_TEMP_DIR}])
end
)).
U#user.id =:= User_id,
IP <- mnesia:table(ip_table),
IP#ip_table.ip =:= U#user.last_ip
- ])) of
+ ]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[{Ban, Ban_duration}] ->
Echeance = date_plus_minutes(Ban, Ban_duration),
Now = now(),
can_register(IP) ->
resultat_transaction(mnesia:transaction(
fun() ->
- case e(q([I || I <- mnesia:table(ip_table), I#ip_table.ip =:= IP])) of
+ case e(q([I || I <- mnesia:table(ip_table), I#ip_table.ip =:= IP]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[] ->
mnesia:write(#ip_table{ip = IP, date_last_try_register = now()}),
true;
trolls() ->
resultat_transaction(mnesia:transaction(
fun() ->
- e(q([T || T <- qlc:keysort(2, mnesia:table(troll))]))
+ e(qlc:keysort(2, q([T || T <- mnesia:table(troll)])), [{tmpdir, ?KEY_SORT_TEMP_DIR}])
end
)).
trolls(Last_id) ->
resultat_transaction(mnesia:transaction(
fun() ->
- e(q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined]))
+ e(qlc:keysort(2, q([T || T <- mnesia:table(troll), T#troll.id > Last_id, T#troll.date_post =:= undefined])), [{tmpdir, ?KEY_SORT_TEMP_DIR}])
end
)).
E#troll.id_user =:= User_id,
E#troll.date_post =:= undefined
]
- ))),
+ ), [{tmpdir, ?KEY_SORT_TEMP_DIR}])),
Nb_troll_poste_total = length(e(q(
[
E#troll.id || E <- mnesia:table(troll),
E#troll.date_post =:= undefined
]
- ))),
+ ), [{tmpdir, ?KEY_SORT_TEMP_DIR}])),
User = user_by_id(User_id),
case User of
{ok, _} ->
troll_by_id(Troll_id) ->
resultat_transaction(mnesia:transaction(
fun() ->
- case e(q([T || T <- mnesia:table(troll), T#troll.id =:= Troll_id])) of
+ case e(q([T || T <- mnesia:table(troll), T#troll.id =:= Troll_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[T] -> {ok, T};
_ ->
erreur
resultat_transaction(mnesia:transaction(
fun() ->
% TODO : ya pas moyen de désigner le champs plutot qu'avec un nombre pour le tri ?
- C = cursor(q([T || T <- qlc:keysort(5, mnesia:table(troll), [{order, descending}]), T#troll.date_post =/= undefined])),
+ C = cursor(qlc:keysort(5, q([T || T <- mnesia:table(troll), T#troll.date_post =/= undefined]), [{order, descending}]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]),
R = case qlc:next_answers(C, 1) of
[T] -> T;
_ -> aucun
random:seed(A1, A2, A3),
mnesia:transaction(
fun() ->
- case e(q([T || T <- mnesia:table(troll), T#troll.date_post =:= undefined])) of
+ case e(q([T || T <- mnesia:table(troll), T#troll.date_post =:= undefined]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[] ->
plus_de_trolls;
Trolls ->
message_id_associe(Troll_id) ->
resultat_transaction(mnesia:transaction(
fun() ->
- case e(q([M#minichat.id || M <- mnesia:table(minichat), M#minichat.troll_id =:= Troll_id])) of
+ case e(q([M#minichat.id || M <- mnesia:table(minichat), M#minichat.troll_id =:= Troll_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of
[Id] -> Id;
_ -> undefined
end