mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-22 17:28:25 +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("mod_privacy.hrl").
|
||||
-include("mod_last.hrl").
|
||||
|
||||
-record(last_activity, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
timestamp = 0 :: non_neg_integer(),
|
||||
status = <<"">> :: binary()}).
|
||||
-callback init(binary(), gen_mod:opts()) -> any().
|
||||
-callback import(binary(), #last_activity{}) -> ok | pass.
|
||||
-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) ->
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||
one_queue),
|
||||
case gen_mod:db_type(Host, Opts) of
|
||||
mnesia ->
|
||||
mnesia:create_table(last_activity,
|
||||
[{disc_copies, [node()]},
|
||||
{attributes,
|
||||
record_info(fields, last_activity)}]),
|
||||
update_table();
|
||||
_ -> ok
|
||||
end,
|
||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||
Mod:init(Host, Opts),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||
?NS_LAST, ?MODULE, process_local_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
||||
@ -163,38 +161,8 @@ process_sm_iq(From, To,
|
||||
%% @spec (LUser::string(), LServer::string()) ->
|
||||
%% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason}
|
||||
get_last(LUser, LServer) ->
|
||||
get_last(LUser, LServer,
|
||||
gen_mod:db_type(LServer, ?MODULE)).
|
||||
|
||||
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.
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
Mod:get_last(LUser, LServer).
|
||||
|
||||
get_last_iq(#iq{lang = Lang} = IQ, SubEl, LUser, LServer) ->
|
||||
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) ->
|
||||
LUser = jid:nodeprep(User),
|
||||
LServer = jid:nameprep(Server),
|
||||
DBType = gen_mod:db_type(LServer, ?MODULE),
|
||||
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).
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
Mod:store_last_info(LUser, LServer, TimeStamp, Status).
|
||||
|
||||
%% @spec (LUser::string(), LServer::string()) ->
|
||||
%% {ok, TimeStamp::integer(), Status::string()} | not_found
|
||||
@ -272,71 +219,20 @@ get_last_info(LUser, LServer) ->
|
||||
remove_user(User, Server) ->
|
||||
LUser = jid:nodeprep(User),
|
||||
LServer = jid:nameprep(Server),
|
||||
DBType = gen_mod:db_type(LServer, ?MODULE),
|
||||
remove_user(LUser, LServer, DBType).
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
Mod:remove_user(LUser, LServer).
|
||||
|
||||
remove_user(LUser, LServer, mnesia) ->
|
||||
US = {LUser, LServer},
|
||||
F = fun () -> mnesia:delete({last_activity, US}) end,
|
||||
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}].
|
||||
export(LServer) ->
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
Mod:export(LServer).
|
||||
|
||||
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}].
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
Mod:import(LServer).
|
||||
|
||||
import(_LServer, mnesia, #last_activity{} = LA) ->
|
||||
mnesia:dirty_write(LA);
|
||||
import(_LServer, riak, #last_activity{} = LA) ->
|
||||
ejabberd_riak:put(LA, last_activity_schema());
|
||||
import(_, _, _) ->
|
||||
pass.
|
||||
import(LServer, DBType, LA) ->
|
||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||
Mod:import(LServer, LA).
|
||||
|
||||
transform_options(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