read_sub(Subscriber, Node, NodeId, SubId, Lang) ->
case pubsub_subscription:get_subscription(Subscriber, NodeId, SubId) of
- {error, notfound} ->
- {error, extended_error('not-acceptable', "invalid-subid")};
{result, #pubsub_subscription{options = Options}} ->
{result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options),
OptionsEl = #xmlel{ns = ?NS_PUBSUB, name = 'options',
?XMLATTR(<<"subid">>, SubId) | nodeAttr(Node)],
children = [XdataEl]},
PubsubEl = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children = [OptionsEl]},
+ {result, PubsubEl};
+ _ ->
+ OptionsEl = #xmlel{ns = ?NS_PUBSUB, name = 'options',
+ attrs = [?XMLATTR(<<"jid">>, exmpp_jid:to_binary(Subscriber)),
+ ?XMLATTR(<<"subid">>, SubId) | nodeAttr(Node)]},
+ PubsubEl = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children = [OptionsEl]},
{result, PubsubEl}
end.
write_sub(_Subscriber, _NodeId, _SubId, invalid) ->
{error, extended_error('bad-request', "invalid-options")};
+write_sub(_Subscriber, _NodeID, _SubID, []) ->
+ {result, []};
write_sub(Subscriber, NodeId, SubId, Options) ->
case pubsub_subscription:set_subscription(Subscriber, NodeId, SubId, Options) of
- {error, notfound} ->
- {error, extended_error('not-acceptable', "invalid-subid")};
{result, _} ->
- {result, []}
+ {result, []};
+ {error, _} ->
+ {error, extended_error('not-acceptable', "invalid-subid")}
end.
%% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response}
pubsub_subscription:init(),
mnesia:create_table(pubsub_state,
[{disc_copies, [node()]},
+ {index, [nodeidx]},
{attributes, record_info(fields, pubsub_state)}]),
mnesia:create_table(pubsub_item,
[{disc_only_copies, [node()]},
+ {index, [nodeidx]},
{attributes, record_info(fields, pubsub_item)}]),
ItemsFields = record_info(fields, pubsub_item),
case mnesia:table_info(pubsub_item, attributes) of
).
create_node(NodeIdx, #jid{node = U, domain = S} = _JID) ->
- set_state(#pubsub_state{id = {{U,S,undefined}, NodeIdx}, affiliation = 'owner'}),
+ set_state(#pubsub_state{id = {{U,S,undefined}, NodeIdx}, nodeidx = NodeIdx, affiliation = 'owner'}),
{'result', {'default', 'broadcast'}}.
%% @spec (Removed) -> ok
_ ->
#pubsub_item{
id = {ItemId, NodeIdx},
+ nodeidx = NodeIdx,
creation = {Now, GenKey}, % TODO, better use {Now, SubKey} ?
modification = Modification,
payload = Payload}
get_states(NodeIdx) ->
States = case
- catch mnesia:match_object(#pubsub_state{id = {'_', NodeIdx}, _ = '_'})
+ catch mnesia:index_read(pubsub_state, NodeIdx, #pubsub_state.nodeidx)
of
PubsubStates when is_list(PubsubStates) -> PubsubStates; %% is_list(PubsubStates) useful ?
_ -> []
get_state(NodeIdx, Entity) ->
case catch mnesia:read({pubsub_state, {Entity, NodeIdx}}) of
[#pubsub_state{} = State] -> State;
- _ -> #pubsub_state{id = {Entity, NodeIdx}}
+ _ -> #pubsub_state{id = {Entity, NodeIdx}, nodeidx=NodeIdx}
end.
%% @spec (State) -> ok | {error, Reason::stanzaError()}
).
get_items(NodeIdx, _Entity) ->
- Items = mnesia:match_object(#pubsub_item{id = {'_', NodeIdx}, _ = '_'}),
+ Items = mnesia:index_read(pubsub_item, NodeIdx, #pubsub_item.nodeidx),
{result, lists:reverse(lists:keysort(#pubsub_item.modification, Items))}.
-type(pubsubNode() :: #pubsub_node{}).
-%%% @type pubsubState() = {pubsub_state, Id, Items, Affiliation, Subscriptions}
+%%% @type pubsubState() = {pubsub_state, Id, NodeIdx, Items, Affiliation, Subscriptions}
%%% Id = {fullUsr(), nodeIdx()}
+%%% NodeIdx = nodeIdx(),
%%% Items = [itemId()]
%%% Affiliation = affiliation()
%%% Subscriptions = [{subscription(), subId()}].
-record(pubsub_state,
{
id :: {fullUsr(), nodeIdx()},
+ nodeidx :: nodeIdx(),
items = [] :: [itemId()],
affiliation = 'none' :: affiliation(),
subscriptions = [] :: [{subscription(), subId()}]
-type(pubsubState() :: #pubsub_state{}).
-%%% @type pubsubItem() = {pubsub_item, Id, Creation, Modification, Payload}
+%%% @type pubsubItem() = {pubsub_item, Id, NodeIdx, Creation, Modification, Payload}
%%% Id = {itemId(), nodeIdx()}
+%%% NodeIdx = nodeIdx()
%%% Creation = {now(), bareUsr()}
%%% Modification = {now(), fullUsr()}
%%% Payload = payload().
-record(pubsub_item,
{
id :: {itemId(), nodeIdx()},
+ nodeidx :: nodeIdx(),
creation = {unknown,unknown} :: {now(), bareUsr()},
modification = {unknown,unknown} :: {now(), fullUsr()},
payload = [] :: payload()
-> SubId::subId()
).
+add_subscription(_JID, _NodeID, []) ->
+ make_subid();
add_subscription(_Entity, _NodeIdx, Options) ->
SubId = make_subid(),
mnesia:write(#pubsub_subscription{subid = SubId, options = Options}),
NodeIdx :: nodeIdx(),
SubId :: subId(),
Options :: [nodeOption()])
- -> 'ok' | {'error', 'notfound'}
- ).
+ -> 'ok'
+ ).
-write_subscription(Entity, NodeIdx, SubId, Options) ->
- case read_subscription(Entity, NodeIdx, SubId) of
- {error, 'notfound'} -> {error, 'notfound'};
- Subscription -> mnesia:write(Subscription#pubsub_subscription{options = Options})
- end.
+write_subscription(_Entity, _NodeIdx, SubId, Options) ->
+ mnesia:write(#pubsub_subscription{subid = SubId, options = Options}).
-spec(make_subid/0 :: () -> SubId::subId()).