* Updated UCI libraries
authorSteven Barth <steven@midlink.org>
Thu, 5 Jun 2008 19:15:31 +0000 (19:15 +0000)
committerSteven Barth <steven@midlink.org>
Thu, 5 Jun 2008 19:15:31 +0000 (19:15 +0000)
* Removed old UCI libraries
* Added new High-Level UCI API

contrib/package/luci/Makefile
libs/core/luasrc/model/uci.lua [deleted file]
libs/core/luasrc/model/uci/libuci.lua [deleted file]
libs/core/luasrc/model/uci/wrapper.lua [deleted file]
libs/uci/Makefile [new file with mode: 0644]
libs/uci/luasrc/model/uci.lua [new file with mode: 0644]

index 2b5befa197fb297d51c9cc061bebd0e9e7c396d2..fdd2f4b0c77c4dcc4070ecee48cb2885f9f63956 100644 (file)
@@ -110,6 +110,16 @@ define Package/luci-cbi/install
 endef
 
 
+define Package/luci-uci
+  $(call Package/luci/libtemplate)
+  TITLE:=High-Level UCI API
+endef
+
+define Package/luci-uci/install
+       $(call Package/luci/install/template,$(1),libs/uci)
+endef
+
+
 define Package/luci-fastindex
   $(call Package/luci/libtemplate)
   TITLE:=Fastindex indexing module
@@ -122,7 +132,7 @@ endef
 
 define Package/luci-web
   $(call Package/luci/libtemplate)
-  DEPENDS+=+luci-addons
+  DEPENDS+=+luci-addons +luci-uci
   TITLE:=MVC Webframework
 endef
 
@@ -363,6 +373,9 @@ endif
 ifneq ($(CONFIG_PACKAGE_luci-fastindex),)
        PKG_SELECTED_MODULES+=libs/fastindex
 endif
+ifneq ($(CONFIG_PACKAGE_luci-uci),)
+       PKG_SELECTED_MODULES+=libs/uci
+endif
 ifneq ($(CONFIG_PACKAGE_luci-web),)
        PKG_SELECTED_MODULES+=libs/web
 endif
@@ -425,6 +438,7 @@ MAKE_FLAGS += MODULES="$(PKG_SELECTED_MODULES)" LUA_TARGET="$(LUA_TARGET)" CFLAG
 $(eval $(call BuildPackage,luci-core))
 $(eval $(call BuildPackage,luci-cbi))
 $(eval $(call BuildPackage,luci-fastindex))
+$(eval $(call BuildPackage,luci-uci))
 $(eval $(call BuildPackage,luci-web))
 
 $(eval $(call BuildPackage,luci-ff-halle))
diff --git a/libs/core/luasrc/model/uci.lua b/libs/core/luasrc/model/uci.lua
deleted file mode 100644 (file)
index 1abf566..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
---[[
-LuCI - UCI mpdel
-
-Description:
-Generalized UCI model
-
-FileId:
-$Id$
-
-License:
-Copyright 2008 Steven Barth <steven@midlink.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.
-
-]]--
-module("luci.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("luci.model.uci.libuci").Session
-else
-       Session = require("luci.model.uci.wrapper").Session
-end
-
--- The default Session
-local default = Session()
-local state   = Session("/var/state")
-
--- The state Session
-function StateSession()
-       return state
-end
-
-
--- Wrapper for "uci add"
-function add(...)
-       return default:add(...)
-end
-
-
--- Wrapper for "uci changes"
-function changes(...)
-       return default:changes(...)
-end
-
--- Wrapper for "uci commit"
-function commit(...)
-       return default:commit(...)
-end
-
-
--- Wrapper for "uci del"
-function del(...)
-       return default:del(...)
-end
-
-
--- Wrapper for "uci get"
-function get(...)
-       return default:get(...)
-end
-
-
--- Wrapper for "uci revert"
-function revert(...)
-       return default:revert(...)
-end
-
-
--- Wrapper for "uci show"
-function sections(...)
-       return default:sections(...)
-end
-
-
--- Wrapper for "uci set"
-function set(...)
-       return default:set(...)
-end
diff --git a/libs/core/luasrc/model/uci/libuci.lua b/libs/core/luasrc/model/uci/libuci.lua
deleted file mode 100644 (file)
index 601ff2f..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
---[[
-LuCI - UCI libuci wrapper
-
-Description:
-Wrapper for the libuci Lua bindings
-
-FileId:
-$Id$
-
-License:
-Copyright 2008 Steven Barth <steven@midlink.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.
-
-]]--
-
-module("luci.model.uci.libuci", package.seeall)
-
-require("uci")
-require("luci.util")
-require("luci.sys")
-
--- Session class
-Session = luci.util.class()
-
--- Session constructor
-function Session.__init__(self, savedir)
-       self.savedir = savedir or luci.model.uci.savedir
-       uci.set_savedir(self.savedir)
-end
-
-function Session.add(self, config, section_type)
-       return uci.add(config, section_type)
-end
-
-function Session.changes(self, config)
-       if config then
-               return uci.changes(config)
-       else
-               return uci.changes()
-       end
-end
-
-function Session.commit(self, config)
-       return self:t_commit(config)
-end
-
-function Session.del(self, config, section, option)
-       return uci.del(config, section, option)
-end
-
-function Session.get(self, config, section, option)
-       return self:t_get(config, section, option)
-end
-
-function Session.revert(self, config)
-       return self:t_revert(config)
-end
-
-function Session.sections(self, config)
-       return self:t_sections(config)
-end
-
-function Session.set(self, config, section, option, value)
-       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)
-       return self:add(config, type)
-end
-
-function Session.t_commit(self, config)
-       return uci.commit(config)
-end
-
-function Session.t_del(self, config, section, option)
-       return self:del(config, section, option)
-end
-
-function Session.t_get(self, config, section, option)
-       if option then
-               return uci.get(config, section, option)
-       else
-               return uci.get(config, section)
-       end
-end
-
-function Session.t_revert(self, config)
-       return uci.revert(config)
-end
-
-function Session.t_sections(self, config)
-       return uci.get_all(config)
-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
-
diff --git a/libs/core/luasrc/model/uci/wrapper.lua b/libs/core/luasrc/model/uci/wrapper.lua
deleted file mode 100644 (file)
index e063b27..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
---[[
-LuCI - UCI wrapper library
-
-Description:
-Wrapper for the /sbin/uci application, syntax of implemented functions
-is comparable to the syntax of the uci application
-
-Any return value of false or nil can be interpreted as an error
-
-FileId:
-$Id$
-
-License:
-Copyright 2008 Steven Barth <steven@midlink.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.
-
-]]--
-
-module("luci.model.uci.wrapper", package.seeall)
-
-require("luci.util")
-require("luci.sys")
-
--- Session class
-Session = luci.util.class()
-
--- Session constructor
-function Session.__init__(self, savedir)
-       self.ucicmd = savedir and "uci -P " .. savedir or "uci"
-end
-
-function Session.add(self, config, section_type)
-       return self:_uci("add " .. _path(config) .. " " .. _path(section_type))
-end
-
-function Session.changes(self, config)
-       return self:_uci("changes " .. _path(config))
-end
-
-function Session.commit(self, config)
-       return self:_uci2("commit " .. _path(config))
-end
-
-function Session.del(self, config, section, option)
-       return self:_uci2("del " .. _path(config, section, option))
-end
-
-function Session.get(self, config, section, option)
-       return self:_uci("get " .. _path(config, section, option))
-end
-
-function Session.revert(self, config)
-       return self:_uci2("revert " .. _path(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, r2
-       else
-               return nil, r2
-       end
-end
-
-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 --
-
-
-function Session._uci(self, cmd)
-       local res = luci.sys.exec(self.ucicmd .. " 2>/dev/null " .. cmd)
-       
-       if res:len() == 0 then
-               return nil
-       else
-               return res:sub(1, res:len()-1)
-       end     
-end
-
-function Session._uci2(self, cmd)
-       local res = luci.sys.exec(self.ucicmd .. " 2>&1 " .. cmd)
-       
-       if res:len() > 0 then
-               return false, res
-       else
-               return true
-       end     
-end
-
-function Session._uci3(self, cmd)
-       local res = luci.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
-
-       local tbl = {}
-       local ord = {}
-
-       for k,line in pairs(res) do
-               c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$")
-               if c then
-                       tbl[s] = {}
-                       table.insert(ord, s)
-                       tbl[s][".type"] = t
-               end
-       
-               c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$")
-               if c then
-                       tbl[s][o] = v
-               end
-       end
-       
-       return tbl, ord
-end
-
--- Build path (config.section.option=value) and prevent command injection
-function _path(...)
-       local result = ""
-       
-       -- Not using ipairs because it is not reliable in case of nil arguments
-       arg.n = nil
-       for k,v in pairs(arg) do
-               if v then
-                       v = tostring(v)
-                       if k == 1 then
-                               result = "'" .. v:gsub("['.]", "") .. "'"
-                       elseif k < 4 then
-                               result = result .. ".'" .. v:gsub("['.]", "") .. "'"
-                       elseif k == 4 then
-                               result = result .. "='" .. v:gsub("'", "") .. "'"
-                       end
-               end
-       end
-       return result
-end
\ No newline at end of file
diff --git a/libs/uci/Makefile b/libs/uci/Makefile
new file mode 100644 (file)
index 0000000..81a96f6
--- /dev/null
@@ -0,0 +1,2 @@
+include ../../build/config.mk
+include ../../build/module.mk
\ No newline at end of file
diff --git a/libs/uci/luasrc/model/uci.lua b/libs/uci/luasrc/model/uci.lua
new file mode 100644 (file)
index 0000000..060e074
--- /dev/null
@@ -0,0 +1,108 @@
+--[[
+LuCI - UCI mpdel
+
+Description:
+Generalized UCI model
+
+FileId:
+$Id$
+
+License:
+Copyright 2008 Steven Barth <steven@midlink.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 uci  = require("uci")
+local util = require("luci.util")
+local setmetatable = setmetatable
+local rawget = rawget
+local rawset = rawset
+local error = error
+local tostring = tostring
+
+module("luci.model.uci", function(m) setmetatable(m, {__index = uci}) end)
+
+local configs_mt = {}
+local sections_mt = {}
+local options_mt = {}
+
+config = {}
+setmetatable(config, configs_mt)
+
+-- Level 1 (configs)
+function configs_mt.__index(self, key)
+       local node = rawget(self, key)
+       if not node then
+               node = {}
+               node[".name"] = key
+               setmetatable(node, sections_mt)
+               rawset(self, key, node)
+       end
+       return node
+end
+function configs_mt.__newindex()
+       error("invalid operation")
+end
+
+
+-- Level 2 (sections)
+function sections_mt.__index(self, key)
+       local node = rawget(self, key)
+       if not node then
+               node = {}
+               node[".conf"] = self[".name"]
+               node[".name"] = key
+               node[".type"] = uci.get(self[".name"], key)
+               setmetatable(node, options_mt)
+               rawset(self, key, node)
+       end
+       return node
+end
+function sections_mt.__newindex(self, key, value)
+       if not value then
+               if uci.delete(self[".name"], key) then
+                       rawset(self, key, nil)
+               else
+                       error("unable to delete section")
+               end
+       elseif key == "" then
+               key = uci.add(self[".name"], tostring(value))
+               if key then
+                       rawset(self, "", self[key])
+               else
+                       error("unable to create section")
+               end 
+       else
+               if not uci.set(self[".name"], key, value) then
+                       error("unable to create section")
+               end
+       end
+end
+
+
+-- Level 3 (options)
+function options_mt.__index(self, key)
+       return uci.get(self[".conf"], self[".name"], key)
+end
+function options_mt.__newindex(self, key, value)
+       if not value then
+               if not uci.delete(self[".conf"], self[".name"], key) then
+                       error("unable to delete option")
+               end
+       else
+               if not uci.set(self[".conf"], self[".name"], key, tostring(value)) then
+                       error("unable to write option")
+               end
+       end
+end