Module:Sequences

local p = {} local h = {}

local utilsArg = require('Module:UtilsArg') local utilsCargo = require('Module:UtilsCargo') local utilsMarkup = require('Module:UtilsMarkup') local utilsTable = require('Module:UtilsTable')

local cargoTable = "UniverseOrders" -- "Order" can't be used because it's an SQL keyword

function p.GetTable return cargoTable end

function p.CargoDeclare(frame) return utilsCargo.declare(cargoTable, {		media = "String",		universeOrder = "String",		name = "String",		ordinality = "Integer",	}) end

function p.CargoStore(frame) local args = frame:getParent.args args = utilsTable.mapValues(args, utilsString.trim) return h.store({		media = args.media or mw.title.getCurrentTitle.subpageText,		order = args[1],		names = utilsTable.slice(2)(args),	}) end

function p.SortValue(frame) local err = utilsArg.validate(frame.args, {		media = { nonEmpty = true },		name = { nonEmpty = true },	}) if err then return utilsMarkup.categories(err) end local media = frame.args.media local order = utilsString.nilIfEmpty(frame.args.order) local name = frame.args.name local sortValue = p.getSortValue(media, order, name) if not sortValue then local warn = ("Sort value not found for  in game  . Defaulting to alphabetical. See Data:Sort Values/%s for list of valid sort values.") :format(name, media, media) mw.addWarning(warn) return "" end local dataSortValue = string.format('data-sort-value="%s"|', sortValue) return dataSortValue end

function p.sort(media, order, names) utilsArg.nonEmpty(media, "media") utilsArg.nonEmpty(order, "order") utilsArg.required(names, "names") local queryResults = utilsCargo.query(cargoTable, "name", {		where = utilsCargo.allOf({ media = media, universeOrder = order }),		orderBy = "ordinality",	}) local validNames = utilsTable.map(queryResults, "name") local sorted = utilsTable.intersection(validNames)(names) local unsorted = utilsTable.difference(names)(sorted) return sorted, unsorted end

function p.getSortValue(media, order, name) local fields = "name, universeOrder=order, ordinality" local queryResults = utilsCargo.query(cargoTable, fields, {		where = utilsCargo.allOf({ media = media, name = name, universeOrder = order, }),		orderBy = "ordinality",	}) local sortValue = queryResults[1] and tonumber(queryResults[1].ordinality) return sortValue end

function h.store(args) local validator = utilsArg.validator({		media = { nonEmpty = true },		order = { nonEmpty = true },		names = { nonEmpty = true },	}) local err = validator(args) if err then return utilsMarkup.categories(err) end for i, v in ipairs(args.names) do		utilsCargo.store(cargoTable, {			media = args.media,			universeOrder = args.order,			ordinality = i,			name = v,		}) end end

local media = { type = "string", required = true, desc = "A string representing a game or other published media.", }

local order = { type = "string", desc = "A string identifiying some sort order.", }

p.Schemas = { sort = { media = media, order = order, names = { type = "array", required = true, items = { type = "string" }, desc = "An array of strings to sort according to the given sort order.", }	},	getSortValue = { media = media, order = order, name = { type = "string", required = true, desc = "Name to get sort value for.", }	} }

p.Documentation = { {		name = "sort", params = {"media", "order", "names"}, returns = { "The array of names, sorted according to the given order for the given media, minus those that aren't defined for that sort order.", "An array of the names that were not sorted." },		cases = { outputOnly = true, {				args = {"ST", "Realm", {"Fire Realm", "Sand Realm", "💩Realm", "Ocean Realm", "Forest Realm", "Fire Realm" }}, expect = { { "Forest Realm", "Ocean Realm", "Fire Realm", "Sand Realm" }, { "💩Realm" }, },			},		},	},	{		name = "getSortValue", params = {"media", "order", "name"}, returns = "Integer sort value of  for the given   in , or   if none found.", cases = { outputOnly = true, {				args = {"ST", "Realm", "Snow Realm"}, expect = 2 },			{				args = {"ST", "Realm", "💩 Realm"}, expect = nil },		}	}, }

return p