[erlang-questions] Modifying an mnesia table key
Bengt Kleberg
bengt.kleberg@REDACTED
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>,nonode@REDACTED,
> {"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