summaryrefslogtreecommitdiffstats
path: root/acf/model
diff options
context:
space:
mode:
Diffstat (limited to 'acf/model')
-rw-r--r--acf/model/field.lua4
-rw-r--r--acf/model/init.lua9
-rw-r--r--acf/model/model.lua35
-rw-r--r--acf/model/node.lua40
-rw-r--r--acf/model/set.lua49
5 files changed, 92 insertions, 45 deletions
diff --git a/acf/model/field.lua b/acf/model/field.lua
index 7e3aa1d..436ce2c 100644
--- a/acf/model/field.lua
+++ b/acf/model/field.lua
@@ -117,12 +117,14 @@ function TreeNode:save(context, value)
local errors = err.ErrorDict()
for k, v in pairs(value) do
- errors:collect(function() new[k] = v end)
+ errors:collect(self.save_member, new, k, v)
end
errors:raise()
end
end
+function TreeNode.save_member(node, k, v) node[k] = v end
+
Model = class(TreeNode)
diff --git a/acf/model/init.lua b/acf/model/init.lua
index bf4f7b4..2800ab6 100644
--- a/acf/model/init.lua
+++ b/acf/model/init.lua
@@ -17,6 +17,7 @@ new = model.new
local to_field = model.to_field
node = require('acf.model.node')
+set = require('acf.model.set')
local object = require('acf.object')
local class = object.class
@@ -196,11 +197,9 @@ function Collection:load(context)
end
-PrimitiveList = class(Collection)
-
-function PrimitiveList:init(params)
- super(self, PrimitiveList):init(params, node.PrimitiveList)
-end
+Set = class(Collection)
+function Set:init(params) super(self, Set):init(params, set.Set) end
+function Set.save_member(node, k, v) set.add(node, v) end
-- experimental
diff --git a/acf/model/model.lua b/acf/model/model.lua
index 5fd96a7..7c27b50 100644
--- a/acf/model/model.lua
+++ b/acf/model/model.lua
@@ -71,22 +71,7 @@ function Model:init(context)
function mt.mmeta(name) return mt.field(name):meta() end
- mt.meta = {type='model',
- fields=util.map(function(f) return mt.mmeta(f) end,
- self._fields)}
-
- function mt.members()
- return util.map(function(f) return f.name end, mt.meta.fields)
- end
-
- function mt.validate()
- for _, name in ipairs(mt.members()) do
- local field = mt.field(name)
- if not field.compute then field:validate_saved() end
- end
- end
-
- function mt.__index(t, k)
+ function mt.get(k)
local f = mt.field(k)
if f then
if f.compute then return f:compute() end
@@ -95,9 +80,25 @@ function Model:init(context)
return mt.class[k]
end
- function mt.__newindex(t, k, v)
+ function mt.set(k, v)
local f = mt.field(k)
if not f then raise(mt.path, 'Field named '..k..' does not exist') end
f:save(v)
end
+
+ mt.meta = {
+ type='model',
+ fields=util.map(function(f) return mt.mmeta(f) end, self._fields)
+ }
+
+ function mt.members()
+ return util.map(function(f) return f.name end, mt.meta.fields)
+ end
+
+ function mt.validate()
+ for _, name in ipairs(mt.members()) do
+ local field = mt.field(name)
+ if not field.compute then field:validate_saved() end
+ end
+ end
end
diff --git a/acf/model/node.lua b/acf/model/node.lua
index 7a818be..cf3111d 100644
--- a/acf/model/node.lua
+++ b/acf/model/node.lua
@@ -52,6 +52,11 @@ TreeNode = class()
function TreeNode:init(context)
local mt = getmetatable(self)
update(mt, context)
+
+ function mt.set(k, v) rawset(self, k, v) end
+ function mt.__index(t, k) return mt.get(k) end
+ function mt.__newindex(t, k, v) mt.set(k, v) end
+
mt.txn.validable[mt.path] = mt.addr
end
@@ -88,28 +93,8 @@ function Collection:init(context, params)
end
end
- function mt.__index(t, k) return mt.field:load(k) end
- function mt.__newindex(t, k, v) mt.field:save(k, v) end
-end
-
-
-PrimitiveList = class(Collection)
-
-function PrimitiveList:init(context, params)
- super(self, PrimitiveList):init(context, params)
-
- local mt = getmetatable(self)
- local index = mt.__index
-
- function mt.__index(t, k)
- if type(k) == 'number' then return index(t, k) end
-
- for i, j in ipairs(mt.txn:get(mt.addr) or {}) do
- assert(i == tonumber(j))
- if mt.field:load(i) == k then return k end
- end
- raise(mt.path, 'Value does not exist: '..k)
- end
+ function mt.get(k) return mt.field:load(k) end
+ function mt.set(k, v) mt.field:save(k, v) end
end
@@ -138,3 +123,14 @@ mmeta = meta_func('mmeta')
parent = meta_func('parent')
path = meta_func('path')
validate = meta_func('validate')
+
+
+local rawpairs = pairs
+
+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
+ return rawpairs(res)
+end
diff --git a/acf/model/set.lua b/acf/model/set.lua
new file mode 100644
index 0000000..be6c2de
--- /dev/null
+++ b/acf/model/set.lua
@@ -0,0 +1,49 @@
+--[[
+Copyright (c) 2012-2013 Kaarle Ritvanen
+See LICENSE file for license details
+--]]
+
+module(..., package.seeall)
+
+local TreeNode = require('acf.model.field').TreeNode
+local npairs = require('acf.model.node').pairs
+local object = require('acf.object')
+
+
+local function find(set, value)
+ for i, member in npairs(set) do
+ if member == value then return i end
+ end
+end
+
+
+Set = object.class(require('acf.model.node').Collection)
+
+function Set:init(context, params)
+ assert(not object.isinstance(params.field, TreeNode))
+ object.super(self, 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.__newindex(t, k, v)
+ assert(v == nil)
+ local i = find(self, k)
+ if not i then return end
+
+ local len = #mt.members()
+ while i < len do
+ mt.set(i, mt.get(i + 1))
+ i = i + 1
+ end
+ mt.set(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
+end