summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2009-10-08 00:11:16 +0000
committerJo-Philipp Wich <jow@openwrt.org>2009-10-08 00:11:16 +0000
commit6ef4b7f7e850eb0b0d9475eb648fff337ac1af72 (patch)
tree4f7b4d5d82bb865262e3cdf61059e3d8f94d644d
parentf6164c6955d6704b587c16f1572c9806c7f11c07 (diff)
libs/uci: add luci.model.uci.bind class for easier oop-uci integration
-rw-r--r--libs/uci/luasrc/model/uci/bind.lua158
1 files changed, 158 insertions, 0 deletions
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 <xm@subsignal.org>
+
+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
+