Spiracraft.data is a general mechanism for representing and manipulating data in the form of Tuples. Tuples are defined using Types which are composed of fields, methods, and relationships to other Types. Types can be defined in many different ways. A typical way of defining the Types in an application data model is by creating an XML Type definition. The XML definition of a Type is contained in a resource named TypeName.type.xml. The package location and name of the file (without ".type.xml") dictates the TypeURI of the Type.
The format of a Type declaration (file) is as follows :
<meta:Type
xmlns:meta="class:/spiralcraft/data/types/meta/"
xmlns:mynamespace="class:/optional/application/namespace"
>
<fields>...</fields>
<keys>...</keys>
</meta:Type>
Fields represent named data elements. Keys represent relationships between Types and also relational constraints.
A standard Field represents a persisted value, for example :
<meta:Field>
<name>foo
</name>
<type><String.type/>
</type>
</meta:Field>
In the typical case, Fields represent primitive types. Some possible values for the type attribute are String.type, Boolean.type, Integer.type, Long.type, Float.type, Double.type.
There are other kinds of Fields as well that are used to expose named data elements which are not persisted as primitive types but instead represent some sort of operation or computation, such as QueryField and CalculatedField.
A QueryField represents a Query operation that will be performed when the Field is accessed. For example, in a database containing musicians (Artist) and their work (Album), we might define a QueryField on Artist that contains the collection of Albums by that Artist.
<meta:QueryField>
<name>discography
</name>
<query>
<query:Selection>
<constraints>.artistId == artistId
</constraints>
<source>
<query:Scan>
<type>
<mynb:Album.type/>
</type>
</query:Scan>
</source>
</query:Selection>
</query>
</meta:QueryField>
In addition to a name and type, QueryFields have a <query> field. Inside of the query property of the QueryField, one of many different kinds of Spiralcraft.data.query.Query subtypes can be referenced.
Evaluating expressions inside of queries. There is a mechanism inside of Spiralcraft.data which is called a Telefocus. Telefocus permits the comparison of 2 objects without having to use an FRO. There is a context object and a subject object. The subject object is referred to using a dot-prefix (".foo"). The context object is referred to using a non-dot-prefix name ("bar").
For example : .foo == bar
This construct is used to effectively parameterize a query by making comparisons between subject (the object being queried) and the context which represents a set of parameters available for comparison, which can be an enclosing Type of a QueryField, or a parent query.
A CalculatedField contains an Expression which is evaluated when the Field is accessed. For example, a User object which has a firstName and lastName field might have a CalculatedField of fullName.
<meta:CalculatedField>
<name>fullName
</name>
<expression>firstName + lastName</expression>
<type><String.type/>
</type>
</meta:CalculatedField>
Keys come in 3 flavors : primary key, unique key, and relational key. For any Type there can be only 1 primary key, denoted by setting the property primary to true. Primary keys are used to create unique identifiers for an object of a given Type. Any key can be set to unique by setting the unique property to true. Relational keys are used to define relationships between Types by mapping individual fields. When a relational key is defined and given a name, a Field is automatically generated with that name that retrieves the related object(s) when accessed.