From 6ef4b7f7e850eb0b0d9475eb648fff337ac1af72 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Thu, 8 Oct 2009 00:11:16 +0000 Subject: [PATCH 1/1] libs/uci: add luci.model.uci.bind class for easier oop-uci integration --- libs/uci/luasrc/model/uci/bind.lua | 158 +++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 libs/uci/luasrc/model/uci/bind.lua diff --git a/libs/uci/luasrc/model/uci/bind.lua b/libs/uci/luasrc/model/uci/bind.lua new file mode 100644 index 000000000..7e3085e39 --- /dev/null +++ b/libs/uci/luasrc/model/uci/bind.lua @@ -0,0 +1,158 @@ +--[[ +LuCI - UCI utilities for model classes + +Copyright 2009 Jo-Philipp Wich + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +]]-- + +local assert, pairs, type = assert, pairs, type +local utl = require "luci.util" + +module "luci.model.uci.bind" + +bind = utl.class() + +function bind.__init__(self, config, cursor) + assert(config, "call to bind() without config file") + self.cfg = config + self.uci = cursor +end + +function bind.init(self, cursor) + assert(cursor, "call to init() without uci cursor") + self.uci = cursor +end + +function bind.section(self, stype) + local x = utl.class(bsection) + x.__init__ = function(inst, sid) + assert(self.uci:get(self.cfg, sid) == stype, + "attempt to instantiate bsection(%q) of wrong type, expected %q" + % { sid, stype }) + + inst.bind = self + inst.stype = stype + inst.sid = sid + end + return x +end + +function bind.usection(self, stype) + local x = utl.class(bsection) + x.__init__ = function(inst) + inst.bind = self + inst.stype = stype + inst.sid = true + end + return x() +end + +function bind.list(self, list, add, rem) + local lookup = { } + + if type(list) == "string" then + local item + for item in list:gmatch("%S+") do + lookup[item] = true + end + + elseif type(list) == "table" then + local item + for _, item in pairs(list) do + lookup[item] = true + end + end + + if add then lookup[add] = true end + if rem then lookup[rem] = nil end + + return utl.keys(lookup) +end + +function bind.bool(self, v) + return ( v == "1" or v == "true" or v == "yes" or v == "on" ) +end + + +bsection = utl.class() + +function bsection.uciop(self, op, ...) + assert(self.bind and self.bind.uci, + "attempt to use unitialized binding: " .. type(self.sid)) + + return op and self.bind.uci[op](self.bind.uci, self.bind.cfg, ...) + or self.bind.uci +end + +function bsection.get(self, k, c) + local v + self:uciop("foreach", self.stype, + function(s) + if type(c) == "table" then + local ck, cv + for ck, cv in pairs(c) do + if s[ck] ~= cv then return true end + end + elseif type(c) == "string" and s['.name'] ~= c then + return true + end + if k ~= nil then + v = s[k] + else + v = s + end + return false + end) + return v +end + +function bsection.set(self, k, v, c) + local stat + self:uciop("foreach", self.stype, + function(s) + if type(c) == "table" then + local ck, cv + for ck, cv in pairs(c) do + if s[ck] ~= cv then return true end + end + elseif type(c) == "string" and s['.name'] ~= c then + return true + end + stat = self:uciop("set", c, k, v) + return false + end) + return stat or false +end + +function bsection.property(self, k, n) + self[n or k] = function(c, val) + if val == nil then + return c:get(k, c.sid) + else + return c:set(k, val, c.sid) + end + end +end + +function bsection.property_bool(self, k, n) + self[n or k] = function(c, val) + if val == nil then + return self.bind:bool(c:get(k, c.sid)) + else + return c:set(k, self.bind:bool(val) and "1" or "0", c.sid) + end + end +end + -- 2.11.0