Comparison

mod_mam/fallback_archive.lib.lua @ 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
child 2508:03f6d9ed2903
comparison
equal deleted inserted replaced
2022:77b9c7e5fd63 2023:98b4794b72e4
1 -- luacheck: ignore 212/self
2
3 local uuid = require "util.uuid".generate;
4 local store = module:shared("archive");
5 local archive_store = { _provided_by = "mam"; name = "fallback"; };
6
7 function archive_store:append(username, key, value, when, with)
8 local archive = store[username];
9 if not archive then
10 archive = { [0] = 0 };
11 store[username] = archive;
12 end
13 local index = (archive[0] or #archive)+1;
14 local item = { key = key, when = when, with = with, value = value };
15 if not key or archive[key] then
16 key = uuid();
17 item.key = key;
18 end
19 archive[index] = item;
20 archive[key] = index;
21 archive[0] = index;
22 return key;
23 end
24
25 function archive_store:find(username, query)
26 local archive = store[username] or {};
27 local start, stop, step = 1, archive[0] or #archive, 1;
28 local qstart, qend, qwith = -math.huge, math.huge;
29 local limit;
30
31 if query then
32 if query.reverse then
33 start, stop, step = stop, start, -1;
34 if query.before and archive[query.before] then
35 start = archive[query.before] - 1;
36 end
37 elseif query.after and archive[query.after] then
38 start = archive[query.after] + 1;
39 end
40 qwith = query.with;
41 limit = query.limit;
42 qstart = query.start or qstart;
43 qend = query["end"] or qend;
44 end
45
46 return function ()
47 if limit and limit <= 0 then return end
48 for i = start, stop, step do
49 local item = archive[i];
50 if (not qwith or qwith == item.with) and item.when >= qstart and item.when <= qend then
51 if limit then limit = limit - 1; end
52 start = i + step; -- Start on next item
53 return item.key, item.value, item.when, item.with;
54 end
55 end
56 end
57 end
58
59 function archive_store:delete(username, query)
60 if not query or next(query) == nil then
61 -- no specifics, delete everything
62 store[username] = nil;
63 return true;
64 end
65 local archive = store[username];
66 if not archive then return true; end -- no messages, nothing to delete
67
68 local start, stop, step = 1, archive[0] or #archive, 1;
69 local qstart = query.start or -math.huge;
70 local qend = query["end"] or math.huge;
71 local qwith = query.with;
72 store[username] = nil;
73 for i = 1, #archive do
74 local item = archive[i];
75 local when, with = item.when, item.when;
76 -- Add things that don't match the query
77 if not ((not qwith or qwith == item.with) and item.when >= qstart and item.when <= qend) then
78 self:append(username, item.key, item.value, when, with);
79 end
80 end
81 return true;
82 end
83
84 return archive_store;