diff options
Diffstat (limited to 'acf/persistence/backends')
-rw-r--r-- | acf/persistence/backends/augeas.lua | 25 | ||||
-rw-r--r-- | acf/persistence/backends/files.lua | 53 | ||||
-rw-r--r-- | acf/persistence/backends/json.lua | 8 | ||||
-rw-r--r-- | acf/persistence/backends/null.lua | 2 | ||||
-rw-r--r-- | acf/persistence/backends/volatile.lua | 6 |
5 files changed, 55 insertions, 39 deletions
diff --git a/acf/persistence/backends/augeas.lua b/acf/persistence/backends/augeas.lua index e25a568..165cf8b 100644 --- a/acf/persistence/backends/augeas.lua +++ b/acf/persistence/backends/augeas.lua @@ -24,16 +24,16 @@ backend = require('acf.object').class() function backend:init() self.aug = require('augeas').init() end -function backend:find(path, tpe) +function backend:find(path, leaf) util.map( function(comp) - return comp == strip_name(comp) and not string.match(comp, '^%.+$') + assert(comp == strip_name(comp) and not string.match(comp, '^%.+$')) end, path ) local res = aug_path(path) - if #self.aug:match(res) == 0 and #path > 1 and tpe ~= 'table' then + if #self.aug:match(res) == 0 and #path > 1 and leaf then local index = path[#path] if type(index) == 'number' then local ppath = copy(path) @@ -51,9 +51,10 @@ function backend:find(path, tpe) return res end -function backend:get(path, tpe) +function backend:get(path, top) + local tpe = top and top.type local leaf = tpe and tpe ~= 'table' - local apath, mvpath = self:find(path, tpe) + local apath, mvpath = self:find(path, leaf) local matches = self.aug:match(apath) if mvpath then @@ -90,13 +91,14 @@ function backend:set(mods) local gcpaths = {} for _, mod in ipairs(mods) do - local path, tpe, value = unpack(mod) + local path, value = unpack(mod) - self.aug:rm(aug_path(path)..(tpe and '/*' or '')) + local delete = value == nil + self.aug:rm(aug_path(path)..(delete and '' or '/*')) - local apath, mvpath, index = self:find(path, tpe) + local apath, mvpath, index = self:find(path, type(value) ~= 'table') - if tpe and mvpath then + if not delete and mvpath then local size = #self.aug:match(mvpath) while size < index do self.aug:insert(ipath(mvpath, size), pth.name(mvpath)) @@ -104,10 +106,11 @@ function backend:set(mods) end end - if tpe or mvpath then self.aug:set(apath, value) + if type(value) == 'table' then value = nil end + if not delete or mvpath then self.aug:set(apath, value) elseif apath > '/' then apath = pth.parent(apath) end - if value == nil or value == '' then gcpaths[mvpath or apath] = true end + if delete or value == '' then gcpaths[mvpath or apath] = true end end local function gc(path) diff --git a/acf/persistence/backends/files.lua b/acf/persistence/backends/files.lua index f0ac5a6..782674d 100644 --- a/acf/persistence/backends/files.lua +++ b/acf/persistence/backends/files.lua @@ -5,19 +5,32 @@ See LICENSE file for license details module(..., package.seeall) +local topology = require('acf.model.root').topology local pth = require('acf.path') local util = require('acf.persistence.util') +local copy = require('acf.util').copy require 'posix' require 'stringy' +local function get_scope(top) + if not top or top.type ~= 'reference' or not pth.is_unique(top.scope) then + return + end + + return stringy.startswith(top.scope, '/files/') and string.sub( + top.scope, 7, -1 + ) or nil +end + + backend = require('acf.object').class() -- TODO cache expiration function backend:init() self.cache = {} end -function backend:get(path, tpe) +function backend:get(path, top) local name = pth.join('/', unpack(path)) if not self.cache[name] then @@ -31,10 +44,10 @@ function backend:get(path, tpe) -- TODO handle relative symlinks local target = posix.readlink(name) assert(target) - if not tpe then return target end - assert(stringy.startswith(tpe, 'reference/files/')) - local scope = string.sub(tpe, 16, -1)..'/' + local scope = get_scope(top) + assert(scope) + scope = scope..'/' local slen = string.len(scope) assert(string.sub(target, 1, slen) == scope) @@ -57,10 +70,10 @@ end function backend:set(mods) for _, mod in pairs(mods) do - local path, tpe, value = unpack(mod) + local path, value = unpack(mod) local name = pth.join('/', unpack(path)) - if not tpe then + if value == nil then print('DEL', name) local t = posix.stat(name, 'type') @@ -70,24 +83,24 @@ function backend:set(mods) self.cache[name] = nil - elseif tpe == 'table' then + elseif type(value) == 'table' then assert(posix.mkdir(name)) - elseif stringy.startswith(tpe, 'reference/files/') then - -- TODO use relative symlink - os.remove(name) - assert( - posix.link( - pth.to_absolute(value, string.sub(tpe, 16, -1)), name, true - ) - ) - else - local file = util.open_file(name, 'w') - file:write(tostring(value)) - file:close() + local scope = get_scope(topology('/files'..name)) + + if scope then + -- TODO use relative symlink + os.remove(name) + assert(posix.link(pth.to_absolute(value, scope), name, true)) - self.cache[name] = value + else + local file = util.open_file(name, 'w') + file:write(tostring(value)) + file:close() + + self.cache[name] = value + end end end end diff --git a/acf/persistence/backends/json.lua b/acf/persistence/backends/json.lua index 65fc987..d2e6196 100644 --- a/acf/persistence/backends/json.lua +++ b/acf/persistence/backends/json.lua @@ -51,21 +51,21 @@ function backend:split_path(path) end end -function backend:get(path, tpe) +function backend:get(path, top) local fpath, jpath = self:split_path(path) if not self.cache[fpath] then self.cache[fpath] = Cache(json.decode(util.read_file(fpath))) end - return self.cache[fpath]:get(jpath, tpe) + return self.cache[fpath]:get(jpath, top) end function backend:set(mods) local dirty = {} for _, mod in ipairs(mods) do - local path, tpe, value = unpack(mod) + local path, value = unpack(mod) local fpath, jpath = self:split_path(path) - self.cache[fpath]:_set(jpath, tpe, value) + self.cache[fpath]:_set(jpath, value) dirty[fpath] = true end diff --git a/acf/persistence/backends/null.lua b/acf/persistence/backends/null.lua index 45b6f22..0343cbf 100644 --- a/acf/persistence/backends/null.lua +++ b/acf/persistence/backends/null.lua @@ -6,5 +6,5 @@ See LICENSE file for license details module(..., package.seeall) backend = require('acf.object').class() -function backend:get(path, tpe) if #path == 0 then return {} end end +function backend:get(path, top) if #path == 0 then return {} end end function backend:set(mods) end diff --git a/acf/persistence/backends/volatile.lua b/acf/persistence/backends/volatile.lua index 7322323..1b1b4cd 100644 --- a/acf/persistence/backends/volatile.lua +++ b/acf/persistence/backends/volatile.lua @@ -22,13 +22,13 @@ function backend:_get(path) return res end -function backend:get(path, tpe) +function backend:get(path, top) local res = self:_get(path) return type(res) == 'table' and util.keys(res) or res end -function backend:_set(path, tpe, value) - if tpe == 'table' then value = {} end +function backend:_set(path, value) + if type(value) == 'table' then value = {} end if #path == 0 then self.data = value |