mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-30 16:36:29 +01:00
clean nodeid/nidx variables names (thanks to Karim)(EJAB-1000)
This commit is contained in:
parent
556892aebf
commit
4b5b98b465
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -123,8 +123,8 @@ delete_node(Removed) ->
|
||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup) ->
|
||||
node_flat:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_flat:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -130,8 +130,8 @@ delete_node(Removed) ->
|
||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) ->
|
||||
node_flat:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_flat:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -128,8 +128,8 @@ delete_node(Removed) ->
|
||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) ->
|
||||
node_flat:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_flat:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -73,33 +73,33 @@ create_node_permission(_Host, _ServerHost, _Node, _ParentNode,
|
||||
_Owner, _Access) ->
|
||||
{result, true}.
|
||||
|
||||
create_node(NodeID, Owner) ->
|
||||
node_flat:create_node(NodeID, Owner).
|
||||
create_node(NodeId, Owner) ->
|
||||
node_flat:create_node(NodeId, Owner).
|
||||
|
||||
delete_node(Removed) ->
|
||||
node_flat:delete_node(Removed).
|
||||
|
||||
subscribe_node(NodeID, Sender, Subscriber, AccessModel,
|
||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
||||
SendLast, PresenceSubscription, RosterGroup, Options) ->
|
||||
node_flat:subscribe_node(NodeID, Sender, Subscriber, AccessModel,
|
||||
node_flat:subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
||||
SendLast, PresenceSubscription, RosterGroup,
|
||||
Options).
|
||||
|
||||
unsubscribe_node(NodeID, Sender, Subscriber, SubID) ->
|
||||
node_flat:unsubscribe_node(NodeID, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeID, Publisher, Model, MaxItems, ItemID, Payload) ->
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
%% TODO: should look up the NodeTree plugin here. There's no
|
||||
%% access to the Host of the request at this level, so for now we
|
||||
%% just use nodetree_dag.
|
||||
case nodetree_dag:get_node(NodeID) of
|
||||
case nodetree_dag:get_node(NodeId) of
|
||||
#pubsub_node{options = Options} ->
|
||||
case find_opt(node_type, Options) of
|
||||
collection ->
|
||||
{error, mod_pubsub:extended_error('not-allowed', "publish")};
|
||||
_ ->
|
||||
node_flat:publish_item(NodeID, Publisher, Model,
|
||||
MaxItems, ItemID, Payload)
|
||||
node_flat:publish_item(NodeId, Publisher, Model,
|
||||
MaxItems, ItemId, Payload)
|
||||
end;
|
||||
Err ->
|
||||
Err
|
||||
@ -109,72 +109,72 @@ find_opt(_, []) -> false;
|
||||
find_opt(Option, [{Option, Value} | _]) -> Value;
|
||||
find_opt(Option, [_ | T]) -> find_opt(Option, T).
|
||||
|
||||
remove_extra_items(NodeID, MaxItems, ItemIDs) ->
|
||||
node_flat:remove_extra_items(NodeID, MaxItems, ItemIDs).
|
||||
remove_extra_items(NodeId, MaxItems, ItemIds) ->
|
||||
node_flat:remove_extra_items(NodeId, MaxItems, ItemIds).
|
||||
|
||||
delete_item(NodeID, Publisher, PublishModel, ItemID) ->
|
||||
node_flat:delete_item(NodeID, Publisher, PublishModel, ItemID).
|
||||
delete_item(NodeId, Publisher, PublishModel, ItemId) ->
|
||||
node_flat:delete_item(NodeId, Publisher, PublishModel, ItemId).
|
||||
|
||||
purge_node(NodeID, Owner) ->
|
||||
node_flat:purge_node(NodeID, Owner).
|
||||
purge_node(NodeId, Owner) ->
|
||||
node_flat:purge_node(NodeId, Owner).
|
||||
|
||||
get_entity_affiliations(Host, Owner) ->
|
||||
node_flat:get_entity_affiliations(Host, Owner).
|
||||
|
||||
get_node_affiliations(NodeID) ->
|
||||
node_flat:get_node_affiliations(NodeID).
|
||||
get_node_affiliations(NodeId) ->
|
||||
node_flat:get_node_affiliations(NodeId).
|
||||
|
||||
get_affiliation(NodeID, Owner) ->
|
||||
node_flat:get_affiliation(NodeID, Owner).
|
||||
get_affiliation(NodeId, Owner) ->
|
||||
node_flat:get_affiliation(NodeId, Owner).
|
||||
|
||||
set_affiliation(NodeID, Owner, Affiliation) ->
|
||||
node_flat:set_affiliation(NodeID, Owner, Affiliation).
|
||||
set_affiliation(NodeId, Owner, Affiliation) ->
|
||||
node_flat:set_affiliation(NodeId, Owner, Affiliation).
|
||||
|
||||
get_entity_subscriptions(Host, Owner) ->
|
||||
node_flat:get_entity_subscriptions(Host, Owner).
|
||||
|
||||
get_node_subscriptions(NodeID) ->
|
||||
node_flat:get_node_subscriptions(NodeID).
|
||||
get_node_subscriptions(NodeId) ->
|
||||
node_flat:get_node_subscriptions(NodeId).
|
||||
|
||||
get_subscriptions(NodeID, Owner) ->
|
||||
node_flat:get_subscriptions(NodeID, Owner).
|
||||
get_subscriptions(NodeId, Owner) ->
|
||||
node_flat:get_subscriptions(NodeId, Owner).
|
||||
|
||||
set_subscriptions(NodeID, Owner, Subscription, SubID) ->
|
||||
node_flat:set_subscriptions(NodeID, Owner, Subscription, SubID).
|
||||
set_subscriptions(NodeId, Owner, Subscription, SubId) ->
|
||||
node_flat:set_subscriptions(NodeId, Owner, Subscription, SubId).
|
||||
|
||||
get_pending_nodes(Host, Owner) ->
|
||||
node_flat:get_pending_nodes(Host, Owner).
|
||||
|
||||
get_states(NodeID) ->
|
||||
node_flat:get_states(NodeID).
|
||||
get_states(NodeId) ->
|
||||
node_flat:get_states(NodeId).
|
||||
|
||||
get_state(NodeID, JID) ->
|
||||
node_flat:get_state(NodeID, JID).
|
||||
get_state(NodeId, JID) ->
|
||||
node_flat:get_state(NodeId, JID).
|
||||
|
||||
set_state(State) ->
|
||||
node_flat:set_state(State).
|
||||
|
||||
get_items(NodeID, From) ->
|
||||
node_flat:get_items(NodeID, From).
|
||||
get_items(NodeId, From) ->
|
||||
node_flat:get_items(NodeId, From).
|
||||
|
||||
get_items(NodeID, JID, AccessModel, PresenceSubscription,
|
||||
RosterGroup, SubID) ->
|
||||
node_flat:get_items(NodeID, JID, AccessModel, PresenceSubscription,
|
||||
RosterGroup, SubID).
|
||||
get_items(NodeId, JID, AccessModel, PresenceSubscription,
|
||||
RosterGroup, SubId) ->
|
||||
node_flat:get_items(NodeId, JID, AccessModel, PresenceSubscription,
|
||||
RosterGroup, SubId).
|
||||
|
||||
get_item(NodeID, ItemID) ->
|
||||
node_flat:get_item(NodeID, ItemID).
|
||||
get_item(NodeId, ItemId) ->
|
||||
node_flat:get_item(NodeId, ItemId).
|
||||
|
||||
get_item(NodeID, ItemID, JID, AccessModel, PresenceSubscription,
|
||||
RosterGroup, SubID) ->
|
||||
node_flat:get_item(NodeID, ItemID, JID, AccessModel,
|
||||
PresenceSubscription, RosterGroup, SubID).
|
||||
get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription,
|
||||
RosterGroup, SubId) ->
|
||||
node_flat:get_item(NodeId, ItemId, JID, AccessModel,
|
||||
PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_flat:set_item(Item).
|
||||
|
||||
get_item_name(Host, Node, ID) ->
|
||||
node_flat:get_item_name(Host, Node, ID).
|
||||
get_item_name(Host, Node, ItemId) ->
|
||||
node_flat:get_item_name(Host, Node, ItemId).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat:node_to_path(Node).
|
||||
|
@ -126,13 +126,13 @@ subscribe_node(_NodeId, _Sender, _Subscriber, _AccessModel,
|
||||
_SendLast, _PresenceSubscription, _RosterGroup, _Options) ->
|
||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')}.
|
||||
|
||||
unsubscribe_node(_NodeId, _Sender, _Subscriber, _SubID) ->
|
||||
unsubscribe_node(_NodeId, _Sender, _Subscriber, _SubId) ->
|
||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')}.
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
lists:foreach(fun(SubNode) ->
|
||||
node_flat:publish_item(
|
||||
SubNode#pubsub_node.id, Publisher, Model,
|
||||
SubNode#pubsub_node.idx, Publisher, Model,
|
||||
MaxItems, ItemId, Payload)
|
||||
end, nodetree_tree:get_subnodes(NodeId, Publisher, Publisher)).
|
||||
|
||||
|
@ -195,30 +195,30 @@ create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) ->
|
||||
|
||||
%% @spec (NodeId, Owner) ->
|
||||
%% {result, Result} | exit
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Owner = ljid()
|
||||
%% @doc <p></p>
|
||||
create_node(NodeId, Owner) ->
|
||||
OwnerKey = jlib:short_prepd_bare_jid(Owner),
|
||||
set_state(#pubsub_state{stateid = {OwnerKey, NodeId}, affiliation = owner}),
|
||||
set_state(#pubsub_state{id = {OwnerKey, NodeId}, affiliation = owner}),
|
||||
{result, {default, broadcast}}.
|
||||
|
||||
%% @spec (Removed) -> ok
|
||||
%% Removed = [mod_pubsub:pubsubNode()]
|
||||
%% Removed = [mod_pubsub:pubsub_node()]
|
||||
%% @doc <p>purge items of deleted nodes after effective deletion.</p>
|
||||
delete_node(Removed) ->
|
||||
Tr = fun(#pubsub_state{stateid = {J, _}, subscriptions = Ss}) ->
|
||||
Tr = fun(#pubsub_state{id = {J, _}, subscriptions = Ss}) ->
|
||||
lists:map(fun(S) ->
|
||||
{J, S}
|
||||
end, Ss)
|
||||
end,
|
||||
Reply = lists:map(
|
||||
fun(#pubsub_node{id = NodeId} = PubsubNode) ->
|
||||
{result, States} = get_states(NodeId),
|
||||
fun(#pubsub_node{idx = Nidx} = PubsubNode) ->
|
||||
{result, States} = get_states(Nidx),
|
||||
lists:foreach(
|
||||
fun(#pubsub_state{stateid = {LJID, _}, items = Items}) ->
|
||||
del_items(NodeId, Items),
|
||||
del_state(NodeId, LJID)
|
||||
fun(#pubsub_state{id = {LJID, _}, items = Items}) ->
|
||||
del_items(Nidx, Items),
|
||||
del_state(Nidx, LJID)
|
||||
end, States),
|
||||
{PubsubNode, lists:flatmap(Tr, States)}
|
||||
end, Removed),
|
||||
@ -321,9 +321,9 @@ subscribe_node(NodeId, Sender, {U,S,R} = Subscriber, AccessModel,
|
||||
|
||||
%% @spec (NodeId, Sender, Subscriber, SubId) ->
|
||||
%% {error, Reason} | {result, []}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Sender = mod_pubsub:jid()
|
||||
%% Subscriber = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Sender = ljid()
|
||||
%% Subscriber = ljid()
|
||||
%% SubId = mod_pubsub:subid()
|
||||
%% Reason = mod_pubsub:stanzaError()
|
||||
%% @doc <p>Unsubscribe the <tt>Subscriber</tt> from the <tt>Node</tt>.</p>
|
||||
@ -399,11 +399,11 @@ delete_subscriptions(SubKey, NodeId, Subscriptions, SubState) ->
|
||||
|
||||
%% @spec (NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
|
||||
%% {true, PubsubItem} | {result, Reply}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Publisher = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Publisher = ljid()
|
||||
%% PublishModel = atom()
|
||||
%% MaxItems = integer()
|
||||
%% ItemId = string()
|
||||
%% ItemId = item()
|
||||
%% Payload = term()
|
||||
%% @doc <p>Publishes the item passed as parameter.</p>
|
||||
%% <p>The mechanism works as follow:
|
||||
@ -465,7 +465,7 @@ publish_item(NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
|
||||
OldItem#pubsub_item{modification = PubId,
|
||||
payload = Payload};
|
||||
_ ->
|
||||
#pubsub_item{itemid = {ItemId, NodeId},
|
||||
#pubsub_item{id = {ItemId, NodeId},
|
||||
creation = {Now, GenKey},
|
||||
modification = PubId,
|
||||
payload = Payload}
|
||||
@ -481,7 +481,7 @@ publish_item(NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
|
||||
end.
|
||||
|
||||
%% @spec (NodeId, MaxItems, ItemIds) -> {NewItemIds,OldItemIds}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% NodeId = nodeidx()
|
||||
%% MaxItems = integer() | unlimited
|
||||
%% ItemIds = [ItemId::string()]
|
||||
%% NewItemIds = [ItemId::string()]
|
||||
@ -508,10 +508,10 @@ remove_extra_items(NodeId, MaxItems, ItemIds) ->
|
||||
%% @spec (NodeId, Publisher, PublishModel, ItemId) ->
|
||||
%% {error, Reason::stanzaError()} |
|
||||
%% {result, []}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Publisher = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Publisher = ljid()
|
||||
%% PublishModel = atom()
|
||||
%% ItemId = string()
|
||||
%% ItemId = item()
|
||||
%% @doc <p>Triggers item deletion.</p>
|
||||
%% <p>Default plugin: The user performing the deletion must be the node owner
|
||||
%% or a publisher, or PublishModel being open.</p>
|
||||
@ -563,8 +563,8 @@ delete_item(NodeId, Publisher, PublishModel, ItemId) ->
|
||||
%% @spec (NodeId, Owner) ->
|
||||
%% {error, Reason::stanzaError()} |
|
||||
%% {result, {default, broadcast}}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Owner = ljid()
|
||||
purge_node(NodeId, Owner) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
GenState = get_state(NodeId, GenKey),
|
||||
@ -586,7 +586,7 @@ purge_node(NodeId, Owner) ->
|
||||
|
||||
%% @spec (Host, JID) -> [{Node,Affiliation}]
|
||||
%% Host = host()
|
||||
%% JID = mod_pubsub:jid()
|
||||
%% JID = ljid()
|
||||
%% @doc <p>Return the current affiliations for the given user</p>
|
||||
%% <p>The default module reads affiliations in the main Mnesia
|
||||
%% <tt>pubsub_state</tt> table. If a plugin stores its data in the same
|
||||
@ -596,14 +596,14 @@ purge_node(NodeId, Owner) ->
|
||||
%% <tt>pubsub_state</tt> table.</p>
|
||||
get_entity_affiliations(Host, Owner) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}),
|
||||
States = mnesia:match_object(#pubsub_state{id = {GenKey, '_'}, _ = '_'}),
|
||||
NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of
|
||||
[{nodetree, N}] -> N;
|
||||
_ -> nodetree_tree
|
||||
end,
|
||||
Reply = lists:foldl(fun(#pubsub_state{stateid = {_, N}, affiliation = A}, Acc) ->
|
||||
Reply = lists:foldl(fun(#pubsub_state{id = {_, N}, affiliation = A}, Acc) ->
|
||||
case NodeTree:get_node(N) of
|
||||
#pubsub_node{nodeid = {Host, _}} = Node -> [{Node, A}|Acc];
|
||||
#pubsub_node{id = {Host, _}} = Node -> [{Node, A}|Acc];
|
||||
_ -> Acc
|
||||
end
|
||||
end, [], States),
|
||||
@ -611,7 +611,7 @@ get_entity_affiliations(Host, Owner) ->
|
||||
|
||||
get_node_affiliations(NodeId) ->
|
||||
{result, States} = get_states(NodeId),
|
||||
Tr = fun(#pubsub_state{stateid = {J, _}, affiliation = A}) ->
|
||||
Tr = fun(#pubsub_state{id = {J, _}, affiliation = A}) ->
|
||||
{J, A}
|
||||
end,
|
||||
{result, lists:map(Tr, States)}.
|
||||
@ -633,7 +633,7 @@ set_affiliation(NodeId, Owner, Affiliation) when ?IS_JID(Owner)->
|
||||
|
||||
%% @spec (Host, Owner) -> [{Node,Subscription}]
|
||||
%% Host = host()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Owner = ljid()
|
||||
%% @doc <p>Return the current subscriptions for the given user</p>
|
||||
%% <p>The default module reads subscriptions in the main Mnesia
|
||||
%% <tt>pubsub_state</tt> table. If a plugin stores its data in the same
|
||||
@ -646,19 +646,19 @@ get_entity_subscriptions(Host, Owner) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
States = case SubKey of
|
||||
GenKey -> mnesia:match_object(
|
||||
#pubsub_state{stateid = {{U, D, '_'}, '_'}, _ = '_'});
|
||||
#pubsub_state{id = {{U, D, '_'}, '_'}, _ = '_'});
|
||||
_ -> mnesia:match_object(
|
||||
#pubsub_state{stateid = {GenKey, '_'}, _ = '_'})
|
||||
#pubsub_state{id = {GenKey, '_'}, _ = '_'})
|
||||
++ mnesia:match_object(
|
||||
#pubsub_state{stateid = {SubKey, '_'}, _ = '_'})
|
||||
#pubsub_state{id = {SubKey, '_'}, _ = '_'})
|
||||
end,
|
||||
NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of
|
||||
[{nodetree, N}] -> N;
|
||||
_ -> nodetree_tree
|
||||
end,
|
||||
Reply = lists:foldl(fun(#pubsub_state{stateid = {J, N}, subscriptions = Ss}, Acc) ->
|
||||
Reply = lists:foldl(fun(#pubsub_state{id = {J, N}, subscriptions = Ss}, Acc) ->
|
||||
case NodeTree:get_node(N) of
|
||||
#pubsub_node{nodeid = {Host, _}} = Node ->
|
||||
#pubsub_node{id = {Host, _}} = Node ->
|
||||
lists:foldl(fun({Sub, SubId}, Acc2) ->
|
||||
[{Node, Sub, SubId, J} | Acc2];
|
||||
(S, Acc2) ->
|
||||
@ -671,7 +671,7 @@ get_entity_subscriptions(Host, Owner) ->
|
||||
|
||||
get_node_subscriptions(NodeId) ->
|
||||
{result, States} = get_states(NodeId),
|
||||
Tr = fun(#pubsub_state{stateid = {J, _}, subscriptions = Subscriptions}) ->
|
||||
Tr = fun(#pubsub_state{id = {J, _}, subscriptions = Subscriptions}) ->
|
||||
%% TODO: get rid of cases to handle non-list subscriptions
|
||||
case Subscriptions of
|
||||
[_|_] ->
|
||||
@ -723,8 +723,8 @@ replace_subscription(NewSub, SubState) ->
|
||||
|
||||
replace_subscription(_, [], Acc) ->
|
||||
Acc;
|
||||
replace_subscription({Sub, SubId}, [{_, SubID} | T], Acc) ->
|
||||
replace_subscription({Sub, SubId}, T, [{Sub, SubID} | Acc]).
|
||||
replace_subscription({Sub, SubId}, [{_, SubId} | T], Acc) ->
|
||||
replace_subscription({Sub, SubId}, T, [{Sub, SubId} | Acc]).
|
||||
|
||||
new_subscription(NodeId, Owner, Subscription, SubState) ->
|
||||
SubId = pubsub_subscription:add_subscription(Owner, NodeId, []),
|
||||
@ -733,34 +733,34 @@ new_subscription(NodeId, Owner, Subscription, SubState) ->
|
||||
{Subscription, SubId}.
|
||||
|
||||
unsub_with_subid(NodeId, SubId, SubState) ->
|
||||
pubsub_subscription:delete_subscription(SubState#pubsub_state.stateid,
|
||||
pubsub_subscription:delete_subscription(SubState#pubsub_state.id,
|
||||
NodeId, SubId),
|
||||
NewSubs = lists:filter(fun ({_, SID}) -> SubId =/= SID end,
|
||||
SubState#pubsub_state.subscriptions),
|
||||
case {NewSubs, SubState#pubsub_state.affiliation} of
|
||||
{[], none} ->
|
||||
del_state(NodeId, element(1, SubState#pubsub_state.stateid));
|
||||
del_state(NodeId, element(1, SubState#pubsub_state.id));
|
||||
_ ->
|
||||
set_state(SubState#pubsub_state{subscriptions = NewSubs})
|
||||
end.
|
||||
%% @spec (Host, Owner) -> {result, [Node]} | {error, Reason}
|
||||
%% Host = host()
|
||||
%% Owner = jid()
|
||||
%% Node = pubsubNode()
|
||||
%% Node = node()
|
||||
%% @doc <p>Returns a list of Owner's nodes on Host with pending
|
||||
%% subscriptions.</p>
|
||||
get_pending_nodes(Host, Owner) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'},
|
||||
States = mnesia:match_object(#pubsub_state{id = {GenKey, '_'},
|
||||
affiliation = owner,
|
||||
_ = '_'}),
|
||||
NodeIDs = [ID || #pubsub_state{stateid = {_, ID}} <- States],
|
||||
Nidxs = [Nidx || #pubsub_state{id = {_, Nidx}} <- States],
|
||||
NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of
|
||||
[{nodetree, N}] -> N;
|
||||
_ -> nodetree_tree
|
||||
end,
|
||||
Reply = mnesia:foldl(fun(#pubsub_state{stateid = {_, NID}} = S, Acc) ->
|
||||
case lists:member(NID, NodeIDs) of
|
||||
Reply = mnesia:foldl(fun(#pubsub_state{id = {_, Nidx}} = S, Acc) ->
|
||||
case lists:member(Nidx, Nidxs) of
|
||||
true ->
|
||||
case get_nodes_helper(NodeTree, S) of
|
||||
{value, Node} -> [Node | Acc];
|
||||
@ -773,7 +773,7 @@ get_pending_nodes(Host, Owner) ->
|
||||
{result, Reply}.
|
||||
|
||||
get_nodes_helper(NodeTree,
|
||||
#pubsub_state{stateid = {_, N}, subscriptions = Subs}) ->
|
||||
#pubsub_state{id = {_, N}, subscriptions = Subs}) ->
|
||||
HasPending = fun ({pending, _}) -> true;
|
||||
(pending) -> true;
|
||||
(_) -> false
|
||||
@ -781,7 +781,7 @@ get_nodes_helper(NodeTree,
|
||||
case lists:any(HasPending, Subs) of
|
||||
true ->
|
||||
case NodeTree:get_node(N) of
|
||||
#pubsub_node{nodeid = {_, Node}} ->
|
||||
#pubsub_node{id = {_, Node}} ->
|
||||
{value, Node};
|
||||
_ ->
|
||||
false
|
||||
@ -791,7 +791,7 @@ get_nodes_helper(NodeTree,
|
||||
end.
|
||||
|
||||
%% @spec (NodeId) -> {result, [State] | []}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% NodeId = nodeidx()
|
||||
%% State = mod_pubsub:pubsubState()
|
||||
%% @doc Returns the list of stored states for a given node.
|
||||
%% <p>For the default PubSub module, states are stored in Mnesia database.</p>
|
||||
@ -805,26 +805,26 @@ get_nodes_helper(NodeTree,
|
||||
%% node_default:get_states(NodeId).'''</p>
|
||||
get_states(NodeId) ->
|
||||
States = case catch mnesia:match_object(
|
||||
#pubsub_state{stateid = {'_', NodeId}, _ = '_'}) of
|
||||
#pubsub_state{id = {'_', NodeId}, _ = '_'}) of
|
||||
List when is_list(List) -> List;
|
||||
_ -> []
|
||||
end,
|
||||
{result, States}.
|
||||
|
||||
%% @spec (NodeId, JID) -> [State] | []
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% JID = mod_pubsub:jid()
|
||||
%% State = mod_pubsub:pubsubItems()
|
||||
%% NodeId = nodeidx()
|
||||
%% JID = ljid()
|
||||
%% State = mod_pubsub:pubsub_item()
|
||||
%% @doc <p>Returns a state (one state list), given its reference.</p>
|
||||
get_state(NodeId, JID) ->
|
||||
StateId = {JID, NodeId},
|
||||
case catch mnesia:read({pubsub_state, StateId}) of
|
||||
[State] when is_record(State, pubsub_state) -> State;
|
||||
_ -> #pubsub_state{stateid=StateId}
|
||||
_ -> #pubsub_state{id=StateId}
|
||||
end.
|
||||
|
||||
%% @spec (State) -> ok | {error, Reason::stanzaError()}
|
||||
%% State = mod_pubsub:pubsubStates()
|
||||
%% State = mod_pubsub:pubsub_state()
|
||||
%% @doc <p>Write a state into database.</p>
|
||||
set_state(State) when is_record(State, pubsub_state) ->
|
||||
mnesia:write(State);
|
||||
@ -832,14 +832,14 @@ set_state(_) ->
|
||||
{error, 'internal-server-error'}.
|
||||
|
||||
%% @spec (NodeId, JID) -> ok | {error, Reason::stanzaError()}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% NodeId = nodeidx()
|
||||
%% @doc <p>Delete a state from database.</p>
|
||||
del_state(NodeId, JID) ->
|
||||
mnesia:delete({pubsub_state, {JID, NodeId}}).
|
||||
|
||||
%% @spec (NodeId, From) -> [Items] | []
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Items = mod_pubsub:pubsubItems()
|
||||
%% NodeId = nodeidx()
|
||||
%% Items = mod_pubsub:pubsub_item()
|
||||
%% @doc Returns the list of stored items for a given node.
|
||||
%% <p>For the default PubSub module, items are stored in Mnesia database.</p>
|
||||
%% <p>We can consider that the pubsub_item table have been created by the main
|
||||
@ -851,7 +851,7 @@ del_state(NodeId, JID) ->
|
||||
%% ```get_items(NodeId, From) ->
|
||||
%% node_default:get_items(NodeId, From).'''</p>
|
||||
get_items(NodeId, _From) ->
|
||||
Items = mnesia:match_object(#pubsub_item{itemid = {'_', NodeId}, _ = '_'}),
|
||||
Items = mnesia:match_object(#pubsub_item{id = {'_', NodeId}, _ = '_'}),
|
||||
{result, lists:reverse(lists:keysort(#pubsub_item.modification, Items))}.
|
||||
get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
|
||||
SubKey = jlib:short_prepd_jid(JID),
|
||||
@ -891,9 +891,9 @@ get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -
|
||||
end.
|
||||
|
||||
%% @spec (NodeId, ItemId) -> [Item] | []
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% ItemId = string()
|
||||
%% Item = mod_pubsub:pubsubItems()
|
||||
%% NodeId = nodeidx()
|
||||
%% ItemId = item()
|
||||
%% Item = mod_pubsub:pubsub_item()
|
||||
%% @doc <p>Returns an item (one item list), given its reference.</p>
|
||||
get_item(NodeId, ItemId) ->
|
||||
case mnesia:read({pubsub_item, {ItemId, NodeId}}) of
|
||||
@ -912,7 +912,7 @@ get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _S
|
||||
%%SubId == "", ?? ->
|
||||
%% Entity has multiple subscriptions to the node but does not specify a subscription ID
|
||||
%{error, ?ERR_EXTENDED('bad-request', "subid-required")};
|
||||
%%InvalidSubID ->
|
||||
%%InvalidSubId ->
|
||||
%% Entity is subscribed but specifies an invalid subscription ID
|
||||
%{error, ?ERR_EXTENDED('not-acceptable', "invalid-subid")};
|
||||
Affiliation == outcast ->
|
||||
@ -938,7 +938,7 @@ get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _S
|
||||
end.
|
||||
|
||||
%% @spec (Item) -> ok | {error, Reason::stanzaError()}
|
||||
%% Item = mod_pubsub:pubsubItems()
|
||||
%% Item = mod_pubsub:pubsub_item()
|
||||
%% @doc <p>Write an item into database.</p>
|
||||
set_item(Item) when is_record(Item, pubsub_item) ->
|
||||
mnesia:write(Item);
|
||||
@ -946,8 +946,8 @@ set_item(_) ->
|
||||
{error, 'internal-server-error'}.
|
||||
|
||||
%% @spec (NodeId, ItemId) -> ok | {error, Reason::stanzaError()}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% ItemId = string()
|
||||
%% NodeId = nodeidx()
|
||||
%% ItemId = item()
|
||||
%% @doc <p>Delete an item from database.</p>
|
||||
del_item(NodeId, ItemId) ->
|
||||
mnesia:delete({pubsub_item, {ItemId, NodeId}}).
|
||||
|
@ -37,7 +37,7 @@
|
||||
%%% development is still a work in progress. However, the system is already
|
||||
%%% useable and useful as is. Please, send us comments, feedback and
|
||||
%%% improvements.</p>
|
||||
|
||||
%%TODO : fix SQL requests with nodeid/id and id/idx changes
|
||||
-module(node_flat_odbc).
|
||||
-author('christophe.romain@process-one.net').
|
||||
|
||||
@ -191,9 +191,9 @@ features() ->
|
||||
%% @spec (Host, ServerHost, Node, ParentNode, Owner, Access) -> bool()
|
||||
%% Host = mod_pubsub:host()
|
||||
%% ServerHost = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% ParentNode = mod_pubsub:pubsubNode()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:node()
|
||||
%% ParentNode = mod_pubsub:node()
|
||||
%% Owner = ljid()
|
||||
%% Access = all | atom()
|
||||
%% @doc Checks if the current user has the permission to create the requested node
|
||||
%% <p>In {@link node_default}, the permission is decided by the place in the
|
||||
@ -212,34 +212,27 @@ create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) ->
|
||||
|
||||
%% @spec (NodeId, Owner) ->
|
||||
%% {result, Result} | exit
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Owner = ljid()
|
||||
%% @doc <p></p>
|
||||
create_node(NodeId, Owner) ->
|
||||
OwnerKey = jlib:short_prepd_bare_jid(Owner),
|
||||
State = #pubsub_state{stateid = {OwnerKey, NodeId}, affiliation = owner},
|
||||
State = #pubsub_state{id = {OwnerKey, NodeId}, affiliation = owner},
|
||||
catch ejabberd_odbc:sql_query_t(
|
||||
["insert into pubsub_state(nodeid, jid, affiliation, subscriptions) "
|
||||
"values(", state_to_raw(NodeId, State), ");"]),
|
||||
{result, {default, broadcast}}.
|
||||
|
||||
%% @spec (Removed) -> ok
|
||||
%% Removed = [mod_pubsub:pubsubNode()]
|
||||
%% Removed = [mod_pubsub:node()]
|
||||
%% @doc <p>purge items of deleted nodes after effective deletion.</p>
|
||||
delete_node(Removed) ->
|
||||
%% pablo: TODO, this is present on trunk/node_flat but not on trunk/node_flat_odbc.
|
||||
%% check what is the desired behaviour
|
||||
%% Tr = fun(#pubsub_state{stateid = {J, _}, subscriptions = Ss}) ->
|
||||
%% lists:map(fun(S) ->
|
||||
%% {J, S}
|
||||
%% end, Ss)
|
||||
%% end,
|
||||
Reply = lists:map(
|
||||
fun(#pubsub_node{id = NodeId} = PubsubNode) ->
|
||||
fun(#pubsub_node{idx = Nidx} = PubsubNode) ->
|
||||
Subscriptions = case catch ejabberd_odbc:sql_query_t(
|
||||
["select jid, subscriptions "
|
||||
"from pubsub_state "
|
||||
"where nodeid='", NodeId, ";"]) of
|
||||
"where nodeid='", Nidx, ";"]) of
|
||||
{selected, ["jid", "subscriptions"], RItems} ->
|
||||
lists:map(fun({SJID, Subscriptions}) ->
|
||||
{decode_jid(SJID), decode_subscriptions(Subscriptions)}
|
||||
@ -345,9 +338,9 @@ subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
||||
|
||||
%% @spec (NodeId, Sender, Subscriber, SubId) ->
|
||||
%% {error, Reason} | {result, []}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Sender = mod_pubsub:jid()
|
||||
%% Subscriber = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Sender = ljid()
|
||||
%% Subscriber = ljid()
|
||||
%% SubId = mod_pubsub:subid()
|
||||
%% Reason = mod_pubsub:stanzaError()
|
||||
%% @doc <p>Unsubscribe the <tt>Subscriber</tt> from the <tt>Node</tt>.</p>
|
||||
@ -417,11 +410,11 @@ delete_subscription(SubKey, NodeId, {Subscription, SubId}, Affiliation, Subscrip
|
||||
|
||||
%% @spec (NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
|
||||
%% {true, PubsubItem} | {result, Reply}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Publisher = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Publisher = ljid()
|
||||
%% PublishModel = atom()
|
||||
%% MaxItems = integer()
|
||||
%% ItemId = string()
|
||||
%% ItemId = item()
|
||||
%% Payload = term()
|
||||
%% @doc <p>Publishes the item passed as parameter.</p>
|
||||
%% <p>The mechanism works as follow:
|
||||
@ -474,7 +467,7 @@ publish_item(NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
|
||||
%% Note: this works cause set_item tries an update before
|
||||
%% the insert, and the update just ignore creation field.
|
||||
PubId = {now(), SubKey},
|
||||
set_item(#pubsub_item{itemid = {ItemId, NodeId},
|
||||
set_item(#pubsub_item{id = {ItemId, NodeId},
|
||||
creation = {now(), GenKey},
|
||||
modification = PubId,
|
||||
payload = Payload}),
|
||||
@ -488,10 +481,10 @@ publish_item(NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
|
||||
end.
|
||||
|
||||
%% @spec (NodeId, MaxItems, ItemIds) -> {NewItemIds,OldItemIds}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% NodeId = nodeidx()
|
||||
%% MaxItems = integer() | unlimited
|
||||
%% ItemIds = [ItemId::string()]
|
||||
%% NewItemIds = [ItemId::string()]
|
||||
%% ItemIds = [item()]
|
||||
%% NewItemIds = [item()]
|
||||
%% @doc <p>This function is used to remove extra items, most notably when the
|
||||
%% maximum number of items has been reached.</p>
|
||||
%% <p>This function is used internally by the core PubSub module, as no
|
||||
@ -515,10 +508,10 @@ remove_extra_items(NodeId, MaxItems, ItemIds) ->
|
||||
%% @spec (NodeId, Publisher, PublishModel, ItemId) ->
|
||||
%% {error, Reason::stanzaError()} |
|
||||
%% {result, []}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Publisher = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Publisher = ljid()
|
||||
%% PublishModel = atom()
|
||||
%% ItemId = string()
|
||||
%% ItemId = item()
|
||||
%% @doc <p>Triggers item deletion.</p>
|
||||
%% <p>Default plugin: The user performing the deletion must be the node owner
|
||||
%% or a publisher, or PublishModel being open.</p>
|
||||
@ -549,8 +542,8 @@ delete_item(NodeId, Publisher, PublishModel, ItemId) ->
|
||||
%% @spec (NodeId, Owner) ->
|
||||
%% {error, Reason::stanzaError()} |
|
||||
%% {result, {default, broadcast}}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% NodeId = nodeidx()
|
||||
%% Owner = ljid()
|
||||
purge_node(NodeId, Owner) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
GenState = get_state(NodeId, GenKey),
|
||||
@ -569,7 +562,7 @@ purge_node(NodeId, Owner) ->
|
||||
|
||||
%% @spec (Host, JID) -> [{Node,Affiliation}]
|
||||
%% Host = host()
|
||||
%% JID = mod_pubsub:jid()
|
||||
%% JID = ljid()
|
||||
%% @doc <p>Return the current affiliations for the given user</p>
|
||||
%% <p>The default module reads affiliations in the main Mnesia
|
||||
%% <tt>pubsub_state</tt> table. If a plugin stores its data in the same
|
||||
@ -632,7 +625,7 @@ set_affiliation(NodeId, Owner, Affiliation) when ?IS_JID(Owner)->
|
||||
|
||||
%% @spec (Host, Owner) -> [{Node,Subscription}]
|
||||
%% Host = host()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Owner = ljid()
|
||||
%% @doc <p>Return the current subscriptions for the given user</p>
|
||||
%% <p>The default module reads subscriptions in the main Mnesia
|
||||
%% <tt>pubsub_state</tt> table. If a plugin stores its data in the same
|
||||
@ -664,13 +657,13 @@ get_entity_subscriptions(Host, Owner) ->
|
||||
{selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} ->
|
||||
lists:foldl(fun({N, T, I, J, S}, Acc) ->
|
||||
Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}),
|
||||
Jid = decode_jid(J),
|
||||
JID = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Node, none, Jid}|Acc];
|
||||
[{Node, none, JID}|Acc];
|
||||
Subs ->
|
||||
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, Jid}|Acc2];
|
||||
(Sub, Acc2) -> [{Node, Sub, Jid}|Acc2]
|
||||
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, JID}|Acc2];
|
||||
(Sub, Acc2) -> [{Node, Sub, JID}|Acc2]
|
||||
end, Acc, Subs)
|
||||
end
|
||||
end, [], RItems);
|
||||
@ -707,13 +700,13 @@ get_entity_subscriptions_for_send_last(Host, Owner) ->
|
||||
{selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} ->
|
||||
lists:foldl(fun({N, T, I, J, S}, Acc) ->
|
||||
Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}),
|
||||
Jid = decode_jid(J),
|
||||
JID = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Node, none, Jid}|Acc];
|
||||
[{Node, none, JID}|Acc];
|
||||
Subs ->
|
||||
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, Jid}|Acc2];
|
||||
(Sub, Acc2) -> [{Node, Sub, Jid}|Acc2]
|
||||
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, JID}|Acc2];
|
||||
(Sub, Acc2) -> [{Node, Sub, JID}|Acc2]
|
||||
end, Acc, Subs)
|
||||
end
|
||||
end, [], RItems);
|
||||
@ -729,13 +722,13 @@ get_node_subscriptions(NodeId) ->
|
||||
"where nodeid='", NodeId, "';"]) of
|
||||
{selected, ["jid", "subscriptions"], RItems} ->
|
||||
lists:foldl(fun({J, S}, Acc) ->
|
||||
Jid = decode_jid(J),
|
||||
JID = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Jid, none}|Acc];
|
||||
[{JID, none}|Acc];
|
||||
Subs ->
|
||||
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Jid, Sub, SubId}|Acc2];
|
||||
(Sub, Acc2) -> [{Jid, Sub}|Acc2]
|
||||
lists:foldl(fun({Sub, SubId}, Acc2) -> [{JID, Sub, SubId}|Acc2];
|
||||
(Sub, Acc2) -> [{JID, Sub}|Acc2]
|
||||
end, Acc, Subs)
|
||||
end
|
||||
end, [], RItems);
|
||||
@ -786,8 +779,8 @@ replace_subscription(NewSub, SubState) ->
|
||||
|
||||
replace_subscription(_, [], Acc) ->
|
||||
Acc;
|
||||
replace_subscription({Sub, SubId}, [{_, SubID} | T], Acc) ->
|
||||
replace_subscription({Sub, SubId}, T, [{Sub, SubID} | Acc]).
|
||||
replace_subscription({Sub, SubId}, [{_, SubId} | T], Acc) ->
|
||||
replace_subscription({Sub, SubId}, T, [{Sub, SubId} | Acc]).
|
||||
|
||||
new_subscription(NodeId, Owner, Subscription, SubState) ->
|
||||
case pubsub_subscription_odbc:subscribe_node(Owner, NodeId, []) of
|
||||
@ -800,13 +793,13 @@ new_subscription(NodeId, Owner, Subscription, SubState) ->
|
||||
end.
|
||||
|
||||
unsub_with_subid(NodeId, SubId, SubState) ->
|
||||
pubsub_subscription_odbc:unsubscribe_node(SubState#pubsub_state.stateid,
|
||||
pubsub_subscription_odbc:unsubscribe_node(SubState#pubsub_state.id,
|
||||
NodeId, SubId),
|
||||
NewSubs = lists:filter(fun ({_, SID}) -> SubId =/= SID end,
|
||||
SubState#pubsub_state.subscriptions),
|
||||
case {NewSubs, SubState#pubsub_state.affiliation} of
|
||||
{[], none} ->
|
||||
del_state(NodeId, element(1, SubState#pubsub_state.stateid));
|
||||
del_state(NodeId, element(1, SubState#pubsub_state.id));
|
||||
_ ->
|
||||
set_state(SubState#pubsub_state{subscriptions = NewSubs})
|
||||
end.
|
||||
@ -814,21 +807,21 @@ unsub_with_subid(NodeId, SubId, SubState) ->
|
||||
%% @spec (Host, Owner) -> {result, [Node]} | {error, Reason}
|
||||
%% Host = host()
|
||||
%% Owner = jid()
|
||||
%% Node = pubsubNode()
|
||||
%% Node = node()
|
||||
%% @doc <p>Returns a list of Owner's nodes on Host with pending
|
||||
%% subscriptions.</p>
|
||||
get_pending_nodes(Host, Owner) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'},
|
||||
States = mnesia:match_object(#pubsub_state{id = {GenKey, '_'},
|
||||
affiliation = owner,
|
||||
_ = '_'}),
|
||||
NodeIDs = [ID || #pubsub_state{stateid = {_, ID}} <- States],
|
||||
Nidxs = [Nidx || #pubsub_state{id = {_, Nidx}} <- States],
|
||||
NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of
|
||||
[{nodetree, N}] -> N;
|
||||
_ -> nodetree_tree_odbc
|
||||
end,
|
||||
Reply = mnesia:foldl(fun(#pubsub_state{stateid = {_, NID}} = S, Acc) ->
|
||||
case lists:member(NID, NodeIDs) of
|
||||
Reply = mnesia:foldl(fun(#pubsub_state{id = {_, Nidx}} = S, Acc) ->
|
||||
case lists:member(Nidx, Nidxs) of
|
||||
true ->
|
||||
case get_nodes_helper(NodeTree, S) of
|
||||
{value, Node} -> [Node | Acc];
|
||||
@ -841,7 +834,7 @@ get_pending_nodes(Host, Owner) ->
|
||||
{result, Reply}.
|
||||
|
||||
get_nodes_helper(NodeTree,
|
||||
#pubsub_state{stateid = {_, N}, subscriptions = Subs}) ->
|
||||
#pubsub_state{id = {_, N}, subscriptions = Subs}) ->
|
||||
HasPending = fun ({pending, _}) -> true;
|
||||
(pending) -> true;
|
||||
(_) -> false
|
||||
@ -849,7 +842,7 @@ get_nodes_helper(NodeTree,
|
||||
case lists:any(HasPending, Subs) of
|
||||
true ->
|
||||
case NodeTree:get_node(N) of
|
||||
#pubsub_node{nodeid = {_, Node}} ->
|
||||
#pubsub_node{id = {_, Node}} ->
|
||||
{value, Node};
|
||||
_ ->
|
||||
false
|
||||
@ -859,7 +852,7 @@ get_nodes_helper(NodeTree,
|
||||
end.
|
||||
|
||||
%% @spec (NodeId) -> {result, [State] | []}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% NodeId = nodeidx()
|
||||
%% State = mod_pubsub:pubsubState()
|
||||
%% @doc Returns the list of stored states for a given node.
|
||||
%% <p>For the default PubSub module, states are stored in Mnesia database.</p>
|
||||
@ -878,7 +871,7 @@ get_states(NodeId) ->
|
||||
"where nodeid='", NodeId, "';"]) of
|
||||
{selected, ["jid", "affiliation", "subscriptions"], RItems} ->
|
||||
{result, lists:map(fun({SJID, Affiliation, Subscriptions}) ->
|
||||
#pubsub_state{stateid = {decode_jid(SJID), NodeId},
|
||||
#pubsub_state{id = {decode_jid(SJID), NodeId},
|
||||
items = itemids(NodeId, SJID),
|
||||
affiliation = decode_affiliation(Affiliation),
|
||||
subscriptions = decode_subscriptions(Subscriptions)}
|
||||
@ -889,13 +882,13 @@ get_states(NodeId) ->
|
||||
|
||||
|
||||
%% @spec (NodeId, JID) -> [State] | []
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% JID = mod_pubsub:jid()
|
||||
%% State = mod_pubsub:pubsubItems()
|
||||
%% NodeId = nodeidx()
|
||||
%% JID = ljid()
|
||||
%% State = mod_pubsub:pubsub_state()
|
||||
%% @doc <p>Returns a state (one state list), given its reference.</p>
|
||||
get_state(NodeId, JID) ->
|
||||
State = get_state_without_itemids(NodeId, JID),
|
||||
{SJID, _} = State#pubsub_state.stateid,
|
||||
{SJID, _} = State#pubsub_state.id,
|
||||
State#pubsub_state{items = itemids(NodeId, SJID)}.
|
||||
get_state_without_itemids(NodeId, JID) ->
|
||||
J = encode_jid(JID),
|
||||
@ -905,25 +898,25 @@ get_state_without_itemids(NodeId, JID) ->
|
||||
"where jid='", J, "' "
|
||||
"and nodeid='", NodeId, "';"]) of
|
||||
{selected, ["jid", "affiliation", "subscriptions"], [{SJID, Affiliation, Subscriptions}]} ->
|
||||
#pubsub_state{stateid = {decode_jid(SJID), NodeId},
|
||||
#pubsub_state{id = {decode_jid(SJID), NodeId},
|
||||
affiliation = decode_affiliation(Affiliation),
|
||||
subscriptions = decode_subscriptions(Subscriptions)};
|
||||
_ ->
|
||||
#pubsub_state{stateid={JID, NodeId}}
|
||||
#pubsub_state{id={JID, NodeId}}
|
||||
end.
|
||||
|
||||
%% @spec (State) -> ok | {error, Reason::stanzaError()}
|
||||
%% State = mod_pubsub:pubsubStates()
|
||||
%% @doc <p>Write a state into database.</p>
|
||||
set_state(State) when is_record(State, pubsub_state) ->
|
||||
{_, NodeId} = State#pubsub_state.stateid,
|
||||
{_, NodeId} = State#pubsub_state.id,
|
||||
set_state(NodeId, State).
|
||||
set_state(NodeId, State) ->
|
||||
%% NOTE: in odbc version, as we do not handle item list,
|
||||
%% we just need to update affiliation and subscription
|
||||
%% cause {JID,NodeId} is the key. if it does not exists, then we insert it.
|
||||
%% MySQL can be optimized using INSERT ... ON DUPLICATE KEY as well
|
||||
{JID, _} = State#pubsub_state.stateid,
|
||||
{JID, _} = State#pubsub_state.id,
|
||||
J = encode_jid(JID),
|
||||
S = encode_subscriptions(State#pubsub_state.subscriptions),
|
||||
A = encode_affiliation(State#pubsub_state.affiliation),
|
||||
@ -941,7 +934,7 @@ set_state(NodeId, State) ->
|
||||
{result, []}.
|
||||
|
||||
%% @spec (NodeId, JID) -> ok | {error, Reason::stanzaError()}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% NodeId = nodeidx()
|
||||
%% @doc <p>Delete a state from database.</p>
|
||||
del_state(NodeId, JID) ->
|
||||
J = encode_jid(JID),
|
||||
@ -952,8 +945,8 @@ del_state(NodeId, JID) ->
|
||||
ok.
|
||||
|
||||
%% @spec (NodeId, From) -> {[Items], RsmOut} | []
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% Items = mod_pubsub:pubsubItems()
|
||||
%% NodeId = nodeidx()
|
||||
%% Items = mod_pubsub:pubsub_item()
|
||||
%% @doc Returns the list of stored items for a given node.
|
||||
%% <p>For the default PubSub module, items are stored in Mnesia database.</p>
|
||||
%% <p>We can consider that the pubsub_item table have been created by the main
|
||||
@ -1100,9 +1093,9 @@ get_last_items(NodeId, _From, Count) ->
|
||||
end.
|
||||
|
||||
%% @spec (NodeId, ItemId) -> [Item] | []
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% ItemId = string()
|
||||
%% Item = mod_pubsub:pubsubItems()
|
||||
%% NodeId = nodeidx()
|
||||
%% ItemId = item()
|
||||
%% Item = mod_pubsub:pubsub_item()
|
||||
%% @doc <p>Returns an item (one item list), given its reference.</p>
|
||||
get_item(NodeId, ItemId) ->
|
||||
I = ?PUBSUB:escape(ItemId),
|
||||
@ -1126,7 +1119,7 @@ get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _S
|
||||
%%SubId == "", ?? ->
|
||||
%% Entity has multiple subscriptions to the node but does not specify a subscription ID
|
||||
%{error, ?ERR_EXTENDED('bad-request', "subid-required")};
|
||||
%%InvalidSubID ->
|
||||
%%InvalidSubId ->
|
||||
%% Entity is subscribed but specifies an invalid subscription ID
|
||||
%{error, ?ERR_EXTENDED('not-acceptable', "invalid-subid")};
|
||||
Affiliation == outcast ->
|
||||
@ -1152,10 +1145,10 @@ get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _S
|
||||
end.
|
||||
|
||||
%% @spec (Item) -> ok | {error, Reason::stanzaError()}
|
||||
%% Item = mod_pubsub:pubsubItems()
|
||||
%% Item = mod_pubsub:pubsub_item()
|
||||
%% @doc <p>Write an item into database.</p>
|
||||
set_item(Item) ->
|
||||
{ItemId, NodeId} = Item#pubsub_item.itemid,
|
||||
{ItemId, NodeId} = Item#pubsub_item.id,
|
||||
I = ?PUBSUB:escape(ItemId),
|
||||
{C, _} = Item#pubsub_item.creation,
|
||||
{M, JID} = Item#pubsub_item.modification,
|
||||
@ -1182,8 +1175,8 @@ set_item(Item) ->
|
||||
{result, []}.
|
||||
|
||||
%% @spec (NodeId, ItemId) -> ok | {error, Reason::stanzaError()}
|
||||
%% NodeId = mod_pubsub:pubsubNodeId()
|
||||
%% ItemId = string()
|
||||
%% NodeId = nodeidx()
|
||||
%% ItemId = item()
|
||||
%% @doc <p>Delete an item from database.</p>
|
||||
del_item(NodeId, ItemId) ->
|
||||
I = ?PUBSUB:escape(ItemId),
|
||||
@ -1337,7 +1330,7 @@ encode_subscriptions(Subscriptions) ->
|
||||
%%% record getter/setter
|
||||
|
||||
state_to_raw(NodeId, State) ->
|
||||
{JID, _} = State#pubsub_state.stateid,
|
||||
{JID, _} = State#pubsub_state.id,
|
||||
J = encode_jid(JID),
|
||||
A = encode_affiliation(State#pubsub_state.affiliation),
|
||||
S = encode_subscriptions(State#pubsub_state.subscriptions),
|
||||
@ -1353,7 +1346,7 @@ raw_to_item(NodeId, {ItemId, SJID, Creation, Modification, XML}) ->
|
||||
{error, _Reason} -> [];
|
||||
[El] -> [El]
|
||||
end,
|
||||
#pubsub_item{itemid = {ItemId, NodeId},
|
||||
#pubsub_item{id = {ItemId, NodeId},
|
||||
creation={ToTime(Creation), JID},
|
||||
modification={ToTime(Modification), JID},
|
||||
payload = Payload}.
|
||||
|
@ -140,8 +140,8 @@ delete_node(Removed) ->
|
||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) ->
|
||||
node_flat:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_flat:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -111,8 +111,8 @@ delete_node(Removed) ->
|
||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) ->
|
||||
node_flat_odbc:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_flat_odbc:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat_odbc:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_flat_odbc:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -137,8 +137,8 @@ subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
||||
NodeId, Sender, Subscriber, AccessModel, SendLast,
|
||||
PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_pep:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_pep:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_pep:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -156,8 +156,8 @@ subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
||||
NodeId, Sender, Subscriber, AccessModel, SendLast,
|
||||
PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
case node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubID) of
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
case node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId) of
|
||||
{error, Error} -> {error, Error};
|
||||
{result, _} -> {result, []}
|
||||
end.
|
||||
@ -177,14 +177,14 @@ purge_node(NodeId, Owner) ->
|
||||
get_entity_affiliations(_Host, Owner) ->
|
||||
{_, D, _} = jlib:short_prepd_jid(Owner),
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}),
|
||||
States = mnesia:match_object(#pubsub_state{id = {GenKey, '_'}, _ = '_'}),
|
||||
NodeTree = case catch ets:lookup(gen_mod:get_module_proc(D, config), nodetree) of
|
||||
[{nodetree, N}] -> N;
|
||||
_ -> nodetree_tree
|
||||
end,
|
||||
Reply = lists:foldl(fun(#pubsub_state{stateid = {_, N}, affiliation = A}, Acc) ->
|
||||
Reply = lists:foldl(fun(#pubsub_state{id = {_, N}, affiliation = A}, Acc) ->
|
||||
case NodeTree:get_node(N) of
|
||||
#pubsub_node{nodeid = {{_, D, _}, _}} = Node -> [{Node, A}|Acc];
|
||||
#pubsub_node{id = {{_, D, _}, _}} = Node -> [{Node, A}|Acc];
|
||||
_ -> Acc
|
||||
end
|
||||
end, [], States),
|
||||
@ -204,22 +204,22 @@ get_entity_subscriptions(_Host, Owner) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
States = case SubKey of
|
||||
GenKey -> mnesia:match_object(
|
||||
#pubsub_state{stateid = {{U, D, '_'}, '_'}, _ = '_'});
|
||||
#pubsub_state{id = {{U, D, '_'}, '_'}, _ = '_'});
|
||||
_ -> mnesia:match_object(
|
||||
#pubsub_state{stateid = {GenKey, '_'}, _ = '_'})
|
||||
#pubsub_state{id = {GenKey, '_'}, _ = '_'})
|
||||
++ mnesia:match_object(
|
||||
#pubsub_state{stateid = {SubKey, '_'}, _ = '_'})
|
||||
#pubsub_state{id = {SubKey, '_'}, _ = '_'})
|
||||
end,
|
||||
NodeTree = case catch ets:lookup(gen_mod:get_module_proc(D, config), nodetree) of
|
||||
[{nodetree, N}] -> N;
|
||||
_ -> nodetree_tree
|
||||
end,
|
||||
Reply = lists:foldl(fun(#pubsub_state{stateid = {J, N}, subscriptions = Ss}, Acc) ->
|
||||
Reply = lists:foldl(fun(#pubsub_state{id = {J, N}, subscriptions = Ss}, Acc) ->
|
||||
case NodeTree:get_node(N) of
|
||||
#pubsub_node{nodeid = {{_, D, _}, _}} = Node ->
|
||||
lists:foldl(fun({subscribed, SubID}, Acc2) ->
|
||||
[{Node, subscribed, SubID, J} | Acc2];
|
||||
({pending, _SubID}, Acc2) ->
|
||||
#pubsub_node{id = {{_, D, _}, _}} = Node ->
|
||||
lists:foldl(fun({subscribed, SubId}, Acc2) ->
|
||||
[{Node, subscribed, SubId, J} | Acc2];
|
||||
({pending, _SubId}, Acc2) ->
|
||||
[{Node, pending, J} | Acc2];
|
||||
(S, Acc2) ->
|
||||
[{Node, S, J} | Acc2]
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
%%% @doc The module <strong>{@module}</strong> is the pep PubSub plugin.
|
||||
%%% <p>PubSub plugin nodes are using the {@link gen_pubsub_node} behaviour.</p>
|
||||
|
||||
%%TODO : fix SQL requests with nodeid/id and id/idx changes
|
||||
-module(node_pep_odbc).
|
||||
-author('christophe.romain@process-one.net').
|
||||
|
||||
@ -163,8 +163,8 @@ subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
||||
NodeId, Sender, Subscriber, AccessModel, SendLast,
|
||||
PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
case node_flat_odbc:unsubscribe_node(NodeId, Sender, Subscriber, SubID) of
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
case node_flat_odbc:unsubscribe_node(NodeId, Sender, Subscriber, SubId) of
|
||||
{error, Error} -> {error, Error};
|
||||
{result, _} -> {result, []}
|
||||
end.
|
||||
|
@ -133,8 +133,8 @@ subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast,
|
||||
SendLast, PresenceSubscription, RosterGroup,
|
||||
Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_flat:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -130,8 +130,8 @@ delete_node(Removed) ->
|
||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) ->
|
||||
node_flat:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options).
|
||||
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubID) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubID).
|
||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
||||
|
||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_flat:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
@ -58,26 +58,26 @@ init(Host, ServerHost, Opts) ->
|
||||
terminate(Host, ServerHost) ->
|
||||
nodetree_tree:terminate(Host, ServerHost).
|
||||
|
||||
create_node(Key, NodeID, Type, Owner, Options, Parents) ->
|
||||
create_node(Key, Node, Type, Owner, Options, Parents) ->
|
||||
OwnerJID = jlib:short_prepd_bare_jid(Owner),
|
||||
case find_node(Key, NodeID) of
|
||||
case find_node(Key, Node) of
|
||||
false ->
|
||||
ID = pubsub_index:new(node),
|
||||
N = #pubsub_node{nodeid = oid(Key, NodeID),
|
||||
id = ID,
|
||||
Nidx = pubsub_index:new(node),
|
||||
N = #pubsub_node{id = oid(Key, Node),
|
||||
idx = Nidx,
|
||||
type = Type,
|
||||
parents = Parents,
|
||||
parents = Parents,
|
||||
owners = [OwnerJID],
|
||||
options = Options},
|
||||
case set_node(N) of
|
||||
ok -> {ok, ID};
|
||||
ok -> {ok, Nidx};
|
||||
Other -> Other
|
||||
end;
|
||||
_ ->
|
||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'conflict')}
|
||||
end.
|
||||
|
||||
set_node(#pubsub_node{nodeid = {Key, _},
|
||||
set_node(#pubsub_node{id = {Key, _},
|
||||
owners = Owners,
|
||||
options = Options} = Node) ->
|
||||
Parents = find_opt(collection, ?DEFAULT_PARENTS, Options),
|
||||
@ -89,43 +89,43 @@ set_node(#pubsub_node{nodeid = {Key, _},
|
||||
Other
|
||||
end.
|
||||
|
||||
delete_node(Key, NodeID) ->
|
||||
case find_node(Key, NodeID) of
|
||||
delete_node(Key, Node) ->
|
||||
case find_node(Key, Node) of
|
||||
false ->
|
||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||
Node ->
|
||||
Record ->
|
||||
%% Find all of N's children, update their configs to
|
||||
%% remove N from the collection setting.
|
||||
lists:foreach(fun (#pubsub_node{options = Opts} = Child) ->
|
||||
NewOpts = remove_config_parent(NodeID, Opts),
|
||||
NewOpts = remove_config_parent(Node, Opts),
|
||||
Parents = find_opt(collection, ?DEFAULT_PARENTS, NewOpts),
|
||||
ok = mnesia:write(pubsub_node,
|
||||
Child#pubsub_node{
|
||||
parents = Parents,
|
||||
options = NewOpts},
|
||||
write)
|
||||
end, get_subnodes(Key, NodeID)),
|
||||
end, get_subnodes(Key, Node)),
|
||||
|
||||
%% Remove and return the requested node.
|
||||
pubsub_index:free(node, Node#pubsub_node.id),
|
||||
mnesia:delete_object(pubsub_node, Node, write),
|
||||
[Node]
|
||||
pubsub_index:free(node, Record#pubsub_node.idx),
|
||||
mnesia:delete_object(pubsub_node, Record, write),
|
||||
[Record]
|
||||
end.
|
||||
|
||||
options() ->
|
||||
nodetree_tree:options().
|
||||
|
||||
get_node(Host, NodeID, _From) ->
|
||||
get_node(Host, NodeID).
|
||||
get_node(Host, Node, _From) ->
|
||||
get_node(Host, Node).
|
||||
|
||||
get_node(Host, NodeID) ->
|
||||
case find_node(Host, NodeID) of
|
||||
get_node(Host, Node) ->
|
||||
case find_node(Host, Node) of
|
||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||
Node -> Node
|
||||
Record -> Record
|
||||
end.
|
||||
|
||||
get_node(NodeId) ->
|
||||
nodetree_tree:get_node(NodeId).
|
||||
get_node(Node) ->
|
||||
nodetree_tree:get_node(Node).
|
||||
|
||||
get_nodes(Key, From) ->
|
||||
nodetree_tree:get_nodes(Key, From).
|
||||
@ -133,49 +133,47 @@ get_nodes(Key, From) ->
|
||||
get_nodes(Key) ->
|
||||
nodetree_tree:get_nodes(Key).
|
||||
|
||||
get_parentnodes(Host, NodeID, _From) ->
|
||||
case find_node(Host, NodeID) of
|
||||
get_parentnodes(Host, Node, _From) ->
|
||||
case find_node(Host, Node) of
|
||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||
#pubsub_node{parents = Parents} ->
|
||||
Q = qlc:q([N || #pubsub_node{nodeid = {NHost, NNode}} = N <- mnesia:table(pubsub_node),
|
||||
Q = qlc:q([N || #pubsub_node{id = {NHost, NNode}} = N <- mnesia:table(pubsub_node),
|
||||
Parent <- Parents,
|
||||
Host == NHost,
|
||||
Parent == NNode]),
|
||||
qlc:e(Q)
|
||||
end.
|
||||
|
||||
get_parentnodes_tree(Host, NodeID, _From) ->
|
||||
Pred = fun (NID, #pubsub_node{nodeid = {_, NNodeID}}) ->
|
||||
NID == NNodeID
|
||||
end,
|
||||
get_parentnodes_tree(Host, Node, _From) ->
|
||||
Pred = fun (Name, #pubsub_node{id = {_, NodeName}}) -> Name == NodeName end,
|
||||
Tr = fun (#pubsub_node{parents = Parents}) -> Parents end,
|
||||
traversal_helper(Pred, Tr, Host, [NodeID]).
|
||||
traversal_helper(Pred, Tr, Host, [Node]).
|
||||
|
||||
get_subnodes(Host, NodeID, _From) ->
|
||||
get_subnodes(Host, NodeID).
|
||||
get_subnodes(Host, Node, _From) ->
|
||||
get_subnodes(Host, Node).
|
||||
|
||||
get_subnodes(Host, <<>>) ->
|
||||
get_subnodes_helper(Host, <<>>);
|
||||
get_subnodes(Host, NodeID) ->
|
||||
case find_node(Host, NodeID) of
|
||||
get_subnodes(Host, Node) ->
|
||||
case find_node(Host, Node) of
|
||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||
_ -> get_subnodes_helper(Host, NodeID)
|
||||
_ -> get_subnodes_helper(Host, Node)
|
||||
end.
|
||||
|
||||
get_subnodes_helper(Host, NodeID) ->
|
||||
Q = qlc:q([Node || #pubsub_node{nodeid = {NHost, _},
|
||||
parents = Parents} = Node <- mnesia:table(pubsub_node),
|
||||
get_subnodes_helper(Host, Node) ->
|
||||
Q = qlc:q([Record || #pubsub_node{id = {NHost, _},
|
||||
parents = Parents} = Record <- mnesia:table(pubsub_node),
|
||||
Host == NHost,
|
||||
lists:member(NodeID, Parents)]),
|
||||
lists:member(Node, Parents)]),
|
||||
qlc:e(Q).
|
||||
|
||||
get_subnodes_tree(Host, NodeID, From) ->
|
||||
Pred = fun (NID, #pubsub_node{parents = Parents}) ->
|
||||
lists:member(NID, Parents)
|
||||
get_subnodes_tree(Host, Node, From) ->
|
||||
Pred = fun (N, #pubsub_node{parents = Parents}) ->
|
||||
lists:member(N, Parents)
|
||||
end,
|
||||
Tr = fun (#pubsub_node{nodeid = {_, N}}) -> [N] end,
|
||||
traversal_helper(Pred, Tr, 1, Host, [NodeID],
|
||||
[{0, [get_node(Host, NodeID, From)]}]).
|
||||
Tr = fun (#pubsub_node{id = {_, N}}) -> [N] end,
|
||||
traversal_helper(Pred, Tr, 1, Host, [Node],
|
||||
[{0, [get_node(Host, Node, From)]}]).
|
||||
|
||||
%%====================================================================
|
||||
%% Internal functions
|
||||
@ -183,9 +181,9 @@ get_subnodes_tree(Host, NodeID, From) ->
|
||||
oid(Key, Name) -> {Key, Name}.
|
||||
|
||||
%% Key = jlib:jid() | host()
|
||||
%% NodeID = string()
|
||||
find_node(Key, NodeID) ->
|
||||
case mnesia:read(pubsub_node, oid(Key, NodeID), read) of
|
||||
%% Node = string()
|
||||
find_node(Key, Node) ->
|
||||
case mnesia:read(pubsub_node, oid(Key, Node), read) of
|
||||
[] -> false;
|
||||
[Node] -> Node
|
||||
end.
|
||||
@ -199,30 +197,30 @@ find_opt(Key, Default, Options) ->
|
||||
_ -> Default
|
||||
end.
|
||||
|
||||
traversal_helper(Pred, Tr, Host, NodeIDs) ->
|
||||
traversal_helper(Pred, Tr, 0, Host, NodeIDs, []).
|
||||
traversal_helper(Pred, Tr, Host, Nodes) ->
|
||||
traversal_helper(Pred, Tr, 0, Host, Nodes, []).
|
||||
|
||||
traversal_helper(_Pred, _Tr, _Depth, _Host, [], Acc) ->
|
||||
Acc;
|
||||
traversal_helper(Pred, Tr, Depth, Host, NodeIDs, Acc) ->
|
||||
Q = qlc:q([Node || #pubsub_node{nodeid = {NHost, _}} = Node <- mnesia:table(pubsub_node),
|
||||
NodeID <- NodeIDs,
|
||||
traversal_helper(Pred, Tr, Depth, Host, Nodes, Acc) ->
|
||||
Q = qlc:q([Record || #pubsub_node{id = {NHost, _}} = Record <- mnesia:table(pubsub_node),
|
||||
Node <- Nodes,
|
||||
Host == NHost,
|
||||
Pred(NodeID, Node)]),
|
||||
Pred(Node, Node)]),
|
||||
Nodes = qlc:e(Q),
|
||||
IDs = lists:flatmap(Tr, Nodes),
|
||||
traversal_helper(Pred, Tr, Depth + 1, Host, IDs, [{Depth, Nodes} | Acc]).
|
||||
Names = lists:flatmap(Tr, Nodes),
|
||||
traversal_helper(Pred, Tr, Depth + 1, Host, Names, [{Depth, Nodes} | Acc]).
|
||||
|
||||
remove_config_parent(NodeID, Options) ->
|
||||
remove_config_parent(NodeID, Options, []).
|
||||
remove_config_parent(Node, Options) ->
|
||||
remove_config_parent(Node, Options, []).
|
||||
|
||||
remove_config_parent(_NodeID, [], Acc) ->
|
||||
remove_config_parent(_Node, [], Acc) ->
|
||||
lists:reverse(Acc);
|
||||
remove_config_parent(NodeID, [{collection, Parents} | T], Acc) ->
|
||||
remove_config_parent(NodeID, T,
|
||||
[{collection, lists:delete(NodeID, Parents)} | Acc]);
|
||||
remove_config_parent(NodeID, [H | T], Acc) ->
|
||||
remove_config_parent(NodeID, T, [H | Acc]).
|
||||
remove_config_parent(Node, [{collection, Parents} | T], Acc) ->
|
||||
remove_config_parent(Node, T,
|
||||
[{collection, lists:delete(Node, Parents)} | Acc]);
|
||||
remove_config_parent(Node, [H | T], Acc) ->
|
||||
remove_config_parent(Node, T, [H | Acc]).
|
||||
|
||||
validate_parentage(_Key, _Owners, []) ->
|
||||
true;
|
||||
@ -230,8 +228,8 @@ validate_parentage(Key, Owners, [[] | T]) ->
|
||||
validate_parentage(Key, Owners, T);
|
||||
validate_parentage(Key, Owners, [<<>> | T]) ->
|
||||
validate_parentage(Key, Owners, T);
|
||||
validate_parentage(Key, Owners, [ParentID | T]) ->
|
||||
case find_node(Key, ParentID) of
|
||||
validate_parentage(Key, Owners, [ParentId | T]) ->
|
||||
case find_node(Key, ParentId) of
|
||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item_not_found')};
|
||||
#pubsub_node{owners = POwners, options = POptions} ->
|
||||
NodeType = find_opt(node_type, ?DEFAULT_NODETYPE, POptions),
|
||||
|
@ -78,7 +78,7 @@ init(_Host, _ServerHost, _Opts) ->
|
||||
mnesia:create_table(pubsub_node,
|
||||
[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, pubsub_node)}]),
|
||||
mnesia:add_table_index(pubsub_node, id),
|
||||
mnesia:add_table_index(pubsub_node, idx),
|
||||
NodesFields = record_info(fields, pubsub_node),
|
||||
case mnesia:table_info(pubsub_node, attributes) of
|
||||
NodesFields -> ok;
|
||||
@ -105,7 +105,7 @@ set_node(_) ->
|
||||
|
||||
%% @spec (Host, Node, From) -> pubsubNode() | {error, Reason}
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% Node = node()
|
||||
get_node(Host, Node, _From) ->
|
||||
get_node(Host, Node).
|
||||
get_node(Host, Node) ->
|
||||
@ -114,24 +114,24 @@ get_node(Host, Node) ->
|
||||
[] -> {error, 'item-not-found'};
|
||||
Error -> Error
|
||||
end.
|
||||
get_node(NodeId) ->
|
||||
case catch mnesia:index_read(pubsub_node, NodeId, #pubsub_node.id) of
|
||||
get_node(Nidx) ->
|
||||
case catch mnesia:index_read(pubsub_node, Nidx, #pubsub_node.idx) of
|
||||
[Record] when is_record(Record, pubsub_node) -> Record;
|
||||
[] -> {error, 'item-not-found'};
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
%% @spec (Host, From) -> [pubsubNode()] | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
get_nodes(Host, _From) ->
|
||||
get_nodes(Host).
|
||||
get_nodes(Host) ->
|
||||
mnesia:match_object(#pubsub_node{nodeid = {Host, '_'}, _ = '_'}).
|
||||
mnesia:match_object(#pubsub_node{id = {Host, '_'}, _ = '_'}).
|
||||
|
||||
%% @spec (Host, Node, From) -> [{Depth, Record}] | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
%% Depth = integer()
|
||||
%% Record = pubsubNode()
|
||||
%% @doc <p>Default node tree does not handle parents, return empty list.</p>
|
||||
@ -139,9 +139,9 @@ get_parentnodes(_Host, _Node, _From) ->
|
||||
[].
|
||||
|
||||
%% @spec (Host, Node, From) -> [{Depth, Record}] | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
%% Depth = integer()
|
||||
%% Record = pubsubNode()
|
||||
%% @doc <p>Default node tree does not handle parents, return a list
|
||||
@ -154,27 +154,27 @@ get_parentnodes_tree(Host, Node, From) ->
|
||||
|
||||
%% @spec (Host, Node, From) -> [pubsubNode()] | {error, Reason}
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
get_subnodes(Host, Node, _From) ->
|
||||
get_subnodes(Host, Node).
|
||||
get_subnodes(Host, <<>>) ->
|
||||
Q = qlc:q([N || #pubsub_node{nodeid = {NHost, _},
|
||||
Q = qlc:q([N || #pubsub_node{id = {NHost, _},
|
||||
parents = Parents} = N <- mnesia:table(pubsub_node),
|
||||
Host == NHost,
|
||||
Parents == []]),
|
||||
qlc:e(Q);
|
||||
get_subnodes(Host, Node) ->
|
||||
Q = qlc:q([N || #pubsub_node{nodeid = {NHost, _},
|
||||
Q = qlc:q([N || #pubsub_node{id = {NHost, _},
|
||||
parents = Parents} = N <- mnesia:table(pubsub_node),
|
||||
Host == NHost,
|
||||
lists:member(Node, Parents)]),
|
||||
qlc:e(Q).
|
||||
|
||||
%% @spec (Host, Index, From) -> [pubsubNodeIdx()] | {error, Reason}
|
||||
%% @spec (Host, Index, From) -> [nodeidx()] | {error, Reason}
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
get_subnodes_tree(Host, Node, _From) ->
|
||||
get_subnodes_tree(Host, Node).
|
||||
get_subnodes_tree(Host, Node) ->
|
||||
@ -184,7 +184,7 @@ get_subnodes_tree(Host, Node) ->
|
||||
Rec ->
|
||||
BasePlugin = list_to_atom("node_"++Rec#pubsub_node.type),
|
||||
BasePath = BasePlugin:node_to_path(Node),
|
||||
mnesia:foldl(fun(#pubsub_node{nodeid = {H, N}} = R, Acc) ->
|
||||
mnesia:foldl(fun(#pubsub_node{id = {H, N}} = R, Acc) ->
|
||||
Plugin = list_to_atom("node_"++R#pubsub_node.type),
|
||||
Path = Plugin:node_to_path(N),
|
||||
case lists:prefix(BasePath, Path) and (H == Host) of
|
||||
@ -195,10 +195,10 @@ get_subnodes_tree(Host, Node) ->
|
||||
end.
|
||||
|
||||
%% @spec (Host, Node, Type, Owner, Options, Parents) -> ok | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% NodeType = mod_pubsub:nodeType()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
%% NodeType = nodeType()
|
||||
%% Owner = ljid()
|
||||
%% Options = list()
|
||||
create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
BJID = jlib:short_prepd_bare_jid(Owner),
|
||||
@ -226,29 +226,29 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
end,
|
||||
case ParentExists of
|
||||
true ->
|
||||
NodeId = pubsub_index:new(node),
|
||||
mnesia:write(#pubsub_node{nodeid = {Host, Node},
|
||||
id = NodeId,
|
||||
Nidx = pubsub_index:new(node),
|
||||
mnesia:write(#pubsub_node{id = {Host, Node},
|
||||
idx = Nidx,
|
||||
parents = Parents,
|
||||
type = Type,
|
||||
owners = [BJID],
|
||||
options = Options}),
|
||||
{ok, NodeId};
|
||||
{ok, Nidx};
|
||||
false ->
|
||||
%% Requesting entity is prohibited from creating nodes
|
||||
{error, 'forbidden'}
|
||||
end;
|
||||
_ ->
|
||||
%% NodeID already exists
|
||||
%% Node already exists
|
||||
{error, 'conflict'}
|
||||
end.
|
||||
|
||||
%% @spec (Host, Node) -> [mod_pubsub:node()]
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
delete_node(Host, Node) ->
|
||||
Removed = get_subnodes_tree(Host, Node),
|
||||
lists:foreach(fun(#pubsub_node{nodeid = {_, N}, id = I}) ->
|
||||
lists:foreach(fun(#pubsub_node{id = {_, N}, idx = I}) ->
|
||||
pubsub_index:free(node, I),
|
||||
mnesia:delete({pubsub_node, {Host, N}})
|
||||
end, Removed),
|
||||
|
@ -32,7 +32,6 @@
|
||||
%%% development is still a work in progress. However, the system is already
|
||||
%%% useable and useful as is. Please, send us comments, feedback and
|
||||
%%% improvements.</p>
|
||||
|
||||
-module(nodetree_tree_odbc).
|
||||
-author('christophe.romain@process-one.net').
|
||||
|
||||
@ -84,16 +83,16 @@ terminate(_Host, _ServerHost) ->
|
||||
ok.
|
||||
|
||||
%% @spec () -> [Option]
|
||||
%% Option = mod_pubsub:nodetreeOption()
|
||||
%% Option = nodetreeOption()
|
||||
%% @doc Returns the default pubsub node tree options.
|
||||
options() ->
|
||||
[{virtual_tree, false},
|
||||
{odbc, true}].
|
||||
|
||||
|
||||
%% @spec (Host, Node, From) -> pubsubNode() | {error, Reason}
|
||||
%% @spec (Host, Node, From) -> node() | {error, Reason}
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% Node = node()
|
||||
get_node(Host, Node, _From) ->
|
||||
get_node(Host, Node).
|
||||
get_node(Host, Node) ->
|
||||
@ -111,22 +110,22 @@ get_node(Host, Node) ->
|
||||
_ ->
|
||||
{error, 'item_not_found'}
|
||||
end.
|
||||
get_node(NodeId) ->
|
||||
get_node(Nidx) ->
|
||||
case catch ejabberd_odbc:sql_query_t(
|
||||
["select host, node, parent, type "
|
||||
"from pubsub_node "
|
||||
"where nodeid='", NodeId, "';"])
|
||||
"where nodeid='", Nidx, "';"])
|
||||
of
|
||||
{selected, ["host", "node", "parent", "type"], [{Host, Node, Parent, Type}]} ->
|
||||
raw_to_node(Host, {Node, Parent, Type, NodeId});
|
||||
raw_to_node(Host, {Node, Parent, Type, Nidx});
|
||||
{'EXIT', _Reason} ->
|
||||
{error, 'internal_server_error'};
|
||||
_ ->
|
||||
{error, 'item_not_found'}
|
||||
end.
|
||||
|
||||
%% @spec (Host, From) -> [pubsubNode()] | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% @spec (Host, From) -> [node()] | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
get_nodes(Host, _From) ->
|
||||
get_nodes(Host).
|
||||
get_nodes(Host) ->
|
||||
@ -143,21 +142,21 @@ get_nodes(Host) ->
|
||||
end.
|
||||
|
||||
%% @spec (Host, Node, From) -> [{Depth, Record}] | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Depth = integer()
|
||||
%% Record = pubsubNode()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
%% Depth = int()
|
||||
%% Record = mod_pubsub:pubsub_node()
|
||||
%% @doc <p>Default node tree does not handle parents, return empty list.</p>
|
||||
get_parentnodes(_Host, _Node, _From) ->
|
||||
[].
|
||||
|
||||
%% @spec (Host, Node, From) -> [{Depth, Record}] | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Depth = integer()
|
||||
%% Record = pubsubNode()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
%% Depth = int()
|
||||
%% Record = mod_pubsub:pubsub_node()
|
||||
%% @doc <p>Default node tree does not handle parents, return a list
|
||||
%% containing just this node.</p>
|
||||
get_parentnodes_tree(Host, Node, From) ->
|
||||
@ -182,10 +181,10 @@ get_subnodes(Host, Node) ->
|
||||
[]
|
||||
end.
|
||||
|
||||
%% @spec (Host, Index, From) -> [pubsubNodeIdx()] | {error, Reason}
|
||||
%% @spec (Host, Index, From) -> [nodeidx()] | {error, Reason}
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
get_subnodes_tree(Host, Node, _From) ->
|
||||
get_subnodes_tree(Host, Node).
|
||||
get_subnodes_tree(Host, Node) ->
|
||||
@ -203,10 +202,10 @@ get_subnodes_tree(Host, Node) ->
|
||||
end.
|
||||
|
||||
%% @spec (Host, Node, Type, Owner, Options, Parents) -> ok | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% NodeType = mod_pubsub:nodeType()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
%% NodeType = nodeType()
|
||||
%% Owner = ljid()
|
||||
%% Options = list()
|
||||
create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
BJID = jlib:short_prepd_bare_jid(Owner),
|
||||
@ -223,9 +222,9 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
true;
|
||||
[Parent | _] ->
|
||||
case nodeid(Host, Parent) of
|
||||
{result, PNodeId} ->
|
||||
{result, Pidx} ->
|
||||
BHost = list_to_binary(Host),
|
||||
case nodeowners(PNodeId) of
|
||||
case nodeowners(Pidx) of
|
||||
[{undefined, BHost, undefined}] -> true;
|
||||
Owners -> lists:member(BJID, Owners)
|
||||
end;
|
||||
@ -239,11 +238,11 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
case ParentExists of
|
||||
true ->
|
||||
case set_node(#pubsub_node{
|
||||
nodeid={Host, Node},
|
||||
id={Host, Node},
|
||||
parents=Parents,
|
||||
type=Type,
|
||||
options=Options}) of
|
||||
{result, NodeId} -> {ok, NodeId};
|
||||
{result, Nidx} -> {ok, Nidx};
|
||||
Other -> Other
|
||||
end;
|
||||
false ->
|
||||
@ -251,16 +250,16 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
{error, 'forbidden'}
|
||||
end;
|
||||
{result, _} ->
|
||||
%% NodeID already exists
|
||||
%% Node already exists
|
||||
{error, 'conflict'};
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
|
||||
%% @spec (Host, Node) -> [mod_pubsub:node()]
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% @spec (Host, Node) -> [node()]
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% Node = node()
|
||||
delete_node(Host, Node) ->
|
||||
H = ?PUBSUB:escape(Host),
|
||||
N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)),
|
||||
@ -273,11 +272,11 @@ delete_node(Host, Node) ->
|
||||
|
||||
%% helpers
|
||||
|
||||
raw_to_node(Host, {Node, Parent, Type, NodeId}) ->
|
||||
raw_to_node(Host, {Node, Parent, Type, Nidx}) ->
|
||||
Options = case catch ejabberd_odbc:sql_query_t(
|
||||
["select name,val "
|
||||
"from pubsub_node_option "
|
||||
"where nodeid='", NodeId, "';"])
|
||||
"where nodeid='", Nidx, "';"])
|
||||
of
|
||||
{selected, ["name", "val"], ROptions} ->
|
||||
DbOpts = lists:map(fun({Key, Value}) ->
|
||||
@ -295,16 +294,16 @@ raw_to_node(Host, {Node, Parent, Type, NodeId}) ->
|
||||
[]
|
||||
end,
|
||||
#pubsub_node{
|
||||
nodeid = {Host, ?PUBSUB:string_to_node(Node)},
|
||||
id = {Host, ?PUBSUB:string_to_node(Node)},
|
||||
parents = [?PUBSUB:string_to_node(Parent)],
|
||||
id = NodeId,
|
||||
idx = Nidx,
|
||||
type = Type,
|
||||
options = Options}.
|
||||
|
||||
%% @spec (NodeRecord) -> ok | {error, Reason}
|
||||
%% Record = mod_pubsub:pubsub_node()
|
||||
set_node(Record) ->
|
||||
{Host, Node} = Record#pubsub_node.nodeid,
|
||||
{Host, Node} = Record#pubsub_node.id,
|
||||
Parent = case Record#pubsub_node.parents of
|
||||
[] -> <<>>;
|
||||
[First | _] -> First
|
||||
@ -313,29 +312,29 @@ set_node(Record) ->
|
||||
H = ?PUBSUB:escape(Host),
|
||||
N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)),
|
||||
P = ?PUBSUB:escape(?PUBSUB:node_to_string(Parent)),
|
||||
NodeId = case nodeid(Host, Node) of
|
||||
{result, OldNodeId} ->
|
||||
Nidx = case nodeid(Host, Node) of
|
||||
{result, OldNidx} ->
|
||||
catch ejabberd_odbc:sql_query_t(
|
||||
["delete from pubsub_node_option "
|
||||
"where nodeid='", OldNodeId, "';"]),
|
||||
"where nodeid='", OldNidx, "';"]),
|
||||
catch ejabberd_odbc:sql_query_t(
|
||||
["update pubsub_node "
|
||||
"set host='", H, "' "
|
||||
"node='", N, "' "
|
||||
"parent='", P, "' "
|
||||
"type='", Type, "' "
|
||||
"where nodeid='", OldNodeId, "';"]),
|
||||
OldNodeId;
|
||||
"where nodeid='", OldNidx, "';"]),
|
||||
OldNidx;
|
||||
_ ->
|
||||
catch ejabberd_odbc:sql_query_t(
|
||||
["insert into pubsub_node(host, node, parent, type) "
|
||||
"values('", H, "', '", N, "', '", P, "', '", Type, "');"]),
|
||||
case nodeid(Host, Node) of
|
||||
{result, NewNodeId} -> NewNodeId;
|
||||
_ -> none % this should not happen
|
||||
{result, NewNidx} -> NewNidx;
|
||||
_ -> none % this should not happe
|
||||
end
|
||||
end,
|
||||
case NodeId of
|
||||
case Nidx of
|
||||
none ->
|
||||
{error, 'internal_server_error'};
|
||||
_ ->
|
||||
@ -344,9 +343,9 @@ set_node(Record) ->
|
||||
SValue = ?PUBSUB:escape(lists:flatten(io_lib:fwrite("~p",[Value]))),
|
||||
catch ejabberd_odbc:sql_query_t(
|
||||
["insert into pubsub_node_option(nodeid, name, val) "
|
||||
"values('", NodeId, "', '", SKey, "', '", SValue, "');"])
|
||||
"values('", Nidx, "', '", SKey, "', '", SValue, "');"])
|
||||
end, Record#pubsub_node.options),
|
||||
{result, NodeId}
|
||||
{result, Nidx}
|
||||
end.
|
||||
|
||||
nodeid(Host, Node) ->
|
||||
@ -357,16 +356,16 @@ nodeid(Host, Node) ->
|
||||
"from pubsub_node "
|
||||
"where host='", H, "' and node='", N, "';"])
|
||||
of
|
||||
{selected, ["nodeid"], [{NodeId}]} ->
|
||||
{result, NodeId};
|
||||
{selected, ["nodeid"], [{Nidx}]} ->
|
||||
{result, Nidx};
|
||||
{'EXIT', _Reason} ->
|
||||
{error, 'internal_server_error'};
|
||||
_ ->
|
||||
{error, 'item_not_found'}
|
||||
end.
|
||||
|
||||
nodeowners(NodeId) ->
|
||||
{result, Res} = node_flat_odbc:get_node_affiliations(NodeId),
|
||||
nodeowners(Nidx) ->
|
||||
{result, Res} = node_flat_odbc:get_node_affiliations(Nidx),
|
||||
lists:foldl(fun({LJID, owner}, Acc) -> [LJID|Acc];
|
||||
(_, Acc) -> Acc
|
||||
end, [], Res).
|
||||
|
@ -86,18 +86,19 @@ set_node(_NodeRecord) ->
|
||||
|
||||
%% @spec (Host, Node, From) -> pubsubNode()
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% Node = node()
|
||||
%% @doc <p>Virtual node tree does not handle a node database. Any node is considered
|
||||
%% as existing. Node record contains default values.</p>
|
||||
get_node(Host, Node, _From) ->
|
||||
get_node(Host, Node).
|
||||
get_node(Host, Node) ->
|
||||
#pubsub_node{nodeid = {Host, Node}, id = {Host, Node}, owners = [{undefined, list_to_binary(Host), undefined}]}.
|
||||
%% TODO : to fix idx
|
||||
#pubsub_node{id = {Host, Node}, idx = {Host, Node}, owners = [{undefined, list_to_binary(Host), undefined}]}.
|
||||
get_node({Host, _} = NodeId) ->
|
||||
#pubsub_node{nodeid = NodeId, id = NodeId, owners = [{undefined, list_to_binary(Host), undefined}]}.
|
||||
#pubsub_node{id = NodeId, idx = NodeId, owners = [{undefined, list_to_binary(Host), undefined}]}.
|
||||
|
||||
%% @spec (Host, From) -> [pubsubNode()]
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
%% Host = mod_pubsub:host() | ljid()
|
||||
%% @doc <p>Virtual node tree does not handle a node database. Any node is considered
|
||||
%% as existing. Nodes list can not be determined.</p>
|
||||
get_nodes(Host, _From) ->
|
||||
@ -107,8 +108,8 @@ get_nodes(_Host) ->
|
||||
|
||||
%% @spec (Host, Node, From) -> [pubsubNode()]
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
%% Node = node()
|
||||
%% From = ljid()
|
||||
%% @doc <p>Virtual node tree does not handle parent/child. Child list is empty.</p>
|
||||
get_subnodes(Host, Node, _From) ->
|
||||
get_subnodes(Host, Node).
|
||||
@ -117,7 +118,7 @@ get_subnodes(_Host, _Node) ->
|
||||
|
||||
%% @spec (Host, Index, From) -> [pubsubNode()]
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% Node = node()
|
||||
%% @doc <p>Virtual node tree does not handle parent/child. Child list is empty.</p>
|
||||
get_subnodes_tree(Host, Node, _From) ->
|
||||
get_subnodes_tree(Host, Node).
|
||||
@ -126,9 +127,9 @@ get_subnodes_tree(_Host, _Node) ->
|
||||
|
||||
%% @spec (Host, Node, Type, Owner, Options, Parents) -> ok
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% Type = mod_pubsub:nodeType()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Node = node()
|
||||
%% Type = nodeType()
|
||||
%% Owner = ljid()
|
||||
%% Options = list()
|
||||
%% @doc <p>No node record is stored on database. Any valid node
|
||||
%% is considered as already created.</p>
|
||||
@ -143,7 +144,7 @@ create_node(Host, Node, _Type, Owner, _Options, _Parents) ->
|
||||
|
||||
%% @spec (Host, Node) -> [mod_pubsub:node()]
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% Node = node()
|
||||
%% @doc <p>Virtual node tree does not handle parent/child.
|
||||
%% node deletion just affects the corresponding node.</p>
|
||||
delete_node(Host, Node) ->
|
||||
|
@ -35,14 +35,25 @@
|
||||
%% -------------------------------
|
||||
%% Pubsub types
|
||||
|
||||
%%% @type host() = string().
|
||||
%%% @type host() = binary().
|
||||
%%% <p><tt>host</tt> is the name of the PubSub service. For example, it can be
|
||||
%%% <tt>"pubsub.localhost"</tt>.</p>
|
||||
%%% <tt>pubsub.localhost</tt>.</p>
|
||||
|
||||
%%% @type pubsubNode() = [string()].
|
||||
%%% <p>A node is defined by a list of its ancestors. The last element is the name
|
||||
%%% of the current node. For example:
|
||||
%%% ```["home", "localhost", "cromain", "node1"]'''</p>
|
||||
%%% @type node() = binary().
|
||||
%%% <p>A <tt>node</tt> is the name of a Node. It can be anything and may represent
|
||||
%%% some hierarchical tree depending of the node type.
|
||||
%%% For example:
|
||||
%%% /home/localhost/user/node
|
||||
%%% princely_musings
|
||||
%%% http://jabber.org/protocol/tune
|
||||
%%% My-Own_Node</p>
|
||||
|
||||
%%% @type item() = binary().
|
||||
%%% <p>An <tt>item</tt> is the name of an Item. It can be anything.
|
||||
%%% For example:
|
||||
%%% 38964
|
||||
%%% my-tune
|
||||
%%% FD6SBE6a27d</p>
|
||||
|
||||
%%% @type stanzaError() = #xmlel{}.
|
||||
%%% Example:
|
||||
@ -82,34 +93,29 @@
|
||||
%%% plugin to use to manage a given node. For example, it can be
|
||||
%%% <tt>"flat"</tt>, <tt>"hometree"</tt> or <tt>"blog"</tt>.</p>
|
||||
|
||||
%%% @type jid() = #jid{
|
||||
%%% user = string(),
|
||||
%%% server = string(),
|
||||
%%% resource = string(),
|
||||
%%% luser = string(),
|
||||
%%% lserver = string(),
|
||||
%%% lresource = string()}.
|
||||
%%% @type ljid() = {User::binary(), Server::binary(), Resource::binary()}.
|
||||
|
||||
%%% @type ljid() = {User::string(), Server::string(), Resource::string()}.
|
||||
%%% @type nodeidx() = int()
|
||||
|
||||
%%% @type affiliation() = none | owner | publisher | outcast.
|
||||
%%% @type affiliation() = none | owner | publisher | member | outcast.
|
||||
%%% @type subscription() = none | pending | unconfigured | subscribed.
|
||||
|
||||
%%% internal pubsub index table
|
||||
-record(pubsub_index, {index, last, free}).
|
||||
|
||||
%%% @type pubsubNode() = #pubsub_node{
|
||||
%%% nodeid = {Host::host(), Node::pubsubNode()},
|
||||
%%% parentid = Node::pubsubNode(),
|
||||
%%% nodeidx = int(),
|
||||
%%% id = {host(), node()},
|
||||
%%% idx = nodeidx(),
|
||||
%%% parents = [Node::pubsubNode()],
|
||||
%%% type = nodeType(),
|
||||
%%% owners = [ljid()],
|
||||
%%% options = [nodeOption()]}.
|
||||
%%% <p>This is the format of the <tt>nodes</tt> table. The type of the table
|
||||
%%% is: <tt>set</tt>,<tt>ram/disc</tt>.</p>
|
||||
%%% <p>The <tt>parentid</tt> and <tt>type</tt> fields are indexed.</p>
|
||||
%%% <p><tt>nodeidx</tt> can be anything you want.</p>
|
||||
-record(pubsub_node, {nodeid,
|
||||
id,
|
||||
%%% <p>The <tt>parents</tt> and <tt>type</tt> fields are indexed.</p>
|
||||
%%% <p><tt>nodeidx</tt> is an integer.</p>
|
||||
-record(pubsub_node, {id,
|
||||
idx,
|
||||
parents = [],
|
||||
type = "flat",
|
||||
owners = [],
|
||||
@ -117,26 +123,26 @@
|
||||
}).
|
||||
|
||||
%%% @type pubsubState() = #pubsub_state{
|
||||
%%% stateid = {ljid(), nodeidx()},
|
||||
%%% items = [ItemId::string()],
|
||||
%%% id = {ljid(), nodeidx()},
|
||||
%%% items = [item()],
|
||||
%%% affiliation = affiliation(),
|
||||
%%% subscriptions = [subscription()]}.
|
||||
%%% <p>This is the format of the <tt>affiliations</tt> table. The type of the
|
||||
%%% table is: <tt>set</tt>,<tt>ram/disc</tt>.</p>
|
||||
-record(pubsub_state, {stateid,
|
||||
-record(pubsub_state, {id,
|
||||
items = [],
|
||||
affiliation = none,
|
||||
subscriptions = []
|
||||
}).
|
||||
|
||||
%%% @type pubsubItem() = #pubsub_item{
|
||||
%%% itemid = {ItemId::string(), nodeidx()},
|
||||
%%% id = {item(), nodeidx()},
|
||||
%%% creation = {now(), ljid()},
|
||||
%%% modification = {now(), ljid()},
|
||||
%%% payload = XMLContent::string()}.
|
||||
%%% <p>This is the format of the <tt>published items</tt> table. The type of the
|
||||
%%% table is: <tt>set</tt>,<tt>disc</tt>,<tt>fragmented</tt>.</p>
|
||||
-record(pubsub_item, {itemid,
|
||||
-record(pubsub_item, {id,
|
||||
creation = {unknown,unknown},
|
||||
modification = {unknown,unknown},
|
||||
payload = []
|
||||
@ -144,7 +150,7 @@
|
||||
|
||||
%% @type pubsubSubscription() = #pubsub_subscription{
|
||||
%% subid = string(),
|
||||
%% state_key = {ljid(), pubsubNodeId()},
|
||||
%% state_key = {ljid(), nodeidx()},
|
||||
%% options = [{atom(), term()}]
|
||||
%% }.
|
||||
%% <p>This is the format of the <tt>subscriptions</tt> table. The type of the
|
||||
@ -153,7 +159,7 @@
|
||||
|
||||
%% @type pubsubLastItem() = #pubsub_last_item{
|
||||
%% nodeid = nodeidx(),
|
||||
%% itemid = string(),
|
||||
%% itemid = item(),
|
||||
%% creation = {now(), ljid()},
|
||||
%% payload = XMLContent::string()}.
|
||||
%% <p>This is the format of the <tt>last items</tt> table. it stores last item payload
|
||||
|
@ -32,27 +32,27 @@
|
||||
|
||||
%% Those -spec lines produce errors in old Erlang versions.
|
||||
%% They can be enabled again in ejabberd 3.0 because it uses R12B or higher.
|
||||
-spec read_subscription(SubID :: string()) -> {ok, #pubsub_subscription{}} | notfound.
|
||||
read_subscription(SubID) ->
|
||||
-spec read_subscription(SubId :: string()) -> {ok, #pubsub_subscription{}} | notfound.
|
||||
read_subscription(SubId) ->
|
||||
case ejabberd_odbc:sql_query_t(
|
||||
["select opt_name, opt_value "
|
||||
"from pubsub_subscription_opt "
|
||||
"where subid = '", ejabberd_odbc:escape(SubID), "'"]) of
|
||||
"where subid = '", ejabberd_odbc:escape(SubId), "'"]) of
|
||||
{selected, ["opt_name", "opt_value"], []} ->
|
||||
notfound;
|
||||
|
||||
{selected, ["opt_name", "opt_value"], Options} ->
|
||||
|
||||
{ok, #pubsub_subscription{subid = SubID,
|
||||
{ok, #pubsub_subscription{subid = SubId,
|
||||
options = lists:map(fun subscription_opt_from_odbc/1, Options)}}
|
||||
end.
|
||||
|
||||
|
||||
|
||||
-spec delete_subscription(SubID :: string()) -> ok.
|
||||
delete_subscription(SubID) ->
|
||||
-spec delete_subscription(SubId :: string()) -> ok.
|
||||
delete_subscription(SubId) ->
|
||||
ejabberd_odbc:sql_query_t(["delete from pubsub_subscription_opt "
|
||||
"where subid = '", ejabberd_odbc:escape(SubID), "'"]),
|
||||
"where subid = '", ejabberd_odbc:escape(SubId), "'"]),
|
||||
ok.
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- mod_pubsub.erl 2010-08-04 18:28:18.000000000 +0200
|
||||
+++ mod_pubsub_odbc.erl 2010-08-04 18:29:41.000000000 +0200
|
||||
--- mod_pubsub.erl 2010-09-10 18:04:47.000000000 +0200
|
||||
+++ mod_pubsub_odbc.erl 2010-09-10 19:43:53.000000000 +0200
|
||||
@@ -42,7 +42,7 @@
|
||||
%%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see
|
||||
%%% XEP-0060 section 12.18.
|
||||
@ -49,7 +49,7 @@
|
||||
init_nodes(Host, ServerHost, NodeTree, Plugins),
|
||||
State = #state{host = Host,
|
||||
server_host = ServerHost,
|
||||
@@ -280,206 +278,15 @@
|
||||
@@ -280,209 +278,14 @@
|
||||
|
||||
init_nodes(Host, ServerHost, _NodeTree, Plugins) ->
|
||||
%% TODO, this call should be done plugin side
|
||||
@ -59,7 +59,7 @@
|
||||
- create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree"),
|
||||
- create_node(Host, ServerHost, string_to_node("/home/" ++ ServerHost), service_jid(Host), "hometree");
|
||||
+ create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree_odbc"),
|
||||
+ create_node(Host, ServerHost, string_to_node("/home/" ++ ServerHost), service_jid(Host), "hometree_odbc");
|
||||
+ create_node(Host, ServerHost, string_to_node("/home/" ++ ServerHost), service_jid(Host), "hometree_odbc");
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
@ -72,18 +72,18 @@
|
||||
- ?INFO_MSG("upgrade node pubsub tables",[]),
|
||||
- F = fun() ->
|
||||
- {Result, LastIdx} = lists:foldl(
|
||||
- fun({pubsub_node, NodeId, ParentId, {nodeinfo, Items, Options, Entities}}, {RecList, NodeIdx}) ->
|
||||
- fun({pubsub_node, NodeId, ParentId, {nodeinfo, Items, Options, Entities}}, {RecList, Nidx}) ->
|
||||
- ItemsList =
|
||||
- lists:foldl(
|
||||
- fun({item, IID, Publisher, Payload}, Acc) ->
|
||||
- fun({item, ItemName, Publisher, Payload}, Acc) ->
|
||||
- C = {unknown, Publisher},
|
||||
- M = {now(), Publisher},
|
||||
- mnesia:write(
|
||||
- #pubsub_item{itemid = {IID, NodeIdx},
|
||||
- #pubsub_item{id = {ItemName, Nidx},
|
||||
- creation = C,
|
||||
- modification = M,
|
||||
- payload = Payload}),
|
||||
- [{Publisher, IID} | Acc]
|
||||
- [{Publisher, ItemName} | Acc]
|
||||
- end, [], Items),
|
||||
- Owners =
|
||||
- dict:fold(
|
||||
@ -97,7 +97,7 @@
|
||||
- end
|
||||
- end, [], ItemsList),
|
||||
- mnesia:write({pubsub_state,
|
||||
- {JID, NodeIdx},
|
||||
- {JID, Nidx},
|
||||
- UsrItems,
|
||||
- Aff,
|
||||
- Sub}),
|
||||
@ -107,12 +107,12 @@
|
||||
- end
|
||||
- end, [], Entities),
|
||||
- mnesia:delete({pubsub_node, NodeId}),
|
||||
- {[#pubsub_node{nodeid = NodeId,
|
||||
- id = NodeIdx,
|
||||
- {[#pubsub_node{id = NodeId,
|
||||
- idx = Nidx,
|
||||
- parents = [element(2, ParentId)],
|
||||
- owners = Owners,
|
||||
- options = Options} |
|
||||
- RecList], NodeIdx + 1}
|
||||
- RecList], Nidx + 1}
|
||||
- end, {[], 1},
|
||||
- mnesia:match_object(
|
||||
- {pubsub_node, {Host, '_'}, '_', '_'})),
|
||||
@ -137,32 +137,33 @@
|
||||
- [nodeid, parentid, type, owners, options] ->
|
||||
- F = fun({pubsub_node, NodeId, {_, Parent}, Type, Owners, Options}) ->
|
||||
- #pubsub_node{
|
||||
- nodeid = NodeId,
|
||||
- id = 0,
|
||||
- id = NodeId,
|
||||
- idx = 0,
|
||||
- parents = [Parent],
|
||||
- type = Type,
|
||||
- owners = Owners,
|
||||
- options = Options}
|
||||
- end,
|
||||
- %% TODO : to change nodeid/id and id/idx or not to change ?
|
||||
- mnesia:transform_table(pubsub_node, F, [nodeid, id, parents, type, owners, options]),
|
||||
- FNew = fun() ->
|
||||
- LastIdx = lists:foldl(fun(#pubsub_node{nodeid = NodeId} = PubsubNode, NodeIdx) ->
|
||||
- mnesia:write(PubsubNode#pubsub_node{id = NodeIdx}),
|
||||
- lists:foreach(fun(#pubsub_state{stateid = StateId} = State) ->
|
||||
- LastIdx = lists:foldl(fun(#pubsub_node{id = NodeId} = PubsubNode, Nidx) ->
|
||||
- mnesia:write(PubsubNode#pubsub_node{idx = Nidx}),
|
||||
- lists:foreach(fun(#pubsub_state{id = StateId} = State) ->
|
||||
- {JID, _} = StateId,
|
||||
- mnesia:delete({pubsub_state, StateId}),
|
||||
- mnesia:write(State#pubsub_state{stateid = {JID, NodeIdx}})
|
||||
- end, mnesia:match_object(#pubsub_state{stateid = {'_', NodeId}, _ = '_'})),
|
||||
- lists:foreach(fun(#pubsub_item{itemid = ItemId} = Item) ->
|
||||
- {IID, _} = ItemId,
|
||||
- mnesia:write(State#pubsub_state{id = {JID, Nidx}})
|
||||
- end, mnesia:match_object(#pubsub_state{id = {'_', NodeId}, _ = '_'})),
|
||||
- lists:foreach(fun(#pubsub_item{id = ItemId} = Item) ->
|
||||
- {ItemName, _} = ItemId,
|
||||
- {M1, M2} = Item#pubsub_item.modification,
|
||||
- {C1, C2} = Item#pubsub_item.creation,
|
||||
- mnesia:delete({pubsub_item, ItemId}),
|
||||
- mnesia:write(Item#pubsub_item{itemid = {IID, NodeIdx},
|
||||
- mnesia:write(Item#pubsub_item{id = {ItemName, Nidx},
|
||||
- modification = {M2, M1},
|
||||
- creation = {C2, C1}})
|
||||
- end, mnesia:match_object(#pubsub_item{itemid = {'_', NodeId}, _ = '_'})),
|
||||
- NodeIdx + 1
|
||||
- end, mnesia:match_object(#pubsub_item{id = {'_', NodeId}, _ = '_'})),
|
||||
- Nidx + 1
|
||||
- end, 1, mnesia:match_object(
|
||||
- {pubsub_node, {Host, '_'}, '_', '_', '_', '_', '_'})
|
||||
- ++ mnesia:match_object(
|
||||
@ -179,13 +180,14 @@
|
||||
- [nodeid, id, parent, type, owners, options] ->
|
||||
- F = fun({pubsub_node, NodeId, Id, Parent, Type, Owners, Options}) ->
|
||||
- #pubsub_node{
|
||||
- nodeid = NodeId,
|
||||
- id = Id,
|
||||
- id = NodeId,
|
||||
- idx = Id,
|
||||
- parents = [Parent],
|
||||
- type = Type,
|
||||
- owners = Owners,
|
||||
- options = Options}
|
||||
- end,
|
||||
- %% TODO : to change nodeid/id and id/idx or not to change ?
|
||||
- mnesia:transform_table(pubsub_node, F, [nodeid, id, parents, type, owners, options]),
|
||||
- rename_default_nodeplugin();
|
||||
- _ ->
|
||||
@ -203,7 +205,7 @@
|
||||
- [<<>>] -> [];
|
||||
- Parents -> Parents
|
||||
- end,
|
||||
- mnesia:write(Node#pubsub_node{nodeid={H, BN}, parents=BP}),
|
||||
- mnesia:write(Node#pubsub_node{id={H, BN}, parents=BP}),
|
||||
- mnesia:delete({pubsub_node, {H, N}});
|
||||
- (_) ->
|
||||
- ok
|
||||
@ -222,15 +224,15 @@
|
||||
- case catch mnesia:table_info(pubsub_state, attributes) of
|
||||
- [stateid, items, affiliation, subscription] ->
|
||||
- ?INFO_MSG("upgrade state pubsub tables", []),
|
||||
- F = fun ({pubsub_state, {JID, NodeID}, Items, Aff, Sub}, Acc) ->
|
||||
- F = fun ({pubsub_state, {JID, NodeId}, Items, Aff, Sub}, Acc) ->
|
||||
- Subs = case Sub of
|
||||
- none ->
|
||||
- [];
|
||||
- _ ->
|
||||
- {result, SubID} = pubsub_subscription:subscribe_node(JID, NodeID, []),
|
||||
- [{Sub, SubID}]
|
||||
- {result, SubId} = pubsub_subscription:subscribe_node(JID, NodeId, []),
|
||||
- [{Sub, SubId}]
|
||||
- end,
|
||||
- NewState = #pubsub_state{stateid = {JID, NodeID},
|
||||
- NewState = #pubsub_state{id = {JID, NodeId},
|
||||
- items = Items,
|
||||
- affiliation = Aff,
|
||||
- subscriptions = Subs},
|
||||
@ -256,11 +258,11 @@
|
||||
- _ ->
|
||||
- ok
|
||||
- end.
|
||||
+
|
||||
|
||||
-
|
||||
send_loop(State) ->
|
||||
receive
|
||||
@@ -491,7 +298,10 @@
|
||||
{presence, JID, Pid} ->
|
||||
@@ -493,7 +296,10 @@
|
||||
%% for each node From is subscribed to
|
||||
%% and if the node is so configured, send the last published item to From
|
||||
lists:foreach(fun(PType) ->
|
||||
@ -272,37 +274,37 @@
|
||||
lists:foreach(
|
||||
fun({Node, subscribed, _, SubJID}) ->
|
||||
if (SubJID == LJID) or (SubJID == BJID) ->
|
||||
@@ -616,7 +426,8 @@
|
||||
@@ -618,7 +424,8 @@
|
||||
[#xmlel{name = 'identity', ns = ?NS_DISCO_INFO,
|
||||
attrs = [?XMLATTR('category', <<"pubsub">>), ?XMLATTR('type', <<"pep">>)]}];
|
||||
disco_identity(Host, Node, From) ->
|
||||
- Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Idx),
|
||||
case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
|
||||
- Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
|
||||
{result, _} ->
|
||||
{result,
|
||||
@@ -647,7 +458,8 @@
|
||||
@@ -649,7 +456,8 @@
|
||||
[?NS_PUBSUB_s
|
||||
| [?NS_PUBSUB_s++"#"++Feature || Feature <- features("pep")]];
|
||||
disco_features(Host, Node, From) ->
|
||||
- Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Idx),
|
||||
case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
|
||||
- Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
|
||||
{result, _} ->
|
||||
{result, [?NS_PUBSUB_s
|
||||
@@ -666,7 +478,8 @@
|
||||
@@ -668,7 +476,8 @@
|
||||
{result, disco_items(To, Node, From) ++ OtherItems}.
|
||||
|
||||
disco_items(Host, <<>>, From) ->
|
||||
- Action = fun(#pubsub_node{nodeid ={_, NodeID}, options = Options, type = Type, id = Idx, owners = Owners}, Acc) ->
|
||||
+ Action = fun(#pubsub_node{nodeid ={_, NodeID}, options = Options, type = Type, id = Idx}, Acc) ->
|
||||
+ Owners = node_owners_call(Type, Idx),
|
||||
case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
|
||||
- Action = fun(#pubsub_node{id ={_, NodeId}, options = Options, type = Type, idx = Nidx, owners = Owners}, Acc) ->
|
||||
+ Action = fun(#pubsub_node{id ={_, NodeId}, options = Options, type = Type, idx = Nidx}, Acc) ->
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
|
||||
{result, _} ->
|
||||
[#xmlel{name = 'item', ns = ?NS_DISCO_INFO,
|
||||
@@ -680,13 +493,14 @@
|
||||
@@ -682,13 +491,14 @@
|
||||
_ -> Acc
|
||||
end
|
||||
end,
|
||||
@ -313,26 +315,26 @@
|
||||
end;
|
||||
|
||||
disco_items(Host, Node, From) ->
|
||||
- Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Idx),
|
||||
case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
|
||||
- Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
|
||||
{result, Items} ->
|
||||
{result,
|
||||
@@ -771,10 +585,10 @@
|
||||
@@ -774,10 +584,10 @@
|
||||
lists:foreach(fun(PType) ->
|
||||
{result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]),
|
||||
lists:foreach(fun
|
||||
- ({#pubsub_node{options = Options, owners = Owners, id = NodeId}, subscribed, _, JID}) ->
|
||||
+ ({#pubsub_node{options = Options, id = NodeId}, subscribed, _, JID}) ->
|
||||
- ({#pubsub_node{options = Options, owners = Owners, idx = Nidx}, subscribed, _, JID}) ->
|
||||
+ ({#pubsub_node{options = Options, idx = Nidx}, subscribed, _, JID}) ->
|
||||
case get_option(Options, access_model) of
|
||||
presence ->
|
||||
- case lists:member(BJID, Owners) of
|
||||
+ case lists:member(BJID, node_owners(Host, PType, NodeId)) of
|
||||
+ case lists:member(BJID, node_owners(Host, PType, Nidx)) of
|
||||
true ->
|
||||
node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]);
|
||||
node_action(Host, PType, unsubscribe_node, [Nidx, Entity, JID, all]);
|
||||
false ->
|
||||
@@ -949,10 +763,11 @@
|
||||
@@ -952,10 +762,11 @@
|
||||
end,
|
||||
ejabberd_router:route(To, From, Res);
|
||||
#iq{type = get, ns = ?NS_DISCO_ITEMS,
|
||||
@ -346,16 +348,16 @@
|
||||
{result, IQRes} ->
|
||||
Result = #xmlel{ns = ?NS_DISCO_ITEMS,
|
||||
name = 'query', attrs = QAttrs,
|
||||
@@ -1089,7 +904,7 @@
|
||||
@@ -1092,7 +903,7 @@
|
||||
[] ->
|
||||
["leaf"]; %% No sub-nodes: it's a leaf node
|
||||
_ ->
|
||||
- case node_call(Type, get_items, [NodeId, From]) of
|
||||
+ case node_call(Type, get_items, [NodeId, From, none]) of
|
||||
- case node_call(Type, get_items, [Nidx, From]) of
|
||||
+ case node_call(Type, get_items, [Nidx, From, none]) of
|
||||
{result, []} -> ["collection"];
|
||||
{result, _} -> ["leaf", "collection"];
|
||||
_ -> []
|
||||
@@ -1105,8 +920,9 @@
|
||||
@@ -1108,8 +919,9 @@
|
||||
[];
|
||||
true ->
|
||||
[#xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [?XMLATTR('var', ?NS_PUBSUB_s)]} |
|
||||
@ -367,7 +369,7 @@
|
||||
end, features(Type))]
|
||||
end,
|
||||
%% TODO: add meta-data info (spec section 5.4)
|
||||
@@ -1135,8 +951,9 @@
|
||||
@@ -1138,8 +950,9 @@
|
||||
#xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [?XMLATTR('var', ?NS_PUBSUB_s)]},
|
||||
#xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [?XMLATTR('var', ?NS_ADHOC_s)]},
|
||||
#xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [?XMLATTR('var', ?NS_VCARD_s)]}] ++
|
||||
@ -379,7 +381,7 @@
|
||||
end, features(Host, Node))};
|
||||
?NS_ADHOC_b ->
|
||||
command_disco_info(Host, Node, From);
|
||||
@@ -1146,7 +963,7 @@
|
||||
@@ -1149,7 +962,7 @@
|
||||
node_disco_info(Host, Node, From)
|
||||
end.
|
||||
|
||||
@ -388,7 +390,7 @@
|
||||
case tree_action(Host, get_subnodes, [Host, <<>>, From]) of
|
||||
Nodes when is_list(Nodes) ->
|
||||
{result, lists:map(
|
||||
@@ -1163,7 +980,7 @@
|
||||
@@ -1166,7 +979,7 @@
|
||||
Other ->
|
||||
Other
|
||||
end;
|
||||
@ -397,7 +399,7 @@
|
||||
%% TODO: support localization of this string
|
||||
CommandItems = [
|
||||
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item',
|
||||
@@ -1172,19 +989,20 @@
|
||||
@@ -1175,19 +988,20 @@
|
||||
?XMLATTR('name', "Get Pending")
|
||||
]}],
|
||||
{result, CommandItems};
|
||||
@ -408,22 +410,22 @@
|
||||
-iq_disco_items(Host, Item, From) ->
|
||||
+iq_disco_items(Host, Item, From, RSM) ->
|
||||
case string:tokens(Item, "!") of
|
||||
[_SNode, _ItemID] ->
|
||||
[_SNode, _ItemId] ->
|
||||
{result, []};
|
||||
[SNode] ->
|
||||
Node = string_to_node(SNode),
|
||||
- Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) ->
|
||||
- NodeItems = case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
|
||||
+ Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Idx),
|
||||
+ {NodeItems, RsmOut} = case get_allowed_items_call(Host, Idx, From, Type, Options, Owners, RSM) of
|
||||
- Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options, owners = Owners}) ->
|
||||
- NodeItems = case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) of
|
||||
+ Action = fun(#pubsub_node{idx = Nidx, type = Type, options = Options}) ->
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
+ {NodeItems, RsmOut} = case get_allowed_items_call(Host, Nidx, From, Type, Options, Owners, RSM) of
|
||||
{result, R} -> R;
|
||||
- _ -> []
|
||||
+ _ -> {[], none}
|
||||
end,
|
||||
Nodes = lists:map(
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) ->
|
||||
@@ -1202,7 +1020,7 @@
|
||||
fun(#pubsub_node{id = {_, SubNode}, options = SubOptions}) ->
|
||||
@@ -1205,7 +1019,7 @@
|
||||
{result, Name} = node_call(Type, get_item_name, [Host, Node, RN]),
|
||||
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [?XMLATTR('jid', Host), ?XMLATTR('name', Name)]}
|
||||
end, NodeItems),
|
||||
@ -432,30 +434,29 @@
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
{result, {_, Result}} -> {result, Result};
|
||||
@@ -1210,12 +1028,6 @@
|
||||
@@ -1213,12 +1027,6 @@
|
||||
end
|
||||
end.
|
||||
|
||||
-get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners) ->
|
||||
-get_allowed_items_call(Host, Nidx, From, Type, Options, Owners) ->
|
||||
- AccessModel = get_option(Options, access_model),
|
||||
- AllowedGroups = get_option(Options, roster_groups_allowed, []),
|
||||
- {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups),
|
||||
- node_call(Type, get_items, [NodeIdx, From, AccessModel, PresenceSubscription, RosterGroup, undefined]).
|
||||
- node_call(Type, get_items, [Nidx, From, AccessModel, PresenceSubscription, RosterGroup, undefined]).
|
||||
-
|
||||
get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups) ->
|
||||
if (AccessModel == presence) or (AccessModel == roster) ->
|
||||
case Host of
|
||||
@@ -1333,7 +1145,8 @@
|
||||
@@ -1336,7 +1144,7 @@
|
||||
(_, Acc) ->
|
||||
Acc
|
||||
end, [], exmpp_xml:remove_cdata_from_list(Els)),
|
||||
- get_items(Host, Node, From, SubId, MaxItems, ItemIDs);
|
||||
+ RSM = jlib:rsm_decode(SubEl),
|
||||
+ get_items(Host, Node, From, SubId, MaxItems, ItemIDs, RSM);
|
||||
- get_items(Host, Node, From, SubId, MaxItems, ItemIds);
|
||||
+ get_items(Host, Node, From, SubId, MaxItems, ItemIds, jlib:rsm_decode(SubEl));
|
||||
{get, 'subscriptions'} ->
|
||||
get_subscriptions(Host, Node, From, Plugins);
|
||||
{get, 'affiliations'} ->
|
||||
@@ -1490,7 +1303,8 @@
|
||||
@@ -1493,7 +1301,8 @@
|
||||
_ -> []
|
||||
end
|
||||
end,
|
||||
@ -465,36 +466,36 @@
|
||||
sync_dirty) of
|
||||
{result, Res} -> Res;
|
||||
Err -> Err
|
||||
@@ -1534,7 +1348,7 @@
|
||||
@@ -1537,7 +1346,7 @@
|
||||
|
||||
%%% authorization handling
|
||||
|
||||
-send_authorization_request(#pubsub_node{owners = Owners, nodeid = {Host, Node}}, Subscriber) ->
|
||||
+send_authorization_request(#pubsub_node{nodeid = {Host, Node}, type = Type, id = NodeId}, Subscriber) ->
|
||||
-send_authorization_request(#pubsub_node{owners = Owners, id = {Host, Node}}, Subscriber) ->
|
||||
+send_authorization_request(#pubsub_node{id = {Host, Node}, type = Type, idx = Nidx}, Subscriber) ->
|
||||
Lang = <<"en">>, %% TODO fix
|
||||
{U, S, R} = Subscriber,
|
||||
Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
|
||||
@@ -1564,7 +1378,7 @@
|
||||
@@ -1567,7 +1376,7 @@
|
||||
lists:foreach(fun(Owner) ->
|
||||
{U, S, R} = Owner,
|
||||
ejabberd_router:route(service_jid(Host), exmpp_jid:make(U, S, R), Stanza)
|
||||
- end, Owners).
|
||||
+ end, node_owners(Host, Type, NodeId)).
|
||||
+ end, node_owners(Host, Type, Nidx)).
|
||||
|
||||
find_authorization_response(Packet) ->
|
||||
Els = Packet#xmlel.children,
|
||||
@@ -1623,8 +1437,8 @@
|
||||
@@ -1626,8 +1435,8 @@
|
||||
"true" -> true;
|
||||
_ -> false
|
||||
end,
|
||||
- Action = fun(#pubsub_node{type = Type, owners = Owners, id = NodeId}) ->
|
||||
- Action = fun(#pubsub_node{type = Type, owners = Owners, idx = Nidx}) ->
|
||||
- IsApprover = lists:member(jlib:short_prepd_bare_jid(From), Owners),
|
||||
+ Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
+ IsApprover = lists:member(jlib:short_prepd_bare_jid(From), node_owners_call(Type, NodeId)),
|
||||
{result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]),
|
||||
+ Action = fun(#pubsub_node{type = Type, idx = Nidx}) ->
|
||||
+ IsApprover = lists:member(jlib:short_prepd_bare_jid(From), node_owners_call(Type, Nidx)),
|
||||
{result, Subscriptions} = node_call(Type, get_subscriptions, [Nidx, Subscriber]),
|
||||
if
|
||||
not IsApprover ->
|
||||
@@ -1823,7 +1637,7 @@
|
||||
@@ -1826,7 +1635,7 @@
|
||||
end,
|
||||
Reply = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
|
||||
[#xmlel{ns = ?NS_PUBSUB, name = 'create', attrs = nodeAttr(Node)}]},
|
||||
@ -503,7 +504,7 @@
|
||||
{result, {NodeId, SubsByDepth, {Result, broadcast}}} ->
|
||||
broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth),
|
||||
case Result of
|
||||
@@ -1927,7 +1741,7 @@
|
||||
@@ -1930,7 +1739,7 @@
|
||||
%%<li>The node does not exist.</li>
|
||||
%%</ul>
|
||||
subscribe_node(Host, Node, From, JID, Configuration) ->
|
||||
@ -512,50 +513,50 @@
|
||||
{result, GoodSubOpts} -> GoodSubOpts;
|
||||
_ -> invalid
|
||||
end,
|
||||
@@ -1937,7 +1751,7 @@
|
||||
@@ -1940,7 +1749,7 @@
|
||||
_:_ ->
|
||||
{undefined, undefined, undefined}
|
||||
end,
|
||||
- Action = fun(#pubsub_node{options = Options, owners = Owners, type = Type, id = NodeId}) ->
|
||||
+ Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) ->
|
||||
- Action = fun(#pubsub_node{options = Options, owners = Owners, type = Type, idx = Nidx}) ->
|
||||
+ Action = fun(#pubsub_node{options = Options, type = Type, idx = Nidx}) ->
|
||||
Features = features(Type),
|
||||
SubscribeFeature = lists:member("subscribe", Features),
|
||||
OptionsFeature = lists:member("subscription-options", Features),
|
||||
@@ -1946,6 +1760,7 @@
|
||||
@@ -1949,6 +1758,7 @@
|
||||
AccessModel = get_option(Options, access_model),
|
||||
SendLast = get_option(Options, send_last_published_item),
|
||||
AllowedGroups = get_option(Options, roster_groups_allowed, []),
|
||||
+ Owners = node_owners_call(Type, NodeId),
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
{PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, Subscriber, Owners, AccessModel, AllowedGroups),
|
||||
if
|
||||
not SubscribeFeature ->
|
||||
@@ -2290,7 +2105,7 @@
|
||||
@@ -2293,7 +2103,7 @@
|
||||
%% <p>The permission are not checked in this function.</p>
|
||||
%% @todo We probably need to check that the user doing the query has the right
|
||||
%% to read the items.
|
||||
-get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
|
||||
+get_items(Host, Node, From, SubId, SMaxItems, ItemIDs, RSM) ->
|
||||
-get_items(Host, Node, From, SubId, SMaxItems, ItemIds) ->
|
||||
+get_items(Host, Node, From, SubId, SMaxItems, ItemIds, RSM) ->
|
||||
MaxItems =
|
||||
if
|
||||
SMaxItems == "" -> get_max_items_node(Host);
|
||||
@@ -2304,12 +2119,13 @@
|
||||
@@ -2307,12 +2117,13 @@
|
||||
{error, Error} ->
|
||||
{error, Error};
|
||||
_ ->
|
||||
- Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) ->
|
||||
- Action = fun(#pubsub_node{options = Options, type = Type, idx = Nidx, owners = Owners}) ->
|
||||
+ Action = fun(#pubsub_node{options = Options, type = Type, idx = Nidx}) ->
|
||||
Features = features(Type),
|
||||
RetreiveFeature = lists:member("retrieve-items", Features),
|
||||
PersistentFeature = lists:member("persistent-items", Features),
|
||||
AccessModel = get_option(Options, access_model),
|
||||
AllowedGroups = get_option(Options, roster_groups_allowed, []),
|
||||
+ Owners = node_owners_call(Type, NodeId),
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
{PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups),
|
||||
if
|
||||
not RetreiveFeature ->
|
||||
@@ -2322,11 +2138,11 @@
|
||||
@@ -2325,11 +2136,11 @@
|
||||
node_call(Type, get_items,
|
||||
[NodeId, From,
|
||||
[Nidx, From,
|
||||
AccessModel, PresenceSubscription, RosterGroup,
|
||||
- SubId])
|
||||
+ SubId, RSM])
|
||||
@ -564,10 +565,10 @@
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
- {result, {_, Items}} ->
|
||||
+ {result, {_, Items, RSMOut}} ->
|
||||
SendItems = case ItemIDs of
|
||||
SendItems = case ItemIds of
|
||||
[] ->
|
||||
Items;
|
||||
@@ -2339,7 +2155,7 @@
|
||||
@@ -2342,7 +2153,7 @@
|
||||
%% number of items sent to MaxItems:
|
||||
{result, #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
|
||||
[#xmlel{ns = ?NS_PUBSUB, name = 'items', attrs = nodeAttr(Node), children =
|
||||
@ -576,7 +577,7 @@
|
||||
Error ->
|
||||
Error
|
||||
end
|
||||
@@ -2360,6 +2176,17 @@
|
||||
@@ -2365,6 +2176,17 @@
|
||||
{result, {_, Items}} -> Items;
|
||||
Error -> Error
|
||||
end.
|
||||
@ -594,7 +595,7 @@
|
||||
|
||||
%% @spec (Host, Node, NodeId, Type, LJID, Number) -> any()
|
||||
%% Host = pubsubHost()
|
||||
@@ -2371,16 +2198,29 @@
|
||||
@@ -2376,16 +2198,29 @@
|
||||
%% @doc <p>Resend the items of a node to the user.</p>
|
||||
%% @todo use cache-last-item feature
|
||||
send_items(Host, Node, NodeId, Type, LJID, last) ->
|
||||
@ -630,21 +631,21 @@
|
||||
send_items(Host, Node, NodeId, Type, {LU, LS, LR} = LJID, Number) ->
|
||||
ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of
|
||||
{result, []} ->
|
||||
@@ -2507,7 +2347,8 @@
|
||||
@@ -2512,7 +2347,8 @@
|
||||
error ->
|
||||
{error, 'bad-request'};
|
||||
_ ->
|
||||
- Action = fun(#pubsub_node{owners = Owners, type = Type, id = NodeId}=N) ->
|
||||
+ Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
+ Owners = node_owners_call(Type, NodeId),
|
||||
- Action = fun(#pubsub_node{owners = Owners, type = Type, idx = Nidx}=N) ->
|
||||
+ Action = fun(#pubsub_node{type = Type, idx = Nidx}) ->
|
||||
+ Owners = node_owners_call(Type, Nidx),
|
||||
case lists:member(Owner, Owners) of
|
||||
true ->
|
||||
OwnerJID = exmpp_jid:make(Owner),
|
||||
@@ -2517,24 +2358,8 @@
|
||||
@@ -2522,24 +2358,8 @@
|
||||
end,
|
||||
lists:foreach(
|
||||
fun({JID, Affiliation}) ->
|
||||
- {result, _} = node_call(Type, set_affiliation, [NodeId, JID, Affiliation]),
|
||||
- {result, _} = node_call(Type, set_affiliation, [Nidx, JID, Affiliation]),
|
||||
- case Affiliation of
|
||||
- owner ->
|
||||
- NewOwner = jlib:short_prepd_bare_jid(JID),
|
||||
@ -663,16 +664,16 @@
|
||||
- ok
|
||||
- end
|
||||
+ % TODO, check if nothing missing here about new owners
|
||||
+ node_call(Type, set_affiliation, [NodeId, JID, Affiliation])
|
||||
+ node_call(Type, set_affiliation, [Nidx, JID, Affiliation])
|
||||
end, FilteredEntities),
|
||||
{result, []};
|
||||
_ ->
|
||||
@@ -2589,11 +2414,11 @@
|
||||
@@ -2594,11 +2414,11 @@
|
||||
end.
|
||||
|
||||
read_sub(Subscriber, Node, NodeID, SubID, Lang) ->
|
||||
- case pubsub_subscription:get_subscription(Subscriber, NodeID, SubID) of
|
||||
+ case pubsub_subscription_odbc:get_subscription(Subscriber, NodeID, SubID) of
|
||||
read_sub(Subscriber, Node, NodeId, SubId, Lang) ->
|
||||
- case pubsub_subscription:get_subscription(Subscriber, NodeId, SubId) of
|
||||
+ case pubsub_subscription_odbc:get_subscription(Subscriber, NodeId, SubId) of
|
||||
{error, notfound} ->
|
||||
{error, extended_error('not-acceptable', "invalid-subid")};
|
||||
{result, #pubsub_subscription{options = Options}} ->
|
||||
@ -680,37 +681,37 @@
|
||||
+ {result, XdataEl} = pubsub_subscription_odbc:get_options_xform(Lang, Options),
|
||||
OptionsEl = #xmlel{ns = ?NS_PUBSUB, name = 'options',
|
||||
attrs = [ ?XMLATTR('jid', exmpp_jid:to_binary(Subscriber)),
|
||||
?XMLATTR('subid', SubID) | nodeAttr(Node)],
|
||||
@@ -2620,7 +2445,7 @@
|
||||
?XMLATTR('subid', SubId) | nodeAttr(Node)],
|
||||
@@ -2625,7 +2445,7 @@
|
||||
end.
|
||||
|
||||
set_options_helper(Configuration, JID, NodeID, SubID, Type) ->
|
||||
set_options_helper(Configuration, JID, NodeId, SubId, Type) ->
|
||||
- SubOpts = case pubsub_subscription:parse_options_xform(Configuration) of
|
||||
+ SubOpts = case pubsub_subscription_odbc:parse_options_xform(Configuration) of
|
||||
{result, GoodSubOpts} -> GoodSubOpts;
|
||||
_ -> invalid
|
||||
end,
|
||||
@@ -2650,7 +2475,7 @@
|
||||
write_sub(_Subscriber, _NodeID, _SubID, invalid) ->
|
||||
@@ -2655,7 +2475,7 @@
|
||||
write_sub(_Subscriber, _NodeId, _SubId, invalid) ->
|
||||
{error, extended_error('bad-request', "invalid-options")};
|
||||
write_sub(Subscriber, NodeID, SubID, Options) ->
|
||||
- case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID, Options) of
|
||||
+ case pubsub_subscription_odbc:set_subscription(Subscriber, NodeID, SubID, Options) of
|
||||
write_sub(Subscriber, NodeId, SubId, Options) ->
|
||||
- case pubsub_subscription:set_subscription(Subscriber, NodeId, SubId, Options) of
|
||||
+ case pubsub_subscription_odbc:set_subscription(Subscriber, NodeId, SubId, Options) of
|
||||
{error, notfound} ->
|
||||
{error, extended_error('not-acceptable', "invalid-subid")};
|
||||
{result, _} ->
|
||||
@@ -2824,8 +2649,8 @@
|
||||
@@ -2829,8 +2649,8 @@
|
||||
?XMLATTR('subsription', subscription_to_string(Sub)) | nodeAttr(Node)]}]}]},
|
||||
ejabberd_router:route(service_jid(Host), JID, Stanza)
|
||||
end,
|
||||
- Action = fun(#pubsub_node{owners = Owners, type = Type, id = NodeId}) ->
|
||||
- Action = fun(#pubsub_node{owners = Owners, type = Type, idx = Nidx}) ->
|
||||
- case lists:member(Owner, Owners) of
|
||||
+ Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
+ case lists:member(Owner, node_owners_call(Type, NodeId)) of
|
||||
+ Action = fun(#pubsub_node{type = Type, idx = Nidx}) ->
|
||||
+ case lists:member(Owner, node_owners_call(Type, Nidx)) of
|
||||
true ->
|
||||
Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) ->
|
||||
|
||||
@@ -3174,7 +2999,7 @@
|
||||
@@ -3179,7 +2999,7 @@
|
||||
{Depth, [{N, get_node_subs(N)} || N <- Nodes]}
|
||||
end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))}
|
||||
end,
|
||||
@ -719,19 +720,16 @@
|
||||
{result, CollSubs} -> CollSubs;
|
||||
_ -> []
|
||||
end.
|
||||
@@ -3188,9 +3013,9 @@
|
||||
@@ -3192,7 +3012,7 @@
|
||||
|
||||
get_options_for_subs(NodeID, Subs) ->
|
||||
lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
|
||||
- case pubsub_subscription:read_subscription(JID, NodeID, SubID) of
|
||||
+ case pubsub_subscription_odbc:get_subscription(JID, NodeID, SubID) of
|
||||
{error, notfound} -> [{JID, SubID, []} | Acc];
|
||||
- #pubsub_subscription{options = Options} -> [{JID, SubID, Options} | Acc];
|
||||
+ {result, #pubsub_subscription{options = Options}} -> [{JID, SubID, Options} | Acc];
|
||||
get_options_for_subs(Nidx, Subs) ->
|
||||
lists:foldl(fun({JID, subscribed, SubId}, Acc) ->
|
||||
- case pubsub_subscription:read_subscription(JID, Nidx, SubId) of
|
||||
+ case pubsub_subscription_odbc:read_subscription(JID, Nidx, SubId) of
|
||||
{error, notfound} -> [{JID, SubId, []} | Acc];
|
||||
#pubsub_subscription{options = Options} -> [{JID, SubId, Options} | Acc];
|
||||
_ -> Acc
|
||||
end;
|
||||
(_, Acc) ->
|
||||
@@ -3412,6 +3237,30 @@
|
||||
@@ -3416,6 +3236,30 @@
|
||||
Result
|
||||
end.
|
||||
|
||||
@ -762,7 +760,7 @@
|
||||
%% @spec (Host, Options) -> MaxItems
|
||||
%% Host = host()
|
||||
%% Options = [Option]
|
||||
@@ -3815,7 +3664,13 @@
|
||||
@@ -3819,7 +3663,13 @@
|
||||
tree_action(Host, Function, Args) ->
|
||||
?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]),
|
||||
Fun = fun() -> tree_call(Host, Function, Args) end,
|
||||
@ -777,7 +775,7 @@
|
||||
|
||||
%% @doc <p>node plugin call.</p>
|
||||
node_call(Type, Function, Args) ->
|
||||
@@ -3835,13 +3690,13 @@
|
||||
@@ -3839,13 +3689,13 @@
|
||||
|
||||
node_action(Host, Type, Function, Args) ->
|
||||
?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]),
|
||||
@ -793,7 +791,7 @@
|
||||
case tree_call(Host, get_node, [Host, Node]) of
|
||||
N when is_record(N, pubsub_node) ->
|
||||
case Action(N) of
|
||||
@@ -3854,13 +3709,20 @@
|
||||
@@ -3858,13 +3708,20 @@
|
||||
end
|
||||
end, Trans).
|
||||
|
||||
@ -818,7 +816,7 @@
|
||||
{result, Result} -> {result, Result};
|
||||
{error, Error} -> {error, Error};
|
||||
{atomic, {result, Result}} -> {result, Result};
|
||||
@@ -3868,6 +3730,15 @@
|
||||
@@ -3872,6 +3729,15 @@
|
||||
{aborted, Reason} ->
|
||||
?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
|
||||
{error, 'internal-server-error'};
|
||||
@ -834,7 +832,7 @@
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
|
||||
{error, 'internal-server-error'};
|
||||
@@ -3876,6 +3747,16 @@
|
||||
@@ -3880,6 +3746,16 @@
|
||||
{error, 'internal-server-error'}
|
||||
end.
|
||||
|
||||
|
@ -89,36 +89,36 @@
|
||||
init() ->
|
||||
ok = create_table().
|
||||
|
||||
subscribe_node(JID, NodeID, Options) ->
|
||||
subscribe_node(JID, NodeId, Options) ->
|
||||
try mnesia:sync_dirty(fun add_subscription/3,
|
||||
[JID, NodeID, Options]) of
|
||||
[JID, NodeId, Options]) of
|
||||
{error, Error} -> {error, Error};
|
||||
Result -> {result, Result}
|
||||
catch
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
unsubscribe_node(JID, NodeID, SubID) ->
|
||||
unsubscribe_node(JID, NodeId, SubId) ->
|
||||
try mnesia:sync_dirty(fun delete_subscription/3,
|
||||
[JID, NodeID, SubID]) of
|
||||
[JID, NodeId, SubId]) of
|
||||
{error, Error} -> {error, Error};
|
||||
Result -> {result, Result}
|
||||
catch
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
get_subscription(JID, NodeID, SubID) ->
|
||||
get_subscription(JID, NodeId, SubId) ->
|
||||
try mnesia:sync_dirty(fun read_subscription/3,
|
||||
[JID, NodeID, SubID]) of
|
||||
[JID, NodeId, SubId]) of
|
||||
{error, Error} -> {error, Error};
|
||||
Result -> {result, Result}
|
||||
catch
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
set_subscription(JID, NodeID, SubID, Options) ->
|
||||
set_subscription(JID, NodeId, SubId, Options) ->
|
||||
try mnesia:sync_dirty(fun write_subscription/4,
|
||||
[JID, NodeID, SubID, Options]) of
|
||||
[JID, NodeId, SubId, Options]) of
|
||||
{error, Error} -> {error, Error};
|
||||
Result -> {result, Result}
|
||||
catch
|
||||
@ -170,22 +170,22 @@ create_table() ->
|
||||
Other -> Other
|
||||
end.
|
||||
|
||||
add_subscription(_JID, _NodeID, Options) ->
|
||||
SubID = make_subid(),
|
||||
mnesia:write(#pubsub_subscription{subid = SubID, options = Options}),
|
||||
SubID.
|
||||
add_subscription(_JID, _NodeId, Options) ->
|
||||
SubId = make_subid(),
|
||||
mnesia:write(#pubsub_subscription{subid = SubId, options = Options}),
|
||||
SubId.
|
||||
|
||||
delete_subscription(_JID, _NodeID, SubID) ->
|
||||
mnesia:delete({pubsub_subscription, SubID}).
|
||||
delete_subscription(_JID, _NodeId, SubId) ->
|
||||
mnesia:delete({pubsub_subscription, SubId}).
|
||||
|
||||
read_subscription(_JID, _NodeID, SubID) ->
|
||||
case mnesia:read({pubsub_subscription, SubID}) of
|
||||
read_subscription(_JID, _NodeId, SubId) ->
|
||||
case mnesia:read({pubsub_subscription, SubId}) of
|
||||
[Sub] -> Sub;
|
||||
_ -> {error, notfound}
|
||||
end.
|
||||
|
||||
write_subscription(JID, NodeID, SubID, Options) ->
|
||||
case read_subscription(JID, NodeID, SubID) of
|
||||
write_subscription(JID, NodeId, SubId, Options) ->
|
||||
case read_subscription(JID, NodeId, SubId) of
|
||||
{error, notfound} -> {error, notfound};
|
||||
Sub -> mnesia:write(Sub#pubsub_subscription{options = Options})
|
||||
end.
|
||||
|
@ -89,33 +89,33 @@
|
||||
init() ->
|
||||
ok = create_table().
|
||||
|
||||
subscribe_node(_JID, _NodeID, Options) ->
|
||||
SubID = make_subid(),
|
||||
?DB_MOD:add_subscription(#pubsub_subscription{subid = SubID, options = Options}),
|
||||
{result, SubID}.
|
||||
subscribe_node(_JID, _Nidx, Options) ->
|
||||
SubId = make_subid(),
|
||||
?DB_MOD:add_subscription(#pubsub_subscription{subid = SubId, options = Options}),
|
||||
{result, SubId}.
|
||||
|
||||
unsubscribe_node(_JID, _NodeID, SubID) ->
|
||||
case ?DB_MOD:read_subscription(SubID) of
|
||||
unsubscribe_node(_JID, _Nidx, SubId) ->
|
||||
case ?DB_MOD:read_subscription(SubId) of
|
||||
{ok, Sub} ->
|
||||
?DB_MOD:delete_subscription(SubID),
|
||||
?DB_MOD:delete_subscription(SubId),
|
||||
{result, Sub};
|
||||
notfound ->
|
||||
{error, notfound}
|
||||
end.
|
||||
|
||||
get_subscription(_JID, _NodeID, SubID) ->
|
||||
case ?DB_MOD:read_subscription(SubID) of
|
||||
get_subscription(_JID, _Nidx, SubId) ->
|
||||
case ?DB_MOD:read_subscription(SubId) of
|
||||
{ok, Sub} -> {result, Sub};
|
||||
notfound -> {error, notfound}
|
||||
end.
|
||||
|
||||
set_subscription(_JID, _NodeID, SubID, Options) ->
|
||||
case ?DB_MOD:read_subscription(SubID) of
|
||||
set_subscription(_JID, _Nidx, SubId, Options) ->
|
||||
case ?DB_MOD:read_subscription(SubId) of
|
||||
{ok, _} ->
|
||||
?DB_MOD:update_subscription(#pubsub_subscription{subid = SubID, options = Options}),
|
||||
?DB_MOD:update_subscription(#pubsub_subscription{subid = SubId, options = Options}),
|
||||
{result, ok};
|
||||
notfound ->
|
||||
?DB_MOD:add_subscription(#pubsub_subscription{subid = SubID, options = Options}),
|
||||
?DB_MOD:add_subscription(#pubsub_subscription{subid = SubId, options = Options}),
|
||||
{result, ok}
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user