XML-API Abstract Das XML-API ist ein API, das alle DB-Funktionalitäten für eine OLTP-Anwendung bereitstellen soll. Es beruht auf dem Austausch von XML-Dokumenten, die sowohl den DBRequest als auch den DB-Reply formulieren. Als Datencontainer wird hier zunächst ein CLOB verwendet. Das XML-API ist verfügbar für alle Oracle-DBs ab Version 8i (XDK ist erforderlich). Das XML-API ist ein Teil einer Gesamtkonzeption, die alle Aufgaben im Bereich der DB in standardisierter Weise erledigen soll. Dazu zählen im weiteren BatchProzessing, Fehler-Behandlung, Historisierung, Validierung, Benutzerrechte-Verwaltung, Online-Nachrichten und Aggregierung für Warehouse-Zwecke. Ausgangspunkt der Entwicklung und Motivation für das XML-API war der Trend zu Anwendungen, die weltweit verfügbar sein sollen. DB und Anwendung kommunizieren dabei über ein WAN (z.B. Internet, Intranet, DFÜ) mit einer Vielzahl von Zwischenknoten und evtl. mit schmaler Bandbreite. Im Unterschied zu schnellen LAN-Verbindungen ist es hier von Vorteil, Frequenz und Umfang der Kommunikations-Vorgänge zwischen DB und Anwendung klein zu halten. So sollten z.B. beliebig viele Aktionen der Anwendung zu einem Request zusammengefasst werden können, um die Frequenz der Zugriffe zu minimieren.Umfangreiche Query-Ergebnisse sollten stückweise abgeholt werden können, was den Umfang senkt, da evtl. dabei nicht der gesamte Result-Set angefordert wird. Weiterhin stellte sich auch ein Trend zu XML als der „Sprache des Datentransfers im Internet“ heraus. Beiden Punkten sollte das XML-API entsprechen. Aus der räumlichen Trennung von DB und Anwendung ließ sich der Kernpunkt der Konzeption des XML-API ableiten: die logische Trennung der Präsentation der Informationen in der Anwendung und deren Ablage (Persistenz) in der DB. Entwicklung, Wartung, der gesamte Lifecycle sollten entkoppelt werden. Beide sollten ausschließlich über eine logisch zu definierende Schnittstelle (ein API) kommunizieren. Dies bedingte die gegenseitige Unabhängigkeit in der Sprache und im Datenmodell. Um die sprachliche Unabhängigkeit zu erreichen, war es wichtig, sich klarzumachen, dass Information immer an eine bestimmte Sprache gebunden ist. Dies gilt in gleicher Weise für Natursprachen als auch für Programmiersprachen. Wenn eine Anwendung, z.B. ein WebClient HTML (oder C++, JAVA, WML etc.) verwendet, so ist auch die Information, die dort verarbeitet wird, an diese Sprache gebunden. Demgegenüber ist die Oracle-DB eine Domäne von SQL. Unabhängig können sie nur werden, wenn sie ausschließlich in einer dritten Sprache Informationen austauschen. XML läßt sich dabei leicht in HTML oder WML übersetzen, da sie der gleichen Sprachfamilie SGML angehören und wurde auch deswegen gewählt. Anwendung und DB sollten dabei die jeweilige Übersetzung ihrer Sprache nach XML leisten und ausschließlich für den Informationstransfer verwenden. Im Vordergrund der Aufgabe, Information zu präsentieren, steht die Ergonomie der Anwendung. Würde die Information so präsentiert, wie sie in der DB relational abgelegt ist, wäre sie kaum transparent. Würde die Information dagegen in der DB so abgelegt, wie sie präsentiert werden soll, wäre eine relationale Ablage kaum möglich. Zudem hätte die Anwendung nur eine Sichtweise der Daten, polymorphe Sichten wären unmöglich. Daher ergab sich, auch die Modellierung der Information zu trennen. Auch hier steht im Zentrum die hierarchische Modellierung bei XML. Die Anwendung transferiert ihr Modell (meist ein OO-Modell) dorthin, das XML-API überträgt dieses wiederum in das relationale DB-Modell. Das zentrale XML-Dokument ist also Träger von Sprache und Modell. Das XML-API erhält dabei beide Komponenten. Wenn es einen Request verarbeitet, antwortet (Reply) es ebenfalls in XML und im gleichen Modell. Sprache und Modell werden konstant gehalten. Dies soll die anschließende Verarbeitung des Dokuments in der Anwendung möglichst einfach machen. Methoden, die den Request erstellen, können für das Auswerten des Reply wiederverwendet werden. (Im Unterschied dazu z.B. SQL-Select: Die DB beantwortet eine Select-Anweisung mit einer Tabelle. Eine Methode, die ein Select generiert, kann nie zur Analyse der ErgebnisTabelle wiederverwendet werden.) In der Praxis enthält das Request-Dokument als Auftrag an die DB eine Request-ID ohne spezielle Zweckbindung, eine Client-ID für eine Benutzerrechte-Verwaltung auf Satzebene sowie die beliebig lange Task-Liste der Einzel-Aktionen. Im Reply enthalten sind dann die Task-Feedbacks sowie allgemeine Return-Codes, letztere besonders bei Fehlersituationen. Auch physisch wird das Dokument konstant gehalten, der Reply entsteht, indem das RequestDokument im Zuge der Verarbeitung in-place transformiert wird. Die Task-Liste eines Requests kann jeweils in beliebiger Menge und Reihenfolge enthalten: QUERY : beliebige Abfragen an die Datenbank. Die Abfrage-Bedingung ist dabei in XML zu formulieren. Sie kann beliebig viele Einzelbedingungen enthalten, die mit Operatoren (eq, lt, gt, le, ge, in, between u.a.) Attribute einer „Abfrage-Klasse“ referenzieren. Die Einzelbedingungen können mit Mengenoperatoren (and, or), auch mit Klammerung verbunden werden. Bei der Verarbeitung wird automatisch eine konfigurierbare Obergrenze des Result-Set wirksam, um die DB-Ressource begrenzen zu können. QUERY liefert nur die Größe des Result-Set zurück und speichert intern die logischen (auch hier logisch!) Primärschlüssel der „Abfrage-Klasse“ für das LIST : das Abholen des Result-Set der letzten Query. In der XML-Struktur des Task wird das gewünschte Modell hinterlegt. Dabei müssen die logischen Primärschlüssel der „Top-Klasse“ lediglich fachlich kompatibel mit dem der „Abfrage-Klasse“ sein. Über eine Bereichsangabe (from, to) kann die zu übertragende Menge genau und stückweise festgelegt werden. LIST füllt dann die „Top-Klasse“ aus dem Query-Result mit allen „sichtbaren“ Attributen und ergänzt die tieferen Ebenen des Modells mit LOAD : das Laden per logischem Primärschlüssel. Logische Primärschlüssel sind beliebig auswählbare Attribute und Attributkombinationen einer „Klasse“, deren Werte vom XML-API als eindeutig angesehen werden sollen. Sie können sichtbar oder nicht sichtbar sein. Sie sind nicht an physische „Primary Keys“ der DB gebunden, da dies der o.g. Unabhängigkeit der Modelle widersprechen würde. Wie bei LIST erwartet LOAD im XML-Text die Vorgabe der Modellstruktur. Jedoch wird nicht ein Query-Result-Set, sondern eine Angabe von Primärschlüssel-Werten der „TopKlasse“ für die Bestimmung der Menge ausgewertet. Aus den mitgeteilten Attributen filtert LOAD die Primärschlüssel heraus. Werden nur Teile oder nichts mitgeteilt, steigt der Result-Set entsprechend an. Letzteres wird z.B. für das initiale Laden von Stammdaten benötigt. Die tieferen Ebenen werden ebenfalls mit LOAD ergänzt, wobei auch zusätzliche Teile von deren Primärschlüsseln mitgeteilt werden können. SAVE : das Speichern in der DB. Es gibt nur SAVE. Anhand der mitgeteilten beliebigen Attribute und der Kenntnis der logischen Primärschlüssel aller Ebenen entscheidet das XML-API selbst ob und wo INSERT-, UPDATE- oder DELETEAnweisungen generiert, ausgeführt und committed werden! Zusätzlich zu den mitgeteilten Attributen der Ebenen können im Hintergrund Attribute ergänzt sowie Validierungen aller Art ausgeführt werden. SAVE speichert die komplette Hierarchie und liefert formidentisch zu LIST und LOAD im Feedback die jeweils komplett sichtbare Struktur aller Ebenen. Zur Auswahl gelangen jedoch nur die jeweils beim SAVE involvierten Entitäten. LOCK : das Sperren von Datensätzen. Ist noch in Vorbereitung. Bei der Beschreibung der einzelnen Tasks zeigte sich bereits, dass weitere Regeln die TaskDokumente verbinden und als Einheit erscheinen lassen. So gilt bei SAVE, LOAD und LIST, dass Request und Reply stets Baum-Strukturen beliebiger Tiefe und beliebigen Umfangs enthalten dürfen. Die einzelnen Ebenen verbinden stets nur semantische Bezüge, nie sind die Ebenen fest aneinander gebunden. Beim Request ist hier immer nur 1 Instanz der obersten Ebene („root“) zulässig, die jedoch beim Reply von LOAD und LIST dem Result-Set entsprechend aufgespalten wird. Bei QUERY, dessen fachlicher Reply ja eigentlich erst in LIST erscheint, ist nur eine Bedingung für eine „Query-Klasse“ ohne Sub-Ebenen zulässig. Jedoch kann diese so ausgelegt werden, dass sie Bedingungen für die später in LIST genannten Sub-Ebenen einbezieht. Eine Instanz des Reply-Baums von SAVE, LOAD und LIST läßt sich ohne weiteres als Request-Baum für SAVE verwenden. Falls keine Änderungen vorgenommen wurden, wird letzteres SAVE auch keine Änderung der Datenbank bewirken. Insbesondere werden auch keine DB-Tabellen-Trigger gestartet. Innerhalb eines Baums gelten immer die Prinzipien der Attribut-Vererbung sowie der Attribut-Überschreibung. Ein Attribut vererbt sich stets auch auf alle tieferen Ebenen, wenn es nicht dort explizit überschrieben wird. Dies hält die Bäume semantisch zusammen. Ein LOAD einer tieferen Ebene (bei LIST und LOAD) sucht automatisch Teile seines logischen Primärschlüssels unter den Attributen höherer Ebenen, wenn sie nicht lokal vorgegeben (überschrieben) sind. Generierte Attribute einer höheren Ebene vererben bei SAVE ihren Wert (!) automatisch an alle tieferen Ebenen, wo sie z.B. zum Primärschlüssel beitragen. Auch sonstige Attribute können von einer höheren Ebene z.B. als Defaults für tiefere Ebenen dienen, was wiederum auch den Umfang der Transfer-Dokumente verkleinert. Alle Namen, ob „Klassen“ (Ebenen) oder deren Attribute sind ausschließlich logische, frei zwischen DB und Anwendung für die XML-Kommunikation definierbare Namen. Sie stehen nicht in Bezug zu Tabellen-Namen oder Spalten-Namen, auch wenn das XML-API sie letztlich auf das physische relationale Schema abbildet. Diese Transformation leistet es transparent mit Hilfe eines Repository und einer (optionalen) View-Schicht, zu denen auch Fach-Module für die Generierung von Attributen oder die Validierungen treten können. Das XML-API selbst ist dagegen ein von fachlichen Aspekten absolut unabhängiges PLSQLPackage. Als reine Meta-Programmierung werden alle XML-Requests zur Laufzeit vom DOM-API geparst um daraus mit Hilfe des o.g. Repository SQL-Statements dynamisch zu generieren und auszuführen. Der beschriebene Feedback wird anschließend ebenfalls zur Laufzeit mit Hilfe des Repository im DOM wieder in XML zurückübersetzt. Da XML alle Aspekte sprachlich ausdrücken kann, genügt für das XML-API eine einzige Prozedur. Deren Spezifikation ist „XMLApi.XMLRequest(XMLClob in out nocopy clob)“. Container ist also z.Zt. nur Clob. Andere Container (z.B. „url“) sind denkbar. Anwendungsseitig wird natürlich empfohlen, die XML-Requests und Replys mit einem DOMParser zu bearbeiten, um z.B. Syntaxfehler zu vermeiden. Zudem kann dann die Übersetzung von und nach HTML oder WML leicht mit Hilfe von XSL geleistet werden. Aus alledem ergibt sich damit um das zentrale Transfer-XML-Dokument herum eine symmetrische, gleichgewichtige Aufgabenverteilung für Anwendung und DB, die die geforderte Entkopplung in Sprache und Modell vollständig umsetzt. Zudem ist sie für beide Seiten relativ einfach handhabbar. Glossary API Application Programmers Interface CLOB Character Large Object DB Database DOM Document Object Model HTML Hypertext Markup Language LAN Local Area Network OLTP Online Transaction Processing OO Object-Oriented SGML Standard Generalized Markup Language SQL Structured Query Language WAN Wide Area Network WML Wireless Markup Language XDK XML-Developpers Kit XML Extensible Markup Language XSL Extensible Styling Language Kontakt Anschrift : Peter Kleifges Im Winkel 8 54484 Maring-Noviand eMail : [email protected]