Tartalomjegyzék

elib::vir — VIR lekérdezés- és kimutatásmotor

Áttekintés

Az include/elib/vir.pm egy deklaratív SQL-lekérdezés generátor / OLAP réteg a VIR (riportok, lekérdezések, kimutatások) számára. A modulok metaadatban leírják, milyen táblák, mezők és dimenziók érhetők el, a motor pedig ebből rak össze SELECT … FROM … JOIN … WHERE … GROUP BY lekérdezéseket — opcionálisan crosstab (pivot) táblával.

A elib::vir absztrakt ősosztály: az _init alapból die „Absztrakt”-tal áll meg, a leszármazottak (pl. dok::szamla::vir, dok::bank::vir — 19+ modulnak van saját vir.pm-je) töltik fel a $self→{meta}-t és a $self→{lists}-et.

A fájl négy package-et tartalmaz:

Package Szerep
elib::vir Absztrakt ős: query-generálás a metaadatból
elib::vir::generated Futásidőben összerakott vir-objektum + relációs-algebra API (filter/project/aggr/join)
elib::vir::table Tábla- (vagy al-lekérdezés-) leíró, ami beépíthető a generated-be
elib::vir::join UNUSED, csak váz

Metaadat-modell

Minden mező egy csoportba (groupname) tartozik — ez a tengelyek és mértékek tipológiája:

Csoport Szerep Példa (számla)
id egyedi azonosító mezők szlafej.id, szlaszam, tetelid
partition dimenzió / bontási tengely tipus, partner, cikk_kategoria
time idő-dimenzió datum, teljdat, fizhat
value mérték (számolható) ossz_netto, ossz_afa
check logikai szűrőmező

A meta→{tables} írja le a táblákat és hogyan joinolnak egymáshoz:

A $self→{lists} névvel ellátott nézetek, amelyek a fenti mezőkből választanak ki egy adott listához használt halmazt (pl. ertekesitesek_aggr).

A generálási pipeline

new → _init → _generate_trivials

Konstrukciókor a _generate_trivials automatikusan legyárt minden time mezőből _month / _year / _year_month partíciókat (substr(datum::text, …)-szal), és minden id-ból egy _view partíciót. A havi/éves bontás így „ingyen” elérhető. (A date_project metódussal egyedi idő-partíció is definiálható.)

generate_query_and_fields($listname, $alter)

Ez a motor szíve. Az $alter paraméter mezőnként vezérli, mi történjen az adott mezővel.

process_field_group végigmegy az id / partition / time / value / check csoportokon, és mezőnként dönt:

$alter érték Jelentés
1 sima oszlop
group GROUP BY tengely
sum / min / max / textcat_all aggregátum
count darabszám
split_day\week\month\quarter\year date_trunc-os időbontás

Segédmetódusok:

calc_tables az $alter→{where} és a tábla-gráf alapján építi a FROM … JOIN … részt. Iteratív: amíg van olyan tábla, aminek a jointo-ja már be van joinolva, hozzáfűzi. Van egy 100-as limit (a szerzők saját HACK SMELL jelölésével) a végtelen ciklus ellen.

Visszatérés: { query, fields, debug }.

crosstable

Ha $alter→{crosstable} meg van adva, a query köré PostgreSQL crosstab(…) hívást rak (tablefunc extension), és dinamikusan generálja az oszlopdefiníciókat egy „columns” segéd-query eredményéből. Ez a pivot/kimutatás.

Belépési pontok a hívóknak

Metódus Visszatérés
generate_query nyers SQL string
generate_query_for_list lista-felülethez illeszkedő struktúra: Tables / Mezok / AllKeys
generate_vir jelenleg undef (csonk)

elib::vir::generated — kompozíciós algebra

A elib::vir::generated (@ISA=('elib::vir')) egy futásidőben, dinamikusan összerakott vir-objektum, ami relációs-algebra-szerű műveleteket ad. Minden művelet új generated példányt ad vissza (immutábilis, láncolható):

Metódus Művelet
filter(todo⇒'keep'\|'drop', fields⇒[…]) mezők szűrése
project(…) új származtatott mezők hozzáadása
aggr($todo, $where) aggregálás: GROUP BY-ra állítja a mezőket, a value-kat összegezhetővé teszi
where($where) szűrőfeltétel (az aggr-ra épül)
left_join_table / inner_join_table / gen_join_table két vir-objektum összejoinolása (vir⇒, joinon⇒, jointo⇒, rename_left/right⇒)
revir / get_table / get_meta nézetből visszatabularizált meta vagy elib::vir::table (al-lekérdezésként újra felhasználható)

A state mező (meta / aggr) és az _assert őrzi, hogy a műveletek csak a megengedett állapotban fussanak (csak $SYS{devel} alatt aktív).

A _add_meta egyesíti több forrás metaadatát (a join-okhoz), rename-mel a mezőnév-, field-, label- és label_prefix-ütközések feloldására.

elib::vir::table — táblaleíró

Egy tábla (vagy al-lekérdezés expr⇒-rel) leírója, describe(…)-szal feltöltve:

Ez teszi lehetővé, hogy egy korábban generált query-t al-lekérdezésként egy új vir építőelemeként használjunk.

Példa: dok::szamla::vir

A dok::szamla::vir::_init tölti fel a metaadatot:

$meta->{tables}={
    szlafej => { table=>'szlafej', primary=>1 },
    szlatet => { table=>'szlatet', jointo=>'szlafej',
                 joinon=>'szlafej.szlaszam=szlatet.szlaszam', type=>'1N' },
    ...
};
$meta->{id}        = { id=>{...}, szlaszam=>{...}, tetelid=>{...} };
$meta->{partition} = { tipus=>{...}, partner=>{...}, cikk_kategoria=>{...} };
$meta->{time}      = { datum=>{...}, teljdat=>{...}, fizhat=>{...} };
$meta->{value}     = { ossz_netto=>{ field=>'szlafej.ossz_netto',
                                     me=>'szlafej.penznem', ... }, ... };
$self->{lists}     = { ertekesitesek_aggr=>{ tables=>[...], id=>[...],
                       partition=>[...], time=>[...], value=>[...] }, ... };

Megjegyzések

A kód tele van a fejlesztők saját SMELL / HACK jelöléseivel és kikommentált debug-sorokkal (#debug(…); use devel;). Ezek a szerzők kétségei, nem hibák, de jelzik, hogy egyes részek (pl. a calc_tables limit-hack, a where az aggr-ra hackelve) tudottan ideiglenesek.


Generálva kódelemzésből — include/elib/vir.pm (r22049, 2025-04-30).