[gnome-photos/wip/rishi/unbreak-delete] Unbreak deletion of items from the Tracker database




commit e6bf3a426b32bf3ef9f7ee485dd7e75399a014d7
Author: Debarshi Ray <debarshir gnome org>
Date:   Sun Mar 14 12:14:38 2021 +0100

    Unbreak deletion of items from the Tracker database
    
    Tracker 3 enforces a clear separation between metadata stored in the
    application's private database and the filesystem miner's global
    database. The application is only permitted to delete metadata from its
    private database.
    
    Therefore, a "DELETE ..." SPARQL update is only used for collections,
    which are stored in the application's private database. For other
    items, the underlying file is trashed and the application relies on
    the filesystem miner to react to it.
    
    As a nice side-effect, the PhotosBaseItem::trash virtual method has now
    been converted into an asynchronous API.
    
    Fallout from bd087d67f938c29776842afbc3b7bc745d2ca9a2
    
    https://gitlab.gnome.org/GNOME/gnome-photos/-/merge_requests/175

 src/photos-base-item.c     | 24 +++++-------
 src/photos-base-item.h     |  6 ++-
 src/photos-device-item.c   |  7 +++-
 src/photos-local-item.c    | 97 ++++++++++++++++++++++++++++++++++++++--------
 src/photos-query-builder.c |  9 ++++-
 5 files changed, 107 insertions(+), 36 deletions(-)
---
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index 6ccde753..e4007853 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -42,7 +42,6 @@
 #include "photos-base-item.h"
 #include "photos-collection-icon-watcher.h"
 #include "photos-debug.h"
-#include "photos-delete-item-job.h"
 #include "photos-error.h"
 #include "photos-filterable.h"
 #include "photos-gegl.h"
@@ -2743,16 +2742,16 @@ photos_base_item_save_to_stream_load (GObject *source_object, GAsyncResult *res,
 
 
 static void
-photos_base_item_trash_executed (GObject *source_object, GAsyncResult *res, gpointer user_data)
+photos_base_item_trash_trash (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
+  PhotosBaseItem *self = PHOTOS_BASE_ITEM (source_object);
   GApplication *app;
   g_autoptr (GTask) task = G_TASK (user_data);
-  PhotosDeleteItemJob *job = PHOTOS_DELETE_ITEM_JOB (source_object);
 
   {
     g_autoptr (GError) error = NULL;
 
-    if (!photos_delete_item_job_finish (job, res, &error))
+    if (!PHOTOS_BASE_ITEM_GET_CLASS (self)->trash_finish (self, res, &error))
       {
         g_task_return_error (task, g_steal_pointer (&error));
         goto out;
@@ -3264,7 +3263,7 @@ gboolean
 photos_base_item_can_trash (PhotosBaseItem *self)
 {
   g_return_val_if_fail (PHOTOS_IS_BASE_ITEM (self), FALSE);
-  return PHOTOS_BASE_ITEM_GET_CLASS (self)->trash != NULL;
+  return PHOTOS_BASE_ITEM_GET_CLASS (self)->trash_async != NULL;
 }
 
 
@@ -4758,24 +4757,21 @@ photos_base_item_trash_async (PhotosBaseItem *self,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
 {
-  PhotosBaseItemPrivate *priv;
   GApplication *app;
   g_autoptr (GTask) task = NULL;
-  g_autoptr (PhotosDeleteItemJob) job = NULL;
 
   g_return_if_fail (PHOTOS_IS_BASE_ITEM (self));
-  priv = photos_base_item_get_instance_private (self);
+
+  app = g_application_get_default ();
 
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_source_tag (task, photos_base_item_trash_async);
 
-  PHOTOS_BASE_ITEM_GET_CLASS (self)->trash (self);
-
-  app = g_application_get_default ();
-  job = photos_delete_item_job_new (priv->id);
-
   g_application_hold (app);
-  photos_delete_item_job_run (job, cancellable, photos_base_item_trash_executed, g_object_ref (task));
+  PHOTOS_BASE_ITEM_GET_CLASS (self)->trash_async (self,
+                                                  cancellable,
+                                                  photos_base_item_trash_trash,
+                                                  g_object_ref (task));
 }
 
 
diff --git a/src/photos-base-item.h b/src/photos-base-item.h
index 20f971ce..1d18410c 100644
--- a/src/photos-base-item.h
+++ b/src/photos-base-item.h
@@ -71,7 +71,11 @@ struct _PhotosBaseItemClass
   void        (*open)                       (PhotosBaseItem *self, GtkWindow *parent, guint32 timestamp);
   void        (*refresh_icon)               (PhotosBaseItem *self);
   void        (*set_favorite)               (PhotosBaseItem *self, gboolean favorite);
-  void        (*trash)                      (PhotosBaseItem *self);
+  void        (*trash_async)                (PhotosBaseItem *self,
+                                             GCancellable *cancellable,
+                                             GAsyncReadyCallback callback,
+                                             gpointer user_data);
+  gboolean    (*trash_finish)               (PhotosBaseItem *self, GAsyncResult *res, GError **error);
   void        (*update_type_description)    (PhotosBaseItem *self);
 
   /* signals */
diff --git a/src/photos-device-item.c b/src/photos-device-item.c
index 275900a9..97d844f9 100644
--- a/src/photos-device-item.c
+++ b/src/photos-device-item.c
@@ -382,7 +382,10 @@ photos_device_item_refresh_icon (PhotosBaseItem *item)
 
 
 static void
-photos_device_item_trash (PhotosBaseItem *item)
+photos_device_item_trash_async (PhotosBaseItem *item,
+                                GCancellable *cancellable,
+                                GAsyncReadyCallback callback,
+                                gpointer user_data)
 {
   g_assert_not_reached ();
 }
@@ -456,5 +459,5 @@ photos_device_item_class_init (PhotosDeviceItemClass *class)
   base_item_class->get_source_widget = photos_device_item_get_source_widget;
   base_item_class->metadata_add_shared = photos_device_item_metadata_add_shared;
   base_item_class->refresh_icon = photos_device_item_refresh_icon;
-  base_item_class->trash = photos_device_item_trash;
+  base_item_class->trash_async = photos_device_item_trash_async;
 }
diff --git a/src/photos-local-item.c b/src/photos-local-item.c
index 2d130634..105d09b5 100644
--- a/src/photos-local-item.c
+++ b/src/photos-local-item.c
@@ -31,7 +31,9 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
+#include "photos-delete-item-job.h"
 #include "photos-error.h"
+#include "photos-filterable.h"
 #include "photos-glib.h"
 #include "photos-local-item.h"
 #include "photos-utils.h"
@@ -381,41 +383,101 @@ photos_local_item_metadata_add_shared (PhotosBaseItem  *item,
 
 
 static void
-photos_local_item_trash_finish (GObject *source_object, GAsyncResult *res, gpointer user_data)
+photos_local_item_trash_executed (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  g_autoptr (GTask) task = G_TASK (user_data);
+  PhotosDeleteItemJob *job = PHOTOS_DELETE_ITEM_JOB (source_object);
+
+  {
+    g_autoptr (GError) error = NULL;
+
+    if (!photos_delete_item_job_finish (job, res, &error))
+      {
+        g_task_return_error (task, g_steal_pointer (&error));
+        goto out;
+      }
+  }
+
+  g_task_return_boolean (task, TRUE);
+
+ out:
+  return;
+}
+
+
+static void
+photos_local_item_trash_trash (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
   GFile *file = G_FILE (source_object);
+  g_autoptr (GTask) task = G_TASK (user_data);
 
   {
     g_autoptr (GError) error = NULL;
 
     if (!g_file_trash_finish (file, res, &error))
       {
-        if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-          {
-            PhotosLocalItem *self = PHOTOS_LOCAL_ITEM (user_data);
-            const gchar *uri;
-
-            uri = photos_base_item_get_uri (PHOTOS_BASE_ITEM (self));
-            g_warning ("Unable to trash %s: %s", uri, error->message);
-          }
+        g_task_return_error (task, g_steal_pointer (&error));
+        goto out;
       }
   }
+
+  g_task_return_boolean (task, TRUE);
+
+ out:
+  return;
 }
 
 
 static void
-photos_local_item_trash (PhotosBaseItem *item)
+photos_local_item_trash_async (PhotosBaseItem *item,
+                               GCancellable *cancellable,
+                               GAsyncReadyCallback callback,
+                               gpointer user_data)
 {
-  g_autoptr (GFile) file = NULL;
-  const gchar *uri;
   PhotosLocalItem *self = PHOTOS_LOCAL_ITEM (item);
+  g_autoptr (GTask) task = NULL;
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, photos_local_item_trash_async);
 
   if (photos_base_item_is_collection (item))
-    return;
+    {
+      g_autoptr (PhotosDeleteItemJob) job = NULL;
+      const gchar *id;
 
-  uri = photos_base_item_get_uri (item);
-  file = g_file_new_for_uri (uri);
-  g_file_trash_async (file, G_PRIORITY_DEFAULT, self->cancellable, photos_local_item_trash_finish, self);
+      id = photos_filterable_get_id (PHOTOS_FILTERABLE (self));
+      job = photos_delete_item_job_new (id);
+      photos_delete_item_job_run (job, cancellable, photos_local_item_trash_executed, g_object_ref (task));
+    }
+  else
+    {
+      g_autoptr (GFile) file = NULL;
+      const gchar *uri;
+
+      uri = photos_base_item_get_uri (item);
+      file = g_file_new_for_uri (uri);
+      g_file_trash_async (file,
+                          G_PRIORITY_DEFAULT,
+                          cancellable,
+                          photos_local_item_trash_trash,
+                          g_object_ref (task));
+    }
+}
+
+
+static gboolean
+photos_local_item_trash_finish (PhotosBaseItem *item, GAsyncResult *res, GError **error)
+{
+  PhotosLocalItem *self = PHOTOS_LOCAL_ITEM (item);
+  GTask *task;
+
+  g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
+  task = G_TASK (res);
+
+  g_return_val_if_fail (g_task_get_source_tag (task) == photos_local_item_trash_async, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  return g_task_propagate_boolean (task, error);
 }
 
 
@@ -477,5 +539,6 @@ photos_local_item_class_init (PhotosLocalItemClass *class)
   base_item_class->download = photos_local_item_download;
   base_item_class->get_source_widget = photos_local_item_get_source_widget;
   base_item_class->metadata_add_shared = photos_local_item_metadata_add_shared;
-  base_item_class->trash = photos_local_item_trash;
+  base_item_class->trash_async = photos_local_item_trash_async;
+  base_item_class->trash_finish = photos_local_item_trash_finish;
 }
diff --git a/src/photos-query-builder.c b/src/photos-query-builder.c
index c7249ba6..85df12cb 100644
--- a/src/photos-query-builder.c
+++ b/src/photos-query-builder.c
@@ -321,9 +321,14 @@ photos_query_builder_delete_resource_query (PhotosSearchContextState *state, con
   PhotosQuery *query;
   g_autofree gchar *sparql = NULL;
 
-  sparql = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }", resource);
-  query = photos_query_new (state, sparql);
+  sparql = g_strdup_printf ("DELETE DATA {"
+                            "  GRAPH tracker:Pictures {"
+                            "    <%s> a rdfs:Resource"
+                            "  }"
+                            "}",
+                            resource);
 
+  query = photos_query_new (state, sparql);
   return query;
 }
 


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