util.stanza: Iterate on childtags instead of all childs.
[prosody.git] / util / pubsub.lua
1 module("pubsub", package.seeall);
2
3 local service = {};
4 local service_mt = { __index = service };
5
6 function new(cb)
7         return setmetatable({ cb = cb or {}, nodes = {} }, service_mt);
8 end
9
10 function service:add_subscription(node, actor, jid)
11         local node_obj = self.nodes[node];
12         if not node_obj then
13                 return false, "item-not-found";
14         end
15         node_obj.subscribers[jid] = true;
16         return true;
17 end
18
19 function service:remove_subscription(node, actor, jid)
20         local node_obj = self.nodes[node];
21         if not node_obj then
22                 return false, "item-not-found";
23         end
24         if not node_obj.subscribers[jid] then
25                 return false, "not-subscribed";
26         end
27         node_obj.subscribers[jid] = nil;
28         return true;
29 end
30
31 function service:get_subscription(node, actor, jid)
32         local node_obj = self.nodes[node];
33         if node_obj then
34                 return node_obj.subscribers[jid];
35         end
36 end
37
38 function service:create(node, actor)
39         if not self.nodes[node] then
40                 self.nodes[node] = { name = node, subscribers = {}, config = {}, data = {} };
41                 return true;
42         end
43         return false, "conflict";
44 end
45
46 function service:publish(node, actor, id, item)
47         local node_obj = self.nodes[node];
48         if not node_obj then
49                 node_obj = { name = node, subscribers = {}, config = {}, data = {} };
50                 self.nodes[node] = node_obj;
51         end
52         node_obj.data[id] = item;
53         self.cb.broadcaster(node, node_obj.subscribers, item);
54         return true;
55 end
56
57 function service:retract(node, actor, id, retract)
58         local node_obj = self.nodes[node];
59         if (not node_obj) or (not node_obj.data[id]) then
60                 return false, "item-not-found";
61         end
62         node_obj.data[id] = nil;
63         if retract then
64                 self.cb.broadcaster(node, node_obj.subscribers, retract);
65         end
66         return true
67 end
68
69 function service:get(node, actor, id)
70         local node_obj = self.nodes[node];
71         if node_obj then
72                 if id then
73                         return { node_obj.data[id] };
74                 else
75                         return node_obj.data;
76                 end
77         end
78 end
79
80 function service:get_nodes(actor)
81         return true, self.nodes;
82 end
83
84 return _M;