Module:CargoUtil

local bool_false = { 'false', '0', 'no' } local argPrefix = 'q?'

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) local result = mw.ext.cargo.query(tbl, field, query) if result[1] then if result[1][field] == '' then return nil else return result[1][field] end else return nil end end

function p.getOneRow(tbl, fields, query) local result = mw.ext.cargo.query(tbl, table.concat(fields,','),query) if result[1] then for k, v in pairs(result[1]) do			if v == '' then result[1][k] = nil end end return result[1] else return {} end end

function p.strToBool(v) if bool_false[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			if v == '' then row[k] = nil elseif types[k] == 'boolean' then row[k] = p.strToBool(v) elseif types[k] == 'number' then row[k] = tonumber(v) end end end 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.sortByValueInTable(tblToSort, key, increasing) -- assume table is sorted as above table.sort(tblToSort, function (a,b)			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				return val_a > val_b and not increasing			end			val_a = tblToSort[a] and tblToSort[a][key] or 0			val_b = tblToSort[b] and tblToSort[b][key] or 0			return val_a > val_b and not increasing		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] = '' frame:callParserFunction{ name = '#cargo_store', args = tbl }	return end

return p