Schema-Deklaration

Zur Optimierung des Datenbankschemas für Modellelemente, können spezialisierte Datenbanktabellen definiert werden. Statt der automatisch generischen Datenbankabbildung kann dann eine spezialisierte Datenbankabbildung durchgeführt werden. Ohne eine eigene Schema-Konfiguration, verwendet TopLogic eine generische Speicherung für Anwendungsdaten.

Schema-Konfiguration

Das Datenbankschema kann entweder direkt über XML-Konfigurationsdateien in einer TL-Studio Umgebung erfolgen, oder in der Applikation selbst im Schema-Editor   erstellt werden. Dieser Abschnitt behandelt die zugrundeliegenden XML-Deklarationen. Wird eine Tabelle interaktiv im Schema-Editor erstellt, werden die hier beschriebenen Dateien automatisch generiert.

Eine Schema-Konfiguration wird im Ordner WEB-INF/kbase angelegt und hat das Namens-Schema <MySchema>Meta.xml, z.B. com.top_logic.demo/webapp/WEB-INF/kbase/DemoTypesMeta.xml.

Die Konfiguration des Datenbankschemas der fertigen Anwendung ist modular. D.h. das fertige Schema setzt sich aus vielen einzelnen Dateien zusammen, die sich in unterschiedlichen Modulen befinden. TopLogic liefert eine Reihe von solchen Schema-Definitionen bereits mit, die von der konkreten Anwendung geerbt und um eigene Deklarationen angereichert werden können. Jede einzelne Schema-Definitionsdatei muss daher in die Anwendungskonfiguration eingebunden werden. 

Die oben erwähnte Konfiguration  DemoTypesMeta.xml aus der Demo-Anwendung ist z.B. auf die folgende Art aus der Anwendungskonfiguration der Demo-Anwendung referenziert, siehe com.top_logic.demo/webapp/WEB-INF/conf/DemoConf.config.xml:

<application xmlns:config="http://www.top-logic.com/ns/config/6.0">
   <configs>
      <config config:interface="com.top_logic.basic.db.schema.setup.config.ApplicationTypes">
         <type-systems>
            <type-system name="Default">
               <declarations>
                  <declaration resource="webinf://kbase/DemoTypesMeta.xml" />
               </declarations>
            </type-system>
         </type-systems>
      </config>
   </configs>
</application>

Tabellendefinition

Eine normale Objekttabelle wird über das Tag metaobject definiert. Der Tabellenname wird über object_name angegeben.

<objectlist xmlns="http://www.top-logic.com/ns/meta/5.8">
  <metaobjects>

    <metaobject abstract="false" object_name="MyTable" super_class="TLObject">
      <attributes>
        ...
      </attributes>
    </metaobject>

  </metaobjects>
</objectlist>

Tabellendefinitionen in TopLogic können "abstrakt" sein. Eine abstrakte Tabelle wird in der Datenbank nicht angelegt, sondern dient nur als Vorlage für andere Tabellen. Eine Tabelle T kann eine andere Tabelle S als Vorlage verwenden, indem sie diese über super_class="S" referenziert. In diesem Fall erhält die Tabelle T alle Spalten von S als vorangestellte Spalten und zusätzlich die eigenen (in T definierten) Spalten hinten angefügt.

Wichtig ist, das der in object_name angegebene Name nur der sog. plattformunabhängige Tabellenname ist. Aus dem plattformunabhängigen Tabellennamen, der für die interne Referenzierung der Tabelle verwendet wird, generiert die Datenbankabstraktionsschicht automatisch einen konkreten Tabellennamen, der in SQL-Statements verwendet wird. Der SQL-Tabellenname ist i.d.R. in Großbuchstaben geschrieben und verwendet Unterstriche als Worttrenner. Zusatzlich kann je nach Datenbank eine Kürzung vorgenommen werden, um spezielle Einschränkungen des Datenbanksystems zu entsprechen. Aus der oben definierten Tabelle MyTable wird in der Datenbank die konkrete Tabelle MY_TABLE. In Fließtext verwendet diese Dokumentation immer den plattformunabhängigen Tabellennamen, wie der in den entsprechenden Schema-Deklarationsdateien zu finden ist. Nur wenn SQL-Statements als Beispiel gegeben werden, wird der SQL-Name der Tabelle verwendet.

Spaltendefinition

Eine Wertespalte (mit primitiven Typ) wird über das Tag mo_attribute definiert. Mit mandatory gibt man an, ob auf Datenbank-Ebene ausgeschlossen werden soll, dass der leere Wert gespeichert werden kann (NOT NULL in SQL). Über db_size wird für String-Spalten angegeben, wieviele Zeichen die Spalte maximal aufnehmen kann.

<mo_attribute att_name="myColumn" att_type="String" mandatory="false" db_size="256"/>

Auch für die Werte-Typen von Tabellenspalten existiert eine plattformunabhängige Beschreibung. Der plattformunabhängige Spaltentyp wird dann je nach verwendetem Datenbanksystem in einen konkreten SQL-Typ umgerechnet. Hierüber wird erreicht, dass eine Anwendung mit derselben Schemadefinition auf allen von TopLogic unterstützten Datenbanksystemen lauffähig ist.

Mögliche Werte-Typen für primitive Spalten sind:

  • String
  • Boolean
  • Integer
  • Long
  • Byte
  • Short
  • Character
  • Float
  • Double
  • Date
  • Time
  • Timestamp
  • Clob
  • Blob

Fremdschlüsselspalten

Eine Fremdschlüsselspalte (eine Spalte deren Wert eine Referenz auf ein anderes Objekt darstellt) wird über das Tag reference definiert. Der Ziel-Typ wird über target-type angegeben. Über den so definierten Fremdschlüssel können alle Objekte referenziert werden, welche in der in target-type angegebenen Tabelle gespeichert sind. Dabei ist es erlaubt, dass eine abstrakte Tabelle als Ziel-Typ angegeben wird. In diesem Fall können all diejenigen Objekte referenziert werden, die in Tabellen gespeichert sind, welche die angegebene abstrakte Tabelle als Vorlage nutzen (entweder direkt oder als Vorlage der Vorlage, usw.).

Die folgende Definition erzeugt eine Fremdschlüsselspalte keyCol, mit der Objekte referenziert werden können, die in der Tabelle OtherTable abgelegt sind:

<reference 
   att_name="keyCol"
   target-type="OtherTable"
   mandatory="false" 
   monomorphic="true" 
   deletion-policy="clear-reference" 
   is-container="false" 
   history-type="current" 
   branch-global="false" 
   initial="false"
   by-value="false"
/>

Da die Referenz nicht mandatory ist, kann die Referenz auch leer sein (auf kein anderes Objekt zeigen).

Mit monomorphic='true' wird angegeben, dass alle Objekte die referenziert werden, in derselben Tabelle (genau der angegebenen Tabelle OtherTable) liegen, auch dann, wenn die angegebene Tabelle als Vorlage für andere Tabellen genutzt wurde. Bei monomorphic='false' kann ein referenziertes Objekt auch in einer Tabelle liegen die den target-type (hier OtherTable) als Vorlage nutzen.

Die Deklaration einer Referenz in einem Tabellentyp erzeugt in konkreten SQL-Schema eine oder mehrere Spalten, je nachdem, wie die Referenz parametrisiert ist. Auf alle Fälle wird aber eine Spalte erzeugt, welche den technischen Identifier des referenzierten Objektes aufnehmen kann, vlg. Technische Spalten. Der Namen dieser ID-Spalte wird aus dem angegebenen Namen der Referenz mit dem Suffix _ID gebildet.

Lösch-Strategien

Über die deletion-policy bestimmt man, was passieren soll, wenn das referenzierte Ziel-Objekt gelöscht wird. Mögliche Werte sind

  • clear-reference: Die Referenz wird auf "leer" gesetzt (gelöscht).
  • delete-referer: Das referenzierende Quell-Objekt wird ebenfalls gelöscht.
  • stabilise-reference: Die Referenz bleibt erhalten und zeigt auf die letzte gültige Version der referenzierten Ziel-Objektes. Hierfür muss history-type auf mixed gesetzt werden.
  • veto: Die Löschung des referenzierten Ziel-Objekts wird verhindert.

Mit is-container kann man bestimmen, dass das referenzierte Ziel-Objekt "Teil" des referenzierenden Quell-Objektes ist und daher zusammen mit dem referenzierenden Quell-Objekt gelöscht werden soll. Eine Löschung setzt sich also über eine is-container Referenz auf das Ziel-Objekt fort. Diese Strategie funktioniert aktuell nur mit history-type=current auf dem referenzierten Zielobjekt.

Scope der Referenz

Ob eine Referenz auf historische Versionen eines Objektes zeigen kann wird über history-type angegeben, vgl. Datenversionierung. Mögliche Werte sind:

  • current: Die Referenz kann nur auf aktuelle Versionen von Objekten zeigen. Wird das referenzierte Objekt gelöscht, wird deletion-policy beachtet.
  • historic: Die Referenz zeigt ausschließlich auf stabile Versionen von Objekten. Wird sie mit einem aktuellen Objekt gefüllt, verweist sie nach dem Commit auf die in diesem Commit gültige Version des referenzierten Objektes (die Referenz wird "stabilisiert").
  • mixed: In einer solchen Referenz können sowohl aktuelle Stände als auch stabile Versionen von Objekten referenziert werden. Bei einer solchen Referenz kann stabilise-reference als deletion-policy verwendet werden, siehe oben.

Assoziationstabellen

Für typische Assoziationstabellen mit lediglich zwei Fremdschlüsseln (Quelle und Ziel) gibt es eine Kurzschreibweise.

Die folgende Definition erzeugt eine Link-Tabelle mit Namen myLinkTable, mit der eine Set- oder List-Referenz im Modell gespeichert werden kann. Hierfür muss die Vorlage hasWrapperAttValueBaseAssociation verwendet werden.

<association super_class="hasWrapperAttValueBaseAssociation" object_name="myLinkTable" />

Die so definierte Tabelle hat die beiden Fremdschlüssel source und dest. Wenn der Typ der Referenz oder die Optionen wie mandatory etc. angepasst werden sollen, dann können diese speziellen Fremdschlüssel auch über <source/> und <dest/> deklariert werden:

<association super_class="hasWrapperAttValueBaseAssociation" object_name="myLinkTable">
   <attributes>
      <source
         override="true"
         target-type="SpecialSourceTable"
      />
      <destination
         override="true"
         target-type="SpecialDestTable"
      />
   </attributes>
</association>

Die obige Definition ist also gleichbedeutend mit:

<association super_class="hasWrapperAttValueBaseAssociation" object_name="myLinkTable">
   <attributes>
      <reference 
         att_name="source"
         override="true"
         target-type="SpecialSourceTable"
      />
      <reference 
         att_name="dest"
         override="true"
         target-type="SpecialDestTable"
      />
   </attributes>
</association>

Indizes

Über das Tag mo_index können benutzerdefinierte Indices für Objekttabellen definiert werden. In der Liste index_parts werden die Attribute und Referenzen aufgezählt, über die der Index erstellt werden soll:

<metaobject abstract="false" object_name="MyTable" super_class="TLObject">
    <attributes>
        ...
    </attributes>

    <index>
        <mo_index name="myIndex" unique="false">
            <index-parts>
	        <index_part name="myAttr1"/>
	        <index_part name="myAttr2"/>
            </index-parts>
        </mo_index>
    </index>
</metaobject>

Das Attribut unique steuert, ob die Datenbank die Eindeutigkeit von Indexeinträgen erzwingen soll.

Branches

TopLogic ist prinzipiell mandantenfähig (siehe auch Mandantenfähigkeit). Hierfür wird in der Datenbank in jeder Fachtabelle eine zusätzliche Spalte "BRANCH" angelegt. Wenn eine Anwendung dies nicht benötigt, kann dies abgeschaltet werden. Je nach Datenvolumen kann so die Datenbank optimiert werden.

Um in die Mandantenfähigkeit abzuschalten und die unnötige "BRANCH" Spalte in der Datenbank zu verhindern kann die Konfigurations-Datei top-logic.singleBranch.config.xml in die Anwendung integriert werden.