This post continues the elaboration of D6 platform topics, which was started with the post on aspects. Property bag was barely mentioned in that post but is explored in detail here.
Before we try to put our arms around the property bag or try to get inside it, we may want to look at a few other concepts. These will help us understand the why as well as how of this new feature.
What’s in a bag, anyway? Readers with exposure to computer science theory and data structures would recognize the bag as a standard data structure. Those who know what a set is can understand that a bag is similar to a set except for the fact that a bag can contain duplicate values while a set cannot. Does property bag have anything to do with the bag data structure? The reference documentation doesn’t make any comment in this regard – the clients of Content Server will not need to worry about it since the Content Server will take care of encoding and decoding information as it gets into or out of the property bag, respectively.
As we will see shortly, a property bag holds values for certain properties that don’t have columns of their own in the underlying tables. So it may be best to think of the property bag as just a place to hold values for multiple properties.
D6 introduces the concept of non-qualifiable properties. So the properties as present in prior versions should be seen as qualifiable. In an object type definition, a property is qualifiable by default (if you don’t specify it to be qualifiable or otherwise). A non-qualifiable property cannot be referenced in an expression or in a qualification (WHERE clause) in a query unless the query is an FTDQL query. Thus, making a property non-qualifiable limits what you can do with it later. You can store and retrieve values for this property but cannot search on it unless it is full-text indexed. Why would you want to put such a limitation on the metadata? The only explanation appears to be related to performance optimization.
How does Content Server distinguish between qualifiable and non-qualifiable properties? It does so in two ways:
attr_restrictionproperty in the
dm_typeobject identifies each property as either qualifiable or non-qualifiable.
- A qualifiable property is represented by a column in the appropriate underlying database table for the type that contains the property. A non-qualifiable property is stored in the
i_property_bagproperty of the object.
Thus, non-qualifiable properties live in the property bag. The property bag stores the names and values of several properties in a serialized format. Since non-qualifiable properties don’t have their own columns they can’t participate in constraint checking such as primary key or foreign key.
Despite the above-mentioned differences the non-qualifiable properties have many similarities to the qualifiable properties:
- They can be full-text indexed
- They can be referenced in the selected values list of a query statement
- Selected non-qualifiable properties are returned by a query as a column in a query result object
- They can be repeating or single-valued
The Property Bag
We now have an idea about the property bag – it is a place for holding non-qualifiable properties in an object. Let’s dive deeper to see how it is implemented.
The property bag is a special property used to store:
- Non-qualifiable properties and their values
- Aspect properties and their values if the properties are defined with fetch optimization
Under the Hood
The property bag is implemented as a pair of properties:
i_property_bag, which is a single-valued string property of 2000 characters
r_property_bag, which is a repeating string property of 2000 characters
i_property_bag stores the names and values of non-qualifiable properties. It is also used to store the names and values of aspect properties if the properties are added to the aspect with the
r_property_bag stores overflow from the
i_property_bag property – that is if
i_property_bag doesn’t have enough space to hold all the property name-values that it needs to hold then
r_property provides the additional space. This property is automatically added to an object type definition if the definition includes the
i_property_bag property. Thus, this property makes the property bag expandable.
Enabling Property Bag
dm_sysobject and its subtypes automatically have a property bag. Other custom types can be altered to contain a property bag using the
ALTER TYPE statement. This adds the above-mentioned properties to the type.
If you include a non-qualifiable property in the definition of a NULL type (has no supertype) or whose supertype is not in the dm_sysobject hierarchy, then the
i_property_bag property is added automatically to the type.
The property bag cannot be removed once it has been added to an object type.
Internally, every property has an identifier, which is unique within its type hierarchy. This identifier is used to identify the property when it is stored in the property bag. The identifier is an integer value stored in the
attr_identifier property of each type’s
dm_type object. A property’s identifier cannot be changed.
If a non-qualifiable property is of string datatype, its length must be less than the value in the
max_nqa_string key in the
server.ini file if that key is set. If this key is not set, it defaults to 2000.