mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Clean mod_last.erl from DB specific code
This commit is contained in:
parent
5eef8a8bcf
commit
7fd4808cde
3
include/mod_last.hrl
Normal file
3
include/mod_last.hrl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-record(last_activity, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||||
|
timestamp = 0 :: non_neg_integer(),
|
||||||
|
status = <<"">> :: binary()}).
|
152
src/mod_last.erl
152
src/mod_last.erl
@ -45,23 +45,21 @@
|
|||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
|
|
||||||
-include("mod_privacy.hrl").
|
-include("mod_privacy.hrl").
|
||||||
|
-include("mod_last.hrl").
|
||||||
|
|
||||||
-record(last_activity, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
timestamp = 0 :: non_neg_integer(),
|
-callback import(binary(), #last_activity{}) -> ok | pass.
|
||||||
status = <<"">> :: binary()}).
|
-callback get_last(binary(), binary()) ->
|
||||||
|
{ok, non_neg_integer(), binary()} | not_found | {error, any()}.
|
||||||
|
-callback store_last_info(binary(), binary(), non_neg_integer(), binary()) ->
|
||||||
|
{atomic, any()}.
|
||||||
|
-callback remove_user(binary(), binary()) -> {atomic, any()}.
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||||
one_queue),
|
one_queue),
|
||||||
case gen_mod:db_type(Host, Opts) of
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
mnesia ->
|
Mod:init(Host, Opts),
|
||||||
mnesia:create_table(last_activity,
|
|
||||||
[{disc_copies, [node()]},
|
|
||||||
{attributes,
|
|
||||||
record_info(fields, last_activity)}]),
|
|
||||||
update_table();
|
|
||||||
_ -> ok
|
|
||||||
end,
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_LAST, ?MODULE, process_local_iq, IQDisc),
|
?NS_LAST, ?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
||||||
@ -163,38 +161,8 @@ process_sm_iq(From, To,
|
|||||||
%% @spec (LUser::string(), LServer::string()) ->
|
%% @spec (LUser::string(), LServer::string()) ->
|
||||||
%% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason}
|
%% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason}
|
||||||
get_last(LUser, LServer) ->
|
get_last(LUser, LServer) ->
|
||||||
get_last(LUser, LServer,
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
gen_mod:db_type(LServer, ?MODULE)).
|
Mod:get_last(LUser, LServer).
|
||||||
|
|
||||||
get_last(LUser, LServer, mnesia) ->
|
|
||||||
case catch mnesia:dirty_read(last_activity,
|
|
||||||
{LUser, LServer})
|
|
||||||
of
|
|
||||||
{'EXIT', Reason} -> {error, Reason};
|
|
||||||
[] -> not_found;
|
|
||||||
[#last_activity{timestamp = TimeStamp,
|
|
||||||
status = Status}] ->
|
|
||||||
{ok, TimeStamp, Status}
|
|
||||||
end;
|
|
||||||
get_last(LUser, LServer, riak) ->
|
|
||||||
case ejabberd_riak:get(last_activity, last_activity_schema(),
|
|
||||||
{LUser, LServer}) of
|
|
||||||
{ok, #last_activity{timestamp = TimeStamp,
|
|
||||||
status = Status}} ->
|
|
||||||
{ok, TimeStamp, Status};
|
|
||||||
{error, notfound} ->
|
|
||||||
not_found;
|
|
||||||
Err ->
|
|
||||||
Err
|
|
||||||
end;
|
|
||||||
get_last(LUser, LServer, odbc) ->
|
|
||||||
case catch odbc_queries:get_last(LServer, LUser) of
|
|
||||||
{selected, []} ->
|
|
||||||
not_found;
|
|
||||||
{selected, [{TimeStamp, Status}]} ->
|
|
||||||
{ok, TimeStamp, Status};
|
|
||||||
Reason -> {error, {invalid_result, Reason}}
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_last_iq(#iq{lang = Lang} = IQ, SubEl, LUser, LServer) ->
|
get_last_iq(#iq{lang = Lang} = IQ, SubEl, LUser, LServer) ->
|
||||||
case ejabberd_sm:get_user_resources(LUser, LServer) of
|
case ejabberd_sm:get_user_resources(LUser, LServer) of
|
||||||
@ -237,29 +205,8 @@ on_presence_update(User, Server, _Resource, Status) ->
|
|||||||
store_last_info(User, Server, TimeStamp, Status) ->
|
store_last_info(User, Server, TimeStamp, Status) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
DBType = gen_mod:db_type(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
store_last_info(LUser, LServer, TimeStamp, Status,
|
Mod:store_last_info(LUser, LServer, TimeStamp, Status).
|
||||||
DBType).
|
|
||||||
|
|
||||||
store_last_info(LUser, LServer, TimeStamp, Status,
|
|
||||||
mnesia) ->
|
|
||||||
US = {LUser, LServer},
|
|
||||||
F = fun () ->
|
|
||||||
mnesia:write(#last_activity{us = US,
|
|
||||||
timestamp = TimeStamp,
|
|
||||||
status = Status})
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F);
|
|
||||||
store_last_info(LUser, LServer, TimeStamp, Status,
|
|
||||||
riak) ->
|
|
||||||
US = {LUser, LServer},
|
|
||||||
{atomic, ejabberd_riak:put(#last_activity{us = US,
|
|
||||||
timestamp = TimeStamp,
|
|
||||||
status = Status},
|
|
||||||
last_activity_schema())};
|
|
||||||
store_last_info(LUser, LServer, TimeStamp, Status,
|
|
||||||
odbc) ->
|
|
||||||
odbc_queries:set_last_t(LServer, LUser, 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
|
||||||
@ -272,71 +219,20 @@ get_last_info(LUser, LServer) ->
|
|||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
DBType = gen_mod:db_type(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
remove_user(LUser, LServer, DBType).
|
Mod:remove_user(LUser, LServer).
|
||||||
|
|
||||||
remove_user(LUser, LServer, mnesia) ->
|
export(LServer) ->
|
||||||
US = {LUser, LServer},
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
F = fun () -> mnesia:delete({last_activity, US}) end,
|
Mod:export(LServer).
|
||||||
mnesia:transaction(F);
|
|
||||||
remove_user(LUser, LServer, odbc) ->
|
|
||||||
odbc_queries:del_last(LServer, LUser);
|
|
||||||
remove_user(LUser, LServer, riak) ->
|
|
||||||
{atomic, ejabberd_riak:delete(last_activity, {LUser, LServer})}.
|
|
||||||
|
|
||||||
update_table() ->
|
|
||||||
Fields = record_info(fields, last_activity),
|
|
||||||
case mnesia:table_info(last_activity, attributes) of
|
|
||||||
Fields ->
|
|
||||||
ejabberd_config:convert_table_to_binary(
|
|
||||||
last_activity, Fields, set,
|
|
||||||
fun(#last_activity{us = {U, _}}) -> U end,
|
|
||||||
fun(#last_activity{us = {U, S}, status = Status} = R) ->
|
|
||||||
R#last_activity{us = {iolist_to_binary(U),
|
|
||||||
iolist_to_binary(S)},
|
|
||||||
status = iolist_to_binary(Status)}
|
|
||||||
end);
|
|
||||||
_ ->
|
|
||||||
?INFO_MSG("Recreating last_activity table", []),
|
|
||||||
mnesia:transform_table(last_activity, ignore, Fields)
|
|
||||||
end.
|
|
||||||
|
|
||||||
last_activity_schema() ->
|
|
||||||
{record_info(fields, last_activity), #last_activity{}}.
|
|
||||||
|
|
||||||
export(_Server) ->
|
|
||||||
[{last_activity,
|
|
||||||
fun(Host, #last_activity{us = {LUser, LServer},
|
|
||||||
timestamp = TimeStamp, status = Status})
|
|
||||||
when LServer == Host ->
|
|
||||||
Username = ejabberd_odbc:escape(LUser),
|
|
||||||
Seconds =
|
|
||||||
ejabberd_odbc:escape(jlib:integer_to_binary(TimeStamp)),
|
|
||||||
State = ejabberd_odbc:escape(Status),
|
|
||||||
[[<<"delete from last where username='">>, Username, <<"';">>],
|
|
||||||
[<<"insert into last(username, seconds, "
|
|
||||||
"state) values ('">>,
|
|
||||||
Username, <<"', '">>, Seconds, <<"', '">>, State,
|
|
||||||
<<"');">>]];
|
|
||||||
(_Host, _R) ->
|
|
||||||
[]
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(LServer) ->
|
import(LServer) ->
|
||||||
[{<<"select username, seconds, state from last">>,
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
fun([LUser, TimeStamp, State]) ->
|
Mod:import(LServer).
|
||||||
#last_activity{us = {LUser, LServer},
|
|
||||||
timestamp = jlib:binary_to_integer(
|
|
||||||
TimeStamp),
|
|
||||||
status = State}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_LServer, mnesia, #last_activity{} = LA) ->
|
import(LServer, DBType, LA) ->
|
||||||
mnesia:dirty_write(LA);
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
import(_LServer, riak, #last_activity{} = LA) ->
|
Mod:import(LServer, LA).
|
||||||
ejabberd_riak:put(LA, last_activity_schema());
|
|
||||||
import(_, _, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
transform_options(Opts) ->
|
transform_options(Opts) ->
|
||||||
lists:foldl(fun transform_options/2, [], Opts).
|
lists:foldl(fun transform_options/2, [], Opts).
|
||||||
|
72
src/mod_last_mnesia.erl
Normal file
72
src/mod_last_mnesia.erl
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_last_mnesia).
|
||||||
|
-behaviour(mod_last).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, import/2, get_last/2, store_last_info/4, remove_user/2]).
|
||||||
|
|
||||||
|
-include("mod_last.hrl").
|
||||||
|
-include("logger.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
mnesia:create_table(last_activity,
|
||||||
|
[{disc_copies, [node()]},
|
||||||
|
{attributes,
|
||||||
|
record_info(fields, last_activity)}]),
|
||||||
|
update_table().
|
||||||
|
|
||||||
|
get_last(LUser, LServer) ->
|
||||||
|
case mnesia:dirty_read(last_activity, {LUser, LServer}) of
|
||||||
|
[] ->
|
||||||
|
not_found;
|
||||||
|
[#last_activity{timestamp = TimeStamp,
|
||||||
|
status = Status}] ->
|
||||||
|
{ok, TimeStamp, Status}
|
||||||
|
end.
|
||||||
|
|
||||||
|
store_last_info(LUser, LServer, TimeStamp, Status) ->
|
||||||
|
US = {LUser, LServer},
|
||||||
|
F = fun () ->
|
||||||
|
mnesia:write(#last_activity{us = US,
|
||||||
|
timestamp = TimeStamp,
|
||||||
|
status = Status})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
remove_user(LUser, LServer) ->
|
||||||
|
US = {LUser, LServer},
|
||||||
|
F = fun () -> mnesia:delete({last_activity, US}) end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
import(_LServer, #last_activity{} = LA) ->
|
||||||
|
mnesia:dirty_write(LA).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
||||||
|
update_table() ->
|
||||||
|
Fields = record_info(fields, last_activity),
|
||||||
|
case mnesia:table_info(last_activity, attributes) of
|
||||||
|
Fields ->
|
||||||
|
ejabberd_config:convert_table_to_binary(
|
||||||
|
last_activity, Fields, set,
|
||||||
|
fun(#last_activity{us = {U, _}}) -> U end,
|
||||||
|
fun(#last_activity{us = {U, S}, status = Status} = R) ->
|
||||||
|
R#last_activity{us = {iolist_to_binary(U),
|
||||||
|
iolist_to_binary(S)},
|
||||||
|
status = iolist_to_binary(Status)}
|
||||||
|
end);
|
||||||
|
_ ->
|
||||||
|
?INFO_MSG("Recreating last_activity table", []),
|
||||||
|
mnesia:transform_table(last_activity, ignore, Fields)
|
||||||
|
end.
|
53
src/mod_last_riak.erl
Normal file
53
src/mod_last_riak.erl
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_last_riak).
|
||||||
|
-behaviour(mod_last).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, import/2, get_last/2, store_last_info/4, remove_user/2]).
|
||||||
|
|
||||||
|
-include("mod_last.hrl").
|
||||||
|
-include("logger.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
get_last(LUser, LServer) ->
|
||||||
|
case ejabberd_riak:get(last_activity, last_activity_schema(),
|
||||||
|
{LUser, LServer}) of
|
||||||
|
{ok, #last_activity{timestamp = TimeStamp,
|
||||||
|
status = Status}} ->
|
||||||
|
{ok, TimeStamp, Status};
|
||||||
|
{error, notfound} ->
|
||||||
|
not_found;
|
||||||
|
Err ->
|
||||||
|
Err
|
||||||
|
end.
|
||||||
|
|
||||||
|
store_last_info(LUser, LServer, TimeStamp, Status) ->
|
||||||
|
US = {LUser, LServer},
|
||||||
|
{atomic, ejabberd_riak:put(#last_activity{us = US,
|
||||||
|
timestamp = TimeStamp,
|
||||||
|
status = Status},
|
||||||
|
last_activity_schema())}.
|
||||||
|
|
||||||
|
remove_user(LUser, LServer) ->
|
||||||
|
{atomic, ejabberd_riak:delete(last_activity, {LUser, LServer})}.
|
||||||
|
|
||||||
|
import(_LServer, #last_activity{} = LA) ->
|
||||||
|
ejabberd_riak:put(LA, last_activity_schema()).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
||||||
|
last_activity_schema() ->
|
||||||
|
{record_info(fields, last_activity), #last_activity{}}.
|
75
src/mod_last_sql.erl
Normal file
75
src/mod_last_sql.erl
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @copyright (C) 2016, Evgeny Khramtsov
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mod_last_sql).
|
||||||
|
-behaviour(mod_last).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([init/2, get_last/2, store_last_info/4, remove_user/2,
|
||||||
|
import/1, import/2, export/1]).
|
||||||
|
|
||||||
|
-include("mod_last.hrl").
|
||||||
|
-include("logger.hrl").
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
init(_Host, _Opts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
get_last(LUser, LServer) ->
|
||||||
|
case catch odbc_queries:get_last(LServer, LUser) of
|
||||||
|
{selected, []} ->
|
||||||
|
not_found;
|
||||||
|
{selected, [{TimeStamp, Status}]} ->
|
||||||
|
{ok, TimeStamp, Status};
|
||||||
|
Reason ->
|
||||||
|
?ERROR_MSG("failed to get last for user ~s@~s: ~p",
|
||||||
|
[LUser, LServer, Reason]),
|
||||||
|
{error, {invalid_result, Reason}}
|
||||||
|
end.
|
||||||
|
|
||||||
|
store_last_info(LUser, LServer, TimeStamp, Status) ->
|
||||||
|
odbc_queries:set_last_t(LServer, LUser, TimeStamp, Status).
|
||||||
|
|
||||||
|
remove_user(LUser, LServer) ->
|
||||||
|
odbc_queries:del_last(LServer, LUser).
|
||||||
|
|
||||||
|
import(_LServer, _LA) ->
|
||||||
|
pass.
|
||||||
|
|
||||||
|
export(_Server) ->
|
||||||
|
[{last_activity,
|
||||||
|
fun(Host, #last_activity{us = {LUser, LServer},
|
||||||
|
timestamp = TimeStamp, status = Status})
|
||||||
|
when LServer == Host ->
|
||||||
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
|
Seconds =
|
||||||
|
ejabberd_odbc:escape(jlib:integer_to_binary(TimeStamp)),
|
||||||
|
State = ejabberd_odbc:escape(Status),
|
||||||
|
[[<<"delete from last where username='">>, Username, <<"';">>],
|
||||||
|
[<<"insert into last(username, seconds, "
|
||||||
|
"state) values ('">>,
|
||||||
|
Username, <<"', '">>, Seconds, <<"', '">>, State,
|
||||||
|
<<"');">>]];
|
||||||
|
(_Host, _R) ->
|
||||||
|
[]
|
||||||
|
end}].
|
||||||
|
|
||||||
|
import(LServer) ->
|
||||||
|
[{<<"select username, seconds, state from last">>,
|
||||||
|
fun([LUser, TimeStamp, State]) ->
|
||||||
|
#last_activity{us = {LUser, LServer},
|
||||||
|
timestamp = jlib:binary_to_integer(
|
||||||
|
TimeStamp),
|
||||||
|
status = State}
|
||||||
|
end}].
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
Loading…
Reference in New Issue
Block a user