aboutsummaryrefslogtreecommitdiff
path: root/src/mod_pubsub/node_flat_odbc.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_pubsub/node_flat_odbc.erl')
-rw-r--r--src/mod_pubsub/node_flat_odbc.erl154
1 files changed, 73 insertions, 81 deletions
diff --git a/src/mod_pubsub/node_flat_odbc.erl b/src/mod_pubsub/node_flat_odbc.erl
index 2a15af325..fa249df69 100644
--- a/src/mod_pubsub/node_flat_odbc.erl
+++ b/src/mod_pubsub/node_flat_odbc.erl
@@ -37,12 +37,11 @@
%%% 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').
-include("pubsub.hrl").
--include_lib("exmpp/include/exmpp.hrl").
-include("jlib.hrl"). %% for rsm_in and rsm_out records definitions
-define(PUBSUB, mod_pubsub_odbc).
@@ -191,9 +190,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 +211,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 +337,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 +409,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 +466,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 +480,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 +507,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 +541,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 +561,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 +624,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 +656,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 +699,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 +721,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 +778,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 +792,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 +806,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 +833,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 +841,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 +851,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 +870,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 +881,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 +897,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 +933,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 +944,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 +1092,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 +1118,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 +1144,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 +1174,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 +1329,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 +1345,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}.