About
Side Projects
Blog
2024-02-04

Generating an ERD for Haiku Depot Server using Graphor

HaikuDepotServer is a Java web application for managing packages for the Haiku operating system. The application uses a Postgres database to store it’s data and uses the Apache Cayenne as an Object-relational mapping (ORM) mapping system to model the database in the Java application logic.

Cayenne ORM

At both design and runtime, Cayenne is centric around a model which abstractly describes the database structure and how the database structure maps to the object-oriented model classes in the Java application. The model file is typically edited using a desktop GUI application called Cayenne Modeller and is saved in an XML format.

Previously the ERD for this model was drawn using a commercial programme, but it needed a refresh and I thought that I would try to use the Graphor UML modelling tool to do this. Being expressed in XML, the Cayenne model file is easy to parse. The Graphor storage format is also expressed in XML and so it was possible to also understand this format too. A transcoder was needed to express the data in the XML Cayenne model as an XML Graphor document.

Cayenne Model

The Cayenne model format is stored in a file HaikuDepot.map.xml. The file contains many elements <db-entity>. These represent the tables in the database and each has a list of <db-attribute> elements; one for each of the columns of the table. Another element <db-relationship> describes the relationship between tables including the columns involved in the join. There are many other elements in the file such as <query>, <obj-relationship> and <obj-entity> which are not required to get an ERD of the database structure.

Graphor

The Graphor file format is more nuanced and required some experimentation to understand. There may be mistakes in the understanding owing to the methodology used.

The Graphor file format contains elements in the following XML structure;

<graphor>
<Package>...</Package>
<Diagram>...</Diagram>
<Class>...</Class>
<ClassItem>...</ClassItem>
<Property>...</Property>
<Association>...</Association>
<AssociationItem>...</AssociationItem>
</graphor>

Each of the tables can be represented as a <Class> plus a <ClassItem>. Each table column can be represented by a <Property>. The relationships between tables can be represented by an <Association> plus an <AssociationItem>. Each of these XML elements has an id and relationships are made between the elements using id-s. An example is shown below;

<Class id="4d8edbebf0e74f57b3f0869f27d458da">
    <name>
        <val>architecture</val>
    </name>
    <ownedAttribute>
        <reflist>
            <ref refid="3550ac66c20d4f06b2cac2358df2a9ab"/>
            <ref refid="5cefcf5423624ead8b3fe23372f6dc93"/>
        </reflist>
    </ownedAttribute>
    <package>
        <ref refid="f37f04d670a34678ace701feb7f5a175"/>
    </package>
    <presentation>
        <reflist>
            <ref refid="c05ec17b21584cf2a0d54daa72272b57"/>
        </reflist>
    </presentation>
</Class>

Transcoding

To transcode the data model into Graphor XML, a Python script was written that uses a simple templating library from the ustache project. This script produces the Graphor UML classes together with their associations but does not concern itself with the layout; this can either be done by hand or can be achieved using Graphor’s auto-layout system.

A cropped image of the resultant model at the time of writing is shown below;

Data Model

The model will be able to be seen in the HDS documentation after the next deployment. Although there could be improvement made, the general process has worked quite well.