Yes, dear reader, you read it well: Hormiga now handles collections too! That means you can now manipulate SPARQL collections (multi valued predicates) as you’d manipulate a normal Gee collection.
A simple example
Say you have loaded a list of resources, as we did in my last post. So you have a list of Photo objects, which are mapping nmm:Photo resources. Now you want to create a tag and assign it to the photo. This is as simple as:
var my_tag = Tag.create (); my_tag.label = "My first tag"; my_tag.save (); photo.tags.add (my_tag); photo.save ();
Now there are a couple of new functions used here:
- create () is used to create a new resource, and assign it a random urn. The resource is saved into the database immediately. It is different from load (), which takes an urn, and can return you a proxy to a resource that does not exist in the database.
- save () does save the modifications made on a proxy in the database. You can also use rollback () if you decide you want to revert the proxy to its original state.
If you look at the generated Vala code, you’ll note that GObject properties mapping multi valued predicates are read only. This is because you have to work with the collection directly, you cannot do this:
photo.tags = new HashSet<Tag> ();
This is because under the hood custom classes are used, and you cannot replace them with a “simple” HashSet.
The complete example is available as usual on my git forge.
OMGWTFBBQ, but how does it works ?
There are two key classes in the way I handle collections, those are PersistentSet and ValueSet.
PersistentSet is a sort of versionned set: it is initialized with the values loaded from database, and can then be modified by the user. When saving, it allows you to get a diff with the original values, and therefore do the saving in a smarter way than erase-all-then-save-all.
ValueSet is an abstract class, and has a subclass for every handled data type (ValueSetInt, ValueSetString etc.). It is a thin layer above a PersistentSet of GValues that allows you to manipulate the values held inside each GValue directly. For example, ValueSetInt sits above a PersistentSet of GValues of type int64, and behaves as a Gee collection of int64. The modification to the ValueSet are replicated in the underlying PersistentSet (which will be used when saving).
Test it! Crash it!
As always, I’m interested in your feedback, be it a remark on the API, the design, or a crash report. You check out the source at git://git.mymadcat.com/hormiga.git , or browse it online. A short reference for mapping files and various examples are available.