X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=util%2Fmultitable.lua;h=7a2d2b2a4224548977339e66fbb0c3cc4eca8631;hb=76e441c85feb7186cb9b1dcfb5b89fe66bb709f7;hp=d1858d8fa10435d4dd85b7a56edad8ea9b649692;hpb=adf1eb86c9e094e05ad1a5d41096ea54d3a60122;p=prosody.git diff --git a/util/multitable.lua b/util/multitable.lua index d1858d8f..7a2d2b2a 100644 --- a/util/multitable.lua +++ b/util/multitable.lua @@ -1,19 +1,16 @@ --- Prosody IM v0.4 --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain --- +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- - - local select = select; local t_insert = table.insert; -local pairs = pairs; -local next = next; +local unpack, pairs, next, type = unpack, pairs, next, type; -module "multitable" +local _ENV = nil; local function get(self, ...) local t = self.data; @@ -129,7 +126,42 @@ local function search_add(self, results, ...) return results; end -function new() +local function iter(self, ...) + local query = { ... }; + local maxdepth = select("#", ...); + local stack = { self.data }; + local keys = { }; + local function it(self) + local depth = #stack; + local key = next(stack[depth], keys[depth]); + if key == nil then -- Go up the stack + stack[depth], keys[depth] = nil, nil; + if depth > 1 then + return it(self); + end + return; -- The end + else + keys[depth] = key; + end + local value = stack[depth][key]; + if query[depth] == nil or key == query[depth] then + if depth == maxdepth then -- Result + local result = {}; -- Collect keys forming path to result + for i = 1, depth do + result[i] = keys[i]; + end + result[depth+1] = value; + return unpack(result, 1, depth+1); + elseif type(value) == "table" then + t_insert(stack, value); -- Descend + end + end + return it(self); + end; + return it, self; +end + +local function new() return { data = {}; get = get; @@ -138,7 +170,11 @@ function new() remove = remove; search = search; search_add = search_add; + iter = iter; }; end -return _M; +return { + iter = iter; + new = new; +};