3

単純なレコード定義があるとします。

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

これらのレコードの1つを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にこのエラーをスローさせる組み込みの方法はありますか?

4

1 に答える 1

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 アクティビティを実行する一連の機能を備えたモジュールと、ワーク ユニットを上記のものと非常によく似た機能を持つ mnesia トランザクションに「構成」する API モジュールです。 .

于 2009-04-07T06:18:52.970 に答える