The majority of the work here is already described in the previous example where we talk about how to write the store.
The difference with this example is that sometimes you want to
insert data and have the URNs returned which were created to
avoid re-querying for them. This is done using
the tracker_sparql_connection_update_blank
function (or asynchronously tracker_sparql_connection_update_blank_async
).
If launched asynchronously, the result of the operation can be obtained with
tracker_sparql_connection_update_blank_finish
.
The _:foo in the example is how a blank node is
represented in SPARQL. The foo part is used to generate the
unique ID that is used for the new URN. It is also used in the
GVariant
that is returned. In the example below, we are creating a new
blank node called foo for every class that
exists.
The format of the GVariant (in D-Bus terms) is an aaa{ss} (an array of an array of dictionaries). This is rather complex but for a good reason. The first array represents each INSERT that may exist in the SPARQL. The second array represents each new node for a given WHERE clause (the example below illustrates this), you need this to differentiate between two INSERT statments like the one below in the same SPARQL sent to the store. Last, we have a final array to represent each new node's name (in this case foo) and the actual URN which was created. For most updates the first two outer arrays will only have one item in them.
The following program shows how a synchronous blank node update can be done to the store:
#include <tracker-sparql.h> int main (int argc, const char **argv) { GError *error = NULL; GVariant *v; TrackerSparqlConnection *connection; const gchar *query = "INSERT { _:foo a nie:InformationElement } WHERE { ?x a rdfs:Class }"; /* Do NOT get a direct connection if you're going to do some write * operation in the Store. The NULL represents a possible * GCancellable. */ connection =tracker_sparql_connection_get
(NULL, &error); if (!connection) { g_printerr ("Couldn't obtain a connection to the Tracker store: %s", error ? error->message : "unknown error"); g_clear_error (&error); return 1; } /* Run a synchronous blank node update query */ v =tracker_sparql_connection_update_blank
(connection, query, G_PRIORITY_DEFAULT, NULL, &error); if (error) { /* Some error happened performing the query, not good */ g_printerr ("Couldn't update the Tracker store: %s", error ? error->message : "unknown error"); g_clear_error (&error); g_object_unref (connection); return 1; } if (!v) { g_print ("No results were returned\n"); } else { GVariantIter iter1, *iter2, *iter3; const gchar *node; const gchar *urn; g_print ("Results:\n"); g_variant_iter_init (&iter1, v); while (g_variant_iter_loop (&iter1, "aa{ss}", &iter2)) { /* aa{ss} */ while (g_variant_iter_loop (iter2, "a{ss}", &iter3)) { /* a{ss} */ while (g_variant_iter_loop (iter3, "{ss}", &node, &urn)) { /* {ss} */ g_print (" Node:'%s', URN:'%s'\n", node, urn); } } } g_variant_unref (v); } g_object_unref (connection); return 0; }