Module:Page/Condition/sandbox

local model = require("Module:Data").model local cargo = require('Module:CargoUtil') local util_table = require('Module:TableUtil')

local render_gear = require('Module:Render/Gear') local render_item = require('Module:Render/Item') local render_job = require('Module:Render/Job')

local langs = {"english", "japanese"}

local function benchmark(f, ...) local multiplier = 1000 local now = os.clock local result = f(...) local elapsed = (os.clock - now) mw.log(("Duration: %.3fms"):format(elapsed * multiplier)) return result end

local p = {} local p2 = { sources = function(frame) local args = require('Module:Arguments').getArgs(frame, {     parentFirst = true,    }) local conditionName = args[2] local server = args.server or 'gl' local lang = args.lang local function tablesFor(whereType, msg) local conditions = model.query('Conditions', 'iname', {where = whereType..' AND server="'..server..'" AND conds HOLDS '..args[1]}) local skills = model.sources.cond.skill(conditions, nil, {'name', 'expr', lang = lang}, 'server="'..server..'"') local abilities = model.sources.skill.ability(skills, nil, nil, 'server="'..server..'"') local sb = {} --     -- Jobs -- --     local jobs = model.sources.ability.job(abilities, nil, nil, 'server="'..server..'"') if #jobs > 0 then table.sort(jobs, function(a, b) return a.iname < b.iname end) -- TODO: Need to support abilities beyond main sb[#sb+1] = '\n=== Skills which '..msg..' '..conditionName..' that are fixed to a job: ===\n{| class="wikitable frozen-header sortable" \n!Job\n!Skill\n!Description' for _, job in ipairs(jobs) do         -- TODO: Wire into Module:Render/Job sb[#sb+1] = '\n|-\n| '..(#job._links.skill > 1 and 'rowspan='..#job._links.skill..' | ' or '') sb[#sb+1] = render_job._icon({job.iname, size='small'}) for i, skill in ipairs(job._links.skill) do           sb[#sb+1] = (i > 1 and '\n|-' or '')..'\n| '..skill.name..'\n| '..skill.expr end end sb[#sb+1] = '\n|}' end ---     -- Artifacts -- ---     local artifacts = model.sources.ability.artifact(abilities, 'icon,rini', nil, 'server="'..server..'"') for _, artifact in ipairs(model.sources.skill.artifact(skills, 'icon,rini', nil, 'server="'..server..'"')) do       for _, skill in ipairs(artifact._links.skill) do skill.name = 'Basic Attack' end artifacts[#artifacts+1] = artifact end if #artifacts > 0 then table.sort(artifacts, function(a, b) return a.iname < b.iname end) sb[#sb+1] = '\n=== Skills which '..msg..' '..conditionName..' that are provided by gear: === \n{| class="wikitable frozen-header sortable" \n!Gear\n!Skill\n!Description' for _, artifact in ipairs(artifacts) do         sb[#sb+1] = '\n|-\n| '..(#artifact._links.skill > 1 and 'rowspan='..#artifact._links.skill..' | ' or '') sb[#sb+1] = render_gear._icon({artifact.iname, data = artifact, size = 'small'}) for i, skill in ipairs(artifact._links.skill) do           sb[#sb+1] = (i > 1 and '\n|-' or '')..'\n| '..skill.name..'\n| '..skill.expr end end sb[#sb+1] = '\n|}' end ---     -- Items -- ---     local items = model.sources.skill.item(skills, 'icon,rare,type', {'expr', lang = lang}, 'server="'..server..'"') if #items > 0 then table.sort(items, function(a, b) return a.iname < b.iname end) sb[#sb+1] = '\n=== Consumables which '..msg..' '..conditionName..' upon use: === \n{| class="wikitable frozen-header sortable" \n!Item\n!Description' for _, item in ipairs(items) do         sb[#sb+1] = '\n|-\n| '..render_item._icon({item.iname, data = item, size = 'small'})..'\n| '..item.expr end sb[#sb+1] = '\n|}' end sb[#sb+1] = '' return table.concat(sb) end return table.concat({     '== Skills Relating to this Condition ==',      tablesFor('Conditions.type<>1 AND Conditions.type<>5', 'inflict'),      tablesFor('Conditions.type=1', 'cure'),      tablesFor('Conditions.type=5', 'grant immunity to'),    }, '\n') end} local h = {}

function h.quote(s) if not s then return end return ('%q'):format(s) end

function h.compareInames(a, b)	return a.iname < b.iname end

function x(tableName, linksKey, customWhere, input, columns, loc, where) local hash = {} for _,inNode in ipairs(input) do   if type(inNode) == 'string' then inNode = {iname = inNode} end for _,outNode in ipairs(cargo.query{			tables = tableName,			fields = {'_pageName','iname',columns},			where = {				where,				customWhere(inNode),			},   }) do      if hash[outNode.iname] == nil then for _,param in ipairs(loc or {}) do       	outNode[param] = model.getLoc(outNode._pageName, param, loc.lang) end outNode._links = inNode._links or {} outNode._links[linksKey] = {inNode} hash[outNode.iname] = outNode else local links = hash[outNode.iname]._links[linksKey] links[#links+1] = inNode end end end local entries = {} for _,v in pairs(hash) do entries[#entries+1] = v end return entries end

function y(args) local function findNodes(inNode, outNodes, fields) local result = {} for _, outNode in ipairs(outNodes) do			local outNodeCopy = util_table.shallowClone(outNode) local found = false for i, field in ipairs(fields) do				if inNode.iname == util_table.remove(outNodeCopy, field) then found = true end end if found then util_table.push(result, outNodeCopy) end end return result end

function handleLangs(rows) local outNodes = {} local t = {} for _, row in ipairs(rows) do   	local lang = util_table.remove(row, 'lang') t[row.iname] = t[row.iname] or {} t[row.iname][lang] = row end for _, v in pairs(t) do			local node = {} for i, lang in ipairs(langs) do				for param, value in pairs(v[lang] or {}) do					if not node[param] then node[param] = value end end end util_table.push(outNodes, node) end return outNodes end

if args.outNodes[1] and args.outNodes[1].lang then args.outNodes = handleLangs(args.outNodes) end

local hash = {} for _, inNode in ipairs(args.inNodes) do		if type(inNode) == 'string' then inNode = {iname=inNode} end local foundNodes = findNodes(inNode, args.outNodes, args.fields) for _, outNode in ipairs(foundNodes) do			if hash[outNode.iname] == nil then outNode._links = inNode._links or {} outNode._links[args.linksKey] = {inNode} hash[outNode.iname] = outNode else util_table.push(hash[outNode.iname]._links[args.linksKey], inNode) end end end local entries = {} for _, v in pairs(hash) do		util_table.push(entries, v)	end table.sort(entries, h.compareInames) return entries end

function p.sources(frame) local args = require('Module:Arguments').getArgs(frame, {   parentFirst = true,  }) local conditionName = args[2] local server = args.server or 'gl' local lang = args.lang local function tablesFor(whereType, msg) local conditions = cargo.query{ tables = 'Conditions', fields = 'iname', where = { whereType, ('server = "%s"'):format(server), 'conds HOLDS '..args[1], }   }    local cids = util_table.extractValueToList(conditions, 'iname') cids = util_table.concat(cids, ',', h.quote)

-- local skills2 = model.sources.cond.skill(conditions, nil, {'name', 'expr', lang = lang}, 'server="'..server..'"') local skill_rows = cargo.query{ tables = 'Skill=A, SkillLoc=L', join = 'A.iname = L.iname', fields = 'A._pageName=_pageName, A.iname=iname, s_cond, t_cond, name, expr, lang', where = { ('A.server = "%s"'):format(server), ('lang IN (%s)'):format(util_table.concat(langs, ',', h.quote)), ('s_cond IN (%s) OR t_cond IN (%s)'):format(cids, cids), },   }    local skills = y{    	linksKey = 'cond', fields = {'s_cond', 't_cond'}, inNodes = conditions, outNodes = skill_rows, }   local skill_ids = util_table.extractValueToList(skills, 'iname') skill_ids = util_table.concat(skill_ids, ',', h.quote)

local ability_rows = cargo.query{ tables = 'Ability', fields = { '_pageName, iname', 'skl1, skl2, skl3, skl4, skl5, skl6, skl7, skl8, skl9, skl10', },   	where = { ('server = "%s"'):format(server), table.concat({	   		('skl1 IN (%s)'):format(skill_ids),	    		('skl2 IN (%s)'):format(skill_ids),	    		('skl3 IN (%s)'):format(skill_ids),	    		('skl4 IN (%s)'):format(skill_ids),	    		('skl5 IN (%s)'):format(skill_ids),	    		('skl6 IN (%s)'):format(skill_ids),	    		('skl7 IN (%s)'):format(skill_ids),	    		('skl8 IN (%s)'):format(skill_ids),	    		('skl9 IN (%s)'):format(skill_ids),	    		('skl10 IN (%s)'):format(skill_ids),	    	}, ' OR '), },   }    -- local abilities = model.sources.skill.ability(skills, nil, nil, 'server="'..server..'"') local abilities = y{   	linksKey = 'skill', fields = {'skl1', 'skl2', 'skl3', 'skl4', 'skl5', 'skl6', 'skl7', 'skl8', 'skl9', 'skl10'}, inNodes = skills, outNodes = ability_rows, }   local ability_ids = util_table.extractValueToList(abilities, 'iname') ability_ids = util_table.concat(ability_ids, ',', h.quote)

local sb = {} --   -- Jobs -- --

local job_rows = cargo.query{ tables = 'Job, JobLoc, Pages', join = 'Job.iname = JobLoc.iname, Job.iname = Pages.iname', fields = { 'Pages._pageName=_pageName', 'Job.iname=iname', 'Job.fixabl=fixabl', 'COALESCE(Job.ac2d,Job.mdl)=icon', 'JobLoc.name=name', 'JobLoc.lang=lang', },   	where = { ('server = "%s"'):format(server), ('lang IN (%s)'):format(util_table.concat(langs, ',', h.quote)), ('fixabl IN (%s)'):format(ability_ids), },   }    local jobs = y{    	linksKey = 'ability', fields = {'fixabl'}, inNodes = abilities, outNodes = job_rows, }

if #jobs > 0 then -- table.sort(jobs, function(a, b) return a.iname < b.iname end) -- TODO: Need to support abilities beyond main sb[#sb+1] = '\n=== Skills which '..msg..' '..conditionName..' that are fixed to a job: ===\n{| class="wikitable frozen-header sortable" \n!Job\n!Skill\n!Description' for _, job in ipairs(jobs) do       -- TODO: Wire into Module:Render/Job sb[#sb+1] = '\n|-\n| '..(#job._links.skill > 1 and 'rowspan='..#job._links.skill..' | ' or '') -- local jobData = { -- 	_pageName = job._pageName, -- 	iname = job.iname, -- 	icon = job.icon, -- 	name = job.name, -- }       sb[#sb+1] = render_job._icon2{data=job, size='small'} for i, skill in ipairs(job._links.skill) do         sb[#sb+1] = (i > 1 and '\n|-' or '')..'\n| '..skill.name..'\n| '..skill.expr end end sb[#sb+1] = '\n|}' end ---   -- Artifacts -- ---   -- local artifacts = model.sources.ability.artifact(abilities, 'icon,rini', nil, 'server="'..server..'"') local artifact_rows = cargo.query{ tables = { 'Artifact', 'Artifact__abils', 'ArtifactLoc', 'Pages', },   	join = { 'Artifact._ID = Artifact__abils._rowID', 'Artifact.iname = ArtifactLoc.iname', 'Artifact.iname = Pages.iname', },   	fields = { 'COALESCE(Pages._pageName,ArtifactLoc.name) = _pageName', -- '_pageName', 'Artifact.iname=iname', 'icon', 'rini', '_value=abil', 'ArtifactLoc.name=name', 'ArtifactLoc.lang=lang', },   	where = { ('server = "%s"'):format(server), ('lang IN (%s)'):format(util_table.concat(langs, ',', h.quote)), ('_value IN (%s)'):format(ability_ids), }   }    local artifacts = y{    	linksKey = 'ability', fields = {'abil'}, inNodes = abilities, outNodes = artifact_rows, }   -- local artifact_rows = model.sources.skill.artifact(skills, 'icon,rini', nil, 'server="'..server..'"') local artifact_rows = cargo.query{ tables = { 'Artifact', 'ArtifactLoc', 'Pages', },   	join = { 'Artifact.iname = ArtifactLoc.iname', 'Artifact.iname = Pages.iname', },   	fields = { 'COALESCE(Pages._pageName,ArtifactLoc.name) = _pageName', -- '_pageName', 'Artifact.iname = iname', 'icon', 'rini', 'attack1', 'attack2', 'attack3', 'attack4', 'attack5', 'equip1', 'equip2','equip3', 'equip4', 'equip5', 'ArtifactLoc.name=name', 'ArtifactLoc.lang=lang', },   	where = { ('server = "%s"'):format(server), ('lang IN (%s)'):format(util_table.concat(langs, ',', h.quote)), table.concat({   			('attack1 IN (%s)'):format(skill_ids),    			('attack2 IN (%s)'):format(skill_ids),    			('attack3 IN (%s)'):format(skill_ids),    			('attack4 IN (%s)'):format(skill_ids),    			('attack5 IN (%s)'):format(skill_ids),    			('equip1 IN (%s)'):format(skill_ids),    			('equip2 IN (%s)'):format(skill_ids),    			('equip3 IN (%s)'):format(skill_ids),    			('equip4 IN (%s)'):format(skill_ids),    			('equip5 IN (%s)'):format(skill_ids),    		}, ' OR '), }   }    local artifacts2 = y{    	linksKey = 'skill', fields = { 'attack1', 'attack2', 'attack3', 'attack4', 'attack5', 'equip1', 'equip2','equip3', 'equip4', 'equip5', },   	inNodes = skills, outNodes = artifact_rows, }   for _, artifact in ipairs(artifacts2) do      for _, skill in ipairs(artifact._links.skill) do skill.name = 'Basic Attack' end util_table.push(artifacts, artifact) end if #artifacts > 0 then table.sort(artifacts, function(a, b) return a.iname < b.iname end) sb[#sb+1] = '\n=== Skills which '..msg..' '..conditionName..' that are provided by gear: === \n{| class="wikitable frozen-header sortable" \n!Gear\n!Skill\n!Description' for _, artifact in ipairs(artifacts) do       sb[#sb+1] = '\n|-\n| '..(#artifact._links.skill > 1 and 'rowspan='..#artifact._links.skill..' | ' or '') sb[#sb+1] = render_gear._icon2{data = artifact, size = 'small'} for i, skill in ipairs(artifact._links.skill) do         sb[#sb+1] = (i > 1 and '\n|-' or '')..'\n| '..skill.name..'\n| '..skill.expr end end sb[#sb+1] = '\n|}' end ---   -- Items -- ---   -- local items = model.sources.skill.item(skills, 'icon,rare,type', {'expr', lang = lang}, 'server="'..server..'"') local t = {} local item_rows = cargo.query{ tables = { 'Item', 'ItemLoc', 'Pages', },     join = { 'Item.iname = ItemLoc.iname', 'Item.iname = Pages.iname', },     fields = { 'Pages._pageName=_pageName', 'Item.iname=iname', 'Item.icon=icon', 'Item.rare=rare', 'Item.type=type', 'Item.skill=skill', 'ItemLoc.name=name', 'ItemLoc.expr=expr', 'ItemLoc.lang=lang', },     where = { ('Item.server = "%s"'):format(server), ('ItemLoc.lang in (%s)'):format(util_table.concat(langs, ',', h.quote)), ('Item.skill IN (%s)'):format(skill_ids), }   }    local items = y{    	linksKey = 'skill', fields = {'skill'}, inNodes = skills, outNodes = item_rows, }

-- mw.logObject(items) if #items > 0 then table.sort(items, function(a, b) return a.iname < b.iname end) sb[#sb+1] = '\n=== Consumables which '..msg..' '..conditionName..' upon use: === \n{| class="wikitable frozen-header sortable" \n!Item\n!Description' for _, item in ipairs(items) do       sb[#sb+1] = '\n|-\n| '..render_item._icon2{data = item, size = 'small'}..'\n| '..(item.expr or '') end sb[#sb+1] = '\n|}' end sb[#sb+1] = '' return table.concat(sb) end

return table.concat({   '== Skills Relating to this Condition ==',    tablesFor('Conditions.type<>1 AND Conditions.type<>5', 'inflict'),    tablesFor('Conditions.type=1', 'cure'),    tablesFor('Conditions.type=5', 'grant immunity to'),  }, '\n') end

function p.test local that = p2 --require('Module:Page/Condition') local this = p local util_vars = require('Module:VarsUtil')

util_vars.setVar('cargo query count', 0) local a = benchmark(that.sources, {0, 'poison'}) local countA = util_vars.getVar('cargo query count')

util_vars.setVar('cargo query count', 0) local b = benchmark(this.sources, {0, 'poison'}) local countB = util_vars.getVar('cargo query count')

if a ~= b then mw.log("============================================================") mw.log("============================== THAT ========================") mw.log("============================================================") mw.log(a) mw.log("============================================================") mw.log("============================== THIS ========================") mw.log("============================================================") mw.log(b) end

mw.log('that: ' .. countA) mw.log('this: ' .. countB) return this.sources{0, 'poison'} end

return p