Datenobjektdefinition

Unter einem Datenobjekt wird ein Objekt verstanden, das Daten in Form von Attributen enthält. Die Datenobjektdefinition legt unter anderem fest welche Attribute zu einem Datenobjekt gehören können, welche Datentypen diese haben, wie ein Objekt identifiziert werden kann, welche Verbindungen zu anderen Datenobjekten bestehen und wie auf die Daten zugegriffen werden kann. In einer relationalen Datenbank ist ein Datenobjekt als Tabelle zu sehen.
Ein Datenobjekt wird durch folgende Elemente beschrieben. In Klammern sind die Analogien einer relationalen Datenbank angegeben:

  • Objektname (Tabellenname)
  • Attribute (Spalten)
  • Objektschlüssel (Primärschlüssel)
  • Assoziationen (Fremdschlüssel)
  • Zusätzliche Abfragebedingung (SQL WHERE)
  • Abfragekommando (SQL SELECT)
  • Nachschlagedefinition (für die Suche von Werten)
  • Vordefinierte Daten (Tabellenzeilen)

Zusätzlich besteht die Möglichkeit, benannte Datenobjekte zu definieren. Dies sind schon definierte Datenobjekte, die zusätzlich unter anderem Namen nochmals definiert sind.
Dabei sind der Objektname, die Attribute und der Objektschlüssel Pflichtangaben. Alle anderen Angaben sind optional und dienen der flexiblen Anpassung an bestehende Applikationsanforderungen.
Innerhalb der XML Definition wird die Grundstruktur eines Datenobjektes innerhalb des MetaDataObjects Blocks wie folgt definiert:

<MetaDataObject
name=“Objektname“
connector=“connectorName“
dataLocalization=“dataLocalizationName“
hidden=“False“
readOnly="False">
<MetaAttributes>
<!-- Attributdefinition -->
</MetaAttributes>
<Select>
<!-- Spaltenliste für Datenbank-Select (optional) -->
</Select>
<FromSelect>
<!-- Tabellenliste für Datenbank-Select (optional) -->
</FromSelect>
<AdditionalWhereClause>
<!-- Where-Ausdruck für Datenbankzugriffe (optional)-->
</AdditionalWhereClause>
<GroupBy>
<!-- Group By-Ausdruck für Datenbank-Select (optional) -->
</GroupBy>
<QueryString>
<!-- SQL-Ausdruck Select .... FROM ... WHERE... (optionale alte Variante für SQL>-->
<!--QueryString>
<MetaObjectIdentifier>
<!-- Objektschlüsseldefinition -->
</MetaObjectIdentifier>
<MetaDataObject>

Konnektor

Der Konnektor ist der Dienst, der für den Datenzugriff für ein Datenobjekt verantwortlich ist. Innerhalb eines Paketes verwenden üblicherweise alle Datenobjekte den gleichen Service. Deshalb ist es sinnvoll, diesen in den Standardvorgaben im XML Kopf der Metadaten zu definieren.
In diesem Fall muß die Angabe des Konnektors nicht bei jedem Datenobjekt erfolgen.
Wird ein anderer Konnektor für ein Datenobjekt benötigt, wird dieser im connector Parameter eines Datenobjektes angegeben.
Dabei wird dort der Servicename aus der DLE Konfiguration angegeben. In der DLE Konfiguration sind dann wiederum die weiteren für den Datenzugriff nötigen Informationen angegeben.

Datenlokalisierung

Ähnlich der Konnektorangabe kann entweder pro Datenobjekt, oder im XML Kopf für alle Datenobjekte der Service für die Übersetzung von Dateninhalten angegeben werden. Dies erfolgt im durch den dataLocalization Parameter im Datenobjekt. Zur weiteren Beschreibung der Lokalisierung sei auf Das Kapitel 7.4 verwiesen.

Versteckte Datenobjekte

Soll ein Datenobjekt nicht in den Auswahllisten der DLE Editoren erscheinen, so kann dies über den Parameter hidden des Datenobjektes definiert werden. Wird der Parameter nicht angegeben, ist der Vorgabewert FALSE.

Datenobjekte ohne Schreibzugriffe

Mit dem Attribut readOnly="True" beim Datenobjekt kann verhindert werden, dass über dieses Datenobjekt Daten in der Datenbanktabelle verändert werden können. Standardwert ist FALSE. Query-Objekte sind immer readOnly

Datenobjektname

Der Objektname dient zur eindeutigen Identifizierung eines Datenobjektes in einem Paket. Innerhalb eines Paketes dürfen deshalb keine anderen Datenobjekte, Variablen oder Aliase denselben Namen haben, da es sonst bei einem späteren Zugriff zu unabsehbaren Problemen kommen kann.
Zudem unterscheidet die DLE durchgehend zwischen Groß- und Kleinbuchstaben.
Die DLE verwendet außerdem einige Sonderzeichen zur Steuerung, diese dürfen daher nicht als Bestandteil des Namens verwendet werden. Grundsätzlich sollten im Namen nur Buchstaben, Ziffern und der Unterstrich verwendet werden.
Je nach verwendeter Zugriffsklasse müssen unter Umständen auch Restriktionen der verwendeten Datenschicht beachtet werden. Wird zum Beispiel eine relationale Datenbank mit einem JDBC Treiber verwendet, kann es Restriktionen in Bezug auf Namenslänge und reservierter Namen geben.

Attribute

Ein Objektattribut besteht aus zwei Pflichtelementen: Einem Attributnamen und einem Datentyp.
Für den Namen eines Attributes gelten grundsätzlich die gleichen Einschränkungen wie für einen Datenobjektnamen. Nur müssen die Attributnamen eindeutig innerhalb eines Datenobjektes sein. Verschiedene Datenobjekte können durchaus Attribute mit gleichem Namen haben. Auch können Variablen den gleichen Namen haben wie ein Attribut. Dies ist möglich, da Attribute immer über ihr Datenobjekt angesprochen werden.
Innerhalb einer XML Definition (siehe auch Beispiel 5-6) erfolgt die Definition eines Attributes innerhalb des MetaAttributes Block dem folgenden Beispiel:

<MetaAttribute name=“AttributeName“>
<DataType dataType=“String“/>
</MetaAttribute>

Datentypen

Attribute und Variablen haben Datentypen. Diese dienen unter anderem dazu, den möglichen Wertebereich festzulegen und die Ein- und Ausgabe zu steuern. Zudem steuert der Datentyp auch die Kommunikation mit der verwendeten Datenschicht.
Die DLE unterscheidet grundsätzlich zwischen 6 Datentypen. Diese sind:

TypBeschreibung
StringZur Definition einer Zeichenkette. Die maximale Länge in Zeichen kann mit dem zusätzlichen Datentypattribut size angegeben werden.
NumberZur Definition einer Zahl. Es wird nicht zwischen ganzen Zahlen und Dezimalzahlen unterschieden. Die Länge und Anzahl der Nachkommazahlen kann mit den zusätzlichen Datentypattributen scale und precision angegeben werden.
DateZur Definition eines Datums. Unformatiert verwendet die DLE intern das Format JJJJ-MM-TT. (Jahr vierstellig, Monat zweistellig, Tag zweistellig).
DateTimeZur Definition eines Datums inklusive Zeitangabe.
Unformatiert verwendet die DLE intern das Format JJJJ-MM-TT SS:MM:SS. (Jahr vierstellig, Monat zweistellig, Tag zweistellig, Stunden zweistellig, Minuten zweistellig, Sekunden zweistellig).
BlobZur Definition eines Binärobjektes.
ClobZur Definition eines langen Textobjektes.

Grundsätzlich gilt, daß jeder Datentyp innerhalb der DLE, zum Beispiel bei Rechenoperationen und Zuweisungen, beliebig gemischt werden kann. Bei nicht passenden Datentypen wird eine automatische Konvertierung durchgeführt. So kann einem Zahlentyp eine Zeichenkette zugewiesen werden, oder mit Zeichentypen auch gerechnet werden. Voraussetzung für sinnvolle Ergebnisse ist jedoch dann auch ein sinnvoller Inhalt.

Zugriffsklassen für ein Attribut

Für eine Attribute kann eine Zugriffsklasse definiert werden. Diese muß das Interface DLEAttributeConnectorIfc implementieren und den entsprechenden Wert zurückliefern.
Zur näheren Erläuterung des Interfaces sei auf die zugehörige JAVADOC Dokumentation hingewiesen.
Die Zugriffsklasse kann noch mit einer beliebigen Anzahl von Parametern versehen werden, um eine weitere Flexibilität zu erhalten:

     <MetaAttribute name="SampleAttribute" transient="true">
      <DataType dataType="String" />
      <Accessor class="at.visionflow.dle.engine.accessors.DLEFieldAccessor">       
       <Parameters>
        <Parameter name="Save" value="GLOBAL:Sample*;DLETEST:OrgUnit.*" />
        <Parameter name="Field1" value="DLETEST:OrgUnit.OrgUnit_ID" />
        <Parameter name="Value1" value="$OrgUnit_ID" />
        <Parameter name="Field2" value="GLOBAL:SampleConstant" />
        <Parameter name="Value2" value="Hello World" />
        <Parameter name="Field3" value="GLOBAL:SampleField" />
        <Parameter name="Value3" value="$DLETEST:TransferOrder.OrgUnit_ID" />
        <Parameter name="Resultfield" value="DLETEST:OrgUnit.Name" />
       </Parameters>
      </Accessor>     
     </MetaAttribute>

 

oder

für Brickaufrufe:

     <MetaAttribute name="SampleAttribute" transient="true">
      <DataType dataType="String" />
      <Accessor class="at.visionflow.dle.engine.accessors.DLECallBrickAttributeAccessor">       
       <Parameters>
        <Parameter name="Save" value="GLOBAL:Sample*;DLETEST:OrgUnit.*" />
        <Parameter name="Folder" value="DLETEST:testFolder" />
        <Parameter name="Field1" value="BASE:BrickName" />
        <Parameter name="Value1" value="myBrick" />
        <Parameter name="Field2" value="DLETEST:OrgUnit.OrgUnit_ID" />
        <Parameter name="Value2" value="$OrgUnit_ID" />
        <Parameter name="Field3" value="GLOBAL:SampleConstant" />
        <Parameter name="Value3" value="Hello World" />
        <Parameter name="Field4" value="GLOBAL:SampleField" />
        <Parameter name="Value4" value="$DLETEST:TransferOrder.OrgUnit_ID" />
        <Parameter name="Resultfield" value="DLETEST:OrgUnit.Name" />
        <Parameter name="setOriginal" value="true" />
       </Parameters>
      </Accessor>     
     </MetaAttribute>

 

Die Parameter hängen von der verwendeten Zugriffsklasse ab. Sie werden bei einer Wertabfrage durch die DLE an die Zugriffsklasse weitergeleitet. Die Attribute sind meistens als transient="True" definiert, weil sie nicht durch den Datenbankzugriff direkt gefüllt werden.

 

 

 

 

 

Leerzeichen automatisch ersetzen

Sollen Leerzeichen am Ende von Daten automatisch durch die DLE entfernt werden, kann das Datentypattribut trim auf true gesetzt werden.
In diesem Fall werden die die Daten bei Übergabe an die DLE und beim Lesen durch die Datenschicht automatisch getrimmt, das heißt alle Leerzeichen am Ende der Daten werden entfernt.
Die Vorgabe für das Attribut trim kann in der Kopfzeile gesetzt werden (Seite 37), wurde diese nicht gesetzt, ist der Standardwert false.

Leerfelder erlauben

Sollen leere Werte erlaubt sein, kann durch das Datentypattribut allowedEmpty dies explizit gesetzt werden. Wird dieses auf true gesetzt, erfolgt durch die DLE in keinem Fall eine Leerfeldabfrage.
Die Vorgabe für das Attribut allowedEmpty kann in der Kopfzeile gesetzt werden (Seite 37), wurde diese nicht gesetzt, ist der Standardwert false.

Nachschlageobjekt innerhalb der Datentypdefinition

Soll die Möglichkeit definiert werden, daß die Werte eines Attributes aus einer Nachschlagetabelle1 bezogen werden können, kann im Datentyp das Datenobjekt angegeben werden, daß als Nachschlageobjekt verwendet werden soll. Das Nachschlageobjekt muß dabei im selben Paket als Datenobjekt definiert sein und eine gültige Nachschlagedefinition haben.
Hier ein Beispiel eines Attributes, daß das Datenobjekt Address als Nachschlageobjekt definiert:

<MetaAttribute name=“Sender_ID“>
<DataType dataType=“Number“ lookup=“Address“/>
</MetaAttribute>

Wird keine Nachschlagetabelle angegeben, versucht die DLE zur Laufzeit über die definierten Assoziationen diese zu ermitteln. Diese ist unter Umständen aber nicht eindeutig. Eine Definition innerhalb des Datentyps wird daher empfohlen.

Read-Only Attribute

Attribute können als Read-Only markiert werden. In diesem Fall werden die Daten zwar durch die Datenschicht gelesen, aber es wird nicht versucht, diese zu schreiben. Innerhalb der DLE können die Daten zwar verändert werden, bei allen Speicherfunktionen wird das Attribut aber nicht berücksichtigt.

<MetaAttribute name=“SumWeight“ readOnly=“true“>
<DataType dataType=“Number“/>
</MetaAttribute>

 

 

Transiente Attribute

Transiente Attribute sind Attribute, die zwar innerhalb der DLE als ganz normale Attribute verwendet werden können, jedoch nicht in der unterliegenden Datenschicht existieren. Transiente Attribute werden durch die Datenschicht weder gelesen noch geschrieben.

<MetaAttribute name=“RowID“ transient=“true“>
<DataType dataType=“Number“/>
</MetaAttribute>

Datenbankabfrage für ein Attribut modifizieren

Normalerweise benutzt die DLE bei der Erstellung von SQL WHERE Bedingungen den Attributnamen. Bei der Benutzung von Abfrageobjekten, die einen SQL Join benutzen, kann es jedoch vorkommen, daß einige Datenbanken mehrdeutige Attributnamen nicht auflösen können.
Verbindet man zum Beispiel zwei Tabellen TabA und TabB über die Spalten KEY_ID, die in beiden vorhanden sind mittels folgender Query:

SELECT A.KEY_ID FROM TabA A, TabB B WHERE A.KEY_ID=B.KEY_ID

kann dies bei einem Zugriff über den Primärschlüssel zu einem SQL Fehler führen, wenn das Attribut KEY_ID als Attribut und Primärschlüssel im Datenobjekt definiert wurde. Da in der angehängten SQL WHERE Bedingung nur der Attributname verwendet wird, dieser aber in beiden Tabellen vorhanden ist, liefern einige Datenbanken einen Fehler.
Um das zu vermeiden, kann man für ein Attribut optional ein Abfragekommando angeben, das dann anstelle des Attributnamens verwendet wird:

<MetaAttribute name=“KEY_ID“ queryString=“A.KEY_ID“>
<DataType dataType=“Number“/>
</MetaAttribute>

Anstelle eine WHERE Bedingung der Form „WHERE … AND KEY_ID = 1“ zu generieren, wird nun eine Bedingung der Form „WHERE … AND A.KEY_ID = 1“ erzeugt, die die Mehrdeutigkeit auflöst.

Übersetzbare Attribute

Die DLE bietet die Möglichkeit Dateninhalte zu übersetzen. Dazu wird der für das Paket definierte Datenlokalisierungsservice verwendet. Nähere Informationen zu diesem Service finden sich im Kapitel 7.4. Um die Übersetzung nicht grundsätzlich für alle Attribute zu versuchen, muß ein Attribut erst als übersetzbar markiert werden. Ist ein Attribut als übersetzbar markiert, wird nach dem Lesen der Daten, anhand verschiedener Informationen, versucht den Wert zu übersetzen.

<MetaAttribute name=“Color“ localizable=“true“>
<DataType dataType=“Number“/>
</MetaAttribute>

Erlaubte Aktionen auf ein Attribut festlegen

Um für bestimmte DLE Kommandos die Liste der möglichen Attribute und Variablen einzugrenzen, besteht die Möglichkeit für ein Attribut (und auch für eine Variable) die erlaubten Aktionen festzulegen.
Folgende Aktionen können angegeben werden:

TypBeschreibung
readDas Attribut kann nur bei Parametern verwendet werden, die als read Parameter gekennzeichnet sind.
setDas Attribut kann nur bei Parametern verwendet werden, die als read oder set Parameter gekennzeichnet sind.
setOriginalDas Attribut kann nur bei Parametern verwendet werden, die als read, set oder setOriginal Parameter gekennzeichnet sind.
storeDas Attribut kann bei allen Parametern verwendet werden. Das ist die Voreinstellung, wenn keine Aktion angegeben wurde.

Die Erlaubten Aktionen definieren nur die mögliche Verwendung der Attribute als Parameter innerhalb eines Kommandos. Sie steuern nicht den Datenzugriff. Innerhalb der DLE ist es zum Beispiel weiterhin möglich Attribute, die als read markiert sind zu speichern.
Das folgende Beispiel verhindert, daß das Attribut ObjectID durch Kommandos wie zum Beispiel FELD SETZEN ORIGINAL überschrieben werden kann. Auch kann dieses Attribut nicht im Kommando FELD SPEICHERN verwendet werden. Jedoch ist es weiterhin möglich, dieses Attribut zu lesen und temporär zu verändern.

<MetaAttribute name=“ObjectID“ action=“set“>
<DataType dataType=“Number“/>
</MetaAttribute>

Erweiterte Konvertierungsmöglichkeiten für Attribute

Wie bei den Datentypen (siehe Seite 39) beschrieben, versucht die DLE bei jeder Operation mit Werten diese vorher in den richtigen Typ zu konvertieren.
Für spezielle Konvertierungen besteht zudem die Möglichkeit für ein Attribut eine Konvertierungsfunktion zu definieren. Dies geschieht, indem für ein Attribut eine Konverterklasse definiert wird. Diese Klasse muß das Interface DLEConverterIfc implementieren.
Zur näheren Beschreibung des Interfaces sei auf die entsprechende JAVADOC Dokumentation verwiesen.
Bei jedem Lese- und Schreibvorgang wird die entsprechende Konvertierungsfunktion in dieser Klasse aufgerufen. Um die Konvertierung noch weiter steuern zu können und damit Konverter zu schreiben, die allgemeingültig sind, kann pro Attribut für einen Konverter noch eine beliebige Anzahl von Parametern definiert werden.
Ein Standardparameter ist das Parameter databaseType, mit dem spezifiziert wird, welcher Datentyp auf der unterliegenden Datenschicht verwendet werden soll. Dieser kann sich von dem in der DLE verwendeten unterscheiden.
Im folgenden werden die in der Standardversion mitgelieferten Konverter beschrieben. Dort finden sich auch Beispiele für die Definition innerhalb der XML Struktur.

Datumskonvertierung mit StringDateConverter

Der StringDateConverter dient zur Konvertierung von Zeichenketten In das DLE Datumsformat (Datentyp Date oder DateTime). Die Attributdaten werden mit dem in den Konverterparametern definierten Datentyp eingelesen, in eine Zeichenkette gewandelt und dann an den Konverter übergeben, der die Zeichenkette anhand eines definierten Musters in ein Datum umwandelt.
Wird ein Wert über die Datenschicht gespeichert, findet der Umgekehrte Prozeß statt.

<MetaAttribute name=“DateString“>
<DataType dataType=“Date“/>
<Converter class=“at.visionflow.dle.engine.connectors.StringDateConverter“>
<Parameters>
<Parameter name=“dataBaseType“ value=“String“/>
<Parameter name=“format“ value=“ddMMyy“/>
</Parameters>
</Converter>
</MetaAttribute>

Innerhalb der DLE wird das Attribut DateString wie ein Datum behandelt, in der Datenschicht aber als String behandelt. Die Konvertierung erfolgt mit einem Muster das im format Parameter definiert wird.
Die Syntax des Formats entspricht dem des in java.text.SimpleDateFormat definierten Musters. Die genaue Beschreibung der Formatierung kann dort nachgelesen werden.
In nachfolgender Tabelle findet sich eine Übersicht der im Muster erlaubten Zeichen.

ZeichenKomponenteBeispiel
GEpocheAD
yJahr1996; 96
MMonat im JahrJuli; Jul; 07
wWoche im Jahr27
WWoche im Monat2
DTag im Jahr189
dTag im Monat10
FWochentag im Monat2
ETag der WocheDienstag; Die
aAM/PMPM
HStunde des Tags (0-23)0
kStunde des Tags (1-24)24
KStunde in AM/PM (0-11)0
hStunde in AM/PM (1-12)12
mMinute der Stunde30
sSekunde der Minute55
SMillisekunde978
zZeitzonePacific Standard Time; PST; GMT-08:00
ZZeitzone nach RFC 822-0800

Das Beispiel 5-15 geht also davon aus, das in der Datenschicht das Datum als Zeichenkette abgelegt ist und der Tag dort in den Ziffern 1-2, der Monat in den Ziffern 3-4 und das Jahr in den Ziffern 5-6 abgelegt ist.

 

Zahlenkonvertierung mit MultiplierConverter

Der MultiplierConverter dient zur Umwandlung von Zahlen zwischen der DLE und der Datenschicht. Zahlen werden vor dem Speichern mit einem Faktor multipliziert und nach dem Lesen durch diesen Faktor dividiert.
Ist zum Beispiel ein Gewicht in Gramm gespeichert und soll es innerhalb der DLE als Kilogramm verwendet werden, ist ein Faktor von 1000 anzugeben.

<MetaAttribute name=“Weight“>
<DataType dataType=“Number“/>
<Converter class=“at.visionflow.dle.engine.connectors.MultiplierConverter“>
<Parameters>
<Parameter name=“factor“ value=“1000“/>
</Parameters>
</Converter>
</MetaAttribute>

Bei dezimalen Faktoren ist ein Punkt als Dezimaltrennzeichen zu verwenden.

Objektschlüssel

Neben mindestens einem Attribut muß für ein Datenobjekt auch ein Objektschlüssel definiert werden. Dieser entspricht üblicherweise dem Primärschlüssel auf einer relationalen Datenbank.
Der Objektschlüssel wird im Anschluß an die Attribute definiert und enthält eine Liste von Attributen des Datenobjekts, aus denen der Objektschlüssel aufgebaut ist.

<MetaDataObject name=“Colors“>
<MetaAttributes>
<MetaAttribute name=“Color_ID“>
<DataType dataType=“Number“/>
</MetaAttribute>
<MetaAttribute name=“Color“>
<DataType dataType=“String“/>
</MetaAttribute>
</MetaAttributes>
<MetaObjectIdentifier>
<MetaAttributes>
<MetaAttribute name=“Color_ID“/>
</MetaAttributes>
</MetaObjectIdentifier>
<MetaDataObject>

Bei der Verwendung eines JDBC Konnektors kann in der Definition des Objektschlüssels noch spezifiziert werden, wie die automatische Vergabe der Schlüsselwerte erfolgt.
Mit dem Attribut autoNumber im MetaObjectIdentifier Block, wird angegeben daß die Datenbank die Werte automatisch befüllt. Mögliche Werte sind TRUE oder FALSE.

<MetaObjectIdentifier autoNumber=“TRUE“>
<MetaAttributes>
<MetaAttribute name=“Color_ID“/>
</MetaAttributes>
</MetaObjectIdentifier>

Dies kann auch global für alle Datenobjekte des Paketes definiert werden, indem im MetaDataObjects Block das Attribut defaultAutoNumber gesetzt wird. Auch hier sind die möglichen Werte TRUE oder FALSE.

<MetaDataObjects defaultAutoNumber=“TRUE“>
<MetaDataObject>

<MetaDataObject>
</MetaDataObjects>

Sollen die Schlüssel alternativ mit SQL SEQUENCES vergeben werden, muß in der Schlüsseldefinition der Sequenzname angegeben werden. Da die Methoden zur Ermittlung von Sequenzen von Datenbank zu Datenbank unterschiedlich sind, muß der Konnektor jedoch den gewählten Datenbankdialekt unterstützen.

<MetaObjectIdentifier autoNumber=“FALSE“ sequence=“COLORSEQ“>
<MetaAttributes>
<MetaAttribute name=“Color_ID“/>
</MetaAttributes>
</MetaObjectIdentifier>

Bei der Verwendung von Sequenzen ist zudem die AutoNumber Funktionalität auszuschalten.
Die Verwendung von Sequenzen mit mehr als einem Attribut im Objektschlüssel wird nicht unterstützt.

Assoziationen

Im Anschluß an die Objektschlüsseldefinition können die Assoziationen eines Datenobjektes zu anderen Datenobjekten definiert werden.
Assoziationen erleichtern den Zugriff auf zusammenhängende Daten innerhalb der DLE, da die abhängigen Daten automatisch anhand der Assoziationsbeschreibung geladen werden können.
Um eine Assoziation zu definieren wird das Zielobjekt, sowie die Fremdschlüsselbeziehungen beider verbundenen Objekte beschrieben.
Der Name einer Assoziation unterliegt dabei den gleichen Restriktionen wie ein Datenobjektname (siehe Seite 38).
Für eine Assoziation kann zudem angegeben werden, ob es sich um eine 1:n Beziehung handelt.
Assoziationen sind immer nur Einseitig. Sollen beide Seiten einer Assoziation zur Verfügung gestellt werden, ist bei beiden Datenobjekten die Beziehung zu definieren. Beispiel 5-20 zeigt die Grundstruktur einer Assoziationsdefinition innerhalb eines Datenobjektes.

<MetaDataObject name=“Objektname“>
<MetaAttributes>
<!-- Attributdefinition -->
</MetaAttributes>
<MetaObjectIdentifier>
<!-- Objektschlüsseldefinition -->
</MetaObjectIdentifier>
<MetaAssociations>
<MetaAssociation
name=“associationName“
targetMetaDataObject=“targetDataObjectName“>
<AttributeRelations>
<AttributeRelation
sourceMetaAttribute=“sourceAttributeName“
targetMetaAttribute=“targetAttributeName“/>
</AttributeRelations>
</MetaAssociation>
<MetaAssociations>
<MetaDataObject>

Die Assoziationen für ein Datenobjekt werden innerhalb des <MetaAssociations> Blocks definiert. Jede Assoziation wird darunter durch einen eigenen <MetaAssociation> Block beschrieben.
Im Parameter name wird der Name der Assoziation angegeben. Im Parameter targetDataObjectName wird der Name des Zielobjektes angegeben. Das Zielobjekt muß dabei innerhalb desselben Paketes definiert sein. Es spielt dabei keine Rolle, ob es innerhalb der XML Definition vor oder nach dem ausgehenden Datenobjekt definiert wird.
Anschließend wird die Beziehung beider Datenobjekte definiert, indem angegeben wird welches Attribut aus dem aktuellen Datenobjekt (sourceMetaAttribute) zu welchem Attribut aus dem Zielobjekt (targetMetaAttribute) in Beziehung steht.
Die Beziehung kann mehrere Attribute umfassen, in solch einem Fall sind einfach weitere <AttributeRelation> Blöcke zu definieren.
Die verwendeten Attribute müssen im jeweiligen Datenobjekt als <MetaAttribute> definiert sein.
Gibt es zum Beispiel zwei Datenobjekte Auftrag und Adresse, wobei jeder Auftrag einen Kunden hat, so würde man diese Beziehung in einer relationalen Datenbank mit einem Attribut im Auftrag (zum Beispiel Kunde_ID) definieren, die auf den Adressschlüssel (zum Beispiel Adresse_ID) im Adressobjekt zeigt.
Innerhalb der XML Metadatendefinition würde man die Assoziation dann wie folgt definieren:

<MetaAssociation
name=“Kunde“
targetMetaDataObject=“Adresse“>
<AttibuteRelations>
<AttributeRelation
sourceMetaAttribute=“Kunde_ID“
targetMetaAttribute=“Adresse_ID“/>
</AttributeRelations>
</MetaAssociation>

1:n Assoziationen

Die Definition von 1:n Assoziationen erfolgt nach dem gleichen Schema, nur das die Assoziation noch mit dem Parameter toMany versehen wird.
Ein typisches Beispiel sind Auftragspositionen. Zu einem Auftrag existieren mehrere Auftragspositionen in einer Tabelle Position. Die Relation wird definiert, indem im Datenobjekt Position der Objektschlüssel des Auftrags (Auftrag_ID) gespeichert wird. In den Metadaten wird solch eine Assoziation wie folgt beschrieben:

<MetaAssociation
name=“Auftragspositionen“
targetMetaDataObject=“Position“
toMany=“True“>
<AttibuteRelations>
<AttributeRelation
sourceMetaAttribute=“Auftrag_ID“
targetMetaAttribute=“Auftrag_ID“/>
</AttributeRelations>
</MetaAssociation>

Durch den Parameter toMany erwartet die DLE als Ziel dieser Assoziation eine Menge von Datenobjekten, in diesem Beispiel Auftragspositionen.
Diese können zum Beispiel durch Schleifenkommandos bearbeitet werden.

Erweiterte Assoziationen

Die Metadaten bieten noch zwei optionale Parameter für Assoziationen, um diese noch flexibler zu gestalten. Dies sind zusätzliche Zielwerte und eine freie Abfragebedingung.
Zielwerte können zusätzlich zu Attributrelationen angegeben werden. Sie dienen zur Einschränkung und Parametrisierung der Daten, die für eine Assoziation geladen werden.
Sie können jedoch auch ohne Attributrelationen alleine eine Assoziation beschreiben.
Zielwerte können auch dazu verwendet werden um aus einer eigentlich 1:n Assoziation eine zu eins Assoziation zu machen, indem die Ergebnismenge eingeschränkt wird.
Als Beispiel dient die oben definierte Beispielassoziation Positionen (Beispiel 5-22). Hat die Position zum Beispiel eine Positionsnummer, so kann man eine Assoziation ErstePosition wie folgt definieren:

<MetaAssociation
name=“ErstePosition“
targetMetaDataObject=“Position“
<AttibuteRelations>
<AttributeRelation
sourceMetaAttribute=“Auftrag_ID“
targetMetaAttribute=“Auftrag_ID“/>
</AttributeRelations>
<TargetValues>
<TargetValueEquals name=“Positionsnummer“ value=“1“/>
</TargetValues>
</MetaAssociation>

Werden die Daten in diesem Fall über die Assoziation selektiert, werden nicht nur die Positionen gesucht, die die entsprechende Auftrag_ID haben, sondern diese werden noch weiter eingeschränkt um die Positionen, die in dem Feld Positionsnummer eine 1 stehen haben.
Da es sich um eine zu eins Assoziation handelt, wird der erste gefundene Datensatz geladen.
Es können mehrere Zielwerte angegeben werden, die dann durch ein logisches und verknüpft werden.
Als Wert können nicht nur konstante Werte angegeben werden, sondern auch Variablenausdrücke, die dann zur Laufzeit mit dem Wert der Variablen ersetzt werden:

<TargetValues>
<TargetValueEquals name=“Datum“ value=“$BASE:CurrentDate“/>
</TargetValues>

Eine weitere, noch flexiblere Möglichkeit zur Anpassung von Assoziationen ist die Angabe einer zusätzlichen Abfragebedingung. Diese wird ähnlich der Zielwertangabe verwendet, um das Laden der Daten zu beeinflussen.
Die Abfragebedingung kann zusätzlich zu bestehenden Attributrelationen und Zielwerten angegeben werden, aber auch alleinig die Assoziation definieren. Hier die Umsetzung von Beispiel 5-23 mit Hilfe einer Abfragebedingung anstelle des Zielwertes in der Assoziation:

<MetaAssociation
name=“ErstePosition“
targetMetaDataObject=“Position“
<AttibuteRelations>
<AttributeRelation
sourceMetaAttribute=“Auftrag_ID“
targetMetaAttribute=“Auftrag_ID“/>
</AttributeRelations>
<AdditionalWhereClause>
<![CDATA[Positionsnummer = 1]]>
</AdditinalWhereClause>
</MetaAssociation>

Die Abfragebedingung wird an bestehende Bedingungen mit einem logischen und angehangen und direkt an die Datenschicht weitergeleitet.
Bei der Verwendung eines JDBC oder Versata Konnektors kann hier ein beliebiger gültiger SQL Teilausdruck verwendet werden, der dann innerhalb einer SQL WHERE Bedingung eingefügt wird. Es ist daher auf korrekte Syntax zu achten, die von der verwendeten Datenschicht bestimmt wird.
Auch in der Abfragebedingung können beliebig viele Variablenausdrücke verwendet werden, die zur Laufzeit durch die aktuellen Variablenwerte ersetzt werden, bevor der Ausdruck an die Datenschicht weitergegeben wird. Hier das Beispiel 5-24 mit einer Abfragebedingung anstelle des Zielwertes:

<AdditionalWhereClause>
<![CDATA[Datum = ’$BASE:CurrentDate’]]>
</AdditinalWhereClause>

Zusätzliche Abfragebedingung bei Datenobjekten

Ähnlich den zusätzlichen Abfragebedingungen bei Assoziationen kann auch direkt für ein Datenobjekt eine zusätzliche Abfragebedingung angegeben werden.
Diese wird grundsätzlich bei jedem Lade- oder Speichervorgang an die Datenschicht übergeben. Die genaue Syntax hängt daher von der verwendeten Datenschicht ab.
Innerhalb der Abfragebedingung können beliebige Variablenausdrücke verwendet werden, die zur Laufzeit durch die entsprechenden Variablenwerte ersetzt werden.
Wurden bestimmte Datenobjekte zum Beispiel mit einem Kennzeichen Aktiv versehen (Numerisch: 1=Ja, 0=Nein), kann man mit einer Abfragebedingung steuern, das nur aktive Datensätze geladen werden:

<MetaDataObject name=“Auftrag“>
<MetaAttributes>
<MetaAttribute name=“Auftrag_ID“>
<DataType dataType=“Number“/>
</MetaAttribute>
<MetaAttribute name=“Aktiv“>
<DataType dataType=“Number“/>
</MetaAttribute>
</MetaAttributes>
<MetaObjectIdentifier>
<MetaAttributes>
<MetaAttribute name=“Auftrag_ID“/>
</MetaAttributes>
</MetaObjectIdentifier>
<AdditionalWhereClause>
<![CDATA[Aktiv = 1]]>
</AdditionalWhereClause>
</MetaDataObject>

Definiert man für das Paket zudem eine Variable, kann diese in der Bedingung verwendet werden. Damit kann dann durch setzen der Variable einfach gesteuert werden, ob aktive oder inaktive Datensätze geladen werden sollen:

<AdditionalWhereClause>
<![CDATA[Aktiv = $DEMOPAKET:Aktiv]]>
</AdditionalWhereClause>

Die Abfragebedingung wird nicht beachtet, wenn ein neuer Datensatz gespeichert wird (insert). Beim speichern eines schon existierenden Datensatzes (update), wird die Abfragebedingung jedoch benutzt um irrtümliches überschreiben falscher Datensätze zu verhindern.
Zur Laufzeit kann über die spezielle Variable $DLE:WhereSubstitute die Position bestimmt werden, an der die zusätzliche Abfragebedingung eingesetzt werden soll. Taucht diese Variable in einer Abfrage auf, wird die zusätzliche Abfragebedingung an dieser Stelle eingesetzt, ansonsten wird sie durch ein logisches und verknüpft angefügt.

Abfrageobjekte definieren

Abfrageobjekte sind normale Datenobjekte, die jedoch über eine definierte Abfragebedingung geladen werden. Abfrageobjekte können nicht gespeichert werden. Sie werden definiert wie ein normales Objekt, erhalten aber ein zusätzliches Parameter <QueryString>, in dem eine Abfrage der zugrunde liegenden Datenschicht angegeben wird.
Derzeit unterstützt nur der JDBC Konnektor Abfrageobjekte. Hier ist als Abfragekommando eine SQL SELECT Anweisung anzugeben.
Die möglichen Werte einer Abfrage müssen als Attribute definiert sein, die Abfrage selber kann beliebig sein und mehrere Tabellen zusammenfassen.
Im Sprachgebrauch der relationalen Datenbanken ist ein Abfrageobjekt somit als VIEW zu verstehen.

<MetaDataObject name=“AuftragKunde“>
<MetaAttributes>
<MetaAttribute name=“Auftrag_ID“>
<DataType dataType=“Number“/>
</MetaAttribute>
<MetaAttribute name=“Nummer“>
<DataType dataType=“String“/>
</MetaAttribute>
<MetaAttribute name=“Kunde“>
<DataType dataType=“String“/>
</MetaAttribute>
</MetaAttributes>
<MetaObjectIdentifier>
<MetaAttributes>
<MetaAttribute name=“Auftrag_ID“/>
</MetaAttributes>
</MetaObjectIdentifier>
<QueryString>
<![CDATA[
SELECT
A.AUFTRAG_ID as Auftrag_ID,
A.NUMMER as Nummer,
K.NAME as Kunde
FROM
AUFTRAG A,
ADRESSE K
WHERE
K.ADDRESS_ID = A.KUNDE_ID
]]>
</QueryString>
</MetaDataObject>

Ein Abfrageobjekt kann ansonsten alle Eigenschaften eines normalen Datenobjektes haben, wie zum Beispiel Assoziationen und Nachschlagedefinitionen.
Innerhalb des Abfragekommandos können zudem beliebige Variablenausdrücke verwendet werden, die zur Laufzeit durch die entsprechenden Variablenwerte ersetzt werden.

Definition von Nachschlageobjekten

Nachschlageobjekte können in Dialogen und Editoren der DLE dazu verwendet werden, um Werte aus einer Liste von möglichen Werten auszuwählen. Ist für eine Variable oder ein Attribut ein Nachschlageobjekt (im Datentyp) angegeben, wird bei der Eingabe der Werte automatisch die Möglichkeit bereitgestellt, die Werte aus einer Auswahlliste zu wählen.
Nachschlageobjekte sind dabei normale Datenobjekte, die mit zusätzlichen Informationen versehen sind, die beschreiben wie diese Auswahllisten aufgebaut und dargestellt werden sollen.
Zur weiteren Erläuterung dient das folgende Beispiel, das die Nachschlagedefinition für ein Datenobjekt Farbe definiert:

<MetaDataObject name=“Farbe“>
<MetaAttributes>
<MetaAttribute name=“Farbe_ID“>
<DataType dataType=“Number“/>
</MetaAttribute>
<MetaAttribute name=“Name“>
<DataType dataType=“String“/>
</MetaAttribute>
<MetaAttribute name=“RGB“>
<DataType dataType=“String“ alternateSelectionType="True"/>
</MetaAttribute>
</MetaAttributes>
<MetaObjectIdentifier>
<MetaAttributes>
<MetaAttribute name=“Farbe_ID“/>
</MetaAttributes>
</MetaObjectIdentifier>
<Lookup>
<Columns>
<Column
attribute=“Farbe_ID“
selectionType=“False“
displayType=“False“
unique=“True“
hidden=“True“
width=0/>
<Column
attribute=“Name“
selectionType=“True“
displayType=“True“
unique=“False“
hidden=“False“
width=100/>
</Columns>
</Lookup>
</MetaDataObject>

Die Nachschlagedefinition erfolgt innerhalb eines <Lookup> Blocks innerhalb einer Datenobjektdefinition. Dazu werden die einzelnen, für die Nachschlageinformationen wichtigen Spalten aufgelistet und typisiert.
Es sind nur die für die Darstellung und Auswahl relevanten Attribute aufgelistet, es ist nicht notwendig alle Attribute des Datenobjektes aufzulisten.
Die Parameter pro Spalte/Attribut sind dabei alle Pflichtfelder und müssen in jedem Fall angegeben werden. Sie haben folgende Bedeutung:

ParameterBeschreibung
attributeAttributname des Datenobjekts.
selectionTypeGibt an, ob das Attribut als Eingabefeld für die Suche verwendet wird. Es ist nur ein Attribut möglich.
alternateSelectionTypeDer alternateSelectionType ist optional. Wird der Wert auf True gesetzt, wird zuerst geschaut, ob es zu dem Suchbegriff einen exakten Match für dieses Attribut gibt. Falls ja, wird der Datensatz als Ergebnis zurückgegeben. Falls nicht, wird mit der normalen Suche über das selectionType Attribut weitergemacht. So kann man z.B. eine Adresssuche normal nach Matchcode und exakt nach Kundennummer definieren. Gibt man eine Kundennummer ein und wird sie gefunden, wird diese ausgewählt. Falls nicht, wird mit der normalen Matchcodesuche fortgefahren.
displayTypeGibt an, on das Attribut im Ergebnisfeld angezeigt werden soll. Wenn mehrere Attribute definiert wurden, werden diese in der Anzeige durch Kommata getrennt angezeigt.
uniqueGibt an, ob es sich um den eindeutigen Schlüssel handelt, der als Wert für die variable oder das Attribut übernommen wird.
hiddenGibt an, ob das Attribut in der Auswahlliste versteckt werden soll. Es können mehrere Attribute angezeigt werden. Üblicherweise werden aber die technischen Schlüssel versteckt.
widthGibt die Breite der Spalte in der Auswahlliste an.
minInputLengthDieser optionale Parameter gibt bei einem Feld das als selectionType definiert wurde die minimale Anzahl der Zeichen an, die für eine Suche eingegeben werden müssen. Wird dieser Parameter nicht angegeben, wird 0 als Standardvorgabe verwendet.
caseSensitiveDer Suchbegriff, welcher für das Feld verwendet wird, welches als „selectionType=true“ definiert wurde, wird case-sensitiv gehandhabt.
upperEs ist im Voraus bekannt, das die Eintragungen in der Datenbank für den Suchbegriff, welcher für das Feld verwendet wird, nur in Grossbuchstaben verwendet werden (typisch bei MATCHCODE). Dann die Suchbegriffe werden automatisch in Grossbuchstabelnumgewandelt.

Die Nachschlagedefinition für Farben in Beispiel 5-30 bedeutet also, daß das Attribut Farbe_ID nach der Auswahl als Wert übernommen wird (unique), jedoch weder in der Auswahl noch im Ergebnis angezeigt wird. Das Attribut Name wird in der Auswahlliste als (einzige) Spalte angezeigt (hidden), es kann über dieses Attribut in der Eingabe gesucht werden (selectionType) und nach der Auswahl wird der Inhalt als Ergebnis angezeigt (displayType).

Vordefinierte Daten

Über einen speziellen Konnektor ist es möglich für Datenobjekte die Daten schon in den Metadaten anzugeben.
Dies ist besonders nützlich in Verbindung mit Nachschlagedefinitionen, um Standardauswahlen zu definieren.
Intern verwendet die DLE solche Definitionen für eine Reihe von Auswahllisten in den Editoren. Als Beispiel hier die Definition der Ja/Nein Auswahl.
Die Definition der Daten erfolgt innerhalb des Datenobjektes in einem <Data> Block. Darunter werden die einzelnen Zeilen jeweils in einem <Row> Block definiert. In einem <Row> Block werden dann die Werte der einzelnen Attribute über jeweils einen <Column> Block angegeben.
Als Konnektor wird der MetaDataConnector verwendet, dies ist ein Standardkonnektor, der in der DLE Konfiguration definiert ist.

<MetaDataObject
name="LookupYesNo"
hidden="true"
connector=“MetaDataConnector“>
<MetaAttributes>
<MetaAttribute name="ID">
<dataType dataType="String"/>
</MetaAttribute>
<MetaAttribute name="ShortName" localizable="True">
<dataType dataType="String" />
</MetaAttribute>
<MetaAttribute name="Text" localizable="True">
<dataType dataType="String" />
</MetaAttribute>
</MetaAttributes>
<MetaObjectIdentifier>
<MetaAttributes>
<MetaAttribute name="ID"/>
</MetaAttributes>
</MetaObjectIdentifier>
<Lookup>
<Columns>
<Column
attribute="ID"
selectionType="False"
displayType="False"
unique="True"
hidden="True"
width="20"/>
<Column
attribute="ShortName"
selectionType="True"
displayType="False"
unique="False"
hidden="False"
width="60"/>
<Column
attribute="Text"
selectionType="False"
displayType="True"
unique="False"
hidden="False"
width="120"/>
</Columns>
</Lookup>
<Data>
<Row>
<Column attribute="ID" value="Y" />
<Column attribute="ShortName" value="Y" />
<Column attribute="Text" value="Yes" />
</Row>
<Row>
<Column attribute="ID" value="N" />
<Column attribute="ShortName" value="N" />
<Column attribute="Text" value="No" />
</Row>
</Data>
</MetaDataObject>

Benannte Datenobjekte

Benannte Datenobjekte sind bereits definierte Datenobjekte, die zusätzlich unter einem anderen Namen geführt werden. Sie haben dieselbe Struktur (Attribute, Objektschlüssel, Assoziationen, Nachschlagedefinition etc.) wie das referenzierte Datenobjekt, werden aber wie eigenständige Datenobjekte unter einem anderen Namen geführt.
Sie können dazu verwendet werden, um gleichartige Daten nicht nur über den Objektschlüssel zu unterscheiden, sondern auch unter einem anderen Namen zu führen:

<MetaDataObject name=“Orginalauftrag“ reference=“Auftrag“/>

Hier wird ein benanntes Datenobjekt definiert, das Orginalauftrag heißt und bei dem es sich um ein Datenobjekt vom Typ Auftrag handelt.
Das Datenobjekt Auftrag muß dabei innerhalb der XML Definition vor dem benannten Datenobjekt definiert worden sein.
Da die DLE pro Datenobjekt immer nur ein bestimmtes als aktuellen Datensatz erlaubt, hat man mit benannten Datenobjekten die Möglichkeit, verschiedene gleichartige Datenobjekte gleichzeitig als aktuellen Datensatz zu definieren. Mit obigem Beispiel kann man zum Beispiel sehr einfach Werte zwischen einem Orginalauftrag und einem Auftrag austauschen oder vergleichen.