From ffb3266efa026dde9275728a06224f2c7814fcba Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:47:06 +0200 Subject: mod_storage_internal: Add basic archive store implementation --- plugins/mod_storage_internal.lua | 85 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index 294d823c..a5401f70 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -1,4 +1,9 @@ local datamanager = require "core.storagemanager".olddm; +local array = require "util.array"; +local datetime = require "util.datetime"; +local st = require "util.stanza"; +local now = require "util.time".now; +local id = require "util.id".medium; local host = module.host; @@ -35,4 +40,84 @@ function keyval:users() return datamanager.users(host, self.store, self.type); end +local archive = {}; +driver.archive = { __index = archive }; + +function archive:append(username, key, value, when, with) + key = key or id(); + when = when or now(); + if not st.is_stanza(value) then + return nil, "unsupported-datatype"; + end + value = st.preserialize(st.clone(value)); + value.key = key; + value.when = when; + value.with = with; + value.attr.stamp = datetime.datetime(when); + value.attr.stamp_legacy = datetime.legacy(when); + local ok, err = datamanager.list_append(username, host, self.store, value); + if not ok then return ok, err; end + return key; +end + +function archive:find(username, query) + local items, err = datamanager.list_load(username, host, self.store); + if not items then return items, err; end + local count = #items; + local i = 0; + if query then + items = array(items); + if query.with then + items:filter(function (item) + return item.with == query.with; + end); + end + if query.start then + items:filter(function (item) + return item.when >= query.start; + end); + end + if query["end"] then + items:filter(function (item) + return item.when <= query["end"]; + end); + end + count = #items; + if query.reverse then + items:reverse(); + if query.before then + for j = 1, count do + if (items[j].key or tostring(j)) == query.before then + i = j; + break; + end + end + end + elseif query.after then + for j = 1, count do + if (items[j].key or tostring(j)) == query.after then + i = j; + break; + end + end + end + if query.limit and #items - i > query.limit then + items[i+query.limit+1] = nil; + end + end + return function () + i = i + 1; + local item = items[i]; + if not item then return; end + local key = item.key or tostring(i); + local when = item.when or datetime.parse(item.attr.stamp); + local with = item.with; + item.key, item.when, item.with = nil, nil, nil; + item.attr.stamp = nil; + item.attr.stamp_legacy = nil; + item = st.deserialize(item); + return key, item, when, with; + end, count; +end + module:provides("storage", driver); -- cgit v1.2.3