[tracker/wip/carlosg/2to3-export] tracker: Add --2to3 switch to "tracker3 export"




commit 2106b0f250a6832d964fbf27adfc2d860effb940
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Sep 2 00:33:06 2020 +0200

    tracker: Add --2to3 switch to "tracker3 export"
    
    This special mode opens the old Tracker2 database, and tries to
    extract data, pretty much in the same fashion than "tracker export"
    command introduced recently in 2.3.x.
    
    So far, this submode only supports exporting of starred files. The
    --keyfile argument is also supported, to ease manipulation of this
    data on the consumer side.

 docs/manpages/tracker-export.1.txt |   8 ++
 src/tracker/tracker-export.c       | 196 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 200 insertions(+), 4 deletions(-)
---
diff --git a/docs/manpages/tracker-export.1.txt b/docs/manpages/tracker-export.1.txt
index 04f407cc8..e4c13d7af 100644
--- a/docs/manpages/tracker-export.1.txt
+++ b/docs/manpages/tracker-export.1.txt
@@ -30,6 +30,14 @@ tool such as rapper(1) to convert the data to different formats.
   the extra GRAPH statements. Some tools which understand Turtle do not
   understand TriG.
 
+*--2to3*::
+  Helper for migrating data from Tracker 2.x databases. This option
+  takes an argument specifying the scope. Only the “files-starred”
+  argument is available so far.
+
+*--keyfile*::
+  Outputs the data in a key file format. Only may be used with --2to3
+
 == EXAMPLES
 
 Export all data from Tracker Index and prettify the output using
diff --git a/src/tracker/tracker-export.c b/src/tracker/tracker-export.c
index 2484e0296..900fc411b 100644
--- a/src/tracker/tracker-export.c
+++ b/src/tracker/tracker-export.c
@@ -27,17 +27,20 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
-#include <libtracker-sparql/tracker-sparql.h>
-#include <libtracker-common/tracker-common.h>
-
 #include "tracker-sparql.h"
 #include "tracker-color.h"
 
+#include <libtracker-sparql/tracker-sparql.h>
+#include <libtracker-common/tracker-common.h>
+#include <libtracker-data/tracker-data.h>
+
 static gchar *database_path;
 static gchar *dbus_service;
 static gchar *remote_service;
 static gboolean show_graphs;
 static gchar **iris;
+static gchar *data_type = NULL;
+static gboolean keyfile = FALSE;
 
 static GOptionEntry entries[] = {
        { "database", 'd', 0, G_OPTION_ARG_FILENAME, &database_path,
@@ -56,6 +59,14 @@ static GOptionEntry entries[] = {
          N_("Output TriG format which includes named graph information"),
          NULL
        },
+        { "2to3", 0, 0, G_OPTION_ARG_STRING, &data_type,
+          NULL,
+          NULL
+        },
+        { "keyfile", 0, 0, G_OPTION_ARG_NONE, &keyfile,
+          NULL,
+          NULL
+        },
        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &iris,
          N_("IRI"),
          N_("IRI")},
@@ -88,7 +99,6 @@ create_connection (GError **error)
        }
 }
 
-
 /* format a URI for Turtle; if it has a prefix, display uri
  * as prefix:rest_of_uri; if not, display as <uri>
  */
@@ -243,6 +253,44 @@ print_trig (TrackerSparqlCursor *cursor,
        g_free (previous_graph);
 }
 
+static void
+print_keyfile (TrackerSparqlCursor *cursor)
+{
+       GKeyFile *key_file;
+       gchar *data;
+
+       key_file = g_key_file_new ();
+
+       while (tracker_sparql_cursor_next (cursor, NULL, 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);
+               GStrv values;
+               gsize n_items;
+
+               values = g_key_file_get_string_list (key_file, resource, key, &n_items, NULL);
+
+               if (values) {
+                       GArray *array;
+
+                       array = g_array_new (TRUE, TRUE, sizeof (char*));
+                       g_array_append_vals (array, values, n_items);
+                       g_array_append_val (array, value);
+
+                       g_key_file_set_string_list (key_file, resource, key,
+                                                   (const gchar * const *) array->data,
+                                                   array->len);
+               } else {
+                       g_key_file_set_string (key_file, resource, key, value);
+               }
+
+               g_strfreev (values);
+       }
+
+       data = g_key_file_to_data (key_file, NULL, NULL);
+       g_print ("%s\n", data);
+}
+
 static int
 export_run_default (void)
 {
@@ -318,6 +366,142 @@ export_run_default (void)
        return EXIT_SUCCESS;
 }
 
+/* Execute a query and export the resulting triples or quads to stdout.
+ *
+ * The query should return quads (graph, subject, predicate, object) plus an extra
+ * boolean column that is false when the 'object' value is a simple type or a resource.
+ */
+static gboolean
+export_2to3_with_query (const gchar  *query,
+                        gboolean      show_graphs,
+                        GError      **error)
+{
+       g_autoptr(TrackerDBManager) db_manager = NULL;
+       TrackerDBInterface *iface = NULL;
+       TrackerDBStatement *stmt = NULL;
+       TrackerSparqlCursor *cursor = NULL;
+       GError *inner_error = NULL;
+       g_autoptr(GFile) store = NULL;
+       g_autofree char *path = NULL;
+
+       path = g_build_filename (g_get_user_cache_dir (),
+                                "tracker", NULL);
+       store = g_file_new_for_path (path);
+
+       db_manager = tracker_db_manager_new (TRACKER_DB_MANAGER_READONLY |
+                                            TRACKER_DB_MANAGER_SKIP_VERSION_CHECK,
+                                            store,
+                                            NULL, FALSE,
+                                            1, 1, NULL, NULL, NULL, NULL, &inner_error);
+
+       if (inner_error) {
+               g_propagate_prefixed_error (error, inner_error,
+                                           "%s: ", _("Could not run query"));
+               g_object_unref (db_manager);
+               return FALSE;
+       }
+
+       iface = tracker_db_manager_get_writable_db_interface (db_manager);
+
+       stmt = tracker_db_interface_create_statement (iface,
+                                                     TRACKER_DB_STATEMENT_CACHE_TYPE_NONE,
+                                                     &inner_error,
+                                                     "%s", query);
+       if (!stmt) {
+               g_propagate_prefixed_error (error, inner_error,
+                                           "%s: ", _("Could not run query"));
+               g_object_unref (db_manager);
+               return FALSE;
+       }
+
+       cursor = TRACKER_SPARQL_CURSOR (tracker_db_statement_start_cursor (stmt, &inner_error));
+       g_object_unref (stmt);
+
+       if (!cursor) {
+               g_propagate_prefixed_error (error, inner_error,
+                                           "%s: ", _("Could not run query"));
+               g_object_unref (db_manager);
+               return FALSE;
+       }
+
+       if (keyfile) {
+               print_keyfile (cursor);
+       } if (show_graphs) {
+               print_trig (cursor, NULL, FALSE);
+       } else {
+               print_turtle (cursor, NULL, FALSE);
+       }
+
+       g_object_unref (cursor);
+
+       return TRUE;
+}
+
+static int
+export_2to3_run_files_starred (void)
+{
+       const gchar *query;
+       g_autoptr(GError) error = NULL;
+
+       query = "SELECT "
+               "  \"\" ,"
+               "  COALESCE ((SELECT \"nie:url\" FROM \"nie:DataObject\" WHERE ID = \"v_u\" ) ,"
+               "            (SELECT Uri FROM Resource WHERE ID = \"v_u\" ) ) ,"
+               "  \"v_p\","
+               "  \"v_v\","
+               "  'true' "
+               "FROM ("
+               "  SELECT * "
+               "  FROM (("
+               "    SELECT "
+               "      \"v_u\" ,"
+               "      'rdf:type' AS \"v_p\" ,"
+               "      'nfo:FileDataObject' AS \"v_v\""
+               "    FROM ("
+               "      SELECT"
+               "        \"nfo:FileDataObject1\".\"ID\" AS \"v_u\""
+               "      FROM \"nfo:FileDataObject\" AS \"nfo:FileDataObject1\" ,"
+               "           \"rdfs:Resource_nao:hasTag\" AS \"rdfs:Resource_nao:hasTag2\""
+               "      WHERE \"nfo:FileDataObject1\".\"ID\" = \"rdfs:Resource_nao:hasTag2\".\"ID\""
+               "        AND \"rdfs:Resource_nao:hasTag2\".\"nao:hasTag\" ="
+               "            COALESCE ((SELECT ID FROM Resource WHERE Uri = 'urn:gnome:nautilus:starred' ), 
0) ) ) )"
+               "  UNION ALL"
+               "  SELECT *"
+               "  FROM (("
+               "    SELECT"
+               "      \"v_u\" ,"
+               "      \"nao:hasTag\" AS \"v_p\" ,"
+               "      \"urn:gnome:nautilus:starred\" AS \"v_v\""
+               "    FROM (SELECT \"nfo:FileDataObject1\".\"ID\" AS \"v_u\""
+               "          FROM \"nfo:FileDataObject\" AS \"nfo:FileDataObject1\" ,"
+               "               \"rdfs:Resource_nao:hasTag\" AS \"rdfs:Resource_nao:hasTag2\""
+               "          WHERE \"nfo:FileDataObject1\".\"ID\" = \"rdfs:Resource_nao:hasTag2\".\"ID\""
+               "            AND \"rdfs:Resource_nao:hasTag2\".\"nao:hasTag\" ="
+               "                COALESCE ((SELECT ID FROM Resource WHERE Uri = 'urn:gnome:nautilus:starred' 
), 0) ) ) ) )"
+               "ORDER BY (SELECT Uri FROM Resource WHERE ID = \"v_u\" )";
+
+       export_2to3_with_query (query, FALSE, &error);
+
+       if (error) {
+               g_printerr ("%s\n", error->message);
+               return EXIT_FAILURE;
+       } else {
+               return EXIT_SUCCESS;
+       }
+}
+
+static gint
+export_2to3_run (void)
+{
+       if (strcmp (data_type, "files-starred") == 0) {
+               return export_2to3_run_files_starred ();
+       }
+
+       g_print ("Options: files-starred\n");
+
+       return EXIT_FAILURE;
+}
+
 int
 tracker_export (int argc, const char **argv)
 {
@@ -338,5 +522,9 @@ tracker_export (int argc, const char **argv)
 
        g_option_context_free (context);
 
+        if (data_type) {
+               return export_2to3_run ();
+        }
+
        return export_run_default ();
 }


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