2007-12-24 14:57:53 +01:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% File : odbc_queries.erl
|
|
|
|
%%% Author : Mickael Remond <mremond@process-one.net>
|
|
|
|
%%% Purpose : ODBC queries dependind on back-end
|
|
|
|
%%% Created : by Mickael Remond <mremond@process-one.net>
|
|
|
|
%%%
|
|
|
|
%%%
|
2016-01-13 12:29:14 +01:00
|
|
|
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
2007-12-24 14:57:53 +01:00
|
|
|
%%%
|
|
|
|
%%% 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.
|
2008-02-12 13:49:41 +01:00
|
|
|
%%%
|
2014-02-22 11:27:40 +01:00
|
|
|
%%% 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.
|
2007-12-24 14:57:53 +01:00
|
|
|
%%%
|
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
2006-09-03 17:15:46 +02:00
|
|
|
-module(odbc_queries).
|
2013-03-14 10:33:02 +01:00
|
|
|
|
2015-06-01 14:38:27 +02:00
|
|
|
-behaviour(ejabberd_config).
|
|
|
|
|
2007-12-24 14:57:53 +01:00
|
|
|
-author("mremond@process-one.net").
|
2006-09-03 17:15:46 +02:00
|
|
|
|
2015-06-01 14:38:27 +02:00
|
|
|
-export([get_db_type/0, update/5, update_t/4,
|
|
|
|
sql_transaction/2, get_last/2, set_last_t/4, del_last/2,
|
|
|
|
get_password/2, get_password_scram/2, set_password_t/3,
|
|
|
|
set_password_scram_t/6, add_user/3, add_user_scram/6,
|
|
|
|
del_user/2, del_user_return_password/3, list_users/1,
|
|
|
|
list_users/2, users_number/1, users_number/2,
|
|
|
|
add_spool_sql/2, add_spool/2, get_and_del_spool_msg_t/2,
|
|
|
|
del_spool_msg/2, get_roster/2, get_roster_jid_groups/2,
|
2013-03-14 10:33:02 +01:00
|
|
|
get_roster_groups/3, del_user_roster_t/2,
|
|
|
|
get_roster_by_jid/3, get_rostergroup_by_jid/3,
|
|
|
|
del_roster/3, del_roster_sql/2, update_roster/5,
|
|
|
|
update_roster_sql/4, roster_subscribe/4,
|
|
|
|
get_subscription/3, set_private_data/4,
|
2015-06-01 14:38:27 +02:00
|
|
|
set_private_data_sql/3, get_private_data/3,
|
|
|
|
get_private_data/2, del_user_private_storage/2,
|
|
|
|
get_default_privacy_list/2,
|
2013-03-14 10:33:02 +01:00
|
|
|
get_default_privacy_list_t/1, get_privacy_list_names/2,
|
|
|
|
get_privacy_list_names_t/1, get_privacy_list_id/3,
|
|
|
|
get_privacy_list_id_t/2, get_privacy_list_data/3,
|
2015-06-01 14:38:27 +02:00
|
|
|
get_privacy_list_data_by_id/2,
|
|
|
|
get_privacy_list_data_t/2,
|
2013-03-14 10:33:02 +01:00
|
|
|
get_privacy_list_data_by_id_t/1,
|
2008-12-26 10:38:54 +01:00
|
|
|
set_default_privacy_list/2,
|
2015-06-01 14:38:27 +02:00
|
|
|
unset_default_privacy_list/2, remove_privacy_list/2,
|
|
|
|
add_privacy_list/2, set_privacy_list/2,
|
|
|
|
del_privacy_lists/3, set_vcard/26, get_vcard/2,
|
|
|
|
escape/1, count_records_where/3, get_roster_version/2,
|
|
|
|
set_roster_version/2, opt_type/1]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
2011-04-14 23:11:37 +02:00
|
|
|
-include("ejabberd.hrl").
|
2013-04-08 11:12:54 +02:00
|
|
|
-include("logger.hrl").
|
2011-04-14 23:11:37 +02:00
|
|
|
|
2008-12-29 10:26:20 +01:00
|
|
|
%% Almost a copy of string:join/2.
|
|
|
|
%% We use this version because string:join/2 is relatively
|
|
|
|
%% new function (introduced in R12B-0).
|
2013-03-14 10:33:02 +01:00
|
|
|
join([], _Sep) -> [];
|
|
|
|
join([H | T], Sep) -> [H, [[Sep, X] || X <- T]].
|
2008-12-29 10:26:20 +01:00
|
|
|
|
2013-03-14 10:33:02 +01:00
|
|
|
get_db_type() -> generic.
|
2006-09-03 17:15:46 +02:00
|
|
|
|
2008-12-26 10:38:54 +01:00
|
|
|
%% Safe atomic update.
|
|
|
|
update_t(Table, Fields, Vals, Where) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
UPairs = lists:zipwith(fun (A, B) ->
|
|
|
|
<<A/binary, "='", B/binary, "'">>
|
|
|
|
end,
|
2008-12-26 10:38:54 +01:00
|
|
|
Fields, Vals),
|
2013-03-14 10:33:02 +01:00
|
|
|
case ejabberd_odbc:sql_query_t([<<"update ">>, Table,
|
|
|
|
<<" set ">>, join(UPairs, <<", ">>),
|
|
|
|
<<" where ">>, Where, <<";">>])
|
|
|
|
of
|
|
|
|
{updated, 1} -> ok;
|
|
|
|
_ ->
|
2014-08-08 11:26:16 +02:00
|
|
|
Res = ejabberd_odbc:sql_query_t([<<"insert into ">>, Table,
|
2013-03-14 10:33:02 +01:00
|
|
|
<<"(">>, join(Fields, <<", ">>),
|
|
|
|
<<") values ('">>, join(Vals, <<"', '">>),
|
2014-08-08 11:26:16 +02:00
|
|
|
<<"');">>]),
|
|
|
|
case Res of
|
|
|
|
{updated,1} -> ok;
|
|
|
|
_ -> Res
|
|
|
|
end
|
2008-12-26 10:38:54 +01:00
|
|
|
end.
|
|
|
|
|
2010-11-01 14:22:41 +01:00
|
|
|
update(LServer, Table, Fields, Vals, Where) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
UPairs = lists:zipwith(fun (A, B) ->
|
|
|
|
<<A/binary, "='", B/binary, "'">>
|
|
|
|
end,
|
2010-11-01 14:22:41 +01:00
|
|
|
Fields, Vals),
|
2013-03-14 10:33:02 +01:00
|
|
|
case ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"update ">>, Table, <<" set ">>,
|
|
|
|
join(UPairs, <<", ">>), <<" where ">>, Where,
|
|
|
|
<<";">>])
|
|
|
|
of
|
|
|
|
{updated, 1} -> ok;
|
|
|
|
_ ->
|
2014-08-08 11:26:16 +02:00
|
|
|
Res = ejabberd_odbc:sql_query(LServer,
|
2013-03-14 10:33:02 +01:00
|
|
|
[<<"insert into ">>, Table, <<"(">>,
|
|
|
|
join(Fields, <<", ">>), <<") values ('">>,
|
2014-08-08 11:26:16 +02:00
|
|
|
join(Vals, <<"', '">>), <<"');">>]),
|
|
|
|
case Res of
|
|
|
|
{updated,1} -> ok;
|
|
|
|
_ -> Res
|
|
|
|
end
|
2010-11-01 14:22:41 +01:00
|
|
|
end.
|
|
|
|
|
2006-11-20 14:20:47 +01:00
|
|
|
%% F can be either a fun or a list of queries
|
2008-12-26 10:38:54 +01:00
|
|
|
%% TODO: We should probably move the list of queries transaction
|
|
|
|
%% wrapper from the ejabberd_odbc module to this one (odbc_queries)
|
2006-09-03 17:15:46 +02:00
|
|
|
sql_transaction(LServer, F) ->
|
|
|
|
ejabberd_odbc:sql_transaction(LServer, F).
|
|
|
|
|
|
|
|
get_last(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select seconds, state from last where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
set_last_t(LServer, Username, Seconds, State) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
update(LServer, <<"last">>,
|
|
|
|
[<<"username">>, <<"seconds">>, <<"state">>],
|
2010-11-01 14:22:41 +01:00
|
|
|
[Username, Seconds, State],
|
2013-03-14 10:33:02 +01:00
|
|
|
[<<"username='">>, Username, <<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
del_last(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from last where username='">>, Username,
|
|
|
|
<<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_password(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select password from users where username='">>,
|
|
|
|
Username, <<"';">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
2015-02-17 21:26:31 +01:00
|
|
|
get_password_scram(LServer, Username) ->
|
|
|
|
ejabberd_odbc:sql_query(
|
|
|
|
LServer,
|
|
|
|
[<<"select password, serverkey, salt, iterationcount from users where "
|
|
|
|
"username='">>, Username, <<"';">>]).
|
|
|
|
|
2006-09-03 17:15:46 +02:00
|
|
|
set_password_t(LServer, Username, Pass) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_transaction(LServer,
|
|
|
|
fun () ->
|
|
|
|
update_t(<<"users">>,
|
|
|
|
[<<"username">>,
|
|
|
|
<<"password">>],
|
|
|
|
[Username, Pass],
|
|
|
|
[<<"username='">>, Username,
|
|
|
|
<<"'">>])
|
|
|
|
end).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
2015-02-17 21:26:31 +01:00
|
|
|
set_password_scram_t(LServer, Username,
|
|
|
|
StoredKey, ServerKey, Salt, IterationCount) ->
|
|
|
|
ejabberd_odbc:sql_transaction(LServer,
|
|
|
|
fun () ->
|
|
|
|
update_t(<<"users">>,
|
|
|
|
[<<"username">>,
|
|
|
|
<<"password">>,
|
|
|
|
<<"serverkey">>,
|
|
|
|
<<"salt">>,
|
|
|
|
<<"iterationcount">>],
|
|
|
|
[Username, StoredKey,
|
|
|
|
ServerKey, Salt,
|
|
|
|
IterationCount],
|
|
|
|
[<<"username='">>, Username,
|
|
|
|
<<"'">>])
|
|
|
|
end).
|
|
|
|
|
2006-09-03 17:15:46 +02:00
|
|
|
add_user(LServer, Username, Pass) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"insert into users(username, password) "
|
|
|
|
"values ('">>,
|
|
|
|
Username, <<"', '">>, Pass, <<"');">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
2015-02-17 21:26:31 +01:00
|
|
|
add_user_scram(LServer, Username,
|
|
|
|
StoredKey, ServerKey, Salt, IterationCount) ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"insert into users(username, password, serverkey, salt, iterationcount) "
|
|
|
|
"values ('">>,
|
|
|
|
Username, <<"', '">>, StoredKey, <<"', '">>,
|
|
|
|
ServerKey, <<"', '">>,
|
|
|
|
Salt, <<"', '">>,
|
|
|
|
IterationCount, <<"');">>]).
|
|
|
|
|
2006-09-03 17:15:46 +02:00
|
|
|
del_user(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from users where username='">>, Username,
|
|
|
|
<<"';">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
del_user_return_password(_LServer, Username, Pass) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
P =
|
|
|
|
ejabberd_odbc:sql_query_t([<<"select password from users where username='">>,
|
|
|
|
Username, <<"';">>]),
|
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from users where username='">>,
|
|
|
|
Username, <<"' and password='">>, Pass,
|
|
|
|
<<"';">>]),
|
2008-05-31 19:09:13 +02:00
|
|
|
P.
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
list_users(LServer) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select username from users">>]).
|
|
|
|
|
|
|
|
list_users(LServer, [{from, Start}, {to, End}])
|
|
|
|
when is_integer(Start) and is_integer(End) ->
|
|
|
|
list_users(LServer,
|
|
|
|
[{limit, End - Start + 1}, {offset, Start - 1}]);
|
|
|
|
list_users(LServer,
|
|
|
|
[{prefix, Prefix}, {from, Start}, {to, End}])
|
|
|
|
when is_binary(Prefix) and is_integer(Start) and
|
|
|
|
is_integer(End) ->
|
|
|
|
list_users(LServer,
|
|
|
|
[{prefix, Prefix}, {limit, End - Start + 1},
|
|
|
|
{offset, Start - 1}]);
|
|
|
|
list_users(LServer, [{limit, Limit}, {offset, Offset}])
|
|
|
|
when is_integer(Limit) and is_integer(Offset) ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[list_to_binary(
|
|
|
|
io_lib:format(
|
|
|
|
"select username from users " ++
|
|
|
|
"order by username " ++
|
|
|
|
"limit ~w offset ~w",
|
|
|
|
[Limit, Offset]))]);
|
|
|
|
list_users(LServer,
|
|
|
|
[{prefix, Prefix}, {limit, Limit}, {offset, Offset}])
|
|
|
|
when is_binary(Prefix) and is_integer(Limit) and
|
|
|
|
is_integer(Offset) ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[list_to_binary(
|
|
|
|
io_lib:format(
|
|
|
|
"select username from users " ++
|
|
|
|
"where username like '~s%' " ++
|
|
|
|
"order by username " ++
|
|
|
|
"limit ~w offset ~w ",
|
|
|
|
[Prefix, Limit, Offset]))]).
|
2007-11-03 18:35:23 +01:00
|
|
|
|
2007-05-12 20:09:38 +02:00
|
|
|
users_number(LServer) ->
|
2013-08-12 14:25:05 +02:00
|
|
|
Type = ejabberd_config:get_option({odbc_type, LServer},
|
|
|
|
fun(pgsql) -> pgsql;
|
|
|
|
(mysql) -> mysql;
|
2015-03-16 19:53:19 +01:00
|
|
|
(sqlite) -> sqlite;
|
2013-08-12 14:25:05 +02:00
|
|
|
(odbc) -> odbc
|
|
|
|
end, odbc),
|
|
|
|
case Type of
|
2013-03-14 10:33:02 +01:00
|
|
|
pgsql ->
|
|
|
|
case
|
2013-08-12 14:25:05 +02:00
|
|
|
ejabberd_config:get_option(
|
2013-03-14 10:33:02 +01:00
|
|
|
{pgsql_users_number_estimate, LServer},
|
|
|
|
fun(V) when is_boolean(V) -> V end,
|
|
|
|
false)
|
|
|
|
of
|
|
|
|
true ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select reltuples from pg_class where "
|
|
|
|
"oid = 'users'::regclass::oid">>]);
|
|
|
|
_ ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select count(*) from users">>])
|
|
|
|
end;
|
|
|
|
_ ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select count(*) from users">>])
|
2007-05-12 20:09:38 +02:00
|
|
|
end.
|
|
|
|
|
2013-03-14 10:33:02 +01:00
|
|
|
users_number(LServer, [{prefix, Prefix}])
|
|
|
|
when is_binary(Prefix) ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[list_to_binary(
|
|
|
|
io_lib:fwrite(
|
|
|
|
"select count(*) from users " ++
|
|
|
|
%% Warning: Escape prefix at higher level to prevent SQL
|
|
|
|
%% injection.
|
|
|
|
"where username like '~s%'",
|
|
|
|
[Prefix]))]);
|
2007-11-03 18:35:23 +01:00
|
|
|
users_number(LServer, []) ->
|
|
|
|
users_number(LServer).
|
|
|
|
|
|
|
|
|
2006-09-03 17:15:46 +02:00
|
|
|
add_spool_sql(Username, XML) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
[<<"insert into spool(username, xml) values ('">>,
|
|
|
|
Username, <<"', '">>, XML, <<"');">>].
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
add_spool(LServer, Queries) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_transaction(LServer, Queries).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_and_del_spool_msg_t(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
F = fun () ->
|
|
|
|
Result =
|
|
|
|
ejabberd_odbc:sql_query_t([<<"select username, xml from spool where "
|
|
|
|
"username='">>,
|
|
|
|
Username,
|
|
|
|
<<"' order by seq;">>]),
|
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from spool where username='">>,
|
|
|
|
Username, <<"';">>]),
|
2006-09-03 17:15:46 +02:00
|
|
|
Result
|
|
|
|
end,
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_transaction(LServer, F).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
del_spool_msg(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from spool where username='">>, Username,
|
|
|
|
<<"';">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_roster(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select username, jid, nick, subscription, "
|
|
|
|
"ask, askmessage, server, subscribe, "
|
|
|
|
"type from rosterusers where username='">>,
|
|
|
|
Username, <<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_roster_jid_groups(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select jid, grp from rostergroups where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_roster_groups(_LServer, Username, SJID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"select grp from rostergroups where username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"';">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
del_user_roster_t(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_transaction(LServer,
|
|
|
|
fun () ->
|
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from rosterusers where "
|
|
|
|
"username='">>,
|
|
|
|
Username,
|
|
|
|
<<"';">>]),
|
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from rostergroups where "
|
|
|
|
"username='">>,
|
|
|
|
Username,
|
|
|
|
<<"';">>])
|
|
|
|
end).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_roster_by_jid(_LServer, Username, SJID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"select username, jid, nick, subscription, "
|
|
|
|
"ask, askmessage, server, subscribe, "
|
|
|
|
"type from rosterusers where username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"';">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_rostergroup_by_jid(LServer, Username, SJID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select grp from rostergroups where username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
del_roster(_LServer, Username, SJID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from rosterusers where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID,
|
|
|
|
<<"';">>]),
|
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from rostergroups where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID,
|
|
|
|
<<"';">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
del_roster_sql(Username, SJID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
[[<<"delete from rosterusers where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"';">>],
|
|
|
|
[<<"delete from rostergroups where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"';">>]].
|
|
|
|
|
|
|
|
update_roster(_LServer, Username, SJID, ItemVals,
|
|
|
|
ItemGroups) ->
|
|
|
|
update_t(<<"rosterusers">>,
|
|
|
|
[<<"username">>, <<"jid">>, <<"nick">>,
|
|
|
|
<<"subscription">>, <<"ask">>, <<"askmessage">>,
|
|
|
|
<<"server">>, <<"subscribe">>, <<"type">>],
|
2008-12-26 10:38:54 +01:00
|
|
|
ItemVals,
|
2013-03-14 10:33:02 +01:00
|
|
|
[<<"username='">>, Username, <<"' and jid='">>, SJID,
|
|
|
|
<<"'">>]),
|
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from rostergroups where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID,
|
|
|
|
<<"';">>]),
|
|
|
|
lists:foreach(fun (ItemGroup) ->
|
|
|
|
ejabberd_odbc:sql_query_t([<<"insert into rostergroups( "
|
|
|
|
" username, jid, grp) values ('">>,
|
|
|
|
join(ItemGroup,
|
|
|
|
<<"', '">>),
|
|
|
|
<<"');">>])
|
2006-09-03 17:15:46 +02:00
|
|
|
end,
|
|
|
|
ItemGroups).
|
|
|
|
|
2013-03-14 10:33:02 +01:00
|
|
|
update_roster_sql(Username, SJID, ItemVals,
|
|
|
|
ItemGroups) ->
|
|
|
|
[[<<"delete from rosterusers where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"';">>],
|
|
|
|
[<<"insert into rosterusers( "
|
|
|
|
" username, jid, nick, "
|
|
|
|
" subscription, ask, askmessage, "
|
|
|
|
" server, subscribe, type) "
|
|
|
|
"values ('">>,
|
|
|
|
join(ItemVals, <<"', '">>), <<"');">>],
|
|
|
|
[<<"delete from rostergroups where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"';">>]]
|
|
|
|
++
|
|
|
|
[[<<"insert into rostergroups( "
|
|
|
|
" username, jid, grp) values ('">>,
|
|
|
|
join(ItemGroup, <<"', '">>), <<"');">>]
|
|
|
|
|| ItemGroup <- ItemGroups].
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
roster_subscribe(_LServer, Username, SJID, ItemVals) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
update_t(<<"rosterusers">>,
|
|
|
|
[<<"username">>, <<"jid">>, <<"nick">>,
|
|
|
|
<<"subscription">>, <<"ask">>, <<"askmessage">>,
|
|
|
|
<<"server">>, <<"subscribe">>, <<"type">>],
|
2008-12-26 10:38:54 +01:00
|
|
|
ItemVals,
|
2013-03-14 10:33:02 +01:00
|
|
|
[<<"username='">>, Username, <<"' and jid='">>, SJID,
|
|
|
|
<<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
|
|
|
get_subscription(LServer, Username, SJID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select subscription from rosterusers "
|
|
|
|
"where username='">>,
|
|
|
|
Username, <<"' and jid='">>, SJID, <<"'">>]).
|
2006-09-03 17:15:46 +02:00
|
|
|
|
2006-11-05 16:51:26 +01:00
|
|
|
set_private_data(_LServer, Username, LXMLNS, SData) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
update_t(<<"private_storage">>,
|
|
|
|
[<<"username">>, <<"namespace">>, <<"data">>],
|
|
|
|
[Username, LXMLNS, SData],
|
|
|
|
[<<"username='">>, Username, <<"' and namespace='">>,
|
|
|
|
LXMLNS, <<"'">>]).
|
2008-02-12 13:49:41 +01:00
|
|
|
|
2006-11-20 14:20:47 +01:00
|
|
|
set_private_data_sql(Username, LXMLNS, SData) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
[[<<"delete from private_storage where username='">>,
|
|
|
|
Username, <<"' and namespace='">>, LXMLNS, <<"';">>],
|
|
|
|
[<<"insert into private_storage(username, "
|
|
|
|
"namespace, data) values ('">>,
|
|
|
|
Username, <<"', '">>, LXMLNS, <<"', '">>, SData,
|
|
|
|
<<"');">>]].
|
2008-02-12 13:49:41 +01:00
|
|
|
|
2006-11-05 16:51:26 +01:00
|
|
|
get_private_data(LServer, Username, LXMLNS) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select data from private_storage where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"' and namespace='">>, LXMLNS,
|
|
|
|
<<"';">>]).
|
|
|
|
|
|
|
|
get_private_data(LServer, Username) ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select namespace, data from private_storage "
|
|
|
|
"where username='">>, Username, <<"';">>]).
|
2006-11-05 16:51:26 +01:00
|
|
|
|
|
|
|
del_user_private_storage(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from private_storage where username='">>,
|
|
|
|
Username, <<"';">>]).
|
|
|
|
|
|
|
|
set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail, SFN,
|
|
|
|
SFamily, SGiven, SLBDay, SLCTRY, SLEMail, SLFN,
|
|
|
|
SLFamily, SLGiven, SLLocality, SLMiddle, SLNickname,
|
|
|
|
SLOrgName, SLOrgUnit, SLocality, SMiddle, SNickname,
|
|
|
|
SOrgName, SOrgUnit, SVCARD, Username) ->
|
|
|
|
ejabberd_odbc:sql_transaction(LServer,
|
|
|
|
fun () ->
|
|
|
|
update_t(<<"vcard">>,
|
|
|
|
[<<"username">>,
|
|
|
|
<<"vcard">>],
|
|
|
|
[LUsername, SVCARD],
|
|
|
|
[<<"username='">>, LUsername,
|
|
|
|
<<"'">>]),
|
|
|
|
update_t(<<"vcard_search">>,
|
|
|
|
[<<"username">>,
|
|
|
|
<<"lusername">>, <<"fn">>,
|
|
|
|
<<"lfn">>, <<"family">>,
|
|
|
|
<<"lfamily">>, <<"given">>,
|
|
|
|
<<"lgiven">>, <<"middle">>,
|
|
|
|
<<"lmiddle">>,
|
|
|
|
<<"nickname">>,
|
|
|
|
<<"lnickname">>, <<"bday">>,
|
|
|
|
<<"lbday">>, <<"ctry">>,
|
|
|
|
<<"lctry">>, <<"locality">>,
|
|
|
|
<<"llocality">>,
|
|
|
|
<<"email">>, <<"lemail">>,
|
|
|
|
<<"orgname">>,
|
|
|
|
<<"lorgname">>,
|
|
|
|
<<"orgunit">>,
|
|
|
|
<<"lorgunit">>],
|
|
|
|
[Username, LUsername, SFN,
|
|
|
|
SLFN, SFamily, SLFamily,
|
|
|
|
SGiven, SLGiven, SMiddle,
|
|
|
|
SLMiddle, SNickname,
|
|
|
|
SLNickname, SBDay, SLBDay,
|
|
|
|
SCTRY, SLCTRY, SLocality,
|
|
|
|
SLLocality, SEMail, SLEMail,
|
|
|
|
SOrgName, SLOrgName,
|
|
|
|
SOrgUnit, SLOrgUnit],
|
|
|
|
[<<"lusername='">>,
|
|
|
|
LUsername, <<"'">>])
|
|
|
|
end).
|
2008-10-03 17:29:48 +02:00
|
|
|
|
|
|
|
get_vcard(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select vcard from vcard where username='">>,
|
|
|
|
Username, <<"';">>]).
|
2008-10-03 17:29:48 +02:00
|
|
|
|
2008-12-26 10:38:54 +01:00
|
|
|
get_default_privacy_list(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select name from privacy_default_list "
|
|
|
|
"where username='">>,
|
|
|
|
Username, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
get_default_privacy_list_t(Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"select name from privacy_default_list "
|
|
|
|
"where username='">>,
|
|
|
|
Username, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
get_privacy_list_names(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select name from privacy_list where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
get_privacy_list_names_t(Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"select name from privacy_list where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
get_privacy_list_id(LServer, Username, SName) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select id from privacy_list where username='">>,
|
|
|
|
Username, <<"' and name='">>, SName, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
get_privacy_list_id_t(Username, SName) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"select id from privacy_list where username='">>,
|
|
|
|
Username, <<"' and name='">>, SName, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
get_privacy_list_data(LServer, Username, SName) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select t, value, action, ord, match_all, "
|
|
|
|
"match_iq, match_message, match_presence_in, "
|
|
|
|
"match_presence_out from privacy_list_data "
|
|
|
|
"where id = (select id from privacy_list "
|
|
|
|
"where username='">>,
|
|
|
|
Username, <<"' and name='">>, SName,
|
|
|
|
<<"') order by ord;">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
2013-07-21 12:24:36 +02:00
|
|
|
get_privacy_list_data_t(Username, SName) ->
|
|
|
|
ejabberd_odbc:sql_query_t([<<"select t, value, action, ord, match_all, "
|
|
|
|
"match_iq, match_message, match_presence_in, "
|
|
|
|
"match_presence_out from privacy_list_data "
|
|
|
|
"where id = (select id from privacy_list "
|
|
|
|
"where username='">>,
|
|
|
|
Username, <<"' and name='">>, SName,
|
|
|
|
<<"') order by ord;">>]).
|
|
|
|
|
2008-12-26 10:38:54 +01:00
|
|
|
get_privacy_list_data_by_id(LServer, ID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select t, value, action, ord, match_all, "
|
|
|
|
"match_iq, match_message, match_presence_in, "
|
|
|
|
"match_presence_out from privacy_list_data "
|
|
|
|
"where id='">>,
|
|
|
|
ID, <<"' order by ord;">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
2012-04-12 06:22:56 +02:00
|
|
|
get_privacy_list_data_by_id_t(ID) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"select t, value, action, ord, match_all, "
|
|
|
|
"match_iq, match_message, match_presence_in, "
|
|
|
|
"match_presence_out from privacy_list_data "
|
|
|
|
"where id='">>,
|
|
|
|
ID, <<"' order by ord;">>]).
|
2012-04-12 06:22:56 +02:00
|
|
|
|
2008-12-26 10:38:54 +01:00
|
|
|
set_default_privacy_list(Username, SName) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
update_t(<<"privacy_default_list">>,
|
|
|
|
[<<"username">>, <<"name">>], [Username, SName],
|
|
|
|
[<<"username='">>, Username, <<"'">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
unset_default_privacy_list(LServer, Username) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from privacy_default_list "
|
|
|
|
" where username='">>,
|
|
|
|
Username, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
remove_privacy_list(Username, SName) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from privacy_list where username='">>,
|
|
|
|
Username, <<"' and name='">>, SName, <<"';">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
add_privacy_list(Username, SName) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"insert into privacy_list(username, name) "
|
|
|
|
"values ('">>,
|
|
|
|
Username, <<"', '">>, SName, <<"');">>]).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
set_privacy_list(ID, RItems) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query_t([<<"delete from privacy_list_data where "
|
|
|
|
"id='">>,
|
|
|
|
ID, <<"';">>]),
|
|
|
|
lists:foreach(fun (Items) ->
|
|
|
|
ejabberd_odbc:sql_query_t([<<"insert into privacy_list_data(id, t, "
|
|
|
|
"value, action, ord, match_all, match_iq, "
|
|
|
|
"match_message, match_presence_in, match_prese"
|
|
|
|
"nce_out ) values ('">>,
|
|
|
|
ID, <<"', '">>,
|
|
|
|
join(Items, <<"', '">>),
|
|
|
|
<<"');">>])
|
|
|
|
end,
|
|
|
|
RItems).
|
2008-12-26 10:38:54 +01:00
|
|
|
|
|
|
|
del_privacy_lists(LServer, Server, Username) ->
|
2006-09-03 17:15:46 +02:00
|
|
|
%% Characters to escape
|
2007-08-28 16:36:39 +02:00
|
|
|
%% Count number of records in a table given a where clause
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from privacy_list where username='">>,
|
|
|
|
Username, <<"';">>]),
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from privacy_list_data where "
|
|
|
|
"value='">>,
|
|
|
|
<<Username/binary, "@", Server/binary>>,
|
|
|
|
<<"';">>]),
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"delete from privacy_default_list where "
|
|
|
|
"username='">>,
|
|
|
|
Username, <<"';">>]).
|
|
|
|
|
|
|
|
escape($\000) -> <<"\\0">>;
|
|
|
|
escape($\n) -> <<"\\n">>;
|
|
|
|
escape($\t) -> <<"\\t">>;
|
|
|
|
escape($\b) -> <<"\\b">>;
|
|
|
|
escape($\r) -> <<"\\r">>;
|
|
|
|
escape($') -> <<"''">>;
|
|
|
|
escape($") -> <<"\\\"">>;
|
|
|
|
escape($\\) -> <<"\\\\">>;
|
|
|
|
escape(C) -> <<C>>.
|
Support for roster versioning (EJAB-964)
Introduces two options for mod_roster and mod_roster_odbc:
- {versioning, true | false} Enable or disable roster versioning on ejabberd.
- {store_current_id, true | false} If true, the current roster version is stored on DB (internal or odbc). Otherwise it is calculated on the fly each time.
Performance:
Setting store_current_id to true should help in reducing the load for both ejabberd and the DB.
Details:
If store_current_id is false, the roster version is a hash of the entire roster. If store_current_id is true, the roster version is a hash, but of the current time
(this has to do with transactional semantics; we need to perform both the roster update and the version update on the same transaction, but we don't
have the entire roster when we are changing a single item on DB. Loading it there requires significant changes to be introduced, so I opted for this simpler approach).
In either case, there is no difference for the clients, the roster version ID is opaque.
IMPORTANT:
mod_shared_roster is not compatible with the option 'store_current_id'. Shared roster and roster versioning can be both enabled, but store_current_id MUST be set to false.
SVN Revision: 2428
2009-08-06 17:45:13 +02:00
|
|
|
|
2013-03-14 10:33:02 +01:00
|
|
|
count_records_where(LServer, Table, WhereClause) ->
|
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select count(*) from ">>, Table, <<" ">>,
|
|
|
|
WhereClause, <<";">>]).
|
Support for roster versioning (EJAB-964)
Introduces two options for mod_roster and mod_roster_odbc:
- {versioning, true | false} Enable or disable roster versioning on ejabberd.
- {store_current_id, true | false} If true, the current roster version is stored on DB (internal or odbc). Otherwise it is calculated on the fly each time.
Performance:
Setting store_current_id to true should help in reducing the load for both ejabberd and the DB.
Details:
If store_current_id is false, the roster version is a hash of the entire roster. If store_current_id is true, the roster version is a hash, but of the current time
(this has to do with transactional semantics; we need to perform both the roster update and the version update on the same transaction, but we don't
have the entire roster when we are changing a single item on DB. Loading it there requires significant changes to be introduced, so I opted for this simpler approach).
In either case, there is no difference for the clients, the roster version ID is opaque.
IMPORTANT:
mod_shared_roster is not compatible with the option 'store_current_id'. Shared roster and roster versioning can be both enabled, but store_current_id MUST be set to false.
SVN Revision: 2428
2009-08-06 17:45:13 +02:00
|
|
|
|
|
|
|
get_roster_version(LServer, LUser) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
ejabberd_odbc:sql_query(LServer,
|
|
|
|
[<<"select version from roster_version where "
|
|
|
|
"username = '">>,
|
|
|
|
LUser, <<"'">>]).
|
|
|
|
|
Support for roster versioning (EJAB-964)
Introduces two options for mod_roster and mod_roster_odbc:
- {versioning, true | false} Enable or disable roster versioning on ejabberd.
- {store_current_id, true | false} If true, the current roster version is stored on DB (internal or odbc). Otherwise it is calculated on the fly each time.
Performance:
Setting store_current_id to true should help in reducing the load for both ejabberd and the DB.
Details:
If store_current_id is false, the roster version is a hash of the entire roster. If store_current_id is true, the roster version is a hash, but of the current time
(this has to do with transactional semantics; we need to perform both the roster update and the version update on the same transaction, but we don't
have the entire roster when we are changing a single item on DB. Loading it there requires significant changes to be introduced, so I opted for this simpler approach).
In either case, there is no difference for the clients, the roster version ID is opaque.
IMPORTANT:
mod_shared_roster is not compatible with the option 'store_current_id'. Shared roster and roster versioning can be both enabled, but store_current_id MUST be set to false.
SVN Revision: 2428
2009-08-06 17:45:13 +02:00
|
|
|
set_roster_version(LUser, Version) ->
|
2013-03-14 10:33:02 +01:00
|
|
|
update_t(<<"roster_version">>,
|
|
|
|
[<<"username">>, <<"version">>], [LUser, Version],
|
|
|
|
[<<"username = '">>, LUser, <<"'">>]).
|
|
|
|
|
2015-06-01 14:38:27 +02:00
|
|
|
opt_type(odbc_type) ->
|
|
|
|
fun (pgsql) -> pgsql;
|
|
|
|
(mysql) -> mysql;
|
|
|
|
(sqlite) -> sqlite;
|
2015-09-13 16:41:54 +02:00
|
|
|
(mssql) -> mssql;
|
2015-06-01 14:38:27 +02:00
|
|
|
(odbc) -> odbc
|
|
|
|
end;
|
|
|
|
opt_type(pgsql_users_number_estimate) ->
|
|
|
|
fun (V) when is_boolean(V) -> V end;
|
|
|
|
opt_type(_) -> [odbc_type, pgsql_users_number_estimate].
|