[erlang-questions] How best to extract value from mnesia query

lloyd@REDACTED lloyd@REDACTED
Thu Nov 16 00:31:58 CET 2017


Hi Jesper,

Thank you!

Lloyd

-----Original Message-----
From: "Jesper Louis Andersen" <jesper.louis.andersen@REDACTED>
Sent: Wednesday, November 15, 2017 4:44pm
To: lloyd@REDACTED
Cc: "Erlang" <erlang-questions@REDACTED>
Subject: Re: [erlang-questions] How best to extract value from mnesia query

I usually do something like:

Txn = fun() -> ... end,
case mnesia:transaction(Txn) of
    {atomic, []} ->
       not_found;
    {atomic, [V]} ->
       <One_Value_Case>
    {atomic, L = [_|_]} ->
        <Multi_Value_Case>
end.

Some times, if there are a bunch of cases, I tend to use a function such as
your confirm/1 function, passing the result on and writing down the case
split at the top level, but it depends a bit on wether I like that code
flow or not in that particular case. In general I prefer matching and
binding values over projection functions such as hd/1, because hd/1 doesn't
work on all lists, only the non-empty ones.

Another common trick is that if your Results are lists, then you can often
avoid using a not_found atom, but handle the [] case naturally. Consider
that

[] = lists:map(F, [])

which is true for a lot of functions working on lists. This suggests you
can avoid having multiple data flows in this case, and use [] as a
degenerate case which "skips" computations in a natural way. This can
sometimes turn a code flow which case-splits its control flow all the time
into a flow that just has one path. Flow with a single path tend to be far
easier to handle in the long run in my experience.

Also, if you really do expect there to be a value, then I use

{atomic, [Value]} = mnesia:transaction(Txn),

and crash the code if it is violated. Defensive code is often a mistake in
Erlang because we can just use the standard crash semantics to recover.
Many other languages doesn't fare so well here.


On Wed, Nov 15, 2017 at 9:04 PM <lloyd@REDACTED> wrote:

> Hello,
>
> The result of a mnesia read transaction looks like this:
>
>    {atomic, Results} where result is either a populated list [value1, ...
> valueN] or, an empty list [].
>
> If the table is initialized as set, then the returned list will contain at
> most one value, e.g:
>
>   [value].
>
> If I want to use of the value in a function or to populate another record,
> I need to extract the value from the list.
>
> I've tried various ways to do this, but they all seem clumsy:
>
> E.g.
>
> [MyValue]
>
> hd[vlaue]
>
> confirm([]) ->
>     not_found;
> confirm([Value]) ->
>     Value;
> confirm(Value) ->
>     Value.
>
> Does there happen to be a preferred/conventional/best-practices way to do
> this?
>
> Many thanks,
>
> LRP
>
>
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>





More information about the erlang-questions mailing list