Modul:Dallisták szerzővel
Dallisták szerzővel[mi ez?] • [dokumentáció: mutat, ] • [tesztek: létrehozás]
A modul célja egytáblás lekérdezések végrehajtása. A tábla adatait egy program gyűjti össze, és (egyelőre) kézzel kerül a Kották metaadatai modulba. A lekérdezések kimenete wikitáblázat fejléc nélkül (így a feliratokat nem kell paraméterben átadni a modulnak). A hívó sablonban a táblázat rendezhetővé tehető. A táblázat lezárása is a hívó sablon dolga, így több modulhívás tehető egy táblázatba.
A modul által végezhető lekérdezések általános alakja SQL-ben:
select oszloplista from Kották_metaadatai where szűrőfeltételek group by oszloporder by oszloplista;
Miután a kimenet-tábla rendezhető, a modul (egyelőre) nem rendez.
Paraméterek
[szerkesztés]A modulnak egyetlen belépési pontja van: a dallista
függvény.
- Oszloplista
Oszlopok = oszlop1, oszlop2, …
, ahol oszlopn a Dal infobox valamelyik mezője. A szócikk címe mindig belekerül a kimenet első oszlopába. Ha az Oszlopok-ban meg van adva a Szerző, továbbá a Dallam és Szöveg valamelyike, akkor e három mező egymás melletti két oszlopba kerül, közvetlenül a szócikk címe után. A Szerző oszlopa dupla széles. E kivételtől eltekintve az oszlopok a paraméterben megadott sorrendben íródnak ki.
- Szűrőfeltételek
oszlop1 = érték1|oszlop2 = érték2| …
, ahol oszlopn jelentése azonos az oszloplistabelivel, értékn a mező értéke. Csonkítás, wildchard nem lehetséges. Az összehasonlítás előtt a modul törli a<ref>…</ref>
közötti szöveget és az érték linkjét. A szűrőfeltételek ÉS kapcsolatban állnak. OR-t két modulhívással lehet elérni.
- NOT a mező eleji felkiáltójellel adható meg. A két felkiáltójel az eredményből kizárja az üres értékeket.
- Ha a szűrőfeltételben az oszlop
dallam
vagyszöveg
, és annak értéke üres, a kiértékelésben az érték aszerző
oszlop értéke lesz. Más szóval: adallam
mezőben megadott komponistát akkor is megtalálja a program, ha az infoboxban aszerző
mezőben adtuk meg. Ez a tulajdonság NOT-tal (felkiáltójellel) kombinálva esetleg nem várt eredményt okozhat.
- Group by
Groupby = oszlop
. Kétoszlopos táblázatot hoz létre úgy, hogy az azonos értékű oszlopokat egyszer írja ki, a második oszlopba az előfordulási szám kerül. A Groupby szűrőfeltételekkel kombinálható, de oszloplista nem adható meg (pontosabban: figyelmen kívül marad).
- Nosum
- Group by használatakor nem ír
Összesen
sort. A paraméternév után ki kell írni az=
jelet, értéket nem kell megadni.
- Felsorolás
Felsorolás = szint
. Táblázat helyett szint szintű wikifelsorolás használata, ha egy oszlopos lenne a táblázat. (Ha a cikkcímeken kívül más is kerül a táblázatba, akkor ez a paraméter figyelmen kívül marad. Ellenkező esetben a Nosum paramétert automatikusan bekapcsolja, így felsorolásos lista végére soha nem kerül összegsor.) Például aFelsorolás=2
két csillaggal kezdett (második szintű) listát generál.
Példák
[szerkesztés]{| class="wikitable sortable" |+ Magyar komolyzenei szócikkek ! Szócikk !! Dallam !! Szöveg {{#invoke:Dallisták szerzővel|dallista|műfaj=magyar komolyzenei dal|Oszlopok=szerző,dallam,szöveg}} |}
Szócikk | Darab |
---|---|
új | 60 |
régi | 100 |
vegyes | 58 |
nincs megadva | 44 |
Összesen | 262 |
A fenti sablonhívás eredménye a bal oldali táblázatban.
Példa group by-os lekérdezésre:
{| class="wikitable sortable" align="right" |+ Magyar népdalok stílus szerint ! Szócikk !! Darab {{#invoke:Dallisták szerzővel|dallista|műfaj=magyar népdal|Groupby=stílus}} |}
Az eredmény a jobb oldali táblázatban.
Azok a népdalok, melyeknek üres a kadenciája: …|kadencia=|…
. Amelyeknek nem üres: …|kadencia=!|…
.
A nem négysoros magyar népdalok (beleértve azokat is, ahol a sorok száma nincs megadva: …|dalsor=!4|műfaj=magyar népdal|…
Azok a nem négysoros magyar népdalok, ahol a sorok száma meg van adva: …|dalsor=!!4|műfaj=magyar népdal|…
Teendők
[szerkesztés]- Groupby-ba link az 1-darabos tételekre
local p = {}
local dalpar = {} -- Dal_infobox paraméternevei és a paraméterek típusa
-- A Dal_infobox-ból kapott paraméterek:
dalpar['ambitus'] = ''
dalpar['cím'] = ''
dalpar['dallam'] = ''
dalpar['dobszay'] = ''
dalpar['előadásmód'] = ''
dalpar['év'] = ''
dalpar['fordító'] = ''
dalpar['gyűjtő'] = ''
dalpar['hangfaj'] = ''
dalpar['hangnem'] = ''
dalpar['hely'] = ''
dalpar['helynév'] = ''
dalpar['kadencia'] = ''
dalpar['megye'] = ''
dalpar['mnt'] = ''
dalpar['műfaj'] = ''
dalpar['nyelv'] = ''
dalpar['sorok'] = ''
dalpar['stílus'] = ''
dalpar['szerző'] = ''
dalpar['szótag'] = ''
dalpar['szöveg'] = ''
dalpar['tempó'] = ''
dalpar['bartók'] = ''
dalpar['típus'] = ''
dalpar['vargyas'] = ''
dalpar['vargyas2'] = ''
-- A Dal_infobox-ból át nem vett paraméterek: kép képaláírás képméret
-- Robottól kapott paraméterek ('a': ambitus típus):
dalpar['amb1s1'] = 'a' dalpar['amb1s2'] = 'a' dalpar['amb1sor'] = 'a'
dalpar['amb2s1'] = 'a' dalpar['amb2s2'] = 'a' dalpar['amb2sor'] = 'a'
dalpar['amb3s1'] = 'a' dalpar['amb3s2'] = 'a' dalpar['amb3sor'] = 'a'
dalpar['amb4s1'] = 'a' dalpar['amb4s2'] = 'a' dalpar['amb4sor'] = 'a'
dalpar['amb5s1'] = 'a' dalpar['amb5s2'] = 'a' dalpar['amb5sor'] = 'a'
dalpar['amb6s1'] = 'a' dalpar['amb6s2'] = 'a' dalpar['amb6sor'] = 'a'
dalpar['amb7s1'] = 'a' dalpar['amb7s2'] = 'a' dalpar['amb7sor'] = 'a'
dalpar['ambdal'] = 'a' dalpar['ambmax'] = 'a' dalpar['ambmin'] = 'a'
dalpar['dalsor'] = ''
dalpar['kad1'] = 'a' dalpar['kad2'] = 'a' dalpar['kad3'] = 'a' dalpar['kad4'] = 'a' dalpar['kad5'] = 'a' dalpar['kad6'] = 'a'
dalpar['szot1'] = '' dalpar['szot2'] = '' dalpar['szot3'] = '' dalpar['szot4'] = '' dalpar['szot5'] = '' dalpar['szot6'] = '' dalpar['szot7'] = ''
dalpar['utmod'] = '' dalpar['creusr'] = '' dalpar['credat'] = ''
local tblsoreleje = '\n|-\n| '
local osszeleje = "\n|-\n!Összesen"
local ujmezo = ' || '
local frame = mw.getCurrentFrame()
--****************** Helyi függvények ***************
local function sablon(txt) -- stringbeli sablon feldolgozása
if txt == nil then return '' end
return frame:preprocess(txt)
end
local function hasonl(egyik,masik) -- a paraméterek rendezőfüggvénye
return egyik[2] < masik[2]
end
local function lnkstrip(str) -- leszedi a wikilinkeket a stringből. Az alternatív szöveget hagyja meg, ha van.
if str then
ret = string.gsub(str,'%[%[[^|]*|','%[%[') -- a link törlése, ha van alternatív szöveg
ret = string.gsub(ret,'%[%[','') -- [[-k törlése
return string.gsub(ret,'%]%]','') -- ]]-k törlése
else return nil
end
end
local function felhang(amb) -- az ambitust félhangra alakítja
if not amb then return '' end
local romai = {}
romai['I'] = -12 romai['II'] = -10 romai['III'] = -8 romai['IV'] = -7 romai['V'] = -5 romai['VI'] = -3 romai['VII'] = -2
local arab = {}
arab[0] = 0 arab[1] = 2 arab[2] = 4 arab[3] = 5 arab[4] = 7 arab[5] = 9 arab[6] = 10
local modjel = {}
modjel["♯"] = 1 modjel["♭"] = -1
local kar = string.sub(amb,1,3) -- kihasznaljuk, hogy a b es a kereszt utf8-kodja egyarant 3 hosszu
local ret = modjel[kar]
if ret then kar = string.sub(amb,4) else ret = 0 kar = amb end -- a módosítójel kész
if romai[kar] then return ret + romai[kar] end -- a római szám kész
local szam = tonumber(kar)
if szam
then if szam > 0 then szam = szam-1 else szam = 0 end
return ret + math.floor(szam/7)*12 + arab[szam%7];
end
return 0
end
local function tblcopy(be) -- shallow copy. Akkor kell, ha "be" írásvédett
ki = {}
for x,y in pairs(be)
do ki[x] = y
end
return ki
end
--****************** select: az SQL select-részének végrehajtása ***************
local function select(daltomb, oszlopstr, nosum, felsorolas)
local ret = ''
local oszlopok = 0
-- Paraméterátvétel
oszloptomb = {}
if oszlopstr then
if string.sub(oszlopstr,-1,1) ~= ',' then oszlopstr = oszlopstr..',' end
oszlopstr = string.gsub(oszlopstr,'[%s]*,[%s]*',',') -- leszedjuk a helyközöket a vessző körülről
for w in string.gmatch(oszlopstr,'[^,]+') do
oszlopok = oszlopok + 1
oszloptomb[ string.gsub(w,',$','') ] = oszlopok
end
end
if oszloptomb['szerző'] and (oszloptomb['dallam'] or oszloptomb['szöveg']) then
szerzoflg = true -- két egymás melletti oszlopba a három mezőt
oszloptomb['szerző'] = nil
oszloptomb['dallam'] = nil
oszloptomb['szöveg'] = nil
else
szerzoflg = false
end
-- Megpróbáljuk számmá alakítani. Ha több oszlopunk van, vagy nem sikerül,
-- hamis logikai értékű lesz, tehát táblázatot készítünk
felsorolas = oszlopok == 0 and tonumber(felsorolas)
if not felsorolas or felsorolas < 1 then
felsorolas = nil
end
-- A paraméterek rendezése.
munkatbl = {} -- áttöltjuk paramtomb-öt normál tömbbe, hogy rendezni lehessen
for i, t in pairs(oszloptomb) do
table.insert(munkatbl, {i, t})
end
table.sort(munkatbl, hasonl) -- rendezés
-- Kiírás
local darab = 0
for i, t in pairs(daltomb) do
darab = darab + 1
if felsorolas then
if ret ~= '' then
-- első sor elé nem kell, hogy egyben maradjon a wikis felsorolás
ret = ret .. '\n'
end
ret = ret .. string.rep('*', felsorolas) .. ' [[' .. i .. ']]'
else
ret = ret..tblsoreleje..'[['..i..']]' -- szócikk címe
if szerzoflg then -- szerző/dallam/szöveg együtt
if (t['szerző'] or '') ~= '' then
ret = ret..ujmezo..'colspan="2" align="center" | '..sablon(t['szerző']) -- ugyanaz a dallam és a szöveg szerzője
else
ret = ret..ujmezo..sablon(t['dallam'])..ujmezo..sablon(t['szöveg']) -- különböző
end
end
for j, u in pairs(munkatbl) do -- a többi oszlop kiírása
if dalpar[u[1]] == 'a' then
partip = 'data-sort-value='..felhang(t[u[1]])..'|'
else
partip = ''
end
ret = ret..ujmezo..partip..sablon(t[u[1]])
end
end
end
if not nosum and not felsorolas then
ret = ret..osszeleje..": "..darab
end
return ret
end
--****************** groupby: az SQL group by részének végrehajtása ***************
local function groupby(tomb,oszlop)
local jobbra = ujmezo..'align="right" |'
local ures = 0 -- nincs megadva az oszlop
local darab = 0 -- összesen
local stat = {} -- darabszámok
local egy = {} -- az 1 darabhoz tartozó érték
-- Számlálás
for i,t in pairs(tomb) do
local str = lnkstrip(t[oszlop])
if str and string.len(str) > 0
then stat[str] = (stat[str] or 0) + 1
egy[str] = '[['..i..']]'
else ures = ures+1
end
darab = darab + 1
end
-- Kiírás
local ret = ''
for i,t in pairs(stat) do
ret = ret..tblsoreleje..i..jobbra
if egy[i] and t == 1
then s = string.match(egy[i],'^%[%[[^|%]]+')
if s ~= nil
then ret = ret..s..'|1]]'
else ret = ret..t
end
else ret = ret..t
end
end
if ures > 0 then ret = ret..tblsoreleje.."''nincs megadva''"..jobbra..ures end
return ret..osszeleje..'!! style="text-align: right" | '..darab
end
--****************** where: az SQL where részének végrehajtása ***************
function p.where(daltomb, args)
local partomb = {} -- A szűrőparamétereket áttesszük partomb-be.
local negtomb = {} -- !-jel kezdődő (negált) feltételek
local par
--local ret = 'where'
local ret = 'paramtomb<br>'
for i, t in pairs(dalpar)
do par = args[i]
if par -- i szerepel a where-feltételek között, az érték par kell legyen, hogy a where teljesüljön
then x,y = string.find(par,'^!%s*')
--ret = ret..'i='..i..',par='..par..', x='..x..',y='..y..'<br>'
if x
then partomb[i] = string.sub(par,y+1) -- negálás van a megkívánt értékben
negtomb[i] = 1
x,y = string.find(partomb[i],'^!%s*')
if x
then negtomb[i] = 2
partomb[i] = string.sub(partomb[i],y+1) -- kettős negálás
end
else partomb[i] = par -- nincs negálás
end
--ret = ret..partomb[i]..', '..par..'<br>'
end
end
-- partomb a where-feltételekbeli értékeket tartalmazza, negtomb azt, van-e negálás. Mindkét tömb kulcsa a Dal_infobox egyik paramétere.
--ret = ret..'paramtomb vege<p>'
local eredm = {}
for i,t in pairs(daltomb) -- végigmegy a Dal_infoboxon
do local flg = true
--ret = ret..i..'<br>'
for j,p in pairs(partomb) -- végigmegyünk a where-feltételeken. j a Dal_infobox mezőneve, p a where-ben megkívánt értéke
do local ertek = t[j] -- a Dal_infobox i nevű mezőjének tényleges értéke
if (ertek or '') == '' and (j == 'dallam' or j == 'szöveg') then ertek = t['szerző'] end -- ha nincs dallam vagy szöveg , a szerző is megteszi
local tj = lnkstrip(ertek) or '' -- a Dal_infobox i nevű mezőjének link nélküli értéke
--ret = ret..'*** i = '..i..', j = '..j..', tj = '..(tj or '')..', p = '..(p or '')..'<br>'
f = tj == p -- f igaz, ha az i paraméterre teljesül a where-feltétel
if negtomb[j] then f = not f end -- de nem szabad igaznak lennie
if not f or (negtomb[j] == 2 and tj == '') then flg = false break end
--ret = ret..i..', flg = true<br>'
end
if flg then eredm[i] = t
if (eredm[i]['dallam'] or '') == ''
then eredm[i] = tblcopy(t) -- mert t csak olvasható
eredm[i]['dallam'] = t['szerző']
end
if (eredm[i]['szöveg'] or '') == ''
then eredm[i] = tblcopy(eredm[i]) -- mert lehet, hogy eredm[i] csak olvasható
eredm[i]['szöveg'] = t['szerző']
end
--ret = ret..'i = '..i..'<br>'
end -- az eredménytömb ugyanolyan szerkezetű, mint az eredeti dallistáké
end
--[[ teszt
for i, t in pairs(eredm)
do ret = ret..i
for j, u in pairs(partomb)
do ret = ret..', '..u
end
end
return ret..'where vege<br>'
]]
return eredm
end
--****************** dallista: a modul belépési pontja ***************
-- dalpar: a metaadatnevek
-- daltomb: a metaadatok értékei (r/o)
-- oszloptomb: tisztitott értékek
function p.dallista(frame, daltomb)
if not daltomb then
daltomb = mw.loadData('Module:Kották metaadatai')
end
local args = require('Modul:Arguments').getArgs(frame, {removeBlanks = false})
local szurt = p.where(daltomb, args)
if args['Groupby'] then
return groupby(szurt, args['Groupby'])
else
return select(szurt, args['Oszlopok'], args['Nosum'], args['Felsorolás'])
end
end
return p