Mercurial > prosody-modules
comparison mod_storage_memory/mod_storage_memory.lua @ 1608:59fdf4f12343
mod_storage_memory: Add support for archive stores
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 12 Feb 2015 21:17:06 +0100 |
parents | 8b997d9cf09e |
children | 54c8a0cb2996 |
comparison
equal
deleted
inserted
replaced
1607:8b997d9cf09e | 1608:59fdf4f12343 |
---|---|
37 end | 37 end |
38 userstore[key] = data; | 38 userstore[key] = data; |
39 return true; | 39 return true; |
40 end | 40 end |
41 | 41 |
42 local archive_store = {}; | |
43 archive_store.__index = archive_store; | |
44 | |
45 function archive_store:append(username, key, when, with, value) | |
46 local a = self.store[username]; | |
47 if not a then | |
48 a = {}; | |
49 self.store[username] = a; | |
50 end | |
51 local i = #a+1; | |
52 local v = { key = key, when = when, with = with, value = value }; | |
53 if not key or a[key] then | |
54 key = tostring(a):match"%x+$"..tostring(v):match"%x+$"; | |
55 v.key = key; | |
56 end | |
57 a[i] = v; | |
58 a[key] = i; | |
59 return true; | |
60 end | |
61 | |
62 local function archive_iter (a, start, stop, step, limit, when_start, when_end, match_with) | |
63 local item, when, with; | |
64 local count = 0; | |
65 coroutine.yield(true); -- Ready | |
66 for i = start, stop, step do | |
67 item = a[i]; | |
68 when, with = item.when, item.with; | |
69 if when >= when_start and when_end >= when and (not match_with or match_with == with) then | |
70 coroutine.yield(item.key, item.value, when, with); | |
71 count = count + 1; | |
72 if limit and count >= limit then return end | |
73 end | |
74 end | |
75 end | |
76 | |
77 function archive_store:find(username, query) | |
78 local a = self.store[username] or {}; | |
79 local start, stop, step = 1, #a, 1; | |
80 local qstart, qend, qwith = -math.huge, math.huge; | |
81 local limit; | |
82 if query then | |
83 module:log("debug", "query included") | |
84 if query.reverse then | |
85 start, stop, step = stop, start, -1; | |
86 if query.before then | |
87 start = a[query.before]; | |
88 end | |
89 elseif query.after then | |
90 start = a[query.after]; | |
91 end | |
92 limit = query.limit; | |
93 qstart = query.start or qstart; | |
94 qend = query["end"] or qend; | |
95 end | |
96 if not start then return nil, "invalid-key"; end | |
97 local iter = coroutine.wrap(archive_iter); | |
98 iter(a, start, stop, step, limit, qstart, qend, qwith); | |
99 return iter; | |
100 end | |
101 | |
102 function archive_store:delete(username, query) | |
103 if not query or next(query) == nil then | |
104 self.store[username] = nil; | |
105 return true; | |
106 end | |
107 local old = self.store[username]; | |
108 if not old then return true; end | |
109 local qstart = query.start or -math.huge; | |
110 local qend = query["end"] or math.huge; | |
111 local qwith = query.with; | |
112 local new = {}; | |
113 self.store[username] = new; | |
114 local t; | |
115 for i = 1, #old do | |
116 i = old[i]; | |
117 t = i.when; | |
118 if not(qstart >= t and qend <= t and (not qwith or i.with == qwith)) then | |
119 self:append(username, i.key, t, i.with, i.value); | |
120 end | |
121 end | |
122 if #new == 0 then | |
123 self.store[username] = nil; | |
124 end | |
125 return true; | |
126 end | |
127 | |
42 local stores = { | 128 local stores = { |
43 keyval = keyval_store; | 129 keyval = keyval_store; |
44 map = map_store; | 130 map = map_store; |
131 archive = archive_store; | |
45 } | 132 } |
46 | 133 |
47 local driver = {}; | 134 local driver = {}; |
48 | 135 |
49 function driver:open(store, typ) | 136 function driver:open(store, typ) |