[tracker/writeback: 2/8] Signalling Writeback in case a property marked as tracker:writeback is changed



commit 9438615929171b07e00c8f4d809d302ef4805ebb
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       |    4 +
 data/ontologies/90-tracker.ontology   |   16 +++-
 src/tracker-store/Makefile.am         |    2 +
 src/tracker-store/tracker-events.c    |    4 +
 src/tracker-store/tracker-main.c      |   23 +++++
 src/tracker-store/tracker-resources.c |   47 ++++++++-
 src/tracker-store/tracker-resources.h |    5 +-
 src/tracker-store/tracker-writeback.c |  170 +++++++++++++++++++++++++++++++++
 src/tracker-store/tracker-writeback.h |   44 +++++++++
 9 files changed, 308 insertions(+), 7 deletions(-)
---
diff --git a/data/dbus/tracker-resources.xml b/data/dbus/tracker-resources.xml
index 7b28ac5..39aa927 100644
--- a/data/dbus/tracker-resources.xml
+++ b/data/dbus/tracker-resources.xml
@@ -37,5 +37,9 @@
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
     </method>
 
+   <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-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..2cfc34d 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,13 @@ 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 {
+	WRITEBACK,
+	LAST_SIGNAL
+};
 
 typedef struct {
-	GSList     *event_sources;
+	GSList *event_sources;
 } TrackerResourcesPrivate;
 
 typedef struct {
@@ -61,6 +66,9 @@ typedef struct {
 	guint request_id;
 } TrackerDBusMethodInfo;
 
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
 static void
 free_event_sources (TrackerResourcesPrivate *priv)
 {
@@ -94,6 +102,16 @@ tracker_resources_class_init (TrackerResourcesClass *klass)
 
 	object_class->finalize = tracker_resources_finalize;
 
+	signals[WRITEBACK] =
+		g_signal_new ("writeback",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (TrackerResourcesClass, writeback),
+			      NULL, NULL,
+			      tracker_marshal_VOID__BOXED,
+			      G_TYPE_NONE, 1,
+			      G_TYPE_STRV);
+
 	g_type_class_add_private (object_class, sizeof (TrackerResourcesPrivate));
 }
 
@@ -346,15 +364,18 @@ tracker_resources_batch_commit (TrackerResources	 *self,
 static void
 on_statements_committed (gpointer user_data)
 {
+	TrackerResources *resources = user_data;
 	GPtrArray *events;
+	const gchar **writebacks;
 	TrackerResourcesPrivate *priv;
 
-	priv = TRACKER_RESOURCES_GET_PRIVATE (user_data);
+	priv = TRACKER_RESOURCES_GET_PRIVATE (resources);
 
 	/* For more information about this call, look at the function end_batch
 	 * of tracker-store.c */
 	tracker_store_flush_journal ();
 
+	/* Class signals feature */
 	events = tracker_events_get_pending ();
 
 	if (events) {
@@ -362,7 +383,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 +420,17 @@ on_statements_committed (gpointer user_data)
 	}
 
 	tracker_events_reset ();
+
+	/* Writeback feature */
+	writebacks = tracker_writeback_get_pending ();
+
+	if (writebacks) {
+		g_signal_emit (resources, signals[WRITEBACK], 0, writebacks);
+		g_free (writebacks);
+
+	}
+
+	tracker_writeback_reset ();
 }
 
 
@@ -406,6 +438,7 @@ static void
 on_statements_rolled_back (gpointer user_data)
 {
 	tracker_events_reset ();
+	tracker_writeback_reset ();
 }
 
 static void
@@ -421,6 +454,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 +472,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 +501,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..9eff7fa 100644
--- a/src/tracker-store/tracker-resources.h
+++ b/src/tracker-store/tracker-resources.h
@@ -46,6 +46,9 @@ struct TrackerResources {
 
 struct TrackerResourcesClass {
 	GObjectClass parent;
+
+	void     (*writeback)                          (TrackerResources *resources,
+	                                                GStrv subjects);
 };
 
 GType             tracker_resources_get_type            (void);
@@ -75,7 +78,7 @@ void              tracker_resources_batch_sparql_update (TrackerResources
 void              tracker_resources_batch_commit        (TrackerResources       *object,
 							 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..78619c8
--- /dev/null
+++ b/src/tracker-store/tracker-writeback.c
@@ -0,0 +1,170 @@
+/* -*- 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;
+	GHashTable *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_hash_table_new_full (g_str_hash, g_str_equal,
+			                                         (GDestroyNotify) g_free,
+			                                         NULL);
+		}
+		g_hash_table_insert (private->events, g_strdup (subject),
+		                     GINT_TO_POINTER (TRUE));
+	}
+}
+
+void 
+tracker_writeback_reset (void)
+{
+	WritebackPrivate *private;
+
+	private = g_static_private_get (&private_key);
+	g_return_if_fail (private != NULL);
+
+	if (private->events) {
+		g_hash_table_unref (private->events);
+		private->events = NULL;
+	}
+}
+
+const gchar **
+tracker_writeback_get_pending (void)
+{
+	WritebackPrivate *private;
+	GHashTableIter iter;
+	gpointer key, value;
+	const gchar **writebacks = NULL;
+	guint i = 0;
+
+	private = g_static_private_get (&private_key);
+	g_return_val_if_fail (private != NULL, NULL);
+
+	if (private->events) {
+		writebacks = g_new0 (const gchar *, g_hash_table_size (private->events) + 1);
+		g_hash_table_iter_init (&iter, private->events);
+
+		while (g_hash_table_iter_next (&iter, &key, &value)) {
+			writebacks[i++] = (gchar *) key;
+		}
+	}
+
+	return writebacks;
+}
+
+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..6e7ac6f
--- /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);
+const gchar **  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]