Module:CargoQuery

local PARAM_LOOKUP = { ['order by'] = 'orderBy', ['join on'] = 'join', ['group by'] = 'groupBy', table = 'tables', }

local h = {}

local p = {} function p.main(frame) local args = h.merge local intro = frame:preprocess(args.intro or '') local outro = frame:preprocess(args.outro or '') local delimiter = args.delimiter or '' local colcount = args.columns or nil local format = args.format or nil result = p.query(args) if (result == args.default or result == '') then return result end local tbl = {} if format == "table" then return (intro .. tostring(h.makeTable(result)) .. outro) else for i, row in ipairs(result) do			row.index = i			tbl[#tbl+1] = frame:expandTemplate{ title = args.template, args = row } end if colcount ~= nil then intro = (intro .. '') outro = ' ' ..outro end if format == "ul" then intro = intro .. "" outro = "" .. outro delimiter = "" end return intro .. table.concat(tbl, delimiter) .. outro end end

function p.query(args) local frame = mw.getCurrentFrame local query = {} for k, v in pairs(args) do		if string.sub(k, 0, 2) == 'q?' then local key = string.sub(k, 3) query[PARAM_LOOKUP[key] or key] = v		elseif PARAM_LOOKUP[k] then query[PARAM_LOOKUP[k]] = v		else query[k] = v		end end if args.one_to_many then query.fields = query.fields .. ',' .. query.one_to_many end local result = mw.ext.cargo.query(query.tables, query.fields, query) if #result == 0 then return frame:preprocess(args.default or '') end if args.one_to_many then result = h.groupOneToManyFields(result, h.getOneToManyTableFromArgs(args)) h.concatOneToManyFieldsInEachRow(result, args.one_to_many_sep or ',') end return result end

-- This function on Leaguepedia is part of Module:ArgsUtil but is copied here to avoid dependencies function h.merge(mergeParent) mergeParent = mergeParent or true local f = mw.getCurrentFrame local origArgs = f.args

local args = {} if mergeParent then local parentArgs = f:getParent.args for k, v in pairs(parentArgs) do			v = mw.text.trim(tostring(v)) if v ~= '' then args[k] = v			end end end for k, v in pairs(origArgs) do		v = mw.text.trim(v) if v ~= '' then args[k] = v		end end return args end

function h.getOneToManyTableFromArgs(args) local oneToMany = { fields = mw.text.split(args.one_to_many, '%s*,%s*'), groupBy = { args.one_to_many_group }, }	return oneToMany end

-- These functions on Leaguepedia are part of Module:CargoUtil but are copied here to avoide dependencies -- Some code is updated to avoid further dependencies function h.groupOneToManyFields(result, oneToMany) if not oneToMany then return result end local currentKey local groupedResult = {} local fields = h.parseFieldsForKeys(oneToMany.fields) for _, row in ipairs(result) do		local newKey = h.getNewKey(row, oneToMany.groupBy) if newKey == currentKey then h.addRowToExistingGroup(groupedResult, row, fields) else h.addRowToNewGroup(groupedResult, row, fields) currentKey = newKey end end return groupedResult end

function h.parseFieldsForKeys(fields) for i, v in ipairs(fields) do		fields[i] = h.parseOneFieldForKey(v) end return fields end

function h.getNewKey(row, groupBy) local toConcat = {} for _, v in ipairs(groupBy) do		toConcat[#toConcat+1] = row[v] end return table.concat(toConcat) end

function h.parseOneFieldForKey(str) if not str:find('=') then return str end return str:match('=(.+)') end

function h.addRowToExistingGroup(groupedResult, row, fields) for _, v in ipairs(fields) do		local parentRowValues = groupedResult[#groupedResult][v] parentRowValues[#parentRowValues+1] = row[v] end end

function h.addRowToNewGroup(groupedResult, row, fields) for _, v in ipairs(fields) do		row[v] = { row[v] } end groupedResult[#groupedResult+1] = row end

function h.concatOneToManyFieldsInEachRow(result, sep) for _, row in ipairs(result) do		for k, v in pairs(row) do			if type(v) == 'table' then row[k] = table.concat(v, sep) end end end end

function p.compound(frame) local util_args = require('Module:Args Utility') local util_table = require('Module:Table Utility')

local args = h.merge(false)

template = frame:preprocess(args['template'] or '') if template == nil or template == '' then error('A template must be specified!') end delimiter = frame:preprocess(args['delimiter'] or '') metasep = frame:preprocess(args['metaseparator'] or ';')

local splitargs = {} for a, b in ipairs(args) do splitargs[a] = util_args.splitNamedArgs(frame:preprocess(b), '%s*' .. metasep .. '%s*') end splitargs['default'] = ''

local result = {} for a, b in ipairs(splitargs) do   		tempresult = p.query(b) if tempresult ~= nil and tempresult ~= '' then result[#result+1] = tempresult end end if result == args.default or result == '' then return result end resulttbl = util_table.mergeArrays(nil, unpack(result)) local tbl = {} for i, row in ipairs(resulttbl) do		row.index = i		tbl[#tbl+1] = frame:expandTemplate{title = args['template'], args = row} end if #tbl == 0 then return frame:preprocess(args['default'] or 'no results') end local intro = frame:preprocess(args['intro'] or '') local outro = frame:preprocess(args['outro'] or '') return intro .. table.concat(tbl, delimiter) .. outro end

function h.getColNames(row) cols = {} for colname, _ in pairs(row)do table.insert(cols, colname) end return cols end

function h.makeTable(result) local util_html = require'Module:HTML Utility' local tbl = mw.html.create('table') :addClass('wikitable') colNames = h.getColNames(result[1]) util_html.printHeader(tbl, colNames) util_html.printRowsByList(tbl, result, colNames) return tbl end

return p