Relace knihovny GLib jsou množiny neuspořádaných záznamů. Můžete si je představovat jako jakési tabulky s několika řádky a sloupci. Řádky jsou jednotlivé záznamy a sloupce příslušné atributy (položky, části záznamů).
Jak již bylo řečeno, záznamy nejsou v relační tabulce nijak uspořádány. Nelze se proto na ně odkazovat konkrétními indexy, jako například na prvky pole. Přístup k datům organizovaným do relací se provádí úplně jiným způsobem, ale o tom až za chvilku. Vnitřně se záznamy ukládají do hash tabulek, takže přístup k nim je velice rychlý.
Relační tabulka je rozdělena do sloupců, takže každý řádek má nutně stejné množství prvků. Z obecného hlediska není počet sloupců omezen. Skutečnost je ale poněkud jiná: relace knihovny GLib jsou stále ještě implementovány tak, že umožňují pracovat jen s tabulkami tvořenými právě dvěma sloupci. Doufejme, že v příštích verzích bude toto omezení odstraněno.
Vytvoření nové GRelation
Relační tabulka je reprezentována neveřejnou strukturou:
struct GRelation;
Novou relaci vytvoříte voláním funkce:
GRelation* g_relation_new(gint fields);
…, kde fields
je počet sloupců tabulky (počet prvků na řádku). Jak už jsem zmínil, nyní musí být fields
rovno 2.
Ihned za vytvořením relační tabulky by mělo následovat jedno nebo několik volání funkce:
void g_relation_index(GRelation *relation, gint field, GHashFunc hash_func, GCompareFunc key_compare_func);
Touto funkcí se inicializuje systém indexování podle sloupce field
. g_relation_index()
připraví GRelation
relation
na to, že v budoucnu budete chtít v tabulce vyhledávat záznamy podle jeho hodnot.
field
Jako argument hash_func
musí být předána funkce, která z hodnot ve sloupci field
vyrobí tzv. hash-hodnotu (viz hash tabulky). A kde je hash_func
, dá se čekat že bude i nějaká key_compare_func
. Také ona musí pracovat s prvky ve sloupci field
a jejím úkolem bude rozhodovat, jsou-li dvě položky shodné (a pak musí vrátit TRUE
) nebo nikoliv ( FALSE
). Za tyto argumenty můžete použít i předpřipravené funkce g_str_hash()
, g_str_equal()
, g_direct_hash()
, g_direct_equal()
nebo g_int_hash()
a g_int_equal()
(opět viz hash-tabulky).
Funkce g_relation_index()
musí být volána před jakýmkoliv přidáváním prvků do tabulky!
Počet indexovaných sloupců není nikterak omezen, z praktického hlediska je ovšem vhodné, aby byl takto indexován alespoň jeden.
Vkládání záznamů do GRelation
void g_relation_insert(GRelation *relation, ...);
…vloží do GRelation
relation
nový záznam. Počet parametrů za pointerem relation
musí odpovídat počtu sloupců v tabulce – jsou to vkládaná políčka, která se uloží do patřičných sloupců a dohromady vytvoří jednu datovou položku v relaci.
Vyhledávání záznamů v GRelation
GTuples* g_relation_select(GRelation *relation, gconstpointer key, gint field);
Funkce g_relation_select()
je nástrojem pro vyhledávání záznamů v relacích. V relační tabulce relation
vyhledá všechny řádky, které ve sloupci field
mají hodnotu key
. Sloupec field
musí být tzv. „indexovaným“ sloupcem, tedy musí být na něj ihned po vytvoření relace zavoláno funkce g_relation_index()
. Porovnávání hodnoty key
se záznamy v tabulce se provádí pomocí funkce key_compare_func
(viz g_relation_index()
).
Jak můžete vidět z funkčního prototypu, výsledkem je nový typ, o kterém ještě nebyla ani zmínka – GTuples
. Je to struktura, jejíž prvky (až na jeden) jsou neveřejné:
typedef struct { guint len; } GTuples;
Úkolem struktury GTuples
je uchovávat výsledek hledání, tedy jakýsi souhrn hledacímu kritériu odpovídajících záznamů relace. Přímo ze struktury lze přímo vyčíst jen počet výsledných řádků – podává o něm informaci položka len
.
Abyste se dostali k samotným záznamům tvořících výstup prohledávání, musíte k tomu použít speciální funkci:
gpointer g_tuples_index(GTuples *tuples, gint index, gint field);
g_tuples_index()
Vždy, když s GTuples
přestanete pracovat, je nutné je dealokovat speciální funkcí:
void g_tuples_destroy(GTuples *tuples);
Odstraňování záznamů z GRelation
Také pro mazání záznamů máte pochopitelně k dispozici nějaký nástroj. Je jím funkce:
gint g_relation_delete(GRelation *relation, gconstpointer key, gint field);
g_relation_delete()
Dealokace GRelation
Stejně tak, ukončíte-li práci s celou relační tabulkou GRelation
, sluší se podle dobrých mravů programátora jí obsazenou paměť vrátit operačnímu systému. I GRelation
pro to mají speciální funkci:
void g_relation_destroy(GRelation *relation);
Dokončení příště.