防止添加主键已经存在于mnesia中的记录的最佳方法是什么?

时间:2009-04-06 23:52:32

标签: database erlang mnesia

假设我有一个简单的记录定义:

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

我想要一个简单的函数,将其中一条记录添加到mnesia数据库中。但是如果已经有一个具有相同主要条目的条目,我希望它失败 键。

(在以下示例中,假设我已经定义了

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

以下作品,但让我觉得有点难看......

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.

这也有效,但也很难看:

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).

与上述不同之处在于上述抛出

{error, bzzt_duplicate_primary_key},

而这一次抛出

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

那么:是否有一些表示这种错误的约定?或者是否有内置的方式让我可以让mnesia为我抛出这个错误?

1 个答案:

答案 0 :(得分:3)

我认为两者都很好,如果你只是让你的代码更漂亮,比如:

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事务,其功能看起来与上面的类似