[tracker/tracker-store-queue] Ported support for removable device to tracker-store



commit ac1db351fca74ec305c64436b75435a4b0badb92
Author: Philip Van Hoof <philip codeminded be>
Date:   Fri May 22 17:50:43 2009 +0200

    Ported support for removable device to tracker-store
---
 src/libtracker-data/tracker-data-update.c      |  110 --------
 src/tracker-indexer/tracker-removable-device.c |  182 ------------
 src/tracker-indexer/tracker-removable-device.h |    4 -
 src/tracker-store/Makefile.am                  |    4 +-
 src/tracker-store/tracker-removable-device.c   |  351 ++++++++++++++++++++++++
 src/tracker-store/tracker-removable-device.h   |   36 +++
 6 files changed, 390 insertions(+), 297 deletions(-)

diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index f907b58..d5dc8e2 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -77,12 +77,6 @@ struct _TrackerDataBlankBuffer {
 	GArray *objects;
 };
 
-typedef struct {
-	const gchar *uri;
-	TrackerLanguage *language;
-	TrackerConfig *config;
-} ForeachInMetadataInfo;
-
 
 static gint transaction_level = 0;
 static TrackerDataUpdateBuffer update_buffer;
@@ -1018,110 +1012,6 @@ tracker_data_delete_resource (const gchar     *uri)
 }
 
 static void
-foreach_in_metadata_set_metadata (gpointer      predicate,
-				  gpointer      value,
-				  gpointer      user_data)
-{
-	ForeachInMetadataInfo *info = user_data;
-	TrackerProperty *field;
-
-	field = tracker_ontology_get_property_by_uri (predicate);
-
-	if (!field)
-		return;
-
-	if (!value) {
-		tracker_data_delete_statement (info->uri, tracker_property_get_uri (field), NULL);
-	} else {
-		tracker_data_insert_statement (info->uri, tracker_property_get_uri (field), value);
-	}
-}
-
-void 
-tracker_data_update_replace_service (const gchar *uri,
-				     GHashTable  *metadata)
-{
-	TrackerDBInterface  *iface;
-	TrackerDBResultSet  *result_set;
-	const gchar         *modified;
-	GError              *error = NULL;
-	gchar               *escaped_uri;
-
-	g_return_if_fail (uri != NULL);
-	g_return_if_fail (metadata != NULL);
-
-	modified = g_hash_table_lookup (metadata, "resource:Modified");
-
-	if (!modified) {
-		return;
-	}
-
-	escaped_uri = tracker_escape_string (uri);
-
-	iface = tracker_db_manager_get_db_interface ();
-
-	result_set = tracker_db_interface_execute_query (iface, &error,
-							 "SELECT ID, \"tracker:modified\" < '%s' FROM \"rdfs:Resource\" "
-							 "WHERE Uri = '%s'",
-							 modified,
-							 escaped_uri);
-
-	g_hash_table_remove (metadata, "resource:Modified");
-
-	if (error) {
-		g_error_free (error);
-	}
-
-	if (result_set) {
-		GValue id_value = { 0, };
-		GValue is_value = { 0, };
-		gint   iid_value, iis_value;
-
-		_tracker_db_result_set_get_value (result_set, 0, &id_value);
-		iid_value = g_value_get_int (&id_value);
-
-		_tracker_db_result_set_get_value (result_set, 1, &is_value);
-		iis_value = g_value_get_int (&is_value);
-
-		if (iis_value) {
-			ForeachInMetadataInfo info;
-
-			info.uri = uri;
-
-			info.config = tracker_data_manager_get_config ();
-			info.language = tracker_data_manager_get_language ();
-
-			g_hash_table_foreach (metadata, 
-					      foreach_in_metadata_set_metadata,
-					      &info);
-		}
-
-		g_value_unset (&id_value);
-		g_value_unset (&is_value);
-
-		g_object_unref (result_set);
-	} else {
-		ForeachInMetadataInfo info;
-		guint32               id;
-
-		id = tracker_data_insert_resource (uri);
-
-		info.uri = uri;
-
-		info.config = tracker_data_manager_get_config ();
-		info.language = tracker_data_manager_get_language ();
-
-		g_hash_table_foreach (metadata, 
-				      foreach_in_metadata_set_metadata,
-				      &info);
-
-	}
-
-	g_free (escaped_uri);
-
-}
-
-static void
 db_set_volume_available (const gchar *uri,
                          gboolean     available)
 {
diff --git a/src/tracker-indexer/tracker-removable-device.c b/src/tracker-indexer/tracker-removable-device.c
index 71cafe3..028e423 100644
--- a/src/tracker-indexer/tracker-removable-device.c
+++ b/src/tracker-indexer/tracker-removable-device.c
@@ -43,194 +43,12 @@
 
 #include "tracker-module-metadata-private.h"
 
-typedef struct {
-	gchar *last_subject;
-	gchar *base;
-	guint amount;
-	TrackerIndexer *indexer;
-	GHashTable *metadata;
-} TurtleStorerInfo;
-
-typedef enum {
-	REMOVAL,
-	REPLACE,
-	MOVE
-} StorerTask;
 
 typedef struct {
 	raptor_serializer *serializer;
 	gchar *about_uri;
 } AddMetadataInfo;
 
-static void
-commit_turtle_parse_info_storer (TurtleStorerInfo *info, 
-				 gboolean          may_flush, 
-				 StorerTask        task,
-				 const gchar      *destination)
-{
-	if (info->last_subject) {
-		switch (task) {
-		    case REMOVAL:
-			tracker_data_delete_resource (info->last_subject);
-		    break;
-		    case MOVE:
-			tracker_data_delete_resource (info->last_subject);
-			tracker_data_update_replace_service (destination, 
-							     info->metadata);
-		    break;
-		    default:
-		    case REPLACE:
-			tracker_data_update_replace_service (info->last_subject, 
-							     info->metadata);
-		    break;
-		}
-
-		info->amount++;
-
-		g_hash_table_destroy (info->metadata);
-		g_free (info->last_subject);
-		info->last_subject = NULL;
-		info->metadata = NULL;
-	}
-
-	/* We commit per transaction of TRACKER_INDEXER_TRANSACTION_MAX here, 
-	 * and then we also iterate the mainloop so that the state-machine 
-	 * gets the opportunity to run for a moment */
-
-	if (may_flush && info->amount > TRACKER_INDEXER_TRANSACTION_MAX) {
-		tracker_indexer_transaction_commit (info->indexer);
-		g_main_context_iteration (NULL, FALSE);
-		tracker_indexer_transaction_open (info->indexer);
-		info->amount = 0;
-	}
-}
-
-static void
-consume_triple_storer (const gchar *subject,
-                       const gchar *predicate,
-                       const gchar *object,
-                       void        *user_data) 
-{
-	TurtleStorerInfo *info = user_data;
-
-	if (!object || !predicate)
-		return;
-
-	if (g_strcmp0 (subject, info->last_subject) != 0) {
-		/* Commit previous subject */
-		commit_turtle_parse_info_storer (info, TRUE, REPLACE, NULL);
-
-		/* Install next subject */
-		info->last_subject = g_strdup (subject);
-		info->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
-							(GDestroyNotify) g_free,
-							(GDestroyNotify) g_free);
-	}
-
-	if (object[0] == '\0' && predicate[0] == '\0') {
-		/* <URI> <rdf:type> "Type" ;                    *
-		 *       <> <>  -  is a removal of the resource */
-
-		/* We commit this subject as a removal, the last_subject
-		 * field will be cleared for the next subject to be set
-		 * ready first next process loop. */
-
-		commit_turtle_parse_info_storer (info, FALSE, REMOVAL, NULL);
-	} else
-	if (object[0] == '\0' && predicate[0] != '\0') {
-		/* <URI> <rdf:type> "Type" ;                             *
-		 *       <Pfx:Predicate> <>  -  is a removal of the      * 
-		 *                              resource's Pfx:Predicate */
-
-		/* We put NULL here, so that a null value goes into 
-		 * SQLite. Perhaps we should change this? If so, Why? */
-
-		g_hash_table_replace (info->metadata,
-				      g_strdup (predicate),
-				      NULL);
-	} else
-	if (object[0] != '\0' && predicate[0] == '\0') {
-		/* <URI> <> <to-URI>  -  is a move of the subject */
-		commit_turtle_parse_info_storer (info, FALSE, MOVE, object);
-	} else {
-		g_hash_table_replace  (info->metadata,
-				       g_strdup (predicate),
-				       g_strdup (object));
-	}
-}
-
-void
-tracker_removable_device_optimize (TrackerIndexer *indexer,
-				   const gchar    *mount_point)
-{
-	gchar *file;
-
-	file = g_build_filename (mount_point,
-				 ".cache", 
-				 "metadata",
-				 "metadata.ttl", 
-				 NULL);
-
-	if (g_file_test (file, G_FILE_TEST_EXISTS)) {
-		tracker_turtle_optimize (file);
-	}
-
-	g_free (file);
-}
-
-void
-tracker_removable_device_load (TrackerIndexer *indexer,
-			       const gchar    *mount_point)
-{
-	gchar *filename;
-
-	filename = g_build_filename (mount_point,
-				     ".cache", 
-				     "metadata",
-				     "metadata.ttl", 
-				     NULL);
-
-	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
-		TurtleStorerInfo  info;
-		gchar            *base_uri, *tmp;
-		GFile            *mountp_file;
-
-		info.indexer = g_object_ref (indexer);
-		info.amount = 0;
-
-		info.base = g_strdup (mount_point);
-
-		/* We need to open the transaction, during the parsing will the
-		 * transaction be committed and reopened */
-
-		tracker_indexer_transaction_open (info.indexer);
-
-		mountp_file = g_file_new_for_path (mount_point);
-		tmp = g_file_get_uri (mountp_file);
-		base_uri = g_strconcat (tmp, "/", NULL);
-
-		tracker_turtle_process (filename, base_uri, consume_triple_storer, &info);
-
-		g_free (base_uri);
-		g_free (tmp);
-		g_object_unref (mountp_file);
-
-		/* Commit final subject (our loop doesn't handle the very last) 
-		 * It can't be a REMOVAL nor MOVE as those happen immediately. */
-
-		commit_turtle_parse_info_storer (&info, FALSE, REPLACE, NULL);
-
-		/* We will (always) be left in open state, so we commit the 
-		 * last opened transaction */
-
-		tracker_indexer_transaction_commit (info.indexer);
-
-		g_free (info.base);
-		g_object_unref (info.indexer);
-	}
-
-	g_free (filename);
-}
 
 static void
 set_metadata (const gchar *key, 
diff --git a/src/tracker-indexer/tracker-removable-device.h b/src/tracker-indexer/tracker-removable-device.h
index 07fee0b..dc86bd4 100644
--- a/src/tracker-indexer/tracker-removable-device.h
+++ b/src/tracker-indexer/tracker-removable-device.h
@@ -28,10 +28,6 @@
 
 G_BEGIN_DECLS
 
-void    tracker_removable_device_load         (TrackerIndexer *indexer, 
-					       const gchar *mount_point);
-void    tracker_removable_device_optimize     (TrackerIndexer *indexer, 
-					       const gchar *mount_point);
 void    tracker_removable_device_add_metadata (TrackerIndexer *indexer, 
 					       const gchar *mount_point,
 					       const gchar *uri,
diff --git a/src/tracker-store/Makefile.am b/src/tracker-store/Makefile.am
index 13d76f4..fd10eac 100644
--- a/src/tracker-store/Makefile.am
+++ b/src/tracker-store/Makefile.am
@@ -65,7 +65,9 @@ tracker_store_SOURCES =							\
 	tracker-resource-class.c					\
 	tracker-resource-class.h					\
 	tracker-store.c							\
-	tracker-store.h
+	tracker-store.h							\
+	tracker-removable-device.c					\
+	tracker-removable-device.h
 
 if OS_WIN32
 tracker_store_win_libs = -lws2_32 -lkernel32
diff --git a/src/tracker-store/tracker-removable-device.c b/src/tracker-store/tracker-removable-device.c
new file mode 100644
index 0000000..19c6736
--- /dev/null
+++ b/src/tracker-store/tracker-removable-device.c
@@ -0,0 +1,351 @@
+/* -*- 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.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+
+#include "config.h"
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/statvfs.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#include <gmodule.h>
+
+#include <raptor.h>
+
+#include <libtracker-data/tracker-data-query.h>
+#include <libtracker-data/tracker-data-update.h>
+#include <libtracker-db/tracker-db-manager.h>
+
+#include <libtracker-data/tracker-turtle.h>
+
+#include "tracker-removable-device.h"
+#include "tracker-store.h"
+
+typedef struct {
+	gchar *last_subject;
+	gchar *base;
+	guint amount;
+	GHashTable *metadata;
+} TurtleStorerInfo;
+
+typedef enum {
+	REMOVAL,
+	REPLACE,
+	MOVE
+} StorerTask;
+
+typedef struct {
+	gchar *destination;
+	GHashTable *metadata;
+} MoveInfo;
+
+static void
+foreach_in_metadata_set_metadata (gpointer      predicate,
+				  gpointer      value,
+				  gpointer      user_data)
+{
+	const gchar *uri = user_data;
+	TrackerProperty *field;
+	const gchar *pred_uri;
+
+	field = tracker_ontology_get_property_by_uri (predicate);
+
+	if (!field)
+		return;
+
+	pred_uri = tracker_property_get_uri (field);
+
+	if (!value) {
+		
+		gchar *query = g_strdup_printf ("DELETE { <%s> <%s> ?o } WHERE { <%s> <%s> ?o }",
+		                                uri, pred_uri,
+		                                uri, pred_uri);
+		tracker_store_queue_sparql_update (query, NULL, NULL, NULL);
+		g_free (query);
+	} else {
+		tracker_store_queue_insert_statement (uri, pred_uri, value, 
+		                                      NULL, NULL, NULL);
+	}
+}
+
+static void 
+replace_service (const gchar *uri,
+		 GHashTable  *metadata)
+{
+	TrackerDBResultSet  *result_set;
+	GError        *error = NULL;
+	gchar         *escaped_uri;
+	gchar         *query;
+
+	g_return_if_fail (uri != NULL);
+	g_return_if_fail (metadata != NULL);
+
+
+	escaped_uri = tracker_escape_string (uri);
+
+	query = g_strdup_printf ("SELECT ?t WHERE { <%s> tracker:modified ?t }",
+	                         escaped_uri);
+
+	result_set = tracker_store_sparql_query (query, &error);
+
+	g_free (query);
+
+	if (error) {
+		g_error_free (error);
+	}
+
+	if (result_set) {
+		GValue       vt_value = { 0, };
+		const gchar *t_value;
+		const gchar *modified;
+
+		_tracker_db_result_set_get_value (result_set, 0, &vt_value);
+		t_value = g_value_get_string (&vt_value);
+
+		modified = g_hash_table_lookup (metadata, "resource:Modified");
+
+		if (g_strcmp0 (t_value, modified) < 0) {
+			g_hash_table_remove (metadata, "resource:Modified");
+
+			g_hash_table_foreach (metadata, 
+					      foreach_in_metadata_set_metadata,
+					      (gpointer) uri);
+		}
+
+		g_value_unset (&vt_value);
+		g_object_unref (result_set);
+
+	} else {
+
+		g_hash_table_remove (metadata, "resource:Modified");
+
+		g_hash_table_foreach (metadata, 
+				      foreach_in_metadata_set_metadata,
+				      (gpointer) uri);
+	}
+
+	g_free (escaped_uri);
+
+}
+
+
+static void
+free_move_info (gpointer user_data)
+{
+	MoveInfo *move_info = user_data;
+	g_free (move_info->destination);
+	g_hash_table_unref (move_info->metadata);
+	g_slice_free (MoveInfo, move_info);
+}
+
+static void
+move_on_deleted (GError *error, gpointer user_data)
+{
+	if (!error) {
+		MoveInfo *move_info = user_data;
+		replace_service (move_info->destination, 
+		                 move_info->metadata);
+	}
+}
+
+static void
+commit_turtle_parse_info_storer (TurtleStorerInfo *info, 
+				 gboolean          may_flush, 
+				 StorerTask        task,
+				 const gchar      *destination)
+{
+	if (info->last_subject) {
+		MoveInfo *move_info;
+		gchar *sparql = NULL;
+
+		switch (task) {
+		    case REMOVAL:
+			sparql = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }", info->last_subject);
+			tracker_store_queue_sparql_update (sparql, NULL, NULL, NULL);
+			g_free (sparql);
+		    break;
+		    case MOVE:
+
+			move_info = g_slice_new (MoveInfo);
+			move_info->destination = g_strdup (destination);
+			move_info->metadata = g_hash_table_ref (info->metadata);
+
+			sparql = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }", info->last_subject);
+			tracker_store_queue_sparql_update (sparql, move_on_deleted,
+			                                   move_info, 
+			                                   free_move_info);
+			g_free (sparql);
+
+		    break;
+		    default:
+		    case REPLACE:
+			replace_service (info->last_subject, 
+			                 info->metadata);
+		    break;
+		}
+
+		info->amount++;
+
+		g_hash_table_unref (info->metadata);
+		g_free (info->last_subject);
+		info->last_subject = NULL;
+		info->metadata = NULL;
+	}
+}
+
+static void
+consume_triple_storer (const gchar *subject,
+                       const gchar *predicate,
+                       const gchar *object,
+                       void        *user_data) 
+{
+	TurtleStorerInfo *info = user_data;
+
+	if (!object || !predicate)
+		return;
+
+	if (g_strcmp0 (subject, info->last_subject) != 0) {
+		/* Commit previous subject */
+		commit_turtle_parse_info_storer (info, TRUE, REPLACE, NULL);
+
+		/* Install next subject */
+		info->last_subject = g_strdup (subject);
+		info->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
+							(GDestroyNotify) g_free,
+							(GDestroyNotify) g_free);
+	}
+
+	if (object[0] == '\0' && predicate[0] == '\0') {
+		/* <URI> <rdf:type> "Type" ;                    *
+		 *       <> <>  -  is a removal of the resource */
+
+		/* We commit this subject as a removal, the last_subject
+		 * field will be cleared for the next subject to be set
+		 * ready first next process loop. */
+
+		commit_turtle_parse_info_storer (info, FALSE, REMOVAL, NULL);
+	} else
+	if (object[0] == '\0' && predicate[0] != '\0') {
+		/* <URI> <rdf:type> "Type" ;                             *
+		 *       <Pfx:Predicate> <>  -  is a removal of the      * 
+		 *                              resource's Pfx:Predicate */
+
+		/* We put NULL here, so that a null value goes into 
+		 * SQLite. Perhaps we should change this? If so, Why? */
+
+		g_hash_table_replace (info->metadata,
+				      g_strdup (predicate),
+				      NULL);
+	} else
+	if (object[0] != '\0' && predicate[0] == '\0') {
+		/* <URI> <> <to-URI>  -  is a move of the subject */
+		commit_turtle_parse_info_storer (info, FALSE, MOVE, object);
+	} else {
+		g_hash_table_replace  (info->metadata,
+				       g_strdup (predicate),
+				       g_strdup (object));
+	}
+}
+
+static gboolean
+process_turtle_idle (gpointer user_data)
+{
+	guint i = 0;
+	gboolean cont = FALSE;
+
+	while (tracker_turtle_reader_next ()) {
+		const gchar *subject = tracker_turtle_reader_get_subject ();
+		const gchar *predicate = tracker_turtle_reader_get_predicate ();
+		const gchar *object_ = tracker_turtle_reader_get_object ();
+
+		if (subject && predicate && object_) {
+			consume_triple_storer (subject, predicate, object_, 
+			                       user_data);
+		}
+
+		cont = TRUE;
+
+		if (i > 100) {
+			break;
+		}
+
+		i++;
+	}
+
+	return cont;
+}
+
+static void
+process_turtle_destroy (gpointer user_data)
+{
+	TurtleStorerInfo *info = user_data;
+
+	commit_turtle_parse_info_storer (info, FALSE, REPLACE, NULL);
+
+	tracker_store_queue_commit (NULL, NULL, NULL);
+
+	g_free (info->base);
+	g_free (info);
+}
+
+void
+tracker_removable_device_load (const gchar    *mount_point)
+{
+	gchar *filename;
+
+	filename = g_build_filename (mount_point,
+				     ".cache", 
+				     "metadata",
+				     "metadata.ttl", 
+				     NULL);
+
+	if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+		TurtleStorerInfo *info;
+		gchar            *base_uri, *tmp;
+		GFile            *mountp_file;
+
+		info = g_new0 (TurtleStorerInfo, 1);
+
+		info->amount = 0;
+		info->base = g_strdup (mount_point);
+
+		mountp_file = g_file_new_for_path (mount_point);
+		tmp = g_file_get_uri (mountp_file);
+		base_uri = g_strconcat (tmp, "/", NULL);
+
+		tracker_turtle_reader_init (filename, base_uri);
+
+		g_idle_add_full (G_PRIORITY_DEFAULT,
+		                 process_turtle_idle,
+		                 info,
+		                 process_turtle_destroy);
+
+		g_free (base_uri);
+		g_free (tmp);
+		g_object_unref (mountp_file);
+	}
+
+	g_free (filename);
+}
diff --git a/src/tracker-store/tracker-removable-device.h b/src/tracker-store/tracker-removable-device.h
new file mode 100644
index 0000000..6f9b0bc
--- /dev/null
+++ b/src/tracker-store/tracker-removable-device.h
@@ -0,0 +1,36 @@
+/* -*- 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.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+
+#ifndef __TRACKER_REMOVABLE_DEVICE_H__
+#define __TRACKER_REMOVABLE_DEVICE_H__
+
+
+G_BEGIN_DECLS
+
+void    tracker_removable_device_load         (const gchar *mount_point);
+
+G_END_DECLS
+
+#endif /* __TRACKER_REMOVABLE_DEVICE_H__ */
+
+
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]