[erlang-questions] Mnesia wildcard query

Janos Hary janos.n.hary@REDACTED
Tue May 14 18:01:23 CEST 2013


Thanks for the answer. As far as I understand it works great if the prefix
is known at compile time. I wasn't clear on this, but in my case the prefix
is given in runtime.

 

So far I come up with this solution. It understands a '*' character at a
pattern's end. I'd be happy to get suggestions to improve it.

 

%% finds '*' in pattern and return a minimum and maximum pattern

%% e.g. <<"hello*">> -> {<<"hello">>, <<"hellp">>}

%% if binary string X starts with 'hello' then <<"hello">> <= X <
<<"hellp">>

wildcard(Pattern) when is_binary(Pattern) ->

       case binary:match(Pattern, <<"*">>) of

              nomatch -> 

                     {Pattern, Pattern};

              {0, _}  -> 

                     {error, wrong_pattern};

              {S, _}  ->

                     PatPref = binary:part(Pattern, 0, S-1),

                     io:format("~s", [PatPref]),

                     <<PatLast:8>> = binary:part(Pattern, S-1, 1),

                     {<<PatPref/binary, PatLast:8>>, <<PatPref/binary,
(PatLast+1):8>>}

       end.

 

find(Pat) ->

       {PatMin, PatMax} = wildcard(Pat),

       F = fun() ->

                     qlc:eval(qlc:q(

                           [Patient || #patient{search_name = N}=Patient <-
mnesia:table(pat),

                                         N >= PatMin, N < PatMax]

                     ))

              end,

       mnesia:activity(transaction, F, [], mnesia_frag).

 

 

Regards,

Janos

 

From: karol skocik [mailto:karol.skocik@REDACTED] 
Sent: Tuesday, May 14, 2013 12:32 PM
To: Janos Hary
Cc: Erlang Questions
Subject: Re: [erlang-questions] Mnesia wildcard query

 

You can use ets:fun2ms/1 to construct example match spec, which can be also
used for select over mnesia table:

 

3> Tab = ets:new(tab, []).

20496

4> ets:insert(Tab, [{"abcdef", 1}, {"abxxxxx", 2}, {"bbbbbb", 3}]).

true

5> MatchSpec = ets:fun2ms(fun ({[$a, $b | _], V}) -> V end).

[{{[97,98|'_'],'$1'},[],['$1']}]

6> ets:select(Tab, MatchSpec).

[1,2]

 

ets:fun2ms/1 does not recognize literal funs like: fun ({"prefix" ++ _, V)
-> V end, (++ is the problem)

so it's more convenient to write a simple wrapper function returning the
MatchSpec, given the prefix.

 

Cheers, 

  Karol

 

On Tue, May 14, 2013 at 10:44 AM, Janos Hary <janos.n.hary@REDACTED> wrote:

Hi,

 

Is there a way to specify a 'begins with' style query in Mnesia? My keys are
strings, and I'd like to get all of them sharing a given prefix.

 

Thanks,

Janos


_______________________________________________
erlang-questions mailing list
erlang-questions@REDACTED
http://erlang.org/mailman/listinfo/erlang-questions

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130514/5ccf2927/attachment.htm>


More information about the erlang-questions mailing list