Moduli:CommonsData
Appearance
local p = {}
function p.importData(frame)
function listFields(sBase, iRecord)
if not sBase then
return nil
end
local b, vT = pcall(mw.ext.data.get, sBase .. ".tab")
if not(b and type(vT) == type({}) and vT.schema) then
return nil
end
local t = {}
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
t[sKey] = bIndex and i or v
elseif vFT[sKey or "key"] then
t[v[vFT[sKey or "key"]]] = bIndex and i or v
else
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
sClip = (sClip and listFields(sClip .. "/info", 1) or {})["postClip"]
sClip = sClip and string.sub(sClip, 6, -5)
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
if not t.val[sObject] then
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.invokeData(frame)
local t = {}
t.object = frame.args[1] or frame.args["object"]
if t.object then
local b, tSub = pcall(require, "Module:Data/" .. t.object)
if type(tSub) == type({}) then
t.selection = frame.args[2] or frame.args["selection"]
t.version = frame.args[3] or frame.args["version"]
t.key = frame.args[4] or frame.args["key"]
t.field = frame.args[5] or frame.args["field"]
for i, v in pairs(frame.args) do
t[i] = t[i] or v
end
if tSub.getData then
return tSub.getData(t)
else
return "[[Module:Data/" .. t.object .."]].getData"
end
else
return "[[Module:Data/" .. t.object .."]]"
end
else
return '<span class="error">object = ""</span>'
end
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
return frame.args[1]
end
return p