aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia/src/mnesia_controller.erl
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2011-09-19 10:49:19 +0200
committerDan Gudmundsson <[email protected]>2011-09-19 10:49:19 +0200
commit40f724a33dae5e7670a710e32abe3493d660ea46 (patch)
treeb181a3e25adf5aa5c28d9a7fe022590004ee7be2 /lib/mnesia/src/mnesia_controller.erl
parent87288e173f09d573460a06d98466f84cba8f4b5c (diff)
parent7ebf84abf7e5d06ce9ef6ec11783318aa393093d (diff)
downloadotp-40f724a33dae5e7670a710e32abe3493d660ea46.tar.gz
otp-40f724a33dae5e7670a710e32abe3493d660ea46.tar.bz2
otp-40f724a33dae5e7670a710e32abe3493d660ea46.zip
Merge branch 'dev' into major
Diffstat (limited to 'lib/mnesia/src/mnesia_controller.erl')
-rw-r--r--lib/mnesia/src/mnesia_controller.erl47
1 files changed, 45 insertions, 2 deletions
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index d4b2c7b5cc..1d3bd55b48 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -57,7 +57,8 @@
release_schema_commit_lock/0,
create_table/1,
get_disc_copy/1,
- get_cstructs/0,
+ get_remote_cstructs/0, % new function
+ get_cstructs/0, % old function
sync_and_block_table_whereabouts/4,
sync_del_table_copy_whereabouts/2,
block_table/1,
@@ -278,9 +279,51 @@ rec_tabs([], _, _, Init) ->
unlink(Init),
ok.
-get_cstructs() ->
+%% New function that does exactly what get_cstructs() used to do.
+%% When this function is called, we know that the calling node knows
+%% how to convert cstructs on the receiving end (should they differ).
+get_remote_cstructs() ->
call(get_cstructs).
+%% Old function kept for backwards compatibility; converts cstructs before sending.
+get_cstructs() ->
+ {cstructs, Cstructs, Running} = call(get_cstructs),
+ Node = node(group_leader()),
+ {cstructs, normalize_cstructs(Cstructs, Node), Running}.
+
+normalize_cstructs(Cstructs, Node) ->
+ %% backward-compatibility hack; normalize before returning
+ case rpc:call(Node, mnesia_lib, val, [{schema,cstruct}]) of
+ {badrpc, _} ->
+ %% assume it's not a schema merge
+ Cstructs;
+ #cstruct{} ->
+ %% same format
+ Cstructs;
+ Cstruct ->
+ %% some other format
+ RemoteFields = [F || {F,_} <- rpc:call(Node, mnesia_schema, cs2list, [Cstruct])],
+ [convert_cs(Cs, RemoteFields) || Cs <- Cstructs]
+ end.
+
+convert_cs(Cs, Fields) ->
+ MyFields = record_info(fields, cstruct),
+ convert(tl(tuple_to_list(Cs)), MyFields, Fields, []).
+
+convert([H|T], [F|FsL], [F|FsR], Acc) ->
+ convert(T, FsL, FsR, [H|Acc]);
+convert([H|T], [Fl|FsL] = L, [Fr|FsR] = R, Acc) ->
+ case {lists:member(Fl, FsR), lists:member(Fr, FsL)} of
+ {true, false} ->
+ convert(T, L, FsR, [H|Acc]);
+ {false, true} ->
+ %% Field Fl doesn't exist on receiver side; skip.
+ convert(T, FsL, R, Acc)
+ end;
+convert([], _, _, Acc) ->
+ list_to_tuple([cstruct|lists:reverse(Acc)]).
+
+
update(Fun) ->
call({update,Fun}).