From 51bf552c3f3b804af1b89218980ef1d48e892832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Wed, 31 Jul 2019 12:20:38 +0200 Subject: [PATCH] For pubsub items with max_item = 1 use order by in sql queries --- src/gen_pubsub_node.erl | 3 +++ src/mod_pubsub.erl | 23 ++++++++++++++++++++++- src/node_flat.erl | 5 ++++- src/node_flat_sql.erl | 22 +++++++++++++++++++++- src/node_pep.erl | 5 ++++- src/node_pep_sql.erl | 6 +++++- 6 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/gen_pubsub_node.erl b/src/gen_pubsub_node.erl index e4fe0e948..a483bd6ee 100644 --- a/src/gen_pubsub_node.erl +++ b/src/gen_pubsub_node.erl @@ -186,6 +186,9 @@ -callback get_last_items(nodeIdx(), jid(), undefined | rsm_set()) -> {result, [pubsubItem()]}. +-callback get_only_item(nodeIdx(), jid()) -> + {result, [pubsubItem()]}. + -callback get_item(NodeIdx :: nodeIdx(), ItemId :: itemId(), JID :: jid(), diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index b2e2fad60..f1f1dbd51 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -2151,6 +2151,21 @@ get_last_items(Host, Type, Nidx, LJID, Count) when Count > 1 -> get_last_items(_Host, _Type, _Nidx, _LJID, _Count) -> []. +-spec get_only_item(host(), binary(), nodeIdx(), ljid()) -> [#pubsub_item{}]. +get_only_item(Host, Type, Nidx, LJID) -> + case get_cached_item(Host, Nidx) of + undefined -> + case node_action(Host, Type, get_only_item, [Nidx, LJID]) of + {result, Items} when length(Items) < 2 -> + Items; + {result, Items} -> + [hd(lists:keysort(#pubsub_item.modification, Items))]; + _ -> [] + end; + LastItem -> + [LastItem] + end. + %% @doc

Return the list of affiliations as an XMPP response.

-spec get_affiliations(host(), binary(), jid(), [binary()]) -> {result, pubsub()} | {error, stanza_error()}. @@ -3031,7 +3046,13 @@ c2s_handle_info(C2SState, _) -> send_items(Host, Node, Nidx, Type, Options, LJID, Number) -> send_items(Host, Node, Nidx, Type, Options, Host, LJID, LJID, Number). send_items(Host, Node, Nidx, Type, Options, Publisher, SubLJID, ToLJID, Number) -> - case get_last_items(Host, Type, Nidx, SubLJID, Number) of + Items = case max_items(Host, Options) of + 1 -> + get_only_item(Host, Type, Nidx, SubLJID); + _ -> + get_last_items(Host, Type, Nidx, SubLJID, Number) + end, + case Items of [] -> ok; Items -> diff --git a/src/node_flat.erl b/src/node_flat.erl index 1bc2c5e6f..f0deeb7e2 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -46,7 +46,7 @@ get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/7, get_items/3, get_item/7, - get_last_items/3, + get_last_items/3, get_only_item/2, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1, can_fetch_item/2, is_subscribed/1, transform/1]). @@ -812,6 +812,9 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM get_items(Nidx, JID, RSM) end. +get_only_item(Nidx, From) -> + get_last_items(Nidx, From, 1). + get_last_items(Nidx, _From, Count) when Count > 0 -> Items = mnesia:index_read(pubsub_item, Nidx, #pubsub_item.nodeidx), LastItems = lists:reverse(lists:keysort(#pubsub_item.modification, Items)), diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index 59e3c89b4..15d9fd770 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -51,7 +51,8 @@ set_state/1, get_items/7, get_items/3, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1, - get_entity_subscriptions_for_send_last/2, get_last_items/3]). + get_entity_subscriptions_for_send_last/2, get_last_items/3, + get_only_item/2]). -export([decode_jid/1, encode_jid/1, encode_jid_like/1, decode_affiliation/1, decode_subscriptions/1, @@ -741,6 +742,25 @@ get_last_items(Nidx, _From, Limit) -> {result, []} end. +get_only_item(Nidx, _From) -> + SNidx = misc:i2l(Nidx), + Query = fun(mssql, _) -> + ejabberd_sql:sql_query_t( + [<<"select itemid, publisher, creation, modification, payload", + " from pubsub_item where nodeid='", SNidx/binary, "'">>]); + (_, _) -> + ejabberd_sql:sql_query_t( + [<<"select itemid, publisher, creation, modification, payload", + " from pubsub_item where nodeid='", SNidx/binary, "'">>]) + end, + case catch ejabberd_sql:sql_query_t(Query) of + {selected, [<<"itemid">>, <<"publisher">>, <<"creation">>, + <<"modification">>, <<"payload">>], RItems} -> + {result, [raw_to_item(Nidx, RItem) || RItem <- RItems]}; + _ -> + {result, []} + end. + get_item(Nidx, ItemId) -> case catch ejabberd_sql:sql_query_t( ?SQL("select @(itemid)s, @(publisher)s, @(creation)s," diff --git a/src/node_pep.erl b/src/node_pep.erl index 3baafc10d..334681578 100644 --- a/src/node_pep.erl +++ b/src/node_pep.erl @@ -42,7 +42,7 @@ get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/7, get_items/3, get_item/7, - get_last_items/3, + get_last_items/3, get_only_item/2, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1, depends/3]). @@ -231,6 +231,9 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM) get_last_items(Nidx, From, Count) -> node_flat:get_last_items(Nidx, From, Count). +get_only_item(Nidx, From) -> + node_flat:get_only_item(Nidx, From). + get_item(Nidx, ItemId) -> node_flat:get_item(Nidx, ItemId). diff --git a/src/node_pep_sql.erl b/src/node_pep_sql.erl index ac3ab2196..6c1e642b2 100644 --- a/src/node_pep_sql.erl +++ b/src/node_pep_sql.erl @@ -46,7 +46,8 @@ set_state/1, get_items/7, get_items/3, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1, depends/3, - get_entity_subscriptions_for_send_last/2, get_last_items/3]). + get_entity_subscriptions_for_send_last/2, get_last_items/3, + get_only_item/2]). depends(_Host, _ServerHost, _Opts) -> [{mod_caps, hard}]. @@ -218,6 +219,9 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM) get_last_items(Nidx, JID, Count) -> node_flat_sql:get_last_items(Nidx, JID, Count). +get_only_item(Nidx, JID) -> + node_flat_sql:get_only_item(Nidx, JID). + get_item(Nidx, ItemId) -> node_flat_sql:get_item(Nidx, ItemId).