Mercurial > prosody-hg
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 |
| parents | 637731f0b9a3 |
| children | 905b4fd863b4 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 |
