diff options
author | Dan Gudmundsson <[email protected]> | 2011-09-19 10:45:32 +0200 |
---|---|---|
committer | Dan Gudmundsson <[email protected]> | 2011-09-19 10:45:32 +0200 |
commit | 7ebf84abf7e5d06ce9ef6ec11783318aa393093d (patch) | |
tree | de28f5b237c1f776fa2691e53a6b7c6d9f5f9a9e /lib/mnesia/src/mnesia_controller.erl | |
parent | 2d13b9580f405541e46491743702eaaedf3f6e91 (diff) | |
parent | 34f20bde33f7c4480ac78f56c7aa1a50ac12b14d (diff) | |
download | otp-7ebf84abf7e5d06ce9ef6ec11783318aa393093d.tar.gz otp-7ebf84abf7e5d06ce9ef6ec11783318aa393093d.tar.bz2 otp-7ebf84abf7e5d06ce9ef6ec11783318aa393093d.zip |
Merge branch 'dgud/mnesia/fix-compat/OTP-9473' into dev
* dgud/mnesia/fix-compat/OTP-9473:
[mnesia] Fix schema conversion to previous versions
[mnesia] Whitespace fixes
[mnesia] Update protocol version
[mnesia] Mnesia schema merge tested with 2 nodes, r13b04 -> r14b (dev)
[mnesia] Fixed bug in aborted schema transactions
[mnesia] Add hrl dependency
Diffstat (limited to 'lib/mnesia/src/mnesia_controller.erl')
-rw-r--r-- | lib/mnesia/src/mnesia_controller.erl | 47 |
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}). |