Contacts - Key/values, Meta-data, and Datatypes

The CloudBackend database design pattern of having data objects in a searchable, hierarchical containers, which then contain objects that can have zero to many streams attached like an XML document, JSON, text, or binary, allows for a flexible data model.

Examples of what containers can represent could be; invoices, calendar, contacts, time reporting, conference room booking, recipe database, truck journal, and so on. Each stored object would then have an XML document and an XML schema that represent its structure.

To enable rapid searches, datatypes can be defined that automatically extract information using XPath expressions from XML documents as soon as they are stored in the meta-data of the object, which is stored as key/value pairs in the data model. This allows both searching and the listing of a container to result in an ATOM feed that contains all data needed to present the list using XIOS/3 built-in UI components or XSLT.

The ATOM feed structure can be bound directly to the UI components or to a component that applies an XSL transformation to present the content as HTML. Any changes to the data model of the ATOM feed will then automatically update the user interface, meaning that if a new XML document is added, deleted, or updated in the container, it will immediately be reflected in the user interface.

As an example, the contact manager application uses an XML version of the vCard format to store contacts in individual XML documents. The datatype declaration for these vCard files has the following meta-data exctraction (indexing) instructions.

<index>
    <dc:firstname xpath="/vcard/n/given"/>
    <dc:lastname xpath="/vcard/n/family"/>
    <dc:nickname xpath="/vcard/nickname"/>
    <dc:homephone xpath="/vcard/tel/home"/>
    <dc:mobilephone xpath="/vcard/tel/cell"/>
    <dc:homecountry xpath="/vcard/adr/home/ctry"/>
    <dc:homemail xpath="/vcard/email/home"/>
    <dc:homestreetaddress xpath="/vcard/adr/home/street"/>
    <dc:homezipcode xpath="/vcard/adr/home/pcode"/>
    <dc:homecity xpath="/vcard/adr/home/city"/>
    <dc:businesscompanyname xpath="/vcard/org/orgname"/>
    <dc:businessdepartment xpath="/vcard/org/orgunit"/>
    <dc:businessphone xpath="/vcard/tel/work"/>
    <dc:businessfax xpath="/vcard/tel/fax/work"/>
    <dc:businessjobtitle xpath="/vcard/title"/>
    <dc:businessmail xpath="/vcard/email/work"/>
    <dc:linkedin xpath="/vcard/linkedIn"/>
    <dc:facebook xpath="/vcard/facebook"/>
    <dc:twitter xpath="/vcard/twitter"/>
    <dc:card xpath="/vcard/@card"/>
    <dc:workmobile xpath="/vcard/tel/cellwork"/>
    <dc:businessindustry xpath="/vcard/org/orgindustry"/>
    <ni:photo xpath="/vcard/photo"/>
  </index>

Whenever a document is updated or uploaded these XPath expressions are applied to the data model in CloudBackend and the extracted properties are stored in the search index as key/value pairs. Just the ATOM feed itself is then enough to present a usable overview of the objects in the container collection.

<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:dc="http://xcerion.com/directory.xsd" xmlns:ni="http://xcerion.com/noindex.xsd" dc:folder="562958574623716" xmlns:fs="http://xcerion.com/folders.xsd">
  <os:totalResults>1</os:totalResults>
  <os:startIndex>0</os:startIndex>
  <os:itemsPerPage>100</os:itemsPerPage>
  <atom:entry>
    <atom:title>Karl Hyltberg.xml</atom:title>
    <atom:published>2021-03-31T09:10:45Z</atom:published>
    <atom:updated>2023-05-29T11:06:39Z</atom:updated>
    <atom:link rel="alternate" type="text/xml" href="https://api.cloudbackend.com/v1/documents/562958574623716/4536952228/1" length="1522" stream_1_length="1522"/>
    <atom:id>mid:10e6c65a4@xios.xcerion.com</atom:id>
    <dc:folder>562958574623716</dc:folder>
    <dc:document>4536952228</dc:document>
    <dc:root xmlns:dc="http://xcerion.com/directory.xsd">vcard</dc:root>
    <dc:firstname xmlns:dc="http://xcerion.com/directory.xsd">Karl</dc:firstname>
    <dc:lastname xmlns:dc="http://xcerion.com/directory.xsd">Hyltberg</dc:lastname>
    <dc:businessmail xmlns:dc="http://xcerion.com/directory.xsd">karl.hyltberg@xios3.com</dc:businessmail>
  </atom:entry>
</atom:feed>

Besides searching and filtering in data sets another common pattern is merging data sets for presentation. Multiple atom feeds can be combined and presented as a single view, which is extra useful when the different data sets are owned by different identities. Think of this as doing a join operation in a traditional relational database.

One example where this is very useful is in the Calendar application where not only different personal schedules can be combined into a single view, but schedules shared by other people can be integrated as well. This is done by allowing calendar layers represented as one container for each calendar layer, through the security and sharing capabilities of the data model (using Access Control Lists, identities, and sharing) to be shared across identities.

This means that the developer of a calendar application only have to design the data model with layers as containers, the XML application for a calendar event and then start storing XML documents in containers. If a layer is to be shared, the container for that layer is then simply shared with the identities or groups that should have access.