diff options
author | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2012-12-16 19:10:38 +0200 |
---|---|---|
committer | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2012-12-16 19:10:38 +0200 |
commit | e4361842fcdec369fbd4466f2528b2815f504ff9 (patch) | |
tree | 4694ca56f9e9a4869763d8fe1f31a81f6f62ac0b /acf/persistence/backends | |
download | aconf-e4361842fcdec369fbd4466f2528b2815f504ff9.tar.bz2 aconf-e4361842fcdec369fbd4466f2528b2815f504ff9.tar.xz |
initial version
Diffstat (limited to 'acf/persistence/backends')
-rw-r--r-- | acf/persistence/backends/augeas.lua | 26 | ||||
-rw-r--r-- | acf/persistence/backends/files.lua | 68 | ||||
-rw-r--r-- | acf/persistence/backends/json.lua | 110 |
3 files changed, 204 insertions, 0 deletions
diff --git a/acf/persistence/backends/augeas.lua b/acf/persistence/backends/augeas.lua new file mode 100644 index 0000000..34d7df8 --- /dev/null +++ b/acf/persistence/backends/augeas.lua @@ -0,0 +1,26 @@ +--[[ +Copyright (c) 2012 Kaarle Ritvanen +See LICENSE file for license details +--]] + +module(..., package.seeall) + +local pth = require('acf.path') +local map = require('acf.util').map + +backend = require('acf.object').class() + +function backend:init() self.aug = require('augeas').init() end + +function backend:get(path) + path = '/'..pth.join(unpack(path)) + local _, count = self.aug:match(path) + if count == 0 then return end + + local value = self.aug:get(path) + if value ~= nil then return value end + + return map(pth.name, self.aug:match(path..'/*')) +end + +-- TODO implement set function diff --git a/acf/persistence/backends/files.lua b/acf/persistence/backends/files.lua new file mode 100644 index 0000000..8e59ab9 --- /dev/null +++ b/acf/persistence/backends/files.lua @@ -0,0 +1,68 @@ +--[[ +Copyright (c) 2012 Kaarle Ritvanen +See LICENSE file for license details +--]] + +module(..., package.seeall) + +local pth = require('acf.path') +local util = require('acf.persistence.util') + +require 'lfs' + + +backend = require('acf.object').class() + +-- TODO cache expiration +function backend:init() self.cache = {} end + +function backend:get(path) + local name = pth.join('/', unpack(path)) + + if not self.cache[name] then + local attrs = lfs.attributes(name) + if not attrs then return end + + if attrs.mode == 'file' then + self.cache[name] = util.read_file(name) + + elseif attrs.mode == 'directory' then + local res = {} + for fname in lfs.dir(name) do + if not ({['.']=true, ['..']=true})[fname] then + table.insert(res, fname) + end + end + return res + + else error('Unsupported file type: '..name) end + + -- TODO present symlinks as references + end + + return self.cache[name] +end + +function backend:set(mods) + for _, mod in pairs(mods) do + local path, t, value = unpack(mod) + local name = pth.join('/', unpack(path)) + + -- TODO save references (t == 'reference') as symlinks + + if not t then + -- TODO del files & dirs + print('DEL', name) + + elseif t == 'table' then + lfs.mkdir(name) + + else + local file = util.open_file(name, 'w') + file:write(value) + file:close() + + self.cache[name] = value + end + end +end diff --git a/acf/persistence/backends/json.lua b/acf/persistence/backends/json.lua new file mode 100644 index 0000000..7300ce9 --- /dev/null +++ b/acf/persistence/backends/json.lua @@ -0,0 +1,110 @@ +--[[ +Copyright (c) 2012 Kaarle Ritvanen +See LICENSE file for license details +--]] + +module(..., package.seeall) + +local pth = require('acf.path') +local util = require('acf.persistence.util') +local copy = require('acf.util').copy + +require 'json' +require 'lfs' + + +local function keys(tbl) + local res = {} + for k, v in pairs(tbl) do table.insert(res, k) end + return res +end + + +backend = require('acf.object').class() + +function backend:init() + -- TODO cache expiration + self.cache = {} + self.dirty = {} +end + +function backend:split_path(path) + local fpath = copy(path) + local jpath = {} + local res + + while #fpath > 0 do + local fp = pth.join('/', unpack(fpath)) + if self.cache[fp] then return fp, jpath end + table.insert(jpath, 1, fpath[#fpath]) + table.remove(fpath) + end + + fpath = '/' + + while true do + fpath = pth.join(fpath, jpath[1]) + table.remove(jpath, 1) + + local attrs = lfs.attributes(fpath) + if not attrs or not ({directory=true, file=true})[attrs.mode] then + error('File or directory does not exist: '..fpath) + end + + if attrs.mode == 'file' then return fpath, jpath end + + assert(#jpath > 0) + end +end + +function backend:_get(path) + local fpath, jpath = self:split_path(path) + + if not self.cache[fpath] then + self.cache[fpath] = json.decode(util.read_file(fpath)) + end + + local res = self.cache[fpath] + + while #jpath > 0 do + if res == nil then return end + assert(type(res) == 'table') + local next = jpath[1] + res = res[tonumber(next) or next] + table.remove(jpath, 1) + end + + return res +end + +function backend:get(path) + local res = self:_get(path) + return type(res) == 'table' and keys(res) or res +end + +function backend:set(mods) + local dirty = {} + + for _, mod in ipairs(mods) do + local p, t, value = unpack(mod) + local fpath, jpath = self:split_path(p) + if t == 'table' then value = {} end + + if #jpath == 0 then self.cache[fpath] = value + + else + local comps = copy(p) + local name = comps[#comps] + table.remove(comps) + self:_get(comps)[tonumber(name) or name] = value + end + + dirty[fpath] = true + end + + for path, _ in pairs(dirty) do + local file = util.open_file(path, 'w') + file:write(json.encode(self.cache[path])) + file:close() + end +end |