The SQL repository supports a simplified form of inheritance that uses an optional one-to-one relationship between the primary table and an auxiliary table. You can define an item descriptor that inherits properties from another item descriptor in the same repository.
This is best explained by example. Let’s look at a simple clothing store catalog that offers coats and shorts. One could model this by creating independent item descriptors to represent coats and shorts and putting each in its own database table. The XML repository definition for this model would look something like:
<!-- The "coat" item type --> <item-descriptor name="coat"> <table name="coat" id-column-names="id" type="primary"> <property name="name"/> <property name="description"/> <property name="color"/> <property name="shippingWeight"/> <property name="size"/> <property name="season"/> </table> </item-descriptor> <!-- The "shorts" item type --> <item-descriptor name="shorts"> <table name="shorts" id-column-names="id" type="primary"> <property name="name"/> <property name="description"/> <property name="color"/> <property name="shippingWeight"/> <property name="size"/> <property name="pleated" data-type="boolean"/> </table> </item-descriptor>
And the database data model would have two unrelated tables:
This would work, but has a few drawbacks:
Coats and shorts have a lot of properties in common, which in the above model means duplicated database columns and probably duplicated code.
This model does not allow you to easily perform a query like: find all the items of clothing (shorts and coats) that have “Star Wars” in their description
An object-oriented approach like that used by the SQL repository allows you to define a base item descriptor class called clothing
to hold the attributes common to coats and shorts. You can use simple inheritance to make coats
and shorts
subclasses of clothing
. You can then model the data in your clothing catalog like this:
and the corresponding XML repository definition (with changes in bold type) becomes:
<!-- The "clothing" item type, a base type --> <item-descriptor name="clothing" sub-type-property="type"> <!-- This is the primary table that holds clothing data --> <table name="clothing" type="primary" id-column-names="id"> <property name="type" data-type="enumerated"> <option value="coat"/> <option value="shorts"/> </property> <property name="name"/> <property name="description"/> <property name="color"/> <property name="size"/> <property name="shippingWeight"/> </table> </item-descriptor> <!-- The "coat" item type, now a subclass of "clothing" --> <item-descriptor name="coat" super-type="clothing" sub-type-value="coat"> <table name="coat" type="auxiliary" id-column-names="id"> <property name="season"/> </table> </item-descriptor> <!-- The "shorts" item type, now a subclass of "clothing" --> <item-descriptor name="shorts" super-type="clothing" sub-type-value="shorts"> <table name="shorts" type="auxiliary" id-column-names="id"> <property name="pleated" data-type="boolean"/> </table> </item-descriptor>
We’ve done two things here:
Created the parent item descriptor,
clothing
, that holds attributes common to thecoat
andshorts
types.Made the
coat
andshorts
types into direct subclasses of theclothing
type.
The clothing
parent item descriptor has a sub-type-property
attribute. This attribute defines the property of the clothing
type that specifies which sub-types can be instantiated. Each item descriptor that extends the clothing
item descriptor must specify a sub-type-value
attribute, which is the value for this property that triggers use of this particular type. The sub-type-value
must not be null. This is the value of the sub-type-property
, which automatically implies this item type. If there is no sub-type-value
, this item-descriptor itself will never be returned from a getItem
or query on one of its super-type
item descriptors. Such an item descriptor may have one or more item descriptors that have it as its super-type and thus can serve as kind of an abstract item-descriptor.
It should be noted that instances of objects are associated with their superclasses by ID. So, in this example, the ID of a coat always has a matching clothing ID.
As noted above, the sub-type-value
of a sub-type item should never be null. If you have clothing items that are neither coats nor shorts, you should create a sub-type-value
in the clothing
item descriptor with a value of clothing
and add a clothing
option to the sub-type-property definition. For example:
<!-- The "clothing" item type, a base type --> <item-descriptor name="clothing" sub-type-property="type" sub-type-value="clothing"> <!-- This is the primary table that holds clothing data --> <table name="clothing" type="primary" id-column-names="id"> <property name="type" data-type="enumerated"> <option value="clothing"/> <option value="coat"/> <option value="shorts"/> <property/> ...
From the Repository API point of view, each ItemDescriptor
maps to a single RepositoryView
. When a SQL repository uses item type inheritance, each parent item type results in a RepositoryViewContainer
that contains its subtype views as children.