local require, getmetatable, type = require, getmetatable, type
--- LuCI UCI model library.
+-- The typical workflow for UCI is: Get a cursor instance from the
+-- cursor factory, modify data (via Cursor.add, Cursor.delete, etc.),
+-- save the changes to the staging area via Cursor.save and finally
+-- Cursor.commit the data to the actual config files.
+-- LuCI then needs to Cursor.apply the changes so deamons etc. are
+-- reloaded.
-- @cstyle instance
module "luci.model.uci"
end
-local Cursor = getmetatable(cursor())
+inst = cursor()
+inst_state = cursor_state()
+
+local Cursor = getmetatable(inst)
--- Applies UCI configuration changes
-- @param configlist List of UCI configurations
function Cursor.apply(self, configlist, command)
configlist = self:_affected(configlist)
local reloadcmd = "/sbin/luci-reload " .. table.concat(configlist, " ")
-
+
return command and reloadcmd or os.execute(reloadcmd .. " >/dev/null 2>&1")
end
-- returns a boolean whether to delete the current section (optional)
function Cursor.delete_all(self, config, stype, comparator)
local del = {}
-
+
if type(comparator) == "table" then
local tbl = comparator
comparator = function(section)
if section[k] ~= v then
return false
end
- end
+ end
return true
end
end
-
+
local function helper (section)
if not comparator or comparator(section) then
return stat
end
+--- Get a boolean option and return it's value as true or false.
+-- @param config UCI config
+-- @param section UCI section name
+-- @param option UCI option
+-- @return Boolean
+function Cursor.get_bool(self, ...)
+ local val = self:get(...)
+ return ( val == "1" or val == "true" or val == "yes" or val == "on" )
+end
+
--- Get an option or list and return values as table.
-- @param config UCI config
-- @param section UCI section name
return false
end
-
-Cursor._changes = Cursor.changes
-function Cursor.changes(self, config)
- if config then
- return Cursor._changes(self, config)
- else
- local changes = Cursor._changes(self)
- util.copcall(function()
- for k,v in pairs(require "luci.fs".dir(self:get_savedir())) do
- if v ~= "." and v ~= ".." then
- util.update(changes, Cursor._changes(self, v))
- end
- end
- end)
- return changes
- end
-end
-
-
-- Return a list of initscripts affected by configuration changes.
function Cursor._affected(self, configlist)
configlist = type(configlist) == "table" and configlist or {configlist}
local function _resolve_deps(name)
local reload = {name}
local deps = {}
-
+
c:foreach("ucitrack", name,
function(section)
if section.affects then
end
end
end)
-
+
for i, dep in ipairs(deps) do
for j, add in ipairs(_resolve_deps(dep)) do
reload[#reload+1] = add
end
end
-
+
return reload
end
-
+
-- Collect initscripts
for j, config in ipairs(configlist) do
for i, e in ipairs(_resolve_deps(config)) do
end
end
end
-
+
return reloadlist
end
-- @param type UCI section type
-- @return Name of created section
---- Get a table of unsaved changes.
+--- Get a table of saved but uncommitted changes.
-- @class function
-- @name Cursor.changes
-- @param config UCI config
-- @return Table of changes
+-- @see Cursor.save
---- Commit unsaved changes.
+--- Commit saved changes.
-- @class function
-- @name Cursor.commit
-- @param config UCI config
-- @return Boolean whether operation succeeded
-- @see Cursor.revert
+-- @see Cursor.save
--- Deletes a section or an option.
-- @class function
-- @see Cursor.save
-- @see Cursor.unload
---- Revert unsaved changes.
+--- Revert saved but uncommitted changes.
-- @class function
-- @name Cursor.revert
-- @param config UCI config
-- @return Boolean whether operation succeeded
-- @see Cursor.commit
+-- @see Cursor.save
--- Saves changes made to a config to make them committable.
-- @class function