[gnome-documents] miner: cleanup data from non-existent GOA accounts at startup
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-documents] miner: cleanup data from non-existent GOA accounts at startup
- Date: Thu, 15 Sep 2011 20:27:24 +0000 (UTC)
commit e4a8ef252ac0d37fbb8bd434b8b3e0a4ce655f8a
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu Sep 15 14:57:49 2011 -0400
miner: cleanup data from non-existent GOA accounts at startup
src/miner/gd-gdata-miner.c | 259 ++++++++++++++++++++++++++++++++++++++++----
1 files changed, 239 insertions(+), 20 deletions(-)
---
diff --git a/src/miner/gd-gdata-miner.c b/src/miner/gd-gdata-miner.c
index dd7d34c..e7cecf0 100644
--- a/src/miner/gd-gdata-miner.c
+++ b/src/miner/gd-gdata-miner.c
@@ -450,7 +450,6 @@ account_miner_job_cleanup_previous (AccountMinerJob *job,
GError **error)
{
GString *delete;
- GList *values;
delete = g_string_new (NULL);
g_string_append (delete, "DELETE { ");
@@ -729,7 +728,6 @@ account_miner_job_query_existing (AccountMinerJob *job,
{
GString *select;
TrackerSparqlCursor *cursor;
- gboolean valid;
select = g_string_new (NULL);
g_string_append_printf (select,
@@ -845,8 +843,6 @@ static void
gd_gdata_miner_complete_error (GdGDataMiner *self,
GError *error)
{
- GList *l;
-
g_assert (self->priv->result != NULL);
g_simple_async_result_take_error (self->priv->result, error);
@@ -898,6 +894,233 @@ gd_gdata_miner_setup_account (GdGDataMiner *self,
account_miner_job_process_async (job, miner_job_process_ready_cb, job);
}
+typedef struct {
+ GdGDataMiner *self;
+ GList *doc_objects;
+ GList *acc_objects;
+ GList *old_datasources;
+} CleanupJob;
+
+static gboolean
+cleanup_old_accounts_done (gpointer data)
+{
+ CleanupJob *job = data;
+ GList *l;
+ GoaObject *object;
+ GdGDataMiner *self = job->self;
+
+ /* now setup all the current accounts */
+ for (l = job->doc_objects; l != NULL; l = l->next)
+ {
+ object = l->data;
+ gd_gdata_miner_setup_account (self, object);
+
+ g_object_unref (object);
+ }
+
+ if (job->doc_objects != NULL)
+ {
+ g_list_free (job->doc_objects);
+ job->doc_objects = NULL;
+ }
+
+ if (job->acc_objects != NULL)
+ {
+ g_list_free_full (job->acc_objects, g_object_unref);
+ job->acc_objects = NULL;
+ }
+
+ if (job->old_datasources != NULL)
+ {
+ g_list_free_full (job->old_datasources, g_free);
+ job->old_datasources = NULL;
+ }
+
+ gd_gdata_miner_check_pending_jobs (self);
+
+ g_clear_object (&job->self);
+ g_slice_free (CleanupJob, job);
+
+ return FALSE;
+}
+
+static void
+cleanup_job_do_cleanup (CleanupJob *job)
+{
+ GdGDataMiner *self = job->self;
+ GString *select, *update;
+ gboolean append_union = FALSE;
+ GList *l;
+ TrackerSparqlCursor *cursor;
+ GError *error = NULL;
+ const gchar *resource;
+
+ if (job->old_datasources == NULL)
+ return;
+
+ update = g_string_new (NULL);
+ g_string_append (update, "DELETE { ");
+
+ /* select all documents from the datasources we want to remove */
+ select = g_string_new (NULL);
+ g_string_append (select, "SELECT ?urn WHERE { ");
+
+ for (l = job->old_datasources; l != NULL; l = l->next)
+ {
+ resource = l->data;
+ g_debug ("Cleaning up old datasource %s", resource);
+
+ if (append_union)
+ g_string_append (select, " UNION ");
+ else
+ append_union = TRUE;
+
+ g_string_append_printf (select, "{ ?urn nie:dataSource \"%s\" }", resource);
+
+ /* also append the datasource itself to the list of resources to delete */
+ g_string_append_printf (update, "<%s> a rdfs:Resource . ", resource);
+ }
+
+ g_string_append (select, " }");
+
+ cursor = tracker_sparql_connection_query (self->priv->connection,
+ select->str,
+ self->priv->cancellable,
+ &error);
+
+ g_string_free (select, TRUE);
+
+ if (error != NULL)
+ {
+ g_printerr ("Error while cleaning up old accounts: %s\n", error->message);
+ return;
+ }
+
+ /* gather all the documents we want to remove */
+ while (tracker_sparql_cursor_next (cursor, self->priv->cancellable, NULL))
+ {
+ resource = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+ g_debug ("Cleaning up resource %s belonging to an old datasource", resource);
+
+ if (resource != NULL)
+ g_string_append_printf (update, "<%s> a rdfs:Resource . ", resource);
+ }
+
+ g_string_append (update, " }");
+
+ /* actually remove everything we have to remove */
+ tracker_sparql_connection_update (self->priv->connection,
+ update->str,
+ G_PRIORITY_DEFAULT,
+ self->priv->cancellable,
+ &error);
+
+ g_string_free (update, TRUE);
+
+ if (error != NULL)
+ {
+ g_printerr ("Error while cleaning up old accounts: %s\n", error->message);
+ return;
+ }
+}
+
+static gint
+cleanup_datasource_compare (gconstpointer a,
+ gconstpointer b)
+{
+ GoaObject *object = GOA_OBJECT (a);
+ const gchar *datasource = b;
+ gint res;
+
+ GoaAccount *account;
+ gchar *object_datasource;
+
+ account = goa_object_peek_account (object);
+ g_assert (account != NULL);
+
+ object_datasource = g_strdup_printf ("gd:goa-account:%s", goa_account_get_id (account));
+ res = g_strcmp0 (datasource, object_datasource);
+
+ g_free (object_datasource);
+
+ return res;
+}
+
+static gboolean
+cleanup_job (GIOSchedulerJob *sched_job,
+ GCancellable *cancellable,
+ gpointer user_data)
+{
+ GString *select;
+ GError *error = NULL;
+ TrackerSparqlCursor *cursor;
+ const gchar *datasource;
+ GList *element;
+ CleanupJob *job = user_data;
+ GdGDataMiner *self = job->self;
+
+ /* find all our datasources in the tracker DB */
+ select = g_string_new (NULL);
+ g_string_append_printf (select, "SELECT ?datasource WHERE { ?datasource a nie:DataSource . "
+ "?datasource nao:identifier \"%s\" }", MINER_IDENTIFIER);
+
+ cursor = tracker_sparql_connection_query (self->priv->connection,
+ select->str,
+ self->priv->cancellable,
+ &error);
+ g_string_free (select, TRUE);
+
+ if (error != NULL)
+ {
+ g_printerr ("Error while cleaning up old accounts: %s\n", error->message);
+ goto out;
+ }
+
+ while (tracker_sparql_cursor_next (cursor, self->priv->cancellable, NULL))
+ {
+ /* If the source we found is not in the current list, add
+ * it to the cleanup list.
+ * Note that the objects here in the list might *not* support
+ * documents, in case the switch has been disabled in System Settings.
+ * In fact, we only remove all the account data in case the account
+ * is really removed from the panel.
+ */
+ datasource = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+ element = g_list_find_custom (job->acc_objects, datasource,
+ cleanup_datasource_compare);
+
+ if (element == NULL)
+ job->old_datasources = g_list_prepend (job->old_datasources,
+ g_strdup (datasource));
+ }
+
+ g_object_unref (cursor);
+
+ /* cleanup the DB */
+ cleanup_job_do_cleanup (job);
+
+ out:
+ g_io_scheduler_job_send_to_mainloop_async (sched_job,
+ cleanup_old_accounts_done, job, NULL);
+ return FALSE;
+}
+
+static void
+gd_gdata_miner_cleanup_old_accounts (GdGDataMiner *self,
+ GList *doc_objects,
+ GList *acc_objects)
+{
+ CleanupJob *job = g_slice_new0 (CleanupJob);
+
+ job->self = g_object_ref (self);
+ job->doc_objects = doc_objects;
+ job->acc_objects = acc_objects;
+
+ g_io_scheduler_push_job (cleanup_job, job, NULL,
+ G_PRIORITY_DEFAULT,
+ self->priv->cancellable);
+}
+
static void
client_ready_cb (GObject *source,
GAsyncResult *res,
@@ -909,8 +1132,7 @@ client_ready_cb (GObject *source,
GoaObject *object;
const gchar *provider_type;
GError *error = NULL;
- GList *accounts, *l;
- gboolean found = FALSE;
+ GList *accounts, *doc_objects, *acc_objects, *l;
self->priv->client = goa_client_new_finish (res, &error);
@@ -920,15 +1142,14 @@ client_ready_cb (GObject *source,
return;
}
+ doc_objects = NULL;
+ acc_objects = NULL;
+
accounts = goa_client_get_accounts (self->priv->client);
for (l = accounts; l != NULL; l = l->next)
{
object = l->data;
- documents = goa_object_peek_documents (object);
- if (documents == NULL)
- continue;
-
account = goa_object_peek_account (object);
if (account == NULL)
continue;
@@ -937,20 +1158,18 @@ client_ready_cb (GObject *source,
if (g_strcmp0 (provider_type, "google") != 0)
continue;
- found = TRUE;
- gd_gdata_miner_setup_account (self, object);
+ acc_objects = g_list_append (acc_objects, g_object_ref (object));
+
+ documents = goa_object_peek_documents (object);
+ if (documents == NULL)
+ continue;
+
+ doc_objects = g_list_append (doc_objects, g_object_ref (object));
}
g_list_free_full (accounts, g_object_unref);
- if (!found)
- {
- gd_gdata_miner_complete_error (self,
- g_error_new_literal (G_IO_ERROR,
- G_IO_ERROR_NOT_FOUND,
- "No GOA resource found supporting documents"));
- return;
- }
+ gd_gdata_miner_cleanup_old_accounts (self, doc_objects, acc_objects);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]