Comparison

util/pubsub.lua @ 5973:905b4fd863b4

Merge 0.10->trunk and Happy New Year!
author Kim Alvefur <zash@zash.se>
date Tue, 31 Dec 2013 19:09:34 +0100
parent 5851:cdcfd93e2f43
parent 5972:f365d3c8fd2c
child 6442:0f4025abbe8f
comparison
equal deleted inserted replaced
5967:3b7206981317 5973:905b4fd863b4
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
225 self.events.fire_event("node-created", { node = node, actor = actor });
222 local ok, err = self:set_affiliation(node, true, actor, "owner"); 226 local ok, err = self:set_affiliation(node, true, actor, "owner");
223 if not ok then 227 if not ok then
224 self.nodes[node] = nil; 228 self.nodes[node] = nil;
229 self.data[node] = nil;
225 end 230 end
226 return ok, err; 231 return ok, err;
227 end 232 end
228 233
229 function service:delete(node, actor) 234 function service:delete(node, actor)
235 local node_obj = self.nodes[node]; 240 local node_obj = self.nodes[node];
236 if not node_obj then 241 if not node_obj then
237 return false, "item-not-found"; 242 return false, "item-not-found";
238 end 243 end
239 self.nodes[node] = nil; 244 self.nodes[node] = nil;
245 self.data[node] = nil;
246 self.events.fire_event("node-deleted", { node = node, actor = actor });
240 self.config.broadcaster("delete", node, node_obj.subscribers); 247 self.config.broadcaster("delete", node, node_obj.subscribers);
241 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
242 end 260 end
243 261
244 function service:publish(node, actor, id, item) 262 function service:publish(node, actor, id, item)
245 -- Access checking 263 -- Access checking
246 if not self:may(node, actor, "publish") then 264 if not self:may(node, actor, "publish") then
256 if not ok then 274 if not ok then
257 return ok, err; 275 return ok, err;
258 end 276 end
259 node_obj = self.nodes[node]; 277 node_obj = self.nodes[node];
260 end 278 end
261 node_obj.data[#node_obj.data + 1] = id; 279 local node_data = self.data[node];
262 node_obj.data[id] = item; 280 remove_item_by_id(node_data, id);
281 node_data[#self.data[node] + 1] = id;
282 node_data[id] = item;
263 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 });
264 self.config.broadcaster("items", node, node_obj.subscribers, item); 284 self.config.broadcaster("items", node, node_obj.subscribers, item);
265 return true; 285 return true;
266 end 286 end
267 287
270 if not self:may(node, actor, "retract") then 290 if not self:may(node, actor, "retract") then
271 return false, "forbidden"; 291 return false, "forbidden";
272 end 292 end
273 -- 293 --
274 local node_obj = self.nodes[node]; 294 local node_obj = self.nodes[node];
275 if (not node_obj) or (not node_obj.data[id]) then 295 if (not node_obj) or (not self.data[node][id]) then
276 return false, "item-not-found"; 296 return false, "item-not-found";
277 end 297 end
278 node_obj.data[id] = nil; 298 self.events.fire_event("item-retracted", { node = node, actor = actor, id = id });
279 for i, _id in ipairs(node_obj.data) do 299 remove_item_by_id(self.data[node], id);
280 if id == _id then
281 table.remove(node_obj, i);
282 break;
283 end
284 end
285 if retract then 300 if retract then
286 self.config.broadcaster("items", node, node_obj.subscribers, retract); 301 self.config.broadcaster("items", node, node_obj.subscribers, retract);
287 end 302 end
288 return true 303 return true
289 end 304 end
296 -- 311 --
297 local node_obj = self.nodes[node]; 312 local node_obj = self.nodes[node];
298 if not node_obj then 313 if not node_obj then
299 return false, "item-not-found"; 314 return false, "item-not-found";
300 end 315 end
301 node_obj.data = {}; -- Purge 316 self.data[node] = {}; -- Purge
317 self.events.fire_event("node-purged", { node = node, actor = actor });
302 if notify then 318 if notify then
303 self.config.broadcaster("purge", node, node_obj.subscribers); 319 self.config.broadcaster("purge", node, node_obj.subscribers);
304 end 320 end
305 return true 321 return true
306 end 322 end
314 local node_obj = self.nodes[node]; 330 local node_obj = self.nodes[node];
315 if not node_obj then 331 if not node_obj then
316 return false, "item-not-found"; 332 return false, "item-not-found";
317 end 333 end
318 if id then -- Restrict results to a single specific item 334 if id then -- Restrict results to a single specific item
319 return true, { id, [id] = node_obj.data[id] }; 335 return true, { id, [id] = self.data[node][id] };
320 else 336 else
321 return true, node_obj.data; 337 return true, self.data[node];
322 end 338 end
323 end 339 end
324 340
325 function service:get_nodes(actor) 341 function service:get_nodes(actor)
326 -- Access checking 342 -- Access checking