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