From acbb01f353d7a156df33d7657f63a7c92fd9ace7 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Mon, 17 Mar 2014 18:53:46 +0200 Subject: model: move fetch to TreeNode metatable --- aconf/model/model.lua | 4 +++ aconf/model/node.lua | 89 +++++++++++++++++++++++++-------------------------- 2 files changed, 48 insertions(+), 45 deletions(-) (limited to 'aconf/model') diff --git a/aconf/model/model.lua b/aconf/model/model.lua index 747d277..7ce3060 100644 --- a/aconf/model/model.lua +++ b/aconf/model/model.lua @@ -217,6 +217,10 @@ function M.Model:init(context) for _, f in ipairs(_members(Model)) do mt.load(f.name) end end +function M.Model:fetch(path, create) + return getmetatable(self).fetch(path, create) +end + function M.Model:match(filter) for k, v in pairs(filter) do if not util.contains(v, getmetatable(self).load(k)) then return false end diff --git a/aconf/model/node.lua b/aconf/model/node.lua index 0f9c552..4ef45d8 100644 --- a/aconf/model/node.lua +++ b/aconf/model/node.lua @@ -81,6 +81,50 @@ function M.TreeNode:init(context, params) end function mt.get(k, options) return mt.load(k, options) end + + function mt.fetch(path, create) + if type(path) == 'string' then + if pth.is_absolute(path) and mt.path > '/' then + assert(not create) + return mt.txn:fetch(path) + end + path = pth.split(path) + end + + if #path == 0 then return self end + + local name = path[1] + table.remove(path, 1) + + if name == pth.up then + if not mt.parent then + raise(mt.path, 'Root object does not have parent') + end + return getmetatable(mt.parent).fetch(path, create) + end + + if not mt.member(name) then + raise(mt.path, 'Member does not exist: '..name) + end + + local options = {} + if create then + options.create = true + if #path == 0 then options.dereference = false end + end + local next = mt.get(name, options) + if next == nil and (not create or #path > 0) then + raise(mt.path, 'Subordinate does not exist: '..name) + end + if #path == 0 then return next end + + if type(next) ~= 'table' then + raise(pth.join(mt.path, name), 'Is a primitive value') + end + + return getmetatable(next).fetch(path, create) + end + function mt.removable() return true end function mt.member_removable(k) @@ -117,50 +161,6 @@ function M.TreeNode:init(context, params) mt.txn.validable[mt.path] = mt.addr end -function M.TreeNode:fetch(path, create) - local mt = getmetatable(self) - - if type(path) == 'string' then - if pth.is_absolute(path) and mt.path > '/' then - assert(not create) - return mt.txn:fetch(path) - end - path = pth.split(path) - end - - if #path == 0 then return self end - - local name = path[1] - table.remove(path, 1) - - if name == pth.up then - if not mt.parent then - raise(mt.path, 'Root object does not have parent') - end - return M.TreeNode.fetch(mt.parent, path, create) - end - - if not mt.member(name) then - raise(mt.path, 'Member does not exist: '..name) - end - - local options = {} - if create then - options.create = true - if #path == 0 then options.dereference = false end - end - local next = mt.get(name, options) - if next == nil and (not create or #path > 0) then - raise(mt.path, 'Subordinate does not exist: '..name) - end - - if #path > 0 and type(next) ~= 'table' then - raise(pth.join(mt.path, name), 'Is a primitive value') - end - - return M.TreeNode.fetch(next, path, create) -end - function M.TreeNode:search_refs(path) if type(path) == 'string' then path = pth.split(path) end @@ -202,7 +202,6 @@ function M.Collection:init(context, params) ) self.init = nil - self.fetch = nil self.search_refs = nil local mt = getmetatable(self) -- cgit v1.2.3