%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
-module(tv_ets_rpc).
-export([all/2,
info/4,
new/4,
tab2list/3,
insert/4,
lookup/4,
delete/4
]).
all(_Node, true) ->
chk(catch ets:all());
all(Node, false) ->
chk(catch rpc:block_call(Node, ets, all, [])).
info(_Node, true, TabId, What) ->
chk(catch ets:info(TabId, What));
info(Node, false, TabId, What) ->
chk(catch rpc:block_call(Node, ets, info, [TabId, What])).
new(_Node, true, TabName, Options) ->
case catch ets:new(TabName, Options) of
{TabName, Pid} when is_pid(Pid) ->
{TabName,Pid};
{TabNo, Pid} when is_pid(Pid) ->
{TabNo,Pid};
OtherResult ->
chk(OtherResult)
end;
new(Node, false, TabName, Options) ->
case catch rpc:block_call(Node, ets, new, [TabName, Options]) of
{TabName, Pid} when is_pid(Pid) ->
{TabName,Pid};
{TabNo, Pid} when is_pid(Pid) ->
{TabNo, Pid};
OtherResult ->
chk(OtherResult)
end.
tab2list(_Node, true, TabId) ->
chk(catch ets:tab2list(TabId));
tab2list(Node, false, TabId) ->
chk(catch rpc:call(Node, ets, tab2list, [TabId])).
insert(_Node, true, TabId, Object) ->
chk(catch ets:insert(TabId, Object));
insert(Node, false, TabId, Object) ->
chk(catch rpc:call(Node, ets, insert, [TabId, Object])).
lookup(_Node, true, TabId, Key) ->
chk(catch ets:lookup(TabId, Key));
lookup(Node, false, TabId, Key) ->
chk(catch rpc:call(Node, ets, lookup, [TabId, Key])).
delete(_Node, true, TabId, Key) ->
chk(catch ets:delete(TabId, Key));
delete(Node, false, TabId, Key) ->
chk(catch rpc:call(Node, ets, delete, [TabId, Key])).
chk(Result) ->
case Result of
undefined ->
throw(no_table);
_Anything when is_list(Result) ->
Result;
_Anything when is_atom(Result) ->
Result;
_Anything when is_integer(Result) ->
Result;
_Anything when is_pid(Result) ->
Result;
%% Messages received when node is down.
{badrpc, nodedown} ->
throw(nodedown);
{'EXIT', nodedown} ->
throw(nodedown);
{'EXIT', {{badarg, {gen, set_monitor_node, _Args}}, _Reason}} ->
throw(nodedown);
%% Messages received when table doesn't exist.
{'EXIT', {badarg, {ets,local_info,_Args}}} ->
%% Due to inconsistencies in R2D and earlier versions:
%% ets:info/1 returned 'undefined' when table didn't
%% exist, while ets:info/2 returned the exit-signal
%% above. This was corrected in R3A - now both functions
%% return 'undefined' :-)
throw(no_table);
{badrpc, {'EXIT', {badarg,_Reason}}} ->
throw(no_table);
{'EXIT', {badarg,_Reason}} ->
throw(no_table);
Error when is_tuple(Error) ->
throw({unexpected_error,Error})
end.