1 |
|
%%%---------------------------------------------------------------------- |
2 |
|
%%% File : mod_private_rdbms.erl |
3 |
|
%%% Author : Alexey Shchepin <alexey@process-one.net> |
4 |
|
%%% Purpose : Private storage support |
5 |
|
%%% Created : 5 Oct 2006 by Alexey Shchepin <alexey@process-one.net> |
6 |
|
%%% |
7 |
|
%%% |
8 |
|
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne |
9 |
|
%%% |
10 |
|
%%% This program is free software; you can redistribute it and/or |
11 |
|
%%% modify it under the terms of the GNU General Public License as |
12 |
|
%%% published by the Free Software Foundation; either version 2 of the |
13 |
|
%%% License, or (at your option) any later version. |
14 |
|
%%% |
15 |
|
%%% This program is distributed in the hope that it will be useful, |
16 |
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 |
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 |
|
%%% General Public License for more details. |
19 |
|
%%% |
20 |
|
%%% You should have received a copy of the GNU General Public License |
21 |
|
%%% along with this program; if not, write to the Free Software |
22 |
|
%%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 |
|
%%% |
24 |
|
%%%---------------------------------------------------------------------- |
25 |
|
|
26 |
|
%%% NS is namespace or key. |
27 |
|
%%% XML is #xmlel{} or value. |
28 |
|
-module(mod_private_rdbms). |
29 |
|
-author('alexey@process-one.net'). |
30 |
|
-author('arcusfelis@gmail.com'). |
31 |
|
-behaviour(mod_private_backend). |
32 |
|
|
33 |
|
-export([init/2, |
34 |
|
multi_set_data/4, |
35 |
|
multi_get_data/4, |
36 |
|
get_all_nss/3, |
37 |
|
remove_user/3, |
38 |
|
remove_domain/2]). |
39 |
|
|
40 |
|
init(HostType, _Opts) -> |
41 |
8 |
mongoose_rdbms:prepare(private_select_data, private_storage, |
42 |
|
[server, username, namespace], |
43 |
|
<<"SELECT data FROM private_storage WHERE server=? AND username=? AND namespace=?">>), |
44 |
8 |
mongoose_rdbms:prepare(private_select_namespaces, private_storage, |
45 |
|
[server, username], |
46 |
|
<<"SELECT namespace FROM private_storage WHERE server=? AND username=?">>), |
47 |
8 |
mongoose_rdbms:prepare(private_remove_user, private_storage, |
48 |
|
[server, username], |
49 |
|
<<"DELETE FROM private_storage WHERE server=? AND username=?">>), |
50 |
8 |
mongoose_rdbms:prepare(private_remove_domain, private_storage, |
51 |
|
[server], |
52 |
|
<<"DELETE FROM private_storage WHERE server=?">>), |
53 |
8 |
rdbms_queries:prepare_upsert(HostType, private_upsert, private_storage, |
54 |
|
[<<"server">>, <<"username">>, <<"namespace">>, <<"data">>], |
55 |
|
[<<"data">>], |
56 |
|
[<<"server">>, <<"username">>, <<"namespace">>]), |
57 |
8 |
ok. |
58 |
|
|
59 |
|
multi_set_data(HostType, LUser, LServer, NS2XML) -> |
60 |
24 |
NS2BinXML = make_xml_binary(NS2XML), |
61 |
24 |
F = fun() -> multi_set_data_t(HostType, LUser, LServer, NS2BinXML) end, |
62 |
24 |
case rdbms_queries:sql_transaction(HostType, F) of |
63 |
24 |
{atomic, ok} -> ok; |
64 |
:-( |
{aborted, Reason} -> {aborted, Reason}; |
65 |
:-( |
{error, Reason} -> {error, Reason} |
66 |
|
end. |
67 |
|
|
68 |
|
multi_set_data_t(HostType, LUser, LServer, NS2XML) -> |
69 |
24 |
[upsert_data_t(HostType, LUser, LServer, NS, XML) || {NS, XML} <- NS2XML], |
70 |
24 |
ok. |
71 |
|
|
72 |
|
upsert_data_t(HostType, LUser, LServer, NS, XML) -> |
73 |
24 |
InsertParams = [LServer, LUser, NS, XML], |
74 |
24 |
UpdateParams = [XML], |
75 |
24 |
UniqueKeyValues = [LServer, LUser, NS], |
76 |
24 |
rdbms_queries:execute_upsert(HostType, private_upsert, |
77 |
|
InsertParams, UpdateParams, UniqueKeyValues). |
78 |
|
|
79 |
|
make_xml_binary(NS2XML) -> |
80 |
24 |
[{NS, exml:to_binary(XML)} || {NS, XML} <- NS2XML]. |
81 |
|
|
82 |
|
multi_get_data(HostType, LUser, LServer, NS2Def) -> |
83 |
24 |
[get_data(HostType, LUser, LServer, NS, Default) || {NS, Default} <- NS2Def]. |
84 |
|
|
85 |
|
%% @doc Return stored value or default. |
86 |
|
get_data(HostType, LUser, LServer, NS, Default) -> |
87 |
24 |
Res = mongoose_rdbms:execute(HostType, private_select_data, [LServer, LUser, NS]), |
88 |
24 |
case Res of |
89 |
|
{selected, [{BinData}]} -> |
90 |
22 |
{ok, Elem} = exml:parse(BinData), |
91 |
22 |
Elem; |
92 |
|
_ -> |
93 |
2 |
Default |
94 |
|
end. |
95 |
|
|
96 |
|
get_all_nss(HostType, LUser, LServer) -> |
97 |
15 |
{selected, Res} = mongoose_rdbms:execute(HostType, private_select_namespaces, [LServer, LUser]), |
98 |
15 |
lists:map(fun({R}) -> R end, Res). |
99 |
|
|
100 |
|
remove_user(HostType, LUser, LServer) -> |
101 |
29 |
mongoose_rdbms:execute(HostType, private_remove_user, [LServer, LUser]). |
102 |
|
|
103 |
|
remove_domain(HostType, LServer) -> |
104 |
1 |
mongoose_rdbms:execute(HostType, private_remove_domain, [LServer]). |