What is the best way to prevent adding an entry whose primary key is already present in mnesia?

Suppose I have a simple entry:

-record(data, {primary_key = '_', more_stuff = '_'}).

I need a simple function that adds one of these entries to the mnesia database. But I want it to fail if there is already a record with the same primary key.

(In the following examples, suppose I have already defined

db_get_data(Key)->
    Q = qlc:q([Datum
               || Datum = #data{primary_key = RecordKey}
                      <- mnesia:table(data),
                  RecordKey =:= Key]),
    qlc:e(Q).

)

The following works, but seem to me somehow ugly ...

add_data(D) when is_record(D, data)->
    {atomic, Result} = mnesia:transaction(fun()->
                                                  case db_get_data(D#data.primary_key) of
                                                      [] -> db_add_data(D);
                                                      _ -> {error, bzzt_duplicate_primary_key}
                                                  end
                                          end),

    case Result of
        {error, _} = Error -> throw(Error);
        _ -> result
    end.

This also works, but also ugly:

add_data(D) when is_record(D, data)->
    {atomic, Result} = mnesia:transaction(fun()->
                                                  case db_get_data(D#data.primary_key) of
                                                      [] -> db_add_data(D);
                                                      _ -> throw({error, bzzt_duplicate_primary_key})
                                                  end
                                          end).

It differs from the above in that the above throws

{error, bzzt_duplicate_primary_key},

whereas this throw

{error, {badmatch, {aborted, {throw,{error, bzzt_duplicate_primary_key}}}}}

So: is there any agreement to indicate such an error? Or is there a built-in way that I can make mnesia throw this error for me?

+3
1

, , , :

add_data(D) when is_record(D, data)->

    Fun = fun() ->
                  case db_get_data(D#data.primary_key) of
                      [] -> db_add_data(D);
                      _  -> throw({error, bzzt_duplicate_primary_key})
                  end
          end,

    {atomic, Result} = mnesia:activity(transaction, Fun).

add_data(D) when is_record(D, data)->

    Fun = fun() ->
                  case db_get_data(D#data.primary_key) of
                      [] -> db_add_data(D);
                      _  -> {error, bzzt_duplicate_primary_key}
                  end
          end,

    {atomic, Result} = mnesia:activity(transaction, Fun),

    case Result of
        {error, Error} -> throw(Error);
        _              -> result
    end.

? . mnesia - , mnesia , api, "" mnesia , .

+3

Source: https://habr.com/ru/post/1706007/


All Articles