aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2019-02-27 10:20:38 +0100
committerKim Alvefur <zash@zash.se>2019-02-27 10:20:38 +0100
commitf07ce519f075844e2c336d9a07b3963abc9841d5 (patch)
tree3cc9bfc9a725856fce5ed18f91c1e129086139e0
parent129a2976d0eb9df2014ff667cfdc14827abd72b4 (diff)
downloadprosody-f07ce519f075844e2c336d9a07b3963abc9841d5.tar.gz
prosody-f07ce519f075844e2c336d9a07b3963abc9841d5.zip
mod_storage_memory: Replace query function with one based on storage_internal (fixes #1322)
The :find method in storage_internal works and is easier to read and understand. Future changes should be simpler to apply to both modules.
-rw-r--r--plugins/mod_storage_memory.lua82
1 files changed, 51 insertions, 31 deletions
diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua
index ed04a5fb..1c6628e3 100644
--- a/plugins/mod_storage_memory.lua
+++ b/plugins/mod_storage_memory.lua
@@ -68,47 +68,67 @@ function archive_store:append(username, key, value, when, with)
return key;
end
-local function archive_iter (a, start, stop, step, limit, when_start, when_end, match_with)
- local item, when, with;
- local count = 0;
- coroutine.yield(true); -- Ready
- for i = start, stop, step do
- item = a[i];
- when, with = item.when, item.with;
- if when >= when_start and when_end >= when and (not match_with or match_with == with) then
- coroutine.yield(item.key, item.value(), when, with);
- count = count + 1;
- if limit and count >= limit then return end
- end
- end
-end
-
function archive_store:find(username, query)
- local a = self.store[username or NULL] or {};
- local start, stop, step = 1, #a, 1;
- local qstart, qend, qwith = -math.huge, math.huge;
- local limit;
+ local items = self.store[username or NULL];
+ if not items then
+ return function () end, 0;
+ end
+ local count = #items;
+ local i = 0;
if query then
- module:log("debug", "query included")
+ items = array():append(items);
+ if query.key then
+ items:filter(function (item)
+ return item.key == query.key;
+ end);
+ end
+ 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
- start, stop, step = stop, start, -1;
+ items:reverse();
if query.before then
- start = a[query.before];
+ 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
- start = a[query.after];
+ 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
- limit = query.limit;
- qstart = query.start or qstart;
- qend = query["end"] or qend;
- qwith = query.with;
end
- if not start then return nil, "invalid-key"; end
- local iter = coroutine.wrap(archive_iter);
- iter(a, start, stop, step, limit, qstart, qend, qwith);
- return iter;
+ return function ()
+ i = i + 1;
+ local item = items[i];
+ if not item then return; end
+ return item.key, item.value(), item.when, item.with;
+ end, count;
end
+
function archive_store:delete(username, query)
if not query or next(query) == nil then
self.store[username or NULL] = nil;