Module:CargoTest2
Jump to navigation
Jump to search
Documentation for this module may be created at Module:CargoTest2/doc
local p = {}
local cargo = mw.ext.cargo
--[[-- Rather important requirements --]]--
local ytils = require('Module:Y_util');
local inft = require('Module:Infotable');
local ydebug,ytable,yxml,ystr = ytils.debug, ytils.table, ytils.xml, ytils.string;
--[[
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Frame_object
https://www.mediawiki.org/wiki/Extension:Cargo/Other_features#Lua_support
Relevant non-LUA/PHP Documentation:
https://www.mediawiki.org/wiki/Extension:Cargo/Querying_data
https://www.w3schools.com/sql/sql_where.asp
https://www.w3schools.com/sql/sql_operators.asp
`fields` is comma separated array of fields that we want to get from the table
- supports setting an alias for field `fields=_pageName=PGNM,Field2`
- no clue why you would do that, so do not do that.
`where` is an array of conditions, where the field values have to match for the field to be
- returned where params are separated with AND / OR
`orderBy` is comma separated array of fields
`limit` limits results, wow
example where strings (essentially SQL with = between WHERE and the conditions):
`WHERE=type LIKE 'Proj%' AND id LIKE '%blood%'`
- gets Projectiles, Projectile Modifiers, whose ID contains word blood
- % matches any or 0 characters in LIKE statements
`WHERE=sortKey='pathseeker'`
- gets all sort keys with pathseeker
HOLDS operator is Cargo builtin for querying fields containing comma separated values
Since `fields=` directly maps to SQL `SELECT`,
it is possible to use `fields=*` to get all fields
]]--
local function getTabbedVars( table2d )
local tab = 1;
local varsExist,vars = {},{};
if( type(table2d)=="table") then
for _,table1d in pairs(table2d) do
if( type(table1d)=="table") then
for prop,pval in pairs(table1d) do
local data = "";
if type(pval)=="string" or type(pval)=="number" then
data = tostring(pval);
end
varsExist[prop] = true;
vars[prop.."_"..tab] = data;
end
end
tab = tab + 1;
end
end
return {
tab_count=tab-1,
tab_vars=vars,
v_exists=varsExist,
};
end
--[[ Cargo Query Source Code For Supported Options
-- https://github.com/wikimedia/mediawiki-extensions-Cargo/blob/master/includes/CargoLuaLibrary.php
--]]
local mdl_enabledCargoQueryArgs = {
"where",
"orderBy",
"limit",
-- "offset"
-- "join",
-- "groupBy",
-- "having",
};
local function doCargoQuery( frameInvoke ) -- returns table2d: { spells(tabs)->{ variables } }
local res = nil;
if( frameInvoke ~= nil
and ystr.isStrExist(frameInvoke.tables)
and ystr.isStrExist(frameInvoke.fields)
and ystr.isStrExist(frameInvoke.where ) ) then
local cargoQueryArgs = {};
for _, arg in pairs(mdl_enabledCargoQueryArgs) do
if( ystr.isStrExist(frameInvoke[ arg ]) ) then
cargoQueryArgs[ arg ] = frameInvoke[ arg ];
end
end
res = cargo.query( -- for some reason the lua query splits the tables
frameInvoke.tables, -- and fields from the rest of the supported
frameInvoke.fields, -- arguments, which are all then passed into
cargoQueryArgs -- the function separately in a table
);
end
return res;
end
local mdl_blacklistCargoQueryArgs = {
"limit",
};
local mdl_optionKeyword = "box";
local mdl_debugKeyword = "debugging";
function p.Generate( frame )
local res = "Invoke Missing Arguments!";
if( frame == nil ) then
res = "No frame found, everything has broken down.";
else
if( frame.args ~= nil ) then
local frameInvoke = {};
local option = frame.args[ mdl_optionKeyword ];
if( ystr.isStrExist( option ) ) then
local test = inft.InvokeOpts[ option ];
if( test ~= nil ) then
frameInvoke = test;
end
end
local loopcount, looplimit = 0, 50;
for k,v in pairs(frame.args) do
loopcount = loopcount + 1;
if( looplimit < loopcount ) then break; end
if( ystr.isStrExist( k )
and ystr.isStrExist( v )
and not(ytable.hasValue( mdl_blacklistCargoQueryArgs, k )) ) then
frameInvoke[ k ] = v;
end
end
if( frameInvoke.fields == "*" ) then
local availableFields = ytable.getAllValStr( inft.TableField[ frameInvoke.tables ], frameInvoke.depth );
if( availableFields ~= nil ) then
frameInvoke.fields = table.concat( availableFields, "," );
end
end
res = "Query returned nothing!";
local cargoTable = doCargoQuery( frameInvoke ); -- a plain table2d
local vadata = getTabbedVars( cargoTable );
vadata.frame = frame;
vadata.table = string.match(frameInvoke.tables, "^([^,]*),?"); -- first table only
vadata.limit = ( frameInvoke.limit or 20 );
vadata.lang = ( frameInvoke.lang or "en" );
res = yxml.reindent( inft.Infobox[option]( vadata, frameInvoke ) ); -- infobox generator, see Module:Infotable
-- Debugging
local dbgLv = frameInvoke[ mdl_debugKeyword ];
if( dbgLv ~= nil ) then
local result = res;
if( ystr.isStrExist(result) ) then
result = result:gsub("<","<"):gsub(">",">");
end
res = "<div style=\"background-color:rgba(0,23,23,0.9);border:0.2em dashed #444;padding:1em;word-break:break-word;\">";
if( dbgLv:match("1") ) then res = res.."<br />\nDBG:frame\n<br />" ..ydebug.e2json( frame ); end
if( dbgLv:match("2") ) then res = res.."<br />\nDBG:fInvoke\n<br />" ..ydebug.e2json( frameInvoke ); end
if( dbgLv:match("3") ) then res = res.."<br />\nDBG:cargoTable\n<br />"..ydebug.e2json( cargoTable ); end
if( dbgLv:match("4") ) then res = res.."<br />\nDBG:vadata\n<br />" ..ydebug.e2json( vadata ); end
if( dbgLv:match("5") ) then res = res.."<br />\nDBG:result\n<br />" ..ydebug.e2json( result ); end
res = res.."</div>";
end
end
end
return res;
end
return p;