[gnome-photos/wip/rishi/unbreak-delete] Unbreak deletion of items from the Tracker database
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos/wip/rishi/unbreak-delete] Unbreak deletion of items from the Tracker database
- Date: Sun, 14 Mar 2021 15:08:19 +0000 (UTC)
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]