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); |