summaryrefslogtreecommitdiffstats
path: root/acf
diff options
context:
space:
mode:
Diffstat (limited to 'acf')
-rw-r--r--acf/model/model.lua8
-rw-r--r--acf/model/node.lua34
-rw-r--r--acf/model/root.lua12
-rw-r--r--acf/model/set.lua8
-rw-r--r--acf/transaction/init.lua4
5 files changed, 45 insertions, 21 deletions
diff --git a/acf/model/model.lua b/acf/model/model.lua
index 365fe20..e94d3fb 100644
--- a/acf/model/model.lua
+++ b/acf/model/model.lua
@@ -71,18 +71,20 @@ function Model:init(context)
return isinstance(res, Field) and node.BoundField(self, res) or nil
end
+ function mt.has_field(name) return mt.field(name) end
+
function mt.mmeta(name) return mt.field(name):meta() end
- function mt.get(k)
+ function mt.load(k, create)
local f = mt.field(k)
if f then
if f.compute then return f:compute() end
- return f:load()
+ return f:load(create)
end
return mt.class[k]
end
- function mt.set(k, v)
+ function mt.save(k, v)
local f = mt.field(k)
if not f then raise(mt.path, 'Field named '..k..' does not exist') end
f:save(v)
diff --git a/acf/model/node.lua b/acf/model/node.lua
index b73cf52..748b20d 100644
--- a/acf/model/node.lua
+++ b/acf/model/node.lua
@@ -53,9 +53,10 @@ function TreeNode:init(context)
local mt = getmetatable(self)
update(mt, context)
- function mt.set(k, v) rawset(self, k, v) end
+ function mt.save(k, v) rawset(self, k, v) end
+ function mt.get(k, create) return mt.load(k, create) end
function mt.__index(t, k) return mt.get(k) end
- function mt.__newindex(t, k, v) mt.set(k, v) end
+ function mt.__newindex(t, k, v) mt.save(k, v) end
function mt.has_permission(user, permission)
local p = permission..mt.path
@@ -72,19 +73,28 @@ function TreeNode:init(context)
mt.txn.validable[mt.path] = mt.addr
end
-function TreeNode:search(path)
+function TreeNode:search(path, create)
+ if type(path) == 'string' then path = pth.split(path) end
+
if #path == 0 then return self end
- local cpath = getmetatable(self).path
+ local mt = getmetatable(self)
local name = path[1]
- local next = self[name]
- if next == nil then raise(cpath, 'Subordinate does not exist: '..name) end
+ if not mt.has_field(name) then
+ raise(mt.path, 'Field does not exist: '..name)
+ end
+
+ local next = mt.get(name, create)
+ if next == nil and (not create or #path > 1) then
+ raise(mt.path, 'Subordinate does not exist: '..name)
+ end
table.remove(path, 1)
if #path > 0 and type(next) ~= 'table' then
- raise(pth.join(cpath, name), 'Is a primitive value')
+ raise(pth.join(mt.path, name), 'Is a primitive value')
end
- return TreeNode.search(next, path)
+
+ return TreeNode.search(next, path, create)
end
@@ -100,6 +110,8 @@ function Collection:init(context, params)
mt.field = BoundField(self, params.field)
mt.meta = {type='collection', members=mt.field:meta('$')}
+
+ function mt.has_field(name) return true end
function mt.mmeta(name) return mt.meta.members end
function mt.members() return mt.txn:get(mt.addr) or {} end
@@ -109,8 +121,8 @@ function Collection:init(context, params)
end
end
- function mt.get(k) return mt.field:load(k) end
- function mt.set(k, v) mt.field:save(k, v) end
+ function mt.load(k, create) return mt.field:load(k, create) end
+ function mt.save(k, v) mt.field:save(k, v) end
end
@@ -148,6 +160,6 @@ function pairs(tbl)
if not object.isinstance(tbl, TreeNode) then return rawpairs(tbl) end
local mt = getmetatable(tbl)
local res = {}
- for _, member in ipairs(mt.members()) do res[member] = mt.get(member) end
+ for _, member in ipairs(mt.members()) do res[member] = mt.load(member) end
return rawpairs(res)
end
diff --git a/acf/model/root.lua b/acf/model/root.lua
index a786064..8571527 100644
--- a/acf/model/root.lua
+++ b/acf/model/root.lua
@@ -5,20 +5,28 @@ See LICENSE file for license details
module(..., package.seeall)
+local node = require('acf.model.node')
local model = require('acf.model.model')
-local super = require('acf.object').super
+local object = require('acf.object')
+local pth = require('acf.path')
RootModel = model.new()
function RootModel:init(txn)
- super(self, RootModel):init{txn=txn, path='/', addr='/volatile'}
+ object.super(self, RootModel):init{txn=txn, path='/', addr='/volatile'}
end
function RootModel:has_permission(user, permission)
return permission == 'read'
end
+function RootModel:meta(path)
+ local obj = self:search(path, true)
+ if object.isinstance(obj, node.TreeNode) then return node.meta(obj) end
+ return node.mmeta(self:search(pth.parent(path), true), pth.name(path))
+end
+
function register(name, addr, field)
RootModel[name] = model.to_field(field, addr)
end
diff --git a/acf/model/set.lua b/acf/model/set.lua
index be6c2de..2ab9d6d 100644
--- a/acf/model/set.lua
+++ b/acf/model/set.lua
@@ -26,7 +26,7 @@ function Set:init(context, params)
local mt = getmetatable(self)
mt.meta.type = 'set'
- function mt.__index(t, k) return find(self, k) and k end
+ function mt.get(k, create) return (create or find(self, k)) and k end
function mt.__newindex(t, k, v)
assert(v == nil)
@@ -35,15 +35,15 @@ function Set:init(context, params)
local len = #mt.members()
while i < len do
- mt.set(i, mt.get(i + 1))
+ mt.save(i, mt.load(i + 1))
i = i + 1
end
- mt.set(len, nil)
+ mt.save(len, nil)
end
end
function add(set, value)
local mt = getmetatable(set)
- if not find(set, value) then mt.set(#mt.members() + 1, value) end
+ if not find(set, value) then mt.save(#mt.members() + 1, value) end
end
diff --git a/acf/transaction/init.lua b/acf/transaction/init.lua
index 48b1832..4c48d94 100644
--- a/acf/transaction/init.lua
+++ b/acf/transaction/init.lua
@@ -125,7 +125,9 @@ function Transaction:set_multiple(mods)
end
end
-function Transaction:search(path) return self.root:search(pth.split(path)) end
+function Transaction:search(path) return self.root:search(path) end
+
+function Transaction:meta(path) return self.root:meta(path) end
function Transaction:commit()
self:check()