Zelda Wiki

Want to contribute to this wiki?
Sign up for an account, and get started!

Come join the Zelda Wiki community Discord server!

READ MORE

Zelda Wiki
mNo edit summary
No edit summary
Line 1: Line 1:
 
local p = {}
 
local p = {}
 
local h = {}
 
local h = {}
 
local utilsString = require("Module:UtilsString")
 
local utilsTable = require("Module:UtilsTable")
 
   
 
local frame = mw.getCurrentFrame()
 
local frame = mw.getCurrentFrame()
Line 54: Line 51:
   
 
function p.IN(field, values)
 
function p.IN(field, values)
values = utilsTable.map(escape)(values)
+
for i, value in ipairs(values) do
  +
value = escape(value)
values = utilsTable.map(utilsString.format("'%s'"))(values)
 
  +
value = string.format("'%s'", value)
  +
values[i] = value
  +
end
 
values = table.concat(values, ", ")
 
values = table.concat(values, ", ")
 
if values == "" then
 
if values == "" then

Revision as of 20:19, 10 April 2020

This module is a wrapper over mw.ext.cargo. It also provides utilities for constructing queries.

Using this module instead of using mw.ext.cargo directly allows us to see via Special:WhatLinksHere what pages are running Cargo queries.


local p = {}
local h = {}

local frame = mw.getCurrentFrame()

function p.declare(cargoTable, fields)
	return frame:callParserFunction{
        name = '#cargo_declare:_table=' .. cargoTable,
        args = fields
    }
end

function p.store(cargoTable, fields)
	frame:callParserFunction{
        name = '#cargo_store:_table=' .. cargoTable,
        args = fields
    }
end

function p.query(tables, fields, args)
	return mw.ext.cargo.query(tables, fields, args)
end

local function escape(str)
	return string.gsub(str, "'", "\\'")
end

function p.allOf(...)
	local query
	for i, v in ipairs({...}) do
		if type(v) == "table" then
			for k, v in pairs(v) do
				v = escape(v)
				query = h.andClause(query, string.format("%s='%s'", k, v))
			end
		else
			query = h.andClause(query, v)
		end
	end
	return query
end

function p.holdsAny(field, values)
	local query
	for i, value in ipairs(values) do
		value = escape(value)
		query = h.orClause(query, string.format("%s HOLDS '%s'", field, value))
	end
	return query
end

function p.IN(field, values)
	for i, value in ipairs(values) do
		value = escape(value)
		value = string.format("'%s'", value)
		values[i] = value
	end
	values = table.concat(values, ", ")
	if values == "" then
		values = "''"
	end
	return string.format("%s IN (%s)", field, values)
end

function h.andClause(query, clause)
	return h.addClause("AND", query, clause)
end

function h.orClause(query, clause)
	return h.addClause("OR", query, clause)
end

function h.addClause(operator, query, clause)
	if not query or query == "" then
		return clause
	end
	return table.concat({query, operator, clause}, " ")
end


p.Schemas = {
	declare = {
		tableName = {
			type = "string",
			required = true,
		},
		fields = {
			type = "map",
			required = true,
			keys = { type = "string" },
			values = { type = "string" },
		},
	},
	store = {
		tableName = {
			type = "string",
			required = true,
		},
		fields = {
			type = "map",
			required = true,
			keys = { type = "string" },
			values = { type = "string" },
		},
	},
	query = {
		tables = {
			type = "string",
			required = true,
		},
		fields = {
			type = "string",
			required = true,
		},
		args = {
			type = "record",
			properties = {
				{
					name = "where",
					type = "string",
				},	
				{
					name = "join",
					type = "string",
				},
				{
					name = "groupBy",
					type = "string",
				},
				{
					name = "having",
					type = "string",
				},
				{
					name = "orderBy",
					type = "string",
				},
				{
					name = "limit",
					type = "number",
					default = 100,
				},
				{
					name = "offset",
					type = "number",
					default = 0,
				},
			}
		},
	},
	allOf = {
		["..."] = {
			type = "array",
			required = true,
			items = {
				oneOf = {
					{
						type = "string",
					},
					{
						type = "map",
						keys = { type = "string" },
						values = { type = "string" },
					},
				},
			}
		},
	},
	holdsAny = {
		field = {
			type = "string",
			required = true,
		},
		values = {
			type = "array",
			required = true,
			items = { type = "string" },
		}
	},
	IN = {
		field = {
			type = "string",
			required = true,
		},
		values = {
			type = "array",
			required = true,
			items = { type = "string" },
		},
	}
}

p.Documentation = {
	{
		name = "declare",
		params = {"tableName", "fields"},
	},
	{
		name = "store",
		params = {"tableName", "fields"},
	},
	{
		name = "query",
		params = {"tables", "fields", "args"},
		returns = "An array of the query results. Throws an error when query syntax is invalid.",
		cases = {
			{
				args = {
					"Games",
					"initialism, subtitle",
					{
						where = "type='main' AND mainrelease !=''",
						orderBy = "mainrelease",
						limit = 3,
					},
				},
				expect = {
					{ initialism = "TLoZ", subtitle = "The Legend of Zelda"},
					{ initialism = "TAoL", subtitle = "The Adventure of Link"},
					{ initialism = "ALttP", subtitle = "A Link to the Past"},
				},
			},
		}
	},
	{
		name = "allOf",
		params = {"..."},
		returns = "A WHERE clause with ANDed conditions and escaped quotation marks.",
		cases = {
			outputOnly = true,
			{
				args = {
					{
						game = "Link's Awakening",
						remakeNum = 2,
					},
					"foo HOLDS 'bar'",
					"baz LIKE '%quux%'",
				},
				expect = [[remakeNum='2' AND game='Link\'s Awakening' AND foo HOLDS 'bar' AND baz LIKE '%quux%']]
			}
		},
	},
	{
		name = "holdsAny",
		params = {"field", "values"},
		returns = "A query string of or'ed HOLDS clauses.",
		cases = {
			outputOnly = true,
			{
				args = {"game", {"Link's Awakening"}},
				expect = "game HOLDS 'Link\\'s Awakening'",
			},
			{
				args = {"game", {"OoT", "TP"}},
				expect = "game HOLDS 'OoT' OR game HOLDS 'TP'",
			}
		}
	},
	{
		name = "IN",
		params = {"field", "values"},
		returns = "A where clause using the SQL IN keyword.",
		cases = {
			outputOnly = true,
			{
				args = {"_pageName", {"Link's Shadow", "Zelda", "Ganon"}},
				expect = [[_pageName IN ('Link\'s Shadow', 'Zelda', 'Ganon')]],
			},
			{
				args = {"_pageName", {}},
				expect = [[_pageName IN ('')]],
			}
		}
	}
}

return p