summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2020-09-02 00:33:06 +0200
committerCarlos Garnacho <carlosg@gnome.org>2020-09-02 10:25:44 +0200
commit2106b0f250a6832d964fbf27adfc2d860effb940 (patch)
tree19f5e1fa7be381e727b46f473758472204f8098b
parent912a8077d370a9d12f6bff723f3c4888933f1542 (diff)
downloadtracker-2106b0f250a6832d964fbf27adfc2d860effb940.tar.gz
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.
-rw-r--r--docs/manpages/tracker-export.1.txt8
-rw-r--r--src/tracker/tracker-export.c196
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 ();
}