summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJerome Sautret <jerome.sautret@process-one.net>2015-07-07 13:23:30 +0200
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2015-07-10 13:56:33 +0300
commit1db65e3614dc2f1c12d549a4f882496c315bb613 (patch)
tree4bed912c38b635360b4450ede8601767509b3032 /src
parentDuring halt only shutdown MUC rooms on local node (diff)
Fix mod_mam compatibility with RSM (only with odbc backend).
Diffstat (limited to 'src')
-rw-r--r--src/mod_mam.erl94
1 files changed, 57 insertions, 37 deletions
diff --git a/src/mod_mam.erl b/src/mod_mam.erl
index 6739feb0..bd1a5a7a 100644
--- a/src/mod_mam.erl
+++ b/src/mod_mam.erl
@@ -550,6 +550,12 @@ select(#jid{luser = LUser, lserver = LServer} = JidRequestor,
Start, End, With, RSM, {odbc, Host}) ->
{Query, CountQuery} = make_sql_query(LUser, LServer,
Start, End, With, RSM),
+ % XXX TODO from XEP-0313:
+ % To conserve resources, a server MAY place a reasonable limit on
+ % how many stanzas may be pushed to a client in one request. If a
+ % query returns a number of stanzas greater than this limit and
+ % the client did not specify a limit using RSM then the server
+ % should return a policy-violation error to the client.
case {ejabberd_odbc:sql_query(Host, Query),
ejabberd_odbc:sql_query(Host, CountQuery)} of
{{selected, _, Res}, {selected, _, [[Count]]}} ->
@@ -718,7 +724,7 @@ make_sql_query(LUser, _LServer, Start, End, With, RSM) ->
RSM#rsm_in.direction,
RSM#rsm_in.id};
none ->
- {none, none, none}
+ {none, none, <<>>}
end,
LimitClause = if is_integer(Max), Max >= 0 ->
[<<" limit ">>, jlib:integer_to_binary(Max)];
@@ -726,37 +732,35 @@ make_sql_query(LUser, _LServer, Start, End, With, RSM) ->
[]
end,
WithClause = case With of
- {text, <<>>} ->
- [];
- {text, Txt} ->
- [<<" and match (txt) against ('">>,
- ejabberd_odbc:escape(Txt), <<"')">>];
- {_, _, <<>>} ->
- [<<" and bare_peer='">>,
- ejabberd_odbc:escape(jlib:jid_to_string(With)),
- <<"'">>];
- {_, _, _} ->
- [<<" and peer='">>,
- ejabberd_odbc:escape(jlib:jid_to_string(With)),
- <<"'">>];
- none ->
- []
- end,
- DirectionClause = case catch jlib:binary_to_integer(ID) of
- I when is_integer(I), I >= 0 ->
- case Direction of
- before ->
- [<<" and timestamp < ">>, ID,
- <<" order by timestamp desc">>];
- aft ->
- [<<" and timestamp > ">>, ID,
- <<" order by timestamp asc">>];
- _ ->
- []
- end;
- _ ->
- []
- end,
+ {text, <<>>} ->
+ [];
+ {text, Txt} ->
+ [<<" and match (txt) against ('">>,
+ ejabberd_odbc:escape(Txt), <<"')">>];
+ {_, _, <<>>} ->
+ [<<" and bare_peer='">>,
+ ejabberd_odbc:escape(jlib:jid_to_string(With)),
+ <<"'">>];
+ {_, _, _} ->
+ [<<" and peer='">>,
+ ejabberd_odbc:escape(jlib:jid_to_string(With)),
+ <<"'">>];
+ none ->
+ []
+ end,
+ PageClause = case catch jlib:binary_to_integer(ID) of
+ I when is_integer(I), I >= 0 ->
+ case Direction of
+ before ->
+ [<<" AND timestamp < ">>, ID];
+ aft ->
+ [<<" AND timestamp > ">>, ID];
+ _ ->
+ []
+ end;
+ _ ->
+ []
+ end,
StartClause = case Start of
{_, _, _} ->
[<<" and timestamp >= ">>,
@@ -772,11 +776,27 @@ make_sql_query(LUser, _LServer, Start, End, With, RSM) ->
[]
end,
SUser = ejabberd_odbc:escape(LUser),
- {[<<"select timestamp, xml, peer from archive where username='">>,
- SUser, <<"'">>] ++ WithClause ++ StartClause ++ EndClause ++
- DirectionClause ++ LimitClause ++ [<<";">>],
- [<<"select count(*) from archive where username='">>,
- SUser, <<"'">>] ++ WithClause ++ StartClause ++ EndClause ++ [<<";">>]}.
+
+ Query = [<<"SELECT timestamp, xml, peer"
+ " FROM archive WHERE username='">>,
+ SUser, <<"'">>, WithClause, StartClause, EndClause,
+ PageClause],
+
+ QueryPage =
+ case Direction of
+ before ->
+ % ID can be empty because of
+ % XEP-0059: Result Set Management
+ % 2.5 Requesting the Last Page in a Result Set
+ [<<"(">>, Query, <<" ORDER BY timestamp DESC ">>,
+ LimitClause, <<") ORDER BY timestamp ASC;">>];
+ _ ->
+ [Query, <<" ORDER BY timestamp ASC ">>,
+ LimitClause, <<";">>]
+ end,
+ {QueryPage,
+ [<<"SELECT COUNT(*) FROM archive WHERE username='">>,
+ SUser, <<"'">>, WithClause, StartClause, EndClause, <<";">>]}.
now_to_usec({MSec, Sec, USec}) ->
(MSec*1000000 + Sec)*1000000 + USec.