Graph-IT

Attributknoten und Datenfunktionen

Attributknoten definieren, welche Werte an Instanzen eines Knoten gesetzt und ausgelesen werden können. Im selbstbeschreibenden Datenmodell des Graphen ist ein Attributknoten eine Instanz des Knotens attributknoten.

Sein eindeutiger typ hat die Form <knoten>_<attribut>, während sein name zusätzlich den Datentyp des Attributknoten enthält. Wie im Kapitel über Knoten näher beschrieben wird, gibt es an jedem Knoten die Attributknoten <knoten>_name, <knoten>_ungueltig und <knoten>_loeschbar.

Durch Datenfunktionen können Werte von Attributknoten automatisch ausgerechnet werden.

Attribute und Datentypen

Bezeichnung und Datentyp eines Attributknoten werden durch Instanzen des Knoten attribut angegeben. Jeder Attributknoten ist mit genau einem Knoten und genau einem Attribut verknüpft, die ihn zusammen vollständig definieren. Datentypen sind Instanzen des Knoten datentyp, die wiederum mit jeweils genau einer Instanz des Knoten speicherort verknüpft sind.

Die Implementierung des Graphen kennt zwei Speicherorte für Attribut-Werte: MySQL-Datentypen werden in der Datenbank abgelegt, während der einzige Dateisystem-Datentyp Dateisystem datei direkt im Dateisystem abgelegte Dateien beschreibt.

Folgende in der Datenbank abgelegte Datentypen kennt der Graph:

Ein Attributknoten kann zusätzlich noch mit einer Instanz von mimetype verknüpft sein. Dieser gibt den MIME-/Datei-Typen der Attribut-Werte an, z.B. application/json oder application/pdf. Am Attribut kann ein Standard-MIME-Typ angegeben werden. Dieser kann an allen Attributknoten, die dieses Attribut verwenden, jeweils überschrieben werden.

Insbesondere für die numerischen Datentypen – integer, float und decimal1 bis decimal5 – kann zusätzlich eine einheit verknüpft sein. Auch diese kann an Attributknoten überschrieben werden.

Schließlich kann für jeden Attributknoten angegeben werden, ob er eindeutig ist, ob in der Datenbank ein Index für ihn angelegt werden soll, und ob er der primäre Attributknoten seines Knoten sein soll.

Setzen und Auslesen von Attribut-Werten

Der Wert eines Attributknoten für eine Knoten-Instanz wird durch die API-Funktion setze(string $node_guid, string $attributknoten_typ, string $wert): ?boolean gesetzt. Er kann durch die API-Funktion attribut(string $node_guid, string $attributknoten_typ): ?string wieder ausgelesen werden.

Außerdem existiert die API-Funktion attribute(string $node_guid, string $knoten_typ, string $attribute): ?array<string, ?string>, mit der die Werte mehrerer Attribute einer Knoten-Instanz gleichzeitig ausgelesen werden können. Hierdurch werden nicht nur API-Aufrufe, sondern intern auch Anfragen an die Datenbank gespart.

Die API-Funktion attributsknoten(string $attributknoten_typ, string $wert): ?string kann verwendet werden, um für eindeutige Attributknoten die Knoten-Instanz anhand des Wertes für diesen zu finden, wobei die Eindeutigkeit gerade bedeutet, dass höchstens eine solche Instanz existiert.

Datenfunktionen

Datenfunktionen sind Funktionen, die Werte von Attributknoten an Instanzen automatisch berechnen und setzen. Sie werden im Graphen als PHP-Code abgelegt, der Zugriff auf die Graph-API hat.

Datenfunktionen dürfen keine Seiteneffekte haben. Daher sind die erlaubten Aufrufe der API wie in deren Dokumentation angegeben eingeschränkt.

Ihre Funktionalität ist sogar noch weiter eingeschränkt: Sie dürfen nur Attribut-Werte von direkt verknüpften Knoten-Instanzen abfragen. Dies stellt sicher, dass einzelne Datenfunktionen keine beliebig komplexen Abfragen an den Graphen machen können. (Durch Datenfunktionen, die wiederum die Neuberechnung anderer Datenfunktionen auslösen, sind jedoch trotzdem sehr aufwändige Aufruf-Hierarchien möglich. Bei Programmier-Fehlern kann es sogar zu Endlos-Schleifen kommen.)

Die Werte, die von Datenfunktionen berechnet werden, müssen sich immer deterministisch aus den von ihr gelesenen Graph-Strukturen ergeben. Daher ist auch der Aufruf von Funktionen, die Informationen von außerhalb des Graphen beziehen – beispielsweise date() – nicht erlaubt.

Diese Einschränkungen werden unter anderem durch das Kritisieren von Datenfunktionen sichergestellt. Dieses ist im Graphmodul graphx implementiert. Es analysiert den Code einer Datenfunktion und markiert nicht erlaubte API-Aufrufe. Die ebenfalls in graphx zur Verfügung stehenden Tasks zum Anlegen und Ändern von Datenfunktionen können dann nicht abgeschlossen werden, solange die Kritik Fehler liefert.

Der Graph analysiert außerdem automatisch, von welchen anderen Verknüpfungen und Attribut-Werten die Berechnung abhängt. Die Ergebnisse dieser Analyse legt er als Instanzen des Knoten benutztattributknoten in sich selbst ab. Bei jeder Veränderung von Verknüpfungen und Attribut-Werten wird dann eine Neuberechnung aller eventuell betroffenen Datenfunktionen angestoßen/getriggert.

Wenn der Code für eine Datenfunktion angepasst wird, stimmen die bisher berechneten Werte eventuell nicht mehr. In diesem Fall können durch initialisieren einer Datenfunktion die Werte für alle Instanzen neu berechnet werden.

Die API-Funktion berechne(string $node_guid, string $datenfunktion_name): ?mixed kann verwendet werden, um den momentanen Wert einer Datenfunktion an einer Instanz auszurechnen. Diese API-Funktion sollte in einem konsistenten Graphen das selbe Ergebnis liefern wie der entsprechende attribut()-Aufruf und ist daher vor allem für die interne Konsistenz-Prüfung von Interesse.

Datenfunktions-Typen

Um möglichst wenig Code manuell schreiben zu müssen und die Seiteneffekt-Freiheit von Datenfunktionen möglichst automatisch zu gewährleisten, werden im Graphmodul graphx Datenfunktions-Typen bereit gestellt.

Diese erlauben durch das Konfigurieren möglichst weniger Verknüpfungen und Attribute das automatische Generieren des Codes von Datenfunktionen. Datenfunktions-Typen sind für immer wieder benötigte Arten von Funktionen definiert. Beispiele hierfür sind Aliasse, die Werte von Attributknoten an benachbarten Knoten übernehmen, Konkatenationen, die Werte von anderen Attributknoten am aktuellen Knoten zu Zeichenketten zusammensetzen, und arithmetische und logische Operationen auf den Werten von anderen Attributknoten.