af83

Erlang et mnesia:select

Pas toujours facile de faire des requêtes un peu compliqués sur des tables ETS ou mnesia.

La syntaxe officielle pour faire des requêtes avec select/2 est vraiment cryptique.

Voici un exemple de la doc officielle erlang. La requête retourne le nom de chaque personne de sexe masculin âgé de plus de 30 ans.

MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
Guard = {'>', '$2', 30},
Result = '$1',
mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),

Les critères sont exprimé avec des $. L'ensemble devient assez indigeste pour des cas plus compliqué.

De plus il est impossible de réaliser des opérations basiques dans d'autres moteurs de base de données, comme trier le résultat.

Un module existe pourtant pour améliorer la lisibilité des requêtes. QLC pour Query List Comprehension. Il supporte de base mnesia, ets et dets.

Voici une réécriture de l'exemple précédent

Query = qlc:q([Person#person.name || Person <- mnesia:table(Tab), Person#person.sex == male, Person#person.age > 30]),

Dans ce cas, la requête est exprimé sous la forme d'une list comprehension. Les critères sont exprimé d'une manière intelligible dans la deuxième partie de la list comprehension.

Si vous voulez exécuter cette requête dans mnesia, vous devez le faire dans une transaction.

-include_lib("stdlib/include/qlc.hrl")
Transaction = fun() ->
    Query = qlc:q([Person#person.name || Person <- mnesia:table(Tab), Person#person.sex == male, Person#person.age > 30]),
    qlc:eval(Query)
end,
mnesia:transaction(Transaction),

Pour trier d'une manière efficace, qlc fournit qlc:sort.

-include_lib("stdlib/include/qlc.hrl")
Transaction = fun() ->
    Query = qlc:q([Person#person.name || Person <- mnesia:table(Tab), Person#person.sex == male, Person#person.age > 30]),
    Order = fun(A, B) ->
        B#person.age > A#person.age
    end,
    qlc:eval(qlc:sort(Query, [order, Order]))
end,
mnesia:transaction(Transaction),

Je n'ait pas encore exploré toutes les fonctionnalités de QLC, mais la syntaxe que ce module offre m'a convaincu de l'utiliser le plus possible. La maintenance des requêtes devient beaucoup plus facile.

Une dernière chose, il est possible de créer ses propres modules utilisable avec QLC. Vous pouvez ainsi proposer une syntaxe de recherche sympathique avec un backend totalement différent de ets ou mnesia.

blog comments powered by Disqus