25
1
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:
Christophe Romain 2010-09-10 19:45:28 +02:00
parent 556892aebf
commit 4b5b98b465
25 changed files with 1017 additions and 1019 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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).

View File

@ -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).

View File

@ -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).

View File

@ -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).

View File

@ -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)).

View File

@ -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}}).

View File

@ -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}.

View File

@ -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).

View File

@ -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).

View File

@ -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).

View File

@ -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]

View File

@ -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.

View File

@ -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).

View File

@ -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).

View File

@ -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),

View File

@ -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),

View File

@ -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).

View File

@ -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) ->

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.