[tracker/writeback: 23/23] Signalling Writeback in case a property marked as tracker:writeback is changed
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/writeback: 23/23] Signalling Writeback in case a property marked as tracker:writeback is changed
- Date: Fri, 6 Nov 2009 12:30:44 +0000 (UTC)
commit 4fa1135afb704b84395d946960214d2282d5f8ad
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Nov 6 13:28:46 2009 +0100
Signalling Writeback in case a property marked as tracker:writeback is changed
data/dbus/tracker-resources.xml | 12 ++
data/ontologies/90-tracker.ontology | 16 +++-
src/tracker-store/Makefile.am | 2 +
src/tracker-store/tracker-dbus.c | 2 +-
src/tracker-store/tracker-events.c | 4 +
src/tracker-store/tracker-main.c | 23 ++++
src/tracker-store/tracker-resources.c | 196 ++++++++++++++++++++++++++++++++-
src/tracker-store/tracker-resources.h | 8 +-
src/tracker-store/tracker-writeback.c | 158 ++++++++++++++++++++++++++
src/tracker-store/tracker-writeback.h | 44 ++++++++
10 files changed, 455 insertions(+), 10 deletions(-)
---
diff --git a/data/dbus/tracker-resources.xml b/data/dbus/tracker-resources.xml
index 7b28ac5..fdefb49 100644
--- a/data/dbus/tracker-resources.xml
+++ b/data/dbus/tracker-resources.xml
@@ -37,5 +37,17 @@
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
</method>
+ <!-- Register yourself for Writeback signals -->
+ <method name="RegisterWriteback">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+ <arg type="s" name="object_path" direction="in" />
+ </method>
+
+<!-- This is a private signal
+ <signal name="Writeback">
+ <arg type="as" name="subjects" />
+ </signal>
+-->
+
</interface>
</node>
diff --git a/data/ontologies/90-tracker.ontology b/data/ontologies/90-tracker.ontology
index c15cb5c..709a9a1 100644
--- a/data/ontologies/90-tracker.ontology
+++ b/data/ontologies/90-tracker.ontology
@@ -41,8 +41,20 @@ tracker:mountPoint a rdf:Property ;
tracker:available a rdf:Property ;
nrl:maxCardinality 1 ;
- rdfs:domain nie:DataObject ;
- rdfs:range xsd:boolean .
+ rdfs:domain nie:DataObject ;
+ rdfs:range xsd:boolean .
+
+tracker:writeback a rdf:Property ;
+ nrl:maxCardinality 1 ;
+ rdfs:domain rdf:Property ;
+ rdfs:range xsd:boolean .
+
+# Remove this afterward
+tracker:writebackTestField a rdf:Property ;
+ nrl:maxCardinality 1 ;
+ tracker:writeback true ;
+ rdfs:domain rdfs:Resource ;
+ rdfs:range xsd:string .
fts: a tracker:Namespace ;
tracker:prefix "fts" .
diff --git a/src/tracker-store/Makefile.am b/src/tracker-store/Makefile.am
index b712417..236cae4 100644
--- a/src/tracker-store/Makefile.am
+++ b/src/tracker-store/Makefile.am
@@ -35,6 +35,8 @@ tracker_store_SOURCES = \
tracker-dbus.h \
tracker-events.c \
tracker-events.h \
+ tracker-writeback.c \
+ tracker-writeback.h \
tracker-main.c \
tracker-resources.c \
tracker-resources.h \
diff --git a/src/tracker-store/tracker-dbus.c b/src/tracker-store/tracker-dbus.c
index 9c7b975..a5e1eaf 100644
--- a/src/tracker-store/tracker-dbus.c
+++ b/src/tracker-store/tracker-dbus.c
@@ -214,7 +214,7 @@ tracker_dbus_register_objects (void)
objects = g_slist_prepend (objects, object);
/* Add org.freedesktop.Tracker1.Resources */
- object = resources = tracker_resources_new ();
+ object = resources = tracker_resources_new (connection);
if (!object) {
g_critical ("Could not create TrackerResources object to register");
return FALSE;
diff --git a/src/tracker-store/tracker-events.c b/src/tracker-store/tracker-events.c
index cf30d0c..5a6de8e 100644
--- a/src/tracker-store/tracker-events.c
+++ b/src/tracker-store/tracker-events.c
@@ -201,6 +201,10 @@ tracker_events_init (TrackerNotifyClassGetter callback)
}
classes_to_signal = (*callback)();
+
+ if (!classes_to_signal)
+ return;
+
count = g_strv_length (classes_to_signal);
for (i = 0; i < count; i++) {
tracker_events_add_allow (classes_to_signal[i]);
diff --git a/src/tracker-store/tracker-main.c b/src/tracker-store/tracker-main.c
index b42dbcb..b12f546 100644
--- a/src/tracker-store/tracker-main.c
+++ b/src/tracker-store/tracker-main.c
@@ -53,6 +53,7 @@
#include "tracker-dbus.h"
#include "tracker-config.h"
#include "tracker-events.h"
+#include "tracker-writeback.h"
#include "tracker-push.h"
#include "tracker-backup.h"
#include "tracker-store.h"
@@ -288,6 +289,25 @@ get_notifiable_classes (void)
return classes_to_signal;
}
+
+static GStrv
+get_writeback_predicates (void)
+{
+ TrackerDBResultSet *result_set;
+ GStrv predicates_to_signal = NULL;
+
+ result_set = tracker_data_query_sparql ("SELECT ?predicate WHERE { ?predicate tracker:writeback true }", NULL);
+
+ if (result_set) {
+ guint count = 0;
+
+ predicates_to_signal = tracker_dbus_query_result_to_strv (result_set, 0, &count);
+ g_object_unref (result_set);
+ }
+
+ return predicates_to_signal;
+}
+
gint
main (gint argc, gchar *argv[])
{
@@ -418,6 +438,8 @@ main (gint argc, gchar *argv[])
}
tracker_events_init (get_notifiable_classes);
+ tracker_writeback_init (get_writeback_predicates);
+
tracker_push_init ();
g_message ("Waiting for D-Bus requests...");
@@ -447,6 +469,7 @@ shutdown:
/* Shutdown major subsystems */
tracker_push_shutdown ();
+ tracker_writeback_shutdown ();
tracker_events_shutdown ();
tracker_dbus_shutdown ();
diff --git a/src/tracker-store/tracker-resources.c b/src/tracker-store/tracker-resources.c
index 57833b1..0806a46 100644
--- a/src/tracker-store/tracker-resources.c
+++ b/src/tracker-store/tracker-resources.c
@@ -41,6 +41,7 @@
#include "tracker-resources.h"
#include "tracker-resource-class.h"
#include "tracker-events.h"
+#include "tracker-writeback.h"
#include "tracker-store.h"
#define RDF_PREFIX TRACKER_RDF_PREFIX
@@ -51,9 +52,15 @@ G_DEFINE_TYPE(TrackerResources, tracker_resources, G_TYPE_OBJECT)
#define TRACKER_RESOURCES_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_RESOURCES, TrackerResourcesPrivate))
+enum {
+ PROP_0,
+ PROP_CONNECTION
+};
typedef struct {
- GSList *event_sources;
+ GSList *event_sources;
+ GPtrArray *writeback_destinations;
+ DBusGConnection *connection;
} TrackerResourcesPrivate;
typedef struct {
@@ -80,11 +87,55 @@ tracker_resources_finalize (GObject *object)
priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+ dbus_g_connection_unref (priv->connection);
+
free_event_sources (priv);
G_OBJECT_CLASS (tracker_resources_parent_class)->finalize (object);
}
+
+static void
+tracker_resources_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerResourcesPrivate *priv;
+
+ priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ priv->connection = dbus_g_connection_ref (g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tracker_resources_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerResourcesPrivate *priv;
+
+ priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ g_value_set_pointer (value, priv->connection);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
static void
tracker_resources_class_init (TrackerResourcesClass *klass)
{
@@ -93,6 +144,15 @@ tracker_resources_class_init (TrackerResourcesClass *klass)
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = tracker_resources_finalize;
+ object_class->get_property = tracker_resources_get_property;
+ object_class->set_property = tracker_resources_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_CONNECTION,
+ g_param_spec_pointer ("connection",
+ "connection",
+ "connection",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (object_class, sizeof (TrackerResourcesPrivate));
}
@@ -101,12 +161,19 @@ tracker_resources_class_init (TrackerResourcesClass *klass)
static void
tracker_resources_init (TrackerResources *object)
{
+ TrackerResourcesPrivate *priv;
+
+ priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+
+ priv->writeback_destinations = g_ptr_array_new ();
}
TrackerResources *
-tracker_resources_new (void)
+tracker_resources_new (DBusGConnection *connection)
{
- return g_object_new (TRACKER_TYPE_RESOURCES, NULL);
+ return g_object_new (TRACKER_TYPE_RESOURCES,
+ "connection", connection,
+ NULL);
}
/*
@@ -344,6 +411,56 @@ tracker_resources_batch_commit (TrackerResources *self,
static void
+tracker_resources_register_writeback_proxy_destroyed (DBusGProxy *proxy,
+ TrackerResources *object)
+{
+ TrackerResourcesPrivate *priv;
+
+ priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+
+ while (g_ptr_array_remove (priv->writeback_destinations, proxy)) {
+ /* Should we unref proxy here too? I think not. I think dbus-
+ * glib garbage collects it in a mainloop iteration. Right? */
+ }
+}
+
+void
+tracker_resources_register_writeback (TrackerResources *object,
+ const gchar *object_path,
+ DBusGMethodInvocation *context,
+ GError **error)
+{
+ TrackerResourcesPrivate *priv;
+ guint request_id;
+ gchar *sender;
+ DBusGProxy *proxy;
+
+ priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+
+ request_id = tracker_dbus_get_next_request_id ();
+
+ sender = dbus_g_method_get_sender (context);
+
+ tracker_dbus_request_new (request_id,
+ "D-Bus request for writeback registration: '%s'",
+ sender);
+
+ proxy = dbus_g_proxy_new_for_name (priv->connection,
+ sender,
+ object_path,
+ "org.freedesktop.Tracker1.WritebackRecipient");
+
+ g_ptr_array_add (priv->writeback_destinations, proxy);
+
+ g_signal_connect (proxy, "destroy",
+ G_CALLBACK (tracker_resources_register_writeback_proxy_destroyed),
+ object);
+
+ dbus_g_method_return (context);
+ tracker_dbus_request_success (request_id);
+}
+
+static void
on_statements_committed (gpointer user_data)
{
GPtrArray *events;
@@ -355,6 +472,7 @@ on_statements_committed (gpointer user_data)
* of tracker-store.c */
tracker_store_flush_journal ();
+ /* Class signals feature */
events = tracker_events_get_pending ();
if (events) {
@@ -362,7 +480,7 @@ on_statements_committed (gpointer user_data)
guint i;
GHashTable *to_emit = NULL;
- event_sources =priv->event_sources;
+ event_sources = priv->event_sources;
for (i = 0; i < events->len; i++) {
GValueArray *event = events->pdata[i];
@@ -399,6 +517,67 @@ on_statements_committed (gpointer user_data)
}
tracker_events_reset ();
+
+ /* Writeback feature */
+ events = tracker_writeback_get_pending ();
+
+ if (events) {
+ guint t;
+ DBusConnection *connection;
+
+ connection = dbus_g_connection_get_connection (priv->connection);
+
+ for (t = 0; t < priv->writeback_destinations->len; t++) {
+ const gchar *destination;
+ DBusMessageIter iter;
+ DBusMessageIter strv_iter;
+ DBusMessage *message;
+ guint n;
+ DBusGProxy *sender;
+
+ /* Get the destination, we do this to reduce broadcasted
+ * signal's DBus traffic. By setting destination we
+ * ensure that only the explicitly registered ones awake.
+ * This might be unnecessary, perhaps we can just do a
+ * broadcast signal instead too? */
+
+ sender = g_ptr_array_index (priv->writeback_destinations, t);
+ destination = dbus_g_proxy_get_bus_name (sender);
+
+ message = dbus_message_new_signal (TRACKER_RESOURCES_PATH,
+ TRACKER_RESOURCES_INTERFACE,
+ "Writeback");
+
+ /* The dbus-glib library can't do this yet, this is why
+ * you are seeing raw DBus API usage. No panic. */
+
+ dbus_message_set_destination (message, destination);
+
+ dbus_message_iter_init_append (message, &iter);
+
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &strv_iter);
+
+ for (n = 0; n < events->len; n++) {
+ const gchar *writeback_subject;
+
+ writeback_subject = g_ptr_array_index (events, n);
+
+ dbus_message_iter_append_basic (&strv_iter,
+ DBUS_TYPE_STRING,
+ &writeback_subject);
+ }
+
+ dbus_message_iter_close_container (&iter, &strv_iter);
+
+ dbus_connection_send (connection, message, NULL);
+
+ dbus_message_unref (message);
+ }
+ }
+
+ tracker_writeback_reset ();
}
@@ -406,6 +585,7 @@ static void
on_statements_rolled_back (gpointer user_data)
{
tracker_events_reset ();
+ tracker_writeback_reset ();
}
static void
@@ -421,6 +601,9 @@ on_statement_inserted (const gchar *graph,
} else {
tracker_events_insert (subject, predicate, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_UPDATE);
}
+
+ /* For predicates it's always update here */
+ tracker_writeback_check (graph, subject, predicate, object);
}
static void
@@ -436,8 +619,10 @@ on_statement_deleted (const gchar *graph,
} else {
tracker_events_insert (subject, predicate, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_UPDATE);
}
-}
+ /* For predicates it's always delete here */
+ tracker_writeback_check (graph, subject, predicate, object);
+}
void
tracker_resources_prepare (TrackerResources *object,
@@ -463,3 +648,4 @@ tracker_resources_unreg_batches (TrackerResources *object,
{
tracker_store_unreg_batches (old_owner);
}
+
diff --git a/src/tracker-store/tracker-resources.h b/src/tracker-store/tracker-resources.h
index aa135d7..a640c3d 100644
--- a/src/tracker-store/tracker-resources.h
+++ b/src/tracker-store/tracker-resources.h
@@ -49,7 +49,7 @@ struct TrackerResourcesClass {
};
GType tracker_resources_get_type (void);
-TrackerResources *tracker_resources_new (void);
+TrackerResources *tracker_resources_new (DBusGConnection *connection);
void tracker_resources_prepare (TrackerResources *object,
GSList *event_sources);
void tracker_resources_unreg_batches (TrackerResources *object,
@@ -75,7 +75,11 @@ void tracker_resources_batch_sparql_update (TrackerResources
void tracker_resources_batch_commit (TrackerResources *object,
DBusGMethodInvocation *context,
GError **error);
-
+void tracker_resources_register_writeback (TrackerResources *object,
+ const gchar *object_path,
+ DBusGMethodInvocation *context,
+ GError **error);
+
G_END_DECLS
#endif /* __TRACKER_STORE_RESOURCES_H__ */
diff --git a/src/tracker-store/tracker-writeback.c b/src/tracker-store/tracker-writeback.c
new file mode 100644
index 0000000..dcbae14
--- /dev/null
+++ b/src/tracker-store/tracker-writeback.c
@@ -0,0 +1,158 @@
+/* -*- 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-writeback.h"
+
+typedef struct {
+ GHashTable *allowances;
+ GPtrArray *events;
+} WritebackPrivate;
+
+static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT;
+
+static void
+tracker_writeback_add_allow (const gchar *predicate)
+{
+ WritebackPrivate *private;
+
+ private = g_static_private_get (&private_key);
+ g_return_if_fail (private != NULL);
+
+ g_hash_table_insert (private->allowances, g_strdup (predicate),
+ GINT_TO_POINTER (TRUE));
+}
+
+static gboolean
+is_allowed (WritebackPrivate *private, const gchar *rdf_predicate)
+{
+ return (g_hash_table_lookup (private->allowances, rdf_predicate) != NULL) ? TRUE : FALSE;
+}
+
+void
+tracker_writeback_check (const gchar *graph,
+ const gchar *subject,
+ const gchar *predicate,
+ const gchar *object)
+{
+ WritebackPrivate *private;
+
+ private = g_static_private_get (&private_key);
+ g_return_if_fail (private != NULL);
+
+ if (is_allowed (private, predicate)) {
+ if (!private->events)
+ private->events = g_ptr_array_new ();
+ g_ptr_array_add (private->events, g_strdup (subject));
+ }
+}
+
+void
+tracker_writeback_reset (void)
+{
+ WritebackPrivate *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_free (private->events->pdata[i]);
+ }
+ g_ptr_array_free (private->events, TRUE);
+
+ private->events = NULL;
+ }
+}
+
+GPtrArray *
+tracker_writeback_get_pending (void)
+{
+ WritebackPrivate *private;
+
+ private = g_static_private_get (&private_key);
+ g_return_val_if_fail (private != NULL, NULL);
+
+ return private->events;
+}
+
+static void
+free_private (WritebackPrivate *private)
+{
+ g_hash_table_unref (private->allowances);
+ g_free (private);
+}
+
+void
+tracker_writeback_init (TrackerWritebackPredicateGetter callback)
+{
+ WritebackPrivate *private;
+ GStrv predicates_to_signal;
+ gint i, count;
+
+ private = g_new0 (WritebackPrivate, 1);
+
+ g_static_private_set (&private_key,
+ private,
+ (GDestroyNotify) free_private);
+
+ private->allowances = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+
+ private->events = NULL;
+
+ if (!callback) {
+ return;
+ }
+
+ predicates_to_signal = (*callback)();
+
+ if (!predicates_to_signal)
+ return;
+
+ count = g_strv_length (predicates_to_signal);
+ for (i = 0; i < count; i++) {
+ tracker_writeback_add_allow (predicates_to_signal[i]);
+ }
+
+ g_strfreev (predicates_to_signal);
+}
+
+void
+tracker_writeback_shutdown (void)
+{
+ WritebackPrivate *private;
+
+ private = g_static_private_get (&private_key);
+ if (private != NULL) {
+ tracker_writeback_reset ();
+ g_static_private_set (&private_key, NULL, NULL);
+ } else {
+ g_warning ("tracker_writeback already shutdown");
+ }
+}
diff --git a/src/tracker-store/tracker-writeback.h b/src/tracker-store/tracker-writeback.h
new file mode 100644
index 0000000..4934f06
--- /dev/null
+++ b/src/tracker-store/tracker-writeback.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, 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_WRITEBACK_H__
+#define __TRACKER_WRITEBACK_H__
+
+#include <libtracker-common/tracker-dbus.h>
+
+G_BEGIN_DECLS
+
+typedef GStrv (*TrackerWritebackPredicateGetter) (void);
+
+void tracker_writeback_init (TrackerWritebackPredicateGetter callback);
+void tracker_writeback_shutdown (void);
+void tracker_writeback_check (const gchar *graph,
+ const gchar *subject,
+ const gchar *predicate,
+ const gchar *object);
+GPtrArray *tracker_writeback_get_pending (void);
+void tracker_writeback_reset (void);
+
+G_END_DECLS
+
+#endif /* __TRACKER_WRITEBACK_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]