26
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-28 17:38:54 +01:00

Correctly handle empty result with RSM

Fixes #2588
This commit is contained in:
Evgeniy Khramtsov 2018-09-02 00:37:07 +03:00
parent 88d0b71d58
commit 5c931d7004

View File

@ -738,39 +738,43 @@ get_items(Nidx, _From, undefined) ->
get_items(Nidx, _From, #rsm_set{max = Max, index = IncIndex, get_items(Nidx, _From, #rsm_set{max = Max, index = IncIndex,
'after' = After, before = Before}) -> 'after' = After, before = Before}) ->
RItems = lists:keysort(#pubsub_item.creation, case lists:keysort(#pubsub_item.creation,
mnesia:index_read(pubsub_item, Nidx, #pubsub_item.nodeidx)), mnesia:index_read(pubsub_item, Nidx, #pubsub_item.nodeidx)) of
Count = length(RItems), [] ->
Limit = case Max of {result, {[], #rsm_set{count = 0}}};
undefined -> ?MAXITEMS; RItems ->
_ -> Max Count = length(RItems),
end, Limit = case Max of
{Offset, ItemsPage} = undefined -> ?MAXITEMS;
case {IncIndex, Before, After} of _ -> Max
{I, undefined, undefined} -> end,
SubList = lists:nthtail(I, RItems), {Offset, ItemsPage} =
{I, lists:sublist(SubList, Limit)}; case {IncIndex, Before, After} of
{_, <<>>, undefined} -> {I, undefined, undefined} ->
%% 2.5 Requesting the Last Page in a Result Set SubList = lists:nthtail(I, RItems),
SubList = lists:reverse(RItems), {I, lists:sublist(SubList, Limit)};
{0, lists:sublist(SubList, Limit)}; {_, <<>>, undefined} ->
{_, Stamp, undefined} -> %% 2.5 Requesting the Last Page in a Result Set
BeforeNow = encode_stamp(Stamp), SubList = lists:reverse(RItems),
SubList = lists:dropwhile( {0, lists:sublist(SubList, Limit)};
fun(#pubsub_item{creation = {Now, _}}) -> {_, Stamp, undefined} ->
Now >= BeforeNow BeforeNow = encode_stamp(Stamp),
end, lists:reverse(RItems)), SubList = lists:dropwhile(
{0, lists:sublist(SubList, Limit)}; fun(#pubsub_item{creation = {Now, _}}) ->
{_, undefined, Stamp} -> Now >= BeforeNow
AfterNow = encode_stamp(Stamp), end, lists:reverse(RItems)),
SubList = lists:dropwhile( {0, lists:sublist(SubList, Limit)};
fun(#pubsub_item{creation = {Now, _}}) -> {_, undefined, Stamp} ->
Now =< AfterNow AfterNow = encode_stamp(Stamp),
end, RItems), SubList = lists:dropwhile(
{0, lists:sublist(SubList, Limit)} fun(#pubsub_item{creation = {Now, _}}) ->
end, Now =< AfterNow
Rsm = rsm_page(Count, IncIndex, Offset, ItemsPage), end, RItems),
{result, {ItemsPage, Rsm}}. {0, lists:sublist(SubList, Limit)}
end,
Rsm = rsm_page(Count, IncIndex, Offset, ItemsPage),
{result, {ItemsPage, Rsm}}
end.
get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM) -> get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM) ->
SubKey = jid:tolower(JID), SubKey = jid:tolower(JID),
@ -920,6 +924,8 @@ first_in_list(Pred, [H | T]) ->
_ -> first_in_list(Pred, T) _ -> first_in_list(Pred, T)
end. end.
rsm_page(Count, _, _, []) ->
#rsm_set{count = Count};
rsm_page(Count, Index, Offset, Items) -> rsm_page(Count, Index, Offset, Items) ->
FirstItem = hd(Items), FirstItem = hd(Items),
LastItem = lists:last(Items), LastItem = lists:last(Items),