Software /
code /
prosody
Comparison
core/rostermanager.lua @ 7155:4a0825984e42
rostermanager: Use map stores when only one contact is changed
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 09 Feb 2016 17:09:01 +0100 |
parent | 7154:b3b92204802f |
child | 7167:7ae430fecf12 |
comparison
equal
deleted
inserted
replaced
7154:b3b92204802f | 7155:4a0825984e42 |
---|---|
27 | 27 |
28 local function add_to_roster(session, jid, item) | 28 local function add_to_roster(session, jid, item) |
29 if session.roster then | 29 if session.roster then |
30 local old_item = session.roster[jid]; | 30 local old_item = session.roster[jid]; |
31 session.roster[jid] = item; | 31 session.roster[jid] = item; |
32 if save_roster(session.username, session.host) then | 32 if save_roster(session.username, session.host, nil, jid) then |
33 return true; | 33 return true; |
34 else | 34 else |
35 session.roster[jid] = old_item; | 35 session.roster[jid] = old_item; |
36 return nil, "wait", "internal-server-error", "Unable to save roster"; | 36 return nil, "wait", "internal-server-error", "Unable to save roster"; |
37 end | 37 end |
42 | 42 |
43 local function remove_from_roster(session, jid) | 43 local function remove_from_roster(session, jid) |
44 if session.roster then | 44 if session.roster then |
45 local old_item = session.roster[jid]; | 45 local old_item = session.roster[jid]; |
46 session.roster[jid] = nil; | 46 session.roster[jid] = nil; |
47 if save_roster(session.username, session.host) then | 47 if save_roster(session.username, session.host, nil, jid) then |
48 return true; | 48 return true; |
49 else | 49 else |
50 session.roster[jid] = old_item; | 50 session.roster[jid] = old_item; |
51 return nil, "wait", "internal-server-error", "Unable to save roster"; | 51 return nil, "wait", "internal-server-error", "Unable to save roster"; |
52 end | 52 end |
121 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster }); | 121 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster }); |
122 end | 122 end |
123 return roster, err; | 123 return roster, err; |
124 end | 124 end |
125 | 125 |
126 function save_roster(username, host, roster) | 126 function save_roster(username, host, roster, jid) |
127 if not um_user_exists(username, host) then | 127 if not um_user_exists(username, host) then |
128 log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host); | 128 log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host); |
129 return nil; | 129 return nil; |
130 end | 130 end |
131 | 131 |
132 log("debug", "save_roster: saving roster for %s@%s", username, host); | 132 log("debug", "save_roster: saving roster for %s@%s, (%s)", username, host, jid or "all contacts"); |
133 if not roster then | 133 if not roster then |
134 roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster; | 134 roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster; |
135 --if not roster then | 135 --if not roster then |
136 -- --roster = load_roster(username, host); | 136 -- --roster = load_roster(username, host); |
137 -- return true; -- roster unchanged, no reason to save | 137 -- return true; -- roster unchanged, no reason to save |
141 local metadata = roster_metadata(roster); | 141 local metadata = roster_metadata(roster); |
142 if metadata.version ~= true then | 142 if metadata.version ~= true then |
143 metadata.version = (metadata.version or 0) + 1; | 143 metadata.version = (metadata.version or 0) + 1; |
144 end | 144 end |
145 if metadata.broken then return nil, "Not saving broken roster" end | 145 if metadata.broken then return nil, "Not saving broken roster" end |
146 local roster_store = require "core.storagemanager".open(host, "roster", "keyval"); | 146 if jid == nil then |
147 return roster_store:set(username, roster); | 147 local roster_store = require "core.storagemanager".open(host, "roster", "keyval"); |
148 return roster_store:set(username, roster); | |
149 else | |
150 local roster_store = require "core.storagemanager".open(host, "roster", "map"); | |
151 return roster_store:set_keys(username, { [false] = metadata, [jid] = roster[jid] or roster_store.remove }); | |
152 end | |
148 end | 153 end |
149 log("warn", "save_roster: user had no roster to save"); | 154 log("warn", "save_roster: user had no roster to save"); |
150 return nil; | 155 return nil; |
151 end | 156 end |
152 | 157 |
158 item.subscription = "to"; | 163 item.subscription = "to"; |
159 else -- subscription == from | 164 else -- subscription == from |
160 item.subscription = "both"; | 165 item.subscription = "both"; |
161 end | 166 end |
162 item.ask = nil; | 167 item.ask = nil; |
163 return save_roster(username, host, roster); | 168 return save_roster(username, host, roster, jid); |
164 end | 169 end |
165 end | 170 end |
166 | 171 |
167 local is_contact_pending_out -- forward declaration | 172 local is_contact_pending_out -- forward declaration |
168 | 173 |
182 item.subscription = "from"; | 187 item.subscription = "from"; |
183 changed = true; | 188 changed = true; |
184 end | 189 end |
185 end | 190 end |
186 if changed then | 191 if changed then |
187 return save_roster(username, host, roster); | 192 return save_roster(username, host, roster, jid); |
188 end | 193 end |
189 end | 194 end |
190 | 195 |
191 local is_contact_pending_in -- forward declaration | 196 local is_contact_pending_in -- forward declaration |
192 | 197 |
206 item.subscription = "to"; | 211 item.subscription = "to"; |
207 changed = true; | 212 changed = true; |
208 end | 213 end |
209 end | 214 end |
210 if changed then | 215 if changed then |
211 return save_roster(username, host, roster); | 216 return save_roster(username, host, roster, jid); |
212 end | 217 end |
213 end | 218 end |
214 | 219 |
215 local function _get_online_roster_subscription(jidA, jidB) | 220 local function _get_online_roster_subscription(jidA, jidB) |
216 local user = bare_sessions[jidA]; | 221 local user = bare_sessions[jidA]; |
239 local item = roster[jid]; | 244 local item = roster[jid]; |
240 if item and (item.subscription == "from" or item.subscription == "both") then | 245 if item and (item.subscription == "from" or item.subscription == "both") then |
241 return; -- false | 246 return; -- false |
242 end | 247 end |
243 roster[false].pending[jid] = true; | 248 roster[false].pending[jid] = true; |
244 return save_roster(username, host, roster); | 249 return save_roster(username, host, roster, jid); |
245 end | 250 end |
246 function is_contact_pending_out(username, host, jid) | 251 function is_contact_pending_out(username, host, jid) |
247 local roster = load_roster(username, host); | 252 local roster = load_roster(username, host); |
248 local item = roster[jid]; | 253 local item = roster[jid]; |
249 return item and item.ask; | 254 return item and item.ask; |
258 item = {subscription = "none", groups = {}}; | 263 item = {subscription = "none", groups = {}}; |
259 roster[jid] = item; | 264 roster[jid] = item; |
260 end | 265 end |
261 item.ask = "subscribe"; | 266 item.ask = "subscribe"; |
262 log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid); | 267 log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid); |
263 return save_roster(username, host, roster); | 268 return save_roster(username, host, roster, jid); |
264 end | 269 end |
265 local function unsubscribe(username, host, jid) | 270 local function unsubscribe(username, host, jid) |
266 local roster = load_roster(username, host); | 271 local roster = load_roster(username, host); |
267 local item = roster[jid]; | 272 local item = roster[jid]; |
268 if not item then return false; end | 273 if not item then return false; end |
273 if item.subscription == "both" then | 278 if item.subscription == "both" then |
274 item.subscription = "from"; | 279 item.subscription = "from"; |
275 elseif item.subscription == "to" then | 280 elseif item.subscription == "to" then |
276 item.subscription = "none"; | 281 item.subscription = "none"; |
277 end | 282 end |
278 return save_roster(username, host, roster); | 283 return save_roster(username, host, roster, jid); |
279 end | 284 end |
280 local function subscribed(username, host, jid) | 285 local function subscribed(username, host, jid) |
281 if is_contact_pending_in(username, host, jid) then | 286 if is_contact_pending_in(username, host, jid) then |
282 local roster = load_roster(username, host); | 287 local roster = load_roster(username, host); |
283 local item = roster[jid]; | 288 local item = roster[jid]; |
289 item.subscription = "from"; | 294 item.subscription = "from"; |
290 else -- subscription == to | 295 else -- subscription == to |
291 item.subscription = "both"; | 296 item.subscription = "both"; |
292 end | 297 end |
293 roster[false].pending[jid] = nil; | 298 roster[false].pending[jid] = nil; |
294 return save_roster(username, host, roster); | 299 return save_roster(username, host, roster, jid); |
295 end -- TODO else implement optional feature pre-approval (ask = subscribed) | 300 end -- TODO else implement optional feature pre-approval (ask = subscribed) |
296 end | 301 end |
297 local function unsubscribed(username, host, jid) | 302 local function unsubscribed(username, host, jid) |
298 local roster = load_roster(username, host); | 303 local roster = load_roster(username, host); |
299 local item = roster[jid]; | 304 local item = roster[jid]; |
309 elseif item.subscription == "both" then | 314 elseif item.subscription == "both" then |
310 item.subscription = "to"; | 315 item.subscription = "to"; |
311 is_subscribed = true; | 316 is_subscribed = true; |
312 end | 317 end |
313 end | 318 end |
314 local success = (pending or is_subscribed) and save_roster(username, host, roster); | 319 local success = (pending or is_subscribed) and save_roster(username, host, roster, jid); |
315 return success, pending, subscribed; | 320 return success, pending, subscribed; |
316 end | 321 end |
317 | 322 |
318 local function process_outbound_subscription_request(username, host, jid) | 323 local function process_outbound_subscription_request(username, host, jid) |
319 local roster = load_roster(username, host); | 324 local roster = load_roster(username, host); |
320 local item = roster[jid]; | 325 local item = roster[jid]; |
321 if item and (item.subscription == "none" or item.subscription == "from") then | 326 if item and (item.subscription == "none" or item.subscription == "from") then |
322 item.ask = "subscribe"; | 327 item.ask = "subscribe"; |
323 return save_roster(username, host, roster); | 328 return save_roster(username, host, roster, jid); |
324 end | 329 end |
325 end | 330 end |
326 | 331 |
327 --[[function process_outbound_subscription_approval(username, host, jid) | 332 --[[function process_outbound_subscription_approval(username, host, jid) |
328 local roster = load_roster(username, host); | 333 local roster = load_roster(username, host); |