diff options
Diffstat (limited to 'acf/model/init.lua')
-rw-r--r-- | acf/model/init.lua | 205 |
1 files changed, 0 insertions, 205 deletions
diff --git a/acf/model/init.lua b/acf/model/init.lua deleted file mode 100644 index 1de5202..0000000 --- a/acf/model/init.lua +++ /dev/null @@ -1,205 +0,0 @@ ---[[ -Copyright (c) 2012-2013 Kaarle Ritvanen -See LICENSE file for license details ---]] - -local M = {} - -M.error = require('acf.error') -local raise = M.error.raise - -local combination = require('acf.model.combination') -M.Union = combination.Union -M.Range = combination.Range - -local fld = require('acf.model.field') -local Field = fld.Field -M.Boolean = fld.Boolean -M.Integer = fld.Integer -M.Number = fld.Number -M.String = fld.String - -local model = require('acf.model.model') -M.Action = model.Action -M.new = model.new -local to_field = model.to_field - -M.net = require('acf.model.net') - -local node = require('acf.model.node') -M.node = {} -for _, m in ipairs{ - 'List', - 'Set', - 'TreeNode', - 'has_permission', - 'insert', - 'meta', - 'mmeta', - 'path', - 'pairs', - 'ipairs' -} do M.node[m] = node[m] end - -M.permission = require('acf.model.permission') -M.register = require('acf.model.root').register -M.node.Set = require('acf.model.set').Set - -local object = require('acf.object') -local class = object.class -local isinstance = object.isinstance -local super = object.super - -local pth = require('acf.path') -local map = require('acf.util').map - - -local stringy = require('stringy') - - -M.Reference = class(Field) - -function M.Reference:init(params) - if not params.widget then params.widget = 'reference' end - super(self, M.Reference):init(params) - self.dtype = 'reference' - if not self.scope then self.scope = '/' end -end - -function M.Reference:topology(context) - local res = super(self, M.Reference):topology(context) - res[1].scope = self.scope - return res -end - -function M.Reference:abs_scope(context) - return pth.to_absolute(self.scope, node.path(context.parent)) -end - -function M.Reference:meta(context) - local res = super(self, M.Reference):meta(context) - res.scope = self:abs_scope(context) - return res -end - -function M.Reference:follow(context, value) - return context.txn:fetch(pth.rawjoin(self:abs_scope(context), value)) -end - -function M.Reference:load(context, options) - local ref = super(self, M.Reference):load(context) - return ( - (not options or options.dereference ~= false) and context.txn and ref - ) and self:follow(context, ref) or ref -end - -function M.Reference:_validate(context, value) - super(self, M.Reference):_validate(context, value) - - if value == nil then return end - - if isinstance(value, node.TreeNode) then value = node.path(value) end - - local path = context.path - if type(value) ~= 'string' then raise(path, 'Path name must be string') end - - if pth.is_absolute(value) then - local scope = self:abs_scope(context) - local prefix = scope..'/' - if not stringy.startswith(value, prefix) then - raise(path, 'Reference out of scope ('..scope..')') - end - value = value:sub(prefix:len() + 1, -1) - end - - -- assume one-level ref for now - if #pth.split(value) > 1 then - raise(path, 'Subtree references not yet supported') - end - - -- TODO check instance type - M.error.relabel(path, self.follow, self, context, value) - - return value -end - -function M.Reference:deleted(context, addr) - local target = self:load(context) - if target and node.addr(target) == addr then - -- TODO raise error for the target object - raise(context.path, 'Refers to '..addr) - end -end - - -M.Model = fld.Model - - -M.Collection = class(fld.TreeNode) - -function M.Collection:init(params, itype) - if params.create == nil then params.create = true end - super(self, M.Collection):init(params) - - assert(self.type) - self.itype = itype or node.Collection - self.iparams = { - destroy=self.destroy, - layout=self.layout, - required=self.required, - ui_member=self.ui_member - } - - self.dtype = 'collection' -end - -function M.Collection:auto_ui_name(name) - if not name then return end - if name:sub(-1, -1) ~= 's' then name = name..'s' end - return super(self, M.Collection):auto_ui_name(name) -end - -function M.Collection:load(context, options) - if not self.iparams.field then self.iparams.field = to_field(self.type) end - return super(self, M.Collection):load(context, options) -end - - -M.List = class(M.Collection) -function M.List:init(params) super(self, M.List):init(params, node.List) end - - -M.Set = class(M.Collection) -function M.Set:init(params) - if not params.widget and isinstance(params.type, M.Reference) then - params.widget = 'checkboxes' - end - super(self, M.Set):init(params, M.node.Set) -end -function M.Set.save_member(tn, k, v) node.insert(tn, v) end - - --- experimental -M.Mixed = class(M.Collection) - -function M.Mixed:init(params) - params.type = M.Mixed - super(self, M.Mixed):init(params, node.Mixed) - self.pfield = Field() -end - -function M.Mixed:topology(context) return {} end - -function M.Mixed:load(context) - local value = self.pfield:load(context) - if type(value) == 'table' then return super(self, M.Mixed):load(context) end - return value -end - -function M.Mixed:save(context, value) - if type(value) == 'table' then super(self, M.Mixed):save(context, value) - else self.pfield:save(context, value) end -end - - -return M |