summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam@afuera.me.uk>2020-09-02 09:12:44 +0000
committerSam Thursfield <sam@afuera.me.uk>2020-09-02 09:12:44 +0000
commit50a3bbcb226be4a7f416f36657af1b41d6174fa9 (patch)
treeb96bab706b442e87d8be1caa4d94f94ac2e596ec
parent9f7252c8ad15822273ef423d42cdd81f1156a64a (diff)
parent2106b0f250a6832d964fbf27adfc2d860effb940 (diff)
downloadtracker-50a3bbcb226be4a7f416f36657af1b41d6174fa9.tar.gz
Merge branch 'wip/carlosg/2to3-export' into 'master'
Add --2to3 exporting capabilities to `tracker3 export` See merge request GNOME/tracker!308
-rw-r--r--docs/manpages/tracker-export.1.txt8
-rw-r--r--src/libtracker-data/tracker-db-manager.c2
-rw-r--r--src/libtracker-data/tracker-db-manager.h1
-rw-r--r--src/tracker/tracker-export.c196
4 files changed, 202 insertions, 5 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/libtracker-data/tracker-db-manager.c b/src/libtracker-data/tracker-db-manager.c
index a90245235..4eec98e11 100644
--- a/src/libtracker-data/tracker-db-manager.c
+++ b/src/libtracker-data/tracker-db-manager.c
@@ -579,7 +579,7 @@ tracker_db_manager_new (TrackerDBManagerFlags flags,
g_object_unref (db_manager);
return NULL;
}
- } else {
+ } else if ((flags & TRACKER_DB_MANAGER_SKIP_VERSION_CHECK) == 0) {
version = db_get_version (db_manager);
if (version < TRACKER_DB_VERSION_NOW) {
diff --git a/src/libtracker-data/tracker-db-manager.h b/src/libtracker-data/tracker-db-manager.h
index 5feb64b6f..7fd99dcbd 100644
--- a/src/libtracker-data/tracker-db-manager.h
+++ b/src/libtracker-data/tracker-db-manager.h
@@ -47,6 +47,7 @@ typedef enum {
TRACKER_DB_MANAGER_FTS_ENABLE_STOP_WORDS = 1 << 6,
TRACKER_DB_MANAGER_FTS_IGNORE_NUMBERS = 1 << 7,
TRACKER_DB_MANAGER_IN_MEMORY = 1 << 8,
+ TRACKER_DB_MANAGER_SKIP_VERSION_CHECK = 1 << 9,
} TrackerDBManagerFlags;
typedef struct _TrackerDBManager TrackerDBManager;
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 ();
}