Dataquay 0.8
|
ObjectStorer is a storage handler capable of turning objects derived from QObject into RDF triples in a Store, such that under the right conditions the original objects can be recreated from the store by ObjectLoader. More...
#include <dataquay/objectmapper/ObjectStorer.h>
Classes | |
struct | StoreCallback |
Public Types | |
enum | PropertyStorePolicy { StoreIfChanged , StoreAlways } |
enum | FollowOption { FollowNone = 0 , FollowObjectProperties = 1 , FollowParent = 2 , FollowSiblings = 4 , FollowChildren = 8 } |
typedef QHash< QObject *, Node > | ObjectNodeMap |
ObjectNodeMap contains a record of the RDF node used for each object. | |
typedef int | FollowPolicy |
Public Member Functions | |
ObjectStorer (Store *s) | |
Create an ObjectStorer ready to store objects to the given datastore. | |
~ObjectStorer () | |
Store * | getStore () |
Retrieve the store object that was passed to the constructor. | |
void | setTypeMapping (const TypeMapping &) |
Provide a TypeMapping object, which controls the URIs chosen by ObjectStorer to represent object types and properties. | |
const TypeMapping & | getTypeMapping () const |
Retrieve the current TypeMapping object. | |
void | setPropertyStorePolicy (PropertyStorePolicy policy) |
Set the policy used to determine whether to store a property. | |
PropertyStorePolicy | getPropertyStorePolicy () const |
Retrieve the current policy used to determine whether to store a property. | |
void | setBlankNodePolicy (BlankNodePolicy policy) |
Set the policy used to determine whether to give an object a URI or use a blank node for it. | |
BlankNodePolicy | getBlankNodePolicy () const |
Retrieve the current policy used to determine whether to give an object a URI or use a blank node for it. | |
void | setFollowPolicy (FollowPolicy policy) |
Set the policy used to determine which objects to store, based on their relationship to an object whose storage is being explicitly requested. | |
FollowPolicy | getFollowPolicy () const |
Uri | store (QObject *o) |
Store the given object and return its URI in the datastore. | |
Uri | store (QObject *o, ObjectNodeMap &map) |
Store the given object; add the object and its node to the ObjectNodeMap, and return its URI in the datastore. | |
void | store (QObjectList o) |
Store the given objects. | |
void | store (QObjectList o, ObjectNodeMap &map) |
Store the given objects, and add them and their nodes to the ObjectNodeMap. | |
void | removeObject (Node node) |
Remove an object from the store, given its node. | |
void | addStoreCallback (StoreCallback *callback) |
Register the given callback (a subclass of the abstract StoreCallback class) as providing a "stored" callback method which will be called after each object is stored. | |
ObjectStorer is a storage handler capable of turning objects derived from QObject into RDF triples in a Store, such that under the right conditions the original objects can be recreated from the store by ObjectLoader.
See also ObjectMapper, for a class which manages a set of objects and uses ObjectStorer and ObjectLoader to map changes bidirectionally between object hierarchy and datastore.
ObjectStorer typically creates a new URI for each object it stores, based on the object's class name with a unique suffix. (In some cases – where an object only exists as the value of a property of another object and is not referred to elsewhere in the hierarchy – it will by default be given a blank node instead of a URI.) The URI created for an object will be stored in that object as a user property named "uri" of type Dataquay::Uri. If that property already exists, ObjectStorer will use its value instead of creating a new URI; you can exploit this if you wish to override the generated URI. Note that ObjectStorer cannot handle objects having a uri property of any type other than Dataquay::Uri.
For each object, ObjectStorer will write an rdf:type; an RDF property for each of the QObject properties of the object that have STORED set to true; and RDF properties identifying the parent and sibling objects if the object is part of a QObject hierarchy. The URIs used for the type and these properties can be controlled using a TypeMapping object.
ObjectStorer uses Node::fromVariant to convert QObject property values to RDF literals: see Node::registerDatatype for the means to add new datatypes. Properties with subclass-of-QObject-pointer values can be written recursively (see setFollowPolicy); the default is to write them only if the "value" QObject already has a URI. ObjectStorer can write properties which have set and sequence container types (converting sets to multiple RDF properties with the same subject URI, and sequences to RDF lists) if those types have been registered with ContainerBuilder.
Finally, you can register callbacks (using addStoreCallback) to be called after each object is stored, in case you wish to associate more information with an object.
ObjectStorer is primarily intended to provide a simple, open and extensible storage format for small networks of application-specific objects. With TypeMapping there is some flexibility to assist with creating object structures from arbitrary RDF graphs, and the mechanism has been tested and optimised to some degree for some millions of triples, but that way could lie madness.
ObjectStorer is re-entrant, but not thread-safe.
Definition at line 107 of file ObjectStorer.h.
QHash<QObject *, Node> Dataquay::ObjectStorer::ObjectNodeMap |
ObjectNodeMap contains a record of the RDF node used for each object.
This can be filled in a call to store() and passed to subsequent calls in order to hasten lookup, avoid unnecessary repeated stores, and ensure consistency for generated URIs.
Note that, although ObjectStorer places the URI of each object in its uri property, certain objects may be written using blank nodes – those nodes can only be retrieved through this map.
The caller is responsible for ensuring that any objects subsequently deleted are also removed from this map.
Definition at line 123 of file ObjectStorer.h.
Definition at line 243 of file ObjectStorer.h.
Enumerator | |
---|---|
StoreIfChanged | Store only properties that differ from default object. |
StoreAlways | Store all properties (if storable, readable & writable) (default) |
Definition at line 151 of file ObjectStorer.h.
Enumerator | |
---|---|
FollowNone | |
FollowObjectProperties | |
FollowParent | |
FollowSiblings | |
FollowChildren |
Definition at line 234 of file ObjectStorer.h.
Dataquay::ObjectStorer::ObjectStorer | ( | Store * | s | ) |
Create an ObjectStorer ready to store objects to the given datastore.
Dataquay::ObjectStorer::~ObjectStorer | ( | ) |
Store * Dataquay::ObjectStorer::getStore | ( | ) |
Retrieve the store object that was passed to the constructor.
void Dataquay::ObjectStorer::setTypeMapping | ( | const TypeMapping & | ) |
Provide a TypeMapping object, which controls the URIs chosen by ObjectStorer to represent object types and properties.
Generally if you are using ObjectStorer and ObjectLoader together, you will want to use the same TypeMapping object with both.
const TypeMapping & Dataquay::ObjectStorer::getTypeMapping | ( | ) | const |
Retrieve the current TypeMapping object.
void Dataquay::ObjectStorer::setPropertyStorePolicy | ( | PropertyStorePolicy | policy | ) |
Set the policy used to determine whether to store a property.
If StoreIfChanged, properties will only be written if they differ in value from those retrieved from a newly-constructed instance of the object. If StoreAlways, all suitable properties will be written. The default is StoreAlways.
StoreIfChanged only works for objects that have been registered with ObjectBuilder so that a default object can be constructed. Any other objects will have all suitable properties written.
In either case, only properties whose QObject property definitions have all of READ, WRITE, and STORED set to true will be considered suitable and stored.
PropertyStorePolicy Dataquay::ObjectStorer::getPropertyStorePolicy | ( | ) | const |
Retrieve the current policy used to determine whether to store a property.
void Dataquay::ObjectStorer::setBlankNodePolicy | ( | BlankNodePolicy | policy | ) |
Set the policy used to determine whether to give an object a URI or use a blank node for it.
If BlankNodesAsNeeded (the default), objects will be given blank nodes if it appears to ObjectStorer that they do not need URIs. In practice this means that objects which are referred to because they are properties of other objects and which do not appear elsewhere in the list of objects being stored, do not have an existing uri property, and do not have a URI node allocated in an ObjectNodeMap passed to the store method, will be assigned blank nodes.
If NoBlankObjectNodes, all objects written will be given URIs. These will be drawn from the object's uri property if it exists and is of Dataquay::Uri type, or else invented uniquely based on the object's class name.
If NeverUseBlankNodes, the ObjectStorer will never generate a blank node – all objects written will be given URIs, and list nodes will be given URIs generated from those of their contents. With this setting, an object graph written twice using the same object-node map will produce identical RDF graphs. !!! ^^^ write a unit test for this, and ensure that it is true
If you are using BlankNodesAsNeeded but would prefer ObjectStorer not to use a blank node for a specific object, you can assign a URI in advance by setting a Dataquay::Uri to its "uri" property (either a declared property or a user property).
Note that if a blank node is used for an object, there will be no way to retrieve that node through the object (no equivalent of the "uri" property). If you want to refer to the node subsequently you will need to ensure you provide an ObjectNodeMap to the store method to retrieve the node that was generated.
BlankNodePolicy Dataquay::ObjectStorer::getBlankNodePolicy | ( | ) | const |
Retrieve the current policy used to determine whether to give an object a URI or use a blank node for it.
void Dataquay::ObjectStorer::setFollowPolicy | ( | FollowPolicy | policy | ) |
Set the policy used to determine which objects to store, based on their relationship to an object whose storage is being explicitly requested.
If the policy is FollowNone, only the objects explicitly requested for storage by being passed as arguments to a store() method call will be stored.
If the policy has FollowObjectProperties set, then where an object has a property that is suitable for storing (see setPropertyStorePolicy) and whose type is a pointer-to-object class for some subclass of QObject, the object referred to by that property will be stored. Otherwise, such properties will only be written where their objects have URIs available already (either because they exist in the object-node map or because they have a QObject property of name uri and Dataquay::Uri type).
If the policy has FollowParent set, then where an object has a QObject parent, that parent will also be written.
If the policy has FollowSiblings set, then where an object has QObject siblings (i.e. the object and those other objects share a parent), those siblings will also be written.
If the policy has FollowChildren set, then where an object has QObject children, those children will also be written.
FollowPolicy Dataquay::ObjectStorer::getFollowPolicy | ( | ) | const |
Uri Dataquay::ObjectStorer::store | ( | QObject * | o | ) |
Store the given object and return its URI in the datastore.
Other objects may also be stored, depending on the FollowPolicy setting.
The object will be stored even if it already exists in the store. No other data will be changed; for example, if other triples already exist with this object's URI as subject, they will be left alone. See setBlankNodePolicy for details of the assignment of nodes to objects.
Uri Dataquay::ObjectStorer::store | ( | QObject * | o, |
ObjectNodeMap & | map ) |
Store the given object; add the object and its node to the ObjectNodeMap, and return its URI in the datastore.
Other objects may also be stored, depending on the FollowPolicy setting, and will be recorded in the ObjectNodeMap as well.
The object will be stored even if it already exists in the store. No other data will be changed; for example, if other triples already exist with this object's URI as subject, they will be left alone. See setBlankNodePolicy for details of the assignment of nodes to objects.
void Dataquay::ObjectStorer::store | ( | QObjectList | o | ) |
Store the given objects.
Other objects may also be stored, depending on the FollowPolicy setting.
void Dataquay::ObjectStorer::store | ( | QObjectList | o, |
ObjectNodeMap & | map ) |
Store the given objects, and add them and their nodes to the ObjectNodeMap.
Other objects may also be stored, depending on the FollowPolicy setting.
void Dataquay::ObjectStorer::removeObject | ( | Node | node | ) |
Remove an object from the store, given its node.
This removes all triples with the node as subject. If any such triple references a blank node that is not referred to elsewhere in the store, all triples with that node as subject will be removed as well. If such a blank node is also the head of an RDF list, the rest of the RDF list will also be removed provided it fulfils the same criteria.
void Dataquay::ObjectStorer::addStoreCallback | ( | StoreCallback * | callback | ) |
Register the given callback (a subclass of the abstract StoreCallback class) as providing a "stored" callback method which will be called after each object is stored.