# HG changeset patch # User Kim Alvefur # Date 1551259238 -3600 # Node ID 96d9c121547b1cbdee7bbee95f04c5792a6c441a # Parent 8e68136cde089f98bc8912b2b777e4e071472839 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. diff -r 8e68136cde08 -r 96d9c121547b plugins/mod_storage_memory.lua --- a/plugins/mod_storage_memory.lua Fri Feb 22 07:33:23 2019 +0100 +++ b/plugins/mod_storage_memory.lua Wed Feb 27 10:20:38 2019 +0100 @@ -68,46 +68,66 @@ 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 +function archive_store:find(username, query) + 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 + 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 + 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 + return item.key, item.value(), item.when, item.with; + end, count; 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; - if query then - module:log("debug", "query included") - if query.reverse then - start, stop, step = stop, start, -1; - if query.before then - start = a[query.before]; - end - elseif query.after then - start = a[query.after]; - 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; -end function archive_store:delete(username, query) if not query or next(query) == nil then