[erlang-questions] Modifying an mnesia table key

Bengt Kleberg <>
Fri May 29 09:01:06 CEST 2009


Greetings,

If you want to change the keys for all entries in a mnesia table you
have to loop over the whole table (either mnesia:foldl/3 or
mnesia:first/1, mnesia:next/2) and
1) read the object
2) delete it
3) modify it
4) write the new object.

The way the code in mnesia_schema:transform_obj/9 is written makes it
impossible to change the key. There is probably a good reason for this,
but I do not understand why.


bengt

(On Fri, 2009-05-29 at 02:35 +0100, Dale Harvey wrote:
> is the only way to modify the key of an mnesia table to copy
> it to a temporary table and back again manually or am I missing
> something?
> 
> -module(test).
> -compile(export_all).
> 
> test() ->
>     application:stop(mnesia),
>     ok = mnesia:delete_schema([node()]),
>     ok = mnesia:create_schema([node()]),
>     application:start(mnesia),
>     create(),
>     mnesia:dirty_write(test, {test, "123", "some data"}),
>     transform().
> 
> create() ->
>     mnesia:create_table(test, [{type, bag},
>                                {attributes, [id, field1]}]).
> 
> transform() ->
>     F = fun({test, _Id, Field}) ->
>                 {test, 123, Field}
>         end,
>     mnesia:transform_table(test, F, [id, field1]).
> 
> >test:test().
> {aborted,{"Bad transform function",test,
>           #Fun<test.0.115054077>,
>           {"Bad key or Record Name",
>            {test,"123","some data"},
>            {test,123,"some data"}}}}
> 
> (also slightly confused by the transform function in mnesia_scheme.erl that
> seems to read that transforms will only work if the transformed record is
> == to the original one)
> 
> transform_obj(Tab, RecName, Key, Fun, [Obj|Rest], NewArity, Type, Ws, Ds) ->
>     NewObj = Fun(Obj),
>     if
>         size(NewObj) /= NewArity ->
>             exit({"Bad arity", Obj, NewObj});
>     NewObj == Obj ->
>         transform_obj(Tab, RecName, Key, Fun, Rest, NewArity, Type, Ws, Ds);
>         RecName == element(1, NewObj), Key == element(2, NewObj) ->
>             transform_obj(Tab, RecName, Key, Fun, Rest, NewArity,
>               Type, [NewObj | Ws], Ds);
>     NewObj == delete ->
>         case Type of
>         bag -> %% Just don't write that object
>            transform_obj(Tab, RecName, Key, Fun, Rest,
>                  NewArity, Type, Ws, Ds);
>         _ ->
>             transform_obj(Tab, RecName, Key, Fun, Rest, NewArity,
>                   Type, Ws, [NewObj | Ds])
>         end;
>         true ->
>             exit({"Bad key or Record Name", Obj, NewObj})
>     end;



More information about the erlang-questions mailing list