Mercurial > prosody-modules
changeset 2023:98b4794b72e4
mod_mam: Include an in-memory fallback driver
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 19 Jan 2016 17:47:47 +0100 (2016-01-19) |
parents | 77b9c7e5fd63 |
children | 6f4dcc723a60 |
files | mod_mam/README.markdown mod_mam/fallback_archive.lib.lua mod_mam/mod_mam.lua |
diffstat | 3 files changed, 91 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_mam/README.markdown Tue Jan 19 17:47:05 2016 +0100 +++ b/mod_mam/README.markdown Tue Jan 19 17:47:47 2016 +0100 @@ -58,6 +58,9 @@ } ``` +If no archive-capable storage backend can be opened then an in-memory +one will be used as fallback. + Query size limits ----------------- @@ -116,12 +119,10 @@ ------- --------------- trunk Works - 0.10 Works [^2] - 0.9 Unsupported + 0.10 Works + 0.9 Works 0.8 Does not work ------- --------------- [^1]: Might be changed to "mam" at some point -[^2]: requires a storage driver with archive support, eg - mod\_storage\_sql in 0.10
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_mam/fallback_archive.lib.lua Tue Jan 19 17:47:47 2016 +0100 @@ -0,0 +1,84 @@ +-- luacheck: ignore 212/self + +local uuid = require "util.uuid".generate; +local store = module:shared("archive"); +local archive_store = { _provided_by = "mam"; name = "fallback"; }; + +function archive_store:append(username, key, value, when, with) + local archive = store[username]; + if not archive then + archive = { [0] = 0 }; + store[username] = archive; + end + local index = (archive[0] or #archive)+1; + local item = { key = key, when = when, with = with, value = value }; + if not key or archive[key] then + key = uuid(); + item.key = key; + end + archive[index] = item; + archive[key] = index; + archive[0] = index; + return key; +end + +function archive_store:find(username, query) + local archive = store[username] or {}; + local start, stop, step = 1, archive[0] or #archive, 1; + local qstart, qend, qwith = -math.huge, math.huge; + local limit; + + if query then + if query.reverse then + start, stop, step = stop, start, -1; + if query.before and archive[query.before] then + start = archive[query.before] - 1; + end + elseif query.after and archive[query.after] then + start = archive[query.after] + 1; + end + qwith = query.with; + limit = query.limit; + qstart = query.start or qstart; + qend = query["end"] or qend; + end + + return function () + if limit and limit <= 0 then return end + for i = start, stop, step do + local item = archive[i]; + if (not qwith or qwith == item.with) and item.when >= qstart and item.when <= qend then + if limit then limit = limit - 1; end + start = i + step; -- Start on next item + return item.key, item.value, item.when, item.with; + end + end + end +end + +function archive_store:delete(username, query) + if not query or next(query) == nil then + -- no specifics, delete everything + store[username] = nil; + return true; + end + local archive = store[username]; + if not archive then return true; end -- no messages, nothing to delete + + local start, stop, step = 1, archive[0] or #archive, 1; + local qstart = query.start or -math.huge; + local qend = query["end"] or math.huge; + local qwith = query.with; + store[username] = nil; + for i = 1, #archive do + local item = archive[i]; + local when, with = item.when, item.when; + -- Add things that don't match the query + if not ((not qwith or qwith == item.with) and item.when >= qstart and item.when <= qend) then + self:append(username, item.key, item.value, when, with); + end + end + return true; +end + +return archive_store;
--- a/mod_mam/mod_mam.lua Tue Jan 19 17:47:05 2016 +0100 +++ b/mod_mam/mod_mam.lua Tue Jan 19 17:47:47 2016 +0100 @@ -39,10 +39,8 @@ local archive = assert(module:open_store(archive_store, "archive")); if archive.name == "null" then - module:log("debug", "Attempt to open archive storage returned null driver"); - module:log("error", "Unable to open archive storage, no archive capable storage driver enabled?"); - module:log("info", "See https://prosody.im/doc/storage and https://prosody.im/doc/archiving for more information"); - return; + module:log("info", "Using in-memory fallback archive driver"); + archive = module:require "fallback_archive"; elseif not archive.find then module:log("debug", "Attempt to open archive storage returned a valid driver but it does not seem to implement the storage API"); module:log("error", "mod_%s does not support archiving", archive._provided_by or archive.name and "storage_"..archive.name.."(?)" or "<unknown>");