Software /
code /
prosody
Comparison
util/pubsub.lua @ 5972:f365d3c8fd2c
util.pubsub: Separate data from node configuration
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 30 Dec 2013 23:49:23 +0100 |
parent | 5971:637731f0b9a3 |
child | 5973:905b4fd863b4 |
child | 6435:689cb04ff9fd |
comparison
equal
deleted
inserted
replaced
5971:637731f0b9a3 | 5972:f365d3c8fd2c |
---|---|
1 local events = require "util.events"; | 1 local events = require "util.events"; |
2 local t_remove = table.remove; | |
2 | 3 |
3 module("pubsub", package.seeall); | 4 module("pubsub", package.seeall); |
4 | 5 |
5 local service = {}; | 6 local service = {}; |
6 local service_mt = { __index = service }; | 7 local service_mt = { __index = service }; |
16 return setmetatable({ | 17 return setmetatable({ |
17 config = setmetatable(config, { __index = default_config }); | 18 config = setmetatable(config, { __index = default_config }); |
18 affiliations = {}; | 19 affiliations = {}; |
19 subscriptions = {}; | 20 subscriptions = {}; |
20 nodes = {}; | 21 nodes = {}; |
22 data = {}; | |
21 events = events.new(); | 23 events = events.new(); |
22 }, service_mt); | 24 }, service_mt); |
23 end | 25 end |
24 | 26 |
25 function service:jids_equal(jid1, jid2) | 27 function service:jids_equal(jid1, jid2) |
210 -- | 212 -- |
211 if self.nodes[node] then | 213 if self.nodes[node] then |
212 return false, "conflict"; | 214 return false, "conflict"; |
213 end | 215 end |
214 | 216 |
217 self.data[node] = {}; | |
215 self.nodes[node] = { | 218 self.nodes[node] = { |
216 name = node; | 219 name = node; |
217 subscribers = {}; | 220 subscribers = {}; |
218 config = {}; | 221 config = {}; |
219 data = {}; | |
220 affiliations = {}; | 222 affiliations = {}; |
221 }; | 223 }; |
224 setmetatable(self.nodes[node], { __index = { data = self.data[node] } }); -- COMPAT | |
222 self.events.fire_event("node-created", { node = node, actor = actor }); | 225 self.events.fire_event("node-created", { node = node, actor = actor }); |
223 local ok, err = self:set_affiliation(node, true, actor, "owner"); | 226 local ok, err = self:set_affiliation(node, true, actor, "owner"); |
224 if not ok then | 227 if not ok then |
225 self.nodes[node] = nil; | 228 self.nodes[node] = nil; |
229 self.data[node] = nil; | |
226 end | 230 end |
227 return ok, err; | 231 return ok, err; |
228 end | 232 end |
229 | 233 |
230 function service:delete(node, actor) | 234 function service:delete(node, actor) |
236 local node_obj = self.nodes[node]; | 240 local node_obj = self.nodes[node]; |
237 if not node_obj then | 241 if not node_obj then |
238 return false, "item-not-found"; | 242 return false, "item-not-found"; |
239 end | 243 end |
240 self.nodes[node] = nil; | 244 self.nodes[node] = nil; |
245 self.data[node] = nil; | |
241 self.events.fire_event("node-deleted", { node = node, actor = actor }); | 246 self.events.fire_event("node-deleted", { node = node, actor = actor }); |
242 self.config.broadcaster("delete", node, node_obj.subscribers); | 247 self.config.broadcaster("delete", node, node_obj.subscribers); |
243 return true; | 248 return true; |
249 end | |
250 | |
251 local function remove_item_by_id(data, id) | |
252 if not data[id] then return end | |
253 data[id] = nil; | |
254 for i, _id in ipairs(data) do | |
255 if id == _id then | |
256 t_remove(data, i); | |
257 return i; | |
258 end | |
259 end | |
244 end | 260 end |
245 | 261 |
246 function service:publish(node, actor, id, item) | 262 function service:publish(node, actor, id, item) |
247 -- Access checking | 263 -- Access checking |
248 if not self:may(node, actor, "publish") then | 264 if not self:may(node, actor, "publish") then |
258 if not ok then | 274 if not ok then |
259 return ok, err; | 275 return ok, err; |
260 end | 276 end |
261 node_obj = self.nodes[node]; | 277 node_obj = self.nodes[node]; |
262 end | 278 end |
263 node_obj.data[id] = item; | 279 local node_data = self.data[node]; |
280 remove_item_by_id(node_data, id); | |
281 node_data[#self.data[node] + 1] = id; | |
282 node_data[id] = item; | |
264 self.events.fire_event("item-published", { node = node, actor = actor, id = id, item = item }); | 283 self.events.fire_event("item-published", { node = node, actor = actor, id = id, item = item }); |
265 self.config.broadcaster("items", node, node_obj.subscribers, item); | 284 self.config.broadcaster("items", node, node_obj.subscribers, item); |
266 return true; | 285 return true; |
267 end | 286 end |
268 | 287 |
271 if not self:may(node, actor, "retract") then | 290 if not self:may(node, actor, "retract") then |
272 return false, "forbidden"; | 291 return false, "forbidden"; |
273 end | 292 end |
274 -- | 293 -- |
275 local node_obj = self.nodes[node]; | 294 local node_obj = self.nodes[node]; |
276 if (not node_obj) or (not node_obj.data[id]) then | 295 if (not node_obj) or (not self.data[node][id]) then |
277 return false, "item-not-found"; | 296 return false, "item-not-found"; |
278 end | 297 end |
279 self.events.fire_event("item-retracted", { node = node, actor = actor, id = id }); | 298 self.events.fire_event("item-retracted", { node = node, actor = actor, id = id }); |
280 node_obj.data[id] = nil; | 299 remove_item_by_id(self.data[node], id); |
281 if retract then | 300 if retract then |
282 self.config.broadcaster("items", node, node_obj.subscribers, retract); | 301 self.config.broadcaster("items", node, node_obj.subscribers, retract); |
283 end | 302 end |
284 return true | 303 return true |
285 end | 304 end |
292 -- | 311 -- |
293 local node_obj = self.nodes[node]; | 312 local node_obj = self.nodes[node]; |
294 if not node_obj then | 313 if not node_obj then |
295 return false, "item-not-found"; | 314 return false, "item-not-found"; |
296 end | 315 end |
297 node_obj.data = {}; -- Purge | 316 self.data[node] = {}; -- Purge |
298 self.events.fire_event("node-purged", { node = node, actor = actor }); | 317 self.events.fire_event("node-purged", { node = node, actor = actor }); |
299 if notify then | 318 if notify then |
300 self.config.broadcaster("purge", node, node_obj.subscribers); | 319 self.config.broadcaster("purge", node, node_obj.subscribers); |
301 end | 320 end |
302 return true | 321 return true |
311 local node_obj = self.nodes[node]; | 330 local node_obj = self.nodes[node]; |
312 if not node_obj then | 331 if not node_obj then |
313 return false, "item-not-found"; | 332 return false, "item-not-found"; |
314 end | 333 end |
315 if id then -- Restrict results to a single specific item | 334 if id then -- Restrict results to a single specific item |
316 return true, { [id] = node_obj.data[id] }; | 335 return true, { id, [id] = self.data[node][id] }; |
317 else | 336 else |
318 return true, node_obj.data; | 337 return true, self.data[node]; |
319 end | 338 end |
320 end | 339 end |
321 | 340 |
322 function service:get_nodes(actor) | 341 function service:get_nodes(actor) |
323 -- Access checking | 342 -- Access checking |