Module:CargoQuery

From Terraria Wiki
Jump to navigation Jump to search
Lua.svg Documentation The documentation below is transcluded from Module:CargoQuery/doc. (edit | history)

This module lets you get around Cargo bugs with html encoding.

To use, preface query arguments with q?. Even if you are only using one table or one field, use |q?tables= or |q?fields=.

Use Lua names of all query parameters, so |q?join=, |q?groupBy, etc.

Each method has several other parameters, which are detailed in their respective sections.

Methods

main

An example of the "no html" bug

Use this method to get around the bug with |no html|format=template. When using {{#cargo_query:tables=...|no html|template|template=... in templates, you may see html code on the page.

{{#invoke:CargoQuery|main
|q?tables= 	<!-- corresponds to table / tables -->
|q?join= 	<!-- corresponds to join on -->
|q?fields= 	<!-- corresponds to fields -->
|q?where= 	<!-- corresponds to where -->
|q?groupBy= 	<!-- corresponds to group by -->
|q?having= 	<!-- corresponds to having -->
|q?orderBy= 	<!-- corresponds to order by -->
|q?limit= 	<!-- corresponds to limit -->
|template=      <!-- pagename of template (required) -->
|delimiter=
|default=
}}

For simplicity of code, the named args parameter is required to be Yes, and you do not need to specify it.

Unlike |format=template, this wrapper will NOT rename parameters with underscores in them to use spaces instead.

This method can also be called from other modules, with arguments table as first parameter. For example:

local cargoQuery = require('Module:cargoQuery')
local tableRows = cargoQuery.main({['q?tables']=<tables>, ["q?fields"]=<fields>, template="cargoRow", default="no result", ... })

list

Use this method to get around the encoded html entity bug with |format=list. For example, you may see &#039; instead of ' in the result.

{{#invoke:CargoQuery|main
|q?tables= 	<!-- corresponds to table / tables -->
|q?join= 	<!-- corresponds to join on -->
|q?fields= 	<!-- corresponds to fields -->
|q?where= 	<!-- corresponds to where -->
|q?groupBy= 	<!-- corresponds to group by -->
|q?having= 	<!-- corresponds to having -->
|q?orderBy= 	<!-- corresponds to order by -->
|q?limit= 	<!-- corresponds to limit -->
|delimiter=
|default=
}}

Only the first field in the results will be used.

This method can be called from other modules, with arguments table as first parameter. For example:

local cargoQuery = require('Module:cargoQuery')
local listString = cargoQuery.list({['q?tables']=<tables>, ["q?fields"]=<field>, delimiter="/", default="no result", ... })

custom

This method can be called from other modules only. It accepts a callback function, can be used to customize result row formatting. For example:

local cargoQuery = require('Module:cargoQuery')
local output = cargoQuery.custom(
    {['q?tables']=<tables>, ["q?fields"]=<field>, delimiter="<br/>", default="no result", ... }, 
    function(row, args, frame)
        local tbl = {}
        for k, v in pairs(row) do
	        tbl[#tbl+1] = k .. ":" .. frame:expandTemplate{ title = "tr", args = {v} }
	    end
	    return table.concat(tbl, args.fieldsep or ',')
    end
)

afExport

Export the query result as an ArrayFunctions Array. This method can be used in templates only.

{{#invoke:CargoQuery|afExport
|q?tables= 	<!-- corresponds to table / tables -->
|q?join= 	<!-- corresponds to join on -->
|q?fields= 	<!-- corresponds to fields -->
|q?where= 	<!-- corresponds to where -->
|q?groupBy= 	<!-- corresponds to group by -->
|q?having= 	<!-- corresponds to having -->
|q?orderBy= 	<!-- corresponds to order by -->
|q?limit= 	<!-- corresponds to limit -->
|plainList = <!-- a fieldName in q?fields list-->
}}

The return array is a 2-dimensional array by default, for example(represented in JSON format):

{
    {name: 'John', age: 56},
    {name: 'Bob', age: 24},
    {name: 'Harry', age: 12}
}

If `plainList` is specified, the return array is a 1-dimensional array with values from that field only. In the above example, if `|plainList=name` is specified, the return array is:

{ 'John', 'Bob', 'Harry' }

Dependencies


local query = function(args)
	local query = {}
	for k, v in pairs(args) do
		if string.sub(k, 0, 2) == 'q?' then
			query[string.sub(k, 3)] = v
		end
	end
	return mw.ext.cargo.query(query.tables, query.fields, query)
end

local parse = function(x)
	local currentFrame = mw.getCurrentFrame()
	if x == currentFrame then
		-- being called from template, x is the frame object.
		return require('Module:ProcessArgs').merge(currentFrame.args, currentFrame:getParent().args, true), currentFrame
	else
		-- being called from module, x is the args table.
		return x, currentFrame
	end
end

local proc = function(x, rowHandle)
	local args, frame = parse(x)
	local result = query(args)
	if not next(result) then
		return args.default and frame:preprocess(args.default) or ''
	end
	local tbl = {}
	for _, row in ipairs(result) do
		tbl[#tbl+1] = rowHandle(row, args, frame)
	end
	return table.concat(tbl, args.delimiter or '')
end

------------------------------------------------------------------------

return {
	-- only for templates, export the query result as an arrayFunctions array.
	afExport = function(x)
		local args, frame = parse(x)
		local result = query(args)
		if args.plainList then
			local field = args.plainList
			local tbl = {}
			for _, row in ipairs(result) do
				tbl[#tbl+1] = row[field]
			end
			return mw.af.export(tbl)
		else
			return mw.af.export(result)
		end
	end,
	
	-- from template: {{#invoke:CargoQuery|main|q?tables=<tables>|q?fields=<fields>| ... }}
	-- from module: require('Module:cargoQuery').main({['q?tables']=<tables>, ["q?fields"]=<fields>, ... })
	main = function(x)
		return proc(x, function(row, args, frame)
			return frame:expandTemplate{ title = args.template, args = row }
		end)
	end,
	
	-- from template: {{#invoke:CargoQuery|list|q?tables=<tables>|q?fields=<field>| ... }}
	-- from module: require('Module:cargoQuery').list({['q?tables']=<tables>, ["q?fields"]=<field>, ... })
	list = function(x)
		return proc(x, function(row, args, frame)
			for _,v in pairs(row) do
				return v
			end
		end)
	end,
	
	-- from module only: require('Module:cargoQuery').callback(args, function(row, args, frame) --[[do something]] end)
	custom = proc,
}