From d6f3eb9a3e0d1bee6b2b20fcd8fde56a6065051a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 11 Jan 2023 13:25:45 +0100 Subject: libtracker-sparql: Handle uint GValues deserializing TrackerResources We may possibly feed those to TrackerResources, but could fail handling them here. --- src/libtracker-sparql/tracker-deserializer-resource.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libtracker-sparql/tracker-deserializer-resource.c b/src/libtracker-sparql/tracker-deserializer-resource.c index 4c3e09fab..b726734cf 100644 --- a/src/libtracker-sparql/tracker-deserializer-resource.c +++ b/src/libtracker-sparql/tracker-deserializer-resource.c @@ -314,6 +314,11 @@ convert_gvalue_to_string (TrackerDeserializerResource *deserializer, val = g_value_get_int (value); return g_strdup_printf ("%d", val); + } else if (G_VALUE_HOLDS (value, G_TYPE_UINT)) { + guint val; + + val = g_value_get_uint (value); + return g_strdup_printf ("%u", val); } else if (G_VALUE_HOLDS (value, G_TYPE_INT64)) { gint64 val; -- cgit v1.2.1 From 3ed049c4937eb8ed8a0ddb3917157916834b165a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 11 Jan 2023 13:27:03 +0100 Subject: libtracker-sparql: Handle blank nodes and compressed IRIs serializing JSON-LD The former need appening the _: prefix in place, and the latter were just propagated as expanded IRIs, but it is nicer that we compress them here. --- src/libtracker-sparql/tracker-serializer-json-ld.c | 58 ++++++++++++++++------ 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/libtracker-sparql/tracker-serializer-json-ld.c b/src/libtracker-sparql/tracker-serializer-json-ld.c index cb7162831..52949f549 100644 --- a/src/libtracker-sparql/tracker-serializer-json-ld.c +++ b/src/libtracker-sparql/tracker-serializer-json-ld.c @@ -102,6 +102,43 @@ finish_objects (TrackerSerializerJsonLD *serializer_json_ld) g_clear_list (&serializer_json_ld->recent_resources, NULL); } +static JsonNode * +create_node (const gchar *id, + TrackerSparqlValueType type, + TrackerNamespaceManager *namespaces) +{ + JsonNode *node; + JsonObject *object; + + node = json_node_new (JSON_NODE_OBJECT); + object = json_object_new (); + + if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE) { + gchar *bnode_label; + + bnode_label = g_strconcat ("_:", id, NULL); + g_strdelimit (&bnode_label[2], ":", '_'); + json_object_set_string_member (object, "@id", bnode_label); + g_free (bnode_label); + } else { + gchar *compressed; + + compressed = tracker_namespace_manager_compress_uri (namespaces, id); + + if (compressed) { + json_object_set_string_member (object, "@id", compressed); + g_free (compressed); + } else { + json_object_set_string_member (object, "@id", id); + } + } + + json_node_set_object (node, object); + json_object_unref (object); + + return node; +} + static gboolean serialize_up_to_position (TrackerSerializerJsonLD *serializer_json_ld, gsize pos, @@ -140,7 +177,7 @@ serialize_up_to_position (TrackerSerializerJsonLD *serializer_json_ld, while (!serializer_json_ld->cursor_finished) { const gchar *graph, *subject, *predicate; gboolean graph_changed, subject_changed; - TrackerSparqlValueType object_type; + TrackerSparqlValueType subject_type, object_type; JsonNode *value = NULL; gchar *prop = NULL; @@ -161,6 +198,7 @@ serialize_up_to_position (TrackerSerializerJsonLD *serializer_json_ld, } subject = tracker_sparql_cursor_get_string (cursor, 0, NULL); + subject_type = tracker_sparql_cursor_get_value_type (cursor, 0); predicate = tracker_sparql_cursor_get_string (cursor, 1, NULL); object_type = tracker_sparql_cursor_get_value_type (cursor, 2); graph = tracker_sparql_cursor_get_string (cursor, 3, NULL); @@ -215,7 +253,6 @@ serialize_up_to_position (TrackerSerializerJsonLD *serializer_json_ld, } if (subject_changed || graph_changed) { - JsonNode *node; JsonObject *object; /* New/different subject */ @@ -228,19 +265,14 @@ serialize_up_to_position (TrackerSerializerJsonLD *serializer_json_ld, node = g_hash_table_lookup (serializer_json_ld->resources, subject); if (!node) { - node = json_node_new (JSON_NODE_OBJECT); - object = json_object_new (); - json_object_set_string_member (object, "@id", subject); - json_node_set_object (node, object); - json_object_unref (object); + node = create_node (subject, subject_type, namespaces); g_hash_table_insert (serializer_json_ld->resources, g_strdup (subject), node); serializer_json_ld->recent_resources = g_list_prepend (serializer_json_ld->recent_resources, node); - } else { - object = json_node_get_object (node); } + object = json_node_get_object (node); serializer_json_ld->cur_resource = object; g_clear_pointer (&serializer_json_ld->cur_subject, g_free); @@ -282,14 +314,8 @@ serialize_up_to_position (TrackerSerializerJsonLD *serializer_json_ld, g_list_remove (serializer_json_ld->recent_resources, node); value = json_node_ref (node); } else { - JsonObject *object; - /* Unknown object, or one already referenced elsewhere */ - value = json_node_new (JSON_NODE_OBJECT); - object = json_object_new (); - json_object_set_string_member (object, "@id", res); - json_node_set_object (value, object); - json_object_unref (object); + value = create_node (res, object_type, namespaces); } break; case TRACKER_SPARQL_VALUE_TYPE_STRING: -- cgit v1.2.1 From d75ad7e585e1b9b8c346a736d524c2ab06a90b96 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 11 Jan 2023 15:56:13 +0100 Subject: libtracker-sparql: Avoid detaching all nodes in JSON-LD serializer If there are circular references, we might end up in a state that all JSON nodes were made part of a subtree, leaving us with no "root" node to unroll the data. Make it sure that we are left at least with a single root node, that every other nodes hang from. --- src/libtracker-sparql/tracker-serializer-json-ld.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libtracker-sparql/tracker-serializer-json-ld.c b/src/libtracker-sparql/tracker-serializer-json-ld.c index 52949f549..27e6a735d 100644 --- a/src/libtracker-sparql/tracker-serializer-json-ld.c +++ b/src/libtracker-sparql/tracker-serializer-json-ld.c @@ -307,6 +307,7 @@ serialize_up_to_position (TrackerSerializerJsonLD *serializer_json_ld, res); if (node && + serializer_json_ld->recent_resources->next != NULL && serializer_json_ld->cur_resource != json_node_get_object (node) && g_list_find (serializer_json_ld->recent_resources, node)) { /* This is still a "root" node, make it part of this tree */ -- cgit v1.2.1