[tracker/gdbus-server-wip] WIP



commit 1a29b491ce6dab9c6a1559c4a850d31a830b9d82
Author: Jürg Billeter <j bitron ch>
Date:   Thu Jan 6 17:54:52 2011 +0100

    WIP

 configure.ac                                 |    4 +-
 src/libtracker-common/libtracker-common.vapi |   16 +
 src/libtracker-common/tracker-dbus.h         |    4 +-
 src/libtracker-data/libtracker-data.vapi     |   20 +-
 src/tracker-store/Makefile.am                |   84 +--
 src/tracker-store/tracker-backup.c           |  215 -------
 src/tracker-store/tracker-backup.h           |   64 --
 src/tracker-store/tracker-backup.vala        |  119 ++++
 src/tracker-store/tracker-config.vapi        |   27 +
 src/tracker-store/tracker-dbus.c             |  382 -----------
 src/tracker-store/tracker-dbus.h             |   42 --
 src/tracker-store/tracker-dbus.vala          |  340 ++++++++++
 src/tracker-store/tracker-events.vapi        |   36 +
 src/tracker-store/tracker-locale-change.c    |    4 +
 src/tracker-store/tracker-main.c             |  575 -----------------
 src/tracker-store/tracker-main.vala          |  484 ++++++++++++++
 src/tracker-store/tracker-marshal.list       |   12 -
 src/tracker-store/tracker-resources.c        |  767 ----------------------
 src/tracker-store/tracker-resources.h        |   95 ---
 src/tracker-store/tracker-resources.vala     |  704 ++++++++++++++++++++
 src/tracker-store/tracker-statistics.c       |  114 ----
 src/tracker-store/tracker-statistics.h       |   58 --
 src/tracker-store/tracker-statistics.vala    |   87 +++
 src/tracker-store/tracker-status.c           |  231 -------
 src/tracker-store/tracker-status.h           |   77 ---
 src/tracker-store/tracker-status.vala        |  139 ++++
 src/tracker-store/tracker-steroids.c         |  886 --------------------------
 src/tracker-store/tracker-steroids.h         |   57 --
 src/tracker-store/tracker-steroids.vala      |  212 ++++++
 src/tracker-store/tracker-store.c            |  733 ---------------------
 src/tracker-store/tracker-store.h            |   92 ---
 src/tracker-store/tracker-store.vala         |  583 +++++++++++++++++
 src/tracker-store/tracker-writeback.c        |    4 +
 33 files changed, 2809 insertions(+), 4458 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1ff2fb1..c184a79 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,7 @@ AC_INIT([tracker],
         [tracker],
         [http://www.tracker-project.org])
 
-AC_CONFIG_SRCDIR([src/tracker-store/tracker-main.c])
+AC_CONFIG_SRCDIR([src/tracker-store/tracker-main.vala])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([config.h])
 
@@ -311,8 +311,6 @@ TRACKER_STORE_REQUIRED="glib-2.0     >= $GLIB_REQUIRED
                         gio-unix-2.0 >= $GLIB_REQUIRED
                         gthread-2.0  >= $GLIB_REQUIRED
                         gmodule-2.0  >= $GLIB_REQUIRED
-                        dbus-1       >= $DBUS_REQUIRED
-                        dbus-glib-1  >= $DBUS_GLIB_REQUIRED
                         sqlite3      >= $SQLITE_REQUIRED"
 
 PKG_CHECK_MODULES(TRACKER_STORE, [$TRACKER_STORE_REQUIRED])
diff --git a/src/libtracker-common/libtracker-common.vapi b/src/libtracker-common/libtracker-common.vapi
index eb546db..1814f4d 100644
--- a/src/libtracker-common/libtracker-common.vapi
+++ b/src/libtracker-common/libtracker-common.vapi
@@ -58,5 +58,21 @@ namespace Tracker {
 		public static void save_string_list (void *object, string property, GLib.KeyFile key_file, string group, string key);
 		public static void save_directory_list (void *object, string property, GLib.KeyFile key_file, string group, string key);
 	}
+
+	[CCode (cheader_filename = "libtracker-common/tracker-common.h")]
+	namespace Log {
+		public bool init (int verbosity, out string used_filename);
+		public void shutdown ();
+	}
+
+	[Compact]
+	[CCode (ref_function = "", unref_function = "", cheader_filename = "libtracker-common/tracker-common.h")]
+	public class DBusRequest {
+		public static DBusRequest begin (string? sender, string format,...);
+		public void debug (string format,...);
+		public void end (GLib.Error? e = null);
+		[CCode (cname = "tracker_dbus_enable_client_lookup")]
+		public static void enable_client_lookup (bool enable);
+	}
 }
 
diff --git a/src/libtracker-common/tracker-dbus.h b/src/libtracker-common/tracker-dbus.h
index 0d9c5ca..84e001d 100644
--- a/src/libtracker-common/tracker-dbus.h
+++ b/src/libtracker-common/tracker-dbus.h
@@ -24,9 +24,11 @@
 
 #include <gio/gio.h>
 
+#if !defined (TRACKER_STORE_COMPILATION)
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -143,7 +145,7 @@ void                tracker_dbus_request_debug         (TrackerDBusRequest
 void                tracker_dbus_enable_client_lookup  (gboolean                    enable);
 
 
-#ifndef NO_LIBDBUS
+#if !defined(NO_LIBDBUS) && !defined (TRACKER_STORE_COMPILATION)
 /* dbus-glib convenience API */
 TrackerDBusRequest *tracker_dbus_g_request_begin       (DBusGMethodInvocation      *context,
                                                         const gchar                *format,
diff --git a/src/libtracker-data/libtracker-data.vapi b/src/libtracker-data/libtracker-data.vapi
index 27955a0..d152d57 100644
--- a/src/libtracker-data/libtracker-data.vapi
+++ b/src/libtracker-data/libtracker-data.vapi
@@ -85,6 +85,12 @@ namespace Tracker {
 		public abstract DBCursor start_sparql_cursor (PropertyType[] types, string[] variable_names, bool threadsafe) throws DBInterfaceError;
 	}
 
+	[CCode (cheader_filename = "libtracker-data/tracker-db-config.h")]
+	public class DBConfig : ConfigFile {
+		public DBConfig ();
+		public bool save ();
+	}
+
 	[CCode (cheader_filename = "libtracker-data/tracker-class.h")]
 	public class Class : GLib.Object {
 		public string name { get; set; }
@@ -134,20 +140,32 @@ namespace Tracker {
 		public unowned Property[] get_properties ();
 	}
 
-	[CCode (cheader_filename = "libtracker-data/tracker-data-query.h,libtracker-data/tracker-data-update.h")]
+	[CCode (cheader_filename = "libtracker-data/tracker-data-query.h,libtracker-data/tracker-data-update.h,libtracker-data/tracker-data-backup.h")]
 	namespace Data {
 		public int query_resource_id (string uri);
+		public DBCursor query_sparql_cursor (string query) throws Sparql.Error;
 		public void begin_db_transaction ();
 		public void commit_db_transaction ();
 		public void begin_transaction () throws DBInterfaceError;
 		public void commit_transaction () throws DBInterfaceError;
 		public void rollback_transaction ();
+		public void update_sparql (string update) throws Sparql.Error;
+		public GLib.PtrArray update_sparql_blank (string update) throws Sparql.Error;
+		public void load_turtle_file (GLib.File file) throws Sparql.Error;
+		public void notify_transaction (bool start_timer);
 		public void delete_statement (string graph, string subject, string predicate, string object) throws Sparql.Error, DateError;
 		public void insert_statement (string graph, string subject, string predicate, string object) throws Sparql.Error, DateError;
 		public void insert_statement_with_uri (string graph, string subject, string predicate, string object) throws Sparql.Error;
 		public void insert_statement_with_string (string graph, string subject, string predicate, string object) throws Sparql.Error, DateError;
 		public void update_buffer_flush () throws DBInterfaceError;
 		public void update_buffer_might_flush () throws DBInterfaceError;
+		public void sync ();
+
+		[CCode (cheader_filename = "libtracker-data/tracker-data-backup.h")]
+		public delegate void BackupFinished (GLib.Error error);
+
+		public void backup_save (GLib.File destination, owned BackupFinished callback);
+		public void backup_restore (GLib.File journal, owned BackupFinished callback, [CCode (array_length = false)] string[]? test_schema, BusyCallback busy_callback);
 	}
 
 	[CCode (cheader_filename = "libtracker-data/tracker-data-manager.h")]
diff --git a/src/tracker-store/Makefile.am b/src/tracker-store/Makefile.am
index b113296..8b9a674 100644
--- a/src/tracker-store/Makefile.am
+++ b/src/tracker-store/Makefile.am
@@ -8,7 +8,9 @@ AM_CPPFLAGS =                                          \
 	-DPUSH_MODULES_DIR=\""$(libdir)/tracker-$(TRACKER_API_VERSION)/push-modules/daemon"\" \
 	-I$(top_srcdir)/src                            \
 	-I$(top_builddir)/src                          \
-	$(TRACKER_STORE_CFLAGS)
+	$(TRACKER_STORE_CFLAGS)                        \
+	-DTRACKER_STORE_COMPILATION                    \
+	-DGETTEXT_PACKAGE=\"NULL\"
 
 #
 # Daemon sources
@@ -16,31 +18,35 @@ AM_CPPFLAGS =                                          \
 libexec_PROGRAMS = tracker-store
 
 tracker_store_SOURCES =                                \
-	$(marshal_sources)                             \
-	$(dbus_sources)                                \
-	tracker-backup.c                               \
-	tracker-backup.h                               \
+	tracker-backup.vala                            \
 	tracker-config.c                               \
-	tracker-config.h                               \
-	tracker-dbus.c                                 \
-	tracker-dbus.h                                 \
+	tracker-dbus.vala                              \
 	tracker-events.c                               \
+	tracker-locale-change.c                        \
+	tracker-main.vala                              \
+	tracker-resources.vala                         \
+	tracker-statistics.vala                        \
+	tracker-status.vala                            \
+	tracker-steroids.vala                          \
+	tracker-store.vala                             \
+	tracker-writeback.c
+
+noinst_HEADERS =                                       \
+	tracker-config.h                               \
 	tracker-events.h                               \
-	tracker-writeback.c                            \
-	tracker-writeback.h                            \
-	tracker-main.c                                 \
-	tracker-resources.c                            \
-	tracker-resources.h                            \
-	tracker-statistics.c                           \
-	tracker-statistics.h                           \
-	tracker-store.c                                \
-	tracker-store.h                                \
-	tracker-status.c                               \
-	tracker-status.h                               \
-	tracker-steroids.c                             \
-	tracker-steroids.h                             \
 	tracker-locale-change.h                        \
-	tracker-locale-change.c
+	tracker-writeback.h
+
+tracker_store_VALAFLAGS = \
+	--pkg gio-2.0 \
+	--pkg gio-unix-2.0 \
+	$(BUILD_VALAFLAGS) \
+	$(top_srcdir)/src/libtracker-common/libtracker-common.vapi \
+	$(top_srcdir)/src/libtracker-sparql/tracker-sparql-$(TRACKER_API_VERSION).vapi \
+	$(top_srcdir)/src/libtracker-data/tracker-sparql-query.vapi \
+	$(top_srcdir)/src/libtracker-data/libtracker-data.vapi \
+	$(top_srcdir)/src/tracker-store/tracker-config.vapi \
+	$(top_srcdir)/src/tracker-store/tracker-events.vapi
 
 tracker_store_LDADD =                                  \
 	$(top_builddir)/src/libtracker-data/libtracker-data.la \
@@ -49,34 +55,6 @@ tracker_store_LDADD =                                  \
 	$(BUILD_LIBS)                                  \
 	$(TRACKER_STORE_LIBS)
 
-marshal_sources =                                      \
-        tracker-marshal.h                              \
-        tracker-marshal.c
-
-dbus_sources =                                         \
-	tracker-backup-glue.h                          \
-	tracker-resources-glue.h                       \
-	tracker-statistics-glue.h                      \
-	tracker-status-glue.h
-
-tracker-marshal.h: tracker-marshal.list
-	$(AM_V_GEN)$(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --header > $@
-
-tracker-marshal.c: tracker-marshal.list
-	$(AM_V_GEN)echo "#include \"tracker-marshal.h\"" > $@ && \
-		   $(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --body >> $@
-
-%-glue.h: $(top_srcdir)/data/dbus/%.xml
-	$(AM_V_GEN)$(DBUSBINDINGTOOL) --mode=glib-server --output=$@ --prefix=$(subst -,_,$*) $^
-
-%-client.h: $(top_srcdir)/data/dbus/%.xml
-	$(AM_V_GEN)$(DBUSBINDINGTOOL) --mode=glib-client --output=$@ --prefix=$(subst -,_,$*) $^
-
-BUILT_SOURCES =                                        \
-	$(marshal_sources)                             \
-	$(dbus_sources)
-
-CLEANFILES = $(BUILT_SOURCES)
-
-EXTRA_DIST = tracker-marshal.list
-
+EXTRA_DIST = \
+	tracker-config.vapi \
+	tracker-events.vapi
diff --git a/src/tracker-store/tracker-backup.vala b/src/tracker-store/tracker-backup.vala
new file mode 100644
index 0000000..59bd023
--- /dev/null
+++ b/src/tracker-store/tracker-backup.vala
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2006, Jamie McCracken <jamiemcc gnome org>
+ * Copyright (C) 2008, Nokia <ivan frade nokia com>
+ *
+ * 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.
+ */
+
+#if 0
+struct TrackerDBusMethodInfo {
+	DBusGMethodInvocation *context;
+	guint request_id;
+	gchar *journal_uri;
+	TrackerResources *resources;
+	TrackerNotifyClassGetter getter;
+	GFile *destination;
+}
+#endif
+
+[DBus (name = "org.freedesktop.Tracker1.Backup")]
+class Tracker.Backup : Object {
+	public async void save (BusName sender, string destination_uri) throws Error {
+		var request = DBusRequest.begin (sender, "D-Bus request to save backup into '%s'", destination_uri);
+		try {
+			var destination = File.new_for_uri (destination_uri);
+
+			NotifyClassGetter getter = null;
+
+			var resources = (Resources) Tracker.DBus.get_object (typeof (Resources));
+			if (resources != null) {
+				resources.disable_signals ();
+				getter = Tracker.Events.get_class_getter ();
+				Tracker.Events.shutdown ();
+			}
+
+			yield Tracker.Store.pause ();
+
+			Error backup_error = null;
+			Data.backup_save (destination, error => {
+				backup_error = error;
+				save.callback ();
+			});
+			yield;
+
+			if (backup_error != null) {
+				throw backup_error;
+			}
+
+			if (resources != null) {
+				Tracker.Events.init (getter);
+				resources.enable_signals ();
+			}
+
+			Tracker.Store.resume ();
+
+			request.end ();
+		} catch (Error e) {
+			request.end (e);
+			throw e;
+		}
+	}
+
+	public async void restore (BusName sender, string journal_uri) throws Error {
+		var request = DBusRequest.begin (sender, "D-Bus request to restore backup from '%s'", journal_uri);
+		try {
+			NotifyClassGetter getter = null;
+
+			var resources = (Resources) Tracker.DBus.get_object (typeof (Resources));
+			if (resources != null) {
+				resources.disable_signals ();
+				getter = Tracker.Events.get_class_getter ();
+				Tracker.Events.shutdown ();
+			}
+
+			yield Tracker.Store.pause ();
+
+			var journal = File.new_for_uri (journal_uri);
+
+			var notifier = (Status) (Tracker.DBus.get_object (typeof (Status)));
+
+			var busy_callback = notifier.get_callback ();
+
+			Error restore_error = null;
+			Data.backup_restore (journal, error => {
+				restore_error = error;
+				restore.callback ();
+			}, null, busy_callback);
+			yield;
+
+			if (restore_error != null) {
+				throw restore_error;
+			}
+
+			if (resources != null) {
+				Tracker.Events.init (getter);
+				resources.enable_signals ();
+			}
+
+			Tracker.Store.resume ();
+
+			request.end ();
+		} catch (Error e) {
+			request.end (e);
+			throw e;
+		}
+	}
+}
diff --git a/src/tracker-store/tracker-config.vapi b/src/tracker-store/tracker-config.vapi
new file mode 100644
index 0000000..72888da
--- /dev/null
+++ b/src/tracker-store/tracker-config.vapi
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011, Nokia <ivan frade nokia com>
+ *
+ * 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.
+ */
+
+namespace Tracker {
+	[CCode (cheader_filename = "tracker-store/tracker-config.h")]
+	public class Config : ConfigFile {
+		public Config ();
+		public bool save ();
+		public int verbosity { get; set; }
+	}
+}
diff --git a/src/tracker-store/tracker-dbus.vala b/src/tracker-store/tracker-dbus.vala
new file mode 100644
index 0000000..37104f5
--- /dev/null
+++ b/src/tracker-store/tracker-dbus.vala
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2006, Jamie McCracken <jamiemcc gnome org>
+ * Copyright (C) 2008, Nokia <ivan frade nokia com>
+ *
+ * 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.
+ */
+
+class Tracker.DBus {
+	static DBusConnection connection;
+
+	const string SERVICE = "org.freedesktop.Tracker1";
+
+#if 0
+	static DBusGProxy      *gproxy;
+#endif
+	static SList<Object> objects;
+	static Tracker.Status notifier;
+	static Tracker.Backup backup;
+	static Tracker.Steroids steroids;
+
+#if 0
+	static gboolean
+	dbus_register_service (DBusGProxy  *proxy,
+		               const gchar *name)
+	{
+		GError *error = NULL;
+		guint   result;
+
+		g_message ("Registering D-Bus service...\n"
+			   "  Name:'%s'",
+			   name);
+
+		if (!org_freedesktop_DBus_request_name (proxy,
+			                                name,
+			                                DBUS_NAME_FLAG_DO_NOT_QUEUE,
+			                                &result, &error)) {
+			g_critical ("Could not aquire name:'%s', %s",
+				    name,
+				    error ? error->message : "no error given");
+			g_error_free (error);
+
+			return FALSE;
+		}
+
+		if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+			g_critical ("D-Bus service name:'%s' is already taken, "
+				    "perhaps the daemon is already running?",
+				    name);
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+#endif
+
+	static void register_object<T> (DBusConnection lconnection, T object, string path) {
+		message ("Registering D-Bus object...");
+		message ("  Path:'%s'", path);
+		message ("  Type:'%s'", typeof (T).name ());
+
+		lconnection.register_object (path, object);
+	}
+
+	public static bool register_names () {
+		/* Register the service name for org.freedesktop.Tracker */
+		Bus.own_name_on_connection (connection, SERVICE, (BusNameOwnerFlags) 1 << 2 /* DBUS_NAME_FLAG_DO_NOT_QUEUE */,
+			() => { /* name acquired */ },
+			() => { /* name lost, TODO: shutdown */ });
+
+		return true;
+	}
+
+	public static bool init () {
+#if 0
+		GError *error = NULL;
+
+		/* Don't reinitialize */
+		if (objects) {
+			return TRUE;
+		}
+#endif
+
+		if (connection != null) {
+			critical ("The DBus connection is already set, have we already initialized?");
+			return false;
+		}
+
+#if 0
+		if (gproxy) {
+			g_critical ("The DBusGProxy is already set, have we already initialized?");
+			return FALSE;
+		}
+#endif
+
+		try {
+			connection = Bus.get_sync (BusType.SESSION);
+		} catch (Error e) {
+			critical ("Could not connect to the D-Bus session bus, %s", e.message);
+			return false;
+		}
+
+#if 0
+		/* The definitions below (DBUS_SERVICE_DBUS, etc) are
+		 * predefined for us to just use (dbus_g_proxy_...)
+		 */
+		gproxy = dbus_g_proxy_new_for_name (connection,
+			                            DBUS_SERVICE_DBUS,
+			                            DBUS_PATH_DBUS,
+			                            DBUS_INTERFACE_DBUS);
+
+		dbus_g_proxy_add_signal (gproxy, "NameOwnerChanged",
+			                 G_TYPE_STRING,
+			                 G_TYPE_STRING,
+			                 G_TYPE_STRING,
+			                 G_TYPE_INVALID);
+#endif
+
+		return true;
+	}
+
+#if 0
+	static void
+	name_owner_changed_cb (DBusGProxy *proxy,
+		               gchar      *name,
+		               gchar      *old_owner,
+		               gchar      *new_owner,
+		               gpointer    user_data)
+	{
+		if (tracker_is_empty_string (new_owner) && !tracker_is_empty_string (old_owner)) {
+			/* This means that old_owner got removed */
+			tracker_resources_unreg_batches (user_data, old_owner);
+		}
+	}
+
+	static void
+	name_owner_changed_closure (gpointer  data,
+		                    GClosure *closure)
+	{
+	}
+
+	static void
+	dbus_set_available (gboolean available)
+	{
+		if (available) {
+			if (!objects) {
+				tracker_dbus_register_objects ();
+			}
+		} else {
+			GSList *l;
+
+			if (objects) {
+				dbus_g_proxy_disconnect_signal (gproxy,
+					                        "NameOwnerChanged",
+					                        G_CALLBACK (name_owner_changed_cb),
+					                        tracker_dbus_get_object (TRACKER_TYPE_RESOURCES));
+			}
+
+
+			for (l = objects; l; l = l->next) {
+				dbus_g_connection_unregister_g_object (connection, l->data);
+				g_object_unref (l->data);
+			}
+
+			g_slist_free (objects);
+			objects = NULL;
+		}
+	}
+
+	void
+	tracker_dbus_shutdown (void)
+	{
+		dbus_set_available (FALSE);
+
+		if (backup) {
+			dbus_g_connection_unregister_g_object (connection, G_OBJECT (backup));
+			g_object_unref (backup);
+		}
+
+		if (notifier) {
+			dbus_g_connection_unregister_g_object (connection, G_OBJECT (notifier));
+			g_object_unref (notifier);
+		}
+
+		if (gproxy) {
+			g_object_unref (gproxy);
+			gproxy = NULL;
+		}
+
+		connection = NULL;
+	}
+#endif
+
+	public static Tracker.Status? register_notifier () {
+		if (connection == null /* || !gproxy */) {
+			critical ("D-Bus support must be initialized before registering objects!");
+			return null;
+		}
+
+		/* Add org.freedesktop.Tracker */
+		notifier = new Tracker.Status ();
+		if (notifier == null) {
+			critical ("Could not create TrackerStatus object to register");
+			return null;
+		}
+
+		register_object (connection, notifier, Tracker.Status.PATH);
+
+		return notifier;
+	}
+
+	public static bool register_objects () {
+		//gpointer object, resources;
+
+		if (connection == null /*|| !gproxy*/) {
+			critical ("D-Bus support must be initialized before registering objects!");
+			return false;
+		}
+
+#if 0
+		/* Add org.freedesktop.Tracker */
+		object = tracker_statistics_new ();
+		if (!object) {
+			g_critical ("Could not create TrackerStatistics object to register");
+			return FALSE;
+		}
+
+		dbus_register_object (connection,
+			              gproxy,
+			              G_OBJECT (object),
+			              &dbus_glib_tracker_statistics_object_info,
+			              TRACKER_STATISTICS_PATH);
+		objects = g_slist_prepend (objects, object);
+#endif
+
+		/* Add org.freedesktop.Tracker1.Resources */
+		var resources = new Tracker.Resources (connection);
+		if (resources == null) {
+			critical ("Could not create TrackerResources object to register");
+			return false;
+		}
+
+#if 0
+		dbus_g_proxy_connect_signal (gproxy, "NameOwnerChanged",
+			                     G_CALLBACK (name_owner_changed_cb),
+			                     object,
+			                     name_owner_changed_closure);
+#endif
+
+		register_object (connection, resources, Tracker.Resources.PATH);
+		//objects = g_slist_prepend (objects, object);
+
+		/* Add org.freedesktop.Tracker1.Steroids */
+		steroids = new Tracker.Steroids ();
+		if (steroids == null) {
+			critical ("Could not create TrackerSteroids object to register");
+			return false;
+		}
+
+		register_object (connection, steroids, Tracker.Steroids.PATH);
+		//objects = g_slist_prepend (objects, object);
+
+#if 0
+		/* Reverse list since we added objects at the top each time */
+		objects = g_slist_reverse (objects);
+
+		if (backup == null) {
+			/* Add org.freedesktop.Tracker1.Backup */
+			backup = tracker_backup_new ();
+			if (!backup) {
+				g_critical ("Could not create TrackerBackup object to register");
+				return FALSE;
+			}
+
+			dbus_register_object (connection,
+				              gproxy,
+				              G_OBJECT (backup),
+				              &dbus_glib_tracker_backup_object_info,
+				              TRACKER_BACKUP_PATH);
+			/* Backup object isn't part of the linked list, set_available wouldn't
+			 * work correctly from the dbus call otherwise */
+		}
+#endif
+
+		return true;
+	}
+
+#if 0
+	gboolean
+	tracker_dbus_register_prepare_class_signal (void)
+	{
+		gpointer resources;
+
+		resources = tracker_dbus_get_object (TRACKER_TYPE_RESOURCES);
+
+		if (!resources) {
+			g_message ("Error during initialization, Resources DBus object not available");
+			return FALSE;
+		}
+
+		tracker_resources_enable_signals (resources);
+
+		return TRUE;
+	}
+#endif
+
+	public static Object? get_object (Type type) {
+		foreach (var object in objects) {
+			if (object.get_type () == type) {
+				return object;
+			}
+		}
+
+		if (type == typeof (Steroids)) {
+			return steroids;
+		}
+
+		if (type == typeof (Status)) {
+			return notifier;
+		}
+
+		if (type == typeof (Backup)) {
+			return backup;
+		}
+
+		return null;
+	}
+}
diff --git a/src/tracker-store/tracker-events.vapi b/src/tracker-store/tracker-events.vapi
new file mode 100644
index 0000000..83e6a56
--- /dev/null
+++ b/src/tracker-store/tracker-events.vapi
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011, Nokia <ivan frade nokia com>
+ *
+ * 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.
+ */
+
+namespace Tracker {
+	[CCode (has_array_length = false, array_null_terminated = true, has_target = false, cheader_filename = "tracker-store/tracker-events.h")]
+	public delegate string[] NotifyClassGetter ();
+
+	[CCode (cheader_filename = "tracker-store/tracker-events.h")]
+	namespace Events {
+		public void init (NotifyClassGetter callback);
+		public NotifyClassGetter get_class_getter ();
+		public void shutdown ();
+		public void add_insert (int graph_id, int subject_id, string subject, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
+		public void add_delete (int graph_id, int subject_id, string subject, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
+		public void classes_iter (GLib.HashTableIter iter);
+		public uint get_total (bool and_reset);
+		public void reset_pending ();
+		public void freeze ();
+	}
+}
diff --git a/src/tracker-store/tracker-locale-change.c b/src/tracker-store/tracker-locale-change.c
index 5a7495c..7c02148 100644
--- a/src/tracker-store/tracker-locale-change.c
+++ b/src/tracker-store/tracker-locale-change.c
@@ -17,6 +17,8 @@
  * Boston, MA  02110-1301, USA.
  */
 
+#if 0
+
 #include "config.h"
 
 #include <stdlib.h>
@@ -140,3 +142,5 @@ tracker_locale_change_shutdown_subscription (void)
 {
 	tracker_locale_notify_remove (locale_notification_id);
 }
+
+#endif
diff --git a/src/tracker-store/tracker-main.vala b/src/tracker-store/tracker-main.vala
new file mode 100644
index 0000000..a935217
--- /dev/null
+++ b/src/tracker-store/tracker-main.vala
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 2006, Jamie McCracken <jamiemcc gnome org>
+ * Copyright (C) 2008, Nokia <ivan frade nokia com>
+ *
+ * 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.
+ */
+
+class Tracker.Main {
+#if 0
+
+//const string ABOUT = "Tracker " PACKAGE_VERSION "\n";
+
+const string LICENSE = "This program is free software and comes without any warranty.
+It is licensed under version 2 or later of the General Public
+License which can be viewed at:
+  http://www.gnu.org/licenses/gpl.txt
+";
+
+#endif
+
+	const int SELECT_CACHE_SIZE = 100;
+	const int UPDATE_CACHE_SIZE = 100;
+
+	static MainLoop main_loop;
+	static string log_filename;
+
+	static string ttl_backup_file;
+
+	static bool first_time_index;
+	static bool reindex_on_shutdown;
+	static bool shutdown;
+
+/* Private command line parameters */
+	static bool version;
+	static int verbosity = -1;
+	static bool force_reindex;
+	static bool readonly_mode;
+
+	const OptionEntry entries[] = {
+		/* Daemon options */
+		{ "version", 'V', 0, OptionArg.NONE, ref version, N_("Displays version information"), null },
+		{ "verbosity", 'v', 0, OptionArg.INT, ref verbosity, N_("Logging, 0 = errors only, 1 = minimal, 2 = detailed and 3 = debug (default = 0)"), null },
+
+		/* Indexer options */
+		{ "force-reindex", 'r', 0, OptionArg.NONE, ref force_reindex, N_("Force a re-index of all content"), null },
+		{ "readonly-mode", 'n', 0, OptionArg.NONE, ref readonly_mode, N_("Only allow read based actions on the database"), null },
+		{ null }
+	};
+
+#if 0
+static void
+private_free (gpointer data)
+{
+	TrackerMainPrivate *private;
+
+	private = data;
+
+	g_free (private->ttl_backup_file);
+	g_free (private->log_filename);
+
+	g_main_loop_unref (private->main_loop);
+
+	g_free (private);
+}
+
+static void
+sanity_check_option_values (TrackerConfig *config)
+{
+	g_message ("General options:");
+	g_message ("  Verbosity  ............................  %d",
+	           tracker_config_get_verbosity (config));
+
+	g_message ("Store options:");
+	g_message ("  Readonly mode  ........................  %s",
+	           readonly_mode ? "yes" : "no");
+}
+#endif
+
+	static void do_shutdown () {
+		if (main_loop != null) {
+			main_loop.quit ();
+		}
+
+		shutdown = true;
+	}
+
+#if 0
+static gboolean
+shutdown_timeout_cb (gpointer user_data)
+{
+	g_critical ("Could not exit in a timely fashion - terminating...");
+	exit (EXIT_FAILURE);
+
+	return FALSE;
+}
+
+static void
+signal_handler (int signo)
+{
+	static gboolean in_loop = FALSE;
+
+	/* Die if we get re-entrant signals handler calls */
+	if (in_loop) {
+		_exit (EXIT_FAILURE);
+	}
+
+	switch (signo) {
+	case SIGTERM:
+	case SIGINT:
+		in_loop = TRUE;
+		do_shutdown ();
+
+		/* Fall through */
+	default:
+		if (g_strsignal (signo)) {
+			g_print ("\n");
+			g_print ("Received signal:%d->'%s'",
+			         signo,
+			         g_strsignal (signo));
+		}
+		break;
+	}
+}
+
+static void
+initialize_signal_handler (void)
+{
+	struct sigaction act;
+	sigset_t         empty_mask;
+
+	sigemptyset (&empty_mask);
+	act.sa_handler = signal_handler;
+	act.sa_mask    = empty_mask;
+	act.sa_flags   = 0;
+
+	sigaction (SIGTERM, &act, NULL);
+	sigaction (SIGINT,  &act, NULL);
+	sigaction (SIGHUP,  &act, NULL);
+}
+
+static void
+initialize_priority (void)
+{
+	/* Set disk IO priority and scheduling */
+	tracker_ioprio_init ();
+
+	/* NOTE: We only set the nice() value when crawling, for all
+	 * other times we don't have a nice() value. Check the
+	 * tracker-status code to see where this is done.
+	 */
+}
+
+static void
+initialize_directories (void)
+{
+	/* NOTE: We don't create the database directories here, the
+	 * tracker-db-manager does that for us.
+	 */
+}
+
+static void
+shutdown_databases (void)
+{
+#if 0
+	TrackerMainPrivate *private;
+
+	private = g_static_private_get (&private_key);
+
+	/* TODO port backup support */
+
+	/* If we are reindexing, save the user metadata  */
+	if (private->reindex_on_shutdown) {
+		tracker_data_backup_save (private->ttl_backup_file, NULL);
+	}
+#endif
+}
+
+static void
+shutdown_directories (void)
+{
+	TrackerMainPrivate *private;
+
+	private = g_static_private_get (&private_key);
+
+	/* If we are reindexing, just remove the databases */
+	if (private->reindex_on_shutdown) {
+		tracker_db_manager_remove_all (FALSE);
+	}
+}
+
+static GStrv
+get_notifiable_classes (void)
+{
+	TrackerDBResultSet *result_set;
+	GStrv classes_to_signal = NULL;
+
+	result_set = tracker_data_query_sparql ("SELECT ?class WHERE { "
+	                                        "  ?class tracker:notify true "
+	                                        "}",
+	                                        NULL);
+
+	if (result_set) {
+		guint count = 0;
+
+		classes_to_signal = tracker_dbus_query_result_to_strv (result_set,
+		                                                       0,
+		                                                       &count);
+		g_object_unref (result_set);
+	}
+
+	return classes_to_signal;
+}
+
+
+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;
+}
+#endif
+
+	static void config_verbosity_changed_cb (Object object, ParamSpec? spec) {
+		int verbosity = ((Tracker.Config) object).verbosity;
+
+		message ("Log verbosity is set to %d, %s D-Bus client lookup",
+		         verbosity,
+		         verbosity > 0 ? "enabling" : "disabling");
+
+		Tracker.DBusRequest.enable_client_lookup (verbosity > 0);
+	}
+
+	static int main (string args[]) {
+#if 0
+		GError *error = NULL;
+		gint chunk_size_mb;
+		gsize chunk_size;
+		const gchar *rotate_to;
+		gboolean do_rotating;
+#endif
+
+		Intl.setlocale (LocaleCategory.ALL, "");
+
+#if 0
+		bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+		bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+		textdomain (GETTEXT_PACKAGE);
+
+		/* Set timezone info */
+		tzset ();
+#endif
+
+		try {
+			/* Translators: this messagge will apper immediately after the
+			 * usage string - Usage: COMMAND <THIS_MESSAGE>
+			 */
+			var context = new OptionContext (_("- start the tracker daemon"));
+			context.add_main_entries (entries, null);
+			context.parse (ref args);
+		} catch (Error e) {
+			printerr ("Invalid arguments, %s\n", e.message);
+			return 1;
+		}
+
+		if (version) {
+			/* Print information */
+			//print ("\n" ABOUT "\n" LICENSE "\n");
+			return 0;
+		}
+
+		print ("Initializing tracker-store...\n");
+
+#if 0
+		initialize_signal_handler ();
+
+		/* Check XDG spec locations XDG_DATA_HOME _MUST_ be writable. */
+		if (!tracker_env_check_xdg_dirs ()) {
+			return EXIT_FAILURE;
+		}
+
+		/* This makes sure we don't steal all the system's resources */
+		initialize_priority ();
+
+		/* Public locations */
+		private->ttl_backup_file =
+			g_build_filename (g_get_user_data_dir (),
+				          "tracker",
+				          "data",
+				          "tracker-userdata-backup.ttl",
+				          NULL);
+#endif
+
+		/* Initialize major subsystems */
+		var config = new Tracker.Config ();
+		var db_config = new Tracker.DBConfig ();
+
+		config.notify["verbosity"].connect (config_verbosity_changed_cb);
+
+		/* Daemon command line arguments */
+		if (verbosity > -1) {
+			config.verbosity = verbosity;
+		} else {
+			/* Make sure we enable/disable the dbus client lookup */
+			config_verbosity_changed_cb (config, null);
+		}
+
+#if 0
+		initialize_directories ();
+#endif
+
+		if (!Tracker.DBus.init ()) {
+			return 1;
+		}
+
+		/* Initialize other subsystems */
+		Tracker.Log.init (3 /*tracker_config_get_verbosity (config)*/, out log_filename);
+		print ("Starting log:\n  File:'%s'\n", log_filename);
+
+#if 0
+		sanity_check_option_values (config);
+#endif
+
+		DBManagerFlags flags = DBManagerFlags.REMOVE_CACHE;
+
+		if (force_reindex) {
+			/* TODO port backup support
+			   backup_user_metadata (config, language); */
+
+			flags |= DBManagerFlags.FORCE_REINDEX;
+		}
+
+		var notifier = Tracker.DBus.register_notifier ();
+		var busy_callback = notifier.get_callback ();
+
+		Tracker.Store.init ();
+
+		/* Make Tracker available for introspection */
+		if (!Tracker.DBus.register_objects ()) {
+			return 1;
+		}
+
+		if (!Tracker.DBus.register_names ()) {
+			return 1;
+		}
+
+#if 0
+		chunk_size_mb = tracker_db_config_get_journal_chunk_size (db_config);
+		chunk_size = (gsize) ((gsize) chunk_size_mb * (gsize) 1024 * (gsize) 1024);
+		rotate_to = tracker_db_config_get_journal_rotate_destination (db_config);
+
+		if (rotate_to[0] == '\0')
+			rotate_to = NULL;
+
+		do_rotating = (chunk_size_mb != -1);
+
+		tracker_db_journal_set_rotating (do_rotating, chunk_size, rotate_to);
+#endif
+
+		int select_cache_size, update_cache_size;
+		string cache_size_s;
+
+		cache_size_s = Environment.get_variable ("TRACKER_STORE_SELECT_CACHE_SIZE");
+		if (cache_size_s != null && cache_size_s != "") {
+			select_cache_size = cache_size_s.to_int ();
+		} else {
+			select_cache_size = SELECT_CACHE_SIZE;
+		}
+
+		cache_size_s = Environment.get_variable ("TRACKER_STORE_UPDATE_CACHE_SIZE");
+		if (cache_size_s != null && cache_size_s != "") {
+			update_cache_size = cache_size_s.to_int ();
+		} else {
+			update_cache_size = UPDATE_CACHE_SIZE;
+		}
+
+		bool is_first_time_index;
+
+		if (!Tracker.Data.Manager.init (flags,
+			                        null,
+			                        out is_first_time_index,
+			                        true,
+			                        select_cache_size,
+			                        update_cache_size,
+			                        busy_callback,
+			                        "Initializing")) {
+
+			return 1;
+		}
+
+
+#if 0
+		g_object_unref (db_config);
+		g_object_unref (notifier);
+#endif
+
+		if (!shutdown) {
+#if 0
+			/* Setup subscription to get notified of locale changes */
+			tracker_locale_change_initialize_subscription ();
+
+			tracker_dbus_register_prepare_class_signal ();
+
+			tracker_events_init (get_notifiable_classes);
+			tracker_writeback_init (get_writeback_predicates);
+#endif
+			Tracker.Store.resume ();
+
+			message ("Waiting for D-Bus requests...");
+		}
+
+		/* Set our status as running, if this is FALSE, threads stop
+		 * doing what they do and shutdown.
+		 */
+		if (!shutdown) {
+			main_loop = new MainLoop ();
+			main_loop.run ();
+		}
+
+		/*
+		 * Shutdown the daemon
+		 */
+		message ("Shutdown started");
+
+#if 0
+		tracker_store_shutdown ();
+
+		g_timeout_add_full (G_PRIORITY_LOW, 5000, shutdown_timeout_cb, NULL, NULL);
+
+		g_message ("Cleaning up");
+
+		shutdown_databases ();
+		shutdown_directories ();
+
+		/* Shutdown major subsystems */
+		tracker_writeback_shutdown ();
+		tracker_events_shutdown ();
+
+		tracker_locale_change_shutdown_subscription ();
+
+		tracker_dbus_shutdown ();
+		tracker_data_manager_shutdown ();
+		tracker_log_shutdown ();
+
+		g_signal_handlers_disconnect_by_func (config, config_verbosity_changed_cb, NULL);
+		g_object_unref (config);
+
+		/* This will free rotate_to up in the journal code */
+		tracker_db_journal_set_rotating ((chunk_size_mb != -1), chunk_size, NULL);
+#endif
+
+		print ("\nOK\n\n");
+
+		return 0;
+	}
+}
diff --git a/src/tracker-store/tracker-resources.vala b/src/tracker-store/tracker-resources.vala
new file mode 100644
index 0000000..1f71e79
--- /dev/null
+++ b/src/tracker-store/tracker-resources.vala
@@ -0,0 +1,704 @@
+/*
+ * Copyright (C) 2006, Jamie McCracken <jamiemcc gnome org>
+ * Copyright (C) 2008, Nokia <ivan frade nokia com>
+ *
+ * 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.
+ */
+
+#if 0
+
+const int TRACKER_GRAPH_UPDATED_IMMEDIATE_EMIT_AT = 1000;
+const int TRACKER_SIGNALS_SECONDS_PER_EMIT = 1;
+
+//#define RDF_PREFIX TRACKER_RDF_PREFIX
+//#define RDF_TYPE RDF_PREFIX "type"
+
+/* I *know* that this is some arbitrary number that doesn't seem to
+ * resemble anything. In fact it's what I experimentally measured to
+ * be a good value on a default Debian testing which has
+ * max_message_size set to 1 000 000 000 in session.conf. I didn't have
+ * the feeling that this value was very much respected, as the size
+ * of the DBusMessage when libdbus decided to exit() the process was
+ * around 160 MB, and not ~ 1000 MB. So if you take 160 MB and you
+ * devide it by 1000000 you have an average string size of ~ 160
+ * bytes plus DBusMessage's overhead. If that makes this number less
+ * arbitrary for you, then fine.
+ *
+ * I really hope that the libdbus people get to their senses and
+ * either stop doing their exit() nonsense in a library, and instead
+ * return a clean DBusError or something, or create crystal clear
+ * clarity about the maximum size of a message. And make it both so
+ * that I can get this length at runtime (without having to parse
+ * libdbus's own configuration files) and my DBusMessage's current
+ * total length. As far as I know are both not possible. So that for
+ * me means that libdbus's exit() is unacceptable.
+ *
+ * Note for the debugger of the future, the "Disconnected" signal gets
+ * sent to us by the bus, which in turn makes libdbus-glib perform exit(). */
+
+const int DBUS_ARBITRARY_MAX_MSG_SIZE = 1000000;
+#endif
+
+[DBus (name = "org.freedesktop.Tracker1.Resources")]
+class Tracker.Resources : Object {
+	public const string PATH = "/org/freedesktop/Tracker1/Resources";
+#if 0
+	enum {
+		WRITEBACK,
+		GRAPHUPDATED,
+		LAST_SIGNAL
+	};
+
+	typedef struct {
+		DBusConnection *connection;
+		guint signal_timeout;
+	} TrackerResourcesPrivate;
+
+	typedef struct {
+		DBusGMethodInvocation *context;
+		guint request_id;
+		DBusMessage *reply;
+	} TrackerDBusMethodInfo;
+
+	typedef struct {
+		DBusMessage *reply;
+		GError *error;
+		gpointer user_data;
+	} InThreadPtr;
+
+	static void tracker_resources_finalize (GObject *object);
+	static guint signals[LAST_SIGNAL] = { 0 };
+
+	static void
+	tracker_resources_class_init (TrackerResourcesClass *klass)
+	{
+		GObjectClass *object_class;
+
+		object_class = G_OBJECT_CLASS (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,
+				      g_cclosure_marshal_VOID__BOXED,
+				      G_TYPE_NONE, 1,
+				      TRACKER_TYPE_INT_ARRAY_MAP);
+
+		/* This is just for introspection to work */
+		signals[GRAPHUPDATED] =
+			g_signal_new ("graph-updated",
+				      G_OBJECT_CLASS_TYPE (object_class),
+				      G_SIGNAL_RUN_LAST,
+				      G_STRUCT_OFFSET (TrackerResourcesClass, graph_updated),
+				      NULL, NULL,
+				      tracker_marshal_VOID__STRING_BOXED_BOXED,
+				      G_TYPE_NONE, 3,
+				      G_TYPE_STRING,
+				      TRACKER_TYPE_FOUR_INT_ARRAY,
+				      TRACKER_TYPE_FOUR_INT_ARRAY);
+
+		g_type_class_add_private (object_class, sizeof (TrackerResourcesPrivate));
+	}
+#endif
+
+	public Resources (DBusConnection connection) {
+#if 0
+		TrackerResourcesPrivate *priv;
+		TrackerResources *resources = g_object_new (TRACKER_TYPE_RESOURCES, NULL);
+
+		priv = TRACKER_RESOURCES_GET_PRIVATE (resources);
+
+		priv->connection = dbus_connection_ref (dbus_g_connection_get_connection (connection));
+#endif
+	}
+
+	public async void load (BusName sender, string uri) throws Error {
+		var request = DBusRequest.begin (sender, "Resources.Load (uri: '%s')", uri);
+		try {
+			var file = File.new_for_uri (uri);
+
+			yield Tracker.Store.queue_turtle_import (file, sender);
+
+			request.end ();
+		} catch (Error e) {
+			request.end (e);
+			throw e;
+		}
+	}
+
+#if 0
+	static void
+	query_callback (gpointer inthread_data, GError *error, gpointer user_data)
+	{
+		InThreadPtr *ptr = inthread_data;
+		TrackerDBusMethodInfo *info = user_data;
+
+		if (ptr && ptr->error) {
+			tracker_dbus_request_failed (info->request_id,
+				                     info->context,
+				                     &ptr->error,
+				                     NULL);
+			dbus_g_method_return_error (info->context, ptr->error);
+			g_error_free (ptr->error);
+		} else if (error) {
+			tracker_dbus_request_failed (info->request_id,
+				                     info->context,
+				                     &error,
+				                     NULL);
+			dbus_g_method_return_error (info->context, error);
+		} else if (ptr) {
+			tracker_dbus_request_success (info->request_id,
+				                      info->context);
+
+			dbus_g_method_send_reply (info->context, ptr->reply);
+		} /* else, !ptr && !error... shouldn't happen */
+
+		if (ptr)
+			g_slice_free (InThreadPtr, ptr);
+	}
+
+	static gpointer
+	query_inthread (TrackerDBCursor *cursor, GCancellable *cancellable, GError *error, gpointer user_data)
+	{
+		InThreadPtr *ptr = g_slice_new0 (InThreadPtr);
+		TrackerDBusMethodInfo *info = user_data;
+		DBusMessage *reply;
+		DBusMessageIter iter, rows_iter;
+		guint cols;
+		GError *loop_error = NULL;
+		guint length = 0;
+		gboolean cont;
+
+		if (error) {
+			ptr->error = g_error_copy (error);
+			return ptr;
+		}
+
+		reply = info->reply;
+
+		dbus_message_iter_init_append (reply, &iter);
+
+		cols = tracker_db_cursor_get_n_columns (cursor);
+
+		dbus_message_iter_open_container (&iter,
+			                          DBUS_TYPE_ARRAY,
+			                          "as",
+			                          &rows_iter);
+
+		cont = TRUE;
+
+		while (tracker_db_cursor_iter_next (cursor, cancellable, &loop_error) && cont) {
+			DBusMessageIter cols_iter;
+			guint i;
+
+			if (loop_error != NULL) {
+				break;
+			}
+
+			dbus_message_iter_open_container (&rows_iter,
+				                          DBUS_TYPE_ARRAY,
+				                          "s",
+				                          &cols_iter);
+
+			for (i = 0; i < cols && cont; i++, length++) {
+				const gchar *result_str;
+				result_str = tracker_db_cursor_get_string (cursor, i, NULL);
+
+				if (result_str == NULL)
+					result_str = "";
+
+				dbus_message_iter_append_basic (&cols_iter, DBUS_TYPE_STRING, &result_str);
+
+				if (length > DBUS_ARBITRARY_MAX_MSG_SIZE) {
+					g_set_error (&loop_error,
+						     TRACKER_DB_INTERFACE_ERROR,
+						     TRACKER_DB_INTERRUPTED,
+						     "result set of the query is too large");
+
+					cont = FALSE;
+				}
+
+			}
+
+			dbus_message_iter_close_container (&rows_iter, &cols_iter);
+		}
+
+		dbus_message_iter_close_container (&iter, &rows_iter);
+
+		if (loop_error) {
+			ptr->error = loop_error;
+			ptr->reply = NULL;
+		} else {
+			ptr->reply = reply;
+		}
+
+		return ptr;
+	}
+
+	void
+	tracker_resources_sparql_query (TrackerResources         *self,
+		                        const gchar              *query,
+		                        DBusGMethodInvocation    *context,
+		                        GError                  **error)
+	{
+		TrackerDBusMethodInfo   *info;
+		guint                 request_id;
+		gchar                 *sender;
+
+		request_id = tracker_dbus_get_next_request_id ();
+
+		tracker_dbus_async_return_if_fail (query != NULL, context);
+
+		tracker_dbus_request_new (request_id,
+			                  context,
+			                  "%s(): '%s'",
+			                  __FUNCTION__,
+			                  query);
+
+		info = g_slice_new (TrackerDBusMethodInfo);
+
+		info->request_id = request_id;
+		info->context = context;
+		info->reply = dbus_g_method_get_reply (context);
+
+		sender = dbus_g_method_get_sender (context);
+
+		tracker_store_sparql_query (query, TRACKER_STORE_PRIORITY_HIGH,
+			                    query_inthread, query_callback, sender,
+			                    info, destroy_method_info);
+
+		g_free (sender);
+	}
+
+	static void
+	update_callback (GError *error, gpointer user_data)
+	{
+		TrackerDBusMethodInfo *info = user_data;
+
+		if (error) {
+			tracker_dbus_request_failed (info->request_id,
+				                     info->context,
+				                     &error,
+				                     NULL);
+			dbus_g_method_return_error (info->context, error);
+			return;
+		}
+
+		tracker_dbus_request_success (info->request_id,
+			                      info->context);
+		dbus_g_method_return (info->context);
+	}
+
+	void
+	tracker_resources_sparql_update (TrackerResources        *self,
+		                         const gchar             *update,
+		                         DBusGMethodInvocation   *context,
+		                         GError                 **error)
+	{
+		TrackerDBusMethodInfo   *info;
+		guint                 request_id;
+		gchar                 *sender;
+
+		request_id = tracker_dbus_get_next_request_id ();
+
+		tracker_dbus_async_return_if_fail (update != NULL, context);
+
+		tracker_dbus_request_new (request_id,
+			                  context,
+			                  "%s(): '%s'",
+			                  __FUNCTION__,
+			                  update);
+
+		info = g_slice_new (TrackerDBusMethodInfo);
+
+		info->request_id = request_id;
+		info->context = context;
+
+		sender = dbus_g_method_get_sender (context);
+
+		tracker_store_sparql_update (update, TRACKER_STORE_PRIORITY_HIGH,
+			                     update_callback, sender,
+			                     info, destroy_method_info);
+
+		g_free (sender);
+	}
+
+	static void
+	update_blank_callback (GPtrArray *blank_nodes, GError *error, gpointer user_data)
+	{
+		TrackerDBusMethodInfo *info = user_data;
+
+		if (error) {
+			tracker_dbus_request_failed (info->request_id,
+				                     info->context,
+				                     &error,
+				                     NULL);
+			dbus_g_method_return_error (info->context, error);
+			return;
+		}
+
+		tracker_dbus_request_success (info->request_id,
+			                      info->context);
+		dbus_g_method_return (info->context, blank_nodes);
+	}
+
+	void
+	tracker_resources_sparql_update_blank (TrackerResources       *self,
+		                               const gchar            *update,
+		                               DBusGMethodInvocation  *context,
+		                               GError                **error)
+	{
+		TrackerDBusMethodInfo   *info;
+		guint                 request_id;
+		gchar                 *sender;
+
+		request_id = tracker_dbus_get_next_request_id ();
+
+		tracker_dbus_async_return_if_fail (update != NULL, context);
+
+		tracker_dbus_request_new (request_id,
+			                  context,
+			                  "%s(): '%s'",
+			                  __FUNCTION__,
+			                  update);
+
+		info = g_slice_new (TrackerDBusMethodInfo);
+
+		info->request_id = request_id;
+		info->context = context;
+
+		sender = dbus_g_method_get_sender (context);
+
+		tracker_store_sparql_update_blank (update, TRACKER_STORE_PRIORITY_HIGH,
+			                           update_blank_callback, sender,
+			                           info, destroy_method_info);
+
+		g_free (sender);
+	}
+#endif
+
+	public void sync (BusName sender) {
+		var request = DBusRequest.begin (sender, "Resources.Sync");
+
+		Data.sync ();
+
+		request.end ();
+	}
+
+#if 0
+	void
+	tracker_resources_batch_sparql_update (TrackerResources          *self,
+		                               const gchar               *update,
+		                               DBusGMethodInvocation     *context,
+		                               GError                   **error)
+	{
+		TrackerDBusMethodInfo   *info;
+		guint                 request_id;
+		gchar                 *sender;
+
+		request_id = tracker_dbus_get_next_request_id ();
+
+		tracker_dbus_async_return_if_fail (update != NULL, context);
+
+		tracker_dbus_request_new (request_id,
+			                  context,
+			                  "%s(): '%s'",
+			                  __FUNCTION__,
+			                  update);
+
+		info = g_slice_new (TrackerDBusMethodInfo);
+
+		info->request_id = request_id;
+		info->context = context;
+
+		sender = dbus_g_method_get_sender (context);
+
+		tracker_store_sparql_update (update, TRACKER_STORE_PRIORITY_LOW,
+			                     update_callback, sender,
+			                     info, destroy_method_info);
+
+		g_free (sender);
+	}
+#endif
+
+	public void batch_commit () {
+		/* no longer needed, just return */
+	}
+
+#if 0
+	static void
+	foreach_add_to_iter (gint graph_id,
+		             gint subject_id,
+		             gint pred_id,
+		             gint object_id,
+		             gpointer user_data)
+	{
+		DBusMessageIter *array_iter = user_data;
+		DBusMessageIter struct_iter;
+
+		dbus_message_iter_open_container (array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter);
+		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &graph_id);
+		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &subject_id);
+		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &pred_id);
+		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &object_id);
+		dbus_message_iter_close_container (array_iter, &struct_iter);
+	}
+
+	static gboolean
+	emit_graph_updated (TrackerResources *self,
+		            TrackerClass     *class)
+	{
+		if (tracker_class_has_insert_events (class) || tracker_class_has_delete_events (class)) {
+			TrackerResourcesPrivate *priv;
+			DBusMessageIter iter, deletes_iter, inserts_iter;
+			DBusMessage *message;
+			const gchar *class_uri;
+
+			priv = TRACKER_RESOURCES_GET_PRIVATE (self);
+
+			message = dbus_message_new_signal (TRACKER_RESOURCES_PATH,
+				                           TRACKER_RESOURCES_INTERFACE,
+				                           "GraphUpdated");
+
+			class_uri = tracker_class_get_uri (class);
+
+			dbus_message_iter_init_append (message, &iter);
+			dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &class_uri);
+
+			dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+				                          "(iiii)", &deletes_iter);
+
+			tracker_class_foreach_delete_event (class, foreach_add_to_iter, &deletes_iter);
+
+			dbus_message_iter_close_container (&iter, &deletes_iter);
+
+
+			dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+				                          "(iiii)", &inserts_iter);
+
+			tracker_class_foreach_insert_event (class, foreach_add_to_iter, &inserts_iter);
+
+			dbus_message_iter_close_container (&iter, &inserts_iter);
+
+			dbus_connection_send (priv->connection, message, NULL);
+
+			dbus_message_unref (message);
+
+			tracker_class_reset_ready_events (class);
+
+			return TRUE;
+		}
+
+		return FALSE;
+	}
+
+	static gboolean
+	on_emit_signals (gpointer user_data)
+	{
+		TrackerResources *resources = user_data;
+		TrackerResourcesPrivate *priv;
+		GHashTableIter iter;
+		gpointer key, value;
+		gboolean had_any = FALSE;
+		GHashTable *writebacks;
+
+		priv = TRACKER_RESOURCES_GET_PRIVATE (resources);
+
+		/* Class signal feature */
+		tracker_events_classes_iter (&iter);
+
+		while (g_hash_table_iter_next (&iter, &key, &value)) {
+			TrackerClass *class = key;
+			if (emit_graph_updated (user_data, class)) {
+				had_any = TRUE;
+			}
+		}
+
+		/* Reset counter */
+		tracker_events_get_total (TRUE);
+
+
+		/* Writeback feature */
+		writebacks = tracker_writeback_get_ready ();
+
+		if (writebacks) {
+			had_any = TRUE;
+			g_signal_emit (resources, signals[WRITEBACK], 0, writebacks);
+		}
+
+		tracker_writeback_reset_ready ();
+
+		if (!had_any)
+			priv->signal_timeout = 0;
+
+		return had_any;
+	}
+
+	static void
+	on_statements_committed (gboolean start_timer,
+		                 gpointer user_data)
+	{
+		TrackerResources *resources = user_data;
+		TrackerResourcesPrivate *priv;
+		GHashTableIter iter;
+		gpointer key, value;
+
+		/* Class signal feature */
+
+		priv = TRACKER_RESOURCES_GET_PRIVATE (resources);
+
+		/* Class signal feature */
+		tracker_events_classes_iter (&iter);
+
+		while (g_hash_table_iter_next (&iter, &key, &value)) {
+			TrackerClass *class = key;
+			tracker_class_transact_events (class);
+		}
+
+		if (start_timer && priv->signal_timeout == 0) {
+			priv->signal_timeout = g_timeout_add_seconds (TRACKER_SIGNALS_SECONDS_PER_EMIT,
+				                                      on_emit_signals,
+				                                      user_data);
+		}
+
+		/* Writeback feature */
+		tracker_writeback_transact ();
+	}
+
+
+	static void
+	on_statements_rolled_back (gboolean start_timer,
+		                   gpointer user_data)
+	{
+		tracker_events_reset_pending ();
+		tracker_writeback_reset_pending ();
+	}
+
+	static void
+	check_graph_updated_signal (TrackerResources *object)
+	{
+		TrackerResourcesPrivate *priv;
+
+		priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+
+		/* Check for whether we need an immediate emit */
+		if (tracker_events_get_total (FALSE) > TRACKER_GRAPH_UPDATED_IMMEDIATE_EMIT_AT) {
+			gpointer key, value;
+			GHashTableIter iter;
+
+			tracker_events_classes_iter (&iter);
+			while (g_hash_table_iter_next (&iter, &key, &value)) {
+				TrackerClass *class = key;
+				emit_graph_updated (object, class);
+			}
+
+			/* Reset counter */
+			tracker_events_get_total (TRUE);
+		}
+	}
+
+	static void
+	on_statement_inserted (gint         graph_id,
+		               const gchar *graph,
+		               gint         subject_id,
+		               const gchar *subject,
+		               gint         pred_id,
+		               gint         object_id,
+		               const gchar *object,
+		               GPtrArray   *rdf_types,
+		               gpointer     user_data)
+	{
+		TrackerResourcesPrivate *priv;
+
+		priv = TRACKER_RESOURCES_GET_PRIVATE (user_data);
+
+		tracker_events_add_insert (graph_id, subject_id, subject, pred_id,
+			                   object_id, object, rdf_types);
+		tracker_writeback_check (graph_id, graph, subject_id,
+			                 subject, pred_id, object_id,
+			                 object, rdf_types);
+		check_graph_updated_signal (user_data);
+	}
+
+	static void
+	on_statement_deleted (gint         graph_id,
+		              const gchar *graph,
+		              gint         subject_id,
+		              const gchar *subject,
+		              gint         pred_id,
+		              gint         object_id,
+		              const gchar *object,
+		              GPtrArray   *rdf_types,
+		              gpointer     user_data)
+	{
+		TrackerResourcesPrivate *priv;
+
+		priv = TRACKER_RESOURCES_GET_PRIVATE (user_data);
+
+		tracker_events_add_delete (graph_id, subject_id, subject, pred_id,
+			                   object_id, object, rdf_types);
+		tracker_writeback_check (graph_id, graph, subject_id,
+			                 subject, pred_id, object_id,
+			                 object, rdf_types);
+		check_graph_updated_signal (user_data);
+	}
+#endif
+
+	public void enable_signals () {
+		/*tracker_data_add_insert_statement_callback (on_statement_inserted, object);
+		tracker_data_add_delete_statement_callback (on_statement_deleted, object);
+		tracker_data_add_commit_statement_callback (on_statements_committed, object);
+		tracker_data_add_rollback_statement_callback (on_statements_rolled_back, object);*/
+	}
+
+	public void disable_signals () {
+		/*tracker_data_remove_insert_statement_callback (on_statement_inserted, object);
+		tracker_data_remove_delete_statement_callback (on_statement_deleted, object);
+		tracker_data_remove_commit_statement_callback (on_statements_committed, object);
+		tracker_data_remove_rollback_statement_callback (on_statements_rolled_back, object);
+
+		if (priv->signal_timeout != 0) {
+			g_source_remove (priv->signal_timeout);
+		}*/
+	}
+
+#if 0
+	static void
+	tracker_resources_finalize (GObject *object)
+	{
+		TrackerResourcesPrivate *priv;
+
+		priv = TRACKER_RESOURCES_GET_PRIVATE (object);
+
+		tracker_resources_disable_signals ((TrackerResources *) object);
+
+		dbus_connection_unref (priv->connection);
+
+		G_OBJECT_CLASS (tracker_resources_parent_class)->finalize (object);
+	}
+
+	void
+	tracker_resources_unreg_batches (TrackerResources *object,
+		                         const gchar      *old_owner)
+	{
+		tracker_store_unreg_batches (old_owner);
+	}
+#endif
+}
diff --git a/src/tracker-store/tracker-statistics.vala b/src/tracker-store/tracker-statistics.vala
new file mode 100644
index 0000000..f843433
--- /dev/null
+++ b/src/tracker-store/tracker-statistics.vala
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2006, Jamie McCracken <jamiemcc gnome org>
+ * Copyright (C) 2008, Nokia <ivan frade nokia com>
+ *
+ * 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.
+ */
+
+#if 0
+
+[DBus (name = "org.freedesktop.Tracker1.Statistics")]
+class Tracker.Statistics : Object {
+#if 0
+	static gint
+	cache_sort_func (gconstpointer a,
+		         gconstpointer b)
+	{
+		const GStrv *strv_a = (GStrv *) a;
+		const GStrv *strv_b = (GStrv *) b;
+
+		g_return_val_if_fail (strv_a != NULL, 0);
+		g_return_val_if_fail (strv_b != NULL, 0);
+
+		return g_strcmp0 (*strv_a[0], *strv_b[0]);
+	}
+#endif
+
+	public new string[,] get () {
+		string[,] values = new string[0,0];
+		return values;
+#if 0
+		TrackerClass **classes, *cl;
+		guint                     request_id;
+		GPtrArray                *values;
+		guint                     i, n_classes;
+
+		request_id = tracker_dbus_get_next_request_id ();
+
+		tracker_dbus_request_new (request_id, context, "%s()", __FUNCTION__);
+
+		values = g_ptr_array_new ();
+
+		classes = tracker_ontologies_get_classes (&n_classes);
+
+		for (i = 0; i < n_classes; i++) {
+			GStrv        strv;
+
+			cl = classes[i];
+
+			if (tracker_class_get_count (cl) == 0) {
+				/* skip classes without resources */
+				continue;
+			}
+
+			strv = g_new (gchar*, 3);
+			strv[0] = g_strdup (tracker_class_get_name (cl));
+			strv[1] = g_strdup_printf ("%d", tracker_class_get_count (cl));
+			strv[2] = NULL;
+
+			g_ptr_array_add (values, strv);
+		}
+
+		/* Sort result so it is alphabetical */
+		g_ptr_array_sort (values, cache_sort_func);
+
+		tracker_dbus_request_success (request_id, context);
+		dbus_g_method_return (context, values);
+
+		g_ptr_array_foreach (values, (GFunc) g_strfreev, NULL);
+		g_ptr_array_free (values, TRUE);
+#endif
+	}
+}
+
+#endif
diff --git a/src/tracker-store/tracker-status.vala b/src/tracker-store/tracker-status.vala
new file mode 100644
index 0000000..e17d231
--- /dev/null
+++ b/src/tracker-store/tracker-status.vala
@@ -0,0 +1,139 @@
+/*
+ * 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>
+ */
+
+[DBus (name = "org.freedesktop.Tracker1.Status")]
+class Tracker.Status : Object {
+	public const string PATH = "/org/freedesktop/Tracker1/Status";
+
+	const int PROGRESS_TIMEOUT_S = 5;
+
+	class WaitContext : Object {
+		public SourceFunc callback;
+	}
+
+	double progress;
+	string status = "Idle";
+	uint timer_id;
+	List<WaitContext> wait_list;
+
+#if 0
+	static void
+	tracker_status_class_init (TrackerStatusClass *klass)
+	{
+		/**
+		 * TrackerStatus::progress:
+		 * @notifier: the TrackerStatus
+		 * @status: store status
+		 * @progress: a #gdouble indicating store progress, from 0 to 1.
+		 *
+		 * the ::progress signal will be emitted by TrackerStatus
+		 * to indicate progress about the store process. @status will
+		 * contain a translated string with the current status and @progress
+		 * will indicate how much has been processed so far.
+		 **/
+		signals[PROGRESS] =
+			g_signal_new ("progress",
+				      G_OBJECT_CLASS_TYPE (object_class),
+				      G_SIGNAL_RUN_LAST,
+				      G_STRUCT_OFFSET (TrackerStatusClass, progress),
+				      NULL, NULL,
+				      tracker_marshal_VOID__STRING_DOUBLE,
+				      G_TYPE_NONE, 2,
+				      G_TYPE_STRING,
+				      G_TYPE_DOUBLE);
+
+		g_type_class_add_private (object_class, sizeof (TrackerStatusPrivate));
+	}
+#endif
+
+	~Status () {
+		if (timer_id != 0) {
+			Source.remove (timer_id);
+		}
+	}
+
+	bool
+	busy_notification_timeout () {
+		//progress (0, status, progress);
+
+		timer_id = 0;
+
+		return false;
+	}
+
+	static bool first_time = true;
+
+	void callback (string status, double progress) {
+		this.progress = progress;
+
+		if (progress == 1 && wait_list != null) {
+			/* notify clients that tracker-store is no longer busy */
+
+			wait_list.reverse ();
+			foreach (var context in wait_list) {
+				context.callback ();
+			}
+
+			wait_list = null;
+		}
+
+		if (status != this.status) {
+			this.status = status;
+		}
+
+		if (timer_id == 0) {
+			if (first_time) {
+				this.timer_id = Idle.add (busy_notification_timeout);
+				first_time = false;
+			} else {
+				timer_id = Timeout.add_seconds (PROGRESS_TIMEOUT_S, busy_notification_timeout);
+			}
+		}
+
+		/*while (g_main_context_iteration (NULL, FALSE))
+			;*/
+	}
+
+	[DBus (visible = false)]
+	public BusyCallback get_callback () {
+		return callback;
+	}
+
+	public double get_progress  () {
+		return this.progress;
+	}
+
+	public string get_status  () {
+		return this.status;
+	}
+
+	public async void wait () throws Error {
+		if (progress == 1) {
+			/* tracker-store is idle */
+		} else {
+			var context = new WaitContext ();
+			context.callback = wait.callback;
+			wait_list.prepend (context);
+			yield;
+		}
+	}
+}
diff --git a/src/tracker-store/tracker-steroids.vala b/src/tracker-store/tracker-steroids.vala
new file mode 100644
index 0000000..a025f60
--- /dev/null
+++ b/src/tracker-store/tracker-steroids.vala
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2010, Codeminded BVBA <abustany gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+[DBus (name = "org.freedesktop.Tracker1.Steroids")]
+class Tracker.Steroids : Object {
+	public const string PATH = "/org/freedesktop/Tracker1/Steroids";
+
+	public const int BUFFER_SIZE = 65536;
+
+	public async string[] query (BusName sender, string query, UnixOutputStream output_stream) throws Error {
+		var request = DBusRequest.begin (sender, "Steroids.Query");
+		request.debug ("query: %s", query);
+		try {
+			string[] variable_names = null;
+
+			yield Tracker.Store.sparql_query (query, Tracker.Store.Priority.HIGH, cursor => {
+				var data_output_stream = new DataOutputStream (new BufferedOutputStream.sized (output_stream, BUFFER_SIZE));
+				data_output_stream.set_byte_order (DataStreamByteOrder.HOST_ENDIAN);
+
+				int n_columns = cursor.n_columns;
+
+				int[] column_sizes = new int[n_columns];
+				int[] column_offsets = new int[n_columns];
+				string[] column_data = new string[n_columns];
+
+				variable_names = new string[n_columns];
+				for (int i = 0; i < n_columns; i++) {
+					variable_names[i] = cursor.get_variable_name (i);
+				}
+
+				while (cursor.next ()) {
+					int last_offset = -1;
+
+					for (int i = 0; i < n_columns ; i++) {
+						unowned string str = cursor.get_string (i);
+
+						column_sizes[i] = str != null ? str.length : 0;
+						column_data[i]  = str;
+
+						last_offset += column_sizes[i] + 1;
+						column_offsets[i] = last_offset;
+					}
+
+					data_output_stream.put_int32 (n_columns);
+
+					for (int i = 0; i < n_columns ; i++) {
+						/* Cast from enum to int */
+						data_output_stream.put_int32 ((int) cursor.get_value_type (i));
+					}
+
+					for (int i = 0; i < n_columns ; i++) {
+						data_output_stream.put_int32 (column_offsets[i]);
+					}
+
+					for (int i = 0; i < n_columns ; i++) {
+						data_output_stream.put_string (column_data[i] != null ? column_data[i] : "");
+						data_output_stream.put_byte (0);
+					}
+				}
+			}, sender);
+
+			request.end ();
+
+			return variable_names;
+		} catch (Error e) {
+			request.end (e);
+			throw e;
+		}
+	}
+
+	async Variant? update_internal (BusName sender, Tracker.Store.Priority priority, bool blank, UnixInputStream input_stream) throws Error {
+		var request = DBusRequest.begin (sender,
+			"Steroids.%sUpdate%s",
+			priority != Tracker.Store.Priority.HIGH ? "Batch" : "",
+			blank ? "Blank" : "");
+		try {
+			size_t bytes_read;
+
+			var data_input_stream = new DataInputStream (input_stream);
+			data_input_stream.set_buffer_size (BUFFER_SIZE);
+			data_input_stream.set_byte_order (DataStreamByteOrder.HOST_ENDIAN);
+
+			int query_size = data_input_stream.read_int32 (null);
+
+			/* We malloc one more char to ensure string is 0 terminated */
+			uint8[] query = new uint8[query_size + 1];
+
+			data_input_stream.read_all (query[0:query_size], out bytes_read);
+
+			data_input_stream = null;
+			input_stream = null;
+
+			request.debug ("query: %s", (string) query);
+
+			if (!blank) {
+				yield Tracker.Store.sparql_update ((string) query, priority, sender);
+
+				request.end ();
+
+				return null;
+			} else {
+				var blank_nodes = yield Tracker.Store.sparql_update_blank ((string) query, priority, sender);
+
+				request.end ();
+
+				var builder = new VariantBuilder ((VariantType) "aaa{ss}");
+
+				for (int i = 0; i < blank_nodes.len; i++) {
+					var inner_array = (PtrArray) blank_nodes.index (i);
+
+					builder.open ((VariantType) "aa{ss}");
+					for (int j = 0; j < inner_array.len; j++) {
+						builder.add_value ((Variant) (HashTable<string,string>) inner_array.index (j));
+					}
+					builder.close ();
+				}
+
+				return builder.end ();
+			}
+		} catch (Error e) {
+			request.end (e);
+			throw e;
+		}
+	}
+
+	public async void update (BusName sender, UnixInputStream input_stream) throws Error {
+		yield update_internal (sender, Tracker.Store.Priority.HIGH, false, input_stream);
+	}
+
+	public async void batch_update (BusName sender, UnixInputStream input_stream) throws Error {
+		yield update_internal (sender, Tracker.Store.Priority.LOW, false, input_stream);
+	}
+
+	[DBus (signature = "aaa{ss}")]
+	public async Variant update_blank (BusName sender, UnixInputStream input_stream) throws Error {
+		return yield update_internal (sender, Tracker.Store.Priority.HIGH, true, input_stream);
+	}
+
+	[DBus (signature = "aaa{ss}")]
+	public async Variant batch_update_blank (BusName sender, UnixInputStream input_stream) throws Error {
+		return yield update_internal (sender, Tracker.Store.Priority.LOW, true, input_stream);
+	}
+
+	[DBus (signature = "as")]
+	public async Variant update_array (BusName sender, UnixInputStream input_stream) throws Error {
+		var request = DBusRequest.begin (sender, "Steroids.UpdateArray");
+		try {
+			var data_input_stream = new DataInputStream (input_stream);
+			data_input_stream.set_buffer_size (BUFFER_SIZE);
+			data_input_stream.set_byte_order (DataStreamByteOrder.HOST_ENDIAN);
+
+			int query_count = data_input_stream.read_int32 ();
+
+			string[] query_array = new string[query_count];
+
+			int i;
+			for (i = 0; i < query_count; i++) {
+				size_t bytes_read;
+
+				int query_size = data_input_stream.read_int32 ();
+
+				/* We malloc one more char to ensure string is 0 terminated */
+				query_array[i] = (string) new uint8[query_size + 1];
+
+				data_input_stream.read_all (((uint8[]) query_array[i])[0:query_size], out bytes_read);
+
+			}
+
+			data_input_stream = null;
+			input_stream = null;
+
+			var builder = new VariantBuilder ((VariantType) "as");
+
+			for (i = 0; i < query_count; i++) {
+				request.debug ("query: %s", query_array[i]);
+
+				try {
+					yield Tracker.Store.sparql_update (query_array[i], Tracker.Store.Priority.HIGH, sender);
+					builder.add ("s", "");
+					builder.add ("s", "");
+				} catch (Error e1) {
+					builder.add ("s", "org.freedesktop.Tracker1.SparqlError.Internal");
+					builder.add ("s", e1.message);
+				}
+
+			}
+
+			request.end ();
+
+			return builder.end ();
+		} catch (Error e) {
+			request.end (e);
+			throw e;
+		}
+	}
+}
diff --git a/src/tracker-store/tracker-store.vala b/src/tracker-store/tracker-store.vala
new file mode 100644
index 0000000..06759d2
--- /dev/null
+++ b/src/tracker-store/tracker-store.vala
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2009, Nokia <ivan frade nokia com>
+ *
+ * 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>
+ */
+
+class Tracker.Store {
+	const int MAX_CONCURRENT_QUERIES = 2;
+
+	const int MAX_TASK_TIME = 30;
+
+	static bool start_log;
+	static Queue<Task> query_queues[3 /* TRACKER_STORE_N_PRIORITIES */];
+	static Queue<Task> update_queues[3 /* TRACKER_STORE_N_PRIORITIES */];
+	static int n_queries_running;
+	static bool update_running;
+	static ThreadPool<Task> update_pool;
+	static ThreadPool<Task> query_pool;
+	//GSList        *running_tasks;
+	static int max_task_time;
+	static bool active;
+	static SourceFunc active_callback;
+
+	public enum Priority {
+		HIGH,
+		LOW,
+		TURTLE,
+		N_PRIORITIES
+	}
+
+	enum TaskType {
+		QUERY,
+		UPDATE,
+		UPDATE_BLANK,
+		TURTLE,
+	}
+
+	public delegate void SparqlQueryInThread (DBCursor cursor);
+
+	abstract class Task {
+		public TaskType type;
+		public string client_id;
+		public Error error;
+		public SourceFunc callback;
+	}
+
+	class QueryTask : Task {
+		public string query;
+		public Cancellable cancellable;
+		public void* thread_data;
+		public uint watchdog_id;
+		public SparqlQueryInThread in_thread;
+	}
+
+	class UpdateTask : Task {
+		public string query;
+		public PtrArray blank_nodes;
+		public Priority priority;
+	}
+
+	class TurtleTask : Task {
+		public string path;
+	}
+
+#if 0
+	/* cpu used for mainloop thread and main update/query thread */
+	static int main_cpu;
+
+	static void
+	private_free (gpointer data)
+	{
+		TrackerStorePrivate *private = data;
+		gint i;
+
+		for (i = 0; i < N_PRIORITIES; i++) {
+			g_queue_free (query_queues[i]);
+			g_queue_free (update_queues[i]);
+		}
+		g_free (private);
+	}
+
+	static void
+	store_task_free (TrackerStoreTask *task)
+	{
+		if (task.type == TaskType.TURTLE) {
+			g_free (task.data.turtle.path);
+		} else if (task.type == TaskType.QUERY) {
+			g_free (task.data.query.query);
+			if (task.data.query.watchdog_id) {
+				g_source_remove (task.data.query.watchdog_id);
+			}
+			if (task.data.query.cancellable) {
+				g_object_unref (task.data.query.cancellable);
+			}
+		} else {
+			g_free (task.data.update.query);
+		}
+
+		g_free (task.client_id);
+		g_slice_free (TrackerStoreTask, task);
+	}
+
+	bool watchdog_cb (gpointer user_data) {
+		TrackerStoreTask *task = user_data;
+
+		g_cancellable_cancel (task.data.query.cancellable);
+
+		return FALSE;
+	}
+#endif
+
+	static void sched () {
+		Queue<Task> queue;
+		Task task = null;
+
+		if (!active) {
+			return;
+		}
+
+		while (n_queries_running < MAX_CONCURRENT_QUERIES) {
+			for (int i = 0; i < Priority.N_PRIORITIES; i++) {
+				task = query_queues[i].pop_head ();
+				if (task != null) {
+					break;
+				}
+			}
+			if (task == null) {
+				/* no pending query */
+				break;
+			}
+			//running_tasks = g_slist_prepend (running_tasks, task);
+
+			if (max_task_time != 0) {
+				//task.watchdog_id = Timeout.add_seconds (max_task_time, watchdog_cb, task);
+			}
+
+			n_queries_running++;
+			query_pool.push (task);
+		}
+
+		if (!update_running) {
+			for (int i = 0; i < Priority.N_PRIORITIES; i++) {
+				task = update_queues[i].pop_head ();
+				if (task != null) {
+					break;
+				}
+			}
+			if (task != null) {
+				update_running = true;
+				update_pool.push (task);
+			}
+		}
+	}
+
+	static bool start_timer_or_not (Task task) {
+		bool result;
+
+		switch (task.type) {
+			case TaskType.UPDATE:
+			case TaskType.UPDATE_BLANK:
+				result = !(((UpdateTask) task).priority == Priority.LOW && update_queues[Priority.LOW].get_length () > 0);
+				break;
+			case TaskType.TURTLE:
+				result = update_queues[Priority.TURTLE].get_length () == 0;
+				break;
+			case TaskType.QUERY:
+			default:
+				result = false;
+				break;
+		}
+
+		return result;
+	}
+
+	static bool task_finish_cb (Task task) {
+		if (task.type == TaskType.QUERY) {
+			var query_task = (QueryTask) task;
+
+			if (task.error == null) {
+				//g_cancellable_set_error_if_cancelled (task.data.query.cancellable, &task.error);
+			}
+
+			task.callback ();
+			task.error = null;
+
+			//running_tasks = g_slist_remove (running_tasks, task);
+			n_queries_running--;
+		} else if (task.type == TaskType.UPDATE) {
+			var update_task = (UpdateTask) task;
+
+			if (task.error == null) {
+				Tracker.Data.notify_transaction (start_timer_or_not (task));
+			}
+
+			task.callback ();
+			task.error = null;
+
+			update_running = false;
+		} else if (task.type == TaskType.UPDATE_BLANK) {
+			var update_task = (UpdateTask) task;
+
+			if (task.error == null) {
+				Tracker.Data.notify_transaction (start_timer_or_not (task));
+			}
+
+#if 0
+			if (!task.data.update.blank_nodes) {
+				/* Create empty GPtrArray for dbus-glib to be happy */
+				task.data.update.blank_nodes = g_ptr_array_new ();
+			}
+#endif
+
+			task.callback ();
+
+#if 0
+			if (task.data.update.blank_nodes) {
+				for (int i = 0; i < task.data.update.blank_nodes->len; i++) {
+					g_ptr_array_foreach (task.data.update.blank_nodes->pdata[i], (GFunc) g_hash_table_unref, NULL);
+					g_ptr_array_free (task.data.update.blank_nodes->pdata[i], TRUE);
+				}
+				g_ptr_array_free (task.data.update.blank_nodes, TRUE);
+			}
+#endif
+
+			task.error = null;
+
+			update_running = false;
+		} else if (task.type == TaskType.TURTLE) {
+			var turtle_task = (TurtleTask) task;
+
+			if (task.error == null) {
+				Tracker.Data.notify_transaction (start_timer_or_not (task));
+			}
+
+			task.callback ();
+			task.error = null;
+
+			update_running = false;
+		}
+
+		if (n_queries_running == 0 && !update_running && active_callback != null) {
+			active_callback ();
+		}
+
+		sched ();
+
+		return false;
+	}
+
+	static void pool_dispatch_cb (Task task) {
+#if 0
+		/* special task, only ever sent to main pool */
+		if (GPOINTER_TO_INT (data) == 1) {
+			if (g_getenv ("TRACKER_STORE_DISABLE_CPU_AFFINITY") == NULL) {
+				cpu_set_t cpuset;
+				CPU_ZERO (&cpuset);
+				CPU_SET (main_cpu, &cpuset);
+
+				/* avoid cpu hopping which can lead to significantly worse performance */
+				pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
+				return;
+			}
+		}
+#endif
+
+		try {
+			if (task.type == TaskType.QUERY) {
+				var query_task = (QueryTask) task;
+
+				var cursor = Tracker.Data.query_sparql_cursor (query_task.query);
+
+				query_task.in_thread (cursor);
+			} else if (task.type == TaskType.UPDATE) {
+				var update_task = (UpdateTask) task;
+
+				Tracker.Data.update_sparql (update_task.query);
+			} else if (task.type == TaskType.UPDATE_BLANK) {
+				var update_task = (UpdateTask) task;
+
+				/*update_task.blank_nodes =*/ Tracker.Data.update_sparql_blank (update_task.query);
+			} else if (task.type == TaskType.TURTLE) {
+				var turtle_task = (TurtleTask) task;
+
+				var file = File.new_for_path (turtle_task.path);
+
+				Tracker.Events.freeze ();
+				Tracker.Data.load_turtle_file (file);
+				Tracker.Events.reset_pending ();
+			}
+		} catch (Error e) {
+			task.error = e;
+		}
+
+		Idle.add (() => {
+			task_finish_cb (task);
+			return false;
+		});
+	}
+
+	public static void init () {
+#if 0
+		TrackerStorePrivate *private;
+		const char *tmp;
+		cpu_set_t cpuset;
+
+		private = g_new0 (TrackerStorePrivate, 1);
+#endif
+
+		/*if ((tmp = g_getenv("TRACKER_STORE_MAX_TASK_TIME")) != NULL) {
+			max_task_time = atoi (tmp);
+		} else*/ {
+			max_task_time = MAX_TASK_TIME;
+		}
+
+		for (int i = 0; i < Priority.N_PRIORITIES; i++) {
+			query_queues[i] = new Queue<Task> ();
+			update_queues[i] = new Queue<Task> ();
+		}
+
+		update_pool = new ThreadPool<Task> (pool_dispatch_cb, 1, true);
+		query_pool = new ThreadPool<Task> (pool_dispatch_cb, MAX_CONCURRENT_QUERIES, true);
+
+#if 0
+		/* as the following settings are global for unknown reasons,
+		   let's use the same settings as gio, otherwise the used settings
+		   are rather random */
+		g_thread_pool_set_max_idle_time (15 * 1000);
+		g_thread_pool_set_max_unused_threads (2);
+
+		if (g_getenv ("TRACKER_STORE_DISABLE_CPU_AFFINITY") == NULL) {
+			sched_getcpu ();
+			main_cpu = sched_getcpu ();
+			CPU_ZERO (&cpuset);
+			CPU_SET (main_cpu, &cpuset);
+
+			/* avoid cpu hopping which can lead to significantly worse performance */
+			pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
+			/* lock main update/query thread to same cpu to improve overall performance
+			   main loop thread is essentially idle during query execution */
+			g_thread_pool_push (update_pool, GINT_TO_POINTER (1), NULL);
+		}
+
+		g_static_private_set (&private_key,
+			              private,
+			              private_free);
+#endif
+	}
+
+	public static void shutdown () {
+#if 0
+		TrackerStorePrivate *private;
+
+		private = g_static_private_get (&private_key);
+		g_return_if_fail (private != NULL);
+
+		g_thread_pool_free (query_pool, FALSE, TRUE);
+		g_thread_pool_free (update_pool, FALSE, TRUE);
+
+		g_static_private_set (&private_key, NULL, NULL);
+#endif
+	}
+
+	public static async void sparql_query (string sparql, Priority priority, SparqlQueryInThread in_thread, string client_id) {
+		var task = new QueryTask ();
+		task.type = TaskType.QUERY;
+		task.query = sparql;
+		task.cancellable = new Cancellable ();
+		task.in_thread = in_thread;
+		task.callback = sparql_query.callback;
+		task.client_id = client_id;
+
+		query_queues[priority].push_tail (task);
+
+		sched ();
+
+		yield;
+
+		if (task.error != null) {
+			throw task.error;
+		}
+	}
+
+	public static async void sparql_update (string sparql, Priority priority, string client_id) throws Error {
+		var task = new UpdateTask ();
+		task.type = TaskType.UPDATE;
+		task.query = sparql;
+		task.priority = priority;
+		task.callback = sparql_update.callback;
+		task.client_id = client_id;
+
+		update_queues[priority].push_tail (task);
+
+		sched ();
+
+		yield;
+
+		if (task.error != null) {
+			throw task.error;
+		}
+	}
+
+	public static async PtrArray sparql_update_blank (string sparql, Priority priority, string client_id) throws Error {
+		var task = new UpdateTask ();
+		task.type = TaskType.UPDATE_BLANK;
+		task.query = sparql;
+		task.priority = priority;
+		task.callback = sparql_update.callback;
+		task.client_id = client_id;
+
+		update_queues[priority].push_tail (task);
+
+		sched ();
+
+		yield;
+
+		if (task.error != null) {
+			throw task.error;
+		}
+
+		return task.blank_nodes;
+	}
+
+	public static async void queue_turtle_import (File file, string client_id) throws Error {
+		var task = new TurtleTask ();
+		task.type = TaskType.TURTLE;
+		task.path = file.get_path ();
+		task.callback = queue_turtle_import.callback;
+		task.client_id = client_id;
+
+		update_queues[Priority.TURTLE].push_tail (task);
+
+		sched ();
+
+		yield;
+
+		if (task.error != null) {
+			throw task.error;
+		}
+	}
+
+#if 0
+	uint get_queue_size () {
+		TrackerStorePrivate *private;
+		gint i;
+		guint result = 0;
+
+		private = g_static_private_get (&private_key);
+		g_return_val_if_fail (private != NULL, 0);
+
+		for (i = 0; i < TRACKER_STORE_N_PRIORITIES; i++) {
+			result += g_queue_get_length (query_queues[i]);
+			result += g_queue_get_length (update_queues[i]);
+		}
+		return result;
+	}
+
+	void unreg_task (Task task, Error error) {
+		if (task.type == TaskType.QUERY) {
+			task.callback.query.query_callback (NULL, error, task.user_data);
+		} else if (task.type == TaskType.UPDATE) {
+			task.callback.update_callback (error, task.user_data);
+		} else if (task.type == TaskType.UPDATE_BLANK) {
+			task.callback.update_blank_callback (NULL, error, task.user_data);
+		} else if (task.type == TaskType.TURTLE) {
+			task.callback.turtle_callback (error, task.user_data);
+		}
+
+		if (task.destroy) {
+			task.destroy (task.user_data);
+		}
+
+		store_task_free (task);
+	}
+
+	public void unreg_batches (string client_id) {
+		TrackerStorePrivate *private;
+		static GError *error = NULL;
+		GList *list, *cur;
+		GSList *running;
+		GQueue *queue;
+		gint i;
+
+		private = g_static_private_get (&private_key);
+		g_return_if_fail (private != NULL);
+
+		for (running = running_tasks; running; running = running->next) {
+			TrackerStoreTask *task;
+
+			task = running->data;
+
+			if (task.data.query.cancellable &&
+			    g_strcmp0 (task.client_id, client_id) == 0) {
+				g_cancellable_cancel (task.data.query.cancellable);
+			}
+		}
+
+		for (i = 0; i < TRACKER_STORE_N_PRIORITIES; i++) {
+			queue = query_queues[i];
+			list = queue->head;
+			while (list) {
+				TrackerStoreTask *task;
+
+				cur = list;
+				list = list->next;
+				task = cur->data;
+
+				if (task && g_strcmp0 (task.client_id, client_id) == 0) {
+					g_queue_delete_link (queue, cur);
+
+					if (!error) {
+						g_set_error (&error, TRACKER_DBUS_ERROR, 0,
+							     "Client disappeared");
+					}
+
+					unreg_task (task, error);
+				}
+			}
+
+			queue = update_queues[i];
+			list = queue->head;
+			while (list) {
+				TrackerStoreTask *task;
+
+				cur = list;
+				list = list->next;
+				task = cur->data;
+
+				if (task && g_strcmp0 (task.client_id, client_id) == 0) {
+					g_queue_delete_link (queue, cur);
+
+					if (!error) {
+						g_set_error (&error, TRACKER_DBUS_ERROR, 0,
+							     "Client disappeared");
+					}
+
+					unreg_task (task, error);
+				}
+			}
+		}
+
+		if (error) {
+			g_clear_error (&error);
+		}
+
+		sched (private);
+	}
+#endif
+
+	public static async void pause () {
+		Tracker.Store.active = false;
+
+		if (n_queries_running > 0 || update_running) {
+			active_callback = pause.callback;
+			yield;
+			active_callback = null;
+		}
+
+		if (active) {
+			sched ();
+		}
+	}
+
+	public static void resume () {
+		Tracker.Store.active = true;
+
+		sched ();
+	}
+}
diff --git a/src/tracker-store/tracker-writeback.c b/src/tracker-store/tracker-writeback.c
index bdd02d5..f26a9c2 100644
--- a/src/tracker-store/tracker-writeback.c
+++ b/src/tracker-store/tracker-writeback.c
@@ -20,6 +20,8 @@
  *  Philip Van Hoof <philip codeminded be>
  */
 
+#if 0
+
 #include "config.h"
 
 #include <libtracker-data/tracker-data.h>
@@ -216,3 +218,5 @@ tracker_writeback_shutdown (void)
 	free_private (private);
 	private = NULL;
 }
+
+#endif



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