[tracker/sam/2.x-export-data: 2/4] cli: Add `tracker export --show-graphs` option



commit 8a9b9bfefe520ee9166bd0aaad9918bfd4553990
Author: Sam Thursfield <sam afuera me uk>
Date:   Mon May 11 01:53:49 2020 +0200

    cli: Add `tracker export --show-graphs` option
    
    This option includes graphs in the exported output.
    
    In this mode the output is no longer Turtle format but
    [TriG](https://www.w3.org/TR/trig/) format. This means
    `tracker export --show-graphs | tracker import` won't
    work, so this mode is disabled by default.
    
    Backport of f85c08e4b0befbfe034fb0e86c68a6c3eb0f88ee

 docs/manpages/tracker-export.1 |  10 ++++
 src/tracker/tracker-export.c   | 101 +++++++++++++++++++++++++++++++++++------
 2 files changed, 98 insertions(+), 13 deletions(-)
---
diff --git a/docs/manpages/tracker-export.1 b/docs/manpages/tracker-export.1
index 2b7e0bd62..e10e7e672 100644
--- a/docs/manpages/tracker-export.1
+++ b/docs/manpages/tracker-export.1
@@ -13,6 +13,16 @@ exports all data stored in a Tracker database, in Turtle format.
 The output is intended to be machine-readable, not human readable.
 Use a tool such as rapper(1) to convert the data to different formats.
 
+.SH OPTIONS
+.TP
+.B \-g, \-\-show-graphs
+This flag causes the relevant GRAPH statements to be output along with
+the data.
+
+In this mode the output is TriG syntax rather than Turtle, due to
+the extra GRAPH statements. Some tools which understand Turtle do not
+understand TriG.
+
 .SH EXAMPLES
 .TP
 Export all data from Tracker Index and prettify the output using rapper(1).
diff --git a/src/tracker/tracker-export.c b/src/tracker/tracker-export.c
index 7528c6f1b..683fe74b9 100644
--- a/src/tracker/tracker-export.c
+++ b/src/tracker/tracker-export.c
@@ -32,8 +32,14 @@
 #include "tracker-sparql.h"
 #include "tracker-color.h"
 
+static gboolean show_graphs;
+
 static GOptionEntry entries[] = {
-       { NULL }
+       { "show-graphs", 'g', 0, G_OPTION_ARG_NONE, &show_graphs,
+         N_("Output TriG format which includes named graph information"),
+         NULL
+       },
+       { NULL }
 };
 
 static TrackerSparqlConnection *
@@ -88,7 +94,7 @@ print_prefix (gpointer key,
        g_print ("@prefix %s: <%s#> .\n", (gchar *) value, (gchar *) key);
 }
 
-/* Print triples for a urn in Turtle format */
+/* Print triples in Turtle format */
 static void
 print_turtle (TrackerSparqlCursor *cursor,
               GHashTable          *prefixes,
@@ -98,10 +104,10 @@ print_turtle (TrackerSparqlCursor *cursor,
        gchar *object;
 
        while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
-               const gchar *resource = tracker_sparql_cursor_get_string (cursor, 0, NULL);
-               const gchar *key = tracker_sparql_cursor_get_string (cursor, 1, NULL);
-               const gchar *value = tracker_sparql_cursor_get_string (cursor, 2, NULL);
-               const gchar *value_is_resource = tracker_sparql_cursor_get_string (cursor, 3, NULL);
+               const gchar *resource = tracker_sparql_cursor_get_string (cursor, 1, NULL);
+               const gchar *key = tracker_sparql_cursor_get_string (cursor, 2, NULL);
+               const gchar *value = tracker_sparql_cursor_get_string (cursor, 3, NULL);
+               const gchar *value_is_resource = tracker_sparql_cursor_get_string (cursor, 4, NULL);
 
                if (!resource || !key || !value || !value_is_resource) {
                        continue;
@@ -133,6 +139,69 @@ print_turtle (TrackerSparqlCursor *cursor,
        }
 }
 
+/* Print graphs and triples in TriG format */
+static void
+print_trig (TrackerSparqlCursor *cursor,
+            GHashTable          *prefixes,
+            gboolean             full_namespaces)
+{
+       gchar *predicate;
+       gchar *object;
+       gchar *previous_graph = NULL;
+       const gchar *graph;
+
+       while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
+               graph = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+               const gchar *resource = tracker_sparql_cursor_get_string (cursor, 1, NULL);
+               const gchar *key = tracker_sparql_cursor_get_string (cursor, 2, NULL);
+               const gchar *value = tracker_sparql_cursor_get_string (cursor, 3, NULL);
+               const gchar *value_is_resource = tracker_sparql_cursor_get_string (cursor, 4, NULL);
+
+               if (!resource || !key || !value || !value_is_resource) {
+                       continue;
+               }
+
+               if (g_strcmp0 (previous_graph, graph) != 0) {
+                       if (previous_graph != NULL) {
+                               /* Close previous graph */
+                               g_print ("}\n");
+                               g_free (previous_graph);
+                       }
+                       previous_graph = g_strdup (graph);
+                       g_print ("GRAPH <%s>\n{\n", graph);
+               }
+
+               /* Don't display nie:plainTextContent */
+               //if (!plain_text_content && strcmp (key, 
"http://tracker.api.gnome.org/ontology/v3/nie#plainTextContent";) == 0) {
+               //      continue;
+               //}
+
+               predicate = format_urn (prefixes, key, full_namespaces);
+
+               if (g_ascii_strcasecmp (value_is_resource, "true") == 0) {
+                       object = g_strdup_printf ("<%s>", value);
+               } else {
+                       gchar *escaped_value;
+
+                       /* Escape value and make sure it is encapsulated properly */
+                       escaped_value = tracker_sparql_escape_string (value);
+                       object = g_strdup_printf ("\"%s\"", escaped_value);
+                       g_free (escaped_value);
+               }
+
+               /* Print final statement */
+               g_print ("  <%s> %s %s .\n", resource, predicate, object);
+
+               g_free (predicate);
+               g_free (object);
+       }
+
+       if (graph != NULL) {
+               g_print ("}\n");
+       }
+       g_free (previous_graph);
+}
+
 static int
 export_run_default (void)
 {
@@ -153,14 +222,16 @@ export_run_default (void)
 
        prefixes = tracker_sparql_get_prefixes ();
 
-       query = "SELECT ?u ?p ?v "
+       query = "SELECT ?g ?u ?p ?v "
                "       (EXISTS { ?p rdfs:range [ rdfs:subClassOf rdfs:Resource ] }) AS ?is_resource "
                "{ "
-               "    ?u ?p ?v "
-               "    FILTER NOT EXISTS { ?u a rdf:Property } "
-               "    FILTER NOT EXISTS { ?u a rdfs:Class } "
-               "    FILTER NOT EXISTS { ?u a tracker:Namespace } "
-               "} ORDER BY ?u";
+               "    GRAPH ?g { "
+               "        ?u ?p ?v "
+               "        FILTER NOT EXISTS { ?u a rdf:Property } "
+               "        FILTER NOT EXISTS { ?u a rdfs:Class } "
+               "        FILTER NOT EXISTS { ?u a tracker:Namespace } "
+               "    } "
+               "} ORDER BY ?g ?u";
 
        cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
 
@@ -174,7 +245,11 @@ export_run_default (void)
        g_hash_table_foreach (prefixes, (GHFunc) print_prefix, NULL);
        g_print ("\n");
 
-       print_turtle (cursor, prefixes, FALSE);
+       if (show_graphs) {
+               print_trig (cursor, prefixes, FALSE);
+       } else {
+               print_turtle (cursor, prefixes, FALSE);
+       }
 
        return EXIT_SUCCESS;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]