Module:CargoUtil
Jump to navigation
Jump to search
This module has no documentation. If you know how to use this template, please add some.
This module depends on: |
The above documentation is transcluded from Module:CargoUtil/doc. (edit | history)
local util_args = require('Module:ArgsUtil')
local bool_false = { ['false'] = true, ['0'] = true, ['no'] = true, [''] = true }
local argPrefix = 'q?'
local lang = mw.getLanguage('en')
local bool_to_str = { [true] = 'Yes', [false] = 'No' }
local p = {}
function p.makeMinMaxQuery(cargoquery, field, orderby, order)
-- modifies a pre-existing query to add an extra set of conditions to get the max/min value of some field
-- order will be either MIN or MAX, and orderby is usually going to be a date/datetime
-- example: c.makeMinMaxQuery(cargoquery, 'SP.Champion','SP.Time','MAX')
--to get the most-recent played champions
result = mw.ext.cargo.query(cargoquery.tables,
string.format("%s(%s)=thisvalue, %s=thisfield",
order,
orderby,
field
),
cargoquery)
local newcondition = {}
if not next(result) then
return cargoquery.where
end
for _, row in ipairs(result) do
newcondition[#newcondition+1] = string.format(
'(%s="%s" AND %s="%s")',
field,
row.thisfield,
orderby,
row.thisvalue
)
end
local newwhere = {
string.format("(%s)",table.concat(newcondition, ' OR ')),
}
if cargoquery.where and cargoquery.where ~= '' then
newwhere[2] = string.format("(%s)",cargoquery.where)
end
local cargowhere = table.concat(newwhere, ' AND ')
return cargowhere
end
function p.getOneResult(tbl, field, query, fieldtype)
if type(tbl) == 'table' then
query = tbl
else
query.tables = tbl
query.fields = field
query.types = {
field = fieldtype
}
end
local result = p.queryAndCast(query)
if result[1] then
return result[1][query.fields]
end
return nil
end
function p.getOneRow(query)
local result = p.queryAndCast(query)
return result[1] or {}
end
function p.getOneField(query, field)
local result = p.queryAndCast(query)
local tbl = {}
for i, row in ipairs(result) do
tbl[#tbl+1] = row[field]
end
return tbl
end
function p.strToBool(v)
if not v then
return false
elseif bool_false[lang:lc(v)] then
return false
end
return true
end
function p.queryAndCast(query, dontcast)
local tables = type(query.tables) == 'table' and table.concat(query.tables,',') or query.tables
local fields = type(query.fields) == 'table' and table.concat(query.fields,',') or query.fields
local result = mw.ext.cargo.query(tables, fields, query)
if dontcast then
return result
else
p.cast(result, query.types or {})
return result
end
end
function p.cast(result, types)
for i, row in ipairs(result) do
for k, v in pairs(row) do
row[k] = p.castField(v, types[k])
end
end
end
function p.castField(v, v_type)
if v == '' then
return nil
elseif v_type == 'boolean' then
return p.strToBool(v)
elseif v_type == 'number' then
return tonumber(v)
else
return v
end
end
function p.makeDict(result, key)
local tbl = {}
for _, row in ipairs(result) do
tbl[row[key]] = row
end
return tbl
end
function p.makeConstDict(result, key, value)
local tbl = {}
for _, row in ipairs(result) do
tbl[row[key]] = row[value]
end
return tbl
end
function p.makeOrderedDict(result, key, sortkey, increasing)
--[[
Format the table like this:
{
a1, a2, a3, a4,
a1 = { key = value, ... },
a2 = { key = value, ... },
a3 = { key = value, ... },
a4 = { key = value, ... }
}
]]
local tbl = {}
for k, row in ipairs(result) do
tbl[k] = row[key]
tbl[row[key]] = mw.clone(row)
end
if sortkey then
p.sortByValueInTable(tbl, sortkey, increasing)
end
return tbl
end
function p.makeOrderedList(result, key)
local tbl = {}
for k, row in ipairs(result) do
tbl[#tbl+1] = row[key]
end
return tbl
end
function p.groupResultOrdered(result, key, f)
local data = {}
local this
local thisvalue
local thistab
local i = 1
for _, row in ipairs(result) do
if not row[key] then row[key] = 'Uncategorized' end
if row[key] ~= thisvalue then
data[#data+1] = { name = row[key], index = i }
i = i + 1
thistab = data[#data] or {}
thisvalue = row[key]
end
thistab[#thistab+1] = f and f(row) or row
end
return data
end
function p.groupResultByValue(result, key, f)
local data = {}
local this
local thisvalue
local i = 1
for _, row in ipairs(result) do
if row[key] ~= thisvalue then
thisvalue = row[key]
data[thisvalue] = { name = row[key] }
i = i + 1
thistab = data[thisvalue]
end
thistab[#thistab+1] = f and f(row) or row
end
return data
end
function p.sortByValueInTable(tblToSort, key, increasing)
-- assume table is sorted as above
table.sort(tblToSort,
function (a,b)
if increasing then
local c = a
a = b
b = c
end
local val_a = tblToSort[a] and tonumber(tblToSort[a][key])
local val_b = tblToSort[b] and tonumber(tblToSort[b][key])
if val_a and val_b then
if val_a == val_b then
return (a < b)
end
return (val_a > val_b)
end
val_a = tblToSort[a] and tblToSort[a][key] or 0
val_b = tblToSort[b] and tblToSort[b][key] or 0
if val_a == val_b then
return (a > b)
end
return val_a > val_b
end
)
return
end
function p.queryFromArgs(args, defaults)
-- sometimes we want to specify query args in the template
-- this function parses them into args that cargo will understand
-- change argPrefix above to change the prefix for query params
local query = mw.clone(defaults or {})
for k, v in pairs(args) do
if string.sub(k, 0, 2) == argPrefix then
query[string.sub(k,3)] = v
end
end
return query
end
function p.store(tbl, frame)
if not frame then
frame = mw.getCurrentFrame()
end
tbl[1] = ''
for k, v in pairs(tbl) do
if type(v) == 'boolean' then
tbl[k] = bool_to_str[v]
end
end
frame:callParserFunction{
name = '#cargo_store',
args = tbl
}
return
end
function p.doWeStoreCargo(nocargo, desiredNamespace,title)
local argOkay = not util_args.castAsBool(nocargo)
if not desiredNamespace then
return argOkay
end
if not title then
title = mw.title.getCurrentTitle()
end
return argOkay and title.nsText == desiredNamespace
end
function p.whereFromArg(str, arg)
-- if an arg is defined, formats a string with the arg to be included in a where table
-- if it's not defined, returns false and NOT nil so the table can be used
-- with util_table.concat
if not arg then
return false
else
return str:format(arg)
end
end
function p.concatWhere(tbl)
local arr = {}
-- pairs because maybe some entries are nil, and since it's an AND, order doesn't matter
for _, v in pairs(tbl) do
if v then
arr[#arr+1] = v
end
end
return table.concat(arr, ' AND ')
end
function p.fakeHolds(field, str, sep)
sep = sep or ','
return ('%s__full RLIKE ".*(^|%s)%s($|%s).*"'):format(field, sep, str, sep)
end
return p