libs/uci: fix property_bool() in luci.model.uci.bind
[project/luci.git] / libs / uci / luasrc / model / uci / bind.lua
1 --[[
2 LuCI - UCI utilities for model classes
3
4 Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17
18 ]]--
19
20 local assert, pairs, type = assert, pairs, type
21 local utl = require "luci.util"
22
23 module "luci.model.uci.bind"
24
25 bind = utl.class()
26
27 function bind.__init__(self, config, cursor)
28 assert(config, "call to bind() without config file")
29 self.cfg = config
30 self.uci = cursor
31 end
32
33 function bind.init(self, cursor)
34 assert(cursor, "call to init() without uci cursor")
35 self.uci = cursor
36 end
37
38 function bind.section(self, stype)
39 local x = utl.class(bsection)
40 x.__init__ = function(inst, sid)
41 assert(self.uci:get(self.cfg, sid) == stype,
42 "attempt to instantiate bsection(%q) of wrong type, expected %q"
43 % { sid, stype })
44
45 inst.bind = self
46 inst.stype = stype
47 inst.sid = sid
48
49 if inst._init then
50 inst:_init(sid)
51 end
52 end
53 return x
54 end
55
56 function bind.usection(self, stype)
57 local x = utl.class(bsection)
58 x.__init__ = function(inst)
59 inst.bind = self
60 inst.stype = stype
61 inst.sid = true
62 end
63 return x()
64 end
65
66 function bind.list(self, list, add, rem)
67 local lookup = { }
68
69 if type(list) == "string" then
70 local item
71 for item in list:gmatch("%S+") do
72 lookup[item] = true
73 end
74
75 elseif type(list) == "table" then
76 local item
77 for _, item in pairs(list) do
78 lookup[item] = true
79 end
80 end
81
82 if add then lookup[add] = true end
83 if rem then lookup[rem] = nil end
84
85 return utl.keys(lookup)
86 end
87
88 function bind.bool(self, v)
89 return ( v == "1" or v == "true" or v == "yes" or v == "on" )
90 end
91
92
93 bsection = utl.class()
94
95 function bsection.uciop(self, op, ...)
96 assert(self.bind and self.bind.uci,
97 "attempt to use unitialized binding")
98
99 if op then
100 return self.bind.uci[op](self.bind.uci, self.bind.cfg, ...)
101 else
102 return self.bind.uci
103 end
104 end
105
106 function bsection.get(self, k, c)
107 local v
108 if type(c) == "string" then
109 v = self:uciop("get", c, k)
110 else
111 self:uciop("foreach", self.stype,
112 function(s)
113 if type(c) == "table" then
114 local ck, cv
115 for ck, cv in pairs(c) do
116 if s[ck] ~= cv then return true end
117 end
118 end
119 if k ~= nil then
120 v = s[k]
121 else
122 v = s
123 end
124 return false
125 end)
126 end
127 return v
128 end
129
130 function bsection.set(self, k, v, c)
131 local stat
132 if type(c) == "string" then
133 if type(v) == "table" and #v == 0 then
134 stat = self:uciop("delete", c, k)
135 else
136 stat = self:uciop("set", c, k, v)
137 end
138 else
139 self:uciop("foreach", self.stype,
140 function(s)
141 if type(c) == "table" then
142 local ck, cv
143 for ck, cv in pairs(c) do
144 if s[ck] ~= cv then return true end
145 end
146 end
147 stat = self:uciop("set", c, k, v)
148 return false
149 end)
150 end
151 return stat or false
152 end
153
154 function bsection.property(self, k, n)
155 self[n or k] = function(c, val)
156 if val == nil then
157 return c:get(k, c.sid)
158 else
159 return c:set(k, val, c.sid)
160 end
161 end
162 end
163
164 function bsection.property_bool(self, k, n)
165 self[n or k] = function(c, val)
166 if val == nil then
167 return bind:bool(c:get(k, c.sid))
168 else
169 return c:set(k, self.bind:bool(val) and "1" or "0", c.sid)
170 end
171 end
172 end
173