[tracker/tracker-store] trackerd: Make class signals work when writes take place in trackerd
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker/tracker-store] trackerd: Make class signals work when writes take place in trackerd
- Date: Tue, 5 May 2009 06:33:03 -0400 (EDT)
commit 7559590a7b5cf6a7f3fc07ed0254199491b02916
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Apr 23 12:05:56 2009 +0200
trackerd: Make class signals work when writes take place in trackerd
---
src/tracker-indexer/tracker-events.c | 1 +
src/tracker-indexer/tracker-events.h | 2 +
src/trackerd/Makefile.am | 2 +
src/trackerd/tracker-events.c | 220 +++++++++++++++++++++++++++++++++
src/trackerd/tracker-events.h | 45 +++++++
src/trackerd/tracker-main.c | 24 ++++
src/trackerd/tracker-resource-class.c | 93 ++++++++++++++
7 files changed, 387 insertions(+), 0 deletions(-)
diff --git a/src/tracker-indexer/tracker-events.c b/src/tracker-indexer/tracker-events.c
index 1c2df13..e4ef793 100644
--- a/src/tracker-indexer/tracker-events.c
+++ b/src/tracker-indexer/tracker-events.c
@@ -27,6 +27,7 @@
#include "tracker-events.h"
+/* TODO: once all writes are vanished from tracker-indexer, this file can be removed */
typedef struct {
GPtrArray *allowances;
diff --git a/src/tracker-indexer/tracker-events.h b/src/tracker-indexer/tracker-events.h
index 9c0197a..fb1d04b 100644
--- a/src/tracker-indexer/tracker-events.h
+++ b/src/tracker-indexer/tracker-events.h
@@ -26,6 +26,8 @@
#include <libtracker-common/tracker-dbus.h>
+/* TODO: once all writes are vanished from tracker-indexer, this file can be removed */
+
G_BEGIN_DECLS
typedef GStrv (*TrackerNotifyClassGetter) (void);
diff --git a/src/trackerd/Makefile.am b/src/trackerd/Makefile.am
index f04fb33..53902d9 100644
--- a/src/trackerd/Makefile.am
+++ b/src/trackerd/Makefile.am
@@ -39,6 +39,8 @@ trackerd_SOURCES = \
tracker-daemon.h \
tracker-dbus.c \
tracker-dbus.h \
+ tracker-events.c \
+ tracker-events.h \
tracker-processor.c \
tracker-processor.h \
tracker-main.c \
diff --git a/src/trackerd/tracker-events.c b/src/trackerd/tracker-events.c
new file mode 100644
index 0000000..1c2df13
--- /dev/null
+++ b/src/trackerd/tracker-events.c
@@ -0,0 +1,220 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Philip Van Hoof <philip codeminded be>
+ */
+
+#include "config.h"
+
+#include <libtracker-common/tracker-ontology.h>
+
+#include "tracker-events.h"
+
+
+typedef struct {
+ GPtrArray *allowances;
+ GPtrArray *events;
+} EventsPrivate;
+
+static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT;
+
+static void
+tracker_events_add_allow (const gchar *rdf_class)
+{
+ EventsPrivate *private;
+
+ private = g_static_private_get (&private_key);
+ g_return_if_fail (private != NULL);
+
+ g_ptr_array_add (private->allowances, g_strdup (rdf_class));
+}
+
+static gboolean
+is_allowed (EventsPrivate *private, const gchar *rdf_class)
+{
+ guint i;
+ gboolean found = FALSE;
+
+ for (i = 0; i < private->allowances->len; i++) {
+ if (g_strcmp0 (rdf_class, private->allowances->pdata[i]) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ return found;
+}
+
+typedef struct {
+ const gchar *uri;
+ TrackerDBusEventsType type;
+} PreparableEvent;
+
+static void
+prepare_event_for_rdf_types (gpointer data, gpointer user_data)
+{
+ const gchar *rdf_class = data;
+ PreparableEvent *info = user_data;
+ const gchar *uri = info->uri;
+ TrackerDBusEventsType type = info->type;
+
+ EventsPrivate *private;
+ GValueArray *event;
+ GValue uri_value = { 0 , };
+ GValue rdfclass_value = { 0 , };
+ GValue type_value = { 0 , };
+
+ private = g_static_private_get (&private_key);
+ g_return_if_fail (private != NULL);
+
+ if (!is_allowed (private, rdf_class))
+ return;
+
+ if (!private->events) {
+ private->events = g_ptr_array_new ();
+ }
+
+ g_value_init (&uri_value, G_TYPE_STRING);
+ g_value_init (&rdfclass_value, G_TYPE_STRING);
+ g_value_init (&type_value, G_TYPE_INT);
+
+ event = g_value_array_new (3);
+
+ g_value_set_string (&uri_value, uri);
+ g_value_set_string (&rdfclass_value, rdf_class);
+ g_value_set_int (&type_value, type);
+
+ g_value_array_append (event, &uri_value);
+ g_value_array_append (event, &rdfclass_value);
+ g_value_array_append (event, &type_value);
+
+ g_ptr_array_add (private->events, event);
+
+ g_value_unset (&uri_value);
+ g_value_unset (&rdfclass_value);
+ g_value_unset (&type_value);
+}
+
+void
+tracker_events_insert (const gchar *uri,
+ const gchar *object,
+ GPtrArray *rdf_types,
+ TrackerDBusEventsType type)
+{
+ PreparableEvent info;
+
+ info.uri = uri;
+ info.type = type;
+
+ if (rdf_types && type == TRACKER_DBUS_EVENTS_TYPE_UPDATE) {
+ /* object is not very important for updates (we don't expose
+ * the value being set to the user's DBus API in trackerd) */
+ g_ptr_array_foreach (rdf_types, prepare_event_for_rdf_types, &info);
+ } else if (type == TRACKER_DBUS_EVENTS_TYPE_UPDATE) {
+ /* In this case we had an INSERT for a resource that didn't exist
+ * yet, but it was not the rdf:type predicate being inserted */
+ prepare_event_for_rdf_types ((gpointer) TRACKER_RDFS_PREFIX "Resource", &info);
+ } else {
+ /* In case of delete and create, object is the rdf:type */
+ prepare_event_for_rdf_types ((gpointer) object, &info);
+ }
+}
+
+void
+tracker_events_reset (void)
+{
+ EventsPrivate *private;
+ guint i;
+
+ private = g_static_private_get (&private_key);
+ g_return_if_fail (private != NULL);
+
+ if (private->events) {
+ for (i = 0; i < private->events->len; i++) {
+ g_value_array_free (private->events->pdata[i]);
+ }
+ g_ptr_array_free (private->events, TRUE);
+
+ private->events = NULL;
+ }
+}
+
+GPtrArray *
+tracker_events_get_pending (void)
+{
+ EventsPrivate *private;
+
+ private = g_static_private_get (&private_key);
+ g_return_val_if_fail (private != NULL, NULL);
+
+ return private->events;
+}
+
+static void
+free_private (EventsPrivate *private)
+{
+ g_ptr_array_foreach (private->allowances, (GFunc)g_free, NULL);
+ g_ptr_array_free (private->allowances, TRUE);
+ g_free (private);
+}
+
+void
+tracker_events_init (TrackerNotifyClassGetter callback)
+{
+ EventsPrivate *private;
+ GStrv classes_to_signal;
+ gint i, count;
+
+ private = g_new0 (EventsPrivate, 1);
+
+ g_static_private_set (&private_key,
+ private,
+ (GDestroyNotify) free_private);
+
+ private->allowances = g_ptr_array_new ();
+ private->events = NULL;
+
+ if (!callback) {
+ return;
+ }
+
+ classes_to_signal = (*callback)();
+ count = g_strv_length (classes_to_signal);
+ for (i = 0; i < count; i++) {
+ tracker_events_add_allow (classes_to_signal[i]);
+ }
+
+ g_strfreev (classes_to_signal);
+}
+
+void
+tracker_events_shutdown (void)
+{
+ EventsPrivate *private;
+
+ private = g_static_private_get (&private_key);
+ if (private != NULL) {
+ /* Shutdown with pending events = ERROR */
+ g_return_if_fail (private->events == NULL);
+ g_static_private_set (&private_key, NULL, NULL);
+ } else {
+ g_warning ("tracker_events already shutdown");
+ }
+}
diff --git a/src/trackerd/tracker-events.h b/src/trackerd/tracker-events.h
new file mode 100644
index 0000000..9c0197a
--- /dev/null
+++ b/src/trackerd/tracker-events.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Philip Van Hoof <philip codeminded be>
+ */
+
+#ifndef __TRACKER_INDEXER_EVENTS_H__
+#define __TRACKER_INDEXER_EVENTS_H__
+
+#include <libtracker-common/tracker-dbus.h>
+
+G_BEGIN_DECLS
+
+typedef GStrv (*TrackerNotifyClassGetter) (void);
+
+void tracker_events_init (TrackerNotifyClassGetter callback);
+void tracker_events_shutdown (void);
+void tracker_events_insert (const gchar *uri,
+ const gchar *object,
+ GPtrArray *rdf_types,
+ TrackerDBusEventsType type);
+GPtrArray *tracker_events_get_pending (void);
+void tracker_events_reset (void);
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_INDEXER_PUSH_H__ */
diff --git a/src/trackerd/tracker-main.c b/src/trackerd/tracker-main.c
index 5b986b7..4ec50fa 100644
--- a/src/trackerd/tracker-main.c
+++ b/src/trackerd/tracker-main.c
@@ -52,12 +52,15 @@
#include <libtracker-common/tracker-nfs-lock.h>
#include <libtracker-common/tracker-ontology.h>
#include <libtracker-common/tracker-thumbnailer.h>
+#include <libtracker-common/tracker-events.h>
#include <libtracker-db/tracker-db-manager.h>
+#include <libtracker-db/tracker-db-dbus.h>
#include <libtracker-data/tracker-data-manager.h>
#include <libtracker-data/tracker-turtle.h>
#include <libtracker-data/tracker-data-backup.h>
+#include <libtracker-data/tracker-data-query.h>
#include <tracker-push.h>
@@ -815,6 +818,25 @@ start_cb (gpointer user_data)
return FALSE;
}
+
+static GStrv
+tracker_daemon_get_notifiable_classes (void)
+{
+ TrackerDBResultSet *result_set;
+ GStrv classes_to_signal = NULL;
+
+ result_set = tracker_data_query_sparql ("SELECT ?class WHERE { ?class tracker:notify true }", NULL);
+
+ if (result_set) {
+ guint count = 0;
+
+ classes_to_signal = tracker_dbus_query_result_to_strv (result_set, 0, &count);
+ g_object_unref (result_set);
+ }
+
+ return classes_to_signal;
+}
+
gint
main (gint argc, gchar *argv[])
{
@@ -1026,6 +1048,7 @@ main (gint argc, gchar *argv[])
return EXIT_FAILURE;
}
+ tracker_events_init (tracker_daemon_get_notifiable_classes);
tracker_push_init (config);
g_message ("Waiting for DBus requests...");
@@ -1090,6 +1113,7 @@ main (gint argc, gchar *argv[])
/* Shutdown major subsystems */
tracker_push_shutdown ();
+ tracker_events_shutdown ();
tracker_volume_cleanup_shutdown ();
tracker_dbus_shutdown ();
diff --git a/src/trackerd/tracker-resource-class.c b/src/trackerd/tracker-resource-class.c
index 93ca6d3..cf42ed6 100644
--- a/src/trackerd/tracker-resource-class.c
+++ b/src/trackerd/tracker-resource-class.c
@@ -28,12 +28,31 @@
#include <libtracker-common/tracker-dbus.h>
#include <libtracker-common/tracker-config.h>
#include <libtracker-common/tracker-ontology.h>
+
#include <libtracker-db/tracker-db-dbus.h>
+#include <libtracker-data/tracker-data-update.h>
+
#include "tracker-dbus.h"
+#include "tracker-events.h"
#include "tracker-resource-class.h"
#include "tracker-marshal.h"
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_TYPE RDF_PREFIX "type"
+
+static void on_statements_committed (gpointer user_data);
+static void on_statement_inserted (const gchar *subject,
+ const gchar *predicate,
+ const gchar *object,
+ GPtrArray *rdf_types,
+ gpointer user_data);
+static void on_statement_deleted (const gchar *subject,
+ const gchar *predicate,
+ const gchar *object,
+ GPtrArray *rdf_types,
+ gpointer user_data);
+
#define TRACKER_RESOURCE_CLASS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_RESOURCE_CLASS, TrackerResourceClassPrivate))
typedef struct {
@@ -99,9 +118,15 @@ tracker_resource_class_class_init (TrackerResourceClassClass *klass)
g_type_class_add_private (object_class, sizeof (TrackerResourceClassPrivate));
}
+
+
+
static void
tracker_resource_class_init (TrackerResourceClass *object)
{
+ tracker_data_set_insert_statement_callback (on_statement_inserted, object);
+ tracker_data_set_delete_statement_callback (on_statement_deleted, object);
+ tracker_data_set_commit_statement_callback (on_statements_committed, object);
}
static void
@@ -230,3 +255,71 @@ tracker_resource_class_emit_events (TrackerResourceClass *object)
priv->dels = NULL;
}
}
+
+
+static void
+on_statements_committed (gpointer user_data)
+{
+ GPtrArray *events;
+
+ events = tracker_events_get_pending ();
+
+ if (events) {
+ GSList *event_sources, *l, *to_emit = NULL;
+ guint i;
+
+ for (i = 0; i < events->len; i++) {
+ GValueArray *event = events->pdata[i];
+ const gchar *uri = g_value_get_string (g_value_array_get_nth (event, 0));
+ const gchar *rdf_class = g_value_get_string (g_value_array_get_nth (event, 1));
+ TrackerDBusEventsType type = g_value_get_int (g_value_array_get_nth (event, 2));
+
+ for (l = event_sources; l; l = l->next) {
+ TrackerResourceClass *class_ = l->data;
+ if (g_strcmp0 (rdf_class, tracker_resource_class_get_rdf_class (class_)) == 0) {
+ tracker_resource_class_add_event (class_, uri, type);
+ to_emit = g_slist_prepend (to_emit, class_);
+ }
+ }
+ }
+
+ if (to_emit) {
+ for (l = to_emit; l; l = l->next) {
+ TrackerResourceClass *class_ = l->data;
+ tracker_resource_class_emit_events (class_);
+ }
+
+ g_slist_free (to_emit);
+ }
+ }
+
+ tracker_events_reset ();
+}
+
+static void
+on_statement_inserted (const gchar *subject,
+ const gchar *predicate,
+ const gchar *object,
+ GPtrArray *rdf_types,
+ gpointer user_data)
+{
+ if (g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
+ tracker_events_insert (subject, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_ADD);
+ } else {
+ tracker_events_insert (subject, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_UPDATE);
+ }
+}
+
+static void
+on_statement_deleted (const gchar *subject,
+ const gchar *predicate,
+ const gchar *object,
+ GPtrArray *rdf_types,
+ gpointer user_data)
+{
+ if (g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
+ tracker_events_insert (subject, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_DELETE);
+ } else {
+ tracker_events_insert (subject, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_UPDATE);
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]