summaryrefslogtreecommitdiffstats
path: root/acf/persistence/backends
diff options
context:
space:
mode:
Diffstat (limited to 'acf/persistence/backends')
-rw-r--r--acf/persistence/backends/augeas.lua25
-rw-r--r--acf/persistence/backends/files.lua53
-rw-r--r--acf/persistence/backends/json.lua8
-rw-r--r--acf/persistence/backends/null.lua2
-rw-r--r--acf/persistence/backends/volatile.lua6
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