FIX optimisation de certaine requête : il faut trier après pas avant, banane !
[euphorik.git] / modules / erl / euphorik_bd.erl
index 187d6ea..89c9836 100755 (executable)
@@ -57,6 +57,7 @@
    messages/2,\r
    messages/3,
    message_by_id/1,
+   message_by_id_sans_transaction/1,
    messages_by_ids/1,
    message_existe/1,
    reponses/0,
@@ -107,6 +108,7 @@ create() ->
    mnesia:start(),
    create_tables(),
    reset().
+   
 create_tables() ->
    mnesia:create_table(counter, [
       {attributes, record_info(fields, counter)},
@@ -153,7 +155,8 @@ connect(Node) ->
 
 % 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),
@@ -304,7 +307,13 @@ update_pseudo_user(UserId, Pseudo) ->
 % 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}]
+         )
+      ),
       Users = qlc:next_answers(C, N),
       lists:foreach(
          fun(U) ->
@@ -505,12 +514,15 @@ messages(N) ->
 
 
 % 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}]
+         )
+      ),
       if P > 1 -> qlc:next_answers(C, N * (P - 1));
          true -> ok
       end,
@@ -529,20 +541,26 @@ messages(Id, N, P) ->
    
 % 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).
@@ -550,8 +568,11 @@ messages_by_ids(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}]
+         ))
       end
    )).
    
@@ -634,15 +655,15 @@ list_ban() ->
    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]))
             } ||
-            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
-         ]))
+         ])))
       end
    )).
 
@@ -733,7 +754,7 @@ can_register(IP) ->
 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)])))
       end
    )).
    
@@ -742,7 +763,7 @@ trolls() ->
 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])))
       end
    )).
    
@@ -833,7 +854,7 @@ current_troll() ->
    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}])),
          R = case qlc:next_answers(C, 1) of
             [T] -> T;
             _ -> aucun