Test Wikimedia Commons
testcommonswiki
https://test-commons.wikimedia.org/wiki/Main_Page
MediaWiki 1.45.0-wmf.6
first-letter
Media
Special
Talk
User
User talk
Commons
Commons talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Creator
Creator talk
TimedText
TimedText talk
Sequence
Sequence talk
Institution
Institution talk
Data
Data talk
TimedText
TimedText talk
Module
Module talk
Translations
Translations talk
Module:TabUtils
828
2434
5025
5024
2025-06-16T20:06:00Z
Brooke Vibber (WMF)
1355
drop the inline, it's cute but not the best way to do that i fwe want to support it ;)
5025
Scribunto
text/plain
--
-- Experimental tabular data utilities for Chart transforms
-- See https://www.mediawiki.org/wiki/Extension:Chart/Transforms
--
local p = {}
--
-- build a map of column names -> indexes
-- @internal
--
function colmap( tab )
local cols = {}
for i, field in ipairs( tab.schema.fields ) do
cols[field.name] = i
end
return cols
end
--
-- select: subset a data set by column reference or comparison on row values
--
-- Arguments:
-- * cols: comma-separated list of column names to keep, otherwise returns all cols
-- * where: column name to match on, otherwise returns all rows
-- * eq, ne, gt, lt, gte, lte: value to compare against to keep rows
-- * sort: column name to sort on
-- * order: sort order "asc" or "desc", defaults to "asc"
--
function p.select( tab, args )
local map = colmap( tab )
local where = nil
if args.where then
local index = map[args.where]
local field = tab.schema.fields[index]
local function convert( val )
if field.type == "number" then
return tonumber( val )
elseif field.type == "localized" then
error( "todo: support localized fields" )
else
return val
end
end
local comparator
if args.eq then
local against = convert( args.eq )
comparator = function ( val )
return val == against
end
elseif args.ne then
local against = convert( args.ne )
comparator = function ( val )
return val ~= against
end
elseif args.gt then
local against = convert( args.gt )
comparator = function ( val )
return val > against
end
elseif args.lt then
local against = convert( args.lt )
comparator = function ( val )
return val < against
end
elseif args.gte then
local against = convert( args.gte )
comparator = function ( val )
return val >= against
end
elseif args.lte then
local against = convert( args.lte )
comparator = function ( val )
return val <= against
end
else
error( "'where' must provide argument for 'eq', 'ne', 'gt', 'lt', 'gte', or 'lte'" )
end
local newdata = {}
for _, row in ipairs( tab.data ) do
if comparator( row[index] ) then
table.insert( newdata, row )
end
end
tab.data = newdata
end
if args.cols then
local cols = mw.text.split( args.cols, ",", true )
local newfields = {}
local newdata = {}
for i, name in ipairs( cols ) do
table.insert( newfields, tab.schema.fields[map[name]] )
end
for n, row in ipairs( tab.data ) do
local newrow = {}
for i, name in ipairs( cols ) do
table.insert( newrow, row[map[name]] )
end
table.insert( newdata, newrow )
end
tab.schema.fields = newfields
tab.data = newdata
map = colmap( tab )
end
if args.sort then
local index = map[args.sort]
if not index then
error("Missing sort column: " .. args.sort)
end
local comparator
if args.order == "desc" then
comparator = function ( a, b )
return a[index] > b[index]
end
elseif args.order == "asc" or not args.order then
comparator = function ( a, b )
return a[index] < b[index]
end
else
error("Invalid sort order: " .. args.order)
end
table.sort( tab.data, comparator )
end
return tab
end
--
-- Convenience function for testing/debugging, run from console
-- while editing this module.
--
function p.demo()
local tab = mw.ext.data.get( "Sample_weekly_temperature_dataset.tab", "_" )
mw.logObject( p.select( tab, {
["cols"] = "month,high",
["where"] = "high",
["lt"] = "25"
} ) )
end
function p.demoSort(order)
local tab = mw.ext.data.get( "Sample_weekly_temperature_dataset.tab", "_" )
mw.logObject( p.select( tab, {
["cols"] = "month,high",
["sort"] = "high",
["order"] = order
} ) )
end
return p
a0e1xganwuwhra3ddbh66vkx5sgctjg
5026
5025
2025-06-16T20:28:28Z
Brooke Vibber (WMF)
1355
decimate option
5026
Scribunto
text/plain
--
-- Experimental tabular data utilities for Chart transforms
-- See https://www.mediawiki.org/wiki/Extension:Chart/Transforms
--
local p = {}
--
-- build a map of column names -> indexes
-- @internal
--
function colmap( tab )
local cols = {}
for i, field in ipairs( tab.schema.fields ) do
cols[field.name] = i
end
return cols
end
--
-- select: subset a data set by column reference or comparison on row values
--
-- Arguments:
-- * cols: comma-separated list of column names to keep, otherwise returns all cols
-- * where: column name to match on, otherwise returns all rows
-- * eq, ne, gt, lt, gte, lte: value to compare against to keep rows
-- * sort: column name to sort on
-- * order: sort order "asc" or "desc", defaults to "asc"
-- * decimate: keep only every nth row
--
function p.select( tab, args )
local map = colmap( tab )
if args.decimate then
local n = tonumber( args.decimate )
local newdata = {}
for i, row in ipairs( tab.data ) do
if i % n == 0 then
table.insert(newdata, row)
end
end
tab.data = newdata
end
local where = nil
if args.where then
local index = map[args.where]
local field = tab.schema.fields[index]
local function convert( val )
if field.type == "number" then
return tonumber( val )
elseif field.type == "localized" then
error( "todo: support localized fields" )
else
return val
end
end
local comparator
if args.eq then
local against = convert( args.eq )
comparator = function ( val )
return val == against
end
elseif args.ne then
local against = convert( args.ne )
comparator = function ( val )
return val ~= against
end
elseif args.gt then
local against = convert( args.gt )
comparator = function ( val )
return val > against
end
elseif args.lt then
local against = convert( args.lt )
comparator = function ( val )
return val < against
end
elseif args.gte then
local against = convert( args.gte )
comparator = function ( val )
return val >= against
end
elseif args.lte then
local against = convert( args.lte )
comparator = function ( val )
return val <= against
end
else
error( "'where' must provide argument for 'eq', 'ne', 'gt', 'lt', 'gte', or 'lte'" )
end
local newdata = {}
for _, row in ipairs( tab.data ) do
if comparator( row[index] ) then
table.insert( newdata, row )
end
end
tab.data = newdata
end
if args.cols then
local cols = mw.text.split( args.cols, ",", true )
local newfields = {}
local newdata = {}
for i, name in ipairs( cols ) do
table.insert( newfields, tab.schema.fields[map[name]] )
end
for n, row in ipairs( tab.data ) do
local newrow = {}
for i, name in ipairs( cols ) do
table.insert( newrow, row[map[name]] )
end
table.insert( newdata, newrow )
end
tab.schema.fields = newfields
tab.data = newdata
map = colmap( tab )
end
if args.sort then
local index = map[args.sort]
if not index then
error("Missing sort column: " .. args.sort)
end
local comparator
if args.order == "desc" then
comparator = function ( a, b )
return a[index] > b[index]
end
elseif args.order == "asc" or not args.order then
comparator = function ( a, b )
return a[index] < b[index]
end
else
error("Invalid sort order: " .. args.order)
end
table.sort( tab.data, comparator )
end
return tab
end
--
-- Convenience function for testing/debugging, run from console
-- while editing this module.
--
function p.demo()
local tab = mw.ext.data.get( "Sample_weekly_temperature_dataset.tab", "_" )
mw.logObject( p.select( tab, {
["cols"] = "month,high",
["where"] = "high",
["lt"] = "25"
} ) )
end
function p.demoSort(order)
local tab = mw.ext.data.get( "Sample_weekly_temperature_dataset.tab", "_" )
mw.logObject( p.select( tab, {
["cols"] = "month,high",
["sort"] = "high",
["order"] = order
} ) )
end
return p
3p58jcioul6t8knsya8tqf0yvzu10gn