25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

Refactor mod_last to use the same core get_last/2 functionality, but keep api stable

The local function get_last/4 has been renamed to get_last_iq/4, since
it converts the result of get_last/2 (typically {ok, TimeStamp, Status})
to an iq packet.
This commit is contained in:
Andreas Köhler 2010-11-05 18:32:25 +01:00 committed by Badlop
parent 510fd8cf73
commit 100f2e9a13
2 changed files with 52 additions and 43 deletions

View File

@ -129,7 +129,7 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
{xmlelement, "presence", [], []}}, {xmlelement, "presence", [], []}},
out]) of out]) of
allow -> allow ->
get_last(IQ, SubEl, User, Server); get_last_iq(IQ, SubEl, User, Server);
deny -> deny ->
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_FORBIDDEN]} sub_el = [SubEl, ?ERR_FORBIDDEN]}
@ -140,14 +140,25 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
end end
end. end.
%% TODO: This function could use get_last_info/2 %% @spec (LUser::string(), LServer::string()) ->
get_last(IQ, SubEl, LUser, LServer) -> %% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason}
get_last(LUser, LServer) ->
case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of
{'EXIT', _Reason} -> {'EXIT', Reason} ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; {error, Reason};
[] -> [] ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; not_found;
[#last_activity{timestamp = TimeStamp, status = Status}] -> [#last_activity{timestamp = TimeStamp, status = Status}] ->
{ok, TimeStamp, Status}
end.
get_last_iq(IQ, SubEl, LUser, LServer) ->
case get_last(LUser, LServer) of
{error, _Reason} ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
not_found ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
{ok, TimeStamp, Status} ->
TimeStamp2 = now_to_seconds(now()), TimeStamp2 = now_to_seconds(now()),
Sec = TimeStamp2 - TimeStamp, Sec = TimeStamp2 - TimeStamp,
IQ#iq{type = result, IQ#iq{type = result,
@ -157,8 +168,6 @@ get_last(IQ, SubEl, LUser, LServer) ->
[{xmlcdata, Status}]}]} [{xmlcdata, Status}]}]}
end. end.
on_presence_update(User, Server, _Resource, Status) -> on_presence_update(User, Server, _Resource, Status) ->
TimeStamp = now_to_seconds(now()), TimeStamp = now_to_seconds(now()),
store_last_info(User, Server, TimeStamp, Status). store_last_info(User, Server, TimeStamp, Status).
@ -177,13 +186,11 @@ store_last_info(User, Server, TimeStamp, Status) ->
%% @spec (LUser::string(), LServer::string()) -> %% @spec (LUser::string(), LServer::string()) ->
%% {ok, TimeStamp::integer(), Status::string()} | not_found %% {ok, TimeStamp::integer(), Status::string()} | not_found
get_last_info(LUser, LServer) -> get_last_info(LUser, LServer) ->
case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of case get_last(LUser, LServer) of
{'EXIT', _Reason} -> {error, _Reason} ->
not_found; not_found;
[] -> Res ->
not_found; Res
[#last_activity{timestamp = TimeStamp, status = Status}] ->
{ok, TimeStamp, Status}
end. end.
remove_user(User, Server) -> remove_user(User, Server) ->

View File

@ -121,7 +121,7 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
{xmlelement, "presence", [], []}}, {xmlelement, "presence", [], []}},
out]) of out]) of
allow -> allow ->
get_last(IQ, SubEl, User, Server); get_last_iq(IQ, SubEl, User, Server);
deny -> deny ->
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_FORBIDDEN]} sub_el = [SubEl, ?ERR_FORBIDDEN]}
@ -132,28 +132,38 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
end end
end. end.
%% TODO: This function could use get_last_info/2 %% @spec (LUser::string(), LServer::string()) ->
get_last(IQ, SubEl, LUser, LServer) -> %% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason}
get_last(LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser), Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_last(LServer, Username) of case catch odbc_queries:get_last(LServer, Username) of
{selected, ["seconds","state"], []} -> {selected, ["seconds","state"], []} ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; not_found;
{selected, ["seconds","state"], [{STimeStamp, Status}]} -> {selected, ["seconds","state"], [{STimeStamp, Status}]} ->
case catch list_to_integer(STimeStamp) of case catch list_to_integer(STimeStamp) of
TimeStamp when is_integer(TimeStamp) -> TimeStamp when is_integer(TimeStamp) ->
{ok, TimeStamp, Status};
Reason ->
{error, {invalid_timestamp, Reason}}
end;
Reason ->
{error, {invalid_result, Reason}}
end.
get_last_iq(IQ, SubEl, LUser, LServer) ->
case get_last(LUser, LServer) of
{error, _Reason} ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
not_found ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
{ok, TimeStamp, Status} ->
TimeStamp2 = now_to_seconds(now()), TimeStamp2 = now_to_seconds(now()),
Sec = TimeStamp2 - TimeStamp, Sec = TimeStamp2 - TimeStamp,
IQ#iq{type = result, IQ#iq{type = result,
sub_el = [{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_LAST}, [{"xmlns", ?NS_LAST},
{"seconds", integer_to_list(Sec)}], {"seconds", integer_to_list(Sec)}],
[{xmlcdata, Status}]}]}; [{xmlcdata, Status}]}]}
_ ->
IQ#iq{type = error,
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
end;
_ ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
end. end.
on_presence_update(User, Server, _Resource, Status) -> on_presence_update(User, Server, _Resource, Status) ->
@ -169,21 +179,13 @@ store_last_info(User, Server, TimeStamp, Status) ->
odbc_queries:set_last_t(LServer, Username, Seconds, State). odbc_queries:set_last_t(LServer, Username, Seconds, State).
%% @spec (LUser::string(), LServer::string()) -> %% @spec (LUser::string(), LServer::string()) ->
%% {ok, Timestamp::integer(), Status::string()} | not_found %% {ok, TimeStamp::integer(), Status::string()} | not_found
get_last_info(LUser, LServer) -> get_last_info(LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser), case get_last(LUser, LServer) of
case catch odbc_queries:get_last(LServer, Username) of {error, _Reason} ->
{selected, ["seconds","state"], []} ->
not_found; not_found;
{selected, ["seconds","state"], [{STimeStamp, Status}]} -> Res ->
case catch list_to_integer(STimeStamp) of Res
TimeStamp when is_integer(TimeStamp) ->
{ok, TimeStamp, Status};
_ ->
not_found
end;
_ ->
not_found
end. end.
remove_user(User, Server) -> remove_user(User, Server) ->