[tracker-miners/wip/carlosg/writeback-refactor: 7/12] tracker-writeback: Change Writeback() DBus API



commit 8ca6fa20413245e991e80c6e53872e15a3cdb26f
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed May 20 14:07:06 2020 +0200

    tracker-writeback: Change Writeback() DBus API
    
    This API now parses a a{sv} gvariant holding a RDF tree describing
    the nie:InformationElement to be written back. This is passed to
    the new replacement internal API.
    
    Fixes: https://gitlab.gnome.org/GNOME/tracker-miners/issues/96

 src/tracker-writeback/tracker-writeback-module.c |  27 ++--
 src/tracker-writeback/tracker-writeback-module.h |  15 +-
 src/tracker-writeback/tracker-writeback.c        | 166 ++++++++++-------------
 3 files changed, 90 insertions(+), 118 deletions(-)
---
diff --git a/src/tracker-writeback/tracker-writeback-module.c 
b/src/tracker-writeback/tracker-writeback-module.c
index f035368da..88aa915d6 100644
--- a/src/tracker-writeback/tracker-writeback-module.c
+++ b/src/tracker-writeback/tracker-writeback-module.c
@@ -192,22 +192,19 @@ tracker_writeback_init (TrackerWriteback *writeback)
 }
 
 gboolean
-tracker_writeback_update_metadata (TrackerWriteback         *writeback,
-                                   GPtrArray                *values,
-                                   TrackerSparqlConnection  *connection,
-                                   GCancellable             *cancellable,
-                                   GError                  **error)
+tracker_writeback_write_metadata (TrackerWriteback         *writeback,
+                                  TrackerResource          *resource,
+                                  GCancellable             *cancellable,
+                                  GError                  **error)
 {
        g_return_val_if_fail (TRACKER_IS_WRITEBACK (writeback), FALSE);
-       g_return_val_if_fail (values != NULL, FALSE);
-
-       if (TRACKER_WRITEBACK_GET_CLASS (writeback)->update_metadata) {
-               return TRACKER_WRITEBACK_GET_CLASS (writeback)->update_metadata (writeback,
-                                                                                values,
-                                                                                connection,
-                                                                                cancellable,
-                                                                                error);
-       }
+       g_return_val_if_fail (resource != NULL, FALSE);
+
+       if (!TRACKER_WRITEBACK_GET_CLASS (writeback)->write_metadata)
+               return FALSE;
 
-       return FALSE;
+       return TRACKER_WRITEBACK_GET_CLASS (writeback)->write_metadata (writeback,
+                                                                       resource,
+                                                                       cancellable,
+                                                                       error);
 }
diff --git a/src/tracker-writeback/tracker-writeback-module.h 
b/src/tracker-writeback/tracker-writeback-module.h
index efbf5188a..6fa0258a0 100644
--- a/src/tracker-writeback/tracker-writeback-module.h
+++ b/src/tracker-writeback/tracker-writeback-module.h
@@ -50,11 +50,6 @@ struct TrackerWriteback {
 struct TrackerWritebackClass {
        GObjectClass parent_class;
 
-       gboolean (* update_metadata) (TrackerWriteback         *writeback,
-                                     GPtrArray                *values,
-                                     TrackerSparqlConnection  *connection,
-                                     GCancellable             *cancellable,
-                                     GError                  **error);
        gboolean (* write_metadata)  (TrackerWriteback         *writeback,
                                      TrackerResource          *resource,
                                      GCancellable             *cancellable,
@@ -75,13 +70,11 @@ struct TrackerWritebackModuleClass {
        GTypeModuleClass parent_class;
 };
 
-
 GType                   tracker_writeback_get_type          (void) G_GNUC_CONST;
-gboolean                tracker_writeback_update_metadata   (TrackerWriteback         *writeback,
-                                                             GPtrArray                *values,
-                                                             TrackerSparqlConnection  *connection,
-                                                             GCancellable             *cancellable,
-                                                             GError                  **error);
+gboolean                tracker_writeback_write_metadata    (TrackerWriteback  *writeback,
+                                                             TrackerResource   *resource,
+                                                             GCancellable      *cancellable,
+                                                             GError           **error);
 
 /* Entry functions to be defined by modules */
 TrackerWriteback *      writeback_module_create             (GTypeModule              *module);
diff --git a/src/tracker-writeback/tracker-writeback.c b/src/tracker-writeback/tracker-writeback.c
index 7fc5c2486..5dba2924c 100644
--- a/src/tracker-writeback/tracker-writeback.c
+++ b/src/tracker-writeback/tracker-writeback.c
@@ -41,9 +41,7 @@ typedef struct {
        GCancellable *cancellable;
        GDBusMethodInvocation *invocation;
        TrackerDBusRequest *request;
-       gchar *subject;
-       GPtrArray *results;
-       TrackerSparqlConnection *connection;
+       TrackerResource *resource;
        GList *writeback_handlers;
        GError *error;
 } WritebackData;
@@ -80,10 +78,8 @@ typedef struct {
 static const gchar *introspection_xml =
        "<node>"
        "  <interface name='org.freedesktop.Tracker3.Writeback'>"
-       "    <method name='PerformWriteback'>"
-       "      <arg type='s' name='subject' direction='in' />"
-       "      <arg type='as' name='rdf_types' direction='in' />"
-       "      <arg type='aas' name='results' direction='in' />"
+       "    <method name='Writeback'>"
+       "      <arg type='a{sv}' name='rdf' direction='in' />"
        "    </method>"
        "  </interface>"
        "</node>";
@@ -200,9 +196,7 @@ tracker_controller_class_init (TrackerControllerClass *klass)
 static WritebackData *
 writeback_data_new (TrackerController       *controller,
                     GList                   *writeback_handlers,
-                    TrackerSparqlConnection *connection,
-                    const gchar             *subject,
-                    GPtrArray               *results,
+                    TrackerResource         *resource,
                     GDBusMethodInvocation   *invocation,
                     TrackerDBusRequest      *request)
 {
@@ -211,10 +205,8 @@ writeback_data_new (TrackerController       *controller,
        data = g_slice_new (WritebackData);
        data->cancellable = g_cancellable_new ();
        data->controller = g_object_ref (controller);
-       data->subject = g_strdup (subject);
-       data->results = g_ptr_array_ref (results);
+       data->resource = g_object_ref (resource);
        data->invocation = invocation;
-       data->connection = g_object_ref (connection);
        data->writeback_handlers = writeback_handlers;
        data->request = request;
        data->error = NULL;
@@ -228,10 +220,8 @@ writeback_data_free (WritebackData *data)
        /* We rely on data->invocation being freed through
         * the g_dbus_method_invocation_return_* methods
         */
-       g_free (data->subject);
-       g_object_unref (data->connection);
-       g_ptr_array_unref (data->results);
        g_object_unref (data->cancellable);
+       g_object_unref (data->resource);
 
        g_list_foreach (data->writeback_handlers, (GFunc) g_object_unref, NULL);
        g_list_free (data->writeback_handlers);
@@ -331,25 +321,6 @@ perform_writeback_cb (gpointer user_data)
        return FALSE;
 }
 
-static gboolean
-sparql_rdf_types_match (const gchar * const *module_types,
-                        const gchar * const *rdf_types)
-{
-       guint n;
-
-       for (n = 0; rdf_types[n] != NULL; n++) {
-               guint i;
-
-               for (i = 0; module_types[i] != NULL; i++) {
-                       if (g_strcmp0 (module_types[i], rdf_types[n]) == 0) {
-                               return TRUE;
-                       }
-               }
-       }
-
-       return FALSE;
-}
-
 static void
 io_writeback_job (GTask        *task,
                   gpointer      source_object,
@@ -369,11 +340,10 @@ io_writeback_job (GTask        *task,
        writeback_handlers = data->writeback_handlers;
 
        while (writeback_handlers) {
-               handled |= tracker_writeback_update_metadata (writeback_handlers->data,
-                                                             data->results,
-                                                             data->connection,
-                                                             data->cancellable,
-                                                             (error) ? NULL : &error);
+               handled |= tracker_writeback_write_metadata (writeback_handlers->data,
+                                                            data->resource,
+                                                            data->cancellable,
+                                                            (error) ? NULL : &error);
                writeback_handlers = writeback_handlers->next;
        }
 
@@ -394,84 +364,102 @@ io_writeback_job (GTask        *task,
        g_idle_add (perform_writeback_cb, data);
 }
 
+gboolean
+module_matches_resource (TrackerWritebackModule *module,
+                         GList                  *types)
+{
+       TrackerNamespaceManager *namespaces;
+       const gchar * const *module_types;
+       GList *l;
+
+       module_types = tracker_writeback_module_get_rdf_types (module);
+       namespaces = tracker_namespace_manager_get_default ();
+
+       for (l = types; l; l = l->next) {
+               GValue *value = l->data;
+               const gchar *type;
+
+               if (G_VALUE_HOLDS_STRING (value)) {
+                       gchar *expanded;
+                       gboolean match;
+
+                       type = g_value_get_string (value);
+                       expanded = tracker_namespace_manager_expand_uri (namespaces,
+                                                                        type);
+                       match = g_strv_contains (module_types, expanded);
+                       g_free (expanded);
+
+                       if (match)
+                               return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
 static void
-handle_method_call_perform_writeback (TrackerController     *controller,
-                                      GDBusMethodInvocation *invocation,
-                                      GVariant              *parameters)
+handle_method_call_writeback (TrackerController     *controller,
+                              GDBusMethodInvocation *invocation,
+                              GVariant              *parameters)
 {
        TrackerControllerPrivate *priv;
        TrackerDBusRequest *request;
-       const gchar *subject;
-       GPtrArray *results = NULL;
+       TrackerResource *resource;
        GHashTableIter iter;
        gpointer key, value;
-       GVariantIter *iter1, *iter2, *iter3;
-       GArray *rdf_types_array;
-       GStrv rdf_types;
-       gchar *rdf_type = NULL;
        GList *writeback_handlers = NULL;
+       GList *types;
 
        priv = tracker_controller_get_instance_private (controller);
 
-       results = g_ptr_array_new_with_free_func ((GDestroyNotify) g_strfreev);
-       g_variant_get (parameters, "(&sasaas)", &subject, &iter1, &iter2);
+       reset_shutdown_timeout (controller);
+       request = tracker_dbus_request_begin (NULL, "%s", __FUNCTION__);
 
-       rdf_types_array = g_array_new (TRUE, TRUE, sizeof (gchar *));
-       while (g_variant_iter_loop (iter1, "&s", &rdf_type)) {
-               g_array_append_val (rdf_types_array, rdf_type);
+       resource = tracker_resource_deserialize (g_variant_get_child_value (parameters, 0));
+       if (!resource) {
+               g_dbus_method_invocation_return_error (invocation,
+                                                      G_DBUS_ERROR,
+                                                      G_DBUS_ERROR_INVALID_ARGS,
+                                                      "GVariant does not serialize to a resource");
+               return;
        }
 
-       rdf_types = (GStrv) rdf_types_array->data;
-       g_array_free (rdf_types_array, FALSE);
-
-       while (g_variant_iter_loop (iter2, "as", &iter3)) {
-               GArray *row_array = g_array_new (TRUE, TRUE, sizeof (gchar *));
-               gchar *cell = NULL;
-
-               while (g_variant_iter_loop (iter3, "&s", &cell)) {
-                       g_array_append_val (row_array, cell);
-               }
-
-               g_ptr_array_add (results, row_array->data);
-               g_array_free (row_array, FALSE);
+       types = tracker_resource_get_values (resource, "rdf:type");
+       if (!types) {
+               g_dbus_method_invocation_return_error (invocation,
+                                                      G_DBUS_ERROR,
+                                                      G_DBUS_ERROR_INVALID_ARGS,
+                                                      "Resource does not define rdf:type");
+               return;
        }
 
-       g_variant_iter_free (iter1);
-       g_variant_iter_free (iter2);
-
-       reset_shutdown_timeout (controller);
-       request = tracker_dbus_request_begin (NULL, "%s (%s)", __FUNCTION__, subject);
-
        g_hash_table_iter_init (&iter, priv->modules);
 
        while (g_hash_table_iter_next (&iter, &key, &value)) {
                TrackerWritebackModule *module;
-               const gchar * const *module_types;
 
                module = value;
-               module_types = tracker_writeback_module_get_rdf_types (module);
 
-               if (sparql_rdf_types_match (module_types, (const gchar * const *) rdf_types)) {
+               if (module_matches_resource (module, types)) {
                        TrackerWriteback *writeback;
 
-                       g_message ("  Updating metadata for subject:'%s' using module:'%s'",
-                                  subject,
-                                  module->name);
+                       g_debug ("Using module '%s' as a candidate",
+                                module->name);
 
                        writeback = tracker_writeback_module_create (module);
                        writeback_handlers = g_list_prepend (writeback_handlers, writeback);
                }
        }
 
+       g_list_free (types);
+
        if (writeback_handlers != NULL) {
                WritebackData *data;
                GTask *task;
 
                data = writeback_data_new (controller,
                                           writeback_handlers,
-                                          priv->connection,
-                                          subject,
-                                          results,
+                                          resource,
                                           invocation,
                                           request);
                task = g_task_new (controller, data->cancellable, NULL, NULL);
@@ -481,19 +469,13 @@ handle_method_call_perform_writeback (TrackerController     *controller,
                g_task_run_in_thread (task, io_writeback_job);
                g_object_unref (task);
        } else {
-               char *rdf_types_string;
-               rdf_types_string = g_strjoinv (", ", rdf_types);
                g_dbus_method_invocation_return_error (invocation,
                                                       TRACKER_DBUS_ERROR,
                                                       TRACKER_DBUS_ERROR_UNSUPPORTED,
-                                                      "None of %i writeback modules matched any of the "
-                                                      "given RDF types: %s",
-                                                      g_hash_table_size (priv->modules),
-                                                      rdf_types_string);
-               g_free (rdf_types_string);
+                                                      "Resource description does not match any writeback 
modules");
        }
 
-       g_free (rdf_types);
+       g_object_unref (resource);
 }
 
 static void
@@ -508,8 +490,8 @@ handle_method_call (GDBusConnection       *connection,
 {
        TrackerController *controller = user_data;
 
-       if (g_strcmp0 (method_name, "PerformWriteback") == 0) {
-               handle_method_call_perform_writeback (controller, invocation, parameters);
+       if (g_strcmp0 (method_name, "Writeback") == 0) {
+               handle_method_call_writeback (controller, invocation, parameters);
        } else {
                g_warning ("Unknown method '%s' called", method_name);
        }


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