[tracker/tracker-store] Squashed commit of the following:



commit 18619659008587aff57937787ecf70e9a4adfb27
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed May 27 18:08:55 2009 +0200

    Squashed commit of the following:
    
    commit 14c608447fbcb146dfc41fb56d6eaa9960ad1b33
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Wed May 27 17:44:22 2009 +0200
    
        Merge fix for the push modules
    
        Reintroduced tracker_store_queue_insert_statement. We'll replace this API with
        tracker_store_queue_sparql_update and a query builder component afterwards.
    
    commit e6dcb8e8205377dc2925d1612c6e17b2ad2eb1d5
    Merge: d07d089 4d9f576
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Wed May 27 17:04:47 2009 +0200
    
        Merge branch 'tracker-store' into tracker-store-queue
    
        Conflicts:
        	src/tracker-indexer/tracker-indexer.c
        	src/tracker-indexer/tracker-indexer.h
        	src/tracker-indexer/tracker-removable-device.c
        	src/tracker-store/Makefile.am
        	src/tracker-store/tracker-resources.c
        	src/tracker-store/tracker-store.c
        	src/tracker-store/tracker-store.h
    
    commit 4d9f576d7c1b9189b4006aa4579067f1ed52572e
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Wed May 27 16:55:36 2009 +0200
    
        Ported push modules to TrackerStore API
    
    commit d07d0894eb9f0bf6c8558c0d7749635e09ec358e
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Tue May 26 17:21:01 2009 +0200
    
        Removed batch_count from push modules
    
    commit eb042c18b501fcc103682a03b8e6a339dd9ccea3
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Tue May 26 15:22:37 2009 +0200
    
        Silly copypaste bug, fixed
    
    commit d9b29d008b8a7b005eaad3b56c38043ba2320b4c
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Tue May 26 15:14:24 2009 +0200
    
        Bugfix setting tags of Evolution E-mail
    
        I also added assertions to avoid such bugs in future
    
    commit 72ca3a18a9377a5d69564ee05ae3a07dec2f14f0
    Author: Jürg Billeter <j bitron ch>
    Date:   Tue May 26 13:59:09 2009 +0200
    
        tracker-store: Fix transaction handling for non-batch updates
    
    commit 25039e79dab8c0502f48b05595df9d84ec5858f6
    Author: Jürg Billeter <j bitron ch>
    Date:   Tue May 26 13:48:18 2009 +0200
    
        tracker-resources.c: Fix leak and minimize differences to tracker-store
    
    commit cfa7c2506e0f1d1562d9e46e9a3a8aacd3499add
    Author: Jürg Billeter <j bitron ch>
    Date:   Tue May 26 13:45:48 2009 +0200
    
        configure.ac: Remove obsolete reference to rss plugin
    
    commit 7a31b5f5fa3bd96bc2693067a024683436d0df97
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Tue May 26 11:24:48 2009 +0200
    
        Fixed a bug in the idle handlers that distribute work
    
    commit 981a3e8ec6ab9e65c26254b831d8b3464b32b299
    Author: Jürg Billeter <j bitron ch>
    Date:   Mon May 25 18:50:11 2009 +0200
    
        tracker-turtle: Warn when trying to parse multiple files in parallel
    
    commit 1661838624637ba2da6a56baf041390f537b62eb
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Mon May 25 18:25:15 2009 +0200
    
        Added Turtle parsing to the queue
    
    commit 41db02c063b9a58fa1a4b3674e63df0b4a51d9ac
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Mon May 25 15:25:44 2009 +0200
    
        Cleanup should always be immediate
    
    commit 52057dca93e2f7116bb8ac8484c71d0f5a83bbe3
    Merge: a954013 4f56a11
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Mon May 25 15:19:05 2009 +0200
    
        Merge branch 'tracker-store' into tracker-store-queue
    
        Conflicts:
        	data/dbus/tracker-indexer.xml
    
    commit a9540137ff4cd88586a73c12fc6c6427896fdfcb
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Fri May 22 17:55:34 2009 +0200
    
        Removed support for NULL in tracker_data_delete_statement, not used anymore
    
    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
    
    commit 301ba0330cc2508eb4b984202893274c49daa44d
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Fri May 22 14:52:16 2009 +0200
    
        Jürg had the luminous idea to ask me to change the queue API a bit
    
        The changes include:
         - Rename TrackerStoreQueue to TrackerStore
         - Rename batch to queue
         - Don't put single update and single queries on the queue
         - Handle transaction-max in tracker-store.c, don't make the callers have
           to care about it
    
        This last one implied that I could remove most of the ++priv->batch_count
        callbacks from tracker-resource.c and that I had to fixup the push modules
        a bit too.
    
    commit d540caa4807ce086fd97b520185c87e87564e918
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Fri May 22 11:57:18 2009 +0200
    
        Sorting of the queue
    
        The updates, statement_insert, statement_delete and queries follow
        natural order in priority group. The batch_update, batch_statement_insert
        and batch_commit follow natural order in non-prioritized group.
    
        Sample order:
    
        query
        delete_statement
        query
        update
        insert_statement
        batch_update
        batch_update
        batch_insert_statement
        batch_update
        batch_commit
    
    commit f0db03a33a46665ecebc841251a30a4e2ac59851
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 21:34:31 2009 +0200
    
        Those commit callbacks where just wrong
    
    commit 42b58d6e0ea982879db8788ba691f1774d445feb
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 21:25:05 2009 +0200
    
        Doing the g_object_unref in the GDestroyNotify everywhere
    
    commit c3bb2243af0c58116cb89e7241ca493bf9250935
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 21:21:10 2009 +0200
    
        Fixed the push modules to yield to the GMainLoop while queuing up
    
    commit f95f031d4298010d2986ee68eebfbac4b306ce42
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 18:15:29 2009 +0200
    
        Fixed the TTL loader to yield to the GMainLoop while queuing up
    
    commit d73e18a022ac21072cb95f8ba40776c336caf5bd
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 17:28:11 2009 +0200
    
        Using insert_statement and delete_statement
    
        I can't use SPARQL's INSERT because it's not possible to reliably know
        whether object and predicate are either string formatted or URI
        formatted. Feel free to remove the extra API and replace it back to
        SPARQL INSERT and DELETE if you know how to quickly know how to format
        the query correctly.
    
    commit 4aa84d992982595db01607858c2bb059405cf0d7
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 14:55:49 2009 +0200
    
        Unset batch_mode when the TTL file is processed
    
    commit 0a0d7610c0b83ced289d5784df9b942e43f3d749
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 14:48:02 2009 +0200
    
        Removed TTL importer from the indexer
    
    commit 4c3040d60aa2438a771e875a081dee947dee4a23
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 14:44:48 2009 +0200
    
        Untested port of Turtle importer to tracker-store
    
    commit 96d0b0145f1137d30ecfa01550ca624f1c3f6336
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 14:19:24 2009 +0200
    
        Indentation
    
    commit 3055f2d8574503ec1462ed706994f099c26f572f
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 14:09:24 2009 +0200
    
        Obvious bugfix
    
    commit 7128821b779e2e127b20ccdbd92156672767556f
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 14:00:39 2009 +0200
    
        Wait before shutting down
    
    commit eec2f934741a84609a3786deb1ff3745a8d2792a
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 13:52:24 2009 +0200
    
        Added a TODO comment in TrackerStoreQueue
    
    commit a3cb7919fe3f7a1c1731bec9b571b96696a4c0b5
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 13:44:53 2009 +0200
    
        Ported the Push modules to the TrackerStoreQueue API
    
        This removes the RSS plugin as this was unused, and in future we
        probably want to provide a generic Nepomuk based push module, which a
        future RSS metadata deliverer should use.
    
    commit 26359f740c471bb73f9a3c43b421cc32713113f1
    Author: Philip Van Hoof <philip codeminded be>
    Date:   Thu May 21 10:40:37 2009 +0200
    
        Introduced TrackerStoreQueue, a queue for querying and updating
    
        TrackerStoreQueue is or will be the internal API for most data access and
        storage. This current implementation uses the GMainLoop and a  GQueue with no
        priority sorting whatsoever. At a later point in time we want to implement
        queue_sorter in a more meaningful way. For example meaning that batch_commits
        have precedence on all others, that queries get precedence after the batch
        commits, etcetera.
    
        Due to its use of the GMainLoop the API is going to block the mainloop, but it
        wont block the caller's code. It will instead find a nice slot during the
        GMainLoop the execute itself on. When finished it'll execute first your
        callback and then your GDestroyNotify. All parameters that you receive in the
        callback that aren't user_data must not be freed (they are to be considered
        read-only in your callback).
---
 configure.ac                                       |    4 +-
 .../evolution/tracker-evolution-registrar.c        |  335 +++++++++++++------
 src/plugins/kmail/tracker-kmail-registrar.c        |  295 ++++++++++++------
 src/tracker-indexer/tracker-removable-device.h     |    4 -
 src/tracker-store/tracker-removable-device.c       |  338 ++++++++++++++++++++
 src/tracker-store/tracker-removable-device.h       |   36 ++
 src/tracker-store/tracker-store.c                  |   58 ++++-
 src/tracker-store/tracker-store.h                  |    8 +
 8 files changed, 873 insertions(+), 205 deletions(-)

diff --git a/configure.ac b/configure.ac
index 88a1a02..81d998c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -621,14 +621,14 @@ AM_CONDITIONAL(HAVE_UNAC, test "x$have_unac" = "xyes")
 AC_ARG_ENABLE([evolution_push_module],
               AS_HELP_STRING([--enable-evolution-push-module],
                              [enable support for Evolution push mechanism [[default=no]]]),,
-              [enable_evolution_push_module=no])
+              [enable_evolution_push_module=yes])
 
 AM_CONDITIONAL(USING_EVOLUTION_PUSH_MODULE, test "x$enable_evolution_push_module" = "xyes")
 
 AC_ARG_ENABLE([kmail_push_module],
               AS_HELP_STRING([--enable-kmail-push-module],
                              [enable support for KMail push mechanism [[default=no]]]),,
-              [enable_kmail_push_module=no])
+              [enable_kmail_push_module=yes])
 
 AM_CONDITIONAL(USING_KMAIL_PUSH_MODULE, test "x$enable_kmail_push_module" = "xyes")
 
diff --git a/src/plugins/evolution/tracker-evolution-registrar.c b/src/plugins/evolution/tracker-evolution-registrar.c
index 8dc72c7..c001917 100644
--- a/src/plugins/evolution/tracker-evolution-registrar.c
+++ b/src/plugins/evolution/tracker-evolution-registrar.c
@@ -28,12 +28,11 @@
 #include <glib-object.h>
 #include <dbus/dbus-glib-bindings.h>
 
-#include <libtracker-data/tracker-data-update.h>
 #include <libtracker-data/tracker-data-manager.h>
-#include <libtracker-data/tracker-data-query.h>
 #include <libtracker-common/tracker-ontology.h>
 
 #include <tracker-store/tracker-push-registrar.h>
+#include <tracker-store/tracker-store.h>
 
 #define __TRACKER_EVOLUTION_REGISTRAR_C__
 
@@ -45,8 +44,6 @@
 #define TRACKER_TYPE_EVOLUTION_PUSH_REGISTRAR    (tracker_evolution_push_registrar_get_type ())
 #define TRACKER_EVOLUTION_PUSH_REGISTRAR(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TRACKER_TYPE_EVOLUTION_PUSH_REGISTRAR, TrackerEvolutionPushRegistrar))
 
-#define TRANSACTION_MAX 200
-
 #define NIE_DATASOURCE 			       TRACKER_NIE_PREFIX "DataSource"
 #define NIE_DATASOURCE_P 		       TRACKER_NIE_PREFIX "dataSource"
 
@@ -191,13 +188,13 @@ extract_mime_parts (GMimeObject *object,
 		subject = g_strdup_printf ("%s/%s", message_subject, 
 					   filename);
 
-		tracker_data_insert_statement (subject, 
-					       "File:Path", 
-					       filename);
+		data_insert_statement (subject, 
+		                      "File:Path", 
+				       filename);
 
-		tracker_data_insert_statement (subject, 
-					       "File:Name", 
-					       filename);
+		data_insert_statement (subject, 
+		                       "File:Name", 
+		                       filename);
 
 		g_free (subject);
 	}
@@ -271,6 +268,17 @@ get_email_and_fullname (const gchar *line, gchar **email, gchar **fullname)
 }
 
 static void
+data_insert_statement (TrackerEvolutionRegistrar *self, 
+		       const gchar *subject, 
+		       const gchar *predicate,
+		       const gchar *object)
+{
+	/* To be replaced with batch_update when query builder is available */
+	tracker_store_queue_insert_statement (subject, predicate, object, 
+	                                      NULL, NULL, NULL);
+}
+
+static void
 perform_set (TrackerEvolutionRegistrar *object, 
 	     const gchar *subject, 
 	     const GStrv predicates, 
@@ -278,19 +286,17 @@ perform_set (TrackerEvolutionRegistrar *object,
 {
 	guint i = 0;
 
-	if (!tracker_data_query_resource_exists (DATASOURCE_URN, NULL, NULL)) {
-		tracker_data_insert_statement (DATASOURCE_URN, RDF_PREFIX "type",
-					       NIE_DATASOURCE);
-	}
+	data_insert_statement (object, DATASOURCE_URN, RDF_PREFIX "type",
+			       NIE_DATASOURCE);
 
-	tracker_data_insert_statement (subject, RDF_PREFIX "type",
-		                       NMO_PREFIX "Email");
+	data_insert_statement (object, subject, RDF_PREFIX "type",
+	                       NMO_PREFIX "Email");
 
-	tracker_data_insert_statement (subject, RDF_PREFIX "type",
-		                       NMO_PREFIX "MailboxDataObject");
+	data_insert_statement (object, subject, RDF_PREFIX "type",
+	                       NMO_PREFIX "MailboxDataObject");
 
-	tracker_data_insert_statement (subject, NIE_DATASOURCE_P,
-		                       DATASOURCE_URN);
+	data_insert_statement (object, subject, NIE_DATASOURCE_P,
+	                       DATASOURCE_URN);
 
 	while (predicates [i] != NULL && values[i] != NULL) {
 
@@ -376,9 +382,9 @@ perform_set (TrackerEvolutionRegistrar *object,
 				} else
 					text = orig_text;
 
-				tracker_data_insert_statement (subject, 
-							       METADATA_EMAIL_TEXT, 
-							       text);
+				data_insert_statement (object, subject, 
+				                       METADATA_EMAIL_TEXT, 
+				                       text);
 
 				g_free (text);
 				g_free (encoding);
@@ -402,85 +408,96 @@ perform_set (TrackerEvolutionRegistrar *object,
 			if (value) {
 				*value = '\0';
 				value++;
-			}
 
-			tracker_data_insert_statement (":1", RDF_PREFIX "type",
-			                               NAO_PREFIX "Property");
+				data_insert_statement (object, ":1", RDF_PREFIX "type",
+				                       NAO_PREFIX "Property");
+
+				data_insert_statement (object, ":1", 
+				                       NAO_PREFIX "propertyName",
+				                       key);
 
-			tracker_data_insert_statement (":1", 
-			                               NAO_PREFIX "propertyName",
-			                               key);
+				data_insert_statement (object, ":1", 
+				                       NAO_PREFIX "propertyValue",
+				                       value);
 
-			tracker_data_insert_statement (":1", 
-			                               NAO_PREFIX "propertyValue",
-			                               value);
+				data_insert_statement (object, subject, 
+				                       NAO_PREFIX "hasProperty", 
+				                       ":1");
+			} else {
+				data_insert_statement (object, ":1", RDF_PREFIX "type",
+				                       NAO_PREFIX "Tag");
 
-			tracker_data_insert_statement (subject, 
-			                               NAO_PREFIX "hasProperty", 
-			                               ":1");
+				data_insert_statement (object, ":1", 
+				                       NAO_PREFIX "prefLabel",
+				                       key);
+
+				data_insert_statement (object, subject, 
+				                       NAO_PREFIX "hasTag", 
+				                       ":1");
+			}
 
 			g_free (key);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SUBJECT) == 0) {
-			tracker_data_insert_statement (subject,
-						       TRACKER_NMO_PREFIX "messageSubject", 
-						       values[i]);
+			data_insert_statement (object, subject,
+			                       TRACKER_NMO_PREFIX "messageSubject", 
+			                       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_SENT) == 0) {
-			tracker_data_insert_statement (subject,
-						       TRACKER_NMO_PREFIX "receivedDate", 
-						       values[i]);
+			data_insert_statement (object, subject,
+			                       TRACKER_NMO_PREFIX "receivedDate", 
+			                       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_FROM) == 0) {
 			gchar *email_uri, *email = NULL, *fullname = NULL;
-			tracker_data_insert_statement (":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
+			data_insert_statement (object, ":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
 			get_email_and_fullname (values[i], &email, &fullname);
 			if (fullname) {
-				tracker_data_insert_statement (":1", NCO_PREFIX "fullname", fullname);
+				data_insert_statement (object, ":1", NCO_PREFIX "fullname", fullname);
 				g_free (fullname);
 			}
 			email_uri = tracker_uri_printf_escaped ("mailto:%s";, email); 
-			tracker_data_insert_statement (email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
-			tracker_data_insert_statement (email_uri, NCO_PREFIX "emailAddress", email);
-			tracker_data_insert_statement (":1", NCO_PREFIX "hasEmailAddress", email_uri);
-			tracker_data_insert_statement (subject, NMO_PREFIX "from", ":1");
+			data_insert_statement (object, email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
+			data_insert_statement (object, email_uri, NCO_PREFIX "emailAddress", email);
+			data_insert_statement (object, ":1", NCO_PREFIX "hasEmailAddress", email_uri);
+			data_insert_statement (object, subject, NMO_PREFIX "from", ":1");
 			g_free (email_uri);
 			g_free (email);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_TO) == 0) {
 			gchar *email_uri, *email = NULL, *fullname = NULL;
-			tracker_data_insert_statement (":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
+			data_insert_statement (object, ":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
 			get_email_and_fullname (values[i], &email, &fullname);
 			if (fullname) {
-				tracker_data_insert_statement (":1", NCO_PREFIX "fullname", fullname);
+				data_insert_statement (object, ":1", NCO_PREFIX "fullname", fullname);
 				g_free (fullname);
 			}
 			email_uri = tracker_uri_printf_escaped ("mailto:%s";, email); 
-			tracker_data_insert_statement (email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
-			tracker_data_insert_statement (email_uri, NCO_PREFIX "emailAddress", email);
-			tracker_data_insert_statement (":1", NCO_PREFIX "hasEmailAddress", email_uri);
-			tracker_data_insert_statement (subject, NMO_PREFIX "to", ":1");
+			data_insert_statement (object, email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
+			data_insert_statement (object, email_uri, NCO_PREFIX "emailAddress", email);
+			data_insert_statement (object, ":1", NCO_PREFIX "hasEmailAddress", email_uri);
+			data_insert_statement (object, subject, NMO_PREFIX "to", ":1");
 			g_free (email_uri);
 			g_free (email);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_EVOLUTION_PREDICATE_CC) == 0) {
 			gchar *email_uri, *email = NULL, *fullname = NULL;
-			tracker_data_insert_statement (":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
+			data_insert_statement (object, ":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
 			get_email_and_fullname (values[i], &email, &fullname);
 			if (fullname) {
-				tracker_data_insert_statement (":1", NCO_PREFIX "fullname", fullname);
+				data_insert_statement (object, ":1", NCO_PREFIX "fullname", fullname);
 				g_free (fullname);
 			}
 			email_uri = tracker_uri_printf_escaped ("mailto:%s";, email); 
-			tracker_data_insert_statement (email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
-			tracker_data_insert_statement (email_uri, NCO_PREFIX "emailAddress", email);
-			tracker_data_insert_statement (":1", NCO_PREFIX "hasEmailAddress", email_uri);
-			tracker_data_insert_statement (subject, NMO_PREFIX "cc", ":1");
+			data_insert_statement (object, email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
+			data_insert_statement (object, email_uri, NCO_PREFIX "emailAddress", email);
+			data_insert_statement (object, ":1", NCO_PREFIX "hasEmailAddress", email_uri);
+			data_insert_statement (object, subject, NMO_PREFIX "cc", ":1");
 			g_free (email_uri);
 			g_free (email);
 		}
@@ -494,22 +511,23 @@ perform_set (TrackerEvolutionRegistrar *object,
 
 static void 
 perform_unset (TrackerEvolutionRegistrar *object, 
-	       const gchar *subject)
+	       const gchar *subject, gboolean batch)
 {
-	tracker_data_delete_resource (subject); 
+	gchar *sparql = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }", subject);
+
+	if (batch) {
+		tracker_store_sparql_update (sparql, NULL);
+	} else {
+		tracker_store_queue_sparql_update (sparql, NULL, NULL, NULL);
+	}
+
+	g_free (sparql);
 }
 
 static void
 perform_cleanup (TrackerEvolutionRegistrar *object)
 {
-	GError *error = NULL;
-
-	tracker_data_update_sparql ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", &error);
-
-	if (error) {
-		g_warning ("%s", error->message);
-		g_error_free (error);
-	}
+	tracker_store_sparql_update ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL);
 }
 
 static void
@@ -540,9 +558,91 @@ tracker_evolution_registrar_set (TrackerEvolutionRegistrar *object,
 
 	set_stored_last_modseq (modseq);
 
+	tracker_store_queue_commit (NULL, NULL, NULL);
+
 	dbus_g_method_return (context);
 }
 
+
+
+typedef struct {
+	TrackerEvolutionRegistrar *object;
+	GStrv subjects;
+	GPtrArray *predicates;
+	GPtrArray *values;
+	guint modseq;
+	DBusGMethodInvocation *context;
+} SetManyInfo;
+
+static gboolean
+set_many_idle (gpointer user_data)
+{
+	guint i = 0;
+	SetManyInfo *info = user_data;
+	gboolean cont = FALSE;
+
+	while (info->subjects[i] != NULL) {
+		GStrv preds = g_ptr_array_index (info->predicates, i);
+		GStrv vals = g_ptr_array_index (info->values, i);
+
+		perform_set (info->object, info->subjects[i], preds, vals);
+
+		if (i > 100) {
+			cont = TRUE;
+			break;
+		}
+
+		i++;
+	}
+
+	return cont;
+}
+
+static void
+strv_ptrarray_free (GPtrArray *array)
+{
+	guint i;
+
+	for (i = 0; i < array->len; i++) {
+		g_strfreev (g_ptr_array_index (array, i));
+	}
+
+	g_ptr_array_free (array, TRUE);
+}
+
+static void 
+set_many_destroy (gpointer user_data)
+{
+	SetManyInfo *info = user_data;
+
+	strv_ptrarray_free (info->predicates);
+	strv_ptrarray_free (info->values);
+	g_strfreev (info->subjects);
+
+	set_stored_last_modseq (info->modseq);
+
+	tracker_store_queue_commit (NULL, NULL, NULL);
+
+	dbus_g_method_return (info->context);
+
+	g_object_unref (info->object);
+	g_free (info);
+}
+
+static GPtrArray* 
+strv_ptrarray_dup (const GPtrArray *array)
+{
+	GPtrArray *new_array = g_ptr_array_sized_new (array->len);
+	guint i;
+
+	for (i = 0; i < array->len; i++) {
+		g_ptr_array_add	(new_array, g_strdupv (
+		                 g_ptr_array_index (array, i)));
+	}
+
+	return new_array;
+}
+
 void
 tracker_evolution_registrar_set_many (TrackerEvolutionRegistrar *object, 
 				      const GStrv subjects, 
@@ -553,7 +653,7 @@ tracker_evolution_registrar_set_many (TrackerEvolutionRegistrar *object,
 				      GError *derror)
 {
 	guint len;
-	guint i = 0, amount = 0;
+	SetManyInfo *info;
 
 	dbus_async_return_if_fail (subjects != NULL, context);
 	dbus_async_return_if_fail (predicates != NULL, context);
@@ -564,30 +664,64 @@ tracker_evolution_registrar_set_many (TrackerEvolutionRegistrar *object,
 	dbus_async_return_if_fail (len == predicates->len, context);
 	dbus_async_return_if_fail (len == values->len, context);
 
-	tracker_data_begin_transaction ();
+	info = g_new0 (SetManyInfo, 1);
+
+	info->object = g_object_ref (object);
+	info->context = context;
+	info->modseq = modseq;
+	info->subjects = g_strdupv (subjects);
+	info->predicates = strv_ptrarray_dup (predicates);
+	info->values = strv_ptrarray_dup (values);
+
+	g_idle_add_full (G_PRIORITY_DEFAULT,
+	                 set_many_idle,
+	                 info,
+	                 set_many_destroy);
+}
+
+
+typedef struct {
+	GStrv subjects;
+	guint modseq;
+	DBusGMethodInvocation *context;
+	TrackerEvolutionRegistrar *object;
+} UnsetManyInfo;
+
+static gboolean
+unset_many_idle (gpointer user_data)
+{
+	guint i = 0;
+	gboolean cont = FALSE;
+	UnsetManyInfo *info = user_data;
 
-	while (subjects[i] != NULL) {
-		GStrv preds = g_ptr_array_index (predicates, i);
-		GStrv vals = g_ptr_array_index (values, i);
+	while (info->subjects[i] != NULL) {
 
-		perform_set (object, subjects[i], preds, vals);
+		perform_unset (info->object, info->subjects[i], TRUE);
 
-		amount++;
-		if (amount > TRANSACTION_MAX) {
-			tracker_data_commit_transaction ();
-			g_main_context_iteration (NULL, FALSE);
-			tracker_data_begin_transaction ();
-			amount = 0;
+		if (i > 100) {
+			cont = TRUE;
+			break;
 		}
 
 		i++;
 	}
 
-	set_stored_last_modseq (modseq);
+	return cont;
+}
+
+static void
+unset_many_destroy (gpointer user_data)
+{
+	UnsetManyInfo *info = user_data;
 
-	tracker_data_commit_transaction ();
+	set_stored_last_modseq (info->modseq);
 
-	dbus_g_method_return (context);
+	tracker_store_queue_commit (NULL, NULL, NULL);
+
+	dbus_g_method_return (info->context);
+
+	g_object_unref (info->object);
+	g_free (info);
 }
 
 void
@@ -597,32 +731,21 @@ tracker_evolution_registrar_unset_many (TrackerEvolutionRegistrar *object,
 					DBusGMethodInvocation *context,
 					GError *derror)
 {
-	guint i = 0, amount = 0;
+	UnsetManyInfo *info;
 
 	dbus_async_return_if_fail (subjects != NULL, context);
 
-	tracker_data_begin_transaction ();
+	info = g_new0 (UnsetManyInfo, 1);
 
-	while (subjects[i] != NULL) {
+	info->object = g_object_ref (object);
+	info->context = context;
+	info->modseq = modseq;
+	info->subjects = g_strdupv (subjects);
 
-		perform_unset (object, subjects[i]);
-
-		amount++;
-		if (amount > TRANSACTION_MAX) {
-			tracker_data_commit_transaction ();
-			g_main_context_iteration (NULL, FALSE);
-			tracker_data_begin_transaction ();
-			amount = 0;
-		}
-
-		i++;
-	}
-
-	set_stored_last_modseq (modseq);
-
-	tracker_data_commit_transaction ();
-
-	dbus_g_method_return (context);
+	g_idle_add_full (G_PRIORITY_DEFAULT,
+	                 unset_many_idle,
+	                 info,
+	                 unset_many_destroy);
 }
 
 void
@@ -634,7 +757,7 @@ tracker_evolution_registrar_unset (TrackerEvolutionRegistrar *object,
 {
 	dbus_async_return_if_fail (subject != NULL, context);
 
-	perform_unset (object, subject);
+	perform_unset (object, subject, FALSE);
 
 	dbus_g_method_return (context);
 }
diff --git a/src/plugins/kmail/tracker-kmail-registrar.c b/src/plugins/kmail/tracker-kmail-registrar.c
index 3aeaff3..d1a462c 100644
--- a/src/plugins/kmail/tracker-kmail-registrar.c
+++ b/src/plugins/kmail/tracker-kmail-registrar.c
@@ -28,16 +28,13 @@
 #include <glib-object.h>
 #include <dbus/dbus-glib-bindings.h>
 
-#include <libtracker-data/tracker-data-update.h>
 #include <libtracker-data/tracker-data-manager.h>
-#include <libtracker-data/tracker-data-query.h>
 
 #include <tracker-store/tracker-push-registrar.h>
+#include <tracker-store/tracker-store.h>
 
 #define __TRACKER_KMAIL_REGISTRAR_C__
 
-#define TRANSACTION_MAX 200
-
 #include "tracker-kmail-registrar.h"
 #include "tracker-kmail-registrar-glue.h"
 
@@ -155,6 +152,16 @@ get_email_and_fullname (const gchar *line, gchar **email, gchar **fullname)
 	}
 }
 
+static void
+data_insert_statement (TrackerKMailRegistrar *self, 
+		       const gchar *subject, 
+		       const gchar *predicate,
+		       const gchar *object)
+{
+	/* To be replaced with batch_update when query builder is available */
+	tracker_store_queue_insert_statement (subject, predicate, object, 
+	                                      NULL, NULL, NULL); 
+}
 
 static void
 perform_set (TrackerKMailRegistrar *object, 
@@ -164,20 +171,18 @@ perform_set (TrackerKMailRegistrar *object,
 {
 	guint i = 0;
 
-	if (!tracker_data_query_resource_exists (DATASOURCE_URN, NULL, NULL)) {
-		tracker_data_insert_statement (DATASOURCE_URN, RDF_PREFIX "type",
-					       NIE_DATASOURCE);
-	}
+	data_insert_statement (object, DATASOURCE_URN, RDF_PREFIX "type",
+	                      NIE_DATASOURCE);
 
 
-	tracker_data_insert_statement (subject, RDF_PREFIX "type",
-		                       NMO_PREFIX "Email");
+	data_insert_statement (object, subject, RDF_PREFIX "type",
+	                       NMO_PREFIX "Email");
 
-	tracker_data_insert_statement (subject, RDF_PREFIX "type",
-		                       NMO_PREFIX "MailboxDataObject");
+	data_insert_statement (object, subject, RDF_PREFIX "type",
+	                       NMO_PREFIX "MailboxDataObject");
 
-	tracker_data_insert_statement (subject, NIE_DATASOURCE_P,
-		                       DATASOURCE_URN);
+	data_insert_statement (object, subject, NIE_DATASOURCE_P,
+	                       DATASOURCE_URN);
 
 	while (predicates [i] != NULL && values[i] != NULL) {
 
@@ -194,77 +199,77 @@ perform_set (TrackerKMailRegistrar *object,
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_TAG) == 0) {
 
-			tracker_data_insert_statement (":1", RDF_PREFIX "type",
-			                               NAO_PREFIX "Tag");
+			data_insert_statement (object, ":1", RDF_PREFIX "type",
+			                       NAO_PREFIX "Tag");
 
-			tracker_data_insert_statement (":1", 
-			                               NAO_PREFIX "prefLabel",
-			                               values[i]);
+			data_insert_statement (object, ":1", 
+			                       NAO_PREFIX "prefLabel",
+			                       values[i]);
 
-			tracker_data_insert_statement (subject, 
-			                               NAO_PREFIX "hasTag", 
-			                                ":1");
+			data_insert_statement (object, subject, 
+			                       NAO_PREFIX "hasTag", 
+			                       ":1");
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_SUBJECT) == 0) {
-			tracker_data_insert_statement (subject,
-						       TRACKER_NMO_PREFIX "messageSubject", 
-						       values[i]);
+			data_insert_statement (object, subject,
+			                       TRACKER_NMO_PREFIX "messageSubject", 
+			                       values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_SENT) == 0) {
-			tracker_data_insert_statement (subject,
-						       TRACKER_NMO_PREFIX "receivedDate", 
-						       values[i]);
+			data_insert_statement (object, subject,
+			                      TRACKER_NMO_PREFIX "receivedDate", 
+			                      values[i]);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_FROM) == 0) {
 			gchar *email_uri, *email = NULL, *fullname = NULL;
-			tracker_data_insert_statement (":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
+			data_insert_statement (object, ":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
 			get_email_and_fullname (values[i], &email, &fullname);
 			if (fullname) {
-				tracker_data_insert_statement (":1", NCO_PREFIX "fullname", fullname);
+				data_insert_statement (object, ":1", NCO_PREFIX "fullname", fullname);
 				g_free (fullname);
 			}
 			email_uri = tracker_uri_printf_escaped ("mailto:%s";, email); 
-			tracker_data_insert_statement (email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
-			tracker_data_insert_statement (email_uri, NCO_PREFIX "emailAddress", email);
-			tracker_data_insert_statement (":1", NCO_PREFIX "hasEmailAddress", email_uri);
-			tracker_data_insert_statement (subject, NMO_PREFIX "from", ":1");
+			data_insert_statement (object, email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
+			data_insert_statement (object, email_uri, NCO_PREFIX "emailAddress", email);
+			data_insert_statement (object, ":1", NCO_PREFIX "hasEmailAddress", email_uri);
+			data_insert_statement (object, subject, NMO_PREFIX "from", ":1");
 			g_free (email_uri);
 			g_free (email);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_TO) == 0) {
 			gchar *email_uri, *email = NULL, *fullname = NULL;
-			tracker_data_insert_statement (":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
+			data_insert_statement (object, ":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
 			get_email_and_fullname (values[i], &email, &fullname);
 			if (fullname) {
-				tracker_data_insert_statement (":1", NCO_PREFIX "fullname", fullname);
+				data_insert_statement (object, ":1", NCO_PREFIX "fullname", fullname);
 				g_free (fullname);
 			}
 			email_uri = tracker_uri_printf_escaped ("mailto:%s";, email); 
-			tracker_data_insert_statement (email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
-			tracker_data_insert_statement (email_uri, NCO_PREFIX "emailAddress", email);
-			tracker_data_insert_statement (":1", NCO_PREFIX "hasEmailAddress", email_uri);
-			tracker_data_insert_statement (subject, NMO_PREFIX "to", ":1");
+			data_insert_statement (object, email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
+			data_insert_statement (object, email_uri, NCO_PREFIX "emailAddress", email);
+			data_insert_statement (object, ":1", NCO_PREFIX "hasEmailAddress", email_uri);
+			data_insert_statement (object, subject, NMO_PREFIX "to", ":1");
 			g_free (email_uri);
 			g_free (email);
 		}
 
 		if (g_strcmp0 (predicates[i], TRACKER_KMAIL_PREDICATE_CC) == 0) {
 			gchar *email_uri, *email = NULL, *fullname = NULL;
-			tracker_data_insert_statement (":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
+			data_insert_statement (object, ":1", RDF_PREFIX "type", NCO_PREFIX "Contact");
 			get_email_and_fullname (values[i], &email, &fullname);
 			if (fullname) {
-				tracker_data_insert_statement (":1", NCO_PREFIX "fullname", fullname);
+				data_insert_statement (object, ":1", NCO_PREFIX "fullname", fullname);
 				g_free (fullname);
 			}
 			email_uri = tracker_uri_printf_escaped ("mailto:%s";, email); 
-			tracker_data_insert_statement (email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
-			tracker_data_insert_statement (email_uri, NCO_PREFIX "emailAddress", email);
-			tracker_data_insert_statement (":1", NCO_PREFIX "hasEmailAddress", email_uri);
-			tracker_data_insert_statement (subject, NMO_PREFIX "cc", ":1");
+			data_insert_statement (object, email_uri, RDF_PREFIX "type", NCO_PREFIX "EmailAddress");
+			data_insert_statement (object, email_uri, NCO_PREFIX "emailAddress", email);
+			data_insert_statement (object, ":1", NCO_PREFIX "hasEmailAddress", email_uri);
+			data_insert_statement (object, subject, NMO_PREFIX "cc", ":1");
 			g_free (email_uri);
 			g_free (email);
 		}
@@ -277,22 +282,24 @@ perform_set (TrackerKMailRegistrar *object,
 
 static void 
 perform_unset (TrackerKMailRegistrar *object, 
-	       const gchar *subject)
+	       const gchar *subject, 
+	       gboolean batch)
 {
-	tracker_data_delete_resource (subject); 
+	gchar *sparql = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }", subject);
+
+	if (batch) {
+		tracker_store_sparql_update (sparql, NULL);
+	} else {
+		tracker_store_queue_sparql_update (sparql, NULL, NULL, NULL);
+	}
+
+	g_free (sparql);
 }
 
 static void
 perform_cleanup (TrackerKMailRegistrar *object)
 {
-	GError *error = NULL;
-
-	tracker_data_update_sparql ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", &error);
-
-	if (error) {
-		g_warning ("%s", error->message);
-		g_error_free (error);
-	}
+	tracker_store_sparql_update ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL);
 }
 
 static void
@@ -323,9 +330,89 @@ tracker_kmail_registrar_set (TrackerKMailRegistrar *object,
 
 	set_stored_last_modseq (modseq);
 
+	tracker_store_queue_commit (NULL, NULL, NULL);
+
 	dbus_g_method_return (context);
 }
 
+typedef struct {
+	TrackerKMailRegistrar *object;
+	GStrv subjects;
+	GPtrArray *predicates;
+	GPtrArray *values;
+	guint modseq;
+	DBusGMethodInvocation *context;
+} SetManyInfo;
+
+static gboolean
+set_many_idle (gpointer user_data)
+{
+	guint i = 0;
+	SetManyInfo *info = user_data;
+	gboolean cont = FALSE;
+
+	while (info->subjects[i] != NULL) {
+		GStrv preds = g_ptr_array_index (info->predicates, i);
+		GStrv vals = g_ptr_array_index (info->values, i);
+
+		perform_set (info->object, info->subjects[i], preds, vals);
+
+		if (i > 100) {
+			cont = TRUE;
+			break;
+		}
+
+		i++;
+	}
+
+	return cont;
+}
+
+static void
+strv_ptrarray_free (GPtrArray *array)
+{
+	guint i;
+
+	for (i = 0; i < array->len; i++) {
+		g_strfreev (g_ptr_array_index (array, i));
+	}
+
+	g_ptr_array_free (array, TRUE);
+}
+
+static void 
+set_many_destroy (gpointer user_data)
+{
+	SetManyInfo *info = user_data;
+
+	strv_ptrarray_free (info->predicates);
+	strv_ptrarray_free (info->values);
+	g_strfreev (info->subjects);
+
+	set_stored_last_modseq (info->modseq);
+
+	tracker_store_queue_commit (NULL, NULL, NULL);
+
+	dbus_g_method_return (info->context);
+
+	g_object_unref (info->object);
+	g_free (info);
+}
+
+static GPtrArray* 
+strv_ptrarray_dup (const GPtrArray *array)
+{
+	GPtrArray *new_array = g_ptr_array_sized_new (array->len);
+	guint i;
+
+	for (i = 0; i < array->len; i++) {
+		g_ptr_array_add	(new_array, g_strdupv (
+		                 g_ptr_array_index (array, i)));
+	}
+
+	return new_array;
+}
+
 void
 tracker_kmail_registrar_set_many (TrackerKMailRegistrar *object, 
 				      const GStrv subjects, 
@@ -336,7 +423,7 @@ tracker_kmail_registrar_set_many (TrackerKMailRegistrar *object,
 				      GError *derror)
 {
 	guint len;
-	guint i = 0, amount = 0;
+	SetManyInfo *info;
 
 	dbus_async_return_if_fail (subjects != NULL, context);
 	dbus_async_return_if_fail (predicates != NULL, context);
@@ -347,30 +434,64 @@ tracker_kmail_registrar_set_many (TrackerKMailRegistrar *object,
 	dbus_async_return_if_fail (len == predicates->len, context);
 	dbus_async_return_if_fail (len == values->len, context);
 
-	tracker_data_begin_transaction ();
+	info = g_new0 (SetManyInfo, 1);
+
+	info->object = g_object_ref (object);
+	info->context = context;
+	info->modseq = modseq;
+	info->subjects = g_strdupv (subjects);
+	info->predicates = strv_ptrarray_dup (predicates);
+	info->values = strv_ptrarray_dup (values);
+
+	g_idle_add_full (G_PRIORITY_DEFAULT,
+	                 set_many_idle,
+	                 info,
+	                 set_many_destroy);
+
+}
+
+typedef struct {
+	GStrv subjects;
+	guint modseq;
+	DBusGMethodInvocation *context;
+	TrackerKMailRegistrar *object;
+} UnsetManyInfo;
+
+static gboolean
+unset_many_idle (gpointer user_data)
+{
+	guint i = 0;
+	gboolean cont = FALSE;
+	UnsetManyInfo *info = user_data;
 
-	while (subjects[i] != NULL) {
-		GStrv preds = g_ptr_array_index (predicates, i);
-		GStrv vals = g_ptr_array_index (values, i);
+	while (info->subjects[i] != NULL) {
 
-		perform_set (object, subjects[i], preds, vals);
+		perform_unset (info->object, info->subjects[i], TRUE);
 
-		amount++;
-		if (amount > TRANSACTION_MAX) {
-			tracker_data_commit_transaction ();
-			g_main_context_iteration (NULL, FALSE);
-			tracker_data_begin_transaction ();
-			amount = 0;
+		if (i > 100) {
+			cont = TRUE;
+			break;
 		}
 
 		i++;
 	}
 
-	set_stored_last_modseq (modseq);
+	return cont;
+}
 
-	tracker_data_commit_transaction ();
+static void
+unset_many_destroy (gpointer user_data)
+{
+	UnsetManyInfo *info = user_data;
 
-	dbus_g_method_return (context);
+	set_stored_last_modseq (info->modseq);
+
+	tracker_store_queue_commit (NULL, NULL, NULL);
+
+	dbus_g_method_return (info->context);
+
+	g_object_unref (info->object);
+	g_free (info);
 }
 
 void
@@ -380,32 +501,22 @@ tracker_kmail_registrar_unset_many (TrackerKMailRegistrar *object,
 				    DBusGMethodInvocation *context,
 				    GError *derror)
 {
-	guint i = 0, amount = 0;
+	UnsetManyInfo *info;
 
 	dbus_async_return_if_fail (subjects != NULL, context);
 
-	tracker_data_begin_transaction ();
+	info = g_new0 (UnsetManyInfo, 1);
 
-	while (subjects[i] != NULL) {
+	info->object = g_object_ref (object);
+	info->context = context;
+	info->modseq = modseq;
+	info->subjects = g_strdupv (subjects);
 
-		perform_unset (object, subjects[i]);
+	g_idle_add_full (G_PRIORITY_DEFAULT,
+	                 unset_many_idle,
+	                 info,
+	                 unset_many_destroy);
 
-		amount++;
-		if (amount > TRANSACTION_MAX) {
-			tracker_data_commit_transaction ();
-			g_main_context_iteration (NULL, FALSE);
-			tracker_data_begin_transaction ();
-			amount = 0;
-		}
-
-		i++;
-	}
-
-	set_stored_last_modseq (modseq);
-
-	tracker_data_commit_transaction ();
-
-	dbus_g_method_return (context);
 }
 
 void
@@ -417,7 +528,7 @@ tracker_kmail_registrar_unset (TrackerKMailRegistrar *object,
 {
 	dbus_async_return_if_fail (subject != NULL, context);
 
-	perform_unset (object, subject);
+	perform_unset (object, subject, FALSE);
 
 	dbus_g_method_return (context);
 }
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/tracker-removable-device.c b/src/tracker-store/tracker-removable-device.c
new file mode 100644
index 0000000..48c55e6
--- /dev/null
+++ b/src/tracker-store/tracker-removable-device.c
@@ -0,0 +1,338 @@
+/* -*- 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 void
+process_turtle_statement (const gchar     *subject,
+                          const gchar     *predicate,
+                          const gchar     *object_,
+                          gpointer         user_data)
+{
+	if (subject && predicate && object_) {
+		consume_triple_storer (subject, predicate, object_, 
+		                       user_data);
+	}
+}
+
+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_store_queue_turtle_import (filename, 
+		                                   base_uri,
+		                                   process_turtle_statement,
+		                                   info,
+		                                   process_turtle_destroy);
+		*/
+
+		g_debug ("Support for removable device cache not yet ported to new TrackerStore API");
+
+		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__ */
+
+
+
diff --git a/src/tracker-store/tracker-store.c b/src/tracker-store/tracker-store.c
index 5ab8b34..8289305 100644
--- a/src/tracker-store/tracker-store.c
+++ b/src/tracker-store/tracker-store.c
@@ -43,7 +43,9 @@ typedef struct {
 typedef enum {
 	TRACKER_STORE_TASK_TYPE_UPDATE = 0,
 	TRACKER_STORE_TASK_TYPE_COMMIT = 1,
-	TRACKER_STORE_TASK_TYPE_TURTLE = 2
+	TRACKER_STORE_TASK_TYPE_TURTLE = 2,
+	/* To be removed when query builder is available */
+	TRACKER_STORE_TASK_TYPE_STATEMENT = 3
 } TrackerStoreTaskType;
 
 typedef struct {
@@ -54,6 +56,12 @@ typedef struct {
 		gboolean           in_progress;
 		gchar             *path;
 	  } turtle;
+	/* To be removed when query builder is available */
+	  struct {
+		gchar             *subject;
+		gchar             *predicate;
+		gchar             *object;
+	  } statement;
 	} data;
 	gpointer                   user_data;
 	GDestroyNotify             destroy;
@@ -80,6 +88,10 @@ tracker_store_task_free (TrackerStoreTask *task)
 {
 	if (task->type == TRACKER_STORE_TASK_TYPE_TURTLE) {
 		g_free (task->data.turtle.path);
+	} else 	if (task->type == TRACKER_STORE_TASK_TYPE_STATEMENT) {
+		g_free (task->data.statement.subject);
+		g_free (task->data.statement.predicate);
+		g_free (task->data.statement.object);
 	} else {
 		g_free (task->data.query);
 	}
@@ -170,6 +182,17 @@ queue_idle_handler (gpointer user_data)
 		if (task->callback.commit_callback) {
 			task->callback.commit_callback (task->user_data);
 		}
+	} else if (task->type == TRACKER_STORE_TASK_TYPE_STATEMENT) {
+
+		/* To be removed when query builder is available */
+		tracker_data_insert_statement (task->data.statement.subject,
+		                               task->data.statement.predicate,
+		                               task->data.statement.object);
+
+		if (task->callback.update_callback) {
+			task->callback.update_callback (NULL, task->user_data);
+		}
+
 	} else if (task->type == TRACKER_STORE_TASK_TYPE_TURTLE) {
 		begin_batch (private);
 
@@ -419,3 +442,36 @@ tracker_store_delete_statement (const gchar   *subject,
 	tracker_data_delete_statement (subject, predicate, object);
 }
 
+/* To be removed when query builder is available */
+void
+tracker_store_queue_insert_statement (const gchar *subject,
+                                      const gchar *predicate,
+                                      const gchar *object,
+                                      TrackerStoreSparqlUpdateCallback callback,
+                                      gpointer user_data,
+                                      GDestroyNotify destroy)
+{
+	TrackerStorePrivate *private;
+	TrackerStoreTask *task;
+
+	g_assert (subject != NULL);
+	g_assert (predicate != NULL);
+	g_assert (object != NULL);
+
+	private = g_static_private_get (&private_key);
+	g_return_if_fail (private != NULL);
+	task = g_slice_new0 (TrackerStoreTask);
+	task->type = TRACKER_STORE_TASK_TYPE_STATEMENT;
+	task->data.statement.subject = g_strdup (subject);
+	task->data.statement.predicate = g_strdup (predicate);
+	task->data.statement.object = g_strdup (object);
+	task->user_data = user_data;
+	task->callback.update_callback = callback;
+	task->destroy = destroy;
+
+	g_queue_push_tail (private->queue, task);
+
+	if (!private->have_handler) {
+		start_handler (private);
+	}
+}
diff --git a/src/tracker-store/tracker-store.h b/src/tracker-store/tracker-store.h
index 0415b12..e29fb8c 100644
--- a/src/tracker-store/tracker-store.h
+++ b/src/tracker-store/tracker-store.h
@@ -61,6 +61,14 @@ TrackerDBResultSet*
              tracker_store_sparql_query           (const gchar   *sparql,
                                                    GError       **error);
 
+/* To be removed when query builder is available */
+void         tracker_store_queue_insert_statement (const gchar *subject,
+                                                   const gchar *predicate,
+                                                   const gchar *object,
+                                                   TrackerStoreSparqlUpdateCallback callback,
+                                                   gpointer user_data,
+                                                   GDestroyNotify destroy);
+
 G_END_DECLS
 
 #endif /* __TRACKER_STORE_H__ */



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