diff options
Diffstat (limited to 'src/mod_private_mnesia.erl')
-rw-r--r-- | src/mod_private_mnesia.erl | 114 |
1 files changed, 75 insertions, 39 deletions
diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl index 7a852c4f8..bf0ce26e8 100644 --- a/src/mod_private_mnesia.erl +++ b/src/mod_private_mnesia.erl @@ -1,19 +1,37 @@ %%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net> -%%% @copyright (C) 2016, Evgeny Khramtsov -%%% @doc -%%% -%%% @end +%%% File : mod_private_mnesia.erl +%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net> %%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net> -%%%------------------------------------------------------------------- +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2019 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%---------------------------------------------------------------------- + -module(mod_private_mnesia). + -behaviour(mod_private). %% API --export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, - import/2]). +-export([init/2, set_data/3, get_data/3, get_all_data/2, del_data/2, + use_cache/1, import/3]). +-export([need_transform/1, transform/1]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_private.hrl"). -include("logger.hrl"). @@ -21,11 +39,17 @@ %%% API %%%=================================================================== init(_Host, _Opts) -> - mnesia:create_table(private_storage, - [{disc_only_copies, [node()]}, - {attributes, - record_info(fields, private_storage)}]), - update_table(). + ejabberd_mnesia:create(?MODULE, private_storage, + [{disc_only_copies, [node()]}, + {attributes, record_info(fields, private_storage)}]). + +use_cache(Host) -> + case mnesia:table_info(private_storage, storage_type) of + disc_only_copies -> + mod_private_opt:use_cache(Host); + _ -> + false + end. set_data(LUser, LServer, Data) -> F = fun () -> @@ -37,7 +61,7 @@ set_data(LUser, LServer, Data) -> xml = Xmlel}) end, Data) end, - mnesia:transaction(F). + transaction(F). get_data(LUser, LServer, XmlNS) -> case mnesia:dirty_read(private_storage, {LUser, LServer, XmlNS}) of @@ -48,13 +72,18 @@ get_data(LUser, LServer, XmlNS) -> end. get_all_data(LUser, LServer) -> - lists:flatten( - mnesia:dirty_select(private_storage, - [{#private_storage{usns = {LUser, LServer, '_'}, - xml = '$1'}, - [], ['$1']}])). + case lists:flatten( + mnesia:dirty_select(private_storage, + [{#private_storage{usns = {LUser, LServer, '_'}, + xml = '$1'}, + [], ['$1']}])) of + [] -> + error; + Res -> + {ok, Res} + end. -remove_user(LUser, LServer) -> +del_data(LUser, LServer) -> F = fun () -> Namespaces = mnesia:select(private_storage, [{#private_storage{usns = @@ -70,28 +99,35 @@ remove_user(LUser, LServer) -> end, Namespaces) end, - mnesia:transaction(F). + transaction(F). -import(_LServer, #private_storage{} = PS) -> +import(LServer, <<"private_storage">>, + [LUser, XMLNS, XML, _TimeStamp]) -> + El = #xmlel{} = fxml_stream:parse_element(XML), + PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El}, mnesia:dirty_write(PS). +need_transform({private_storage, {U, S, NS}, _}) + when is_list(U) orelse is_list(S) orelse is_list(NS) -> + ?INFO_MSG("Mnesia table 'private_storage' will be converted to binary", []), + true; +need_transform(_) -> + false. + +transform(#private_storage{usns = {U, S, NS}, xml = El} = R) -> + R#private_storage{usns = {iolist_to_binary(U), + iolist_to_binary(S), + iolist_to_binary(NS)}, + xml = fxml:to_xmlel(El)}. + %%%=================================================================== %%% Internal functions %%%=================================================================== -update_table() -> - Fields = record_info(fields, private_storage), - case mnesia:table_info(private_storage, attributes) of - Fields -> - ejabberd_config:convert_table_to_binary( - private_storage, Fields, set, - fun(#private_storage{usns = {U, _, _}}) -> U end, - fun(#private_storage{usns = {U, S, NS}, xml = El} = R) -> - R#private_storage{usns = {iolist_to_binary(U), - iolist_to_binary(S), - iolist_to_binary(NS)}, - xml = fxml:to_xmlel(El)} - end); - _ -> - ?INFO_MSG("Recreating private_storage table", []), - mnesia:transform_table(private_storage, ignore, Fields) +transaction(F) -> + case mnesia:transaction(F) of + {atomic, Res} -> + Res; + {aborted, Reason} -> + ?ERROR_MSG("Mnesia transaction failed: ~p", [Reason]), + {error, db_failure} end. |