|
|
(2 tussenliggende versies door 2 gebruikers niet weergegeven) |
Regel 1: |
Regel 1: |
| local p = {} | | local mt = {} |
|
| |
|
| function p.importData(frame) | | function mt.__index(t, k) |
| function listFields(sBase, iRecord) | | return function(frame) |
| if not sBase then
| | local data = mw.loadData(k) |
| return nil
| | local i = 1 |
| end
| | for _,v in ipairs(frame.args) do |
| local b, vT = pcall(mw.ext.data.get, sBase .. ".tab") | | local ty = type(data) |
| if not(b and type(vT) == type({}) and vT.schema) then
| | if ty ~= 'table' then |
| return nil
| | local args = {} |
| end
| | for j = 1, i - 1 do |
| local t = {} | | args[j] = frame.args[j] |
| for i, v in ipairs(vT.schema.fields) do | |
| if iRecord and vT.data[iRecord] then | |
| t[v.name] = vT.data[iRecord][i]
| |
| else
| |
| t[v.name] = i
| |
| end
| |
| end
| |
| return t
| |
| end
| |
| function listRecords(sBase, sKey, bIndex)
| |
| if not sBase then
| |
| return nil
| |
| end
| |
| local b, vT = pcall(mw.ext.data.get, sBase .. "/key.tab")
| |
| local vKT = b and type(vT) == type({}) and vT.data
| |
| b, vT = pcall(mw.ext.data.get, sBase .. ".tab")
| |
| if not(b and type(vT) == type({}) and vT.data) then
| |
| return nil
| |
| end
| |
| local vFT = listFields(sBase)
| |
| if not vFT then
| |
| return nil
| |
| end
| |
| local t = {}
| |
| for i, v in ipairs(vT.data) do
| |
| if vKT then
| |
| sKey = ""
| |
| for iK, vK in ipairs(vKT) do
| |
| sKey = sKey .. v[vFT[vK[1]]] or "" .. vK[2] or "" | |
| end | | end |
| t[sKey] = bIndex and i or v | | if frame.args.softfail then |
| elseif vFT[sKey or "key"] then
| | return '<span class="error">[[Category:Pages with failed Module:Data lookups]]Error: Tried to read index "' .. mw.text.nowiki(v) .. '" of mw.loadData("' .. mw.text.nowiki(k) .. '").' .. mw.text.nowiki(table.concat(args, '.')) .. ', which is a ' .. ty .. '</span>' |
| t[v[vFT[sKey or "key"]]] = bIndex and i or v
| | else |
| else
| | error('Tried to read index "' .. v .. '" of mw.loadData("' .. k .. '").' .. table.concat(args, '.') .. ', which is a ' .. ty) |
| return nil
| |
| end
| |
| end
| |
| return t
| |
| end
| |
| function selectTable(sBase, vKeyValue, nAdd, sKey)
| |
| if not sBase then
| |
| return nil
| |
| end
| |
| local sClip = tostring(sBase)
| |
| if type(vKeyValue) == type(nil) then
| |
| return nil
| |
| end
| |
| nAdd = tonumber(nAdd) or 0
| |
| while nAdd == nAdd - 1 do
| |
| nAdd = nAdd / 2
| |
| end
| |
| repeat
| |
| local t = listRecords(sClip, sKey)
| |
| if t and t[vKeyValue] then
| |
| return t[vKeyValue]
| |
| end
| |
| sClip = (sClip and listFields(sClip .. "/info", 1) or {})["postClip"]
| |
| sClip = sClip and string.sub(sClip, 6, -5)
| |
| until not sClip
| |
| if nAdd < 1 then
| |
| return nil
| |
| end
| |
| sClip = tostring(sBase)
| |
| local tNil = {}
| |
| local b, vT = pcall(mw.ext.data.get, sClip .. "/nil.tab")
| |
| if b and type(vT) == type({}) and vT.data then
| |
| for i, v in ipairs(vT.data) do
| |
| tNil[tostring(v[1])] = tostring(v[1])
| |
| end
| |
| end
| |
| nAdd = nAdd - 1
| |
| local t
| |
| sClip = sClip .. "/add"
| |
| repeat
| |
| b, vT = pcall(mw.ext.data.get, sClip .. ".tab")
| |
| if b and type(vT) == type({}) and vT.data then
| |
| vT["schema"] = listFields(sClip)
| |
| for i, v in ipairs(vT.data) do
| |
| if type(v[vT.schema["keySum"] or 1]) == type(vKeyValue) and v[vT.schema["keySum"] or 1] == vKeyValue then
| |
| local tT = {
| |
| ["fld"] = listFields(sBase),
| |
| ["val"] = selectTable(sBase, v[vT.schema["keySummand"] or 2], nAdd, sKey)
| |
| }
| |
| if tT.val then
| |
| if t then
| |
| for iF, vF in pairs(tT.fld) do
| |
| if tNil[iF] then
| |
| t[vF] = nil
| |
| else
| |
| if not type(t[vF]) == type(tT.val[vF]) then
| |
| t[vF] = nil
| |
| elseif type(t[vF]) == type(0) then
| |
| t[vF] = t[vF] + tT.val[vF]
| |
| elseif type(t[vF]) == type("") then
| |
| t[vF] = t[vF] .. ", " .. tT.val[vF]
| |
| else
| |
| t[vF] = nil
| |
| end
| |
| end
| |
| end
| |
| else
| |
| t = tT.val
| |
| end
| |
| else
| |
| return nil
| |
| end
| |
| end
| |
| end | | end |
| end | | end |
| sClip = (sClip and listFields(sClip .. "/info", 1) or {})["postClip"] | | data = data[v] |
| sClip = sClip and string.sub(sClip, 6, -5)
| | i = i + 1 |
| until not sClip
| |
| return t
| |
| end
| |
| local tField = {
| |
| ["object error"] = "objectError",
| |
| ["selection error"] = "selectionError",
| |
| ["key error"] = "keyError",
| |
| ["field error"] = "fieldError",
| |
| ["key addition"] = "keyAddition",
| |
| ["arg 1"] = "arg1"
| |
| }
| |
| local sField = frame.args[5] or frame.args["field"]
| |
| if tField[sField] then
| |
| return frame.args[tField[sField]] or ""
| |
| end
| |
| local sBase = "Data"
| |
| tField["object table link"] = "[[commons:Data:" .. sBase .. ".tab]]"
| |
| if tField[sField] then
| |
| return tField[sField]
| |
| end
| |
| local sObject = frame.args[1] or frame.args["object"]
| |
| if sObject then
| |
| local t = {
| |
| ["fld"] = listFields(sBase),
| |
| ["val"] = listRecords(sBase, "object")
| |
| }
| |
| local sClip = sBase
| |
| while not t.val[sObject] do
| |
| local tInfo = listFields(sClip .. "/info", 1) | |
| if not (tInfo and tInfo["postClip"]) then
| |
| break
| |
| end
| |
| sClip = string.sub(tostring(tInfo["postClip"]), 6, -5)
| |
| t.val = listRecords(sClip, "object")
| |
| end | | end |
| if not t.val[sObject] then | | return data |
| return frame.args["objectError"] or '<span class="error">[[commons:Data:' .. sBase .. '.tab]]!object</span>'
| |
| end
| |
| if not t.val[sObject][t.fld["table"]] then
| |
| return '<span class="error">[[commons:Data:' .. sBase .. '.tab]]!table</span>'
| |
| end
| |
| sBase = string.sub(tostring(t.val[sObject][t.fld["table"]]), 6, -5)
| |
| tField["selection table link"] = "[[commons:Data:" .. sBase .. ".tab]]"
| |
| if tField[sField] then
| |
| return tField[sField]
| |
| end
| |
| local vSelection = frame.args[2] or frame.args["selection"]
| |
| local sSelectionName = frame.args["selectionName"]
| |
| if not tonumber(vSelection) then
| |
| sSelectionName = vSelection
| |
| end
| |
| vSelection = tonumber(vSelection)
| |
| if vSelection or sSelectionName then
| |
| t = {
| |
| ["fld"] = listFields(sBase),
| |
| ["val"] = listRecords(sBase, "selection"),
| |
| ["vnm"] = listRecords(sBase, "selectionName")
| |
| }
| |
| sClip = sBase
| |
| while not (t.val[vSelection] or t.vnm[sSelectionName]) do
| |
| local tInfo = listFields(sClip .. "/info", 1)
| |
| if not (tInfo and tInfo["postClip"]) then
| |
| break
| |
| end
| |
| sClip = string.sub(tostring(tInfo["postClip"]), 6, -5)
| |
| t.val = listRecords(sClip, "selection")
| |
| t.vnm = listRecords(sClip, "selectionName")
| |
| end
| |
| if not (t.val[vSelection] or t.vnm[sSelectionName]) then
| |
| return frame.args["selectionError"] or '<span class="error">[[commons:Data:' .. sBase .. '.tab]]!selection</span>'
| |
| end
| |
| if not (t.val[vSelection] or t.vnm[sSelectionName])[t.fld["table"]] then
| |
| return '<span class="error">[[commons:Data:' .. sBase .. '.tab]]!table</span>'
| |
| end
| |
| sBase = string.sub(tostring((t.val[vSelection] or t.vnm[sSelectionName])[t.fld["table"]]), 6, -5)
| |
| tField["version table link"] = "[[commons:Data:" .. sBase .. ".tab]]"
| |
| if tField[sField] then
| |
| return tField[sField]
| |
| end
| |
| local vVersion = frame.args[3] or frame.args["version"]
| |
| local sVersionDate = frame.args["versionDate"]
| |
| if not tonumber(vVersion) then
| |
| sVersionDate = vVersion
| |
| end
| |
| vVersion = tonumber(vVersion)
| |
| if vVersion or sVersionDate or frame.args["current"] then
| |
| local tInfo = listFields(sBase .. "/info", 1)
| |
| if not (vVersion or sVersionDate) then
| |
| vVersion = tonumber(tInfo["currentVersion"])
| |
| end
| |
| t = {
| |
| ["fld"] = listFields(sBase),
| |
| ["val"] = listRecords(sBase, "version"),
| |
| ["vdt"] = listRecords(sBase, "versionDate")
| |
| }
| |
| sClip = sBase
| |
| while not (t.val[vVersion] or t.vdt[sVersionDate]) do
| |
| tInfo = listFields(sClip .. "/info", 1)
| |
| if not (tInfo and tInfo["postClip"]) then
| |
| break
| |
| end
| |
| sClip = string.sub(tostring(tInfo["postClip"]), 6, -5)
| |
| t.val = listRecords(sClip, "version")
| |
| t.vdt = listRecords(sClip, "versionDate")
| |
| end
| |
| if not (t.val[vVersion] or t.vdt[sVersionDate]) then
| |
| return frame.args["versionError"] or '<span class="error">[[commons:Data:' .. sBase .. '.tab]]!version</span>'
| |
| end
| |
| if not (t.val[vVersion] or t.vdt[sVersionDate])[t.fld["table"]] then
| |
| return '<span class="error">[[commons:Data:' .. sBase .. '.tab]]!table</span>'
| |
| end
| |
| sBase = string.sub(tostring((t.val[vVersion] or t.vdt[sVersionDate])[t.fld["table"]]), 6, -5)
| |
| tInfo = listFields(sBase .. "/info", 1)
| |
| for i, v in pairs(tInfo) do
| |
| tField[i .. " info"] = v
| |
| end
| |
| tField["value table link"] = "[[commons:Data:" .. sBase .. ".tab]]"
| |
| if tField[sField] then
| |
| return tField[sField]
| |
| end
| |
| local vKey = frame.args[4] or frame.args["key"]
| |
| if vKey then
| |
| t = {
| |
| ["fld"] = listFields(sBase),
| |
| ["val"] = selectTable(sBase, vKey, 0, "key"),
| |
| ["add"] = selectTable(sBase, vKey, 5, "key")
| |
| }
| |
| sClip = sBase
| |
| while not (t.add and t.fld and t.add[t.fld[sField]]) do
| |
| tInfo = listFields(sClip .. "/info", 1)
| |
| if not (frame.args["tryOther"] and tInfo and tInfo["postVersion"]) then
| |
| break
| |
| end
| |
| sClip = string.sub(tostring(tInfo["postVersion"]), 6, -5)
| |
| t.val = selectTable(sClip, vKey, 0, "key")
| |
| t.add = selectTable(sClip, vKey, 5, "key")
| |
| end
| |
| if t.fld and t.fld[sField] and not t.add then
| |
| if vKey == "" then
| |
| return ""
| |
| end
| |
| return frame.args["keyError"] or '<span class="error">[[commons:Data:' .. sBase .. '.tab]]!key*</span>'
| |
| end
| |
| if t.fld and t.fld[sField] then
| |
| return t.add[t.fld[sField]]
| |
| end
| |
| tField["key note"] = (t.val or not t.add) and "" or frame.args["keyAddition"]
| |
| if tField[sField] then
| |
| return tField[sField]
| |
| end
| |
| for i, v in pairs(t.fld) do
| |
| tField[i] = v
| |
| end
| |
| end
| |
| end
| |
| end
| |
| end
| |
| tField["field list"] = ""
| |
| if tField[sField] then
| |
| local s = ""
| |
| local t = {}
| |
| for i, v in pairs(tField) do
| |
| t[#t + 1] = i
| |
| end
| |
| table.sort(t)
| |
| for i, v in pairs(t) do
| |
| s = s .. "* " .. v .. "\n"
| |
| end
| |
| return s
| |
| end
| |
| return frame.args["fieldError"] or '<span class="error">field = "field list"</span>'
| |
| end
| |
| | |
| function p.evaluate(frame)
| |
| if tonumber(frame.args[1]) then
| |
| return mw.getCurrentFrame():callParserFunction("#expr", mw.ustring.gsub(frame.args[2], "#", frame.args[1]))
| |
| end | | end |
| return frame.args[1]
| |
| end | | end |
|
| |
|
| return p | | return setmetatable({}, mt) |