From edcd7b309885d0d01a8a84dfe212fae3fee711c0 Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Fri, 6 Nov 2015 15:45:04 +0000 Subject: Create bulkcreatedevices action --- provisioning-model.lua | 121 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 6 deletions(-) (limited to 'provisioning-model.lua') diff --git a/provisioning-model.lua b/provisioning-model.lua index 1f6c9c7..669ed4a 100644 --- a/provisioning-model.lua +++ b/provisioning-model.lua @@ -396,7 +396,7 @@ local get_device_params = function(device_id, editable) end -- This function is used by scripts, do not change prototype -local set_device_params = function(params, editable) +local set_device_params = function(params, editable, intransaction) -- Validate the settings local success = validateparam(params) local errtxt @@ -414,7 +414,7 @@ local set_device_params = function(params, editable) if not saved_device_params[params.value.device_id.value] then get_device_params(params.value.device_id.value) end local sql = "BEGIN TRANSACTION" - runsqlcommand(sql) + if not intransaction then runsqlcommand(sql) end if not editable then -- Delete all values for this device (can't do this if only updating editable) sql = "DELETE FROM provisioning_values WHERE device_id='"..provdb.escape(params.value.device_id.value).."'" @@ -437,7 +437,7 @@ local set_device_params = function(params, editable) end sql = "COMMIT" - runsqlcommand(sql) + if not intransaction then runsqlcommand(sql) end local tmp = saved_device_params[params.value.device_id.value] local p = params @@ -1558,7 +1558,7 @@ mymodule.create_device = function(self, device, action) return mymodule.update_device(self, device, action, true) end -mymodule.update_device = function(self, device, action, create) +mymodule.update_device = function(self, device, action, create, intransaction) local success = true local errtxt -- Validate the settings @@ -1586,7 +1586,7 @@ mymodule.update_device = function(self, device, action, create) if not saved_device_params[device.value.device_id.value] then get_device_params(device.value.device_id.value) end local sql = "BEGIN TRANSACTION" - runsqlcommand(sql) + if not intransaction then runsqlcommand(sql) end if create then sql = "SELECT nextval('provisioning_device_seq')" local tmp = getselectresponse(sql, true) @@ -1605,7 +1605,7 @@ mymodule.update_device = function(self, device, action, create) end sql = "COMMIT" - runsqlcommand(sql) + if not intransaction then runsqlcommand(sql) end local s = saved_device_params[device.value.device_id.value] callscript(updatedevicescriptfile, device, saved_devices[device.value.device_id.value], get_device_params(device.value.device_id.value), s) @@ -2287,4 +2287,113 @@ mymodule.create_from_request = function(self, request) return request end +mymodule.get_bulk_create_request = function(self, clientdata) + local retval = {} + retval.bulkdevicedata = cfe({ type="list", value={}, label="Bulk device list", descr="List of devices as comma-separated fields (first row must contain column headers)" }) + return cfe({ type="group", value=retval, label="Create Multiple Devices" }) +end + +mymodule.bulk_create_devices = function(self, devicelist) + local res, err = pcall(function() + local connected = databaseconnect() + + local groups = mymodule.list_class_groups() + + local headers = format.string_to_table(devicelist.value.bulkdevicedata.value[1], ",") + local reverseheaders = {} + for i,h in ipairs(headers) do + reverseheaders[h] = i + end + + runsqlcommand("BEGIN TRANSACTION") + for i=2,#devicelist.value.bulkdevicedata.value do + local values = format.string_to_table(devicelist.value.bulkdevicedata.value[i], ",") + + -- Create the device + local device = get_device(nil, true) + for name,class in pairs(device.value.classes.value) do + if reverseheaders[name] then + local value = values[reverseheaders[name]] + -- Allow the class value to be the class_id number or a unique string + local found = false + if tonumber(value) then + for k,c in ipairs(class.option) do + if tonumber(value) == tonumber(c.value) then + found = true + class.value = value + break + end + end + end + if not found then + -- Check for string match + for k,c in ipairs(class.option) do + if string.find(c.label, value) then + if found then + error("Ambiguous "..name.." class in line "..i) + end + found = c.value + end + end + if found then + class.value = found + else + error("Invalid "..name.." class in line "..i) + end + end + end + end + + device = mymodule.update_device(self, device, "Create", true, true) + + if device.errtxt then + local err = {"Failed to create device in line "..i} + err[#err+1] = device.errtxt + for n,v in pairs(device.value) do + if v.errtxt then + err[#err + 1] = v.errtxt + end + end + error(table.concat(err, "\n")) + end + + -- Set the params + local params = get_device_params(device.value.device_id.value, false) + for j,h in ipairs(headers) do + if values[j] and string.find(h, "%.") then + local class,param = string.match(h, "^([^.]+)%.(.*)") + if params.value[class] and params.value[class].value[param] then + params.value[class].value[param].value = values[j] + end + end + end + + params = set_device_params(params, false, true) + + if params.errtxt then + local err = {"Failed to create device in line "..i} + err[#err+1] = params.errtxt + for cname,cvalue in pairs(params.value) do + if type(cvalue.value) == "table" then + for pname,pvalue in pairs(cvalue.value) do + if pvalue.errtxt then + err[#err + 1] = cname.."."..pname..": "..pvalue.errtxt + end + end + end + end + error(table.concat(err, "\n")) + end + end + runsqlcommand("COMMIT") + if connected then provdb.databasedisconnect() end + end) + if not res and err then + pcall(function() runsqlcommand("ROLLBACK") end) + devicelist.errtxt = err + end + + return devicelist +end + return mymodule -- cgit v1.2.3