REPORT de la branche 1.1 (459->476)
[euphorik.git] / modules / erl / euphorik_bd.erl
index 81a36a0..4fecb73 100755 (executable)
@@ -46,7 +46,6 @@
    % messages :\r
    nouveau_message/3,\r
    nouveau_message_sys/1,\r
-   nouveau_message_sys/2,\r
    messages/1,\r
    messages/2,\r
    messages/3,\r
@@ -78,7 +77,6 @@
    troll_by_id/1,\r
    current_troll/0,\r
    elire_troll/0,\r
-   message_id_associe/1,\r
    \r
    % utiles :\r
    resultat_transaction/1\r
@@ -277,13 +275,16 @@ user_by_mess(Id) ->
 nouveau_message(Mess, Auteur_id, Repond_A_ids) ->\r
    % regarde si les id 'Repond_A' existent\r
    F = fun() ->         \r
-      Repond_a = lists:map(\r
-         fun(Repond_a_id) ->\r
-            [M] = mnesia:wread({minichat, Repond_a_id}),\r
-            M\r
-         end,\r
+      Repond_a = lists:foldr(\r
+         fun(Repond_a_id, Acc) ->\r
+            case mnesia:read({minichat, Repond_a_id}) of
+               [M] -> [M | Acc];\r
+               _ -> Acc % le message n'est pas trouvé
+            end\r
+         end,
+         [],\r
          Repond_A_ids\r
-      ),      \r
+      ),\r
       Racine_id = case Repond_a of\r
          [] -> undefined;\r
          [M | _] -> \r
@@ -295,16 +296,16 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) ->
                _ ->\r
                   {erreur, "Les messages ne font pas partie de la même conversation"}\r
             end\r
-      end,\r
-      case Racine_id of\r
-         {erreur, E} -> {erreur, E};\r
-         _ ->\r
-            % est-ce que l'auteur existe ?\r
-            case mnesia:wread({user, Auteur_id}) of\r
-               [#user{profile = Profile} = Auteur] ->\r
-                  if length(Repond_a) =/= length(Repond_A_ids) ->\r
-                        {erreur, "Un ou plusieurs messages introuvable"};\r
-                     true ->\r
+      end,      
+      if length(Repond_a) =/= length(Repond_A_ids) ->
+            {erreur, "Un ou plusieurs messages introuvable"};
+         true ->\r
+            case Racine_id of\r
+               {erreur, E} -> {erreur, E};\r
+               _ ->\r
+                  % est-ce que l'auteur existe ?\r
+                  case mnesia:wread({user, Auteur_id}) of\r
+                     [#user{profile = Profile} = Auteur] ->\r
                         % comparaison entre la date du dernier poste et maintenant (gestion du flood)\r
                         Now = now(),\r
                         Delta = euphorik_common:delta_date_ms(Auteur#user.date_derniere_connexion, Now),\r
@@ -332,11 +333,11 @@ nouveau_message(Mess, Auteur_id, Repond_A_ids) ->
                                  racine_id = if Racine_id =:= undefined -> Id; true -> Racine_id end\r
                               }),\r
                               Id\r
-                        end\r
-                  end;\r
-               _ ->\r
-                  {erreur, "L'auteur du message est introuvable"}\r
-            end\r
+                        end;\r
+                     _ ->\r
+                        {erreur, "L'auteur du message est introuvable"}\r
+                  end\r
+            end
       end\r
    end,\r
    resultat_transaction(mnesia:transaction(F)).\r
@@ -352,16 +353,11 @@ inserer_reponses(_, []) ->
 % Permet de créer un message système.\r
 % Renvoie l'id du message système\r
 nouveau_message_sys(Mess) ->\r
-   nouveau_message_sys(Mess, undefined).\r
-   \r
-\r
-% Création d'un message système lié à un troll.\r
-nouveau_message_sys(Mess, Troll_id) ->\r
    {ok, #user{profile = Profile}} = user_by_id(0),\r
    resultat_transaction(mnesia:transaction(\r
       fun() ->\r
          Id = nouvel_id(minichat),\r
-         mnesia:write(#minichat{id = Id, auteur_id = 0, date = now(), pseudo = Profile#profile.pseudo, contenu = Mess, troll_id = Troll_id, racine_id = Id}),\r
+         mnesia:write(#minichat{id = Id, auteur_id = 0, date = now(), pseudo = Profile#profile.pseudo, contenu = Mess, racine_id = Id}),\r
          Id\r
       end\r
    )).\r
@@ -372,26 +368,29 @@ messages(N) ->
    messages(N, 1).\r
 \r
 \r
-% Renvoie N messages se trouvant sur la page P\r
+% Renvoie N messages se trouvant sur la page P
+% TODO FIXME : fonction en O(N * P) !\r
 messages(N, P) ->\r
-   F = fun() ->\r
-      C = cursor(\r
-         qlc:keysort(\r
-            #minichat.id, \r
-            q([E#minichat{contenu = contenu_message(E)} || E <- mnesia:table(minichat)]),\r
-            [{order, descending}]\r
-         ),\r
-         [{tmpdir, ?KEY_SORT_TEMP_DIR}]\r
-      ),\r
-      if P > 1 -> qlc:next_answers(C, N * (P - 1));\r
-         true -> ok\r
-      end,\r
-      R = qlc:next_answers(C, N),\r
-      qlc:delete_cursor(C),\r
-      R\r
+   F = fun() ->
+      % % #minichat{contenu = contenu_message(E)}
+      get_tuples_avant(minichat, reculer(minichat, mnesia:last(minichat), N * (P - 1)), N)     \r
    end,\r
-   lists:reverse(resultat_transaction(mnesia:transaction(F))).\r
-\r
+   resultat_transaction(mnesia:transaction(F)).
+   
+get_tuples_avant(Table, Id, N) ->
+   get_tuples_avant(Table, Id, N, []).
+get_tuples_avant(_, '$end_of_table', _, Tuples) -> Tuples;
+get_tuples_avant(_, _, 0, Tuples) ->
+   Tuples;
+get_tuples_avant(Table, Id, N, Tuples) ->
+   [T] = mnesia:read({Table, Id}),
+   get_tuples_avant(Table, mnesia:prev(Table, Id), N - 1, [T | Tuples]).
+
+reculer(_, '$end_of_table' = Fin, _) -> Fin;
+reculer(_, Id, 0) -> Id;
+reculer(Table, Id, N) ->
+   reculer(Table, mnesia:prev(Table, Id), N - 1).
+   \r
 \r
 % Renvoie les messages manquants pour la page P en sachant qu'il y a N message\r
 % par page et que le dernier message que l'on possède est Id\r
@@ -412,9 +411,9 @@ message_by_id(Id) ->
    \r
    \r
 % Renvoie le contenu d'un message donnée en fonction du troll associé, à utiliser à l'intérieur d'une transaction.\r
-% TODO : Cette fonction pourrait être remplacé par un "outer-join", est-ce possible avec qlc ?\r
+% TODO : Cette fonction pourrait être remplacée par un "outer-join", est-ce possible avec qlc ?\r
 contenu_message(E) ->\r
-   case mnesia:read({troll, E#minichat.troll_id}) of\r
+   case mnesia:index_read(troll, E#minichat.id, #troll.id_minichat) of\r
       [] -> E#minichat.contenu;\r
       [T] -> E#minichat.contenu ++ T#troll.content\r
    end.\r
@@ -796,26 +795,13 @@ elire_troll() ->
                plus_de_trolls;\r
             Trolls ->\r
                Troll = lists:nth(random:uniform(length(Trolls)), Trolls),\r
-               Troll2 = Troll#troll{date_post = now()},\r
-               mnesia:write(Troll2),\r
-               nouveau_message_sys("Troll de la semaine : ", Troll2#troll.id)\r
+               Id_message = nouveau_message_sys("Troll de la semaine : "),\r
+               Troll2 = Troll#troll{date_post = now(), id_minichat = Id_message},\r
+               mnesia:write(Troll2)\r
          end\r
       end\r
    ).\r
    \r
-\r
-% Renvoie l'id du message associé au troll dont l'id est donnée.\r
-% Renvoie undefined si il n'y en a pas.\r
-message_id_associe(Troll_id) ->\r
-   resultat_transaction(mnesia:transaction(\r
-      fun() ->\r
-         case e(q([M#minichat.id || M <- mnesia:table(minichat), M#minichat.troll_id =:= Troll_id]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of\r
-            [Id] -> Id;\r
-            _ -> undefined\r
-         end\r
-      end\r
-   )).\r
-\r
    \r
 % Renvoie le résultat d'une transaction (en décomposant le tuple fournit)\r
 resultat_transaction({_, T}) ->\r