Modul:SmwUtil
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This module provides serveral useful function that can be used in other module to store or retrive data using semantic annotations.
Usage
local _SMW= require('Module:SmwUtil')
if dataStore == 'smw' and stash then
_SMW.set(stash)
end
local query = {
select = {'[[is public::yes]]', '[[is of type::datasheet]]', '[[has id::>>10]]'}
fields = {'_CDAT=Create date', 'bears name=nickname', 'works as=occupation', 'has siblings'}
}
local attributes = {
limit = 10,
mainlabel ='-'
}
local result = _SMW.ask(query, attributes)
Functions
Provided functions are as follow:
ask(query, attributes, retainBlanks)
Runs an ask query on the semantic mediawiki triple store according to the parameters provided and returns the result as a lua table. The first parameter (query) has the following fields:
- select
- table or string, mandatory
- the condition the query filters for. can be of string and arbitrarily complex or a table being either of format
,{ propertyname = 'value' }
or a mix of both{ '[[propertyname::value]]' }
- fields
- table or string, optional
- the fields, you want to get data from. format of values is fieldname or fieldname=headline (you can skip the preceeding ?). DO NOT USE AN ARRAY! All keys will be discarded! Please uses string only if you have just one field to display. If you want to format the fields and add a headline, please do it before the =, e.g. fieldname#km2=area
Please keep in mind:
- attributes may contain any attribute you find in the documentation, but intro and outro will be NILed, default and more results text will be set to the empty string, and format will be overwritten
- per default, does only return fields that contain a value. that can result in an "unbalanced" result, where one row contains more elements than others. if you want to get all fields, set
retainBlanks
to true
- query
- table, mandatory
- the arguments to construct the query. see above for details
- attributes
- table, optional
- more attributes, you want to pass on to the ask query (like limit, for instance)
- retainBlanks
- boolean, optional
- if set to true, result can contain entries with empty values. per default, these entries will be deleted
- return
- table, query result as a lua table. see the following printout as example
In contrast to Module:CargoUtil, SmwUtil's ask recognizes when a property holds a list of values and returns this as a lua table (see example below on property references). CargoUtils would treat this as a comma separated list. |
{
1 = {
1 = 'Extension:Cargo'
has id = '7'
references = { '901', '821' }
description = 'Cargo provides a lightweight way to store and query the data contained within the calls to templates, such as infoboxes in mysql tables.'
MainLabel = 'Extension:Cargo'
}
2 = {
1 = 'Extension:SyntaxHighlight GeSHi'
has id = '6'
references = '911'
description = 'The SyntaxHighlight GeSHi extension provides rich formatting of source code using the "syntaxhighlight"-tag. ...'
MainLabel = 'Extension:SyntaxHighlight GeSHi'
}
}
As you can see, the data fields can be indexed either by number or by the provided headline in table fields. (The headline is either the fieldname or a special string you provided via fieldname=headline. The mainlabel always has number 1 and whatever you passed on to attribute mainlabel (if nothing, default is MainLabel).
get(page, field)
A shortcut for show(page, field).
lua(query, attributes, retainBlanks)
A shortcut for ask(query, attributes, retainBlanks).
rawask(query, attributes)
Calls the parser function #ask according to the provided parameters and passes the result on directly. The format of the output is depending on attributes.format. The first parameter (query) has the following mandatory fields:
- select
- table or string, mandatory
- the condition the query filters for. can be of string and arbitrarily complex or a table being either of format
,{ propertyname : 'value' }
or a mix of both{ '[[propertyname::value]]' }
- fields
- table or string, optional
- the fields, you want to get data from. format is fieldname or fieldname=headline (you can skip the preceeding ?). Please uses string only if you have just one field to display. If you want to format the fields and add a headline, please do it before the =, e.g. fieldname#km2=area
Please keep in mind:
- attributes may contain any attribute you find in the documentation, but intro and outro will be NILed, default and more results text will be set to the empty string, and format will be overwritten
- per default, does only return fields that contain a value. that can result in an "unbalanced" result, where one row contains more elements than others. if you want to get all fields, set
retainBlanks
to true
- query
- table, mandatory
- the arguments to construct the query. see above for details
- attributes
- table, optional
- more attributes, you want to pass on to the ask query (like limit, for instance)
- return
- string, the renderd output
set(stash)
Stores provided stash in semantic triple stores.
- stash
- string or table, mandatory
- data to store. if provided as string
, one triple can be stores. if provided as table, you can either use'has property=value'
,{ has property = 'value' }
, or a mix thereof. Even{ 'has propert=value' }
is possible.{ has property = {'value1', 'value2', 'value3' }
- return
- string, hopefully empty, result of set parser function
show(page, field)
Returns contents of field stored on page
- page
- string, mandatory
- name of page, to get the property contents from (please include namespace but explude brackets), e.g. 'Meta:Mail'
- field
- string, mandatory
- name of property, to get the contents from. You can skip the '?'
- return
- string, contents of property 'field' on page
subobject(stash, uid)
Stores provided stash as a subject. Contrary to set(stash) the data is not stored directly on the page but in a separate entity called subobject. These objects can be queried for separately.
- stash
- string or table, mandatory
- data to store. if provided as string
, one triple can be stores. if provided as table, you can either use'has property=value'
,{ has property = 'value' }
, or a mix thereof. Even{ 'has propert=value' }
is possible.{ has property = {'value1', 'value2', 'value3' }
- uid
- string, optional
- You can supply a uid to identify the object by. Just make sure, it is unique. :)
- return
- string, hopefully empty, result of set parser function
The above documentation is transcluded from Modul:SmwUtil/doc. (edit | history) Subpages of this module. |
local p = {}
local classDebug = require('Module:Debug/class')
local getArgs = require('Module:Arguments').getArgs
local smw = mw.smw
local _TT = require('Module:TableTools')
local cfg = {
nameMainLabel = 'PageName',
}
local buildQueryFrom = function(stash)
local query = {}
if type(stash) == 'table' then
for k, v in pairs(stash) do
if type(v) == 'table' then
for _, vv in pairs(v) do
local val = vv
if type(vv) == 'boolean' then
val = vv and 'wahr' or 'falsch'
end
if type(k) == 'number' then
table.insert(query, val)
elseif type(val) == 'table' then
error( 'While building set-query, detected invalid table value for key ' .. k .. ': ' .. _TT.printTable(val) )
else
table.insert(query, k .. '=' .. val)
end
end
else
local val = v
if type(v) == 'boolean' then
val = v and 'wahr' or 'falsch'
end
if type(k) == 'number' then
table.insert(query, val)
else
table.insert(query, k .. '=' .. val)
end
end
end
else
query[1] = stash
end
return query
end
local extractFieldFrom = function(s)
local ret = '?' .. s:match('^%??([^#=]+).*$')
local headline = s:find('=', 1, true) and
s:match('^.*=([^=]*)$') or nil
local formatter = s:find('#', 1, true) and
s:match('^.*#([^=]*).*$') or nil
if formatter and not formatter:find('-', 1, true) then
formatter = formatter .. '-'
end
return ret .. ( formatter and ('#' .. formatter) or '' ) .. ( headline and ( '=' .. headline ) or '' )
end
function p.ask(query, attributes, retainBlanks)
classDebug:log(21, 'entering SmwUtil.ask', 'SmwUtil.ask')
classDebug:log(23, ' with query: ' .. (query and _TT.printTable(query) or 'NONE'), 'SmwUtil.ask')
classDebug:log(23, ' with attributes: ' .. (attributes and _TT.printTable(attributes) or 'NONE'), 'SmwUtil.ask')
local select = query.select and query.select or (query.where and query.where or nil)
local fields = query.fields
local attributes = attributes or {}
if not select or (type(select) == 'table' and _TT.size(select) == 0) or (#select == 0) then
error('SmwUtil.ask: Argument query.select is missing or empty!', 2)
end
if type(attributes) == 'string' then
attributes = { attributes }
elseif type(attributes) ~= 'table' then
error('SmwUtil.ask: Argument attributes has wrong parameter type (' .. type(attributes) .. '); must be table or string', 2)
end
if not attributes.limit then
attributes.limit = 1000
end
local nameMainlabel = (attributes.mainlabel and attributes.mainlabel ~= '-') and attributes.mainlabel or cfg.nameMainLabel
attributes.mainlabel = '-'
-- now build the query
local query = {}
if type(select) == 'string' then
table.insert(query, select)
else
for k, v in pairs(select) do
if type(k) == 'number' then
table.insert(query, v)
else
table.insert(query, '[[' .. k .. '::' .. v .. ']]')
end
end
end
table.insert(query, '?#-=' .. nameMainlabel)
if type(fields) == 'string' then
table.insert(query, extractFieldFrom(fields))
elseif type(fields) == 'table' then
for _, v in pairs(fields) do
table.insert(query, extractFieldFrom(v))
end
end
for k, v in pairs(attributes) do
if type(k) == 'number' then
table.insert(query, v)
else
table.insert(query, k .. '=' .. v)
end
end
local result = smw.ask(query)
if type(result) == 'table' and result[nameMainlabel] then
result[1] = nameMainlabel
end
return result, query
end
function p.rawask(query, attributes)
classDebug:log(21, 'entering SmwUtil.rawask', 'SmwUtil.rawask')
classDebug:log(23, ' with query: ' .. (query and _TT.printTable(query) or 'NONE'), 'SmwUtil.rawask')
classDebug:log(23, ' with attributes: ' .. (attributes and _TT.printTable(attributes) or 'NONE'), 'SmwUtil.rawask')
local frame = mw.getCurrentFrame()
local select = query.select and query.select or (query.where and query.where or nil)
local fields = query.fields
local selection = ''
if type(select) == 'string' then
selection = select
elseif type(select) == 'table' then
for k, v in pairs(select) do
if type(k) == 'number' then
selection = selection .. ' ' .. v
else
selection = selection .. ' [[' .. k .. '::' .. v .. ']]'
end
end
else
error('SmwUtil.rawask: Argument query.select has wrong parameter type (' .. type(select) .. '); must be table or string', 2)
end
local args = {}
if type(fields) == 'string' then
args[1] = mw.ustring.sub( fields, 1, 1 ) ~= '?' and '?' .. fields or fields
elseif type(fields) == 'table' then
for k, v in pairs(fields) do
args[k] = mw.ustring.sub( v, 1, 1 ) ~= '?' and '?' .. v or v
end
end
if attributes then
if type(attributes) == 'string' then
table.insert(args, attributes)
elseif type(attributes) == 'table' then
for k, v in pairs(attributes) do
args[k] = v
end
else
error('SmwUtil.rawask: Argument attributes has wrong parameter type (' .. type(attributes) .. '); must be table or string', 2)
end
end
return frame:callParserFunction{ name = '#ask:' .. selection, args = args}
end
function p.set(stash)
classDebug:log(21, 'entering SmwUtil.set', 'SmwUtil.set')
classDebug:log(23, ' with stash: ' .. (stash and _TT.printTable(stash) or 'NONE'), 'SmwUtil.set')
if type(stash) ~= 'string' and type(stash) ~= 'table' then
error('SmwUtil.set: Argument stash has wrong parameter type (' .. type(stash) .. '); must be table or string', 2)
end
-- build and execute query
local query = buildQueryFrom(stash)
local result = smw.set(query)
if result == true then
return ''
else
return result.error
end
end
function p.show(page, field)
classDebug:log(21, 'entering SmwUtil.show', 'SmwUtil.show')
classDebug:log(23, ' with page: ' .. (page and page or 'NONE'), 'SmwUtil.show')
classDebug:log(23, ' with field: ' .. (field and field or 'NONE'), 'SmwUtil.show')
local frame = mw.getCurrentFrame()
local page = page:match('^[%[]*([^%[%]]+)[%]]*$')
local field = mw.ustring.sub( field, 1, 1 ) ~= '?' and '?' .. field or field
return frame:callParserFunction('#show:' .. page, field)
end
function p.subobject(stash, uid)
classDebug:log(21, 'entering SmwUtil.subobject', 'SmwUtil.subobject')
classDebug:log(23, ' with stash: ' .. (stash and _TT.printTable(stash) or 'NONE'), 'SmwUtil.subobject')
classDebug:log(23, ' with uid: ' .. (uid and uid or 'NONE'), 'SmwUtil.subobject')
if type(stash) ~= 'string' and type(stash) ~= 'table' then
error('SmwUtil.subobject: Argument stash has wrong parameter type (' .. type(stash) .. '); must be table or string', 2)
end
-- build and execute query
local uid = uid or nil
local query = buildQueryFrom(stash)
local result = smw.subobject(query, uid)
if result == true then
return ''
else
return result.error
end
end
-- ************************************
-- alias definition
-- ************************************
p.get = p.show
p.lua = p.ask
return p