tracker r1282 - in trunk: . src/trackerd



Author: carlosg
Date: Mon Apr 21 13:32:35 2008
New Revision: 1282
URL: http://svn.gnome.org/viewvc/tracker?rev=1282&view=rev

Log:
2008-04-14  Carlos Garnacho  <carlos imendio com>

        Implement a database abstraction interface, with a sqlite
        implementation. Queries/procedures return a TrackerDBResultSet object,
        which simplifies result data extraction. Fixes bug #528051.

        * src/trackerd/tracker-db-interface.[ch]: Added. Interface to access
        databases.

        * src/trackerd/tracker-db-interface-sqlite.[ch]: Added. Sqlite
        implementation.

        * src/trackerd/Makefile.am: add these files.

        * src/trackerd/tracker-db-email.[ch], tracker-db-sqlite.[ch],
        tracker-db.c, tracker-dbus-files.c, tracker-dbus-keywords.c,
        tracker-dbus-metadata.c, tracker-dbus-search.c,
        tracker-email-evolution.c, tracker-email-modest.c, tracker-inotify.c,
        tracker-process-files.c, tracker-process-requests.c, trackerd.c: Use
        the new API.

        * src/trackerd/tracker-dbus-methods.[ch]: Modify to build a
        DBusMessage from a TrackerDBResultSet.

        * src/trackerd/tracker-email.c: Report the error in case the mail
        client module can't be loaded.


Added:
   trunk/src/trackerd/tracker-db-interface-sqlite.c
   trunk/src/trackerd/tracker-db-interface-sqlite.h
   trunk/src/trackerd/tracker-db-interface.c
   trunk/src/trackerd/tracker-db-interface.h
Modified:
   trunk/ChangeLog
   trunk/src/trackerd/Makefile.am
   trunk/src/trackerd/tracker-db-email.c
   trunk/src/trackerd/tracker-db-email.h
   trunk/src/trackerd/tracker-db-sqlite.c
   trunk/src/trackerd/tracker-db-sqlite.h
   trunk/src/trackerd/tracker-db.c
   trunk/src/trackerd/tracker-dbus-files.c
   trunk/src/trackerd/tracker-dbus-keywords.c
   trunk/src/trackerd/tracker-dbus-metadata.c
   trunk/src/trackerd/tracker-dbus-methods.c
   trunk/src/trackerd/tracker-dbus-methods.h
   trunk/src/trackerd/tracker-dbus-search.c
   trunk/src/trackerd/tracker-email-evolution.c
   trunk/src/trackerd/tracker-email-modest.c
   trunk/src/trackerd/tracker-email.c
   trunk/src/trackerd/tracker-indexer.h
   trunk/src/trackerd/tracker-inotify.c
   trunk/src/trackerd/tracker-process-files.c
   trunk/src/trackerd/tracker-process-requests.c
   trunk/src/trackerd/trackerd.c

Modified: trunk/src/trackerd/Makefile.am
==============================================================================
--- trunk/src/trackerd/Makefile.am	(original)
+++ trunk/src/trackerd/Makefile.am	Mon Apr 21 13:32:35 2008
@@ -53,6 +53,10 @@
 	tracker-cache.h							\
 	tracker-parser.c						\
 	tracker-parser.h						\
+	tracker-db-interface.c						\
+	tracker-db-interface.h						\
+	tracker-db-interface-sqlite.c					\
+	tracker-db-interface-sqlite.h					\
 	tracker-db-sqlite.c						\
 	tracker-db-sqlite.h						\
 	tracker-db-email.c						\

Modified: trunk/src/trackerd/tracker-db-email.c
==============================================================================
--- trunk/src/trackerd/tracker-db-email.c	(original)
+++ trunk/src/trackerd/tracker-db-email.c	Mon Apr 21 13:32:35 2008
@@ -33,25 +33,17 @@
 static gint
 tracker_db_email_get_mbox_offset (DBConnection *db_con, const gchar *mbox_uri)
 {
-	gchar ***res;
-	gchar **row;
+	TrackerDBResultSet *result_set;
 	gint  offset;
 
-	res = tracker_exec_proc (db_con, "GetMBoxDetails", 1, mbox_uri);
+	result_set = tracker_exec_proc (db_con, "GetMBoxDetails", mbox_uri, NULL);
 
-	if (!res) {
+	if (!result_set) {
 		return -1;
 	}
 
-	row = tracker_db_get_row (res, 0);
-
-	if (!(row && row[0] && row[4])) {
-		return -1;
-	} else {
-		offset = atoi (row[4]);
-	}
-
-	tracker_db_free_result (res);
+	tracker_db_result_set_get (result_set, 4, &offset, -1);
+	g_object_unref (result_set);
 
 	return offset;
 }
@@ -70,7 +62,7 @@
 	gchar *str_mail_app = tracker_int_to_str (mail_app);
 	gchar *str_mail_type = tracker_int_to_str (mail_type);
 
-	tracker_exec_proc (db_con, "InsertMboxDetails", 5, str_mail_app, str_mail_type, filename, path, uri_prefix);
+	tracker_exec_proc (db_con, "InsertMboxDetails", str_mail_app, str_mail_type, filename, path, uri_prefix, NULL);
 
 	tracker_log ("Registered email store %s of type %s", filename, types[mail_type]);
 
@@ -82,21 +74,21 @@
 void
 tracker_db_email_flag_mbox_junk (DBConnection *db_con, const gchar *mbox_uri)
 {
-	tracker_exec_proc (db_con, "SetJunkMbox", 2, "1", mbox_uri);
+	tracker_exec_proc (db_con, "SetJunkMbox", "1", mbox_uri, NULL);
 }
 
 
 void
 tracker_db_email_reset_mbox_junk (DBConnection *db_con, const gchar *mbox_uri)
 {
-	tracker_exec_proc (db_con, "SetJunkMbox", 2, "0", mbox_uri);
+	tracker_exec_proc (db_con, "SetJunkMbox", "0", mbox_uri, NULL);
 }
 
 
-gchar ***
+TrackerDBResultSet *
 tracker_db_email_get_mboxes (DBConnection *db_con)
 {
-	return tracker_exec_proc (db_con, "GetMboxes", 0);
+	return tracker_exec_proc (db_con, "GetMboxes", NULL);
 }
 
 
@@ -114,7 +106,7 @@
 
 	if (!tracker_db_email_lookup_junk (db_con, str_mbox_id, uid)) {
 
-		tracker_exec_proc (db_con, "InsertJunk", 2, str_uid, str_mbox_id);
+		tracker_exec_proc (db_con, "InsertJunk", str_uid, str_mbox_id, NULL);
 	}
 
 	g_free (str_uid);	
@@ -125,40 +117,30 @@
 MailStore *
 tracker_db_email_get_mbox_details (DBConnection *db_con, const gchar *mbox_uri)
 {
-        gchar     ***res;
-        gchar     **row;
+	TrackerDBResultSet *result_set;
         MailStore *mail_store;
 
-        res = tracker_exec_proc (db_con, "GetMBoxDetails", 1, mbox_uri);
+        result_set = tracker_exec_proc (db_con, "GetMBoxDetails", mbox_uri, NULL);
 
-        if (!res) {
+        if (!result_set) {
                 return NULL;
         }
 
-        mail_store = NULL;
-
-        row = tracker_db_get_row (res, 0);
-
-        if (!(row && row[3] && row[4])) {
-                return NULL;
-
-        } else {
-                mail_store = g_slice_new0 (MailStore);
-
-                mail_store->offset = atoi (row[4]);
-                mail_store->mail_count = atoi (row[6]);
-                mail_store->junk_count = atoi (row[7]);
-                mail_store->delete_count = atoi (row[8]);
-                mail_store->uri_prefix = g_strdup (row[3]);
-                mail_store->type = atoi (row[1]);
-        }
+	mail_store = g_slice_new0 (MailStore);
+	tracker_db_result_set_get (result_set,
+				   1, &mail_store->type,
+				   3, &mail_store->uri_prefix,
+				   4, &mail_store->offset,
+				   6, &mail_store->mail_count,
+				   7, &mail_store->junk_count,
+				   8, &mail_store->delete_count,
+				   -1);
 
-        tracker_db_free_result (res);
+	g_object_unref (result_set);
 
-        return mail_store;
+	return mail_store;
 }
 
-
 void
 tracker_db_email_free_mail_store (MailStore *store)
 {
@@ -175,25 +157,17 @@
 gint
 tracker_db_email_get_mbox_id (DBConnection *db_con, const gchar *mbox_uri)
 {
-	gchar ***res;
-	gchar **row;
+	TrackerDBResultSet *result_set;
 	gint  id;
 
-	res = tracker_exec_proc (db_con, "GetMboxID", 1, mbox_uri);
-
-	if (!res) {
-		return -1;
-	}
-
-	row = tracker_db_get_row (res, 0);
+	result_set = tracker_exec_proc (db_con, "GetMboxID", mbox_uri, NULL);
 
-	if (!(row && row[0])) {
+	if (!result_set) {
 		return -1;
-	} else {
-		id = atoi (row[0]);
 	}
 
-	tracker_db_free_result (res);
+	tracker_db_result_set_get (result_set, 0, &id, -1);
+	g_object_unref (result_set);
 
 	return id;
 }
@@ -202,25 +176,17 @@
 gchar *
 tracker_db_email_get_mbox_uri_prefix (DBConnection *db_con, const gchar *mbox_uri)
 {
-	gchar ***res;
-	gchar **row;
+	TrackerDBResultSet *result_set;
 	gchar *uri;
 
-	res = tracker_exec_proc (db_con, "GetMBoxDetails", 1, mbox_uri);
+	result_set = tracker_exec_proc (db_con, "GetMBoxDetails", mbox_uri, NULL);
 
-	if (!res) {
+	if (!result_set) {
 		return NULL;
 	}
 
-	row = tracker_db_get_row (res, 0);
-
-	if (!(row && row[3])) {
-		return NULL;
-	} else {
-		uri = g_strdup (row[3]);
-	}
-
-	tracker_db_free_result (res);
+	tracker_db_result_set_get (result_set, 3, &uri, -1);
+	g_object_unref (result_set);
 
 	return uri;
 }
@@ -229,25 +195,17 @@
 gchar *
 tracker_db_email_get_mbox_path (DBConnection *db_con, const gchar *filename)
 {
-	gchar ***res;
-	gchar **row;
+	TrackerDBResultSet *result_set;
 	gchar *path;
 
-	res = tracker_exec_proc (db_con, "GetMBoxPath", 1, filename);
-
-	if (!res) {
-		return NULL;
-	}
-
-	row = tracker_db_get_row (res, 0);
+	result_set = tracker_exec_proc (db_con, "GetMBoxPath", filename, NULL);
 
-	if (!(row && row[0])) {
+	if (!result_set) {
 		return NULL;
-	} else {
-		path = g_strdup (row[0]);
 	}
 
-	tracker_db_free_result (res);
+	tracker_db_result_set_get (result_set, 0, &path, -1);
+	g_object_unref (result_set);
 
 	return path;
 }
@@ -260,31 +218,25 @@
                                      gint         *junk_count,
                                      gint         *delete_count)
 {
-	gchar ***res;
-	gchar **row;
+	TrackerDBResultSet *result_set;
 
 	*mail_count = 0;
 	*junk_count = 0;
 	*delete_count = 0;
 
-	res = tracker_exec_proc (db_con, "GetMBoxDetails", 1, mbox_file_path);
+	result_set = tracker_exec_proc (db_con, "GetMBoxDetails", mbox_file_path, NULL);
 
-	if (!res) {
+	if (!result_set) {
 		return;
 	}
 
-	row = tracker_db_get_row (res, 0);
+	tracker_db_result_set_get (result_set,
+				   6, mail_count,
+				   7, junk_count,
+				   8, delete_count,
+				   -1);
 
-	if (!(row && row[6] && row[7] && row[8] )) {
-		return;
-	} else {
-		*mail_count = atoi (row[6]);
-		*junk_count = atoi (row[7]);
-		*delete_count = atoi (row[8]);
-		
-	}
-
-	tracker_db_free_result (res);
+	g_object_unref (result_set);
 }
 
 
@@ -306,7 +258,7 @@
 		str_junk_count = tracker_uint_to_str (junk_count);
 		str_delete_count = tracker_uint_to_str (delete_count);
 
-		tracker_exec_proc (db_con, "UpdateMboxCounts", 4, str_mail_count, str_junk_count, str_delete_count, dir_path);
+		tracker_exec_proc (db_con, "UpdateMboxCounts", str_mail_count, str_junk_count, str_delete_count, dir_path, NULL);
 
 		g_free (str_mail_count);
 		g_free (str_junk_count);
@@ -353,7 +305,7 @@
 		gchar *str_offset;
 
 		str_offset = tracker_uint_to_str (mf->next_email_offset);
-		tracker_exec_proc (db_con, "UpdateMboxOffset", 2, str_offset, mf->path);
+		tracker_exec_proc (db_con, "UpdateMboxOffset", str_offset, mf->path, NULL);
 
 		g_free (str_offset);
 
@@ -825,30 +777,22 @@
 gboolean
 tracker_db_email_lookup_junk (DBConnection *db_con, const gchar *mbox_id, gint uid)
 {
+	TrackerDBResultSet *result_set;
         gchar *str_uid;
-	gchar ***res;
-	gchar **row;
+	gint id;
 
 	str_uid = tracker_uint_to_str (uid);
 
-	res = tracker_exec_proc (db_con, "LookupJunk", 2, str_uid, mbox_id);
-
-	if (!res) {
-		g_free (str_uid);
-		return FALSE;
-	}
+	result_set = tracker_exec_proc (db_con, "LookupJunk", str_uid, mbox_id, NULL);
 
-	row = tracker_db_get_row (res, 0);
+	g_free (str_uid);
 
-	if (!(row && row[0] )) {
-		tracker_db_free_result (res);
-		g_free (str_uid);
+	if (!result_set) {
 		return FALSE;
 	}
 
-	tracker_db_free_result (res);
-
-	g_free (str_uid);
+	tracker_db_result_set_get (result_set, 0, &id, -1);
+	g_object_unref (result_set);
 
-	return TRUE;
+	return (id > 0);
 }

Modified: trunk/src/trackerd/tracker-db-email.h
==============================================================================
--- trunk/src/trackerd/tracker-db-email.h	(original)
+++ trunk/src/trackerd/tracker-db-email.h	Mon Apr 21 13:32:35 2008
@@ -36,7 +36,6 @@
 gboolean  tracker_db_email_delete_email          (DBConnection *db_con, const gchar *uri);
 gint	  tracker_db_email_get_mbox_id 	         (DBConnection *db_con, const gchar *mbox_uri);
 void	  tracker_db_email_insert_junk 	         (DBConnection *db_con, const gchar *mbox_uri, guint32 uid);
-gchar *** tracker_db_email_get_mbox_junk         (DBConnection *db_con);
 void	  tracker_db_email_reset_mbox_junk       (DBConnection *db_con, const gchar *mbox_uri);
 void	  tracker_db_email_flag_mbox_junk        (DBConnection *db_con, const gchar *mbox_uri);
 void	  tracker_db_email_register_mbox         (DBConnection *db_con, MailApplication mail_app, MailType mail_type,
@@ -63,7 +62,7 @@
 MailStore *
 tracker_db_email_get_mbox_details (DBConnection *db_con, const gchar *mbox_uri);
 
-gchar ***
+TrackerDBResultSet *
 tracker_db_email_get_mboxes (DBConnection *db_con);
 
 #endif

Added: trunk/src/trackerd/tracker-db-interface-sqlite.c
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-db-interface-sqlite.c	Mon Apr 21 13:32:35 2008
@@ -0,0 +1,600 @@
+/* Tracker - Sqlite implementation
+ * 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.
+ */
+
+#include <sqlite3.h>
+#include "tracker-db-interface-sqlite.h"
+
+#define TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_DB_INTERFACE_SQLITE, TrackerDBInterfaceSqlitePrivate))
+
+typedef struct TrackerDBInterfaceSqlitePrivate TrackerDBInterfaceSqlitePrivate;
+typedef struct SqliteFunctionData SqliteFunctionData;
+
+struct TrackerDBInterfaceSqlitePrivate {
+	gchar *filename;
+	sqlite3 *db;
+
+	GHashTable *statements;
+	GHashTable *procedures;
+
+	GSList *function_data;
+
+	guint in_transaction : 1;
+};
+
+struct SqliteFunctionData {
+	TrackerDBInterface *interface;
+	TrackerDBFunc func;
+};
+
+static void tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface);
+
+enum {
+	PROP_0,
+	PROP_FILENAME,
+	PROP_IN_TRANSACTION
+};
+
+G_DEFINE_TYPE_WITH_CODE (TrackerDBInterfaceSqlite, tracker_db_interface_sqlite, G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (TRACKER_TYPE_DB_INTERFACE,
+						tracker_db_interface_sqlite_iface_init))
+
+static GObject *
+tracker_db_interface_sqlite_constructor (GType                  type,
+					 guint                  n_construct_properties,
+					 GObjectConstructParam *construct_params)
+{
+	GObject *object;
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	object = (* G_OBJECT_CLASS (tracker_db_interface_sqlite_parent_class)->constructor) (type,
+											     n_construct_properties,
+											     construct_params);
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
+	g_assert (priv->filename != NULL);
+
+	if (sqlite3_open (priv->filename, &priv->db) != SQLITE_OK) {
+		g_critical ("Can't open DB at: %s\n", priv->filename);
+	}
+
+	sqlite3_extended_result_codes (priv->db, 0);
+	sqlite3_busy_timeout (priv->db, 10000000);
+
+	return object;
+}
+
+static void
+tracker_db_interface_sqlite_set_property (GObject       *object,
+					  guint          prop_id,
+					  const GValue  *value,
+					  GParamSpec    *pspec)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_FILENAME:
+		priv->filename = g_value_dup_string (value);
+		break;
+	case PROP_IN_TRANSACTION:
+		priv->in_transaction = g_value_get_boolean (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+static void
+tracker_db_interface_sqlite_get_property (GObject    *object,
+					  guint       prop_id,
+					  GValue     *value,
+					  GParamSpec *pspec)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_FILENAME:
+		g_value_set_string (value, priv->filename);
+		break;
+	case PROP_IN_TRANSACTION:
+		g_value_set_boolean (value, priv->in_transaction);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+static void
+tracker_db_interface_sqlite_finalize (GObject *object)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
+
+	g_free (priv->filename);
+
+	g_hash_table_destroy (priv->statements);
+	g_hash_table_unref (priv->procedures);
+
+	g_slist_foreach (priv->function_data, (GFunc) g_free, NULL);
+	g_slist_free (priv->function_data);
+
+	sqlite3_close (priv->db);
+
+	G_OBJECT_CLASS (tracker_db_interface_sqlite_parent_class)->finalize (object);
+}
+
+static void
+tracker_db_interface_sqlite_class_init (TrackerDBInterfaceSqliteClass *class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+	object_class->constructor = tracker_db_interface_sqlite_constructor;
+	object_class->set_property = tracker_db_interface_sqlite_set_property;
+	object_class->get_property = tracker_db_interface_sqlite_get_property;
+	object_class->finalize = tracker_db_interface_sqlite_finalize;
+
+	g_object_class_install_property (object_class,
+					 PROP_FILENAME,
+					 g_param_spec_string ("filename",
+							      "DB filename",
+							      "DB filename",
+							      NULL,
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	/* Override properties from interface */
+	g_object_class_override_property (object_class,
+					  PROP_IN_TRANSACTION,
+					  "in-transaction");
+
+	g_type_class_add_private (object_class,
+				  sizeof (TrackerDBInterfaceSqlitePrivate));
+}
+
+static void
+tracker_db_interface_sqlite_init (TrackerDBInterfaceSqlite *db_interface)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+
+	priv->procedures = g_hash_table_new_full (g_str_hash, g_str_equal,
+						  (GDestroyNotify) g_free,
+						  (GDestroyNotify) g_free);
+	priv->statements = g_hash_table_new_full (g_str_hash, g_str_equal,
+						  (GDestroyNotify) g_free,
+						  (GDestroyNotify) sqlite3_finalize);
+}
+
+static void
+add_row (TrackerDBResultSet *result_set,
+	 sqlite3_stmt       *stmt)
+{
+	gint cols, i;
+
+	cols = sqlite3_column_count (stmt);
+	_tracker_db_result_set_append (result_set);
+
+	for (i = 0; i < cols; i++) {
+		GValue value = { 0, };
+		gint col_type;
+
+		col_type = sqlite3_column_type (stmt, i);
+
+		switch (col_type) {
+		case SQLITE_TEXT:
+			g_value_init (&value, G_TYPE_STRING);
+			g_value_set_string (&value, (gchar *) sqlite3_column_text (stmt, i));
+			break;
+		case SQLITE_INTEGER:
+			g_value_init (&value, G_TYPE_INT);
+			g_value_set_int (&value, sqlite3_column_int (stmt, i));
+			break;
+		case SQLITE_FLOAT:
+			g_value_init (&value, G_TYPE_DOUBLE);
+			g_value_set_double (&value, sqlite3_column_double (stmt, i));
+			break;
+		case SQLITE_NULL:
+			/* just ignore NULLs */
+			break;
+		default:
+			g_critical ("Unknown database column type: %d\n", col_type);
+		}
+
+		if (G_VALUE_TYPE (&value) != G_TYPE_INVALID) {
+			_tracker_db_result_set_set_value (result_set, i, &value);
+			g_value_unset (&value);
+		}
+	}
+}
+
+static void
+internal_sqlite3_function (sqlite3_context *context,
+			   int              argc,
+			   sqlite3_value   *argv[])
+{
+	SqliteFunctionData *data;
+	GValue *values, result;
+	GByteArray *blob_array;
+	gint i;
+
+	data = (SqliteFunctionData *) sqlite3_user_data (context);
+	values = g_new0 (GValue, argc);
+
+	/* Transform the arguments */
+	for (i = 0; i < argc; i++) {
+		switch (sqlite3_value_type (argv[i])) {
+		case SQLITE_TEXT:
+			g_value_init (&values[i], G_TYPE_STRING);
+			g_value_set_string (&values[i], (gchar *) sqlite3_value_text (argv[i]));
+			break;
+		case SQLITE_INTEGER:
+			g_value_init (&values[i], G_TYPE_INT);
+			g_value_set_int (&values[i], sqlite3_value_int (argv[i]));
+			break;
+		case SQLITE_FLOAT:
+			g_value_init (&values[i], G_TYPE_DOUBLE);
+			g_value_set_double (&values[i], sqlite3_value_double (argv[i]));
+			break;
+		case SQLITE_BLOB: {
+			gconstpointer blob;
+			gint size;
+
+			blob = sqlite3_value_blob (argv[i]);
+			size = sqlite3_value_bytes (argv[i]);
+
+			blob_array = g_byte_array_sized_new (size);
+			g_byte_array_append (blob_array, blob, size);
+
+			g_value_init (&values[i], TRACKER_TYPE_DB_BLOB);
+			g_value_take_boxed (&values[i], blob_array);
+
+			break;
+		}
+		default:
+			g_critical ("Unknown database value type: %d\n", sqlite3_value_type (argv[i]));
+		}
+	}
+
+	/* Call the function */
+	result = data->func (data->interface, argc, values);
+
+	/* And return something appropriate to the context */
+	if (G_VALUE_HOLDS_INT (&result)) {
+		sqlite3_result_int (context, g_value_get_int (&result));
+	} else if (G_VALUE_HOLDS_DOUBLE (&result)) {
+		sqlite3_result_double (context, g_value_get_double (&result));
+	} else if (G_VALUE_HOLDS_STRING (&result)) {
+		sqlite3_result_text (context,
+				     g_value_dup_string (&result),
+				     -1, g_free);
+	} else if (G_VALUE_HOLDS (&result, TRACKER_TYPE_DB_BLOB)) {
+		blob_array = g_value_get_boxed (&result);
+		sqlite3_result_blob (context,
+				     g_memdup (blob_array->data, blob_array->len),
+				     blob_array->len,
+				     g_free);
+	} else if (G_VALUE_HOLDS (&result, G_TYPE_INVALID)) {
+		sqlite3_result_null (context);
+	} else {
+		g_critical ("Returned type not managed: %s\n", G_VALUE_TYPE_NAME (&result));
+		sqlite3_result_null (context);
+	}
+
+	/* Now free all this mess */
+	for (i = 0; i < argc; i++) {
+		g_value_unset (&values[i]);
+	}
+
+	if (! G_VALUE_HOLDS (&result, G_TYPE_INVALID)) {
+		g_value_unset (&result);
+	}
+
+	g_free (values);
+}
+
+static void
+tracker_db_interface_sqlite_set_procedure_table (TrackerDBInterface *db_interface,
+						 GHashTable         *procedure_table)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+	priv->procedures = g_hash_table_ref (procedure_table);
+}
+
+static TrackerDBResultSet *
+create_result_set_from_stmt (TrackerDBInterfaceSqlite  *interface,
+			     sqlite3_stmt              *stmt,
+			     GError                   **error)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+	TrackerDBResultSet *result_set = NULL;
+	gint columns, result, busy_count;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (interface);
+	columns = sqlite3_column_count (stmt);
+	result = SQLITE_OK;
+
+	while (result == SQLITE_OK  ||
+	       result == SQLITE_ROW ||
+	       result == SQLITE_BUSY) {
+
+		result = sqlite3_step (stmt);
+
+		switch (result) {
+		case SQLITE_ERROR:
+			sqlite3_reset (stmt);
+			break;
+		case SQLITE_BUSY:
+			busy_count++;
+
+			if (busy_count > 100000) {
+				/* tracker_error ("ERROR: excessive busy count in query %s", query); */
+				busy_count = 0;
+			}
+
+			if (busy_count > 50) {
+				g_usleep (g_random_int_range (1000, busy_count * 200));
+			} else {
+				g_usleep (100);
+			}
+
+			break;
+		case SQLITE_ROW:
+			if (G_UNLIKELY (!result_set)) {
+				result_set = _tracker_db_result_set_new (columns);
+			}
+
+			add_row (result_set, stmt);
+			break;
+		}
+	}
+
+	if (result != SQLITE_DONE) {
+		if (result == SQLITE_CORRUPT) {
+			g_critical ("Database %s is corrupt. Can't live without it", priv->filename);
+			g_assert_not_reached ();
+		}
+
+		if (!error) {
+			g_warning (sqlite3_errmsg (priv->db));
+		} else {
+			g_set_error (error,
+				     TRACKER_DB_INTERFACE_ERROR,
+				     TRACKER_DB_QUERY_ERROR,
+				     sqlite3_errmsg (priv->db));
+		}
+
+		/* If there was an error, result set may be invalid or incomplete */
+		if (result_set) {
+			g_object_unref (result_set);
+		}
+
+		return NULL;
+	}
+
+	return result_set;
+}
+
+static sqlite3_stmt *
+get_stored_stmt (TrackerDBInterfaceSqlite *db_interface,
+		 const gchar              *procedure_name)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+	sqlite3_stmt *stmt;
+	gint result;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+	stmt = g_hash_table_lookup (priv->statements, procedure_name);
+
+	if (!stmt || sqlite3_expired (stmt) != 0) {
+		const gchar *procedure;
+
+		procedure = g_hash_table_lookup (priv->procedures, procedure_name);
+
+		if (!procedure) {
+			g_critical ("Prepared query %s not found", procedure_name);
+			return NULL;
+		}
+
+		result = sqlite3_prepare_v2 (priv->db, procedure, -1, &stmt, NULL);
+
+		if (result == SQLITE_OK && stmt) {
+			g_hash_table_insert (priv->statements,
+					     g_strdup (procedure_name),
+					     stmt);
+		}
+	} else {
+		sqlite3_reset (stmt);
+	}
+
+	return stmt;
+}
+
+static TrackerDBResultSet *
+tracker_db_interface_sqlite_execute_procedure (TrackerDBInterface  *db_interface,
+					       GError             **error,
+					       const gchar         *procedure_name,
+					       va_list              args)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+	sqlite3_stmt *stmt;
+	gint stmt_args, n_args;
+	gchar *str;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+	stmt = get_stored_stmt (TRACKER_DB_INTERFACE_SQLITE (db_interface), procedure_name);
+	stmt_args = sqlite3_bind_parameter_count (stmt);
+	n_args = 1;
+
+	while ((str = va_arg (args, gchar *)) != NULL) {
+		sqlite3_bind_text (stmt, n_args, str, -1, SQLITE_STATIC);
+		n_args++;
+	}
+
+	/* Just panic if the number of arguments don't match */
+	g_assert (n_args != stmt_args);
+
+	return create_result_set_from_stmt (db_interface, stmt, error);
+}
+
+static TrackerDBResultSet *
+tracker_db_interface_sqlite_execute_procedure_len (TrackerDBInterface  *db_interface,
+						   GError             **error,
+						   const gchar         *procedure_name,
+						   va_list              args)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+	sqlite3_stmt *stmt;
+	gint stmt_args, n_args, len;
+	gchar *str;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+	stmt = get_stored_stmt (TRACKER_DB_INTERFACE_SQLITE (db_interface), procedure_name);
+	stmt_args = sqlite3_bind_parameter_count (stmt);
+	n_args = 1;
+
+	while ((str = va_arg (args, gchar *)) != NULL) {
+		len = va_arg (args, gint);
+
+		if (len == -1) {
+			/* Assume we're dealing with strings */
+			sqlite3_bind_text (stmt, n_args, str, len, SQLITE_STATIC);
+		} else {
+			/* Deal with it as a blob */
+			sqlite3_bind_blob (stmt, n_args, str, len, SQLITE_STATIC);
+		}
+
+		n_args++;
+	}
+
+	/* Just panic if the number of arguments don't match */
+	g_assert (n_args != stmt_args);
+
+	return create_result_set_from_stmt (db_interface, stmt, error);
+}
+
+static TrackerDBResultSet *
+tracker_db_interface_sqlite_execute_query (TrackerDBInterface  *db_interface,
+					   GError             **error,
+					   const gchar         *query)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+	TrackerDBResultSet *result_set;
+	sqlite3_stmt *stmt;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+
+	sqlite3_prepare_v2 (priv->db, query, -1, &stmt, NULL);
+
+	if (!stmt) {
+		g_set_error (error,
+			     TRACKER_DB_INTERFACE_ERROR,
+			     TRACKER_DB_QUERY_ERROR,
+			     sqlite3_errmsg (priv->db));
+		return NULL;
+	}
+
+	result_set = create_result_set_from_stmt (db_interface, stmt, error);
+	sqlite3_finalize (stmt);
+
+	return result_set;
+}
+
+static void
+tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface)
+{
+	iface->set_procedure_table = tracker_db_interface_sqlite_set_procedure_table;
+	iface->execute_procedure = tracker_db_interface_sqlite_execute_procedure;
+	iface->execute_procedure_len = tracker_db_interface_sqlite_execute_procedure_len;
+	iface->execute_query = tracker_db_interface_sqlite_execute_query;
+}
+
+TrackerDBInterface *
+tracker_db_interface_sqlite_new (const gchar *filename)
+{
+	return g_object_new (TRACKER_TYPE_DB_INTERFACE_SQLITE,
+			     "filename", filename,
+			     NULL);
+}
+
+static gint
+collation_function (gpointer      data,
+		    int           len1,
+		    gconstpointer str1,
+		    int           len2,
+		    gconstpointer str2)
+{
+	TrackerDBCollationFunc func;
+
+	func = (TrackerDBCollationFunc) data;
+
+	return (func) ((gchar *) str1, len1, (gchar *) str2, len2);
+}
+
+void
+tracker_db_interface_sqlite_create_function (TrackerDBInterface *interface,
+					     const gchar        *name,
+					     TrackerDBFunc       func,
+					     gint                n_args)
+{
+	SqliteFunctionData *data;
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (interface);
+
+	data = g_new0 (SqliteFunctionData, 1);
+	data->interface = interface;
+	data->func = func;
+
+	priv->function_data = g_slist_prepend (priv->function_data, data);
+
+	sqlite3_create_function (priv->db, name, n_args, SQLITE_ANY, data, &internal_sqlite3_function, NULL, NULL);
+}
+
+gboolean
+tracker_db_interface_sqlite_set_collation_function (TrackerDBInterfaceSqlite *interface,
+						    const gchar              *name,
+						    TrackerDBCollationFunc    func)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+	gint result;
+
+	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE_SQLITE (interface), FALSE);
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (interface);
+
+	result = sqlite3_create_collation (priv->db, name, SQLITE_UTF8, func, &collation_function);
+
+	return (result == SQLITE_OK);
+}
+
+gint64
+tracker_db_interface_sqlite_get_last_insert_id (TrackerDBInterfaceSqlite *interface)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE_SQLITE (interface), 0);
+
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (interface);
+
+	return (gint64) sqlite3_last_insert_rowid (priv->db);
+}

Added: trunk/src/trackerd/tracker-db-interface-sqlite.h
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-db-interface-sqlite.h	Mon Apr 21 13:32:35 2008
@@ -0,0 +1,70 @@
+/* Tracker - Sqlite implementation
+ * 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.
+ */
+
+#ifndef __TRACKER_DB_INTERFACE_SQLITE_H__
+#define __TRACKER_DB_INTERFACE_SQLITE_H__
+
+#include "tracker-db-interface.h"
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_DB_INTERFACE_SQLITE         (tracker_db_interface_sqlite_get_type ())
+#define TRACKER_DB_INTERFACE_SQLITE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DB_INTERFACE_SQLITE, TrackerDBInterfaceSqlite))
+#define TRACKER_DB_INTERFACE_SQLITE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_DB_INTERFACE_SQLITE, TrackerDBInterfaceSqliteClass))
+#define TRACKER_IS_DB_INTERFACE_SQLITE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DB_INTERFACE_SQLITE))
+#define TRACKER_IS_DB_INTERFACE_SQLITE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((o),    TRACKER_TYPE_DB_INTERFACE_SQLITE))
+#define TRACKER_DB_INTERFACE_SQLITE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_DB_INTERFACE_SQLITE, TrackerDBInterfaceSqliteClass))
+
+typedef struct TrackerDBInterfaceSqlite TrackerDBInterfaceSqlite;
+typedef struct TrackerDBInterfaceSqliteClass TrackerDBInterfaceSqliteClass;
+
+typedef gint (* TrackerDBCollationFunc) (gchar *str1,
+					 gint   len1,
+					 gchar *str2,
+					 gint   len2);
+typedef GValue (* TrackerDBFunc) (TrackerDBInterface *interface,
+				  gint                argc,
+				  GValue              argv[]);
+
+struct TrackerDBInterfaceSqlite {
+	GObject parent_instance;
+};
+
+struct TrackerDBInterfaceSqliteClass {
+	GObjectClass parent_class;
+};
+
+GType tracker_db_interface_sqlite_get_type (void);
+
+TrackerDBInterface * tracker_db_interface_sqlite_new (const gchar *filename);
+
+void                 tracker_db_interface_sqlite_create_function        (TrackerDBInterface       *interface,
+									 const gchar              *name,
+									 TrackerDBFunc             func,
+									 gint                      n_args);
+gboolean             tracker_db_interface_sqlite_set_collation_function (TrackerDBInterfaceSqlite *interface,
+									 const gchar              *name,
+									 TrackerDBCollationFunc    func);
+
+gint64               tracker_db_interface_sqlite_get_last_insert_id     (TrackerDBInterfaceSqlite *interface);
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_DB_INTERFACE_SQLITE_H__ */

Added: trunk/src/trackerd/tracker-db-interface.c
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-db-interface.c	Mon Apr 21 13:32:35 2008
@@ -0,0 +1,626 @@
+/* Tracker - DB abstraction
+ * 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.
+ */
+
+#include <string.h>
+#include <gobject/gvaluecollector.h>
+#include "tracker-db-interface.h"
+
+
+#define TRACKER_DB_RESULT_SET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_DB_RESULT_SET, TrackerDBResultSetPrivate))
+
+typedef struct TrackerDBResultSetPrivate TrackerDBResultSetPrivate;
+
+struct TrackerDBResultSetPrivate {
+	GType *col_types;
+	GPtrArray *array;
+	guint columns;
+	guint current_row;
+};
+
+enum {
+	PROP_0,
+	PROP_COLUMNS
+};
+
+G_DEFINE_TYPE (TrackerDBResultSet, tracker_db_result_set, G_TYPE_OBJECT)
+
+GQuark
+tracker_db_interface_error_quark (void)
+{
+  return g_quark_from_static_string ("tracker-db-interface-error-quark");
+}
+
+static void
+tracker_db_interface_class_init (gpointer iface)
+{
+  g_object_interface_install_property (iface,
+				       g_param_spec_boolean ("in-transaction",
+							     "In transaction",
+							     "Whether the connection has a transaction opened",
+							     FALSE,
+							     G_PARAM_READWRITE));
+}
+
+GType
+tracker_db_interface_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		type = g_type_register_static_simple (G_TYPE_INTERFACE,
+						      "TrackerDBInterface",
+						      sizeof (TrackerDBInterfaceIface),
+						      (GClassInitFunc) tracker_db_interface_class_init,
+						      0, NULL, 0);
+
+		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+	}
+
+	return type;
+}
+
+/* Boxed type for blobs */
+static gpointer
+blob_copy (gpointer boxed)
+{
+	GByteArray *array, *copy;
+
+	array = (GByteArray *) boxed;
+	copy = g_byte_array_sized_new (array->len);
+	g_byte_array_append (copy, array->data, array->len);
+
+	return copy;
+}
+
+static void
+blob_free (gpointer boxed)
+{
+	GByteArray *array;
+
+	array = (GByteArray *) boxed;
+	g_byte_array_free (array, TRUE);
+}
+
+GType
+tracker_db_blob_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		type = g_boxed_type_register_static ("TrackerDBBlob",
+						     blob_copy,
+						     blob_free);
+	}
+
+	return type;
+}
+
+/* TrackerDBResultSet */
+static void
+tracker_db_result_set_set_property (GObject       *object,
+				    guint          prop_id,
+				    const GValue  *value,
+				    GParamSpec    *pspec)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_COLUMNS:
+		priv->columns = g_value_get_uint (value);
+		priv->col_types = g_new0 (GType, priv->columns);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+static void
+tracker_db_result_set_get_property (GObject    *object,
+				    guint       prop_id,
+				    GValue     *value,
+				    GParamSpec *pspec)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_COLUMNS:
+		g_value_set_uint (value, priv->columns);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+static void
+free_row (gpointer *row,
+	  gpointer  data)
+{
+	guint columns = GPOINTER_TO_UINT (data);
+	guint i;
+
+	if (!row)
+		return;
+
+	for (i = 0; i < columns; i++) {
+		g_free (row[i]);
+	}
+
+	g_free (row);
+}
+
+static void
+tracker_db_result_set_finalize (GObject *object)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (object);
+
+	if (priv->array) {
+		g_ptr_array_foreach (priv->array, (GFunc) free_row,
+				     GUINT_TO_POINTER (priv->columns));
+		g_ptr_array_free (priv->array, TRUE);
+	}
+
+	g_free (priv->col_types);
+
+	G_OBJECT_CLASS (tracker_db_result_set_parent_class)->finalize (object);
+}
+
+static void
+tracker_db_result_set_class_init (TrackerDBResultSetClass *class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+	object_class->set_property = tracker_db_result_set_set_property;
+	object_class->get_property = tracker_db_result_set_get_property;
+	object_class->finalize = tracker_db_result_set_finalize;
+
+	g_object_class_install_property (object_class,
+					 PROP_COLUMNS,
+					 g_param_spec_uint ("columns",
+							    "Columns",
+							    "Resultset columns",
+							    0, G_MAXUINT, 0,
+							    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+
+	g_type_class_add_private (object_class,
+				  sizeof (TrackerDBResultSetPrivate));
+}
+
+static void
+tracker_db_result_set_init (TrackerDBResultSet *result_set)
+{
+}
+
+static TrackerDBResultSet *
+ensure_result_set_state (TrackerDBResultSet *result_set)
+{
+	if (!result_set)
+		return NULL;
+
+	if (tracker_db_result_set_get_n_rows (result_set) == 0) {
+		g_object_unref (result_set);
+		return NULL;
+	}
+
+	/* ensure that it's at the first item */
+	tracker_db_result_set_rewind (result_set);
+
+	return result_set;
+}
+
+TrackerDBResultSet *
+tracker_db_interface_execute_vquery (TrackerDBInterface  *interface,
+				     GError             **error,
+				     const gchar         *query,
+				     va_list              args)
+{
+	TrackerDBResultSet *result_set = NULL;
+	gchar *str;
+
+	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (interface), NULL);
+	g_return_val_if_fail (query != NULL, NULL);
+
+	if (!TRACKER_DB_INTERFACE_GET_IFACE (interface)->execute_query) {
+		g_critical ("Database abstraction %s doesn't implement the method execute_vquery()", G_OBJECT_TYPE_NAME (interface));
+		return NULL;
+	}
+
+	str = g_strdup_vprintf (query, args);
+	result_set = TRACKER_DB_INTERFACE_GET_IFACE (interface)->execute_query (interface, error, str);
+	g_free (str);
+
+	return ensure_result_set_state (result_set);
+}
+
+TrackerDBResultSet *
+tracker_db_interface_execute_query (TrackerDBInterface  *interface,
+				    GError             **error,
+				    const gchar         *query,
+				    ...)
+{
+	TrackerDBResultSet *result_set;
+	va_list args;
+
+	va_start (args, query);
+	result_set = tracker_db_interface_execute_vquery (interface, error, query, args);
+	va_end (args);
+
+	return result_set;
+}
+
+void
+tracker_db_interface_set_procedure_table (TrackerDBInterface *interface,
+					  GHashTable         *procedure_table)
+{
+	g_return_if_fail (TRACKER_IS_DB_INTERFACE (interface));
+	g_return_if_fail (procedure_table != NULL);
+
+	if (!TRACKER_DB_INTERFACE_GET_IFACE (interface)->set_procedure_table) {
+		g_critical ("Database abstraction %s doesn't implement the method set_procedure_table()", G_OBJECT_TYPE_NAME (interface));
+		return;
+	}
+
+	TRACKER_DB_INTERFACE_GET_IFACE (interface)->set_procedure_table (interface, procedure_table);
+}
+
+TrackerDBResultSet *
+tracker_db_interface_execute_vprocedure (TrackerDBInterface  *interface,
+					 GError             **error,
+					 const gchar         *procedure,
+					 va_list              args)
+{
+	TrackerDBResultSet *result_set;
+
+	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (interface), NULL);
+	g_return_val_if_fail (procedure != NULL, NULL);
+
+	if (!TRACKER_DB_INTERFACE_GET_IFACE (interface)->execute_procedure) {
+		g_critical ("Database abstraction %s doesn't implement the method execute_procedure()", G_OBJECT_TYPE_NAME (interface));
+		return NULL;
+	}
+
+	result_set = TRACKER_DB_INTERFACE_GET_IFACE (interface)->execute_procedure (interface, error, procedure, args);
+
+	return ensure_result_set_state (result_set);
+}
+
+TrackerDBResultSet *
+tracker_db_interface_execute_vprocedure_len (TrackerDBInterface  *interface,
+					     GError             **error,
+					     const gchar         *procedure,
+					     va_list              args)
+{
+	TrackerDBResultSet *result_set;
+
+	g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (interface), NULL);
+	g_return_val_if_fail (procedure != NULL, NULL);
+
+	if (!TRACKER_DB_INTERFACE_GET_IFACE (interface)->execute_procedure_len) {
+		g_critical ("Database abstraction %s doesn't implement the method execute_procedure_len()", G_OBJECT_TYPE_NAME (interface));
+		return NULL;
+	}
+
+	result_set = TRACKER_DB_INTERFACE_GET_IFACE (interface)->execute_procedure_len (interface, error, procedure, args);
+
+	return ensure_result_set_state (result_set);
+}
+
+TrackerDBResultSet *
+tracker_db_interface_execute_procedure (TrackerDBInterface  *interface,
+					GError             **error,
+					const gchar         *procedure,
+					...)
+{
+	TrackerDBResultSet *result_set;
+	va_list args;
+
+	va_start (args, procedure);
+	result_set = tracker_db_interface_execute_vprocedure (interface, error, procedure, args);
+	va_end (args);
+
+	return result_set;
+}
+
+TrackerDBResultSet *
+tracker_db_interface_execute_procedure_len (TrackerDBInterface  *interface,
+					    GError             **error,
+					    const gchar         *procedure,
+					    ...)
+{
+	TrackerDBResultSet *result_set;
+	va_list args;
+
+	va_start (args, procedure);
+	result_set = tracker_db_interface_execute_vprocedure_len (interface, error, procedure, args);
+	va_end (args);
+
+	return result_set;
+}
+
+gboolean
+tracker_db_interface_start_transaction (TrackerDBInterface *interface)
+{
+	GError *error = NULL;
+
+	tracker_db_interface_execute_query (interface, &error, "BEGIN TRANSACTION");
+
+	if (error) {
+		g_warning (error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+
+	g_object_set (interface, "in-transaction", TRUE, NULL);
+	return TRUE;
+}
+
+gboolean
+tracker_db_interface_end_transaction (TrackerDBInterface *interface)
+{
+	gboolean in_transaction;
+	GError *error = NULL;
+
+	g_object_get (interface, "in-transaction", &in_transaction, NULL);
+
+	if (!in_transaction)
+		return FALSE;
+
+	g_object_set (interface, "in-transaction", FALSE, NULL);
+	tracker_db_interface_execute_query (interface, &error, "COMMIT");
+
+	if (error) {
+		g_warning (error->message);
+		g_error_free (error);
+
+		tracker_db_interface_execute_query (interface, NULL, "ROLLBACK");
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/* TrackerDBResultSet semiprivate API */
+TrackerDBResultSet *
+_tracker_db_result_set_new (guint columns)
+{
+	return g_object_new (TRACKER_TYPE_DB_RESULT_SET,
+			     "columns", columns,
+			     NULL);
+}
+
+void
+_tracker_db_result_set_append (TrackerDBResultSet *result_set)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_DB_RESULT_SET (result_set));
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+
+	if (G_UNLIKELY (!priv->array)) {
+		priv->array = g_ptr_array_sized_new (100);
+	}
+
+	g_ptr_array_add (priv->array, NULL);
+	priv->current_row = priv->array->len - 1;
+}
+
+void
+_tracker_db_result_set_set_value (TrackerDBResultSet *result_set,
+				  guint               column,
+				  const GValue       *value)
+{
+	TrackerDBResultSetPrivate *priv;
+	gpointer *row = NULL;
+
+	g_return_if_fail (TRACKER_IS_DB_RESULT_SET (result_set));
+
+	/* just return if the value doesn't contain anything */
+	if (G_VALUE_TYPE (value) == 0)
+		return;
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+
+	g_return_if_fail (column < priv->columns);
+
+	/* Assign a GType if it didn't have any */
+	if (G_UNLIKELY (priv->col_types[column] == 0))
+		priv->col_types[column] = G_VALUE_TYPE (value);
+
+	row = g_ptr_array_index (priv->array, priv->current_row);
+
+	/* Allocate space for the row, if it wasn't allocated previously */
+	if (G_UNLIKELY (!row)) {
+		row = g_new0 (gpointer, priv->columns);
+		g_ptr_array_index (priv->array, priv->current_row) = row;
+	}
+
+	switch (priv->col_types [column]) {
+	case G_TYPE_INT: {
+		gint *val;
+
+		val = g_new (gint, 1);
+		*val = g_value_get_int (value);
+		row[column] = val;
+		break;
+	}
+	case G_TYPE_DOUBLE: {
+		gdouble *val;
+
+		val = g_new (gdouble, 1);
+		*val = g_value_get_double (value);
+		row[column] = val;
+		break;
+	}
+	case G_TYPE_STRING:
+		row[column] = (gpointer) g_value_dup_string (value);
+		break;
+	default:
+		g_warning ("Unknown type for resultset: %s\n", G_VALUE_TYPE_NAME (value));
+	}
+}
+
+static void
+fill_in_value (GValue   *value,
+	       gpointer  data)
+{
+	switch (G_VALUE_TYPE (value)) {
+	case G_TYPE_INT:
+		g_value_set_int (value, *((gint*) data));
+		break;
+	case G_TYPE_DOUBLE:
+		g_value_set_double (value, *((gdouble *) data));
+		break;
+	case G_TYPE_STRING:
+		g_value_set_string (value, data);
+		break;
+	}
+}
+
+void
+_tracker_db_result_set_get_value (TrackerDBResultSet *result_set,
+				  guint               column,
+				  GValue             *value)
+{
+	TrackerDBResultSetPrivate *priv;
+	gpointer *row;
+
+	g_return_if_fail (TRACKER_IS_DB_RESULT_SET (result_set));
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+	row = g_ptr_array_index (priv->array, priv->current_row);
+
+	if (priv->col_types[column] != G_TYPE_INVALID) {
+		g_value_init (value, priv->col_types[column]);
+		fill_in_value (value, row[column]);
+	} else {
+		/* Make up some empty value */
+		g_value_init (value, G_TYPE_STRING);
+		g_value_set_string (value, "");
+	}
+}
+
+/* TrackerDBResultSet API */
+void
+tracker_db_result_set_get (TrackerDBResultSet *result_set,
+			   ...)
+{
+	TrackerDBResultSetPrivate *priv;
+	va_list args;
+	gint n_col;
+	GValue value = { 0, };
+	gpointer *row;
+	gchar *error = NULL;
+
+	g_return_if_fail (TRACKER_IS_DB_RESULT_SET (result_set));
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+	row = g_ptr_array_index (priv->array, priv->current_row);
+	va_start (args, result_set);
+
+	while ((n_col = va_arg (args, gint)) >= 0) {
+		if ((guint) n_col >= priv->columns) {
+			g_critical ("Result set has %d columns, trying to access column %d, "
+				    "maybe -1 is missing at the end of the arguments?",
+				    priv->columns, n_col);
+			break;
+		}
+
+		if (priv->col_types[n_col] != G_TYPE_INVALID) {
+			g_value_init (&value, priv->col_types[n_col]);
+			fill_in_value (&value, row[n_col]);
+			G_VALUE_LCOPY (&value, args, 0, &error);
+			g_value_unset (&value);
+		} else {
+			gpointer *pointer;
+
+			/* No valid type, set to NULL/0 */
+			pointer = va_arg (args, gpointer *);
+			*pointer = NULL;
+		}
+
+		if (error) {
+			g_warning (error);
+			g_free (error);
+		}
+	}
+
+	va_end (args);
+}
+
+void
+tracker_db_result_set_rewind (TrackerDBResultSet *result_set)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_DB_RESULT_SET (result_set));
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+	priv->current_row = 0;
+}
+
+gboolean
+tracker_db_result_set_iter_next (TrackerDBResultSet *result_set)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_DB_RESULT_SET (result_set), FALSE);
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+
+	if (priv->current_row + 1 >= priv->array->len)
+		return FALSE;
+
+	priv->current_row++;
+	return TRUE;
+}
+
+guint
+tracker_db_result_set_get_n_columns (TrackerDBResultSet *result_set)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_DB_RESULT_SET (result_set), 0);
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+
+	return priv->columns;
+}
+
+guint
+tracker_db_result_set_get_n_rows (TrackerDBResultSet *result_set)
+{
+	TrackerDBResultSetPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_DB_RESULT_SET (result_set), 0);
+
+	priv = TRACKER_DB_RESULT_SET_GET_PRIVATE (result_set);
+
+	if (!priv->array)
+		return 0;
+
+	return priv->array->len;
+}

Added: trunk/src/trackerd/tracker-db-interface.h
==============================================================================
--- (empty file)
+++ trunk/src/trackerd/tracker-db-interface.h	Mon Apr 21 13:32:35 2008
@@ -0,0 +1,141 @@
+/* Tracker - DB abstraction
+ * 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.
+ */
+
+#ifndef __TRACKER_DB_INTERFACE_H__
+#define __TRACKER_DB_INTERFACE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_DB_INTERFACE           (tracker_db_interface_get_type ())
+#define TRACKER_DB_INTERFACE(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRACKER_TYPE_DB_INTERFACE, TrackerDBInterface))
+#define TRACKER_IS_DB_INTERFACE(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRACKER_TYPE_DB_INTERFACE))
+#define TRACKER_DB_INTERFACE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TRACKER_TYPE_DB_INTERFACE, TrackerDBInterfaceIface))
+
+#define TRACKER_TYPE_DB_RESULT_SET          (tracker_db_result_set_get_type ())
+#define TRACKER_DB_RESULT_SET(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DB_RESULT_SET, TrackerDbResultSet))
+#define TRACKER_DB_RESULT_SET_CLASS(c)      (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_DB_RESULT_SET, TrackerDbResultSetClass))
+#define TRACKER_IS_DB_RESULT_SET(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DB_RESULT_SET))
+#define TRACKER_IS_DB_RESULT_SET_CLASS(c)   (G_TYPE_CHECK_CLASS_TYPE ((o),    TRACKER_TYPE_DB_RESULT_SET))
+#define TRACKER_DB_RESULT_SET_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_DB_RESULT_SET, TrackerDbResultSetClass))
+
+#define TRACKER_TYPE_DB_BLOB                (tracker_db_blob_get_type ())
+
+#define TRACKER_DB_INTERFACE_ERROR          (tracker_db_interface_error_quark ())
+
+typedef enum {
+	TRACKER_DB_QUERY_ERROR,
+	TRACKER_DB_CORRUPT
+} TrackerDBInterfaceError;
+
+typedef struct TrackerDBInterface TrackerDBInterface;
+typedef struct TrackerDBInterfaceIface TrackerDBInterfaceIface;
+typedef struct TrackerDBResultSet TrackerDBResultSet;
+typedef struct TrackerDBResultSetClass TrackerDBResultSetClass;
+
+struct TrackerDBInterfaceIface {
+	GTypeInterface iface;
+
+	void                 (* set_procedure_table)   (TrackerDBInterface  *interface,
+							GHashTable          *procedure_table);
+	TrackerDBResultSet * (* execute_procedure)     (TrackerDBInterface  *interface,
+							GError             **error,
+							const gchar         *procedure,
+							va_list              args);
+	TrackerDBResultSet * (* execute_procedure_len) (TrackerDBInterface  *interface,
+							GError             **error,
+							const gchar         *procedure,
+							va_list              args);
+	TrackerDBResultSet * (* execute_query)         (TrackerDBInterface  *interface,
+							GError             **error,
+							const gchar         *query);
+};
+
+struct TrackerDBResultSet {
+	GObject parent_class;
+};
+
+struct TrackerDBResultSetClass {
+	GObjectClass parent_class;
+};
+
+
+GQuark tracker_db_interface_error_quark (void);
+
+GType tracker_db_interface_get_type (void);
+GType tracker_db_result_set_get_type (void);
+GType tracker_db_blob_get_type (void);
+
+
+/* Functions to create queries/procedures */
+TrackerDBResultSet *    tracker_db_interface_execute_vquery      (TrackerDBInterface   *interface,
+								  GError             **error,
+								  const gchar          *query,
+								  va_list               args);
+TrackerDBResultSet *    tracker_db_interface_execute_query       (TrackerDBInterface   *interface,
+								  GError             **error,
+								  const gchar          *query,
+								  ...) G_GNUC_PRINTF (3, 4);
+void                    tracker_db_interface_set_procedure_table (TrackerDBInterface   *interface,
+								  GHashTable           *procedure_table);
+TrackerDBResultSet *    tracker_db_interface_execute_vprocedure  (TrackerDBInterface   *interface,
+								  GError             **error,
+								  const gchar          *procedure,
+								  va_list               args);
+TrackerDBResultSet *    tracker_db_interface_execute_procedure   (TrackerDBInterface   *interface,
+								  GError             **error,
+								  const gchar          *procedure,
+								  ...) G_GNUC_NULL_TERMINATED;
+
+TrackerDBResultSet *    tracker_db_interface_execute_vprocedure_len (TrackerDBInterface   *interface,
+								     GError             **error,
+								     const gchar          *procedure,
+								     va_list               args);
+TrackerDBResultSet *    tracker_db_interface_execute_procedure_len  (TrackerDBInterface   *interface,
+								     GError             **error,
+								     const gchar          *procedure,
+								     ...) G_GNUC_NULL_TERMINATED;
+
+gboolean                tracker_db_interface_start_transaction      (TrackerDBInterface   *interface);
+gboolean                tracker_db_interface_end_transaction        (TrackerDBInterface   *interface);
+
+
+/* Semi private TrackerDBResultSet functions */
+TrackerDBResultSet *      _tracker_db_result_set_new           (guint               cols);
+void                      _tracker_db_result_set_append        (TrackerDBResultSet *result_set);
+void                      _tracker_db_result_set_set_value     (TrackerDBResultSet *result_set,
+								guint               column,
+								const GValue       *value);
+void                      _tracker_db_result_set_get_value     (TrackerDBResultSet *result_set,
+								guint               column,
+								GValue             *value);
+
+/* Functions to deal with the resultset */
+void                      tracker_db_result_set_get            (TrackerDBResultSet *result_set,
+								...);
+void                      tracker_db_result_set_rewind         (TrackerDBResultSet *result_set);
+gboolean                  tracker_db_result_set_iter_next      (TrackerDBResultSet *result_set);
+guint                     tracker_db_result_set_get_n_columns  (TrackerDBResultSet *result_set);
+guint                     tracker_db_result_set_get_n_rows     (TrackerDBResultSet *result_set);
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_DB_INTERFACE_H__ */

Modified: trunk/src/trackerd/tracker-db-sqlite.c
==============================================================================
--- trunk/src/trackerd/tracker-db-sqlite.c	(original)
+++ trunk/src/trackerd/tracker-db-sqlite.c	Mon Apr 21 13:32:35 2008
@@ -46,6 +46,7 @@
 #include <libtracker-common/tracker-log.h>
 #include <libtracker-common/tracker-config.h>
 
+#include "tracker-db-interface-sqlite.h"
 #include "tracker-db-sqlite.h"
 #include "tracker-indexer.h"
 #include "tracker-cache.h"
@@ -80,7 +81,7 @@
 /* sqlite utf-8 user defined collation sequence */
 
 static int 
-sqlite3_utf8_collation (void *NotUsed,  int len1, const void *str1,  int len2, const void *str2)
+utf8_collation_func (gchar *str1, gint len1, gchar *str2, int len2)
 {
 	char *word1, *word2;
 	int result;
@@ -104,151 +105,130 @@
 /* sqlite user defined functions for use in sql */
 
 /* converts date/time in UTC format to ISO 8160 standardised format for display */
-static void
-sqlite3_date_to_str (sqlite3_context *context, int argc, sqlite3_value **argv)
-{
-	const char *output;
-
-	switch (sqlite3_value_type (argv[0])) {
-
-		case SQLITE_NULL: 
-			sqlite3_result_null (context);
-			break;
-		
+static GValue
+function_date_to_str (TrackerDBInterface *interface,
+		      gint                argc,
+		      GValue              values[])
+{
+	GValue result = { 0, };
+	gchar *str;
+
+	str = tracker_date_to_str (g_value_get_double (&values[0]));
+	g_value_init (&result, G_TYPE_STRING);
+	g_value_take_string (&result, str);
 
-		default:
-			output = tracker_date_to_str (sqlite3_value_double (argv[0]));
-			sqlite3_result_text (context, output, strlen (output), g_free);
-		
-	}
+	return result;
 }
 
-
-/* implements regexp functionality */
-static void
-sqlite3_regexp (sqlite3_context *context, int argc, sqlite3_value **argv)
+static GValue
+function_regexp (TrackerDBInterface *interface,
+		 gint                argc,
+		 GValue              values[])
 {
-	int	ret;
+	GValue result = { 0, };
 	regex_t	regex;
+	int	ret;
 
 	if (argc != 2) {
-		sqlite3_result_error (context, "Invalid argument count", -1);
-		return;
+		g_critical ("Invalid argument count");
+		return result;
 	}
 
-	ret = regcomp (&regex, (char *) sqlite3_value_text(argv[0]), REG_EXTENDED | REG_NOSUB);
+	ret = regcomp (&regex,
+		       g_value_get_string (&values[0]),
+		       REG_EXTENDED | REG_NOSUB);
 
 	if (ret != 0) {
-		sqlite3_result_error (context, "error compiling regular expression", -1);
-		return;
+		g_critical ("Error compiling regular expression");
+		return result;
 	}
 
-	ret = regexec (&regex, (char *) sqlite3_value_text(argv[1]), 0, NULL, 0);
+	ret = regexec (&regex,
+		       g_value_get_string (&values[1]),
+		       0, NULL, 0);
+
+	g_value_init (&result, G_TYPE_INT);
+	g_value_set_int (&result, (ret == REG_NOMATCH) ? 0 : 1);
 	regfree (&regex);
 
-	sqlite3_result_int (context, (ret == REG_NOMATCH) ? 0 : 1);
+	return result;
 }
 
-
 /* unzips data */
-static void
-sqlite3_uncompress (sqlite3_context *context, int argc, sqlite3_value **argv)
+static GValue
+function_uncompress (TrackerDBInterface *interface,
+		     gint                argc,
+		     GValue              values[])
 {
-	switch (sqlite3_value_type (argv[0])) {
-
-		case SQLITE_NULL: {
-			sqlite3_result_null (context);
-			break;
-		}
-
-		default:{
-			int  len1, len2;
-			char *output;
+	GByteArray *array;
+	GValue result = { 0, };
+	gchar *output;
+	gint len;
 
-			len1 = sqlite3_value_bytes (argv[0]);
+	array = g_value_get_boxed (&values[0]);
 
-			output = tracker_uncompress (sqlite3_value_blob (argv[0]), len1, &len2);
-
-			if (output) {
-				sqlite3_result_text (context, output, len2, g_free);
-			} else {
-				tracker_error ("ERROR: decompression failed");
-				sqlite3_result_text (context, sqlite3_value_blob (argv[0]), len1, NULL);
-			}
-		}
+	if (!array) {
+		return result;
 	}
-}
- 
-
-static void
-sqlite3_get_service_name (sqlite3_context *context, int argc, sqlite3_value **argv)
-{
-	switch (sqlite3_value_type (argv[0])) {
-
-		case SQLITE_NULL: {
-			sqlite3_result_null (context);
-			break;
-		}
 
-		default:{
-			gchar *output;
+	output = tracker_uncompress ((const gchar *) array->data, array->len, &len);
 
-			output = tracker_service_manager_get_service_by_id (sqlite3_value_int (argv[0]));
-			sqlite3_result_text (context, output, strlen (output), g_free);
-		}
+	if (!output) {
+		g_warning ("Uncompress failed");
+		return result;
 	}
-}
-
-
-static void
-sqlite3_get_service_type (sqlite3_context *context, int argc, sqlite3_value **argv)
-{
-	switch (sqlite3_value_type (argv[0])) {
 
-		case SQLITE_NULL: {
-			sqlite3_result_null (context);
-			break;
-		}
+	g_value_init (&result, G_TYPE_STRING);
+	g_value_take_string (&result, output);
 
-		default:{
-                        const gchar *service;
-			gint         output;
-
-                        service = (const gchar*) sqlite3_value_text (argv[0]);
-			output = tracker_service_manager_get_id_for_service (service);
-			sqlite3_result_int (context, output);
-		}
-	}
+	return result;
 }
 
+static GValue
+function_get_service_name (TrackerDBInterface *interface,
+			   gint                argc,
+			   GValue              values[])
+{
+	GValue result = { 0, };
+	gchar *str;
+
+	str = tracker_service_manager_get_service_by_id (g_value_get_int (&values[0]));
+	g_value_init (&result, G_TYPE_STRING);
+	g_value_take_string (&result, str);
 
-static void
-sqlite3_get_max_service_type (sqlite3_context *context, int argc, sqlite3_value **argv)
-{
-	switch (sqlite3_value_type (argv[0])) {
-
-		case SQLITE_NULL: {
-			sqlite3_result_null (context);
-			break;
-		}
+	return result;
+}
 
-		default:{
-                        const gchar *service;
-			gint          output;
+static GValue
+function_get_service_type (TrackerDBInterface *interface,
+			   gint                argc,
+			   GValue              values[])
+{
+	GValue result = { 0, };
+	gint id;
+
+	id = tracker_service_manager_get_id_for_service (g_value_get_string (&values[0]));
+	g_value_init (&result, G_TYPE_INT);
+	g_value_set_int (&result, id);
 
-                        service = (const gchar*) sqlite3_value_text (argv[0]);
-			output = tracker_service_manager_get_id_for_service (service);
+	return result;
+}
 
-			if (output == 0) {
-				output = 8;
-			}
+static GValue
+function_get_max_service_type (TrackerDBInterface *interface,
+			       gint                argc,
+			       GValue              values[])
+{
+	GValue result = { 0, };
+	gint id;
+
+	id = tracker_service_manager_get_id_for_service (g_value_get_string (&values[0]));
+	g_value_init (&result, G_TYPE_INT);
+	g_value_set_int (&result, id);
 
-			sqlite3_result_int (context, output);
-		}
-	}
+	return result;
 }
 
-
 static void
 load_sql_file (DBConnection *db_con, const char *sql_file)
 {
@@ -339,54 +319,6 @@
 	return NULL;
 }
 
-
-void
-tracker_db_log_result (char ***result)
-{
-	char ***rows;
-
-	if (!result) {
-		tracker_log ("no records");
-		return;
-	}
-
-	for (rows = result; *rows; rows++) {
-		char **row;
-		char *str;
-
-		str = NULL;
-
-		for (row = *rows; *row; row++) {
-			char *value;
-
-                        value = tracker_string_replace (*row, "%", "%%");
-
-			if (!value) {
-				value = "NULL";
-			}
-
-			if (str) {
-				char *tmp;
-
-				tmp = g_strdup (str);
-				g_free (str);
-				str = g_strconcat (tmp, ", ", value, NULL);
-				g_free (tmp);
-			} else {
-				str = g_strconcat (value, NULL);
-			}
-
-			g_free (value);
-		}
-
-		if (str) {
-			tracker_log (str);
-			g_free (str);
-		}
-	}
-}
-
-
 void
 tracker_db_free_result (char ***result)
 {
@@ -462,21 +394,13 @@
 
 
 gboolean
-tracker_db_initialize (const char *datadir)
+tracker_db_initialize (void)
 {
 	FILE	 *file;
 	char	 *sql_file;
 	GTimeVal *tv;
 	int i = 0;
 
-
-	//g_assert (sqlite3_threadsafe() != 0);
-
-	tracker_log ("Using Sqlite version %s", sqlite3_version);
-
-	//sequence_mutex = g_mutex_new ();
-
-	/* load prepared queries */
 	prepared_queries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
 	tracker_log ("Loading prepared queries...");
@@ -515,15 +439,15 @@
 		sep = strchr (buffer, ' ');
 
 		if (sep) {
-			char *query, *name;
+			const char *query, *name;
 
 			*sep = '\0';
 
-			query = g_strdup (sep + 1);
-			name = g_strdup (buffer);
+			query = sep + 1;
+			name = buffer;
 
 			//tracker_log ("installing query %s with sql %s", name, query);
-			g_hash_table_insert (prepared_queries, name, query);
+			g_hash_table_insert (prepared_queries, g_strdup (name), g_strdup (query));
 		} else {
 			continue;
 		}
@@ -547,60 +471,20 @@
 //	sqlite3_enable_shared_cache (1);
 }
 
-
-void
-tracker_db_thread_end (void)
-{
-	sqlite3_thread_cleanup ();
-}
-
-
 void
 tracker_db_finalize (void)
 {
 }
 
-
-static void
-finalize_statement (gpointer key,
-		    gpointer value,
-		    gpointer user_data)
-{
-	sqlite3_stmt *stmt;
-
-	stmt = value;
-
-	if (key && stmt) {
-		if (sqlite3_finalize (stmt)!= SQLITE_OK) {
-			DBConnection *db_con;
-
-			db_con = user_data;
-
-			tracker_error ("ERROR: statement could not be finalized for %s with error %s", (char *) key, sqlite3_errmsg (db_con->db));
-		}
-	}
-}
-
-
-
 static inline void
 close_db (DBConnection *db_con)
 {
-	if (db_con->statements) {
-		g_hash_table_foreach (db_con->statements, finalize_statement, db_con);
-	}
-
-	g_hash_table_destroy (db_con->statements);
-	db_con->statements = NULL;
-
-	if (sqlite3_close (db_con->db) != SQLITE_OK) {
-		tracker_error ("ERROR: database close operation failed for thread %s due to %s", db_con->thread, sqlite3_errmsg (db_con->db));
-	} else {
-		if (db_con->thread)
-			tracker_debug ("Database closed for thread %s", db_con->thread);
+	if (db_con->db) {
+		g_object_unref (db_con->db);
+		db_con->db = NULL;
 	}
 
-
+	tracker_debug ("Database closed for thread %s", db_con->thread);
 }
 
 
@@ -648,66 +532,55 @@
 */
 
 
-static sqlite3 *
+static TrackerDBInterface *
 open_user_db (const char *name, gboolean *create_table)
 {
-	char	     	*dbname;
-	sqlite3 	*db;
+	TrackerDBInterface *db;
+	gboolean db_exists;
+	char *dbname;
 
-	*create_table = FALSE;
-	
 	dbname = g_build_filename (tracker->user_data_dir, name, NULL);
+	db_exists = g_file_test (dbname, G_FILE_TEST_IS_REGULAR);
 
-	if (!g_file_test (dbname, G_FILE_TEST_IS_REGULAR)) {
+	if (!db_exists) {
 		tracker_log ("database file %s is not present - will create", dbname);
-		*create_table = TRUE;
-	} 
-
-
-	if (sqlite3_open (dbname, &db) != SQLITE_OK) {
-		tracker_error ("FATAL ERROR: can't open database at %s: %s", dbname, sqlite3_errmsg (db));
-		exit (1);
 	}
 
-	sqlite3_extended_result_codes (db, 0);
+	if (create_table) {
+		*create_table = db_exists;
+	}
 
+	db = tracker_db_interface_sqlite_new (dbname);
+	tracker_db_interface_set_procedure_table (db, prepared_queries);
 	g_free (dbname);
 
-	sqlite3_busy_timeout (db, 10000000);
-
 	return db;
-
 }
 
 
 
-static sqlite3 *
+static TrackerDBInterface *
 open_db (const char *name, gboolean *create_table)
 {
-	char	     	*dbname;
-	sqlite3 	*db;
+	TrackerDBInterface *db;
+	gboolean db_exists;
+	char *dbname;
 
-	*create_table = FALSE;
-	
 	dbname = g_build_filename (tracker->data_dir, name, NULL);
+	db_exists = g_file_test (dbname, G_FILE_TEST_IS_REGULAR);
 
-	if (!g_file_test (dbname, G_FILE_TEST_IS_REGULAR)) {
+	if (!db_exists) {
 		tracker_log ("database file %s is not present - will create", dbname);
-		*create_table = TRUE;
-	} 
-
-
-	if (sqlite3_open (dbname, &db) != SQLITE_OK) {
-		tracker_error ("FATAL ERROR: can't open database at %s: %s", dbname, sqlite3_errmsg (db));
-		exit (1);
 	}
 
-	sqlite3_extended_result_codes (db, 0);
+	if (create_table) {
+		*create_table = db_exists;
+	}
 
+	db = tracker_db_interface_sqlite_new (dbname);
+	tracker_db_interface_set_procedure_table (db, prepared_queries);
 	g_free (dbname);
 
-	sqlite3_busy_timeout (db, 10000000);
-
 	return db;
 
 }
@@ -716,49 +589,28 @@
 static void
 set_params (DBConnection *db_con, int cache_size, gboolean add_functions)
 {
-	db_con->statements = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
 	tracker_db_set_default_pragmas (db_con);
 
-	tracker_db_exec_no_reply (db_con, "PRAGMA page_size = 4096");
-
-	char *prag;
+	tracker_db_exec_no_reply (db_con, "PRAGMA page_size = %d", 4096);
 
-	if (!tracker_config_get_low_memory_mode (tracker->config)) {
-		prag = g_strdup_printf ("PRAGMA cache_size = %d", cache_size);
-	} else {
-		prag = g_strdup_printf ("PRAGMA cache_size = %d", cache_size/2);
+	if (tracker_config_get_low_memory_mode (tracker->config)) {
+		cache_size /= 2;
 	}
 
-	tracker_db_exec_no_reply (db_con, prag);
-
-	sqlite3_busy_timeout (db_con->db, 10000000);
-
-	g_free (prag);
+	tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = %d", cache_size);
 
 	if (add_functions) {
-		/* create user defined utf-8 collation sequence */
-		if (SQLITE_OK != sqlite3_create_collation (db_con->db, "UTF8", SQLITE_UTF8, 0, &sqlite3_utf8_collation)) {
-			tracker_error ("ERROR: collation sequence failed due to %s", sqlite3_errmsg (db_con->db));
+		if (! tracker_db_interface_sqlite_set_collation_function (TRACKER_DB_INTERFACE_SQLITE (db_con->db),
+									  "UTF8", utf8_collation_func)) {
+			tracker_error ("ERROR: collation sequence failed");
 		}
-	
 
 		/* create user defined functions that can be used in sql */
-		if (SQLITE_OK != sqlite3_create_function (db_con->db, "FormatDate", 1, SQLITE_ANY, NULL, &sqlite3_date_to_str, NULL, NULL)) {
-			tracker_error ("ERROR: function FormatDate failed due to %s", sqlite3_errmsg (db_con->db));
-		}
-		if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetServiceName", 1, SQLITE_ANY, NULL, &sqlite3_get_service_name, NULL, NULL)) {
-			tracker_error ("ERROR: function GetServiceName failed due to %s", sqlite3_errmsg (db_con->db));
-		}
-		if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetServiceTypeID", 1, SQLITE_ANY, NULL, &sqlite3_get_service_type, NULL, NULL)) {
-			tracker_error ("ERROR: function GetServiceTypeID failed due to %s", sqlite3_errmsg (db_con->db));
-		}
-		if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetMaxServiceTypeID", 1, SQLITE_ANY, NULL, &sqlite3_get_max_service_type, NULL, NULL)) {
-			tracker_error ("ERROR: function GetMaxServiceTypeID failed due to %s", sqlite3_errmsg (db_con->db));
-		}
-		if (SQLITE_OK != sqlite3_create_function (db_con->db, "REGEXP", 2, SQLITE_ANY, NULL, &sqlite3_regexp, NULL, NULL)) {
-			tracker_error ("ERROR: function REGEXP failed due to %s", sqlite3_errmsg (db_con->db));
-		}
+		tracker_db_interface_sqlite_create_function (db_con->db, "FormatDate", function_date_to_str, 1);
+		tracker_db_interface_sqlite_create_function (db_con->db, "GetServiceName", function_get_service_name, 1);
+		tracker_db_interface_sqlite_create_function (db_con->db, "GetServiceTypeID", function_get_service_type, 1);
+		tracker_db_interface_sqlite_create_function (db_con->db, "GetMaxServiceTypeID", function_get_max_service_type, 1);
+		tracker_db_interface_sqlite_create_function (db_con->db, "REGEXP", function_regexp, 2);
 	}
 }
 
@@ -804,28 +656,17 @@
 void
 tracker_db_attach_db (DBConnection *db_con, const char *name)
 {
-
-	char *sql = NULL;
+	gchar *path;
 
 	if (strcmp (name, "common") == 0) {
-	
-		char *path = g_build_filename (tracker->user_data_dir, "common.db", NULL);
-		sql = g_strdup_printf ("ATTACH '%s' as %s", path, name);
-		g_free (path);
-
-		tracker_db_exec_no_reply (db_con, sql);
-
+		path = g_build_filename (tracker->user_data_dir, "common.db", NULL);
+		tracker_db_exec_no_reply (db_con, "ATTACH '%s' as %s", path, name);
 	} else if (strcmp (name, "cache") == 0) {
-	
-		char *path = g_build_filename (tracker->sys_tmp_root_dir, "cache.db", NULL);
-		sql = g_strdup_printf ("ATTACH '%s' as %s", path, name);
-		g_free (path);
-
-		tracker_db_exec_no_reply (db_con, sql);
-
+		path = g_build_filename (tracker->sys_tmp_root_dir, "cache.db", NULL);
+		tracker_db_exec_no_reply (db_con, "ATTACH '%s' as %s", path, name);
 	}
 
-	g_free (sql);
+	g_free (path);
 }
 
 static inline void
@@ -938,25 +779,17 @@
 void
 tracker_db_start_index_transaction (DBConnection *db_con)
 {
-	DBConnection *tmp;
 	DBConnection *email_db_con = db_con->emails;
 
-
-	tmp = db_con->common;
-	if (!tmp->in_transaction) tracker_db_start_transaction (tmp);
-	
+	tracker_db_interface_start_transaction (db_con->common->db);
 
 	/* files */
-	if (!db_con->in_transaction) tracker_db_start_transaction (db_con);
-
-	tmp = db_con->blob;
-	if (!tmp->in_transaction) tracker_db_start_transaction (tmp);
+	tracker_db_interface_start_transaction (db_con->db);
+	tracker_db_interface_start_transaction (db_con->blob->db);
 
 	/* emails */
-	if (!email_db_con->in_transaction) tracker_db_start_transaction (email_db_con);
-
-	tmp = email_db_con->blob;
-	if (!tmp->in_transaction) tracker_db_start_transaction (tmp);
+	tracker_db_interface_start_transaction (email_db_con->db);
+	tracker_db_interface_start_transaction (email_db_con->blob->db);
 }
 
 
@@ -964,34 +797,17 @@
 void
 tracker_db_end_index_transaction (DBConnection *db_con)
 {
-	DBConnection *tmp;
 	DBConnection *email_db_con = db_con->emails;
 
-	tmp = db_con->common;
-	if (tmp->in_transaction) {
-		tracker_db_end_transaction (tmp);
-	}
+	tracker_db_interface_end_transaction (db_con->common->db);
 
 	/* files */
-	if (db_con->in_transaction) {
-		tracker_db_end_transaction (db_con);
-	}
-
-	tmp = db_con->blob;
-	if (tmp->in_transaction) {
-		tracker_db_end_transaction (tmp);
-	}
+	tracker_db_interface_end_transaction (db_con->db);
+	tracker_db_interface_end_transaction (db_con->blob->db);
 
 	/* emails */
-	if (email_db_con->in_transaction) {
-		tracker_db_end_transaction (email_db_con);
-	}
-
-	tmp = email_db_con->blob;
-	if (tmp->in_transaction) {
-		tracker_db_end_transaction (tmp);
-	}
-
+	tracker_db_interface_end_transaction (email_db_con->db);
+	tracker_db_interface_end_transaction (email_db_con->blob->db);
 }
 
 
@@ -1014,65 +830,47 @@
 DBConnection *
 tracker_db_connect (void)
 {
-	char	     *dbname;
 	DBConnection *db_con;
-
 	gboolean create_table = FALSE;
+	char *dbname;
 
 	dbname = g_build_filename (tracker->data_dir, "file-meta.db", NULL);
 
 	if (!g_file_test (dbname, G_FILE_TEST_IS_REGULAR)) {
 		tracker_log ("database file %s is not present - will create", dbname);
 		create_table = TRUE;
-	} 
-
-	db_con = g_new0 (DBConnection, 1);
-
-	if (sqlite3_open (dbname, &db_con->db) != SQLITE_OK) {
-		tracker_error ("FATAL ERROR: can't open database at %s: %s", dbname, sqlite3_errmsg (db_con->db));
-		exit (1);
 	}
 
+	db_con = g_new0 (DBConnection, 1);
+	db_con->db = tracker_db_interface_sqlite_new (dbname);
+	tracker_db_interface_set_procedure_table (db_con->db, prepared_queries);
 	g_free (dbname);
 
 	db_con->db_type = TRACKER_DB_TYPE_DATA;
 	db_con->db_category = DB_CATEGORY_FILES;
 
-	sqlite3_busy_timeout (db_con->db, 10000000);
-
 	db_con->data = db_con;
 
-	db_con->statements = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
 	tracker_db_set_default_pragmas (db_con);
 	
 	if (!tracker_config_get_low_memory_mode (tracker->config)) {
-		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 32");
+		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = %d", 32);
 	} else {
-		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 16");
+		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = %d", 16);
 	}
 
 	/* create user defined utf-8 collation sequence */
-	if (SQLITE_OK != sqlite3_create_collation (db_con->db, "UTF8", SQLITE_UTF8, 0, &sqlite3_utf8_collation)) {
-		tracker_error ("ERROR: collation sequence failed due to %s", sqlite3_errmsg (db_con->db));
+	if (! tracker_db_interface_sqlite_set_collation_function (TRACKER_DB_INTERFACE_SQLITE (db_con->db),
+								  "UTF8", utf8_collation_func)) {
+		tracker_error ("ERROR: collation sequence failed");
 	}
 
 	/* create user defined functions that can be used in sql */
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "FormatDate", 1, SQLITE_ANY, NULL, &sqlite3_date_to_str, NULL, NULL)) {
-		tracker_error ("ERROR: function FormatDate failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetServiceName", 1, SQLITE_ANY, NULL, &sqlite3_get_service_name, NULL, NULL)) {
-		tracker_error ("ERROR: function GetServiceName failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetServiceTypeID", 1, SQLITE_ANY, NULL, &sqlite3_get_service_type, NULL, NULL)) {
-		tracker_error ("ERROR: function GetServiceTypeID failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetMaxServiceTypeID", 1, SQLITE_ANY, NULL, &sqlite3_get_max_service_type, NULL, NULL)) {
-		tracker_error ("ERROR: function GetMaxServiceTypeID failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "REGEXP", 2, SQLITE_ANY, NULL, &sqlite3_regexp, NULL, NULL)) {
-		tracker_error ("ERROR: function REGEXP failed due to %s", sqlite3_errmsg (db_con->db));
-	}
+	tracker_db_interface_sqlite_create_function (db_con->db, "FormatDate", function_date_to_str, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "GetServiceName", function_get_service_name, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "GetServiceTypeID", function_get_service_type, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "GetMaxServiceTypeID", function_get_max_service_type, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "REGEXP", function_regexp, 2);
 
 	if (create_table) {
 		tracker_log ("Creating file database...");
@@ -1191,10 +989,7 @@
 		tracker_log ("creating file content table");
 	}
 
-	sqlite3_create_function (db_con->db, "uncompress", 1, SQLITE_ANY, NULL, &sqlite3_uncompress, NULL, NULL);
-
-	
-
+	tracker_db_interface_sqlite_create_function (db_con->db, "uncompress", function_uncompress, 1);
 }
 
 DBConnection *
@@ -1230,10 +1025,7 @@
 		tracker_log ("creating email content table");
 	}
 
-	sqlite3_create_function (db_con->db, "uncompress", 1, SQLITE_ANY, NULL, &sqlite3_uncompress, NULL, NULL);
-
-	
-
+	tracker_db_interface_sqlite_create_function (db_con->db, "uncompress", function_uncompress, 1);
 }
 
 DBConnection *
@@ -1262,8 +1054,7 @@
 	DBConnection *cache = db_con->cache;
 	DBConnection *emails = db_con->emails;
 
-	if (cache && cache->in_transaction) {
-		tracker_db_end_transaction (cache);
+	if (cache && tracker_db_interface_end_transaction (cache->db)) {
 		cache_trans = TRUE;
 	}
 
@@ -1283,7 +1074,7 @@
 	open_email_db (emails);
 		
 	if (cache_trans) {
-		tracker_db_start_transaction (cache);
+		tracker_db_interface_start_transaction (cache->db);
 	}
 
 
@@ -1295,8 +1086,7 @@
 	gboolean cache_trans = FALSE;
 	DBConnection *cache = db_con->cache;
 
-	if (cache && cache->in_transaction) {
-		tracker_db_end_transaction (cache);
+	if (cache && tracker_db_interface_end_transaction (cache->db)) {
 		cache_trans = TRUE;
 	}
 
@@ -1313,10 +1103,8 @@
 	open_email_db (emails);
 
 	if (cache_trans) {
-		tracker_db_start_transaction (cache);
+		tracker_db_interface_start_transaction (cache->db);
 	}
-
-	
 }
 
 DBConnection *
@@ -1340,27 +1128,19 @@
 	}
 
 	db_con = g_new0 (DBConnection, 1);
-
-	if (sqlite3_open (dbname, &db_con->db) != SQLITE_OK) {
-		tracker_error ("FATAL ERROR: can't open database at %s: %s", dbname, sqlite3_errmsg (db_con->db));
-		exit (1);
-	}
-
+	db_con->db = tracker_db_interface_sqlite_new (dbname);
+	tracker_db_interface_set_procedure_table (db_con->db, prepared_queries);
 	g_free (dbname);
 
 	db_con->db_type = TRACKER_DB_TYPE_CACHE;
 	db_con->cache = db_con;
 
-	sqlite3_busy_timeout (db_con->db, 10000000);
-
-	db_con->statements = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
 	tracker_db_set_default_pragmas (db_con);
 
 	if (!tracker_config_get_low_memory_mode (tracker->config)) {
-		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 128");
+		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = %d", 128);
 	} else {
-		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 32");
+		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = %d", 32);
 	}
 
 
@@ -1394,12 +1174,8 @@
 
 
 	db_con = g_new0 (DBConnection, 1);
-
-	if (sqlite3_open (dbname, &db_con->db) != SQLITE_OK) {
-		tracker_error ("FATAL ERROR: can't open database at %s: %s", dbname, sqlite3_errmsg (db_con->db));
-		exit (1);
-	}
-
+	db_con->db = tracker_db_interface_sqlite_new (dbname);
+	tracker_db_interface_set_procedure_table (db_con->db, prepared_queries);
 	g_free (dbname);
 
 
@@ -1408,43 +1184,24 @@
 
 	db_con->emails = db_con;
 
-	sqlite3_busy_timeout (db_con->db, 10000000);
-
-	db_con->statements = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-	tracker_db_exec_no_reply (db_con, "PRAGMA page_size = 4096");
+	tracker_db_exec_no_reply (db_con, "PRAGMA page_size = %d", 4096);
 
 	tracker_db_set_default_pragmas (db_con);
 
-	if (!tracker_config_get_low_memory_mode (tracker->config)) {
-		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 8");
-	} else {
-		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 8");
-	}
-
+	tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = %d", 8);
 
 	/* create user defined utf-8 collation sequence */
-	if (SQLITE_OK != sqlite3_create_collation (db_con->db, "UTF8", SQLITE_UTF8, 0, &sqlite3_utf8_collation)) {
-		tracker_error ("ERROR: collation sequence failed due to %s", sqlite3_errmsg (db_con->db));
+	if (! tracker_db_interface_sqlite_set_collation_function (TRACKER_DB_INTERFACE_SQLITE (db_con->db),
+								  "UTF8", utf8_collation_func)) {
+		tracker_error ("ERROR: collation sequence failed");
 	}
-	
 
 	/* create user defined functions that can be used in sql */
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "FormatDate", 1, SQLITE_ANY, NULL, &sqlite3_date_to_str, NULL, NULL)) {
-		tracker_error ("ERROR: function FormatDate failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetServiceName", 1, SQLITE_ANY, NULL, &sqlite3_get_service_name, NULL, NULL)) {
-		tracker_error ("ERROR: function GetServiceName failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetServiceTypeID", 1, SQLITE_ANY, NULL, &sqlite3_get_service_type, NULL, NULL)) {
-		tracker_error ("ERROR: function GetServiceTypeID failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "GetMaxServiceTypeID", 1, SQLITE_ANY, NULL, &sqlite3_get_max_service_type, NULL, NULL)) {
-		tracker_error ("ERROR: function GetMaxServiceTypeID failed due to %s", sqlite3_errmsg (db_con->db));
-	}
-	if (SQLITE_OK != sqlite3_create_function (db_con->db, "REGEXP", 2, SQLITE_ANY, NULL, &sqlite3_regexp, NULL, NULL)) {
-		tracker_error ("ERROR: function REGEXP failed due to %s", sqlite3_errmsg (db_con->db));
-	}
+	tracker_db_interface_sqlite_create_function (db_con->db, "FormatDate", function_date_to_str, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "GetServiceName", function_get_service_name, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "GetServiceTypeID", function_get_service_type, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "GetMaxServiceTypeID", function_get_max_service_type, 1);
+	tracker_db_interface_sqlite_create_function (db_con->db, "REGEXP", function_regexp, 2);
 
 	if (create_table) {
 		tracker_log ("Creating email database...");
@@ -1604,619 +1361,83 @@
 
 
 gboolean
-tracker_db_exec_no_reply (DBConnection *db_con, const char *query)
+tracker_db_exec_no_reply (DBConnection *db_con, const char *query, ...)
 {
-	char *msg = NULL;	
-	int rc,  busy_count = 0;
+	TrackerDBResultSet *result_set;
+	va_list args;
 
 	lock_db();
 
-	while ((rc = sqlite3_exec (db_con->db, query, NULL, NULL, &msg)) == SQLITE_BUSY) {
-
-		unlock_db ();
-		busy_count++;
+	va_start (args, query);
+	result_set = tracker_db_interface_execute_vquery (db_con->db, NULL, query, args);
+	va_end (args);
 
-		if (msg) {
-			sqlite3_free (msg);
-			msg = NULL;
-		}
+	/* This function is meant for queries that don't return any result set,
+	 * if it's passed some query that returns a result set, just discard it.
+	 */
+	if (G_UNLIKELY (result_set)) {
+		g_object_unref (result_set);
+	}
 
-		if (busy_count > 1000000) {
-			tracker_error ("WARNING: excessive busy count in query %s and thread %s", "save file contents", db_con->thread);
-			busy_count = 0;
-		}
-			
+	unlock_db ();
 
-		if (busy_count > 50) {
-			g_usleep (g_random_int_range (1000, busy_count * 200));
-		} else {
-			g_usleep (100);
-		}
+	return TRUE;
+}
 
-		lock_db();
-		
-	}
-	unlock_db ();
+void
+tracker_db_release_memory (void)
+{
 
-	if (rc != SQLITE_OK) {
+}
 
-		if (msg) {
-			tracker_error ("WARNING: sql query %s failed because %s", query, msg);	
-			sqlite3_free (msg);
-		} else {
-			tracker_error ("WARNING: sql query %s failed with code %d", query, rc);	
-		}
+char *
+tracker_escape_string (const char *in)
+{
+	gchar **array, *out;
 
-		return FALSE;
+	if (strchr (in, '\'')) {
+		return g_strdup (in);
 	}
 
-	return TRUE;
+	/* double single quotes */
+	array = g_strsplit (in, "'", -1);
+	out = g_strjoinv ("''", array);
+	g_strfreev (array);
 
+	return out;
 }
 
-
-
-static char ***
-exec_sql (DBConnection *db_con, const char *query, gboolean ignore_nulls)
+TrackerDBResultSet *
+tracker_exec_proc (DBConnection *db_con, const char *procedure, ...)
 {
-	char **array, **result;
-	int  cols, rows;
-	char *msg = NULL;
-	int  i, busy_count, totalrows, k;
-
-	g_return_val_if_fail (query, NULL);
+	TrackerDBResultSet *result_set;
+	va_list args;
 
-	array = NULL;
-	msg = NULL;
+	va_start (args, procedure);
+	result_set = tracker_db_interface_execute_vprocedure (db_con->db, NULL, procedure, args);
+	va_end (args);
 
-	if (!lock_db ()) {
-		return NULL;
-	}
+	return result_set;
+}
 
-	busy_count = 0;
 
-	i = SQLITE_BUSY;
+gboolean
+tracker_exec_proc_no_reply (DBConnection *db_con, const char *procedure, ...)
+{
+	TrackerDBResultSet *result_set;
+	va_list args;
 
-	while (i == SQLITE_BUSY) {
+	va_start (args, procedure);
+	result_set = tracker_db_interface_execute_vprocedure (db_con->db, NULL, procedure, args);
+	va_end (args);
 
-		lock_connection (db_con);
-	
-		i = sqlite3_get_table (db_con->db, query, &array, &rows, &cols, &msg);
-
-		unlock_connection (db_con);
-
-		if (i == SQLITE_BUSY) {
-		
-			if (array) {
-				sqlite3_free_table (array);
-				array = NULL;
-			}
-
-			if (msg) {
-				sqlite3_free (msg);
-				msg = NULL;
-			}
-		
-
-			busy_count++;
-
-			if (busy_count > 10000) {
-				tracker_error ("ERROR: excessive busy count in query %s and thread %s", query, db_con->thread);
-				busy_count = 0;
-			}
-
-			if (busy_count > 50) {
-				g_usleep (g_random_int_range (1000, busy_count * 200));
-			} else {
-				g_usleep (100);
-			}
-	
-		}
-	}
-
-	if (i != SQLITE_OK) {
-		unlock_db ();
-		tracker_error ("ERROR: query %s failed with error: %s", query, msg);
-		sqlite3_free (msg);
-		return NULL;
-	}
-
-	unlock_db ();
-
-	if (msg) {
-		sqlite3_free (msg);
-	}
-
-	if (!array || rows == 0 || cols == 0) {
-
-		if (array) sqlite3_free_table (array);
-		return NULL;
-	}
-
-
-	result = g_new (char *, rows+1);
-	result[rows] = NULL;
-
-	totalrows = (rows+1) * cols;
-
-	//tracker_log ("total rows is %d", totalrows);
-	//for (i=0;i<totalrows;i++) tracker_log (array[i]);
-
-	for (i = cols, k = 0; i < totalrows; i += cols, k++) {
-		char **row;
-		int  j;
-
-		row = g_new (char *, cols + 1);
-		row[cols] = NULL;
-
-		for (j = 0; j < cols; j++) {
-			if (ignore_nulls && !array[i+j]) {
-				row[j] = g_strdup ("");
-			} else {
-				row[j] = g_strdup (array[i+j]);
-			}
-			//tracker_log ("data for row %d, col %d is %s", k, j, row[j]);
-		}
-
-		result[k] = (gpointer) row;
-	}
-
-	sqlite3_free_table (array);
-
-	return (char ***) result;
-}
-
-void
-tracker_db_release_memory (void)
-{
-
-}
-
-
-char ***
-tracker_exec_sql (DBConnection *db_con, const char *query)
-{
-	return exec_sql (db_con, query, FALSE);
-}
-
-
-char ***
-tracker_exec_sql_ignore_nulls (DBConnection *db_con, const char *query)
-{
-	return exec_sql (db_con, query, TRUE);
-}
-
-
-char *
-tracker_escape_string (const char *in)
-{
-
-
-	char *str = sqlite3_mprintf ("%q", in);
-
-	/* copy this as sqlite3_free needs to be called to prevent invalid delete error */
-	char *str2 = g_strdup (str);
-
-	sqlite3_free (str);
-
-	return str2;
-
-
-}
-
-
-
-static sqlite3_stmt *
-get_prepared_query (DBConnection *db_con, const char *procedure)
-{
-	sqlite3_stmt *stmt;
-
-	/* check if query is already prepared (i.e. is in table) */
-	stmt = g_hash_table_lookup (db_con->statements, procedure);
-
-	/* check if query is in list and prepare it if so */
-	if (!stmt || sqlite3_expired (stmt) != 0) {
-		char *query;
-
-		query = g_hash_table_lookup (prepared_queries, procedure);
-
-		if (!query) {
-			tracker_error ("ERROR: prepared query %s not found", procedure);
-			return NULL;
-		} else {
-			int rc;
-
-			/* prepare the query */
-			rc = sqlite3_prepare_v2 (db_con->db, query, -1, &stmt, NULL);
-
-			if (rc == SQLITE_OK && stmt) {
-				//tracker_log ("successfully prepared query %s", procedure);
-				g_hash_table_insert (db_con->statements, g_strdup (procedure), stmt);
-			} else {
-
-				rc = sqlite3_step (stmt);
-	
-				if (rc == SQLITE_OK && stmt) {
-					//tracker_log ("successfully prepared query %s", procedure);
-	
-					g_hash_table_insert (db_con->statements, g_strdup (procedure), stmt);
-				} else {
-					tracker_error ("ERROR: failed to prepare query %s with sql %s due to code %d and %s", procedure, query, sqlite3_errcode(db_con->db), sqlite3_errmsg (db_con->db));
-					return NULL;
-				}
-			}
-		}
-
-	} else {
-		sqlite3_reset (stmt);
-	}
-
-	return stmt;
-}
-
-
-char ***
-tracker_exec_proc (DBConnection *db_con, const char *procedure, int param_count, ...)
-{
-	GPtrArray    *res;
-	va_list      args;
-	int 	     i, busy_count, cols;
-	sqlite3_stmt *stmt;
-	int	     rc;
-
-	stmt = get_prepared_query (db_con, procedure);
-
-	va_start (args, param_count);
-
-	if (param_count != sqlite3_bind_parameter_count (stmt)) {
-		tracker_error ("ERROR: incorrect no of parameters %d supplied to %s", param_count, procedure);
-	}
-
-	for (i = 0; i < param_count; i++) {
-		char *str;
-
-		str = va_arg (args, char *);
-
-		if (!str) {
-			tracker_debug ("WARNING: parameter %d is null when executing SP %s", i, procedure);
-			if  (sqlite3_bind_null (stmt, i+1)) {
-				tracker_error ("ERROR: null parameter %d could not be bound to %s", i, procedure);
-			}
-		} else {
-
-			if (sqlite3_bind_text (stmt, i+1, str, strlen (str), SQLITE_TRANSIENT) != SQLITE_OK) {
-				tracker_error ("ERROR: parameter %d could not be bound to %s", i, procedure);
-			}
-		}
-	}
-
-	va_end (args);
-
-	cols = sqlite3_column_count (stmt);
-	res = g_ptr_array_sized_new (100);
-
-	busy_count = 0;
-
-	lock_connection (db_con);
-	while (TRUE) {
-
-		if (!lock_db ()) {
-			unlock_connection (db_con);	
-			return NULL;
-		}
-		
-		db_con->in_error = FALSE;
-		
-		rc = sqlite3_step (stmt);
-
-		if (rc == SQLITE_ERROR) {
-			sqlite3_reset (stmt);
-			unlock_db ();
-			db_con->in_error = TRUE;
-			break;
-		} else if (rc == SQLITE_BUSY) {
-			unlock_db ();
-			unlock_connection (db_con);
-			busy_count++;
-
-			if (busy_count > 100000) {
-				tracker_error ("ERROR: excessive busy count in query %s and thread %s", procedure, db_con->thread);
-				busy_count = 0;
-			}
-
-			if (busy_count > 50) {
-				g_usleep (g_random_int_range (1000, busy_count * 200));
-			} else {
-				g_usleep (100);
-			}
-
-			lock_connection (db_con);
-		} else if (rc == SQLITE_ROW) {
-			char **new_row;
-
-			new_row = g_new0 (char *, cols+1);
-
-			unlock_db ();
-			
-
-			for (i = 0; i < cols; i++) {
-				const char *st;
-
-				st = (char *) sqlite3_column_text (stmt, i);
-
-				if (st) {
-					new_row[i] = g_strdup (st);
-					//tracker_log ("%s : row %d, col %d is %s", procedure, row, i, st);
-				} else {
-					tracker_info ("WARNING: null detected in query return result for %s", procedure);
-				}
-			}
-
-			if (new_row[0]) {
-				g_ptr_array_add (res, new_row);
-			} else {
-				g_strfreev (new_row);
-			}
-		} else {
-			unlock_db ();
-			break;
-		}
-	}
-
-	unlock_connection (db_con);
-
-	if (rc != SQLITE_DONE) {
-		tracker_error ("ERROR: execution of prepared query %s failed due to %s with return code %d", procedure, sqlite3_errmsg (db_con->db), rc);
-		db_con->in_error = TRUE;
-
-		if (rc == SQLITE_CORRUPT) {
-			tracker->reindex = TRUE;
-
-			g_timeout_add_full (G_PRIORITY_LOW,
-			     		    1,
-		 	    		    (GSourceFunc) tracker_do_cleanup,
-			     		    NULL, NULL
-			   		    );
-			return NULL;
-		}
-
-	}
-
-	if (res->len == 0) {
-		g_ptr_array_free (res, TRUE);
-		return NULL;
-	}
-
-	g_ptr_array_add (res, NULL);
-
-	return (char ***) g_ptr_array_free (res, FALSE);
-}
-
-
-gboolean
-tracker_exec_proc_no_reply (DBConnection *db_con, const char *procedure, int param_count, ...)
-{
-	va_list      args;
-	int 	     i, busy_count, cols, row;
-	sqlite3_stmt *stmt;
-	GSList	     *result;
-	int	     rc;
-
-	stmt = get_prepared_query (db_con, procedure);
-
-	va_start (args, param_count);
-
-	if (param_count != sqlite3_bind_parameter_count (stmt)) {
-		tracker_error ("ERROR: incorrect no of parameters %d supplied to %s", param_count, procedure);
-	}
-
-	for (i = 0; i < param_count; i++) {
-		char *str;
-
-		str = va_arg (args, char *);
-
-		if (!str) {
-			tracker_debug ("WARNING: parameter %d is null when executing SP %s", i, procedure);
-			if  (sqlite3_bind_null (stmt, i+1)) {
-				tracker_error ("ERROR: null parameter %d could not be bound to %s", i, procedure);
-			}
-		} else {
-
-			if (sqlite3_bind_text (stmt, i+1, str, strlen (str), SQLITE_TRANSIENT) != SQLITE_OK) {
-				tracker_error ("ERROR: parameter %d could not be bound to %s", i, procedure);
-			}
-		}
-	}
-
-	va_end (args);
-
-	cols = sqlite3_column_count (stmt);
-
-	busy_count = 0;
-	row = 0;
-
-	result = NULL;
-	
-	lock_connection (db_con);
-	while (TRUE) {
-
-		if (!lock_db ()) {
-			unlock_connection (db_con);	
-			return FALSE;
-		}
-		
-		db_con->in_error = FALSE;
-		
-		rc = sqlite3_step (stmt);
-
-		if (rc == SQLITE_ERROR) {
-			sqlite3_reset (stmt);
-			unlock_db ();
-			db_con->in_error = TRUE;
-			break;
-		}
-		
-
-		if (rc == SQLITE_BUSY) {
-			unlock_db ();
-			unlock_connection (db_con);
-			busy_count++;
-
-			if (busy_count > 100000) {
-				tracker_error ("ERROR: excessive busy count in query %s and thread %s", procedure, db_con->thread);
-				busy_count = 0;
-			}
-
-			if (busy_count > 50) {
-				g_usleep (g_random_int_range (1000, busy_count * 200));
-			} else {
-				g_usleep (100);
-			}
-
-			lock_connection (db_con);
-			continue;
-		}
-
-		
-
-		unlock_db ();
-		break;
-	}
-
-	unlock_connection (db_con);
-
-	if (rc != SQLITE_DONE) {
-		tracker_error ("ERROR: execution of prepared query %s failed due to %s with return code %d", procedure, sqlite3_errmsg (db_con->db), rc);
-		db_con->in_error = TRUE;
-		return FALSE;
-
-	}
+	if (result_set) {
+		g_object_unref (result_set);
+	}
 
 	return TRUE;
 }
 
-
-char ***
-tracker_exec_proc_ignore_nulls (DBConnection *db_con, const char *procedure, int param_count, ...)
-{
-	va_list      args;
-	GPtrArray    *res;
-	int 	     i, busy_count, cols;
-	sqlite3_stmt *stmt;
-	int	     rc;
-
-	stmt = get_prepared_query (db_con, procedure);
-
-	va_start (args, param_count);
-
-	if (param_count != sqlite3_bind_parameter_count (stmt)) {
-		tracker_error ("ERROR: incorrect no. of paramters %d supplied to %s", param_count, procedure);
-	}
-
-	for (i = 0; i < param_count; i++) {
-		char *str;
-
-		str = va_arg (args, char *);
-
-		if (!str) {
-			tracker_debug ("WARNING: parameter %d is null when executing SP %s", i, procedure);
-			if  (sqlite3_bind_null (stmt, i+1)) {
-				tracker_error ("ERROR: null parameter %d could not be bound to %s", i, procedure);
-			}
-		} else {
-
-			if (sqlite3_bind_text (stmt, i+1, str, strlen (str), SQLITE_TRANSIENT) != SQLITE_OK) {
-				tracker_error ("ERROR: parameter %d could not be bound to %s", i, procedure);
-			}
-		}
-	}
-
-	va_end (args);
-
-	res = g_ptr_array_sized_new (100);
-	cols = sqlite3_column_count (stmt);
-
-	busy_count = 0;
-
-	lock_connection (db_con);
-	while (TRUE) {
-
-		if (!lock_db ()) {
-			unlock_connection (db_con);	
-			return NULL;
-		}
-
-		
-		rc = sqlite3_step (stmt);
-		
-
-		if (rc == SQLITE_BUSY) {
-			unlock_db ();
-			unlock_connection (db_con);
-			busy_count++;
-
-			if (busy_count > 1000000) {
-				tracker_error ("ERROR: excessive busy count in query %s and thread %s", procedure, db_con->thread);
-				busy_count = 0;
-			}
-
-			if (busy_count > 50) {
-				g_usleep (g_random_int_range (1000, busy_count * 200));
-			} else {
-				g_usleep (100);
-			}
-
-			lock_connection (db_con);
-		} else if (rc == SQLITE_ROW) {
-			char **new_row;
-
-			new_row = g_new0 (char *, cols+1);
-
-			unlock_db ();
-			
-
-			for (i = 0; i < cols; i++) {
-				const char *st;
-
-				st = (char *) sqlite3_column_text (stmt, i);
-
-				if (st) {
-					new_row[i] = g_strdup (st);
-				} else {
-					new_row[i] = g_strdup (" ");
-				}
-			}
-
-			if (new_row[0]) {
-				g_ptr_array_add (res, new_row);
-			} else {
-				g_strfreev (new_row);
-			}
-		} else {
-			unlock_db ();
-			break;
-		}
-	}
-
-	unlock_connection (db_con);
-
-	if (rc != SQLITE_DONE) {
-		tracker_error ("ERROR: prepared query %s failed due to %s", procedure, sqlite3_errmsg (db_con->db));
-	}
-
-	if (res->len == 0) {
-		g_ptr_array_free (res, TRUE);
-		return NULL;
-	}
-
-	g_ptr_array_add (res, NULL);
-
-	return (char ***) g_ptr_array_free (res, FALSE);
-}
-
-
-
-
 void
 tracker_db_load_stored_procs (DBConnection *db_con)
 {
@@ -2264,28 +1485,6 @@
 	
 }
 
-
-
-
-
-void
-tracker_log_sql (DBConnection *db_con, const char *query)
-{
-	char ***res;
-
-	res = tracker_exec_sql (db_con, query);
-
-	if (!res) {
-		return;
-	}
-
-	tracker_db_log_result (res);
-
-	tracker_db_free_result (res);
-}
-
-
-
 static gboolean
 db_exists (const char *name)
 {
@@ -2334,29 +1533,22 @@
 gboolean
 tracker_update_db (DBConnection *db_con)
 {
-	char ***res;
-	char **row;
+	TrackerDBResultSet *result_set;
 	char *version;
 	int i;
 
-	res = tracker_exec_sql (db_con, "SELECT OptionValue FROM Options WHERE OptionKey = 'DBVersion'");
-
-	if (!res) {
-		return FALSE;
-	}
-
-	row = tracker_db_get_row (res, 0);
+	result_set = tracker_db_interface_execute_query
+		(db_con->db, NULL, "SELECT OptionValue FROM Options WHERE OptionKey = 'DBVersion'");
 
-	if (!row || !row[0]) {
-		tracker_db_free_result (res);
+	if (!result_set) {
 		return FALSE;
 	}
 
-
-	version = row[0];
+	tracker_db_result_set_get (result_set, 0, &version, -1);
 	i = atoi (version);
 
-	tracker_db_free_result (res);
+	g_object_unref (result_set);
+	g_free (version);
 
 	tracker_log ("Checking tracker DB version...Current version is %d and needed version is %d", i, TRACKER_DB_VERSION_REQUIRED);
 
@@ -2381,9 +1573,9 @@
 		load_sql_file (db_con, "sqlite-service-types.sql");
 		load_sql_file (db_con, "sqlite-metadata.sql");
 
-		tracker_exec_sql (db_con, "update Options set OptionValue = '16' where OptionKey = 'DBVersion'");
-
-		tracker_exec_sql (db_con, "ANALYZE");
+		tracker_db_interface_execute_query (db_con->db, NULL,
+						    "update Options set OptionValue = '16' where OptionKey = 'DBVersion'");
+		tracker_db_interface_execute_query (db_con->db, NULL, "ANALYZE");
 	}
 
 	/* apply and table changes for each version update */
@@ -2469,77 +1661,32 @@
 GHashTable *
 tracker_db_get_file_contents_words (DBConnection *db_con, guint32 id, GHashTable *old_table)
 {
-	sqlite3_stmt 	*stmt;
-	char		*str_file_id;
-	int 		busy_count;
-	int		rc;
+	TrackerDBResultSet *result_set;
+	char *str_file_id;
+	gboolean valid = TRUE;
 
 	str_file_id = tracker_uint_to_str (id);
 
-	stmt = get_prepared_query (db_con, "GetAllContents");
-
-	sqlite3_bind_text (stmt, 1, str_file_id, strlen (str_file_id), SQLITE_STATIC);
-
-	busy_count = 0;
-
 	lock_connection (db_con);
-	while (TRUE) {
-
-		if (!lock_db ()) {
-			unlock_connection (db_con);
-			g_free (str_file_id);
-			return NULL;
-		}
-
-		
-		rc = sqlite3_step (stmt);
-		
-
-		if (rc == SQLITE_BUSY) {
-			unlock_db ();
-			unlock_connection (db_con);
-			busy_count++;
-
-			if (busy_count > 1000000) {
-				tracker_error ("ERROR: excessive busy count in query %s and thread %s", "save file contents", db_con->thread);
-				busy_count = 0;
-			}
-
-			if (busy_count > 50) {
-				g_usleep (g_random_int_range (1000, (busy_count * 200) ));
-			} else {
-				g_usleep (100);
-			}
-			lock_connection (db_con);
-			continue;
-		}
-
-
-		if (rc == SQLITE_ROW) {
-			const char *st;
-
-			st = (char *) sqlite3_column_text (stmt, 0);
-
-			unlock_db ();
+	result_set = tracker_db_interface_execute_procedure (db_con->db, NULL, "GetAllContents", str_file_id, NULL);
+	unlock_connection (db_con);
 
-			if (st) {
+	g_free (str_file_id);
 
-				old_table = tracker_parse_text (old_table, st, 1, TRUE, FALSE);
-			}
+	if (!result_set)
+		return NULL;
 
-			continue;
-		}
+	while (valid) {
+		gchar *st;
 
-		unlock_db ();
-		break;
-	}
-	unlock_connection (db_con);
+		tracker_db_result_set_get (result_set, 0, &st, -1);
+		old_table = tracker_parse_text (old_table, st, 1, TRUE, FALSE);
 
-	if (rc != SQLITE_DONE) {
-		tracker_error ("WARNING: retrieval of text contents has failed");
+		valid = tracker_db_result_set_iter_next (result_set);
+		g_free (st);
 	}
 
-	g_free (str_file_id);
+	g_object_unref (result_set);
 
 	return old_table;
 }
@@ -2548,50 +1695,63 @@
 GHashTable *
 tracker_db_get_indexable_content_words (DBConnection *db_con, guint32 id, GHashTable *table, gboolean embedded_only)
 {
-	char ***res;
+	TrackerDBResultSet *result_set;
 	char *str_id;
 
 	str_id = tracker_uint_to_str (id);
 
 	if (embedded_only) {
-		res = tracker_exec_proc (db_con, "GetAllIndexable", 2, str_id, "1");
+		result_set = tracker_exec_proc (db_con, "GetAllIndexable", str_id, "1", NULL);
 	} else {
-		res = tracker_exec_proc (db_con, "GetAllIndexable", 2, str_id, "0");
+		result_set = tracker_exec_proc (db_con, "GetAllIndexable", str_id, "0", NULL);
 	}
 
-	if (res) {
-		int  k;
-		char **row;
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *value;
+		gint weight;
+
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   0, &value,
+						   1, &weight,
+						   -1);
 
-		for (k = 0; (row = tracker_db_get_row (res, k)); k++) {
+			table = tracker_parse_text_fast (table, value, weight);
 
-			if (row[0] && row[1]) {
-				table = tracker_parse_text_fast (table, row[0], atoi (row[1]));
-			}
+			g_free (value);
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	if (embedded_only) {
-		res = tracker_exec_proc (db_con, "GetAllIndexableKeywords", 2, str_id, "1");
+		result_set = tracker_exec_proc (db_con, "GetAllIndexableKeywords", str_id, "1", NULL);
 	} else {
-		res = tracker_exec_proc (db_con, "GetAllIndexableKeywords", 2, str_id, "0");
+		result_set = tracker_exec_proc (db_con, "GetAllIndexableKeywords", str_id, "0", NULL);
 	}
 
+	if (result_set) {
+		gboolean valid = TRUE;
+		gboolean filtered, delimited;
+		gchar *value;
+		gint weight;
+
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   0, &value,
+						   1, &weight,
+						   2, &filtered,
+						   3, &delimited
+						   -1);
 
-	if (res) {
-		int  k;
-		char **row;
-
-		for (k = 0; (row = tracker_db_get_row (res, k)); k++) {
-
-			if (row[0] && row[1] && row[2] && row[3]) {
-				table = tracker_parse_text (table, row[0], atoi (row[1]), !strcmp (row[2], "1"), !strcmp (row[3], "1"));
-			}
+			table = tracker_parse_text (table, value, weight, filtered, delimited);
+			valid = tracker_db_result_set_iter_next (result_set);
+			g_free (value);
 		}
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	g_free (str_id);
@@ -2602,90 +1762,37 @@
 static void
 save_full_text_bytes (DBConnection *blob_db_con, const char *str_file_id, GByteArray *byte_array)
 {
-	sqlite3_stmt 	*stmt;
-	int		busy_count;
-	int		rc;
-
-	stmt = get_prepared_query (blob_db_con, "SaveServiceContents");
+	FieldDef *def;
 
-	FieldDef *def = tracker_db_get_field_def (blob_db_con, "File:Contents");
+	def = tracker_db_get_field_def (blob_db_con, "File:Contents");
 
 	if (!def) {
 		tracker_error ("WARNING: metadata not found for type %s", "File:Contents");
 		return;
 	}
 
-	sqlite3_bind_text (stmt, 1, str_file_id, strlen (str_file_id), SQLITE_STATIC);
-	sqlite3_bind_text (stmt, 2, def->id, strlen (def->id), SQLITE_STATIC);
-	sqlite3_bind_blob (stmt, 3, (void *) byte_array->data, byte_array->len, SQLITE_STATIC);
-	sqlite3_bind_int  (stmt, 4, 0);
-
-	busy_count = 0;
-	lock_connection (blob_db_con);
-
-	while (TRUE) {
-
-		if (!lock_db ()) {
-
-			unlock_connection (blob_db_con);
-
-			return;
-		}
-
-		
-		rc = sqlite3_step (stmt);
-		
-
-		if (rc == SQLITE_BUSY) {
-			unlock_db ();
-			unlock_connection (blob_db_con);
-			busy_count++;
-
-			if (busy_count > 1000000) {
-				tracker_log ("WARNING: excessive busy count in query %s and thread %s", "save file contents", blob_db_con->thread);
-				busy_count = 0;
-			}
-			
-
-			if (busy_count > 50) {
-				g_usleep (g_random_int_range (1000, busy_count * 200));
-			} else {
-				g_usleep (100);
-			}
-			lock_connection (blob_db_con);
-			continue;
-		}
-
-		unlock_db ();
-		break;
-	}
-
-	unlock_connection (blob_db_con);
-	
-	if (rc != SQLITE_DONE) {
-		tracker_error ("WARNING: failed to update contents ");
-	}
+	tracker_db_interface_execute_procedure_len (blob_db_con->db,
+						    NULL,
+						    "SaveServiceContents",
+						    str_file_id, -1,
+						    def->id, -1,
+						    byte_array->data, byte_array->len,
+						    NULL);
 }
 
 
 static void
 save_full_text (DBConnection *blob_db_con, const char *str_file_id, const char *text, int length)
 {
-	char		*value;
-	sqlite3_stmt 	*stmt;
-	char		*compressed;
-	int		bytes_compressed;
-	int		busy_count;
-	int		rc;
-
-	stmt = get_prepared_query (blob_db_con, "SaveServiceContents");
+	gchar *compressed, *value = NULL;
+	gint bytes_compressed;
+	FieldDef *def;
 
 	compressed = tracker_compress (text, length, &bytes_compressed);
 
 	if (compressed) {
 		tracker_debug ("compressed full text size of %d to %d", length, bytes_compressed);
 		value = compressed;
-		
 	} else {
 		tracker_error ("WARNING: compression has failed");
 		value = g_strdup (text);
@@ -2693,7 +1800,7 @@
 	}
 
 
-	FieldDef *def = tracker_db_get_field_def (blob_db_con, "File:Contents");
+	def = tracker_db_get_field_def (blob_db_con, "File:Contents");
 
 	if (!def) {
 		tracker_error ("WARNING: metadata not found for type %s", "File:Contents");
@@ -2701,65 +1808,14 @@
 		return;
 	}
 
-	sqlite3_bind_text (stmt, 1, str_file_id, strlen (str_file_id), SQLITE_STATIC);
-	sqlite3_bind_text (stmt, 2, def->id, strlen (def->id), SQLITE_STATIC);
-	sqlite3_bind_text (stmt, 3, value, bytes_compressed, SQLITE_STATIC);
-	sqlite3_bind_int (stmt, 4, 0);
-
-	busy_count = 0;
-	lock_connection (blob_db_con);
-
-	while (TRUE) {
-
-		if (!lock_db ()) {
-			
-
-			if (value) {
-				g_free (value);
-			}
-
-			unlock_connection (blob_db_con);
-
-			return;
-		}
-
-		
-		rc = sqlite3_step (stmt);
-		
-
-		if (rc == SQLITE_BUSY) {
-			unlock_db ();
-			unlock_connection (blob_db_con);
-			busy_count++;
-
-			if (busy_count > 1000000) {
-				tracker_log ("WARNING: excessive busy count in query %s and thread %s", "save file contents", blob_db_con->thread);
-				busy_count = 0;
-			}
-			
-
-			if (busy_count > 50) {
-				g_usleep (g_random_int_range (1000, busy_count * 200));
-			} else {
-				g_usleep (100);
-			}
-			lock_connection (blob_db_con);
-			continue;
-		}
-
-		unlock_db ();
-		break;
-	}
-
-	unlock_connection (blob_db_con);
-
-	if (value) {
-		g_free (value);
-	}
-
-	if (rc != SQLITE_DONE) {
-		tracker_error ("WARNING: failed to update contents ");
-	}
+	tracker_db_interface_execute_procedure_len (blob_db_con->db,
+						    NULL,
+						    "SaveServiceContents",
+						    str_file_id, -1,
+						    def->id, -1,
+						    value, bytes_compressed,
+						    NULL);
+	g_free (value);
 }
 
 
@@ -2947,93 +2003,55 @@
 void
 tracker_db_clear_temp (DBConnection *db_con)
 {
-	tracker_db_start_transaction (db_con->cache);
+	tracker_db_interface_start_transaction (db_con->cache->db);
 	tracker_db_exec_no_reply (db_con->cache, "DELETE FROM FilePending");
 	tracker_db_exec_no_reply (db_con->cache, "DELETE FROM FileWatches");
-	tracker_db_end_transaction (db_con->cache);
+	tracker_db_interface_end_transaction (db_con->cache->db);
 }
 
-
-
-gboolean
-tracker_db_start_transaction (DBConnection *db_con)
-{
-	//if (db_con->in_transaction) {
-	//	tracker_error ("Error - cannot start transaction - database is already in a transaction");
-	//}
-
-	if (!tracker_db_exec_no_reply (db_con, "BEGIN TRANSACTION")) {
-		tracker_error ("could not start transaction");
-		return FALSE;
-	}
-
-	db_con->in_transaction = TRUE;
-	return TRUE;
-}
-
-
-gboolean
-tracker_db_end_transaction (DBConnection *db_con)
-{
-
-	if (!db_con->in_transaction) {
-		tracker_error ("Error - cannot end transaction. Rolling back...");
-		return FALSE;
-	}
-
-	db_con->in_transaction = FALSE;
-
-	if (!tracker_db_exec_no_reply (db_con, "COMMIT")) {
-		tracker_error ("could not commit transaction");
-		tracker_db_exec_no_reply (db_con, "ROLLBACK");		
-		return FALSE;
-	}	
-	
-	return TRUE;
-}
-
-
 void
 tracker_db_check_tables (DBConnection *db_con)
 {
 }
 
-char ***
+
+TrackerDBResultSet *
 tracker_db_search_text (DBConnection *db_con, const char *service, const char *search_string, int offset, int limit, gboolean save_results, gboolean detailed)
 {
 	TrackerQueryTree *tree;
-	char 		***result, **array;
+	TrackerDBResultSet *result_set, *result;
+	char 		**array;
 	GArray          *hits;
 	int 		count;
 	gboolean	detailed_emails = FALSE, detailed_apps = FALSE;
 	int		service_array[255];
 	const gchar     *procedure;
 	GArray          *services = NULL;
-	guint           i, j;
 	GSList          *duds = NULL;
+	guint           i = 0;
 
 	array = tracker_parse_text_into_array (search_string);
 
-	char ***res = tracker_exec_proc (db_con->common, "GetRelatedServiceIDs", 2, service, service);
-	i = j = 0;
-	char **row;
-	
-	if (res) {	
-		while ((row = tracker_db_get_row (res, i))) {
-
-			if (row[0]) {
-				service_array[j] = atoi (row[0]);
-				j++;
-			}
+	result_set = tracker_exec_proc (db_con->common, "GetRelatedServiceIDs", service, service, NULL);
 
+	if (result_set) {
+		gboolean valid = TRUE;
+		gint type_id;
+
+		while (valid) {
+			g_print ("aaaandaya %d\n", i);
+			tracker_db_result_set_get (result_set, 0, &type_id, -1);
+			service_array[i] = type_id;
 			i++;
+
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
 
-		service_array[j] = 0;
+		service_array[i] = 0;
 		services = g_array_new (TRUE, TRUE, sizeof (gint));
-		g_array_append_vals (services, service_array, j);
+		g_array_append_vals (services, service_array, i);
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	tree = tracker_query_tree_new (search_string, db_con->word_index, services);
@@ -3044,11 +2062,9 @@
 		count = hits->len;
 
 		if (count > limit) count = limit;
-
-		result = g_new (char **, count + 1);
 	} else {
-		tracker_db_start_transaction (db_con);
-		tracker_exec_proc (db_con, "DeleteSearchResults1", 0);
+		tracker_db_interface_start_transaction (db_con->db);
+		tracker_exec_proc (db_con, "DeleteSearchResults1", NULL);
 	}
 
 	count = 0;
@@ -3056,7 +2072,6 @@
 	for (i = 0; i < hits->len; i++) {
 		TrackerSearchHit hit;
 		char	  *str_id;
-		char	  ***res;
 
 		if (count >= limit) break;
 
@@ -3070,7 +2085,7 @@
 
 			str_score = tracker_int_to_str (hit.score);
 
-			tracker_exec_proc (db_con, "InsertSearchResult1", 2, str_id, str_score);
+			tracker_exec_proc (db_con, "InsertSearchResult1", str_id, str_score, NULL);
 
 			g_free (str_id);
 			g_free (str_score);
@@ -3092,30 +2107,40 @@
 			procedure = "GetFileByID";
 		}
 
-		res = tracker_exec_proc_ignore_nulls (db_con, procedure, 1, str_id);
+		result_set = tracker_exec_proc (db_con, procedure, str_id, NULL);
 		g_free (str_id);
 
-		if (res) {
-			if (res[0] && res[0][0] && res[0][1]) {
+		if (result_set) {
+			gchar *path;
 
-				char **row = NULL;
+			tracker_db_result_set_get (result_set, 0, &path, -1);
 
-				if (detailed) {
-					if (detailed_emails || detailed_apps)
-						row = res[0];
-					else {
-						if (res[0][2] && g_file_test (res[0][0], G_FILE_TEST_EXISTS))
-							row = res[0];
-					}
-				} else {
-					row = res[0];
+			if (!detailed || detailed_emails || detailed_apps ||
+			    (detailed && g_file_test (path, G_FILE_TEST_EXISTS))) {
+				guint columns, i;
+
+				columns = tracker_db_result_set_get_n_columns (result_set);
+
+				if (G_UNLIKELY (!result)) {
+					guint columns;
+
+					columns = tracker_db_result_set_get_n_columns (result_set);
+					result = _tracker_db_result_set_new (columns);
+				}
+
+				_tracker_db_result_set_append (result);
+
+				for (i = 0; i < columns; i++) {
+					GValue value = { 0, };
+
+					_tracker_db_result_set_get_value (result_set, i, &value);
+					_tracker_db_result_set_set_value (result, i, &value);
+					g_value_unset (&value);
 				}
-				
-				result[count] = row;
-				count++;
 			}
 
-			g_free (res);
+			g_free (path);
+			g_object_unref (result_set);
 		} else {
 			tracker_log ("dud hit for search detected");
 			/* add to dud list */
@@ -3125,9 +2150,7 @@
 	}
 
 	if (save_results) {
-		tracker_db_end_transaction (db_con);
-	} else {
-		result[count] = NULL;
+		tracker_db_interface_end_transaction (db_con->db);
 	}
 
 	/* delete duds */
@@ -3149,26 +2172,31 @@
 	g_array_free (hits, TRUE);
 	g_array_free (services, TRUE);
 
-	return (char ***)result;
-}
-
+	if (!result)
+		return NULL;
 
-char ***
-tracker_db_search_files_by_text (DBConnection *db_con, const char *text, int offset, int limit, gboolean sort)
-{
-	char ***result;
+	if (tracker_db_result_set_get_n_rows (result) == 0) {
+		g_object_unref (result);
+		return NULL;
+	}
 
-	result = NULL;
+	tracker_db_result_set_rewind (result);
 
 	return result;
 }
 
+TrackerDBResultSet *
+tracker_db_search_files_by_text (DBConnection *db_con, const char *text, int offset, int limit, gboolean sort)
+{
+	return NULL;
+}
+
 
-char ***
+TrackerDBResultSet *
 tracker_db_search_metadata (DBConnection *db_con, const char *service, const char *field, const char *text, int offset, int limit)
 {
 	FieldDef *def;
-	char	 ***res;
+	TrackerDBResultSet *result_set;
 
 	g_return_val_if_fail ((service && field && text), NULL);
 
@@ -3182,61 +2210,34 @@
 	switch (def->type) {
 
 		case 0: 
-		case 1: res = tracker_exec_proc (db_con, "SearchMetadata", 2, def->id, text); break;
+		case 1: result_set = tracker_exec_proc (db_con, "SearchMetadata", def->id, text, NULL); break;
 
 		case 2:
-		case 3: res = tracker_exec_proc (db_con, "SearchMetadataNumeric", 2, def->id, text); break;
+		case 3: result_set = tracker_exec_proc (db_con, "SearchMetadataNumeric", def->id, text, NULL); break;
 
-		case 5: res = tracker_exec_proc (db_con, "SearchMetadataKeywords", 2, def->id, text); break;
+		case 5: result_set = tracker_exec_proc (db_con, "SearchMetadataKeywords", def->id, text, NULL); break;
 
-		default: tracker_error ("ERROR: metadata could not be retrieved as type %d is not supported", def->type); res = NULL;
+		default: tracker_error ("ERROR: metadata could not be retrieved as type %d is not supported", def->type); result_set = NULL;
 	}
 
 
-	return res;
+	return result_set;
 }
 
 
-char ***
+TrackerDBResultSet *
 tracker_db_search_matching_metadata (DBConnection *db_con, const char *service, const char *id, const char *text)
 {
-	char ***result;
-
 	g_return_val_if_fail (id, NULL);
 
-	result = NULL;
-
-	return result;
-}
-
-
-/*
-static int
-get_metadata_type (DBConnection *db_con, const char *meta)
-{
-	char ***res;
-	int  result;
-
-	res = tracker_exec_proc (db_con, "GetMetaDataTypeID", 1, meta);
-
-	if (res && res[0][0]) {
-		result = atoi (res[0][0]);
-		tracker_db_free_result (res);
-	} else {
-		result = -1;
-	}
-
-	return result;
+	return NULL;
 }
-*/
 
-
-
-char ***
+TrackerDBResultSet *
 tracker_db_get_metadata (DBConnection *db_con, const char *service, const char *id, const char *key)
 {
+	TrackerDBResultSet *result_set;
 	FieldDef *def;
-	char	 ***res;
 
 	g_return_val_if_fail (id, NULL);
 
@@ -3248,25 +2249,27 @@
 	}
 
 	switch (def->type) {
-		
 		case DATA_INDEX:
 		case DATA_STRING:
 		case DATA_DOUBLE:
-			res = tracker_exec_proc (db_con, "GetMetadata", 2, id, def->id); break;
-
+			result_set = tracker_exec_proc (db_con, "GetMetadata", id, def->id, NULL);
+			break;
 		case DATA_INTEGER:
-		case DATA_DATE: res = tracker_exec_proc (db_con, "GetMetadataNumeric", 2, id, def->id); break;
-
-		case DATA_FULLTEXT: res = tracker_exec_proc (db_con, "GetContents", 2, id, def->id); break;
-			
+		case DATA_DATE:
+			result_set = tracker_exec_proc (db_con, "GetMetadataNumeric", id, def->id, NULL);
+			break;
+		case DATA_FULLTEXT:
+			result_set = tracker_exec_proc (db_con, "GetContents", id, def->id, NULL);
+			break;
 		case DATA_KEYWORD:
-			res = tracker_exec_proc (db_con, "GetMetadataKeyword", 2, id, def->id); break;
+			result_set = tracker_exec_proc (db_con, "GetMetadataKeyword", id, def->id, NULL);
+			break;
 
-		default: tracker_error ("ERROR: metadata could not be retrieved as type %d is not supported", def->type); res = NULL;
+		default:
+			tracker_error ("ERROR: metadata could not be retrieved as type %d is not supported", def->type); result_set = NULL;
 	}
 
-
-	return res;
+	return result_set;
 }
 
 
@@ -3275,28 +2278,28 @@
 tracker_db_get_metadata_delimited (DBConnection *db_con, const char *service, const char *id, const char *key)
 {
 	GString *gstr = NULL;
-	char **row;
+	TrackerDBResultSet *result_set;
+
+	result_set = tracker_db_get_metadata (db_con, service, id, key);
 
-	char ***res = tracker_db_get_metadata (db_con, service, id, key);
-	
-	if (res) {
-		int i = 0;
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *str;
 
-		while ((row = tracker_db_get_row (res, i))) {
+		while (valid) {
+			tracker_db_result_set_get (result_set, 0, &str, -1);
 
-			if (row[0]) {
-				if (gstr) {
-					g_string_append_printf (gstr, "|%s", row[0]);
-				} else {
-					gstr = g_string_new (row[0]);
-				}						
+			if (gstr) {
+				g_string_append_printf (gstr, "|%s", str);
+			} else {
+				gstr = g_string_new (str);
 			}
-		
-			i++;
-		}
 
-		tracker_db_free_result (res);
+			g_free (str);
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
 
+		g_object_unref (result_set);
 	}
 
 	if (gstr) {
@@ -3304,7 +2307,6 @@
 	} else {
 		return NULL;
 	}
-
 }
 
 
@@ -3349,34 +2351,31 @@
 char *
 tracker_get_related_metadata_names (DBConnection *db_con, const char *name)
 {
-	char	 ***res = NULL;
+	TrackerDBResultSet *result_set;
 
-	res = tracker_exec_proc (db_con, "GetMetadataAliasesForName", 2, name, name);
+	result_set = tracker_exec_proc (db_con, "GetMetadataAliasesForName", name, name, NULL);
 
-	if (res) {
-		int k = 0;
-		GString *str;
-		char **row;
+	if (result_set) {
+		GString *gstr = NULL;
+		gboolean valid = TRUE;
+		gint id;
 
-		str = g_string_new ("");
+		while (valid) {
+			tracker_db_result_set_get (result_set, 1, &id, -1);
 
-		while ((row = tracker_db_get_row (res, k))) {
-			if (row[1]) {
-				if (k==0) {
-					g_string_append (str, row[1]);
-				} else {
-					g_string_append_printf (str, ", %s", row[1]);
-				}
+			if (gstr) {
+				g_string_append_printf (gstr, ", %d", id);
+			} else {
+				gstr = g_string_new ("");
+				g_string_append_printf (gstr, "%d", id);
 			}
-		
-			k++;
+
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
 
-		char *value = g_string_free (str, FALSE);
-		
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 
-		return value;
+		return g_string_free (gstr, FALSE);
 	}
 
 	return NULL;
@@ -3487,7 +2486,7 @@
 					g_free (mvalue);
 				}
 	
-				tracker_exec_proc (db_con, "SetMetadataKeyword", 3, id, def->id, values[i]); 
+				tracker_exec_proc (db_con, "SetMetadataKeyword", id, def->id, values[i], NULL);
 			}
 
 			break;
@@ -3507,7 +2506,7 @@
 					table = tracker_parse_text_fast (table, mvalue, def->weight);
 				}
 				
-				tracker_exec_proc (db_con, "SetMetadata", 4, id, def->id, mvalue, values[i]); 
+				tracker_exec_proc (db_con, "SetMetadata", id, def->id, mvalue, values[i], NULL);
 				
 				g_free (mvalue);
 			}
@@ -3537,7 +2536,7 @@
                                         continue;
                                 }
 
-				tracker_exec_proc (db_con, "SetMetadata", 4, id, def->id, " ", values[i]); 
+				tracker_exec_proc (db_con, "SetMetadata", id, def->id, " ", values[i], NULL);
 			}
 
                         break;
@@ -3551,7 +2550,7 @@
 
 				gchar *mvalue = tracker_parse_text_to_string (values[i], def->filtered,  def->filtered, def->delimited);
 
-				tracker_exec_proc (db_con, "SetMetadata", 4, id, def->id, mvalue, values[i]);
+				tracker_exec_proc (db_con, "SetMetadata", id, def->id, mvalue, values[i], NULL);
 
 				g_free (mvalue);
 			}
@@ -3565,7 +2564,7 @@
                                         continue;
                                 }
 
-				tracker_exec_proc (db_con, "SetMetadataNumeric", 3, id, def->id, values[i]); 
+				tracker_exec_proc (db_con, "SetMetadataNumeric", id, def->id, values[i], NULL);
 			}
 
 			break;
@@ -3584,7 +2583,7 @@
 					continue;
 				}
 
-				tracker_exec_proc (db_con, "SetMetadataNumeric", 3, id, def->id, mvalue); 
+				tracker_exec_proc (db_con, "SetMetadataNumeric", id, def->id, mvalue, NULL);
 
 				g_free (mvalue);
 			}
@@ -3617,13 +2616,11 @@
 				g_free (my_val);
 			}
 
-			gchar *sql = g_strdup_printf ("update Services set KeyMetadata%d = '%s' where id = %s",
-                                                      key_field, esc_value, id);
-
-			tracker_db_exec_no_reply (db_con, sql);
+			tracker_db_exec_no_reply (db_con,
+						  "update Services set KeyMetadata%d = '%s' where id = %s",
+						  key_field, esc_value, id);
 
 			g_free (esc_value);
-			g_free (sql);
 		}
 	}
 }
@@ -3632,31 +2629,25 @@
 static char *
 get_backup_id (DBConnection *db_con, const char *id)
 {
+	TrackerDBResultSet *result_set;
 	char *backup_id = NULL;
-	DBConnection *db_common = db_con;
 
-	char ***res = tracker_exec_proc (db_common, "GetBackupServiceByID", 1, id);
+	result_set = tracker_exec_proc (db_con, "GetBackupServiceByID", id, NULL);
 
-	if (res) {
-		if (res[0] && res[0][0]) {
-			backup_id = g_strdup (res[0][0]);	
-		} else {
-			tracker_exec_proc (db_common, "InsertBackupService", 1, id);
-			backup_id = tracker_int_to_str (sqlite3_last_insert_rowid (db_common->db));
-
-		}
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 0, &backup_id, -1);
+		g_object_unref (result_set);
+	}
 
-		tracker_db_free_result (res);
+	if (!backup_id) {
+		gint64 id;
 
-	} else {
-		tracker_exec_proc (db_common, "InsertBackupService", 1, id);
-		backup_id = tracker_int_to_str (sqlite3_last_insert_rowid (db_common->db));
+		tracker_exec_proc (db_con, "InsertBackupService", id, NULL);
+		id = tracker_db_interface_sqlite_get_last_insert_id (TRACKER_DB_INTERFACE_SQLITE (db_con->db));
+		backup_id = tracker_int_to_str (id);
 	}
 
-
 	return backup_id;
-
-
 }
 
 
@@ -3667,7 +2658,7 @@
 	char *backup_id = get_backup_id (db_con, id);
 
 	if (backup_id) {
-		tracker_exec_proc (db_con->common, "SetBackupMetadata", 3, backup_id, key_id, value);
+		tracker_exec_proc (db_con->common, "SetBackupMetadata", backup_id, key_id, value, NULL);
 		g_free (backup_id);
 	}
 
@@ -3682,7 +2673,7 @@
 	char *backup_id = get_backup_id (db_con, id);
 
 	if (backup_id) {
-		tracker_exec_proc (db_con->common, "DeleteBackupMetadataValue", 3, backup_id, key_id, value);
+		tracker_exec_proc (db_con->common, "DeleteBackupMetadataValue", backup_id, key_id, value, NULL);
 		g_free (backup_id);
 	}
 
@@ -3695,7 +2686,7 @@
 	char *backup_id = get_backup_id (db_con, id);
 
 	if (backup_id) {
-		tracker_exec_proc (db_con->common, "DeleteBackupMetadata", 2, backup_id, key_id);
+		tracker_exec_proc (db_con->common, "DeleteBackupMetadata", backup_id, key_id, NULL);
 		g_free (backup_id);
 	}
 
@@ -3776,7 +2767,7 @@
 
 				if (!values[i] || !values[i][0]) continue;
 
-				tracker_exec_proc (db_con, "SetMetadataKeyword", 3, id, def->id, values[i]);
+				tracker_exec_proc (db_con, "SetMetadataKeyword", id, def->id, values[i], NULL);
 
 				/* backup non-embedded data for embedded services */
 				if (do_backup && 
@@ -3818,7 +2809,7 @@
 
 				char *mvalue = tracker_parse_text_to_string (values[i], def->filtered,  def->filtered, def->delimited);
 
-				tracker_exec_proc (db_con, "SetMetadata", 4, id, def->id, mvalue, values[i]); 
+				tracker_exec_proc (db_con, "SetMetadata", id, def->id, mvalue, values[i], NULL);
 
 				g_free (mvalue);
 
@@ -3853,7 +2844,7 @@
 
 				char *mvalue = tracker_parse_text_to_string (values[i], def->filtered,  def->filtered, def->delimited);
 
-				tracker_exec_proc (db_con, "SetMetadata", 4, id, def->id, mvalue, values[i]);
+				tracker_exec_proc (db_con, "SetMetadata", id, def->id, mvalue, values[i], NULL);
 
 				g_free (mvalue);
 			}
@@ -3874,7 +2865,7 @@
 				}
 
 
-				tracker_exec_proc (db_con, "SetMetadata", 4, id, def->id, " ", values[i]); 
+				tracker_exec_proc (db_con, "SetMetadata", id, def->id, " ", values[i], NULL);
 
 			}
 			break;
@@ -3894,7 +2885,7 @@
 				}
 
 
-				tracker_exec_proc (db_con, "SetMetadataNumeric", 3, id, def->id, values[i]); 
+				tracker_exec_proc (db_con, "SetMetadataNumeric", id, def->id, values[i], NULL);
 			}
 
 			break;
@@ -3913,7 +2904,7 @@
 
 				}
 
-				tracker_exec_proc (db_con, "SetMetadataNumeric", 3, id, def->id, mvalue); 
+				tracker_exec_proc (db_con, "SetMetadataNumeric", id, def->id, mvalue, NULL);
 
 				/* backup non-embedded data for embedded services */
 				if (do_backup && 
@@ -3959,12 +2950,11 @@
 
 			}
 
-			char *sql = g_strdup_printf ("update Services set KeyMetadata%d = '%s' where id = %s", key_field, esc_value, id);
-
-			tracker_db_exec_no_reply (db_con, sql);
+			tracker_db_exec_no_reply (db_con,
+						  "update Services set KeyMetadata%d = '%s' where id = %s",
+						  key_field, esc_value, id);
 
-			g_free (esc_value);	
-			g_free (sql);
+			g_free (esc_value);
 		}
 
 	}
@@ -4080,26 +3070,26 @@
 		case DATA_INDEX:
 		case DATA_STRING:
 			mvalue = tracker_parse_text_to_string (value, def->filtered,  def->filtered, def->delimited);
-			tracker_exec_proc (db_con, "DeleteMetadataValue", 3, id, def->id, mvalue); 
+			tracker_exec_proc (db_con, "DeleteMetadataValue", id, def->id, mvalue, NULL);
 			g_free (mvalue);
 			break;
 
 
 		case DATA_DOUBLE:
-			tracker_exec_proc (db_con, "DeleteMetadataValue", 3, id, def->id, value); 
+			tracker_exec_proc (db_con, "DeleteMetadataValue", id, def->id, value, NULL);
 			break;
 
 		
 		case DATA_INTEGER:
 		case DATA_DATE:
 
-			tracker_exec_proc (db_con, "DeleteMetadataNumericValue", 3, id, def->id, value);  
+			tracker_exec_proc (db_con, "DeleteMetadataNumericValue", id, def->id, value, NULL);
 			break;
 
 		
 		case DATA_KEYWORD:
 			
-			tracker_exec_proc (db_con, "DeleteMetadataKeywordValue", 3, id, def->id, value); 
+			tracker_exec_proc (db_con, "DeleteMetadataKeywordValue", id, def->id, value, NULL);
 			break;
 		
 		default:	
@@ -4110,45 +3100,36 @@
 	}
 
 	if (key_field > 0) {
-	
-		char ***res = tracker_db_get_metadata (db_con, service, id, key);
-	
-		if (res) {
-			char **row;
-	
-			row = tracker_db_get_row (res, 0);
+		TrackerDBResultSet *result_set;
+		gchar *value;
 
-			if (row && row[0]) {
-				char *esc_value = tracker_escape_string (row[0]);
-				char *sql = g_strdup_printf ("update Services set KeyMetadata%d = '%s' where id = %s", key_field, esc_value, id);
+		result_set = tracker_db_get_metadata (db_con, service, id, key);
 
-				tracker_db_exec_no_reply (db_con, sql);
+		if (result_set) {
+			tracker_db_result_set_get (result_set, 0, &value, -1);
 
-				g_free (esc_value);	
-				g_free (sql);	
-
-			} else {
-				char *sql = g_strdup_printf ("update Services set KeyMetadata%d = NULL where id = %s", key_field, id);
+			if (value) {
+				char *esc_value = tracker_escape_string (value);
 
-				tracker_db_exec_no_reply (db_con, sql);
-		
-				g_free (sql);
+				tracker_db_exec_no_reply (db_con,
+							 "update Services set KeyMetadata%d = '%s' where id = %s",
+							  key_field, esc_value, id);
 
+				g_free (esc_value);
+				g_free (value);
+			} else {
+				tracker_db_exec_no_reply (db_con,
+							  "update Services set KeyMetadata%d = NULL where id = %s",
+							  key_field, id);
 			}
 
-			tracker_db_free_result (res);
-		
+			g_object_unref (result_set);
 		} else {
-			char *sql = g_strdup_printf ("update Services set KeyMetadata%d = NULL where id = %s", key_field, id);
-
-			tracker_db_exec_no_reply (db_con, sql);
-		
-			g_free (sql);
-
-
+			tracker_db_exec_no_reply (db_con,
+						  "update Services set KeyMetadata%d = NULL where id = %s",
+						  key_field, id);
 		}
-				
-	} 
+	}
 
 
 	/* update fulltext index differentially with old and new values */
@@ -4210,11 +3191,9 @@
 
 	
 	if (key_field > 0) {
-		char *sql = g_strdup_printf ("update Services set KeyMetadata%d = NULL where id = %s", key_field, id);
-
-		tracker_db_exec_no_reply (db_con, sql);
-		
-		g_free (sql);
+		tracker_db_exec_no_reply (db_con,
+					  "update Services set KeyMetadata%d = NULL where id = %s",
+					  key_field, id);
 	}
 	
 	
@@ -4224,23 +3203,23 @@
 		case DATA_INDEX:
 		case DATA_STRING:
 		case DATA_DOUBLE:
-			tracker_exec_proc (db_con, "DeleteMetadata", 2, id, def->id); 
+			tracker_exec_proc (db_con, "DeleteMetadata", id, def->id, NULL);
 			break;
 
 		case DATA_INTEGER:
 		case DATA_DATE:
-			tracker_exec_proc (db_con, "DeleteMetadataNumeric", 2, id, def->id);  
+			tracker_exec_proc (db_con, "DeleteMetadataNumeric", id, def->id, NULL);
 			break;
 
 		
 		case DATA_KEYWORD:
-			tracker_exec_proc (db_con, "DeleteMetadataKeyword", 2, id, def->id); 
+			tracker_exec_proc (db_con, "DeleteMetadataKeyword", id, def->id, NULL);
 			break;
 
 		case DATA_FULLTEXT:
 
-			tracker_exec_proc (db_con, "DeleteContent", 2, id, def->id); 
-			break;						
+			tracker_exec_proc (db_con, "DeleteContent", id, def->id, NULL);
+			break;
 
 		default:
 			tracker_error ("ERROR: metadata could not be deleted as this operation is not supported by type %d for metadata %s", def->type, key);
@@ -4264,7 +3243,7 @@
 guint32
 tracker_db_create_service (DBConnection *db_con, const char *service, FileInfo *info)
 {
-	char	   ***res;
+	TrackerDBResultSet *result_set;
 	int	   i;
 	guint32	   id = 0;
 	char	   *sid;
@@ -4291,20 +3270,22 @@
 
 	/* get a new unique ID for the service - use mutex to prevent race conditions */
 
-	res = tracker_exec_proc (db_con->common, "GetNewID", 0);
+	result_set = tracker_exec_proc (db_con->common, "GetNewID", NULL);
 
-	if (!res || !res[0] || !res[0][0]) {
+	if (!result_set) {
 		tracker_error ("ERROR: could not create service - GetNewID failed");
 		return 0;
 	}
 
-	i = atoi (res[0][0]);
+	tracker_db_result_set_get (result_set, 0, &sid, -1);
+	i = atoi (sid);
+	g_free (sid);
 	i++;
 
 	sid = tracker_int_to_str (i);
-	tracker_exec_proc (db_con->common, "UpdateNewID",1, sid);
+	tracker_exec_proc (db_con->common, "UpdateNewID", sid, NULL);
 
-	tracker_db_free_result (res);
+	g_object_unref (result_set);
 
 	if (info->is_directory) {
 		str_is_dir = "1";
@@ -4340,9 +3321,9 @@
               //  gchar *apath = tracker_escape_string (path);
              //   gchar *aname = tracker_escape_string (name);
 
-		tracker_exec_proc (db_con, "CreateService", 11, sid, path, name,
+		tracker_exec_proc (db_con, "CreateService", sid, path, name,
                                    str_service_type_id, info->mime, str_filesize,
-                                   str_is_dir, str_is_link, str_offset, str_mtime, str_aux);
+                                   str_is_dir, str_is_link, str_offset, str_mtime, str_aux, NULL);
               //  g_free (apath);
              //   g_free (aname);
 
@@ -4358,22 +3339,20 @@
 			g_free (str_offset);
 			return 0;
 		}
-		id = sqlite3_last_insert_rowid (db_con->db);
+		id = tracker_db_interface_sqlite_get_last_insert_id (TRACKER_DB_INTERFACE_SQLITE (db_con->db));
 
 		if (info->is_hidden) {
-			char *sql = g_strdup_printf ("Update services set Enabled = 0 where ID = %d", (int) id);
-
-			tracker_db_exec_no_reply (db_con, sql);
-
-			g_free (sql);
+			tracker_db_exec_no_reply (db_con,
+						  "Update services set Enabled = 0 where ID = %d",
+						  (int) id);
 		}
 
-		tracker_exec_proc (db_con->common, "IncStat", 1, service);
+		tracker_exec_proc (db_con->common, "IncStat", service, NULL);
 
                 parent = tracker_service_manager_get_parent_service (service);
 		
 		if (parent) {
-			tracker_exec_proc (db_con->common, "IncStat", 1, parent);
+			tracker_exec_proc (db_con->common, "IncStat", parent, NULL);
 			g_free (parent);
 		}
 
@@ -4416,7 +3395,7 @@
 
 	str_file_id = tracker_uint_to_str (id);
 
-	tracker_exec_proc (db_con->blob, "DeleteAllContents", 1, str_file_id);
+	tracker_exec_proc (db_con->blob, "DeleteAllContents", str_file_id, NULL);
 
 	g_free (str_file_id);
 
@@ -4495,12 +3474,12 @@
 	if (service) {
 		gchar *parent;
 
-		tracker_exec_proc (db_con->common, "DecStat", 1, service);
+		tracker_exec_proc (db_con->common, "DecStat", service, NULL);
 
                 parent = tracker_service_manager_get_parent_service (service);
 		
 		if (parent) {
-			tracker_exec_proc (db_con->common, "DecStat", 1, parent);
+			tracker_exec_proc (db_con->common, "DecStat", parent, NULL);
 			g_free (parent);
 		}
 
@@ -4541,34 +3520,35 @@
 tracker_db_delete_file (DBConnection *db_con, guint32 file_id)
 {
 	char *str_file_id, *name = NULL, *path;
+	TrackerDBResultSet *result_set;
+	gint id;
 
 	delete_index_for_service (db_con, file_id);
 
 	str_file_id = tracker_uint_to_str (file_id);
 
-	char ***res = tracker_exec_proc (db_con, "GetFileByID3", 1, str_file_id);
+	result_set = tracker_exec_proc (db_con, "GetFileByID3", str_file_id, NULL);
 
-	if (res) {
-		
-		if (res[0] && res[0][0] && res[0][1]) {
-			name = res[0][0];
-			path = res[0][1];
-		} else {
-			tracker_db_free_result (res);
-			g_free (str_file_id);
-			return;
-		}
+	if (result_set) {
+		tracker_db_result_set_get (result_set,
+					   0, &name,
+					   1, &path,
+					   3, &id,
+					   -1);
+
+		if (name && path) {
+			dec_stat (db_con, id);
+
+			tracker_exec_proc (db_con, "DeleteService1", str_file_id, NULL);
+			tracker_exec_proc (db_con->common, "DeleteService6", path, name, NULL);
+			tracker_exec_proc (db_con->common, "DeleteService7", path, name, NULL);
+			tracker_exec_proc (db_con->common, "DeleteService9", path, name, NULL);
 
-		if (res[0] && res[0][3]) {
-			dec_stat (db_con, atoi (res[0][3]));
+			g_free (name);
+			g_free (path);
 		}
 
-		tracker_exec_proc (db_con, "DeleteService1", 1, str_file_id);
-		tracker_exec_proc (db_con->common, "DeleteService6", 2, path, name);
-		tracker_exec_proc (db_con->common, "DeleteService7", 2, path, name);
-		tracker_exec_proc (db_con->common, "DeleteService9", 2, path, name);
-
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	g_free (str_file_id);
@@ -4578,7 +3558,7 @@
 void
 tracker_db_delete_directory (DBConnection *db_con, guint32 file_id, const char *uri)
 {
-	char ***res;
+	TrackerDBResultSet *result_set;
 	char *str_file_id, *uri_prefix;
 
 	str_file_id = tracker_uint_to_str (file_id);
@@ -4588,34 +3568,32 @@
 	delete_index_for_service (db_con, file_id);
 
 	/* get all file id's for all files recursively under directory amd delete them */
-	res = tracker_exec_proc (db_con, "SelectSubFileIDs", 2, uri, uri_prefix);
+	result_set = tracker_exec_proc (db_con, "SelectSubFileIDs", uri, uri_prefix, NULL);
 
-	if (res) {
-		char **row;
-		int  i;
-
-		for (i = 0; (row = tracker_db_get_row (res, i)); i++) {
-			if (row[0]) {
-				tracker_db_delete_file (db_con, atoi (row[0]));
-		
-			}
+	if (result_set) {
+		gboolean valid = TRUE;
+		gint id;
 
+		while (valid) {
+			tracker_db_result_set_get (result_set, 0, &id, -1);
+			tracker_db_delete_file (db_con, id);
 
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 
 	/* delete all files underneath directory 
-	tracker_db_start_transaction (db_con);
-	tracker_exec_proc (db_con, "DeleteService2", 1, uri);
-	tracker_exec_proc (db_con, "DeleteService3", 1, uri_prefix);
-	tracker_exec_proc (db_con, "DeleteService4", 1, uri);
-	tracker_exec_proc (db_con, "DeleteService5", 1, uri_prefix);
-	tracker_exec_proc (db_con, "DeleteService8", 2, uri, uri_prefix);
-	tracker_exec_proc (db_con, "DeleteService10", 2, uri, uri_prefix);
-	tracker_db_end_transaction (db_con);
+	tracker_db_interface_start_transaction (db_con->db);
+	tracker_exec_proc (db_con, "DeleteService2", uri, NULL);
+	tracker_exec_proc (db_con, "DeleteService3", uri_prefix, NULL);
+	tracker_exec_proc (db_con, "DeleteService4", uri, NULL);
+	tracker_exec_proc (db_con, "DeleteService5", uri_prefix, NULL);
+	tracker_exec_proc (db_con, "DeleteService8", uri, uri_prefix, NULL);
+	tracker_exec_proc (db_con, "DeleteService10", uri, uri_prefix, NULL);
+	tracker_db_interface_end_transaction (db_con->db);
 	*/
 
 	/* delete directory */
@@ -4654,7 +3632,7 @@
 	name = g_path_get_basename (info->uri);
 	path = g_path_get_dirname (info->uri);
 
-	tracker_exec_proc (db_con->index, "UpdateFile", 8, str_service_type_id, path, name, info->mime, str_size, str_mtime, str_offset, str_file_id);
+	tracker_exec_proc (db_con->index, "UpdateFile", str_service_type_id, path, name, info->mime, str_size, str_mtime, str_offset, str_file_id, NULL);
 	
 	g_free (str_service_type_id);
 	g_free (str_size);
@@ -4669,7 +3647,7 @@
 gboolean
 tracker_db_has_pending_files (DBConnection *db_con)
 {
-	char	 ***res;
+	TrackerDBResultSet *result_set;
 	gboolean has_pending;
 
 	if (!tracker->is_running) {
@@ -4678,22 +3656,15 @@
 
 	has_pending = FALSE;
 
-	res = tracker_exec_proc (db_con->cache, "ExistsPendingFiles", 0);
-
-	if (res) {
-		char **row;
+	result_set = tracker_exec_proc (db_con->cache, "ExistsPendingFiles", NULL);
 
-		row = tracker_db_get_row (res, 0);
-
-		if (row && row[0]) {
-			int pending_file_count;
+	if (result_set) {
+		gint pending_file_count;
 
-			pending_file_count = atoi (row[0]);
-			tracker_debug ("%d files are pending with count %s", pending_file_count, row[0]);
-			has_pending = (pending_file_count > 0);
-		}
+		tracker_db_result_set_get (result_set, 0, &pending_file_count, -1);
+		has_pending = (pending_file_count > 0);
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	return has_pending;
@@ -4703,7 +3674,7 @@
 gboolean
 tracker_db_has_pending_metadata (DBConnection *db_con)
 {
-	char	 ***res;
+	TrackerDBResultSet *result_set;
 	gboolean has_pending;
 
 	if (!tracker->is_running) {
@@ -4712,53 +3683,47 @@
 
 	has_pending = FALSE;
 
-	res = tracker_exec_proc (db_con->cache, "CountPendingMetadataFiles", 0);
-
-	if (res) {
-		char **row;
+	result_set = tracker_exec_proc (db_con->cache, "CountPendingMetadataFiles", 0);
 
-		row = tracker_db_get_row (res, 0);
-
-		if (row && row[0]) {
-			int pending_file_count;
+	if (result_set) {
+		gint pending_file_count;
 
-			pending_file_count = atoi (row[0]);
-			tracker_debug ("metadata queue has %d rows pending", atoi (row[0]));
-			has_pending = (pending_file_count > 0);
-		}
+		tracker_db_result_set_get (result_set, 0, &pending_file_count, -1);
+		has_pending = (pending_file_count > 0);
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	return has_pending;
 }
 
 
-char ***
+TrackerDBResultSet *
 tracker_db_get_pending_files (DBConnection *db_con)
 {
+	DBConnection *cache;
 	time_t time_now;
-	char *time_str, *str;
 
 	if (!tracker->is_running) {
 		return NULL;
 	}
 
+	cache = db_con->cache;
 	time (&time_now);
 
-	time_str = tracker_int_to_str (time_now);
-
-
-	tracker_db_exec_no_reply (db_con->cache, "DELETE FROM FileTemp");
-	str = g_strconcat ("INSERT INTO FileTemp (ID, FileID, Action, FileUri, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID) SELECT ID, FileID, Action, FileUri, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID FROM FilePending WHERE (PendingDate < ", time_str, ") AND (Action <> 20) LIMIT 250", NULL);
-	tracker_db_exec_no_reply (db_con->cache, str);
-	tracker_db_exec_no_reply (db_con->cache, "DELETE FROM FilePending WHERE ID IN (SELECT ID FROM FileTemp)");
+	tracker_db_exec_no_reply (cache, "DELETE FROM FileTemp");
 
+	tracker_db_exec_no_reply (cache,
+				  "INSERT INTO FileTemp (ID, FileID, Action, FileUri, MimeType,"
+				  " IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID) "
+				  "SELECT ID, FileID, Action, FileUri, MimeType,"
+				  " IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID "
+				  "FROM FilePending WHERE (PendingDate < %d) AND (Action <> 20) LIMIT 250",
+				  (gint) time_now);
 
-	g_free (str);
-	g_free (time_str);
+	tracker_db_exec_no_reply (cache, "DELETE FROM FilePending WHERE ID IN (SELECT ID FROM FileTemp)");
 
-	return tracker_exec_sql (db_con->cache, "SELECT FileID, FileUri, Action, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID FROM FileTemp ORDER BY ID");
+	return tracker_db_interface_execute_query (cache->db, NULL, "SELECT FileID, FileUri, Action, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID FROM FileTemp ORDER BY ID");
 }
 
 
@@ -4769,29 +3734,25 @@
 }
 
 
-char ***
+TrackerDBResultSet *
 tracker_db_get_pending_metadata (DBConnection *db_con)
 {
+	DBConnection *cache;
 	const char *str;
 
 	if (!tracker->is_running) {
 		return NULL;
 	}
 
-	str = "INSERT INTO MetadataTemp (ID, FileID, Action, FileUri, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID) SELECT ID, FileID, Action, FileUri, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID FROM FilePending WHERE Action = 20 LIMIT 250";
-
-	tracker_db_exec_no_reply (db_con->cache, "DELETE FROM MetadataTemp");
-	tracker_db_exec_no_reply (db_con->cache, str);
-	tracker_db_exec_no_reply (db_con->cache, "DELETE FROM FilePending WHERE ID IN (SELECT ID FROM MetadataTemp)");
+	cache = db_con->cache;
 
-	return tracker_exec_sql (db_con->cache, "SELECT FileID, FileUri, Action, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID FROM MetadataTemp ORDER BY ID");
-}
+	str = "INSERT INTO MetadataTemp (ID, FileID, Action, FileUri, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID) SELECT ID, FileID, Action, FileUri, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID FROM FilePending WHERE Action = 20 LIMIT 250";
 
+	tracker_db_exec_no_reply (cache, "DELETE FROM MetadataTemp");
+	tracker_db_exec_no_reply (cache, str);
+	tracker_db_exec_no_reply (cache, "DELETE FROM FilePending WHERE ID IN (SELECT ID FROM MetadataTemp)");
 
-unsigned int
-tracker_db_get_last_id (DBConnection *db_con)
-{
-	return sqlite3_last_insert_rowid (db_con->db);
+	return tracker_db_interface_execute_query (cache->db, NULL, "SELECT FileID, FileUri, Action, MimeType, IsDir, IsNew, RefreshEmbedded, RefreshContents, ServiceTypeID FROM MetadataTemp ORDER BY ID");
 }
 
 
@@ -4830,9 +3791,9 @@
 	str_service_type_id = tracker_int_to_str (service_type_id);
 
 	if (is_dir) {
-		tracker_exec_proc (db_con->cache, "InsertPendingFile", 10, id, action, time_str, uri, mime, "1", str_new, "1", "1", str_service_type_id);
+		tracker_exec_proc (db_con->cache, "InsertPendingFile", id, action, time_str, uri, mime, "1", str_new, "1", "1", str_service_type_id, NULL);
 	} else {
-		tracker_exec_proc (db_con->cache, "InsertPendingFile", 10, id, action, time_str, uri, mime, "0", str_new, "1", "1", str_service_type_id);
+		tracker_exec_proc (db_con->cache, "InsertPendingFile", id, action, time_str, uri, mime, "0", str_new, "1", "1", str_service_type_id, NULL);
 	}
 
 	g_free (str_service_type_id);
@@ -4853,36 +3814,35 @@
 
 	time_str = tracker_int_to_str (time_now + i);
 
-	tracker_exec_proc (db_con->cache, "UpdatePendingFile", 3, time_str, action, uri);
+	tracker_exec_proc (db_con->cache, "UpdatePendingFile", time_str, action, uri, NULL);
 
 	g_free (time_str);
 }
 
 
-char ***
+TrackerDBResultSet *
 tracker_db_get_files_by_service (DBConnection *db_con, const char *service, int offset, int limit)
 {
+	TrackerDBResultSet *result_set;
 	char *str_limit, *str_offset;
-	char ***res;
 
 	str_limit = tracker_int_to_str (limit);
 	str_offset = tracker_int_to_str (offset);
 
-	res = tracker_exec_proc (db_con, "GetByServiceType", 4, service, service, str_offset, str_limit);
+	result_set = tracker_exec_proc (db_con, "GetByServiceType", service, service, str_offset, str_limit, NULL);
 
 	g_free (str_offset);
 	g_free (str_limit);
 
-	return res;
+	return result_set;
 }
 
-
-char ***
+TrackerDBResultSet *
 tracker_db_get_files_by_mime (DBConnection *db_con, char **mimes, int n, int offset, int limit, gboolean vfs)
 {
+	TrackerDBResultSet *result_set;
 	int	i;
 	char *service;
-	char	***res;
 	char	*query;
 	GString	*str;
 
@@ -4909,22 +3869,20 @@
 
 	tracker_debug ("getting files with mimes using sql %s", query);
 
-	res = tracker_exec_sql (db_con, query);
+	result_set = tracker_db_interface_execute_query (db_con->db, NULL, query);
 
 	g_free (query);
 
-	return res;
+	return result_set;
 }
 
-
-char ***
-tracker_db_search_text_mime (DBConnection *db_con, const char *text, char **mime_array, int n)
+TrackerDBResultSet *
+tracker_db_search_text_mime (DBConnection *db_con, const char *text, char **mime_array)
 {
 	TrackerQueryTree *tree;
+	TrackerDBResultSet *result;
 	GArray       *hits;
-	char 	     **result;
 	GSList 	     *result_list;
-	const GSList *tmp;
 	guint        i;
 	int 	     count;
 	gint         service_array[8];
@@ -4947,49 +3905,48 @@
 
 	tree = tracker_query_tree_new (text, db_con->word_index, services);
 	hits = tracker_query_tree_get_hits (tree, 0, 0);
-
 	count = 0;
 
 	for (i = 0; i < hits->len; i++) {
+		TrackerDBResultSet *result_set;
 		TrackerSearchHit hit;
-		char	  *str_id;
-		char	  ***res;
+		char *str_id, *mimetype;
 
 		hit = g_array_index (hits, TrackerSearchHit, i);
 
 		str_id = tracker_uint_to_str (hit.service_id);
 
-		res = tracker_exec_proc (db_con, "GetFileByID", 1, str_id);
+		result_set = tracker_exec_proc (db_con, "GetFileByID", str_id, NULL);
 
 		g_free (str_id);
 
-		if (res) {
-			if (res[0] && res[0][0] && res[0][1] && res[0][2]) {
-				int i;
-
-				for (i = 0; i < n; i++) {
+		if (result_set) {
+			tracker_db_result_set_get (result_set, 2, &mimetype, -1);
 
-					if (strcasecmp (mime_array[i], res[0][2]) == 0) {
-						char **row;
+			if (tracker_str_in_array (mimetype, mime_array) != -1) {
+				GValue value = { 0, };
 
-						row = g_new (char *, 3);
-
-						row[0] = g_strdup (res[0][0]);
-						row[1] = g_strdup (res[0][1]);
-						row[2] = NULL;
-
-						tracker_debug ("hit is %s", row[1]);
+				if (G_UNLIKELY (!result)) {
+					result = _tracker_db_result_set_new (2);
+				}
 
-						result_list = g_slist_prepend (result_list, row);
+				_tracker_db_result_set_append (result);
 
-						count++;
+				/* copy value in column 0 */
+				_tracker_db_result_set_get_value (result_set, 0, &value);
+				_tracker_db_result_set_set_value (result, 0, &value);
+				g_value_unset (&value);
+
+				/* copy value in column 1 */
+				_tracker_db_result_set_get_value (result_set, 1, &value);
+				_tracker_db_result_set_set_value (result, 1, &value);
+				g_value_unset (&value);
 
-						break;
-					}
-				}
+				count++;
 			}
 
-			tracker_db_free_result (res);
+			g_free (mimetype);
+			g_object_unref (result_set);
 		}
 
 		if (count > 2047) {
@@ -4997,41 +3954,30 @@
 		}
 	}
 
-	if (!result_list) {
-		return NULL;
-	}
-
-	count = g_slist_length (result_list);
-	result_list = g_slist_reverse (result_list);
-
-	result = g_new ( char *, count + 1);
-	result[count] = NULL;
+	g_object_unref (tree);
+	g_array_free (hits, TRUE);
+	g_array_free (services, TRUE);
 
-	count = 0;
+	if (!result)
+		return NULL;
 
-	for (tmp = result_list; tmp; tmp = tmp->next) {
-		result[count] = (char *) tmp->data;
-		count++;
+	if (tracker_db_result_set_get_n_rows (result) == 0) {
+		g_object_unref (result);
+		return NULL;
 	}
 
-	g_slist_free (result_list);
-	g_object_unref (tree);
-	g_array_free (hits, TRUE);
-	g_array_free (services, TRUE);
+	tracker_db_result_set_rewind (result);
 
-	return (char ***) result;
+	return result;
 }
 
-
-char ***
+TrackerDBResultSet *
 tracker_db_search_text_location (DBConnection *db_con, const char *text, const char *location)
 {
+	TrackerDBResultSet *result;
 	TrackerQueryTree *tree;
 	GArray       *hits;
 	char	     *location_prefix;
-	char 	     **result;
-	GSList 	     *result_list;
-	const GSList *tmp;
 	int 	     count;
 	gint         service_array[8];
 	guint        i;
@@ -5053,45 +3999,47 @@
 
 	tree = tracker_query_tree_new (text, db_con->word_index, services);
 	hits = tracker_query_tree_get_hits (tree, 0, 0);
-
-	result_list = NULL;
-
 	count = 0;
 
 	for (i = 0; i < hits->len; i++) {
+		TrackerDBResultSet *result_set;
 		TrackerSearchHit hit;
-		char	  *str_id;
-		char	  ***res;
+		char *str_id, *path;
 
 		hit = g_array_index (hits, TrackerSearchHit, i);
 
 		str_id = tracker_uint_to_str (hit.service_id);
 
-		res = tracker_exec_proc (db_con, "GetFileByID", 1, str_id);
+		result_set = tracker_exec_proc (db_con, "GetFileByID", str_id, NULL);
 
 		g_free (str_id);
 
-		if (res) {
-			if (res[0] && res[0][0] && res[0][1]) {
+		if (result_set) {
+			tracker_db_result_set_get (result_set, 0, &path, -1);
 
-				if (g_str_has_prefix (res[0][0], location_prefix) || (strcmp (res[0][0], location) == 0)) {
-					char **row;
+			if (g_str_has_prefix (path, location_prefix) || (strcmp (path, location) == 0)) {
+				GValue value = { 0, };
 
-					row = g_new (char *, 3);
-
-					row[0] = g_strdup (res[0][0]);
-					row[1] = g_strdup (res[0][1]);
-					row[2] = NULL;
+				if (G_UNLIKELY (!result)) {
+					result = _tracker_db_result_set_new (2);
+				}
 
-					//tracker_log ("hit is %s", row[1]);
+				_tracker_db_result_set_append (result);
 
-					result_list = g_slist_prepend (result_list, row);
+				/* copy value in column 0 */
+				_tracker_db_result_set_get_value (result_set, 0, &value);
+				_tracker_db_result_set_set_value (result, 0, &value);
+				g_value_unset (&value);
+
+				/* copy value in column 1 */
+				_tracker_db_result_set_get_value (result_set, 1, &value);
+				_tracker_db_result_set_set_value (result, 1, &value);
+				g_value_unset (&value);
 
-					count++;
-				}
+				count++;
 			}
 
-			tracker_db_free_result (res);
+			g_object_unref (result_set);
 		}
 
 		if (count > 2047) {
@@ -5101,41 +4049,30 @@
 
 	g_free (location_prefix);
 
-	if (!result_list) {
-		return NULL;
-	}
-
-	count = g_slist_length (result_list);
-	result_list = g_slist_reverse (result_list);
-
-	result = g_new (char *, count + 1);
-	result[count] = NULL;
+	g_object_unref (tree);
+	g_array_free (hits, TRUE);
+	g_array_free (services, TRUE);
 
-	count = 0;
+	if (!result)
+		return NULL;
 
-	for (tmp = result_list; tmp; tmp = tmp->next) {
-		result[count] = (char *) tmp->data;
-		count++;
+	if (tracker_db_result_set_get_n_rows (result) == 0) {
+		g_object_unref (result);
+		return NULL;
 	}
 
-	g_slist_free (result_list);
-	g_object_unref (tree);
-	g_array_free (hits, TRUE);
-	g_array_free (services, TRUE);
+	tracker_db_result_set_rewind (result);
 
-	return (char ***) result;
+	return result;
 }
 
-
-char ***
-tracker_db_search_text_mime_location (DBConnection *db_con, const char *text, char **mime_array, int n, const char *location)
+TrackerDBResultSet *
+tracker_db_search_text_mime_location (DBConnection *db_con, const char *text, char **mime_array, const char *location)
 {
+	TrackerDBResultSet *result;
 	TrackerQueryTree *tree;
 	GArray       *hits;
 	char	     *location_prefix;
-	char 	     **result;
-	GSList 	     *result_list;
-	const GSList *tmp;
 	int	     count;
 	gint         service_array[8];
 	guint        i;
@@ -5157,54 +4094,53 @@
 
 	tree = tracker_query_tree_new (text, db_con->word_index, services);
 	hits = tracker_query_tree_get_hits (tree, 0, 0);
-
-	result_list = NULL;
-
 	count = 0;
 
 	for (i = 0; i < hits->len; i++) {
+		TrackerDBResultSet *result_set;
 		TrackerSearchHit hit;
-		char	  *str_id;
-		char	  ***res;
+		char *str_id, *path, *mimetype;
 
 		hit = g_array_index (hits, TrackerSearchHit, i);
 
 		str_id = tracker_uint_to_str (hit.service_id);
 
-		res = tracker_exec_proc (db_con, "GetFileByID", 1, str_id);
+		result_set = tracker_exec_proc (db_con, "GetFileByID", str_id, NULL);
 
 		g_free (str_id);
 
-		if (res) {
-			if (res[0] && res[0][0] && res[0][1] && res[0][2]) {
-
-				if (g_str_has_prefix (res[0][0], location_prefix) || (strcmp (res[0][0], location) == 0)) {
-					int i;
-
-					for (i = 0; i < n; i++) {
+		if (result_set) {
+			tracker_db_result_set_get (result_set,
+						   0, &path,
+						   2, &mimetype,
+						   -1);
+
+			if ((g_str_has_prefix (path, location_prefix) || (strcmp (path, location) == 0)) &&
+			    tracker_str_in_array (mimetype, mime_array) != -1) {
+				GValue value = { 0, };
 
-						if ((mime_array[i]) && (res[0][2] != 0) && (strcasecmp (mime_array[i], res[0][2]) == 0)) {
-							char **row;
-
-							row = g_new (char *, 3);
-
-							row[0] = g_strdup (res[0][0]);
-							row[1] = g_strdup (res[0][1]);
-							row[2] = NULL;
-
-							//tracker_log ("hit is %s", row[1]);
+				if (G_UNLIKELY (!result)) {
+					result = _tracker_db_result_set_new (2);
+				}
 
-							result_list = g_slist_prepend (result_list, row);
+				_tracker_db_result_set_append (result);
 
-							count++;
+				/* copy value in column 0 */
+				_tracker_db_result_set_get_value (result_set, 0, &value);
+				_tracker_db_result_set_set_value (result, 0, &value);
+				g_value_unset (&value);
+
+				/* copy value in column 1 */
+				_tracker_db_result_set_get_value (result_set, 1, &value);
+				_tracker_db_result_set_set_value (result, 1, &value);
+				g_value_unset (&value);
 
-							break;
-						}
-					}
-				}
+				count++;
 			}
 
-			tracker_db_free_result (res);
+			g_free (path);
+			g_free (mimetype);
+			g_object_unref (result_set);
 		}
 
 		if (count > 2047) {
@@ -5214,80 +4150,71 @@
 
 	g_free (location_prefix);
 
-	if (!result_list) {
-		return NULL;
-	}
-
-	count = g_slist_length (result_list);
-	result_list = g_slist_reverse (result_list);
+	g_object_unref (tree);
+	g_array_free (hits, TRUE);
+	g_array_free (services, TRUE);
 
-	result = g_new (char *, count + 1);
-	result[count] = NULL;
+	if (!result)
+		return NULL;
 
-	count = 0;
-	for (tmp = result_list; tmp; tmp = tmp->next) {
-		result[count] = (char *) tmp->data;
-		count++;
+	if (tracker_db_result_set_get_n_rows (result) == 0) {
+		g_object_unref (result);
+		return NULL;
 	}
 
-	g_slist_free (result_list);
-	g_object_unref (tree);
-	g_array_free (hits, TRUE);
-	g_array_free (services, TRUE);
+	tracker_db_result_set_rewind (result);
 
-	return (char ***) result;
+	return result;
 }
 
-
-char ***
+TrackerDBResultSet *
 tracker_db_get_metadata_types (DBConnection *db_con, const char *class, gboolean writeable)
 {
 	if (strcmp (class, "*") == 0) {
 		if (writeable) {
-			return tracker_exec_proc (db_con, "GetWriteableMetadataTypes", 0);
+			return tracker_exec_proc (db_con, "GetWriteableMetadataTypes", NULL);
 		} else {
-			return tracker_exec_proc (db_con, "GetMetadataTypes", 0);
+			return tracker_exec_proc (db_con, "GetMetadataTypes", NULL);
 		}
 
 	} else {
 		if (writeable) {
-			return tracker_exec_proc (db_con, "GetWriteableMetadataTypesLike", 1, class);
+			return tracker_exec_proc (db_con, "GetWriteableMetadataTypesLike", class, NULL);
 		} else {
-			return tracker_exec_proc (db_con, "GetMetadataTypesLike", 1, class);
+			return tracker_exec_proc (db_con, "GetMetadataTypesLike", class, NULL);
 		}
 	}
 }
 
-
-char ***
+TrackerDBResultSet *
 tracker_db_get_sub_watches (DBConnection *db_con, const char *dir)
 {
-	char ***res;
+	TrackerDBResultSet *result_set;
 	char *folder;
 
 	folder = g_strconcat (dir, G_DIR_SEPARATOR_S, "*", NULL);
 
-	res = tracker_exec_proc (db_con->cache, "GetSubWatches", 1, folder);
+	result_set = tracker_exec_proc (db_con->cache, "GetSubWatches", folder, NULL);
 
 	g_free (folder);
 
-	return res;
+	return result_set;
 }
 
 
-char ***
+TrackerDBResultSet *
 tracker_db_delete_sub_watches (DBConnection *db_con, const char *dir)
 {
+	TrackerDBResultSet *result_set;
 	char *folder;
-	char ***res;
 
 	folder = g_strconcat (dir, G_DIR_SEPARATOR_S, "*", NULL);
 
-	res = tracker_exec_proc (db_con->cache, "DeleteSubWatches", 1, folder);
+	result_set = tracker_exec_proc (db_con->cache, "DeleteSubWatches", folder, NULL);
 
 	g_free (folder);
 
-	return res;
+	return result_set;
 }
 
 
@@ -5302,7 +4229,7 @@
 	if (id == 0) {
 		tracker_debug ("WARNING: original file %s not found in DB", moved_from_uri);
 		tracker_db_insert_pending_file (db_con, id, moved_to_uri,  NULL, "unknown", 0, TRACKER_ACTION_WRITABLE_FILE_CLOSED, FALSE, TRUE, -1);
-		tracker_db_end_transaction (db_con);
+		tracker_db_interface_end_transaction (db_con->db);
 		return;
 	}
 
@@ -5314,7 +4241,7 @@
 
 
 	/* update db so that fileID reflects new uri */
-	tracker_exec_proc (db_con, "UpdateFileMove", 3, path, name, str_file_id);
+	tracker_exec_proc (db_con, "UpdateFileMove", path, name, str_file_id, NULL);
 
 	/* update File:Path and File:Filename metadata */
 	tracker_db_set_single_metadata (db_con, "Files", str_file_id, "File:Path", path, FALSE);
@@ -5327,7 +4254,7 @@
 	}
 
 	/* update backup service if necessary */
-	tracker_exec_proc (db_con->common, "UpdateBackupService", 4, path, name, old_path, old_name);
+	tracker_exec_proc (db_con->common, "UpdateBackupService", path, name, old_path, old_name, NULL);
 
 	g_free (str_file_id);
 	g_free (name);
@@ -5370,37 +4297,38 @@
 static void
 move_directory_files (DBConnection *db_con, const char *moved_from_uri, const char *moved_to_uri)
 {
+	TrackerDBResultSet *result_set;
 
 	/* get all sub files (excluding folders) that were moved and add watches */
-	char ***res = tracker_exec_proc (db_con, "SelectFileChildWithoutDirs", 1, moved_from_uri); 
+	result_set = tracker_exec_proc (db_con, "SelectFileChildWithoutDirs", moved_from_uri, NULL);
 
-	if (res) {
-		char **row;
-		int  k;
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *prefix, *name, *file_name, *moved_file_name;
 
-		k = 0;
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   0, &prefix,
+						   1, &name,
+						   -1);
 
-		while ((row = tracker_db_get_row (res, k))) {
+			if (prefix && name) {
+				file_name = g_build_filename (prefix, name, NULL);
+				moved_file_name = g_build_filename (moved_to_uri, name, NULL);
 
-			k++;
+				tracker_db_move_file (db_con, file_name, moved_file_name);
 
-			if (!row || !row[0] || !row[1]) {
-				continue;
+				g_free (moved_file_name);
+				g_free (file_name);
+				g_free (prefix);
+				g_free (name);
 			}
 
-			char *file_name = g_build_filename (row[0], row[1], NULL);
-			char *moved_file_name = g_build_filename (moved_to_uri, row[1], NULL);
-
-			tracker_db_move_file (db_con, file_name, moved_file_name);
-
-			g_free (moved_file_name);
-			g_free (file_name);
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
-	
-		tracker_db_free_result (res);
-		
+
+		g_object_unref (result_set);
 	}
-			
 }
 
 
@@ -5424,31 +4352,27 @@
 void
 tracker_db_move_directory (DBConnection *db_con, const char *moved_from_uri, const char *moved_to_uri)
 {
+	TrackerDBResultSet *result_set;
 	char *old_path;
-	char ***res;
 
 	old_path = g_strconcat (moved_from_uri, G_DIR_SEPARATOR_S, NULL);
 
 	/* get all sub folders that were moved and add watches */
-	res = tracker_db_get_file_subfolders (db_con, moved_from_uri);
-
-	if (res) {
-		char **row;
-		int  k;
-
-		k = 0;
-
-		while ((row = tracker_db_get_row (res, k))) {
-
-			char *dir_name, *sep, *new_path;
-			k++;
+	result_set = tracker_db_get_file_subfolders (db_con, moved_from_uri);
 
-			if (!row || !row[0] || !row[1] || !row[2]) {
-				continue;
-			}
+	if (result_set) {
+		gboolean valid = TRUE;
 
-			dir_name = g_build_filename (row[1], row[2], NULL);
+		while (valid) {
+			gchar *prefix, *name;
+			gchar *dir_name, *sep, *new_path;
+
+			tracker_db_result_set_get (result_set,
+						   1, &prefix,
+						   2, &name,
+						   -1);
 
+			dir_name = g_build_filename (prefix, name, NULL);
 			sep = str_get_after_prefix (dir_name, old_path);
 
 			if (!sep) {
@@ -5460,39 +4384,41 @@
 			g_free (sep);
 
 			tracker_info ("moving subfolder %s to %s", dir_name, new_path);
-			
+
 			move_directory (db_con, dir_name, new_path);
 
 			g_usleep (1000);
-						
+
+			g_free (prefix);
+			g_free (name);
 			g_free (new_path);
 			g_free (dir_name);
 
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
-	move_directory (db_con, moved_from_uri, moved_to_uri);	
-	
-	g_free (old_path);
+	move_directory (db_con, moved_from_uri, moved_to_uri);
 
+	g_free (old_path);
 }
 
 
-char ***
+TrackerDBResultSet *
 tracker_db_get_file_subfolders (DBConnection *db_con, const char *uri)
 {
-	char ***res;
+	TrackerDBResultSet *result_set;
 	char *folder;
 
 	folder = g_strconcat (uri, G_DIR_SEPARATOR_S, "*", NULL);
 
-	res = tracker_exec_proc (db_con, "SelectFileSubFolders", 2, uri, folder);
+	result_set = tracker_exec_proc (db_con, "SelectFileSubFolders", uri, folder, NULL);
 
 	g_free (folder);
 
-	return res;
+	return result_set;
 }
 
 
@@ -5636,14 +4562,12 @@
 }
 
 
-char ***
+TrackerDBResultSet *
 tracker_db_get_keyword_list (DBConnection *db_con, const char *service)
 {
 
 	tracker_debug (service);
-	char ***res = tracker_exec_proc (db_con, "GetKeywordList", 2, service, service);
-
-	return res;
+	return tracker_exec_proc (db_con, "GetKeywordList", service, service, NULL);
 }
 
 GSList *
@@ -5651,25 +4575,25 @@
                        const gchar  *stored_proc, 
                        gint          service_id)
 {
-
+	TrackerDBResultSet *result_set;
 	GSList  *result = NULL;
 	gchar   *service_id_str;
-        gchar ***result_set;
 
 	service_id_str = g_strdup_printf ("%d", service_id);
-	result_set = tracker_exec_proc (db_con, stored_proc, 1, service_id_str);
+	result_set = tracker_exec_proc (db_con, stored_proc, service_id_str, NULL);
 	g_free (service_id_str);
 
 	if (result_set) {
-		gchar **row;
-		gint    k;
-		
-		for (k = 0; (row = tracker_db_get_row (result_set, k)); k++) {
-			result = g_slist_prepend (result, g_strdup(row[0]));
-		}
+		gboolean valid = TRUE;
+		gchar *str;
 
-		tracker_db_free_result (result_set);
+		while (valid) {
+			tracker_db_result_set_get (result_set, 0, &str, -1);
+			result = g_slist_prepend (result, str);
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
 
+		g_object_unref (result_set);
 	}
 
 	return result;
@@ -5690,41 +4614,41 @@
 }
 
 static TrackerService *
-db_row_to_service (gchar **row)
+db_row_to_service (TrackerDBResultSet *result_set)
 {
         TrackerService *service;
-        GSList         *new_list;
-        gint            id;
-        const gchar    *name;
-        gint            i;
-
-        if (!row[0] || !row[1] || 
-            !row[2] || !row[3] || 
-            !row[4] || !row[5] || 
-            !row[6] || !row[7] || 
-            !row[8]) {
-                return NULL;
-        }
-               
+        GSList         *new_list = NULL;
+        gint            id, i;
+	gchar          *name, *parent, *content_metadata;
+	gboolean        enabled, embedded, has_metadata, has_fulltext;
+	gboolean        has_thumbs, show_service_files, show_service_directories;
+
         service = tracker_service_new ();
-        
-        new_list = NULL;
-        id = atoi (row[0]);
-        name = row[1];
+
+	tracker_db_result_set_get (result_set,
+				   0, &id,
+				   1, &name,
+				   2, &parent,
+				   3, &enabled,
+				   4, &embedded,
+				   5, &has_metadata,
+				   6, &has_fulltext,
+				   7, &has_thumbs,
+				   8, &content_metadata,
+				   10, &show_service_files,
+				   11, &show_service_directories,
+				   -1);
 
         tracker_service_set_id (service, id);
         tracker_service_set_name (service, name);
-        tracker_service_set_parent (service, row[2]);
-        tracker_service_set_enabled (service, row[3][0] == '1');
-        tracker_service_set_embedded (service, row[4][0] == '1');
-        tracker_service_set_has_metadata (service, row[5][0] == '1');
-        tracker_service_set_has_full_text (service, row[6][0] == '1');
-        tracker_service_set_has_thumbs (service, row[7][0] == '1');
-        
-        if (row[8][1]) {
-                tracker_service_set_content_metadata (service, row[8]);
-        }
-        
+        tracker_service_set_parent (service, parent);
+        tracker_service_set_enabled (service, enabled);
+        tracker_service_set_embedded (service, embedded);
+        tracker_service_set_has_metadata (service, has_metadata);
+        tracker_service_set_has_full_text (service, has_fulltext);
+        tracker_service_set_has_thumbs (service, has_thumbs);
+	tracker_service_set_content_metadata (service, content_metadata);
+
         if (g_str_has_prefix (name, "Email") ||
             g_str_has_suffix (name, "Emails")) {
                 tracker_service_set_db_type (service, TRACKER_DB_TYPE_EMAIL);
@@ -5742,16 +4666,17 @@
                 tracker_service_set_db_type (service, TRACKER_DB_TYPE_DATA);
         }
         
-        tracker_service_set_show_service_files (service, row[10][0] == '1');
-        tracker_service_set_show_service_directories (service, row[11][0] == '1');
+        tracker_service_set_show_service_files (service, show_service_files);
+        tracker_service_set_show_service_directories (service, show_service_directories);
         
         for (i = 12; i < 23; i++) {
-                if (row[i] && row[i][1]) {
-                        /* We do not duplicate the data here because
-                         * the TrackerService will do this for us.
-                         */
-                        new_list = g_slist_prepend (new_list, row[i]);
-                }
+		gchar *metadata;
+
+		tracker_db_result_set_get (result_set, i, &metadata, -1);
+
+		if (metadata) {
+			new_list = g_slist_prepend (new_list, metadata);
+		}
         }
         
         /* Hack to prevent db change late in the cycle, check the
@@ -5761,14 +4686,15 @@
                 /* These strings should be definitions at the top of
                  * this file somewhere really.
                  */
-                new_list = g_slist_prepend (new_list, "App:DisplayName");
-                new_list = g_slist_prepend (new_list, "App:Exec");
-                new_list = g_slist_prepend (new_list, "App:Icon");
+                new_list = g_slist_prepend (new_list, g_strdup ("App:DisplayName"));
+                new_list = g_slist_prepend (new_list, g_strdup ("App:Exec"));
+                new_list = g_slist_prepend (new_list, g_strdup ("App:Icon"));
         }
         
         new_list = g_slist_reverse (new_list);
         
         tracker_service_set_key_metadata (service, new_list);
+	g_slist_foreach (new_list, (GFunc) g_free, NULL);
         g_slist_free (new_list);
 
         return service;
@@ -5778,85 +4704,90 @@
 void
 tracker_db_get_static_data (DBConnection *db_con)
 {
-	gchar ***res;
-	gint     i = 0;
-        gint     j;
-
-	/* Get static metadata info */
-	res  = tracker_exec_proc (db_con, "GetMetadataTypes", 0);
-
-	if (res) {
-		gchar **row;
-
-		while ((row = tracker_db_get_row (res, i))) {
-			i++;
+	TrackerDBResultSet *result_set;
 
-			if (row[0] && row[1] && row[2] && row[3] && row[4] && row[5] && row[6] && row[7] && row[8] && row[9]) {
-				FieldDef *def = NULL;				
-	
-				def = g_new (FieldDef, 1);
-				def->id = g_strdup (row[0]);
-				def->type = atoi (row[2]);
-				def->field_name = g_strdup (row[3]);
-				def->weight = atoi (row[4]);
-				def->embedded = (row[5][0] == '1');
-				def->multiple_values = (row[6][0] == '1');
-				def->delimited = (row[7][0] == '1');
-				def->filtered = (row[8][0] == '1');
-				def->store_metadata = (row[9][0] == '1');
-				
+	/* get static metadata info */
+	result_set  = tracker_exec_proc (db_con, "GetMetadataTypes", 0);
 
-				def->child_ids = NULL;
-				
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *name;
+		gint id;
+
+		while (valid) {
+			TrackerDBResultSet *result_set2;
+			gboolean embedded, multiple_values, delimited, filtered, store_metadata;
+			FieldDef *def;
+
+			def = g_new0 (FieldDef, 1);
+
+			tracker_db_result_set_get (result_set,
+						   0, &id,
+						   1, &name,
+						   2, &def->type,
+						   3, &def->field_name,
+						   4, &def->weight,
+						   5, &embedded,
+						   6, &multiple_values,
+						   7, &delimited,
+						   8, &filtered,
+						   9, &store_metadata,
+						   -1);
+
+			def->id = tracker_int_to_str (id);
+			def->embedded = embedded;
+			def->multiple_values = multiple_values;
+			def->delimited = delimited;
+			def->filtered = filtered;
+			def->store_metadata = store_metadata;
+
+			result_set2 = tracker_exec_proc (db_con, "GetMetadataAliases", def->id, NULL);
+
+			if (result_set2) {
+				valid = TRUE;
+
+				while (valid) {
+					tracker_db_result_set_get (result_set2, 1, &id, -1);
+					def->child_ids = g_slist_prepend (def->child_ids,
+									  tracker_int_to_str (id));
 
-				j=0;
-				char ***res2 = tracker_exec_proc (db_con, "GetMetadataAliases", 1, def->id);
+					valid = tracker_db_result_set_iter_next (result_set2);
+				}
 
-				if (res2) {
-					char **row2;
+				g_object_unref (result_set2);
+			}
 
-					while ((row2 = tracker_db_get_row (res2, j))) {
-						j++;
+			g_hash_table_insert (tracker->metadata_table, g_utf8_strdown (name, -1), def);
+			tracker_debug ("loading metadata def %s with weight %d", def->field_name, def->weight);
 
-						if (row2[1]) {
-							def->child_ids = g_slist_prepend (def->child_ids, g_strdup (row[1]));
-						}
-					}
-					tracker_db_free_result (res2);	
-				}
+			g_free (name);
 
-				g_hash_table_insert (tracker->metadata_table, g_utf8_strdown  (row[1], -1), def);
-				tracker_debug ("loading metadata def %s with weight %d", 
-                                               def->field_name, def->weight);
-			} 
-		}		
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
-	/* Get static service info */	
-	res  = tracker_exec_proc_ignore_nulls (db_con, "GetAllServices", 0);
-	
-	if (res) {
-		gchar **row;
-
-		i = 0;
+	/* get static service info */	
+	result_set  = tracker_exec_proc (db_con, "GetAllServices", 0);
 
-		 tracker->email_service_min = 0;
-		 tracker->email_service_max = 0;
+	if (result_set) {
+		gboolean valid = TRUE;
+		
+		tracker->email_service_min = 0;
+		tracker->email_service_max = 0;
 
-		while ((row = tracker_db_get_row (res, i++))) {
-                        TrackerService *service;
-                        gint            id;
-                        const gchar    *name;
-                        GSList         *mimes;
-                        GSList         *mime_prefixes;
+		while (valid) {
+			TrackerService *service;
+			GSList *mimes, *mime_prefixes;
+			const gchar *name;
+			gint id;
 
-                        service = db_row_to_service (row);
+                        service = db_row_to_service (result_set);
 
                         if (!service) {
                                 continue;
-				}
+			}
 
                         id = tracker_service_get_id (service);
                         name = tracker_service_get_name (service);
@@ -5871,20 +4802,19 @@
 
                         g_slist_free (mimes);
                         g_slist_free (mime_prefixes);
-
                         g_object_unref (service);
-				}
 
-		tracker_db_free_result (res);
-		
+			valid = tracker_db_result_set_iter_next (result_set);
+		}
+
+		g_object_unref (result_set);
+
 		/* check for web history */
 		if (!tracker_service_manager_get_service ("Webhistory")) {
 			tracker_log ("Adding missing Webhistory service");
-			tracker_exec_proc (db_con, "InsertServiceType", 1, "Webhistory");	
+			tracker_exec_proc (db_con, "InsertServiceType", "Webhistory", NULL);
 		}
-		
 	}
-
 }
 
 DBConnection *
@@ -5905,23 +4835,17 @@
 char *
 tracker_db_get_service_for_entity (DBConnection *db_con, const char *id)
 {
-	char ***res;
+	TrackerDBResultSet *result_set;
 	char *result = NULL;
 
-	res  = tracker_exec_proc (db_con, "GetFileByID2", 1, id);
-	
-	if (res) {
-		if (res[0][1]) {
-			
-			result = g_strdup (res[0][1]);
-		}
-
-		tracker_db_free_result (res);
+	result_set = tracker_exec_proc (db_con, "GetFileByID2", id, NULL);
 
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 1, &result, -1);
+		g_object_unref (result_set);
 	}
 
 	return result;
-	
 }
 
 
@@ -5964,7 +4888,7 @@
 {
 	GKeyFile 		*key_file = NULL;
 	const char * const 	*locale_array;
-	char 			*service_file, *sql;
+	char 			*service_file;
 	gboolean		is_metadata = FALSE, is_service = FALSE, is_extractor = FALSE;
 	int			id;
 
@@ -6005,8 +4929,8 @@
 				FieldDef *def = tracker_db_get_field_def (db_con, *array);
 
 				if (!def) {
-					tracker_exec_proc (db_con, "InsertMetadataType", 1, *array);			
-					id = sqlite3_last_insert_rowid (db_con->db);		
+					tracker_exec_proc (db_con, "InsertMetadataType", *array, NULL);
+					id = tracker_db_interface_sqlite_get_last_insert_id (TRACKER_DB_INTERFACE_SQLITE (db_con->db));
 				} else {
 					id = atoi (def->id);
 				}
@@ -6017,8 +4941,8 @@
 				service = tracker_service_manager_get_service (*array);
 
 				if (!service) {
-					tracker_exec_proc (db_con, "InsertServiceType", 1, *array);	
-					id = sqlite3_last_insert_rowid (db_con->db);		
+					tracker_exec_proc (db_con, "InsertServiceType", *array, NULL);
+					id = tracker_db_interface_sqlite_get_last_insert_id (TRACKER_DB_INTERFACE_SQLITE (db_con->db));
 				} else {
 					id = tracker_service_get_id (service);
 				}
@@ -6054,27 +4978,25 @@
 
 						if (strcasecmp (*array2, "Parent") == 0) {
 
-							tracker_exec_proc (db_con, "InsertMetaDataChildren", 2, str_id, value);		
+							tracker_exec_proc (db_con, "InsertMetaDataChildren", str_id, value, NULL);
 
 						} else if (strcasecmp (*array2, "DataType") == 0) {
 
 							int data_id = tracker_str_in_array (value, DataTypeArray);
 
 							if (data_id != -1) {
-								sql = g_strdup_printf ("update MetaDataTypes set DataTypeID = %d where ID = %s", data_id, str_id);
-								tracker_db_exec_no_reply (db_con, sql);
-								g_free (sql);
-								
+								tracker_db_exec_no_reply (db_con,
+											  "update MetaDataTypes set DataTypeID = %d where ID = %s",
+											  data_id, str_id);
 							}
 						
 
 						} else {
 							char *esc_value = tracker_escape_string (value);
 
-							sql = g_strdup_printf ("update MetaDataTypes set  %s = '%s' where ID = %s", *array2, esc_value, str_id);
-								
-							tracker_db_exec_no_reply (db_con, sql);
-							g_free (sql);
+							tracker_db_exec_no_reply (db_con,
+										  "update MetaDataTypes set  %s = '%s' where ID = %s",
+										  *array2, esc_value, str_id);
 							g_free (esc_value);
 						}
 	
@@ -6087,7 +5009,7 @@
 							char **tmp;
 							for (tmp = tab_array; *tmp; tmp++) { 			
 
-								tracker_exec_proc (db_con, "InsertServiceTabularMetadata", 2, str_id, *tmp);		
+								tracker_exec_proc (db_con, "InsertServiceTabularMetadata", str_id, *tmp, NULL);
 								
 							}
 
@@ -6102,7 +5024,7 @@
 							char **tmp;
 							for (tmp = tab_array; *tmp; tmp++) { 			
 
-								tracker_exec_proc (db_con, "InsertServiceTileMetadata", 2, str_id, *tmp);		
+								tracker_exec_proc (db_con, "InsertServiceTileMetadata", str_id, *tmp, NULL);
 							}
 
 							g_strfreev (tab_array);
@@ -6113,11 +5035,11 @@
 
 							char **tmp;
 							for (tmp = tab_array; *tmp; tmp++) { 			
-								tracker_exec_proc (db_con, "InsertMimes", 1, *tmp);		
+								tracker_exec_proc (db_con, "InsertMimes", *tmp, NULL);
 							
-								sql = g_strdup_printf ("update FileMimes set ServiceTypeID = %s where Mime = '%s'", str_id, *tmp);
-								tracker_db_exec_no_reply (db_con, sql);
-								g_free (sql);
+								tracker_db_exec_no_reply (db_con,
+											  "update FileMimes set ServiceTypeID = %s where Mime = '%s'",
+											  str_id, *tmp);
 							}
 
 							g_strfreev (tab_array);
@@ -6128,11 +5050,11 @@
 
 							char **tmp;
 							for (tmp = tab_array; *tmp; tmp++) { 			
-								tracker_exec_proc (db_con, "InsertMimePrefixes", 1, *tmp);		
-							
-								sql = g_strdup_printf ("update FileMimePrefixes set ServiceTypeID = %s where MimePrefix = '%s'", str_id, *tmp);
-								tracker_db_exec_no_reply (db_con, sql);
-								g_free (sql);
+								tracker_exec_proc (db_con, "InsertMimePrefixes", *tmp, NULL);
+
+								tracker_db_exec_no_reply (db_con,
+											  "update FileMimePrefixes set ServiceTypeID = %s where MimePrefix = '%s'",
+											  str_id, *tmp);
 							}
 
 							g_strfreev (tab_array);
@@ -6140,9 +5062,10 @@
 
 						} else {
 							char *esc_value = tracker_escape_string (value);
-							sql = g_strdup_printf ("update ServiceTypes set  %s = '%s' where TypeID = %s", *array2, esc_value, str_id);
-							tracker_db_exec_no_reply (db_con, sql);
-							g_free (sql);
+
+							tracker_db_exec_no_reply (db_con,
+										  "update ServiceTypes set  %s = '%s' where TypeID = %s",
+										  *array2, esc_value, str_id);
 							g_free (esc_value);
 						}
 	
@@ -6244,16 +5167,14 @@
 char *
 tracker_db_get_option_string (DBConnection *db_con, const char *option)
 {
+	TrackerDBResultSet *result_set;
+	gchar *value = NULL;
 
-	char *value = "";
+	result_set = tracker_exec_proc (db_con->common, "GetOption", option, NULL);
 
-	gchar ***res = tracker_exec_proc (db_con->common, "GetOption", 1, option);
-
-	if (res) {
-		if (res[0] && res[0][0]) {
-			value = g_strdup (res[0][0]);
-		}
-		tracker_db_free_result (res);
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 0, &value, -1);
+		g_object_unref (result_set);
 	}
 
 	return value;
@@ -6263,23 +5184,28 @@
 void
 tracker_db_set_option_string (DBConnection *db_con, const char *option, const char *value)
 {
-	tracker_exec_proc (db_con->common, "SetOption", 2, value, option);
+	tracker_exec_proc (db_con->common, "SetOption", value, option, NULL);
 }
 
 
 int
 tracker_db_get_option_int (DBConnection *db_con, const char *option)
 {
-
+	TrackerDBResultSet *result_set;
+	gchar *str;
 	int value = 0;
 
-	gchar ***res = tracker_exec_proc (db_con->common, "GetOption", 1, option);
+	result_set = tracker_exec_proc (db_con->common, "GetOption", option, NULL);
 
-	if (res) {
-		if (res[0] && res[0][0]) {
-			value = atoi (res[0][0]);
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 0, &str, -1);
+
+		if (str) {
+			value = atoi (str);
+			g_free (str);
 		}
-		tracker_db_free_result (res);
+
+		g_object_unref (result_set);
 	}
 
 	return value;
@@ -6291,8 +5217,8 @@
 {
 	char *str_value = tracker_int_to_str (value);
 
-	tracker_exec_proc (db_con->common, "SetOption", 2, str_value, option);
-		
+	tracker_exec_proc (db_con->common, "SetOption", str_value, option, NULL);
+
 	g_free (str_value);
 }
 
@@ -6321,19 +5247,24 @@
 gboolean
 tracker_db_integrity_check (DBConnection *db_con)
 {
+	TrackerDBResultSet *result_set;
 	gboolean integrity_check = TRUE;
 
-	char ***res = tracker_exec_sql (db_con, "pragma integrity_check;");
+	result_set = tracker_db_interface_execute_query (db_con->db, NULL, "pragma integrity_check;");
 
-	if (!res) {
+	if (!result_set) {
 		integrity_check = FALSE;
 	} else {
+		gchar *check;
 
-		char **row = tracker_db_get_row (res, 0);
+		tracker_db_result_set_get (result_set, 0, &check, -1);
 
-		if (row && row[0]) {
-			integrity_check = (strcasecmp (row[0], "ok") == 0);
+		if (check) {
+			integrity_check = (strcasecmp (check, "ok") == 0);
+			g_free (check);
 		}
+
+		g_object_unref (result_set);
 	}
 
 	return integrity_check;

Modified: trunk/src/trackerd/tracker-db-sqlite.h
==============================================================================
--- trunk/src/trackerd/tracker-db-sqlite.h	(original)
+++ trunk/src/trackerd/tracker-db-sqlite.h	Mon Apr 21 13:32:35 2008
@@ -22,9 +22,9 @@
 #ifndef _TRACKER_SQLITE_DB_H_
 #define _TRACKER_SQLITE_DB_H_
 
-#include <sqlite3.h>
 #include <glib.h>
 
+#include "tracker-db-interface.h"
 #include "tracker-utils.h"
 #include "tracker-service-manager.h"
 
@@ -38,36 +38,33 @@
 
 
 
+typedef struct DBConnection DBConnection;
 
-
-typedef struct {
-	sqlite3		*db;
-	TrackerDBType    db_type;
+struct DBConnection {
+	TrackerDBInterface *db;
+	TrackerDBType   db_type;
 	DBCategory	db_category;
 	char		*err;
 	char		*name;
 	char		*file_name;
 	int		rc;
 	char		*thread; /* name of the thread that created this */
-	GHashTable	*statements;
 
 	guint           in_transaction : 1;
 	guint           in_error : 1;
 
 	/* pointers to other database connection objects */
-	gpointer	data;
-	gpointer	common;
-	gpointer	files;
-	gpointer	index;
-	gpointer	emails;
-	gpointer	others;
-	gpointer	blob;
-	gpointer	cache;
-	gpointer	user;
+	DBConnection	*data;
+	DBConnection	*common;
+	DBConnection	*files;
+	DBConnection	*index;
+	DBConnection	*emails;
+	DBConnection	*others;
+	DBConnection	*blob;
+	DBConnection	*cache;
+	DBConnection	*user;
 	gpointer	word_index;
-
-
-} DBConnection;
+};
 
 
 char **		tracker_db_get_row		(char ***result, int num);
@@ -79,7 +76,7 @@
 
 gboolean	tracker_db_needs_setup		(void);
 gboolean 	tracker_db_needs_data 		(void);
-gboolean	tracker_db_initialize		(const char *data_dir);
+gboolean        tracker_db_initialize           (void);
 void		tracker_db_thread_init		(void);
 void		tracker_db_thread_end		(void);
 void		tracker_db_close		(DBConnection *db_con);
@@ -103,12 +100,9 @@
 char *		tracker_escape_string		(const char *in);
 
 void		tracker_db_prepare_queries	(DBConnection *db_con);
-char ***	tracker_exec_proc		(DBConnection *db_con, const char *procedure, int param_count, ...);
-gboolean	tracker_exec_proc_no_reply 	(DBConnection *db_con, const char *procedure, int param_count, ...);
-char ***	tracker_exec_sql		(DBConnection *db_con, const char *query);
-char ***	tracker_exec_sql_ignore_nulls	(DBConnection *db_con, const char *query);
-gboolean	tracker_db_exec_no_reply 	(DBConnection *db_con, const char *query);
-void		tracker_log_sql			(DBConnection *db_con, const char *query);
+TrackerDBResultSet * tracker_exec_proc          (DBConnection *db_con, const char *procedure, ...);
+gboolean	tracker_exec_proc_no_reply 	(DBConnection *db_con, const char *procedure, ...);
+gboolean        tracker_db_exec_no_reply        (DBConnection *db_con, const char *query, ...);
 void		tracker_create_db		(void);
 void		tracker_db_load_stored_procs	(DBConnection *db_con);
 void		tracker_db_save_file_contents	(DBConnection *db_con, GHashTable *index_table, GHashTable *old_table, const char *file_name, FileInfo *info);
@@ -132,13 +126,13 @@
 char *		tracker_get_related_metadata_names 	(DBConnection *db_con, const char *name);
 char *		tracker_get_metadata_table 		(DataTypes type);
 
-char ***	tracker_db_search_text		(DBConnection *db_con, const char *service, const char *search_string, int offset, int limit, gboolean save_results, gboolean detailed);
-char ***	tracker_db_search_files_by_text	(DBConnection *db_con, const char *text, int offset, int limit, gboolean sort);
-char ***	tracker_db_search_metadata	(DBConnection *db_con, const char *service, const char *field, const char *text, int offset, int limit);
-char ***	tracker_db_search_matching_metadata (DBConnection *db_con, const char *service, const char *id, const char *text);
+TrackerDBResultSet * tracker_db_search_text		(DBConnection *db_con, const char *service, const char *search_string, int offset, int limit, gboolean save_results, gboolean detailed);
+TrackerDBResultSet * tracker_db_search_files_by_text	(DBConnection *db_con, const char *text, int offset, int limit, gboolean sort);
+TrackerDBResultSet * tracker_db_search_metadata	(DBConnection *db_con, const char *service, const char *field, const char *text, int offset, int limit);
+TrackerDBResultSet * tracker_db_search_matching_metadata (DBConnection *db_con, const char *service, const char *id, const char *text);
 
 /* gets metadata as a single row (with multiple values delimited by semicolons) */
-char ***	tracker_db_get_metadata		(DBConnection *db_con, const char *service, const char *id, const char *key);
+TrackerDBResultSet * tracker_db_get_metadata		(DBConnection *db_con, const char *service, const char *id, const char *key);
 
 /* gets metadata using a separate row for each value it has */
 char *		tracker_db_get_metadata_delimited (DBConnection *db_con, const char *service, const char *id, const char *key);
@@ -170,27 +164,27 @@
 
 gboolean	tracker_db_has_pending_files	(DBConnection *db_con);
 gboolean	tracker_db_has_pending_metadata	(DBConnection *db_con);
-char ***	tracker_db_get_pending_files	(DBConnection *db_con);
+TrackerDBResultSet * tracker_db_get_pending_files	(DBConnection *db_con);
 void		tracker_db_remove_pending_files	(DBConnection *db_con);
-char ***	tracker_db_get_pending_metadata	(DBConnection *db_con);
+TrackerDBResultSet * tracker_db_get_pending_metadata	(DBConnection *db_con);
 void		tracker_db_remove_pending_metadata (DBConnection *db_con);
 void		tracker_db_insert_pending	(DBConnection *db_con, const char *id, const char *action, const char *counter, const char *uri, const char *mime, gboolean is_dir, gboolean is_new, int service_type_id);
 void		tracker_db_update_pending	(DBConnection *db_con, const char *counter, const char *action, const char *uri);
 
-char ***	tracker_db_get_files_by_service	(DBConnection *db_con, const char *service, int offset, int limit);
-char ***	tracker_db_get_files_by_mime	(DBConnection *db_con, char **mimes, int n, int offset, int limit, gboolean vfs);
-char ***	tracker_db_search_text_mime	(DBConnection *db_con, const char *text, char **mime_array, int n);
-char ***	tracker_db_search_text_location	(DBConnection *db_con, const char *text,const char *location);
-char ***	tracker_db_search_text_mime_location (DBConnection *db_con, const char *text, char **mime_array, int n, const char *location);
+TrackerDBResultSet * tracker_db_get_files_by_service	(DBConnection *db_con, const char *service, int offset, int limit);
+TrackerDBResultSet * tracker_db_get_files_by_mime	(DBConnection *db_con, char **mimes, int n, int offset, int limit, gboolean vfs);
+TrackerDBResultSet * tracker_db_search_text_mime	(DBConnection *db_con, const char *text, char **mime_array);
+TrackerDBResultSet * tracker_db_search_text_location	(DBConnection *db_con, const char *text,const char *location);
+TrackerDBResultSet * tracker_db_search_text_mime_location (DBConnection *db_con, const char *text, char **mime_array, const char *location);
 
-char ***	tracker_db_get_file_subfolders	(DBConnection *db_con, const char *uri);
+TrackerDBResultSet * tracker_db_get_file_subfolders	(DBConnection *db_con, const char *uri);
 
-char ***	tracker_db_get_metadata_types	(DBConnection *db_con, const char *class, gboolean writeable);
+TrackerDBResultSet * tracker_db_get_metadata_types	(DBConnection *db_con, const char *class, gboolean writeable);
 
-char ***	tracker_db_get_sub_watches	(DBConnection *db_con, const char *dir);
-char ***	tracker_db_delete_sub_watches	(DBConnection *db_con, const char *dir);
+TrackerDBResultSet * tracker_db_get_sub_watches	(DBConnection *db_con, const char *dir);
+TrackerDBResultSet * tracker_db_delete_sub_watches	(DBConnection *db_con, const char *dir);
 
-char ***	tracker_db_get_keyword_list	(DBConnection *db_con, const char *service);
+TrackerDBResultSet * tracker_db_get_keyword_list	(DBConnection *db_con, const char *service);
 
 void		tracker_db_update_index_multiple_metadata 	(DBConnection *db_con, const char *service, const char *id, const char *key, char **values);
 

Modified: trunk/src/trackerd/tracker-db.c
==============================================================================
--- trunk/src/trackerd/tracker-db.c	(original)
+++ trunk/src/trackerd/tracker-db.c	Mon Apr 21 13:32:35 2008
@@ -61,8 +61,8 @@
 gboolean
 tracker_db_is_file_up_to_date (DBConnection *db_con, const char *uri, guint32 *id)
 {
+	TrackerDBResultSet *result_set;
 	char	*path, *name;
-	char	***res;
 	gint32	index_time;
 
 	g_return_val_if_fail (db_con, FALSE);
@@ -76,7 +76,7 @@
 		path = tracker_get_vfs_path (uri);
 	}
 
-	res = tracker_exec_proc (db_con, "GetServiceID", 2, path, name);
+	result_set = tracker_exec_proc (db_con, "GetServiceID", path, name, NULL);
 
 	g_free (path);
 	g_free (name);
@@ -84,32 +84,13 @@
 	index_time = 0;
 	*id = 0;
 
-	if (res) {
-		char **row;
-
-		row = tracker_db_get_row (res, 0);
-
-		if (row && row[0]) {
-			long long tmp_id;
-
-			tmp_id = atoll (row[0]);
-
-			if (tmp_id > G_MAXUINT32) {
-				tracker_error ("ERROR: file id is too big (> G_MAXUINT32)! Is database corrupted?");
-				tracker_db_free_result (res);
-				return FALSE;
-
-			} else {
-				*id = (guint32) tmp_id;
-			}
-		}
-
-		if (row && row[1]) {
-			index_time = atoi (row[1]);
-		}
-
-		tracker_db_free_result (res);
+	if (result_set) {
+		tracker_db_result_set_get (result_set,
+					   0, id,
+					   1, &index_time,
+					   -1);
 
+		g_object_unref (result_set);
 	} else {
 		return FALSE;
 	}
@@ -125,8 +106,8 @@
 guint32
 tracker_db_get_file_id (DBConnection *db_con, const char *uri)
 {
+	TrackerDBResultSet *result_set;
 	char	*path, *name;
-	char	***res;
 	guint32	id;
 
 	g_return_val_if_fail (db_con, 0);
@@ -140,23 +121,16 @@
 		path = tracker_get_vfs_path (uri);
 	}
 
-	res = tracker_exec_proc (db_con->index, "GetServiceID", 2, path, name);
+	result_set = tracker_exec_proc (db_con->index, "GetServiceID", path, name, NULL);
 
 	g_free (path);
 	g_free (name);
 
 	id = 0;
 
-	if (res) {
-		char **row;
-
-		row = tracker_db_get_row (res, 0);
-
-		if (row && row[0]) {
-			id = atoi (row[0]);
-		}
-
-		tracker_db_free_result (res);
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 0, &id, -1);
+		g_object_unref (result_set);
 	}
 
 	return id;
@@ -166,9 +140,8 @@
 FileInfo *
 tracker_db_get_file_info (DBConnection *db_con, FileInfo *info)
 {
-	char *path, *name;
-//	char *apath, *aname;
-	char ***res;
+	TrackerDBResultSet *result_set;
+	gchar *path, *name;
 
 	g_return_val_if_fail (db_con, info);
 	g_return_val_if_fail (info, info);
@@ -183,7 +156,7 @@
 	//apath = tracker_escape_string (path);
 	//aname = tracker_escape_string (name);
 
-	res = tracker_exec_proc (db_con->index, "GetServiceID", 2, path, name);
+	result_set = tracker_exec_proc (db_con->index, "GetServiceID", path, name, NULL);
 
 //	g_free (aname);
 //	g_free (apath);
@@ -191,30 +164,27 @@
 	g_free (name);
 	g_free (path);
 
-	if (res) {
-		char **row;
-
-		row = tracker_db_get_row (res, 0);
+	if (result_set) {
+		gint id, indextime, service_type_id;
+		gboolean is_directory;
+
+		tracker_db_result_set_get (result_set,
+					   0, &id,
+					   1, &indextime,
+					   2, &is_directory,
+					   3, &service_type_id,
+					   -1);
 
-		if (row && row[0]) {
-			info->file_id = atol (row[0]);
+		if (id > 0) {
+			info->file_id = id;
 			info->is_new = FALSE;
 		}
 
-		if (row && row[1]) {
-			info->indextime = atoi (row[1]);
-		}
-
-		if (row && row[2]) {
-			info->is_directory = (strcmp (row[2], "1") == 0) ;
-		}
-
-		if (row && row[3]) {
-			info->service_type_id = atoi (row[3]);
-		}
-
+		info->indextime = indextime;
+		info->is_directory = is_directory;
+		info->service_type_id = service_type_id;
 
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	return info;
@@ -316,7 +286,7 @@
 
 		small_thumb_file = tracker_escape_string (small_thumb);
 /* 		tracker_db_set_metadata (db_con, "Files", str_file_id, "File.SmallThumbnailPath", small_thumb_file, TRUE, FALSE, TRUE); */
-/* 		tracker_exec_proc (db_con, "SetMetadata", 5, "Files", str_file_id, "File.SmallThumbnailPath", small_thumb_file, "1"); */
+/* 		tracker_exec_proc (db_con, "SetMetadata", "Files", str_file_id, "File.SmallThumbnailPath", small_thumb_file, "1", NULL); */
 		g_free (small_thumb_file);
 	}
 
@@ -335,55 +305,40 @@
 char **
 tracker_db_get_files_in_folder (DBConnection *db_con, const char *folder_uri)
 {
-	char **array;
-	char ***res;
+	TrackerDBResultSet *result_set;
+	GPtrArray *array;
 
 	g_return_val_if_fail (db_con, NULL);
 	g_return_val_if_fail (db_con->index, NULL);
 	g_return_val_if_fail (folder_uri, NULL);
 	g_return_val_if_fail (folder_uri[0] != '\0', NULL);
 
-	res = tracker_exec_proc (db_con->index, "SelectFileChild", 1, folder_uri);
-
-	if (res) {
-		int row_count;
-
-		row_count = tracker_get_row_count (res);
+	result_set = tracker_exec_proc (db_con->index, "SelectFileChild", folder_uri, NULL);
+	array = g_ptr_array_new ();
 
-		if (row_count > 0) {
-			char	**row;
-			int	i;
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *name, *prefix;
 
-			array = g_new (char *, row_count + 1);
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   1, &prefix,
+						   2, &name,
+						   -1);
 
-			i = 0;
+			g_ptr_array_add (array, g_build_filename (prefix, name, NULL));
 
-			while ((row = tracker_db_get_row (res, i))) {
-
-				if (row[1] && row[2]) {
-					array[i] = g_build_filename (row[1], row[2], NULL);
-
-				} else {
-					array[i] = NULL;
-				}
-				i++;
-			}
-
-			array [row_count] = NULL;
-
-		} else {
-			array = g_new (char *, 1);
-			array[0] = NULL;
+			g_free (prefix);
+			g_free (name);
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
 
-		tracker_db_free_result (res);
-
-	} else {
-		array = g_new (char *, 1);
-		array[0] = NULL;
+		g_object_unref (result_set);
 	}
 
-	return array;
+	g_ptr_array_add (array, NULL);
+
+	return (gchar **) g_ptr_array_free (array, FALSE);
 }
 
 
@@ -413,29 +368,36 @@
 FileInfo *
 tracker_db_get_pending_file (DBConnection *db_con, const char *uri)
 {
+	TrackerDBResultSet *result_set;
 	FileInfo *info;
-	char	 ***res;
 
 	info = NULL;
+	result_set = tracker_exec_proc (db_con->cache, "SelectPendingByUri", uri, NULL);
 
-	res = tracker_exec_proc (db_con->cache, "SelectPendingByUri", 1, uri);
+	if (result_set) {
+		gboolean is_directory, is_new, extract_embedded, extract_contents;
+		gint counter, service_type_id;
+		gchar *mimetype;
+
+		tracker_db_result_set_get (result_set,
+					   2, &counter,
+					   3, &mimetype,
+					   4, &is_directory,
+					   5, &is_new,
+					   6, &extract_embedded,
+					   7, &extract_contents,
+					   8, &service_type_id,
+					   -1);
+
+		info = tracker_create_file_info (uri, counter, 0, 0);
+		info->mime = mimetype;
+		info->is_directory = is_directory;
+		info->is_new = is_new;
+		info->extract_embedded = extract_embedded;
+		info->extract_contents = extract_contents;
+		info->service_type_id = service_type_id;
 
-	if (res) {
-		char **row;
-
-		row = tracker_db_get_row (res, 0);
-
-		if (row && row[0] && row[1] && row[2] && row[3] && row[4] && row[5] && row[6] && row[7] && row[8]) {
-			info = tracker_create_file_info (uri, atoi (row[2]), 0, 0);
-			info->mime = g_strdup (row[3]);
-			info->is_directory = (strcmp (row[4], "1") == 0);
-			info->is_new = (strcmp (row[5], "1") == 0);
-			info->extract_embedded = (strcmp (row[6], "1") == 0);
-			info->extract_contents = (strcmp (row[7], "1") == 0);
-			info->service_type_id = atoi (row[8]);
-		}
-
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	return info;
@@ -964,9 +926,9 @@
 		old_table = tracker_db_get_indexable_content_words (db_con, info->file_id, old_table, TRUE);
 
 		/* delete any exisitng embedded metadata */
-		tracker_exec_proc (db_con, "DeleteEmbeddedServiceMetadata1", 1, str_file_id);
-		tracker_exec_proc (db_con, "DeleteEmbeddedServiceMetadata2", 1, str_file_id);
-		tracker_exec_proc (db_con, "DeleteEmbeddedServiceMetadata3", 1, str_file_id);
+		tracker_exec_proc (db_con, "DeleteEmbeddedServiceMetadata1", str_file_id, NULL);
+		tracker_exec_proc (db_con, "DeleteEmbeddedServiceMetadata2", str_file_id, NULL);
+		tracker_exec_proc (db_con, "DeleteEmbeddedServiceMetadata3", str_file_id, NULL);
 
 	}
 
@@ -991,35 +953,35 @@
 
 	/* check for backup user defined metadata */
 	if (info->is_new) {
-
+		TrackerDBResultSet *result_set;
 		char *name = tracker_get_vfs_name (info->uri);
 		char *path = tracker_get_vfs_path (info->uri);
 
-		char ***result_set = tracker_exec_proc (db_con->common, "GetBackupMetadata", 2, path, name); 
+		result_set = tracker_exec_proc (db_con->common, "GetBackupMetadata", path, name, NULL);
 
 		if (result_set) {
-			char **row;
-			int  k;
-
-			k = 0;
-			GHashTable *meta_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) free_metadata_list);
-
-			while ((row = tracker_db_get_row (result_set, k))) {
-
-				k++;
-
-				if (row[0] && row[1]) {
+			gboolean valid = TRUE;
+			GHashTable *meta_table;
+			DatabaseAction db_action;
+			gchar *key, *value;
 
-					tracker_add_metadata_to_table  (meta_table, g_strdup (row[0]), g_strdup (row[1]));
+			meta_table = g_hash_table_new_full (g_str_hash, g_str_equal,
+							    (GDestroyNotify) g_free,
+							    (GDestroyNotify) free_metadata_list);
+
+			while (valid) {
+				tracker_db_result_set_get (result_set,
+							   0, &key,
+							   1, &value,
+							   -1);
 
-					tracker_log ("found backup metadata for %s\%s with key %s and value %s", path, name, row[0], row[1]);
+				tracker_log ("found backup metadata for %s\%s with key %s and value %s", path, name, key, value);
+				tracker_add_metadata_to_table (meta_table, key, value);
 
-				}
+				valid = tracker_db_result_set_iter_next (result_set);
 			}
 
-			tracker_db_free_result (result_set);
-
-			DatabaseAction db_action;
+			g_object_unref (result_set);
 
 			db_action.db_con = db_con;
 			db_action.file_id = str_file_id;
@@ -1033,8 +995,6 @@
 			g_hash_table_foreach (meta_table, restore_backup_data, &db_action);	
 
 			g_hash_table_destroy (meta_table);
-					
-
 		}
 
 		g_free (name);

Modified: trunk/src/trackerd/tracker-dbus-files.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus-files.c	(original)
+++ trunk/src/trackerd/tracker-dbus-files.c	Mon Apr 21 13:32:35 2008
@@ -211,13 +211,13 @@
 void
 tracker_dbus_method_files_delete (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusMessage  *reply;
 	DBusError    dbus_error;
 	char	     *uri, *name, *path, *str_file_id;
 	guint32	     file_id;
 	gboolean     is_dir;
-	char	     ***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -256,18 +256,11 @@
 	str_file_id = tracker_uint_to_str (file_id);
 	is_dir = FALSE;
 
-	res = tracker_exec_proc (db_con, "GetServiceID", 2, path, name);
+	result_set = tracker_exec_proc (db_con, "GetServiceID", path, name, NULL);
 
-	if (res) {
-		char **row;
-
-		row = tracker_db_get_row (res, 0);
-
-		if (row && row[2] ) {
-			is_dir = (strcmp (row[2], "1") == 0);
-		}
-
-		tracker_db_free_result (res);
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 2, &is_dir, -1);
+		g_object_unref (result_set);
 	}
 
 	if (file_id != 0) {
@@ -360,12 +353,12 @@
 void
 tracker_dbus_method_files_get_text_contents (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	char	     *uri, *service_id;
 	int	     offset, max_length;
 	char 	     *str_offset, *str_max_length;
-	char 	     ***res;
 
 /*
 		<!-- Get the "File.Content" field for a file and allows you to specify the offset and amount of text to retrieve  -->
@@ -417,24 +410,23 @@
 	if (!service_id) {
 		g_free (service_id);
 		tracker_set_error (rec, "Unable to retrieve serviceID for uri %s", uri);
-		return;		
-	} 
-	
+		return;
+	}
+
 	str_offset = tracker_int_to_str (offset);
 	str_max_length = tracker_int_to_str (max_length);
-	res = tracker_exec_proc (db_con->blob, "GetFileContents", 
-				 3, str_offset, str_max_length, service_id);
+	result_set = tracker_exec_proc (db_con->blob, "GetFileContents",
+					str_offset, str_max_length, service_id, NULL);
 	g_free (str_offset);
 	g_free (str_max_length);
 	g_free (service_id);
 
 	const gchar *txt;
 
-	if (res && res[0][0]) {
-		txt = res[0][0];
-
+	if (result_set) {
 		DBusMessage *reply;
 
+		tracker_db_result_set_get (result_set, 0, &txt, -1);
 		reply = dbus_message_new_method_return (rec->message);
 
 		dbus_message_append_args (reply,
@@ -443,11 +435,10 @@
 
 		dbus_connection_send (rec->connection, reply, NULL);
 		dbus_message_unref (reply);
-		tracker_db_free_result (res);		
+		g_object_unref (result_set);
 	} else {
 		tracker_set_error (rec, "Contents of the URI not stored");
 	}
-	
 }
 
 
@@ -490,8 +481,8 @@
 	}
 
 	if (uri) {
+		TrackerDBResultSet *result_set = NULL;
 		char *path, *name, *str_max_length;
-		char ***res;
 
 
 		if (uri[0] == G_DIR_SEPARATOR) {
@@ -510,16 +501,13 @@
 		g_free (path);
 		g_free (name);
 
-		if (res) {
-			char **row;
+		if (result_set) {
+			char *result;
 
-			row = tracker_db_get_row (res, 0);
+			tracker_db_result_set_get (result_set, 0, &result, -1);
 
-			if (row && row[0]) {
+			if (result) {
 				DBusMessage *reply;
-				const char  *result;
-
-				result = row[0];
 
 				reply = dbus_message_new_method_return (rec->message);
 
@@ -529,9 +517,10 @@
 
 				dbus_connection_send (rec->connection, reply, NULL);
 				dbus_message_unref (reply);
+				g_free (result);
 			}
 
-			tracker_db_free_result (res);
+			g_object_unref (result_set);
 		}
 	}
 }
@@ -566,8 +555,8 @@
 	}
 
 	if (uri) {
+		TrackerDBResultSet *result_set;
 		char *path, *name;
-		char ***res;
 
 		if (uri[0] == G_DIR_SEPARATOR) {
 			name = g_path_get_basename (uri);
@@ -577,32 +566,27 @@
 			path = tracker_get_vfs_path (uri);
 		}
 
-		res = tracker_exec_proc (db_con, "GetFileMTime", 2, path, name);
+		result_set = tracker_exec_proc (db_con, "GetFileMTime", path, name, NULL);
 
 		g_free (path);
 		g_free (name);
 
-		if (res) {
-			char **row;
+		if (result_set) {
+			DBusMessage *reply;
+			int result;
 
-			row = tracker_db_get_row (res, 0);
+			tracker_db_result_set_get (result_set, 0, &result, -1);
 
-			if (row && row[0]) {
-				DBusMessage *reply;
-				int	    result;
+			reply = dbus_message_new_method_return (rec->message);
 
-				result = atoi (row[0]);
-				reply = dbus_message_new_method_return (rec->message);
+			dbus_message_append_args (reply,
+						  DBUS_TYPE_INT32, &result,
+						  DBUS_TYPE_INVALID);
 
-				dbus_message_append_args (reply,
-							  DBUS_TYPE_INT32, &result,
-							  DBUS_TYPE_INVALID);
-
-				dbus_connection_send (rec->connection, reply, NULL);
-				dbus_message_unref (reply);
-			}
+			dbus_connection_send (rec->connection, reply, NULL);
+			dbus_message_unref (reply);
 
-			tracker_db_free_result (res);
+			g_object_unref (result_set);
 		}
 	}
 }
@@ -611,13 +595,13 @@
 void
 tracker_dbus_method_files_get_by_service_type (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	int 	     query_id, limit, offset, row_count;
 	char 	     *service;
 	char 	     **array;
-	char	     ***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -654,14 +638,14 @@
 	}
 
 
-	res = tracker_db_get_files_by_service (db_con, service, offset, limit);
+	result_set = tracker_db_get_files_by_service (db_con, service, offset, limit);
 
 	array = NULL;
 	row_count = 0;
 
-	if (res) {
-		array = tracker_get_query_result_as_array (res, &row_count);
-		tracker_db_free_result (res);
+	if (result_set) {
+		array = tracker_get_query_result_as_array (result_set, &row_count);
+		g_object_unref (result_set);
 	}
 
 	reply = dbus_message_new_method_return (rec->message);
@@ -680,12 +664,12 @@
 void
 tracker_dbus_method_files_get_by_mime_type (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	int	     query_id, n, offset, limit, row_count;
 	char	     **array, **mimes;
-	char	     ***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -719,14 +703,14 @@
 		return;
 	}
 
-	res = tracker_db_get_files_by_mime (db_con, mimes, n, offset, limit, FALSE);
+	result_set = tracker_db_get_files_by_mime (db_con, mimes, n, offset, limit, FALSE);
 
 	array = NULL;
 	row_count = 0;
 
-	if (res) {
-		array = tracker_get_query_result_as_array (res, &row_count);
-		tracker_db_free_result (res);
+	if (result_set) {
+		array = tracker_get_query_result_as_array (result_set, &row_count);
+		g_object_unref (result_set);
 	}
 
 	reply = dbus_message_new_method_return (rec->message);
@@ -745,12 +729,12 @@
 void
 tracker_dbus_method_files_get_by_mime_type_vfs (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	int	     query_id, n, offset, limit, row_count;
 	char	     **array, **mimes;
-	char	     ***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -779,14 +763,14 @@
 		return;
 	}
 
-	res = tracker_db_get_files_by_mime (db_con, mimes, n, offset, limit, TRUE);
+	result_set = tracker_db_get_files_by_mime (db_con, mimes, n, offset, limit, TRUE);
 
 	array = NULL;
 	row_count = 0;
 
-	if (res) {
-		array = tracker_get_query_result_as_array (res, &row_count);
-		tracker_db_free_result (res);
+	if (result_set) {
+		array = tracker_get_query_result_as_array (result_set, &row_count);
+		g_object_unref (result_set);
 	}
 
 	reply = dbus_message_new_method_return (rec->message);
@@ -805,13 +789,13 @@
 void
 tracker_dbus_method_files_get_metadata_for_files_in_folder (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection	*db_con;
 	DBusError		dbus_error;
 	int		i, query_id, folder_name_len, file_id, n;
 	char		*tmp_folder, *folder, *str;
 	char		**array;
 	GString		*sql;
-	char		***res;
 	FieldDef	*defs[255];
 	gboolean 	needs_join[255];
 
@@ -922,26 +906,26 @@
 
 	tracker_debug (str);
 
-	res = tracker_exec_sql_ignore_nulls (db_con, str);
+	result_set = tracker_db_interface_execute_query (db_con->db, NULL, str);
 
 	g_free (str);
 
-	tracker_dbus_reply_with_query_result (rec, res);
+	tracker_dbus_reply_with_query_result (rec, result_set);
 
-	tracker_db_free_result (res);
+	g_object_unref (result_set);
 }
 
 
 void
 tracker_dbus_method_files_search_by_text_mime (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	char	     *str;
 	char	     **array;
 	int	     n, row_count;
-	char	     ***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -957,37 +941,34 @@
 		return;
 	}
 
-	res = tracker_db_search_text_mime (db_con, str, array, n);
+	result_set = tracker_db_search_text_mime (db_con, str, array);
 
 	array = NULL;
 	row_count = 0;
 
-	if (res) {
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *prefix, *name;
+		gint i = 0;
 
-		row_count = tracker_get_row_count (res);
+		row_count = tracker_db_result_set_get_n_rows (result_set);
+		array = g_new (gchar *, row_count);
 
-		if (row_count > 0) {
-			char **row;
-			int  i;
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   0, &prefix,
+						   1, &name,
+						   -1);
 
-			array = g_new (char *, row_count);
+			array[i] = g_build_filename (prefix, name, NULL);
+			valid = tracker_db_result_set_iter_next (result_set);
+			i++;
 
-			i = 0;
-
-			while ((row = tracker_db_get_row (res, i))) {
-
-				if (row && row[0] && row[1]) {
-					array[i] = g_build_filename (row[0], row[1], NULL);
-				}
-				i++;
-			}
-
-		} else {
-			tracker_log ("Result set is empty");
+			g_free (prefix);
+			g_free (name);
 		}
 
-		tracker_db_free_result (res);
-
+		g_object_unref (result_set);
 	} else {
 		array = g_new (char *, 1);
 
@@ -1011,13 +992,13 @@
 void
 tracker_dbus_method_files_search_by_text_location (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	char	     *str, *location;
 	char	     **array;
 	int	     row_count;
-	char	     ***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -1033,37 +1014,34 @@
 		return;
 	}
 
-	res = tracker_db_search_text_location (db_con, str, location);
+	result_set = tracker_db_search_text_location (db_con, str, location);
 
 	array = NULL;
 	row_count = 0;
 
-	if (res) {
-
-		row_count = tracker_get_row_count (res);
-
-		if (row_count > 0) {
-			char **row;
-			int  i;
-
-			array = g_new (char *, row_count);
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *prefix, *name;
+		gint i = 0;
 
-			i = 0;
+		row_count = tracker_db_result_set_get_n_rows (result_set);
+		array = g_new (char *, row_count);
 
-			while ((row = tracker_db_get_row (res, i))) {
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   0, &prefix,
+						   1, &name,
+						   -1);
 
-				if (row && row[0] && row[1]) {
-					array[i] = g_build_filename (row[0], row[1], NULL);
-				}
-				i++;
-			}
+			array[i] = g_build_filename (prefix, name, NULL);
+			valid = tracker_db_result_set_iter_next (result_set);
+			i++;
 
-		} else {
-			tracker_log ("Result set is empty");
+			g_free (prefix);
+			g_free (name);
 		}
 
-		tracker_db_free_result (res);
-
+		g_object_unref (result_set);
 	} else {
 		array = g_new (char *, 1);
 
@@ -1087,13 +1065,13 @@
 void
 tracker_dbus_method_files_search_by_text_mime_location (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	char	     *str, *location;
 	char	     **array;
 	int	     n, row_count;
-	char	     ***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -1110,37 +1088,34 @@
 		return;
 	}
 
-	res = tracker_db_search_text_mime_location (db_con, str, array, n, location);
+	result_set = tracker_db_search_text_mime_location (db_con, str, array, location);
 
 	array = NULL;
 	row_count = 0;
 
-	if (res) {
-
-		row_count = tracker_get_row_count (res);
-
-		if (row_count > 0) {
-			char **row;
-			int  i;
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *prefix, *name;
+		gint i = 0;
 
-			array = g_new (char *, row_count);
+		row_count = tracker_db_result_set_get_n_rows (result_set);
+		array = g_new (char *, row_count);
 
-			i = 0;
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   0, &prefix,
+						   1, &name,
+						   -1);
 
-			while ((row = tracker_db_get_row (res, i))) {
+			array[i] = g_build_filename (prefix, name, NULL);
+			valid = tracker_db_result_set_iter_next (result_set);
+			i++;
 
-				if (row && row[0] && row[1]) {
-					array[i] = g_build_filename (row[0], row[1], NULL);
-				}
-				i++;
-			}
-
-		} else {
-			tracker_log ("Result set is empty");
+			g_free (prefix);
+			g_free (name);
 		}
 
-		tracker_db_free_result (res);
-
+		g_object_unref (result_set);
 	} else {
 		array = g_new (char *, 1);
 

Modified: trunk/src/trackerd/tracker-dbus-keywords.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus-keywords.c	(original)
+++ trunk/src/trackerd/tracker-dbus-keywords.c	Mon Apr 21 13:32:35 2008
@@ -175,10 +175,10 @@
 void
 tracker_dbus_method_keywords_get_list (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection 	*db_con;
 	DBusError    dbus_error;
 	char 		*service;
-	char		***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -211,23 +211,23 @@
 
 	db_con = tracker_db_get_service_connection (db_con, service);
 
-	res = tracker_db_get_keyword_list (db_con, service);
+	result_set = tracker_db_get_keyword_list (db_con, service);
 
-	tracker_dbus_reply_with_query_result (rec, res);
+	tracker_dbus_reply_with_query_result (rec, result_set);
 
-	tracker_db_free_result (res);
+	g_object_unref (result_set);
 }
 
 
 void
 tracker_dbus_method_keywords_get (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection 	*db_con;
 	DBusError    dbus_error;
 	DBusMessage 	*reply;
 	char 		*id, *uri, *service;
 	char 		**array;
-	char		***res;
 	int 		row_count;
 
 	g_return_if_fail (rec && rec->user_data);
@@ -274,16 +274,16 @@
 
 	
 
-	res = tracker_db_get_metadata (db_con, service, id, "User:Keywords");
+	result_set = tracker_db_get_metadata (db_con, service, id, "User:Keywords");
 
 	g_free (id);
 
 	row_count = 0;
 	array = NULL;
 
-	if (res) {
-		array = tracker_get_query_result_as_array (res, &row_count);
-		tracker_db_free_result (res);
+	if (result_set) {
+		array = tracker_get_query_result_as_array (result_set, &row_count);
+		g_object_unref (result_set);
 	}
 
 	reply = dbus_message_new_method_return (rec->message);
@@ -521,13 +521,13 @@
 void
 tracker_dbus_method_keywords_search (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection 	*db_con;
 	DBusError    dbus_error;
 	DBusMessage 	*reply;
 	char 		*service;
 	char 		**array;
 	int 		row_count, limit, query_id, offset;
-	char		***res;
 	GString		*str_words, *str_select, *str_where;
 	char		*query_sel, *query_where, *query;
 	int		i;
@@ -631,7 +631,7 @@
 	query = g_strconcat (query_sel, query_where, NULL);
 
 	tracker_log (query);
-	res = tracker_exec_sql (db_con, query);
+	result_set = tracker_db_interface_execute_query (db_con->db, NULL, query);
 
 	g_free (query_sel);
 	g_free (query_where);
@@ -641,9 +641,9 @@
 	row_count = 0;
 	array = NULL;
 	
-	if (res) {
-		array = tracker_get_query_result_as_array (res, &row_count);
-		tracker_db_free_result (res);
+	if (result_set) {
+		array = tracker_get_query_result_as_array (result_set, &row_count);
+		g_object_unref (result_set);
 	}
 
 	reply = dbus_message_new_method_return (rec->message);

Modified: trunk/src/trackerd/tracker-dbus-metadata.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus-metadata.c	(original)
+++ trunk/src/trackerd/tracker-dbus-metadata.c	Mon Apr 21 13:32:35 2008
@@ -126,6 +126,7 @@
 void
 tracker_dbus_method_metadata_get (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection 	*db_con;
 	DBusError	dbus_error;
 	DBusMessage 	*reply;
@@ -133,7 +134,6 @@
 	char 		**keys, **array;
 	char		*uri, *id, *str, *service, *res_service;
 	GString 	*sql, *sql_join;
-	char		***res;
 
 
 	g_return_if_fail (rec && rec->user_data);
@@ -232,7 +232,7 @@
 
 	tracker_log (str);
 
-	res = tracker_exec_sql_ignore_nulls (db_con, str);
+	result_set = tracker_db_interface_execute_query (db_con->db, NULL, str);
 
 	g_free (str);
 	g_free (id);
@@ -242,43 +242,30 @@
 
 	row_count = 0;
 
-	if (res) {
+	if (result_set) {
+		GValue transform = { 0, };
 
-//		tracker_db_log_result (res);
+		row_count = key_count;
+		array = g_new (char *, key_count);
 
-		row_count = tracker_get_row_count (res);
+		g_value_init (&transform, G_TYPE_STRING);
 
-		i = 0;
+		for (i = 0; i < key_count; i++) {
+			GValue value = { 0, };
 
-		if (row_count > 0) {
-			char **row;
+			_tracker_db_result_set_get_value (result_set, i, &value);
 
-			array = g_new (char *, key_count);
-
-			row = tracker_db_get_row (res, 0);
-
-			for (i = 0; i < key_count; i++) {
-
-
-				if (row[i]) {
-					array[i] = g_strdup (row[i]);
-				} else {
-					array[i] = g_strdup ("");
-				}
+			if (g_value_transform (&value, &transform)) {
+				array[i] = g_value_dup_string (&transform);
+			} else {
+				array[i] = g_strdup ("");
 			}
 
-			row_count = key_count;
-
-		} else {
-			tracker_log ("Result set is empty");
-			row_count = 1;
-			array = g_new (char *, 1);
-			array[0] = g_strdup ("");
-
+			g_value_unset (&value);
+			g_value_reset (&transform);
 		}
 
-		tracker_db_free_result (res);
-
+		g_object_unref (result_set);
 	} else {
 		row_count = 1;
 		array = g_new (char *, 1);
@@ -339,7 +326,7 @@
 		return;
 	}
 
-	tracker_exec_proc (db_con, "InsertMetadataType", 4, meta, type_id, "0", "1");
+	tracker_exec_proc (db_con, "InsertMetadataType", meta, type_id, "0", "1", NULL);
 
 	reply = dbus_message_new_method_return (rec->message);
 
@@ -352,11 +339,13 @@
 void
 tracker_dbus_method_metadata_get_type_details (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	char	     *meta, *data_type;
 	gboolean     is_embedded, is_writable;
+	gint         id;
 
 /*
 		<method name="GetTypeDetails">
@@ -389,38 +378,21 @@
 		return;
 	}
 
-	char ***res;
+	result_set = tracker_exec_proc (db_con, "GetMetadataTypeInfo", meta, NULL);
 
-	res = tracker_exec_proc (db_con, "GetMetadataTypeInfo", 1, meta);
-
-	if (!res) {
+	if (!result_set) {
 		tracker_set_error (rec, "Unknown metadata type %s", meta);
 		return;
 	}
 
-	char **row;
-
-	row = tracker_db_get_row (res, 0);
-
-	if (!(row && row[1] && row[2] && row[3])) {
-		tracker_set_error (rec, "Bad info for metadata type %s", meta);
-		return;
-	}
-
-	int i;
-
-	i = atoi (row[1]);
-
-	if (i > 3 || i < 0) {
-		tracker_set_error (rec, "Bad info for metadata type %s", meta);
-		return;
-	}
-
-	data_type = type_array[i];
-	is_embedded = (strcmp (row[2], "1") == 0);
-	is_writable = (strcmp (row[3], "1") == 0);
+	tracker_db_result_set_get (result_set,
+				   1, &id,
+				   2, &is_embedded,
+				   3, &is_writable,
+				   -1);
 
-	tracker_db_free_result (res);
+	data_type = type_array[id];
+	g_object_unref (result_set);
 
 	reply = dbus_message_new_method_return (rec->message);
 
@@ -469,13 +441,13 @@
 	row_count = 0;
 
 	if (class) {
-		char ***res;
+		TrackerDBResultSet *result_set;
 
-		res = tracker_db_get_metadata_types (db_con, class, TRUE);
+		result_set = tracker_db_get_metadata_types (db_con, class, TRUE);
 
-		if (res) {
-			array = tracker_get_query_result_as_array (res, &row_count);
-			tracker_db_free_result (res);
+		if (result_set) {
+			array = tracker_get_query_result_as_array (result_set, &row_count);
+			g_object_unref (result_set);
 		}
 	}
 
@@ -528,17 +500,17 @@
 	row_count = 0;
 
 	if (class) {
-		char ***res;
+		TrackerDBResultSet *result_set;
 
 		class_formatted = g_strconcat (class, ".*", NULL);
 
-		res = tracker_db_get_metadata_types (db_con, class_formatted, TRUE);
+		result_set = tracker_db_get_metadata_types (db_con, class_formatted, TRUE);
 
 		g_free (class_formatted);
 
-		if (res) {
-			array = tracker_get_query_result_as_array (res, &row_count);
-			tracker_db_free_result (res);
+		if (result_set) {
+			array = tracker_get_query_result_as_array (result_set, &row_count);
+			g_object_unref (result_set);
 		}
 	}
 
@@ -558,11 +530,11 @@
 void
 tracker_dbus_method_metadata_get_registered_classes (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusMessage  *reply;
 	char	     **array;
 	int	     row_count;
-	char	     ***res;
 
 /*
 		<!-- returns an array of all metadata type classes that are registered -->
@@ -575,14 +547,14 @@
 
 	db_con = rec->user_data;
 
-	res = tracker_exec_proc (db_con, "SelectMetadataClasses", 0);
+	result_set = tracker_exec_proc (db_con, "SelectMetadataClasses", NULL);
 
 	array = NULL;
 	row_count = 0;
 
-	if (res) {
-		array = tracker_get_query_result_as_array (res, &row_count);
-		tracker_db_free_result (res);
+	if (result_set) {
+		array = tracker_get_query_result_as_array (result_set, &row_count);
+		g_object_unref (result_set);
 	}
 
 	reply = dbus_message_new_method_return (rec->message);

Modified: trunk/src/trackerd/tracker-dbus-methods.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus-methods.c	(original)
+++ trunk/src/trackerd/tracker-dbus-methods.c	Mon Apr 21 13:32:35 2008
@@ -67,35 +67,18 @@
 char *
 tracker_get_metadata (DBConnection *db_con, const char *service, const char *id, const char *key)
 {
-	char ***res;
+	TrackerDBResultSet *result_set;
 	char *value;
 
 	g_return_val_if_fail (db_con && !tracker_is_empty_string (id), NULL);
 
 	value = g_strdup (" ");
 
-	res = tracker_db_get_metadata (db_con, service, id, key);
+	result_set = tracker_db_get_metadata (db_con, service, id, key);
 
-	if (res) {
-		int  row_count;
-
-		row_count = tracker_get_row_count (res);
-
-		if (row_count > 0) {
-			char **row;
-
-			row = tracker_db_get_row (res, 0);
-
-			if (row && row[0]) {
-				g_free (value);
-				value = g_strdup (row[0]);
-			}
-
-		} else {
-			tracker_log ("Result set is empty");
-		}
-
-		tracker_db_free_result (res);
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 0, &value, -1);
+		g_object_unref (result_set);
 	}
 
 	tracker_log ("Metadata %s is %s", key, value);
@@ -158,16 +141,20 @@
 
 
 void
-tracker_dbus_reply_with_query_result (DBusRec *rec, char ***res)
+tracker_dbus_reply_with_query_result (DBusRec            *rec,
+				      TrackerDBResultSet *result_set)
 {
 	DBusMessage	*reply;
 	DBusMessageIter iter;
 	DBusMessageIter iter2;
-	char **row;
-	int  k;
+	gboolean valid = TRUE;
+	gint columns;
 
-	reply = dbus_message_new_method_return (rec->message);
+	if (result_set) {
+		columns = tracker_db_result_set_get_n_columns (result_set);
+	}
 
+	reply = dbus_message_new_method_return (rec->message);
 	dbus_message_iter_init_append (reply, &iter);
 
 	dbus_message_iter_open_container (&iter,
@@ -175,43 +162,41 @@
 					  "as",
 					  &iter2);
 
-	k = 0;
-
-	while ((row = tracker_db_get_row (res, k)) != NULL) {
-
+	while (result_set && valid) {
 		DBusMessageIter iter_array;
-		char 		**values;	
-
-		k++;
+		gint            i;
+		GValue          transform = { 0, };
 
+		g_value_init (&transform, G_TYPE_STRING);
 		dbus_message_iter_open_container (&iter2,
 						  DBUS_TYPE_ARRAY,
 						  DBUS_TYPE_STRING_AS_STRING,
 						  &iter_array);
 
 		/* append fields to the array */
-		for (values = row; *values; values++) {
-			char *value;
+		for (i = 0; i < columns; i++) {
+			GValue value = { 0, };
+			const gchar *str;
+
+			_tracker_db_result_set_get_value (result_set, i, &value);
 
-			if (!tracker_is_empty_string (*values)) {
-				value = *values;
-				//tracker_log (value);
+			if (g_value_transform (&value, &transform)) {
+				str = g_value_get_string (&transform);
 			} else {
-				/* dbus does not like NULLs */
-				value = " ";
+				str = "";
 			}
 
 			dbus_message_iter_append_basic (&iter_array,
 							DBUS_TYPE_STRING,
-							&value);
+							&str);
+			g_value_unset (&value);
+			g_value_reset (&transform);
 		}
 
-
 		dbus_message_iter_close_container (&iter2, &iter_array);
-
+		valid = tracker_db_result_set_iter_next (result_set);
 	}
 
-
 	dbus_message_iter_close_container (&iter, &iter2);
 	dbus_connection_send (rec->connection, reply, NULL);
 	dbus_message_unref (reply);
@@ -221,114 +206,89 @@
 
 
 void
-tracker_add_query_result_to_dict (char ***res, DBusMessageIter *iter_dict)
+tracker_add_query_result_to_dict (TrackerDBResultSet *result_set,
+				  DBusMessageIter    *iter_dict)
 {
-	int  row_count;
+	gint field_count;
+	gboolean valid = TRUE;
 
-	g_return_if_fail (res);
+	g_return_if_fail (result_set);
 
-	row_count = tracker_get_row_count (res);
+	field_count = tracker_db_result_set_get_n_columns (result_set);
 
-	if (row_count > 0) {
-		char **row;
-		int  field_count;
-		int  k;
+	while (valid) {
+		DBusMessageIter iter_dict_entry;
+		DBusMessageIter iter_var, iter_array;
+		char		*key;
+		int		i;
+		GValue          transform;
 
-		field_count = tracker_get_field_count (res);
+		g_value_init (&transform, G_TYPE_STRING);
+		tracker_db_result_set_get (result_set, 0, &key, -1);
 
-		k = 0;
+		dbus_message_iter_open_container (iter_dict,
+						  DBUS_TYPE_DICT_ENTRY,
+						  NULL,
+						  &iter_dict_entry);
 
-		while ((row = tracker_db_get_row (res, k)) != NULL) {
-			DBusMessageIter iter_dict_entry;
-			DBusMessageIter iter_var, iter_array;
-			char		*key;
-			int		i;
+		dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &key);
 
-			k++;
 
-			if (row[0]) {
-				key = row[0];
-			} else {
-				continue;
-			}
+		dbus_message_iter_open_container (&iter_dict_entry,
+						  DBUS_TYPE_VARIANT,
+						  DBUS_TYPE_ARRAY_AS_STRING
+						  DBUS_TYPE_STRING_AS_STRING,
+						  &iter_var);
+
+		dbus_message_iter_open_container (&iter_var,
+						  DBUS_TYPE_ARRAY,
+						  DBUS_TYPE_STRING_AS_STRING,
+						  &iter_array);
 
-			dbus_message_iter_open_container (iter_dict,
-						  	  DBUS_TYPE_DICT_ENTRY,
-						  	  NULL,
-							  &iter_dict_entry);
-
-			dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &key);
-
-
-			dbus_message_iter_open_container (&iter_dict_entry,
-							  DBUS_TYPE_VARIANT,
-							  DBUS_TYPE_ARRAY_AS_STRING
-							  DBUS_TYPE_STRING_AS_STRING,
-							  &iter_var);
-
-			dbus_message_iter_open_container (&iter_var,
-							  DBUS_TYPE_ARRAY,
-							  DBUS_TYPE_STRING_AS_STRING,
-							  &iter_array);
-
-			/* append additional fields to the variant */
-			for (i = 1; i < field_count; i++) {
-				char *value;
-
-				if (!tracker_is_empty_string (row[i])) {
-					value = g_strdup (row[i]);
-					} else {
-					/* dbus does not like NULLs */
-					value = g_strdup (" ");
-				}
-
-				dbus_message_iter_append_basic (&iter_array,
-								DBUS_TYPE_STRING,
-								&value);
+		/* append additional fields to the variant */
+		for (i = 1; i < field_count; i++) {
+			GValue value;
+			const gchar *str;
 
-				g_free (value);
+			_tracker_db_result_set_get_value (result_set, i, &value);
+
+			if (g_value_transform (&value, &transform)) {
+				str = g_value_get_string (&transform);
+			} else {
+				str = "";
 			}
 
-			dbus_message_iter_close_container (&iter_var, &iter_array);
-			dbus_message_iter_close_container (&iter_dict_entry, &iter_var);
-			dbus_message_iter_close_container (iter_dict, &iter_dict_entry);
+			dbus_message_iter_append_basic (&iter_array,
+							DBUS_TYPE_STRING,
+							&str);
+			g_value_unset (&value);
+			g_value_reset (&transform);
 		}
 
-	} else {
-		tracker_log ("Result set is empty");
+		dbus_message_iter_close_container (&iter_var, &iter_array);
+		dbus_message_iter_close_container (&iter_dict_entry, &iter_var);
+		dbus_message_iter_close_container (iter_dict, &iter_dict_entry);
+
+		valid = tracker_db_result_set_iter_next (result_set);
 	}
 }
 
 
 char **
-tracker_get_query_result_as_array (char ***res, int *row_count)
+tracker_get_query_result_as_array (TrackerDBResultSet *result_set,
+				   int                *row_count)
 {
+	gboolean valid = TRUE;
 	char **array;
+	gint i = 0;
 
-	*row_count = tracker_get_row_count (res);
+	*row_count = tracker_db_result_set_get_n_rows (result_set);
+	array = g_new (char *, *row_count);
 
-	if (*row_count > 0) {
-		char **row;
-		int  i;
-
-		array = g_new (char *, *row_count);
-
-		i = 0;
-
-		while ((row = tracker_db_get_row (res, i))) {
-
-			if (row && row[0]) {
-				array[i] = g_strdup (row[0]);
-			} else {
-				array[i] = NULL;
-			}
-			i++;
-		}
-
-	} else {
-		array = g_new (char *, 1);
-
-		array[0] = NULL;
+	while (valid) {
+		tracker_db_result_set_get (result_set, 0, &array[i], -1);
+		valid = tracker_db_result_set_iter_next (result_set);
+		i++;
 	}
 
 	return array;
@@ -338,13 +298,13 @@
 void
 tracker_dbus_method_get_services (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection	*db_con;
 	DBusError	dbus_error;
 	DBusMessage	*reply;
 	DBusMessageIter iter;
 	DBusMessageIter iter_dict;
 	gboolean	main_only;
-	char		***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -360,7 +320,7 @@
 		return;
 	}
 	
-	res = tracker_exec_proc (db_con, "GetServices", 0);
+	result_set = tracker_exec_proc (db_con, "GetServices", 0);
 
 	reply = dbus_message_new_method_return (rec->message);
 
@@ -374,9 +334,9 @@
 					  DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
 					  &iter_dict);
 
-	if (res) {
-		tracker_add_query_result_to_dict (res, &iter_dict);
-		tracker_db_free_result (res);
+	if (result_set) {
+		tracker_add_query_result_to_dict (result_set, &iter_dict);
+		g_object_unref (result_set);
 	}
 
 	dbus_message_iter_close_container (&iter, &iter_dict);
@@ -388,8 +348,8 @@
 void
 tracker_dbus_method_get_stats (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection	*db_con;
-	char		***res;
 
 	g_return_if_fail (rec && rec->user_data);
 
@@ -397,12 +357,11 @@
 
 	tracker_log ("Executing GetStats Dbus Call");
 
-	res = tracker_exec_proc (db_con, "GetStats", 0);
-	
-	tracker_dbus_reply_with_query_result (rec, res);
+	result_set = tracker_exec_proc (db_con, "GetStats", 0);
 
-	tracker_db_free_result (res);
+	tracker_dbus_reply_with_query_result (rec, result_set);
 
+	g_object_unref (result_set);
 }
 
 void

Modified: trunk/src/trackerd/tracker-dbus-methods.h
==============================================================================
--- trunk/src/trackerd/tracker-dbus-methods.h	(original)
+++ trunk/src/trackerd/tracker-dbus-methods.h	Mon Apr 21 13:32:35 2008
@@ -24,6 +24,7 @@
 
 #include "tracker-dbus.h"
 #include "tracker-db.h"
+#include "tracker-db-interface.h"
 
 
 void	tracker_set_error			(DBusRec *rec, const char *fmt, ...);
@@ -34,14 +35,14 @@
 
 guint32	tracker_get_file_id 			(DBConnection *db_con, const char *uri, gboolean create_record);
 
-void	tracker_dbus_reply_with_query_result 	(DBusRec *rec, char ***res);
+void	tracker_dbus_reply_with_query_result 	(DBusRec *rec, TrackerDBResultSet *result_set);
 
-void	tracker_add_query_result_to_dict 	(char ***res, DBusMessageIter *iter_dict);
+void	tracker_add_query_result_to_dict 	(TrackerDBResultSet *result_set, DBusMessageIter *iter_dict);
 
 char *	tracker_format_search_terms 		(const char *str, gboolean *do_bool_search);
 
 
-char **	tracker_get_query_result_as_array 	(char ***res, int *row_count);
+char **	tracker_get_query_result_as_array 	(TrackerDBResultSet *result_set, int *row_count);
 
 void	tracker_dbus_method_get_stats	 	(DBusRec *rec);
 void	tracker_dbus_method_get_status 		(DBusRec *rec);

Modified: trunk/src/trackerd/tracker-dbus-search.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus-search.c	(original)
+++ trunk/src/trackerd/tracker-dbus-search.c	Mon Apr 21 13:32:35 2008
@@ -135,11 +135,12 @@
 void
 tracker_dbus_method_search_get_hit_count_all (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set = NULL;
 	TrackerQueryTree *tree;
 	GArray       *hit_counts, *mail_hit_counts;
 	DBConnection *db_con;
 	DBusError    dbus_error;
-	gchar	     ***res, *str;
+	gchar	     *str;
 	guint        i;
 
 	g_return_if_fail (rec);
@@ -180,33 +181,47 @@
 	g_array_append_vals (hit_counts, mail_hit_counts->data, mail_hit_counts->len);
 	g_array_free (mail_hit_counts, TRUE);
 
-	res = g_new0 (gchar **, hit_counts->len + 1);
-
 	for (i = 0; i < hit_counts->len; i++) {
 		TrackerHitCount count;
-		gchar **elem;
+		GValue value = { 0, };
+
+		if (G_UNLIKELY (!result_set)) {
+			result_set = _tracker_db_result_set_new (2);
+		}
 
 		count = g_array_index (hit_counts, TrackerHitCount, i);
-		elem = g_new (char *, 3);
+		_tracker_db_result_set_append (result_set);
+
+		g_value_init (&value, G_TYPE_STRING);
+		g_value_take_string (&value, tracker_service_manager_get_service_by_id (count.service_type_id));
+		_tracker_db_result_set_set_value (result_set, 0, &value);
+		g_value_unset (&value);
 
-		elem[0] = tracker_service_manager_get_service_by_id (count.service_type_id);
-		elem[1] = tracker_uint_to_str (count.count);
-		elem[2] = NULL;
+		g_value_init (&value, G_TYPE_INT);
+		g_value_set_int (&value, count.count);
+		_tracker_db_result_set_set_value (result_set, 1, &value);
+		g_value_unset (&value);
+	}
 
-		res[i] = elem;
+	if (result_set) {
+		tracker_db_result_set_rewind (result_set);
 	}
 
-	tracker_dbus_reply_with_query_result (rec, res);
+	tracker_dbus_reply_with_query_result (rec, result_set);
 
-	tracker_db_free_result (res);
 	g_array_free (hit_counts, TRUE);
 	g_object_unref (tree);
+
+	if (result_set) {
+		g_object_unref (result_set);
+	}
 }
 
 
 void
 tracker_dbus_method_search_text (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
@@ -214,7 +229,6 @@
 	gint	     row_count, i;
 	gint	     limit, query_id, offset;
 	gchar	     *service;
-	gchar	     ***res;
 	gchar	     *str;
 
 	g_return_if_fail (rec);
@@ -270,36 +284,34 @@
 
 	db_con = tracker_db_get_service_connection (db_con, service);
 
-	res = tracker_db_search_text (db_con, service, str, offset, limit, FALSE, FALSE);
+	result_set = tracker_db_search_text (db_con, service, str, offset, limit, FALSE, FALSE);
 
 	row_count = 0;
 	array = NULL;
 
-	if (res) {
-
-		row_count = tracker_get_row_count (res);
-
-		if (row_count > 0) {
-			gchar **row;
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *prefix, *name;
+
+		row_count = tracker_db_result_set_get_n_rows (result_set);
+		array = g_new (gchar *, row_count);
+		i = 0;
+
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   0, &prefix,
+						   1, &name,
+						   -1);
+
+			array[i] = g_build_filename (prefix, name, NULL);
+			valid = tracker_db_result_set_iter_next (result_set);
+			i++;
 
-			array = g_new (gchar *, row_count);
-
-			i = 0;
-
-			while ((row = tracker_db_get_row (res, i))) {
-
-				if (row && row[0] && row[1]) {
-					array[i] = g_build_filename (row[0], row[1], NULL);
-				}
-				i++;
-			}
-
-		} else {
-			tracker_log ("search returned no results");
+			g_free (prefix);
+			g_free (name);
 		}
 
-		tracker_db_free_result (res);
-
+		g_object_unref (result_set);
 	} else {
 		array = g_new (gchar *, 1);
 		array[0] = NULL;
@@ -327,11 +339,11 @@
 void
 tracker_dbus_method_search_text_detailed (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	gint	     limit, query_id, offset;
 	gchar	     *service;
-	gchar	     ***res;
 	gchar	     *str;
 
 	g_return_if_fail (rec);
@@ -387,21 +399,26 @@
 
 	db_con = tracker_db_get_service_connection (db_con, service);
 
-	res = tracker_db_search_text (db_con, service, str, offset, limit, FALSE, TRUE);
+	result_set = tracker_db_search_text (db_con, service, str, offset, limit, FALSE, TRUE);
 
+	/*
 	if (tracker_config_get_verbosity (tracker->config) > 0) {
 		tracker_db_log_result (res);
 	}
+	*/
 
-	tracker_dbus_reply_with_query_result (rec, res);
+	tracker_dbus_reply_with_query_result (rec, result_set);
 
-	tracker_db_free_result (res);
+	if (result_set) {
+		g_object_unref (result_set);
+	}
 }
 
 
 void
 tracker_dbus_method_search_get_snippet (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
@@ -460,30 +477,24 @@
 		return;		
 	}
 
-	gchar ***res;
-	const gchar *txt;
-
 	snippet = NULL;
 
-	res = tracker_exec_proc (db_con->blob, "GetAllContents", 1, service_id);
+	result_set = tracker_exec_proc (db_con->blob, "GetAllContents", service_id, NULL);
 	g_free (service_id);
 	
-	if (res) {
-		if (res[0][0]) {
-			txt = res[0][0];
+	if (result_set) {
+		gchar **array, *text;
 
-			gchar **array = 	tracker_parse_text_into_array (str);
+		tracker_db_result_set_get (result_set, 0, &text, -1);
+		array = tracker_parse_text_into_array (str);
 
-			if (array && array[0]) {
-				snippet = tracker_get_snippet (txt, array, 120);
-			}
-
-			g_strfreev (array);
-
-			tracker_db_free_result (res);
-				
+		if (array && array[0]) {
+			snippet = tracker_get_snippet (text, array, 120);
 		}
-		
+
+		g_strfreev (array);
+		g_free (text);
+		g_object_unref (result_set);
 	}
 
 	/* do not pass NULL to dbus or it will crash */
@@ -509,6 +520,7 @@
 void
 tracker_dbus_method_search_files_by_text (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection 	*db_con;
 	DBusError    dbus_error;
 	DBusMessage 	*reply;
@@ -517,7 +529,6 @@
 	gchar 		*text;
 	gint		limit, query_id, offset;
 	gboolean	sort;
-	gchar		***res;
 
 	g_return_if_fail (rec);
 	g_return_if_fail (rec->user_data);
@@ -554,28 +565,25 @@
 		return;
 	}
 
-	res = tracker_db_search_files_by_text (db_con, text, offset, limit, sort);
+	result_set = tracker_db_search_files_by_text (db_con, text, offset, limit, sort);
 
-	if (res) {
+	if (!result_set)
+		return;
 
-		reply = dbus_message_new_method_return (rec->message);
+	reply = dbus_message_new_method_return (rec->message);
 
-		dbus_message_iter_init_append (reply, &iter);
+	dbus_message_iter_init_append (reply, &iter);
 
-		dbus_message_iter_open_container (&iter,
-						  DBUS_TYPE_ARRAY,
-						  DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-						  DBUS_TYPE_STRING_AS_STRING
-						  DBUS_TYPE_VARIANT_AS_STRING
-						  DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
-						  &iter_dict);
+	dbus_message_iter_open_container (&iter,
+					  DBUS_TYPE_ARRAY,
+					  DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+					  DBUS_TYPE_STRING_AS_STRING
+					  DBUS_TYPE_VARIANT_AS_STRING
+					  DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+					  &iter_dict);
 
-		tracker_add_query_result_to_dict (res, &iter_dict);
-		tracker_db_free_result (res);
-
-	} else {
-		return;
-	}
+	tracker_add_query_result_to_dict (result_set, &iter_dict);
+	g_object_unref (result_set);
 
 	dbus_message_iter_close_container (&iter, &iter_dict);
 	dbus_connection_send (rec->connection, reply, NULL);
@@ -586,13 +594,13 @@
 void
 tracker_dbus_method_search_metadata (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	DBusMessage  *reply;
 	gchar 	     *service, *field, *text;
 	gchar 	     **array;
 	gint 	     limit, row_count = 0, offset;
-	gchar	     ***res;
 
 	g_return_if_fail (rec);
 	g_return_if_fail (rec->user_data);
@@ -630,14 +638,14 @@
 		return;
 	}
 
-//	res = tracker_db_search_metadata (db_con, service, field, text, offset, limit);
-	res = NULL;
+//	result_set = tracker_db_search_metadata (db_con, service, field, text, offset, limit);
+	result_set = NULL;
 
 	array = NULL;
 
-	if (res) {
-		array = tracker_get_query_result_as_array (res, &row_count);
-		tracker_db_free_result (res);
+	if (result_set) {
+		array = tracker_get_query_result_as_array (result_set, &row_count);
+		g_object_unref (result_set);
 	}
 
 	reply = dbus_message_new_method_return (rec->message);
@@ -656,10 +664,10 @@
 void
 tracker_dbus_method_search_matching_fields (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection *db_con;
 	DBusError    dbus_error;
 	gchar 	     *text, *service, *id;
-	gchar	     ***res;
 
 	g_return_if_fail (rec);
 	g_return_if_fail (rec->user_data);
@@ -702,9 +710,9 @@
 		return;
 	}
 	db_con = tracker_db_get_service_connection (db_con, service);
-	res = tracker_db_search_matching_metadata (db_con, service, id, text);
+	result_set = tracker_db_search_matching_metadata (db_con, service, id, text);
 
-	if (res) {
+	if (result_set) {
 		DBusMessage	*reply;
 		DBusMessageIter iter;
 		DBusMessageIter iter_dict;
@@ -721,8 +729,8 @@
 						  DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
 						  &iter_dict);
 
-		tracker_add_query_result_to_dict (res, &iter_dict);
-		tracker_db_free_result (res);
+		tracker_add_query_result_to_dict (result_set, &iter_dict);
+		g_object_unref (result_set);
 
 		dbus_message_iter_close_container (&iter, &iter_dict);
 		dbus_connection_send (rec->connection, reply, NULL);
@@ -734,11 +742,11 @@
 void
 tracker_dbus_method_search_query (DBusRec *rec)
 {
+	TrackerDBResultSet *result_set;
 	DBConnection	*db_con;
 	DBusError    dbus_error;
 	gchar		**fields;
 	gint		limit, row_count, query_id, offset;
-	gchar		***res;
 	gchar		*query, *search_text, *service, *keyword;
 	gboolean	sort_results;
 
@@ -800,7 +808,7 @@
 		limit = 1024;
 	}
 
-	res = NULL;
+	result_set = NULL;
 
 	if (query) {
 		gchar	 *str;
@@ -845,7 +853,7 @@
 			tracker_db_search_text (db_con, service, search_text, 0, 999999, TRUE, FALSE);
 		}
 
-		res = tracker_exec_sql_ignore_nulls (db_con, str);
+		result_set = tracker_db_interface_execute_query (db_con->db, NULL, str);
 
 		g_free (str);
 
@@ -853,9 +861,9 @@
 		return;
 	}
 
-	tracker_dbus_reply_with_query_result (rec, res);
+	tracker_dbus_reply_with_query_result (rec, result_set);
 
-	tracker_db_free_result (res);
+	g_object_unref (result_set);
 }
 
 

Modified: trunk/src/trackerd/tracker-email-evolution.c
==============================================================================
--- trunk/src/trackerd/tracker-email-evolution.c	(original)
+++ trunk/src/trackerd/tracker-email-evolution.c	Mon Apr 21 13:32:35 2008
@@ -263,34 +263,41 @@
 void
 tracker_email_watch_emails (DBConnection *db_con)
 {
-	gchar ***res, **row;
-	gint  j;
+	TrackerDBResultSet *result_set;
 
 	/* if initial indexing has not finished reset mtime on all email stuff so they are rechecked */
 	if (tracker_db_get_option_int (db_con->common, "InitialIndex") == 1) {
 		char *sql = g_strdup_printf ("update Services set mtime = 0 where path like '%s/.evolution/%s'", g_get_home_dir (), "%");
 
-		tracker_exec_sql (db_con, sql);
+		tracker_db_interface_execute_query (db_con->db, NULL, sql);
 		g_free (sql);
 	}
 
 	/* check all registered mbox/paths for deletions */
-	res = tracker_db_email_get_mboxes (db_con);
+	result_set = tracker_db_email_get_mboxes (db_con);
 
-	for (j = 0; (row = tracker_db_get_row (res, j)); j++) {
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *filename, *path;
+		MailStore *store;
+
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   2, &filename,
+						   3, &path,
+						   -1);
 
-		if (row[2] && row[3]) {
-			MailStore *store = tracker_db_email_get_mbox_details (db_con, row[3]);
+			store = tracker_db_email_get_mbox_details (db_con, path);
 
 			if (store) {
-				check_summary_file (db_con, row[2], store);
+				check_summary_file (db_con, filename, store);
 				tracker_db_email_free_mail_store (store);
 			}
+
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
-	}
 
-	if (res) {
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	email_watch_directory (evolution_config->dir_local, "EvolutionEmails");

Modified: trunk/src/trackerd/tracker-email-modest.c
==============================================================================
--- trunk/src/trackerd/tracker-email-modest.c	(original)
+++ trunk/src/trackerd/tracker-email-modest.c	Mon Apr 21 13:32:35 2008
@@ -273,34 +273,41 @@
 void
 tracker_email_watch_emails (DBConnection *db_con)
 {
-	gchar ***res, **row;
-	gint  j;
+	TrackerDBResultSet *result_set;
 
 	/* if initial indexing has not finished reset mtime on all email stuff so they are rechecked */
 	if (tracker_db_get_option_int (db_con->common, "InitialIndex") == 1) {
 		char *sql = g_strdup_printf ("update Services set mtime = 0 where path like '%s/.modest/%s'", g_get_home_dir (), "%");
 
-		tracker_exec_sql (db_con, sql);
+		tracker_db_interface_execute_query (db_con->db, NULL, sql);
 		g_free (sql);
 	}
 
 	/* check all registered mbox/paths for deletions */
-	res = tracker_db_email_get_mboxes (db_con);
+	result_set = tracker_db_email_get_mboxes (db_con);
 
-	for (j = 0; (row = tracker_db_get_row (res, j)); j++) {
+	if (result_set) {
+		gboolean valid = TRUE;
+		gchar *filename, *path;
+		MailStore *store;
+
+		while (valid) {
+			tracker_db_result_set_get (result_set,
+						   2, &filename,
+						   3, &path,
+						   -1);
 
-		if (row[2] && row[3]) {
-			MailStore *store = tracker_db_email_get_mbox_details (db_con, row[3]);
+			store = tracker_db_email_get_mbox_details (db_con, path);
 
 			if (store) {
-				check_summary_file (db_con, row[2], store);
+				check_summary_file (db_con, filename, store);
 				tracker_db_email_free_mail_store (store);
 			}
+
+			valid = tracker_db_result_set_iter_next (result_set);
 		}
-	}
 
-	if (res) {
-		tracker_db_free_result (res);
+		g_object_unref (result_set);
 	}
 
 	email_watch_directories (modest_config->dirs, "ModestEmails");

Modified: trunk/src/trackerd/tracker-email.c
==============================================================================
--- trunk/src/trackerd/tracker-email.c	(original)
+++ trunk/src/trackerd/tracker-email.c	Mon Apr 21 13:32:35 2008
@@ -107,7 +107,7 @@
 	module = g_module_open (module_path, G_MODULE_BIND_LOCAL);
 
 	if (!module) {
-		g_warning ("Could not load EMail module: %s\n", module_name);
+		g_warning ("Could not load EMail module: %s , %s\n", module_name, g_module_error ());
 		g_free (module_name);
 		g_free (module_path);
 		return result;

Modified: trunk/src/trackerd/tracker-indexer.h
==============================================================================
--- trunk/src/trackerd/tracker-indexer.h	(original)
+++ trunk/src/trackerd/tracker-indexer.h	Mon Apr 21 13:32:35 2008
@@ -25,13 +25,14 @@
 
 #include <stdlib.h>
 #include <glib.h>
+#include "tracker-utils.h"
+#include "tracker-db-interface.h"
 
 typedef struct {                         /* type of structure for an element of search result */
 	guint32 	id;              /* Service ID number of the document */
 	int 		amalgamated;     /* amalgamation of service_type and score of the word in the document's metadata */
 } WordDetails;
 
-
 typedef enum {
 	WordNormal,
 	WordWildCard,

Modified: trunk/src/trackerd/tracker-inotify.c
==============================================================================
--- trunk/src/trackerd/tracker-inotify.c	(original)
+++ trunk/src/trackerd/tracker-inotify.c	Mon Apr 21 13:32:35 2008
@@ -60,8 +60,8 @@
 gboolean
 tracker_is_directory_watched (const char * dir, DBConnection *db_con)
 {
-	char ***res;
-	char **row;
+	TrackerDBResultSet *result_set;
+	gint id;
 
 	g_return_val_if_fail (dir != NULL && dir[0] == G_DIR_SEPARATOR, FALSE);
 
@@ -69,21 +69,16 @@
 		return FALSE;
 	}
 
-	res = tracker_exec_proc (db_con->cache, "GetWatchID", 1, dir);
+	result_set = tracker_exec_proc (db_con->cache, "GetWatchID", dir, NULL);
 
-	if (!res) {
+	if (!result_set) {
 		return FALSE;
 	}
 
-	row = tracker_db_get_row (res, 0);
+	tracker_db_result_set_get (result_set, 0, &id, -1);
+	g_object_unref (result_set);
 
-	if (!row || !row[0] || atoi (row[0]) < 0) {
-		tracker_db_free_result (res);
-		return FALSE;
-	}
-
-	tracker_db_free_result (res);
-	return TRUE;
+	return (id >= 0);
 }
 
 
@@ -322,11 +317,11 @@
 process_inotify_events (void)
 {
 	while (g_queue_get_length (inotify_queue) > 0) {
+		TrackerDBResultSet   *result_set;
 		TrackerChangeAction  action_type;
 		char		     *str = NULL, *filename = NULL, *monitor_name = NULL, *str_wd;
 		char		     *file_utf8_uri = NULL, *dir_utf8_uri = NULL;
 		guint		     cookie;
-		char		     ***res;
 
 		struct inotify_event *event;
 
@@ -359,31 +354,23 @@
 
 		str_wd = g_strdup_printf ("%d", event->wd);
 
-		res = tracker_exec_proc (main_thread_db_con->cache, "GetWatchUri", 1, str_wd);
+		result_set = tracker_exec_proc (main_thread_db_con->cache, "GetWatchUri", str_wd, NULL);
 
 		g_free (str_wd);
 
-		if (res) {
-			char **row;
+		if (result_set) {
+			tracker_db_result_set_get (result_set, 0, &monitor_name, -1);
+			g_object_unref (result_set);
 
-			row = tracker_db_get_row (res, 0);
-
-			if (row && row[0]) {
-				monitor_name = g_strdup (row[0]);
-			} else {
-				monitor_name = NULL;
+			if (!monitor_name) {
 				g_free (event);
 				continue;
 			}
-
-			tracker_db_free_result (res);
 		} else {
 			g_free (event);
 			continue;
 		}
 
-		
-
 		if (tracker_is_empty_string (filename)) {
 			//tracker_log ("WARNING: inotify event has no filename");
 			g_free (event);
@@ -578,7 +565,7 @@
 		}
 
 		str_wd = g_strdup_printf ("%d", wd);
-		tracker_exec_proc (db_con->cache, "InsertWatch", 2, dir, str_wd);
+		tracker_exec_proc (db_con->cache, "InsertWatch", dir, str_wd, NULL);
 		g_free (str_wd);
 		inotify_count++;
 		tracker_log ("Watching directory %s (total watches = %d)", dir, inotify_count);
@@ -594,33 +581,24 @@
 static gboolean
 delete_watch (const char *dir, DBConnection *db_con)
 {
-	char ***res;
-	int	    wd;
-	char  **row;
+	TrackerDBResultSet *result_set;
+	int wd;
 
 	g_return_val_if_fail (dir != NULL && dir[0] == G_DIR_SEPARATOR, FALSE);
 
-	res = tracker_exec_proc (db_con->cache, "GetWatchID", 1, dir);
+	result_set = tracker_exec_proc (db_con->cache, "GetWatchID", dir, NULL);
 
 	wd = -1;
 
-	if (!res) {
+	if (!result_set) {
 		tracker_log ("WARNING: watch id not found for uri %s", dir);
 		return FALSE;
 	}
 
-	row = tracker_db_get_row (res, 0);
+	tracker_db_result_set_get (result_set, 0, &wd, -1);
+	g_object_unref (result_set);
 
-	if (!row || !row[0]) {
-		tracker_log ("WARNING: watch id not found for uri %s", dir);
-		return FALSE;
-	}
-
-	wd = atoi (row[0]);
-
-	tracker_db_free_result (res);
-
-	tracker_exec_proc (db_con->cache, "DeleteWatch", 1, dir);
+	tracker_exec_proc (db_con->cache, "DeleteWatch", dir, NULL);
 
 	if (wd > -1) {
 		inotify_rm_watch (inotify_monitor_fd, wd);
@@ -634,10 +612,9 @@
 void
 tracker_remove_watch_dir (const char *dir, gboolean delete_subdirs, DBConnection *db_con)
 {
-	char ***res;
-	char **row;
-	int  k;
-	int  wd;
+	TrackerDBResultSet *result_set;
+	gboolean valid = TRUE;
+	int wd;
 
 	g_return_if_fail (dir != NULL && dir[0] == G_DIR_SEPARATOR);
 
@@ -647,17 +624,17 @@
 		return;
 	}
 
-	res = tracker_db_get_sub_watches (db_con, dir);
+	result_set = tracker_db_get_sub_watches (db_con, dir);
 
 	wd = -1;
 
-	if (!res) {
+	if (!result_set) {
 		return;
 	}
 
-	for (k = 0; (row = tracker_db_get_row (res, k)) && row[0]; k++) {
-
-		wd = atoi (row[0]);
+	while (valid) {
+		tracker_db_result_set_get (result_set, 0, &wd, -1);
+		valid = tracker_db_result_set_iter_next (result_set);
 
 		if (wd < 0) {
 			continue;
@@ -667,8 +644,7 @@
 		inotify_count--;
 	}
 
-	tracker_db_free_result (res);
-
+	g_object_unref (result_set);
 	tracker_db_delete_sub_watches (db_con, dir);
 }
 

Modified: trunk/src/trackerd/tracker-process-files.c
==============================================================================
--- trunk/src/trackerd/tracker-process-files.c	(original)
+++ trunk/src/trackerd/tracker-process-files.c	Mon Apr 21 13:32:35 2008
@@ -647,14 +647,14 @@
         db_con = tracker->index_db;
 
         tracker_db_start_index_transaction (db_con);
-        tracker_db_start_transaction (db_con->cache);
+        tracker_db_interface_start_transaction (db_con->cache->db);
         
         tracker_applications_add_service_directories ();
         
         list = tracker_get_service_dirs ("Applications");
         process_directory_list (tracker, list, FALSE);
 
-        tracker_db_end_transaction (db_con->cache);
+        tracker_db_interface_end_transaction (db_con->cache->db);
         
         g_slist_free (list);
 }
@@ -811,7 +811,7 @@
                 return;
         }
         
-        tracker_db_start_transaction (db_con->cache);
+        tracker_db_interface_start_transaction (db_con->cache->db);
         
         /* Index watched dirs first */
         process_watch_directories (tracker, index_include);
@@ -840,7 +840,7 @@
                 crawl_directories = NULL;
         }
         
-        tracker_db_end_transaction (db_con->cache);
+        tracker_db_interface_end_transaction (db_con->cache->db);
         tracker_dbus_send_index_progress_signal ("Files", "");
 
         g_slist_free (index_include);
@@ -910,7 +910,7 @@
                 return;
         }
         
-        tracker_db_start_transaction (db_con->cache);
+        tracker_db_interface_start_transaction (db_con->cache->db);
         
         process_index_crawl_add_directories (tracker, crawl_directory_roots);
         
@@ -934,7 +934,7 @@
                 crawl_directories = NULL;
         }
         
-        tracker_db_end_transaction (db_con->cache);
+        tracker_db_interface_end_transaction (db_con->cache->db);
 }
 
 static void
@@ -965,9 +965,9 @@
                 db_con = tracker->index_db;
 
                 tracker_log ("Starting chat log indexing...");
-                tracker_db_start_transaction (db_con->cache);
+                tracker_db_interface_start_transaction (db_con->cache->db);
                 process_directory_list (tracker, list, TRUE);
-                tracker_db_end_transaction (db_con->cache);
+                tracker_db_interface_end_transaction (db_con->cache->db);
                 g_slist_free (list);
         }
         
@@ -993,9 +993,9 @@
                 tracker_log ("Starting Firefox web history indexing...");
                 tracker_add_service_path ("WebHistory", firefox_dir);
                 
-                tracker_db_start_transaction (db_con->cache);		
+                tracker_db_interface_start_transaction (db_con->cache->db);
                 process_directory_list (tracker, list, TRUE);
-                tracker_db_end_transaction (db_con->cache);
+                tracker_db_interface_end_transaction (db_con->cache->db);
                 g_slist_free (list);
         }
 
@@ -1036,7 +1036,7 @@
                 tracker_email_add_service_directories (db_con->emails);
                 tracker_log ("Starting email indexing...");
                 
-                tracker_db_start_transaction (db_con->cache);
+                tracker_db_interface_start_transaction (db_con->cache->db);
 
 		name = tracker_email_get_name ();
 
@@ -1048,7 +1048,7 @@
                         g_slist_free (list);
                 }
                 
-                tracker_db_end_transaction (db_con->cache);
+                tracker_db_interface_end_transaction (db_con->cache->db);
         }
 }
 
@@ -1155,13 +1155,13 @@
                 
                 tracker_log ("Updating database stats, please wait...");
                 
-                tracker_db_start_transaction (db_con);
+                tracker_db_interface_start_transaction (db_con->db);
                 tracker_db_exec_no_reply (db_con, "ANALYZE");
-                tracker_db_end_transaction (db_con);
+                tracker_db_interface_end_transaction (db_con->db);
                 
-                tracker_db_start_transaction (db_con->emails);
+                tracker_db_interface_start_transaction (db_con->emails->db);
                 tracker_db_exec_no_reply (db_con->emails, "ANALYZE");
-                tracker_db_end_transaction (db_con->emails);
+                tracker_db_interface_end_transaction (db_con->emails->db);
                 
                 tracker_log ("Finished optimizing, waiting for new events...");
         }
@@ -1502,7 +1502,7 @@
 
 		/* Check pending table if we haven't got anything */
 		if (!info) {
-			gchar ***res;
+			TrackerDBResultSet *result_set;
 			gint     k;
 
 			if (!tracker_db_has_pending_files (tracker->index_db)) {
@@ -1522,35 +1522,40 @@
                                 }
                         }
 
-			res = tracker_db_get_pending_files (tracker->index_db);
+			result_set = tracker_db_get_pending_files (tracker->index_db);
 
 			k = 0;
 			pushed_events = FALSE;
 
-			if (res) {
-				gchar **row;
+			if (result_set) {
+				gboolean is_valid = TRUE;
 
 				tracker_set_status (tracker, STATUS_PENDING, 0, FALSE);
 
-				while ((row = tracker_db_get_row (res, k))) {
+				while (is_valid) {
 					FileInfo	    *info_tmp;
 					TrackerChangeAction  tmp_action;
+					gchar               *uri;
 
 					if (!tracker->is_running) {
-						tracker_db_free_result (res);
+						g_object_unref (result_set);
 						break;
 					}
 
-					k++;
+					tracker_db_result_set_get (result_set,
+								   1, &uri,
+								   2, &tmp_action,
+								   -1);
 
-					tmp_action = atoi (row[2]);
-
-					info_tmp = tracker_create_file_info (row[1], tmp_action, 0, WATCH_OTHER);
+					info_tmp = tracker_create_file_info (uri, tmp_action, 0, WATCH_OTHER);
 					g_async_queue_push (tracker->file_process_queue, info_tmp);
+					is_valid = tracker_db_result_set_iter_next (result_set);
 					pushed_events = TRUE;
+
+					g_free (uri);
 				}
 
-				tracker_db_free_result (res);
+				g_object_unref (result_set);
 			}
 
 			if (!tracker->is_running) {
@@ -1564,7 +1569,7 @@
                          * should sleep for 100ms (only occurs when
                          * using FAM or inotify move/create). 
                          */
-			if (!pushed_events && k == 0) {
+			if (!pushed_events) {
 				g_usleep (100000);
 			}
 
@@ -1606,7 +1611,6 @@
 	xdg_mime_shutdown ();
 
 	tracker_db_close_all (tracker->index_db);
-	tracker_db_thread_end ();
 
 	g_mutex_unlock (tracker->files_stopped_mutex);
 

Modified: trunk/src/trackerd/tracker-process-requests.c
==============================================================================
--- trunk/src/trackerd/tracker-process-requests.c	(original)
+++ trunk/src/trackerd/tracker-process-requests.c	Mon Apr 21 13:32:35 2008
@@ -392,7 +392,6 @@
 	}
 
 	tracker_db_close_all (db_con);
-        tracker_db_thread_end ();
 
 	tracker_debug ("Request thread has exited successfully");
 

Modified: trunk/src/trackerd/trackerd.c
==============================================================================
--- trunk/src/trackerd/trackerd.c	(original)
+++ trunk/src/trackerd/trackerd.c	Mon Apr 21 13:32:35 2008
@@ -135,15 +135,21 @@
 static gint
 get_update_count (DBConnection *db_con)
 {
-
+	TrackerDBResultSet *result_set;
+	gchar *str;
 	gint  count = 0;
-	gchar ***res = tracker_exec_proc (db_con, "GetUpdateCount", 0);
 
-	if (res) {
-		if (res[0] && res[0][0]) {
-			count = atoi (res[0][0]);
-		}
-		tracker_db_free_result (res);
+	result_set = tracker_exec_proc (db_con, "GetUpdateCount", NULL);
+
+	if (result_set) {
+		tracker_db_result_set_get (result_set, 0, &str, -1);
+
+		if (str) {
+			count = atoi (str);
+                }
+
+		g_free (str);
+		g_object_unref (result_set);
 	}
 
 	return count;
@@ -190,7 +196,7 @@
 	tracker_log ("resetting black list file %s", uri);
 
 	/* reset mtime on parent folder of all outstanding black list files so they get indexed when next restarted */
-	tracker_exec_proc (main_thread_db_con, "UpdateFileMTime", 3, "0", parent_path, parent_name);
+	tracker_exec_proc (main_thread_db_con, "UpdateFileMTime", "0", parent_path, parent_name, NULL);
 
 	g_free (parent);
 	g_free (parent_name);
@@ -922,7 +928,7 @@
 	/* set thread safe DB connection */
 	tracker_db_thread_init ();
 
-	if (!tracker_db_initialize (tracker->data_dir)) {
+	if (!tracker_db_initialize ()) {
 		tracker_log ("ERROR: failed to initialise database engine - exiting...");
 		return 1;
 	}



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