diff options
author | Steven Barth <steven@midlink.org> | 2008-05-06 14:28:51 +0000 |
---|---|---|
committer | Steven Barth <steven@midlink.org> | 2008-05-06 14:28:51 +0000 |
commit | 6a1fee5115cdf047a29812dcf81b03edeefccb15 (patch) | |
tree | ef1a698180652fb236610850c514e1abcf110f4d /core/src | |
parent | 522c6c928e36db9b5243681fb16f751451ad473a (diff) |
* Rewrote and optimized ffluci.model.uci
* Use optimized UCI code for ffluci.cbi and ffluci.controller.admin.index if possible
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/ffluci/cbi.lua | 40 | ||||
-rw-r--r-- | core/src/ffluci/model/uci.lua | 4 | ||||
-rw-r--r-- | core/src/ffluci/model/uci/libuci.lua | 137 | ||||
-rw-r--r-- | core/src/ffluci/model/uci/wrapper.lua | 48 |
4 files changed, 135 insertions, 94 deletions
diff --git a/core/src/ffluci/cbi.lua b/core/src/ffluci/cbi.lua index 99d742b993..4d6d25c396 100644 --- a/core/src/ffluci/cbi.lua +++ b/core/src/ffluci/cbi.lua @@ -119,12 +119,19 @@ function Map.__init__(self, config, ...) self.config = config self.template = "cbi/map" self.uci = ffluci.model.uci.Session() - self.ucidata = self.uci:sections(self.config) - if not self.ucidata then + self.ucidata, self.uciorder = self.uci:sections(self.config) + if not self.ucidata or not self.uciorder then error("Unable to read UCI data: " .. self.config) end end +-- Use optimized UCI writing +function Map.parse(self, ...) + self.uci:t_load(self.config) + Node.parse(self, ...) + self.uci:t_save(self.config) +end + -- Creates a child section function Map.section(self, class, ...) if instanceof(class, AbstractSection) then @@ -138,21 +145,20 @@ end -- UCI add function Map.add(self, sectiontype) - local name = self.uci:add(self.config, sectiontype) + local name = self.uci:t_add(self.config, sectiontype) if name then self.ucidata[name] = {} self.ucidata[name][".type"] = sectiontype - self.ucidata[".order"] = self.ucidata[".order"] or {} - table.insert(self.ucidata[".order"], name) + table.insert(self.uciorder, name) end return name end -- UCI set function Map.set(self, section, option, value) - local stat = self.uci:set(self.config, section, option, value) + local stat = self.uci:t_set(self.config, section, option, value) if stat then - local val = self.uci:get(self.config, section, option) + local val = self.uci:t_get(self.config, section, option) if option then self.ucidata[section][option] = val else @@ -160,8 +166,7 @@ function Map.set(self, section, option, value) self.ucidata[section] = {} end self.ucidata[section][".type"] = val - self.ucidata[".order"] = self.ucidata[".order"] or {} - table.insert(self.ucidata[".order"], section) + table.insert(self.uciorder, section) end end return stat @@ -169,15 +174,15 @@ end -- UCI del function Map.del(self, section, option) - local stat = self.uci:del(self.config, section, option) + local stat = self.uci:t_del(self.config, section, option) if stat then if option then self.ucidata[section][option] = nil else self.ucidata[section] = nil - for i, k in ipairs(self.ucidata[".order"]) do + for i, k in ipairs(self.uciorder) do if section == k then - table.remove(self.ucidata[".order"], i) + table.remove(self.uciorder, i) end end end @@ -188,7 +193,7 @@ end -- UCI get (cached) function Map.get(self, section, option) if not section then - return self.ucidata + return self.ucidata, self.uciorder elseif option and self.ucidata[section] then return self.ucidata[section][option] else @@ -362,19 +367,16 @@ end -- Return all matching UCI sections for this TypedSection function TypedSection.cfgsections(self) local sections = {} + local map, order = self.map:get() - local map = self.map:get() - if not map[".order"] then - return sections - end - - for i, k in pairs(map[".order"]) do + for i, k in ipairs(order) do if map[k][".type"] == self.sectiontype then if self:checkscope(k) then table.insert(sections, k) end end end + return sections end diff --git a/core/src/ffluci/model/uci.lua b/core/src/ffluci/model/uci.lua index 511c97433d..ca5b232eb3 100644 --- a/core/src/ffluci/model/uci.lua +++ b/core/src/ffluci/model/uci.lua @@ -25,6 +25,9 @@ limitations under the License. ]]-- module("ffluci.model.uci", package.seeall) +-- Default savedir +savedir = "/tmp/.uci" + -- Test whether to load libuci-Wrapper or /sbin/uci-Wrapper if pcall(require, "uci") then Session = require("ffluci.model.uci.libuci").Session @@ -53,7 +56,6 @@ function changes(...) return default:changes(...) end - -- Wrapper for "uci commit" function commit(...) return default:commit(...) diff --git a/core/src/ffluci/model/uci/libuci.lua b/core/src/ffluci/model/uci/libuci.lua index 8414fadc42..b160dc10a3 100644 --- a/core/src/ffluci/model/uci/libuci.lua +++ b/core/src/ffluci/model/uci/libuci.lua @@ -26,24 +26,17 @@ limitations under the License. module("ffluci.model.uci.libuci", package.seeall) +require("uci") require("ffluci.util") -require("ffluci.fs") require("ffluci.sys") --- The OS uci command -ucicmd = "uci" - -- Session class Session = ffluci.util.class() -- Session constructor -function Session.__init__(self, path, uci) - uci = uci or ucicmd - if path then - self.ucicmd = uci .. " -P " .. path - else - self.ucicmd = uci - end +function Session.__init__(self, savedir) + self.ucicmd = savedir and "uci -P " .. savedir or "uci" + self.savedir = savedir or ffluci.model.uci.savedir end function Session.add(self, config, section_type) @@ -55,7 +48,8 @@ function Session.changes(self, config) end function Session.commit(self, config) - return self:_uci2("commit " .. _path(config)) + self:t_load(config) + return self:t_commit(config) end function Session.del(self, config, section, option) @@ -63,31 +57,96 @@ function Session.del(self, config, section, option) end function Session.get(self, config, section, option) - return self:_uci("get " .. _path(config, section, option)) + self:t_load(config) + return self:t_get(config, section, option) end function Session.revert(self, config) - return self:_uci2("revert " .. _path(config)) + self:t_load(config) + return self:t_revert(config) end -function Session.sections(self, config) - if not config then - return nil - end - - local r1, r2 = self:_uci3("show " .. _path(config)) - if type(r1) == "table" then - return r1[config] +function Session.sections(self, config) + self:t_load(config) + return self:t_sections(config) +end + +function Session.set(self, config, section, option, value) + self:t_load(config) + return self:t_set(config, section, option, value) and self:t_save(config) +end + +function Session.synchronize(self) + return uci.set_savedir(self.savedir) +end + + +-- UCI-Transactions + +function Session.t_load(self, config) + return self:synchronize() and uci.load(config) +end + +function Session.t_save(self, config) + return uci.save(config) +end + +function Session.t_add(self, config, type) + self:t_save(config) + local r = self:add(config, type) + self:t_load(config) + return r +end + +function Session.t_commit(self, config) + return uci.commit(config) +end + +function Session.t_del(self, config, section, option) + self:t_save(config) + local r = self:del(config, section, option) + self:t_load(config) + return r +end + +function Session.t_get(self, config, section, option) + if option then + return uci.get(config, section, option) else - return nil, r2 + return uci.get(config, section) end end -function Session.set(self, config, section, option, value) - return self:_uci2("set " .. _path(config, section, option, value)) +function Session.t_revert(self, config) + return uci.revert(config) end +function Session.t_sections(self, config) + local raw = uci.get_all(config) + if not raw then + return nil + end + + local s = {} + local o = {} + + for i, sec in ipairs(raw) do + table.insert(o, sec.name) + + s[sec.name] = sec.options + s[sec.name][".type"] = sec.type + end + + return s, o +end +function Session.t_set(self, config, section, option, value) + if option then + return uci.set(config.."."..section.."."..option.."="..value) + else + return uci.set(config.."."..section.."="..value) + end +end -- Internal functions -- @@ -112,34 +171,6 @@ function Session._uci2(self, cmd) end end -function Session._uci3(self, cmd) - local res = ffluci.sys.execl(self.ucicmd .. " 2>&1 " .. cmd) - if res[1] and res[1]:sub(1, self.ucicmd:len()+1) == self.ucicmd..":" then - return nil, res[1] - end - - tbl = {} - - for k,line in pairs(res) do - c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$") - if c then - tbl[c] = tbl[c] or {} - tbl[c][".order"] = tbl[c][".order"] or {} - - tbl[c][s] = {} - table.insert(tbl[c][".order"], s) - tbl[c][s][".type"] = t - end - - c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$") - if c then - tbl[c][s][o] = v - end - end - - return tbl -end - -- Build path (config.section.option=value) and prevent command injection function _path(...) local result = "" diff --git a/core/src/ffluci/model/uci/wrapper.lua b/core/src/ffluci/model/uci/wrapper.lua index 142e71958d..3aa3b5fd1d 100644 --- a/core/src/ffluci/model/uci/wrapper.lua +++ b/core/src/ffluci/model/uci/wrapper.lua @@ -30,23 +30,14 @@ limitations under the License. module("ffluci.model.uci.wrapper", package.seeall) require("ffluci.util") -require("ffluci.fs") require("ffluci.sys") --- The OS uci command -ucicmd = "uci" - -- Session class Session = ffluci.util.class() -- Session constructor -function Session.__init__(self, path, uci) - uci = uci or ucicmd - if path then - self.ucicmd = uci .. " -P " .. path - else - self.ucicmd = uci - end +function Session.__init__(self, savedir) + self.ucicmd = savedir and "uci -P " .. savedir or "uci" end function Session.add(self, config, section_type) @@ -80,7 +71,7 @@ function Session.sections(self, config) local r1, r2 = self:_uci3("show " .. _path(config)) if type(r1) == "table" then - return r1[config] + return r1, r2 else return nil, r2 end @@ -90,6 +81,23 @@ function Session.set(self, config, section, option, value) return self:_uci2("set " .. _path(config, section, option, value)) end +function Session.synchronize(self) end + +-- Dummy transaction functions + +function Session.t_load(self) end +function Session.t_save(self) end + +Session.t_add = Session.add +Session.t_commit = Session.commit +Session.t_del = Session.del +Session.t_get = Session.get +Session.t_revert = Session.revert +Session.t_sections = Session.sections +Session.t_set = Session.set + + + -- Internal functions -- @@ -121,26 +129,24 @@ function Session._uci3(self, cmd) return nil, res[1] end - tbl = {} + local tbl = {} + local ord = {} for k,line in pairs(res) do c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$") if c then - tbl[c] = tbl[c] or {} - tbl[c][".order"] = tbl[c][".order"] or {} - - tbl[c][s] = {} - table.insert(tbl[c][".order"], s) - tbl[c][s][".type"] = t + tbl[s] = {} + table.insert(ord, s) + tbl[s][".type"] = t end c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$") if c then - tbl[c][s][o] = v + tbl[s][o] = v end end - return tbl + return tbl, ord end -- Build path (config.section.option=value) and prevent command injection |