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 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 local tbl = {} for i, row in ipairs(result) do		row.index = i		tbl[#tbl+1] = frame:expandTemplate{ title = args.template, args = row } end local intro = frame:preprocess(args.intro or '') local outro = frame:preprocess(args.outro or '') if #result >= tonumber(args.limit or '100') then outro = outro .. frame:preprocess('') end return intro .. table.concat(tbl,args.delimiter or '') .. outro end

function h.merge local f = mw.getCurrentFrame local origArgs = f.args local parentArgs = f:getParent.args

local args = {} for k, v in pairs(origArgs) do		v = mw.text.trim(tostring(v)) if v ~= '' then args[k] = v		end end for k, v in pairs(parentArgs) 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

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

return p