[erlang-questions] Mnesia queries

Ulf Wiger (TN/EAB) <>
Tue Dec 11 16:37:00 CET 2007


Bob Cowdery skrev:
> 
> Bob Cowdery skrev:
>> I need a little help with mnesia queries. I want to parameterise the query but can't seem to find any examples of how to do that. The general form seems to be
>>
>> qlc:q([X#rec.bar || X <- mnesia:table(foo), X#rec.bar == baz])
>>
>> If I now want to select columns at run time is there some way I can construct the left side of the qlc.
>>
>> Thanks
>> Bob
> 
>>> Do you mean something like this?
> 
>>> qlc:q([{X#rec.bar, X#rec.baz} || X <- mnesia:table(foo), ...])
> 
> 
> I've used that construct when I want to select several columns and know what they are at compile time. If I want to do that at run time by passing in a list like: 
> 
> myquery(List) ->
> 	qlc:q([{construct this from 'List'} || X <- mnesia:table(foo), ...]).
> 
> what is the approach to doing that.

You can put any expression on the LHS of a list comprehension,
and you can construct something at run-time e.g. using the
function mnesia:table_info/2:


myquery(Cols, List) ->
    PosL = cols2pos(Cols),
    qlc:q([ [element(P,X) || P <- PosL] ||
              X <- mnesia:table(foo), ...]).

cols2pos(Cols) ->
    Attrs = mnesia:table_info(foo, attributes),
    Arity = length(Attrs) + 1,
    lists:map(
       fun(P) when is_integer(P), P > 1, P =< Arity -> P;
          (C) when is_atom(C) -> pos(C, Attrs)
       end, Cols).

pos(X, L) ->
   pos(X, L, 2). % record tag is pos 1

pos(H, [H|_], P) -> P;
pos(H, [_|T], P) ->
    pos(H, T, P+1).

You can of course also make use of my little exprecs.erl
parse transform, which generates accessor functions for
records.

http://forum.trapexit.org/viewtopic.php?p=21790#21790

BR,
Ulf W



More information about the erlang-questions mailing list