[tracker/journal-compression-review: 3/12] libtracker-db: Support for moving rotated chunks to another location



commit 47e7dd1858221fb4fe46e6252d4a74f8a08a6114
Author: Philip Van Hoof <philip codeminded be>
Date:   Mon May 10 17:51:48 2010 +0200

    libtracker-db: Support for moving rotated chunks to another location

 src/libtracker-common/tracker-keyfile-object.c    |   21 +
 src/libtracker-common/tracker-keyfile-object.h    |    2 +
 src/libtracker-data/tracker-data-backup.c         |    8 +-
 src/libtracker-data/tracker-data-manager.c        |    8 +-
 src/libtracker-data/tracker-data-manager.h        |   74 +-
 src/libtracker-data/tracker-data-update.c         |    6 +-
 src/libtracker-db/Makefile.am                     |    6 +-
 src/libtracker-db/tracker-db-config.c             |  400 ++++++++
 src/libtracker-db/tracker-db-config.h             |   70 ++
 src/libtracker-db/tracker-db-journal.c            | 1048 ++++++++++++---------
 src/libtracker-db/tracker-db-journal.h            |   15 +-
 src/libtracker-db/tracker-db-manager.c            |  220 +++--
 src/libtracker-db/tracker-db.h                    |    1 +
 src/tracker-control/tracker-control.c             |   19 +-
 src/tracker-store/tracker-config.c                |   63 +--
 src/tracker-store/tracker-config.h                |    3 -
 src/tracker-store/tracker-main.c                  |   21 +-
 tests/libtracker-data/tracker-backup-test.c       |    6 +-
 tests/libtracker-data/tracker-ontology-test.c     |   18 +-
 tests/libtracker-data/tracker-sparql-blank-test.c |    3 +-
 tests/libtracker-data/tracker-sparql-test.c       |    4 +-
 tests/libtracker-db/tracker-db-journal.c          |   11 +-
 tests/libtracker-fts/tracker-fts-test.c           |    2 +-
 23 files changed, 1377 insertions(+), 652 deletions(-)
---
diff --git a/src/libtracker-common/tracker-keyfile-object.c b/src/libtracker-common/tracker-keyfile-object.c
index 422eb0a..8db76f8 100644
--- a/src/libtracker-common/tracker-keyfile-object.c
+++ b/src/libtracker-common/tracker-keyfile-object.c
@@ -93,6 +93,27 @@ tracker_keyfile_object_default_boolean (gpointer     object,
 	return bspec->default_value;
 }
 
+const gchar*
+tracker_keyfile_object_default_string (gpointer     object,
+                                       const gchar *property)
+{
+	GObjectClass *klass;
+	GParamSpec *spec;
+	GParamSpecString *bspec;
+
+	g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
+	g_return_val_if_fail (property != NULL, FALSE);
+
+	klass = G_OBJECT_GET_CLASS (object);
+	spec = g_object_class_find_property (G_OBJECT_CLASS (klass), property);
+	g_return_val_if_fail (spec != NULL, FALSE);
+
+	bspec = G_PARAM_SPEC_STRING (spec);
+	g_return_val_if_fail (bspec != NULL, FALSE);
+
+	return bspec->default_value;
+}
+
 gint
 tracker_keyfile_object_default_int (gpointer     object,
                                     const gchar *property)
diff --git a/src/libtracker-common/tracker-keyfile-object.h b/src/libtracker-common/tracker-keyfile-object.h
index c06cfcb..18135ab 100644
--- a/src/libtracker-common/tracker-keyfile-object.h
+++ b/src/libtracker-common/tracker-keyfile-object.h
@@ -34,6 +34,8 @@ gboolean     tracker_keyfile_object_default_boolean  (gpointer      object,
                                                       const gchar  *property);
 gint         tracker_keyfile_object_default_int      (gpointer      object,
                                                       const gchar  *property);
+const gchar* tracker_keyfile_object_default_string   (gpointer      object,
+                                                      const gchar  *property);
 gboolean     tracker_keyfile_object_validate_int     (gpointer      object,
                                                       const gchar  *property,
                                                       gint          value);
diff --git a/src/libtracker-data/tracker-data-backup.c b/src/libtracker-data/tracker-data-backup.c
index f08f4d0..c92744e 100644
--- a/src/libtracker-data/tracker-data-backup.c
+++ b/src/libtracker-data/tracker-data-backup.c
@@ -347,8 +347,6 @@ tracker_data_backup_restore (GFile *journal,
 	if (g_file_query_exists (info->journal, NULL)) {
 		TrackerDBManagerFlags flags = tracker_db_manager_get_flags ();
 		gboolean is_first;
-		gsize chunk_size = 0;
-		gboolean do_rotating = FALSE;
 		GFile *parent = g_file_get_parent (info->destination);
 		gchar *tmp_stdout = NULL;
 		gchar *tmp_stderr = NULL;
@@ -393,8 +391,7 @@ tracker_data_backup_restore (GFile *journal,
 		g_strfreev (argv);
 
 		tracker_db_manager_init_locations ();
-		tracker_db_journal_get_rotating (&do_rotating, &chunk_size);
-		tracker_db_journal_init (NULL, FALSE, do_rotating, chunk_size);
+		tracker_db_journal_init (NULL, FALSE);
 
 		if (info->error) {
 			tracker_db_manager_restore_from_temp ();
@@ -404,8 +401,7 @@ tracker_data_backup_restore (GFile *journal,
 
 		tracker_db_journal_shutdown ();
 
-		tracker_data_manager_init (flags, do_rotating, chunk_size,
-		                           test_schemas, &is_first, TRUE,
+		tracker_data_manager_init (flags, test_schemas, &is_first, TRUE,
 		                           busy_callback, busy_user_data,
 		                           "Restoring backup");
 
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index c178414..359d253 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -2241,8 +2241,6 @@ get_new_service_id (TrackerDBInterface *iface)
 
 gboolean
 tracker_data_manager_init (TrackerDBManagerFlags  flags,
-                           gboolean               do_journal_rotating,
-                           gsize                  chunk_size,
                            const gchar          **test_schemas,
                            gboolean              *first_time,
                            gboolean               journal_check,
@@ -2334,7 +2332,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		in_journal_replay = FALSE;
 
 		/* open journal for writing */
-		tracker_db_journal_init (NULL, FALSE, do_journal_rotating, chunk_size);
+		tracker_db_journal_init (NULL, FALSE);
 
 		check_ontology = TRUE;
 
@@ -2347,7 +2345,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		/* Truncate journal as it does not even contain a single valid transaction
 		 * or is explicitly ignored (journal_check == FALSE, only for test cases) */
-		tracker_db_journal_init (NULL, TRUE, do_journal_rotating, chunk_size);
+		tracker_db_journal_init (NULL, TRUE);
 
 		/* load ontology from files into memory (max_id starts at zero: first-time) */
 
@@ -2408,7 +2406,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		/* First time, no need to check ontology */
 		check_ontology = FALSE;
 	} else {
-		tracker_db_journal_init (NULL, FALSE, do_journal_rotating, chunk_size);
+		tracker_db_journal_init (NULL, FALSE);
 
 		/* Load ontology from database into memory */
 		db_get_static_data (iface);
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index a98e263..e83d6c7 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -39,44 +39,42 @@ G_BEGIN_DECLS
 #error "only <libtracker-data/tracker-data.h> must be included directly."
 #endif
 
-gboolean tracker_data_manager_init                   (TrackerDBManagerFlags  flags,
-                                                      gboolean               do_journal_rotating,
-                                                      gsize                  chunk_size,
-                                                      const gchar          **test_schema,
-                                                      gboolean              *first_time,
-                                                      gboolean               journal_check,
-                                                      TrackerBusyCallback    busy_callback,
-                                                      gpointer               busy_user_data,
-                                                      const gchar           *busy_status);
-void     tracker_data_manager_shutdown               (void);
-gboolean tracker_data_manager_interrupt_thread       (GThread               *thread);
-void     tracker_data_manager_interrupt_thread_reset (GThread               *thread);
-gint64   tracker_data_manager_get_db_option_int64    (const gchar           *option);
-void     tracker_data_manager_set_db_option_int64    (const gchar           *option,
-                                                      gint64                 value);
-void     tracker_data_ontology_load_statement        (const gchar           *ontology_file,
-                                                      gint                   subject_id,
-                                                      const gchar           *subject,
-                                                      const gchar           *predicate,
-                                                      const gchar           *object,
-                                                      gint                  *max_id,
-                                                      gboolean               in_update,
-                                                      GHashTable            *classes,
-                                                      GHashTable            *properties,
-                                                      GPtrArray             *seen_classes,
-                                                      GPtrArray             *seen_properties);
-void     tracker_data_ontology_import_into_db        (gboolean               is_new);
-void     tracker_data_ontology_process_statement     (const gchar           *graph,
-                                                      const gchar           *subject,
-                                                      const gchar           *predicate,
-                                                      const gchar           *object,
-                                                      gboolean               is_uri,
-                                                      gboolean               in_update,
-                                                      gboolean               ignore_nao_last_modified);
-void    tracker_data_ontology_import_finished        (void);
-void    tracker_data_ontology_process_changes        (GPtrArray             *seen_classes,
-                                                      GPtrArray             *seen_properties);
-void    tracker_data_ontology_free_seen              (GPtrArray             *seen);
+gboolean tracker_data_manager_init                (TrackerDBManagerFlags  flags,
+                                                   const gchar          **test_schema,
+                                                   gboolean              *first_time,
+                                                   gboolean               journal_check,
+                                                   TrackerBusyCallback    busy_callback,
+                                                   gpointer               busy_user_data,
+                                                   const gchar           *busy_status);
+void     tracker_data_manager_shutdown            (void);
+gboolean tracker_data_manager_interrupt_thread    (GThread               *thread);
+
+gint64   tracker_data_manager_get_db_option_int64 (const gchar           *option);
+void     tracker_data_manager_set_db_option_int64 (const gchar           *option,
+                                                   gint64                 value);
+void     tracker_data_ontology_load_statement     (const gchar           *ontology_file,
+                                                   gint                   subject_id,
+                                                   const gchar           *subject,
+                                                   const gchar           *predicate,
+                                                   const gchar           *object,
+                                                   gint                  *max_id,
+                                                   gboolean               in_update,
+                                                   GHashTable            *classes,
+                                                   GHashTable            *properties,
+                                                   GPtrArray             *seen_classes,
+                                                   GPtrArray             *seen_properties);
+void     tracker_data_ontology_import_into_db     (gboolean               is_new);
+void     tracker_data_ontology_process_statement  (const gchar           *graph,
+                                                   const gchar           *subject,
+                                                   const gchar           *predicate,
+                                                   const gchar           *object,
+                                                   gboolean               is_uri,
+                                                   gboolean               in_update,
+                                                   gboolean               ignore_nao_last_modified);
+void    tracker_data_ontology_import_finished     (void);
+void    tracker_data_ontology_process_changes     (GPtrArray             *seen_classes,
+                                                   GPtrArray             *seen_properties);
+void    tracker_data_ontology_free_seen           (GPtrArray             *seen);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 71b99bb..a8ab034 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -2933,15 +2933,11 @@ tracker_data_replay_journal (GHashTable          *classes,
 
 	if (journal_error) {
 		gsize size;
-		gsize chunk_size = 0;
-		gboolean do_rotating = FALSE;
 
 		size = tracker_db_journal_reader_get_size_of_correct ();
 		tracker_db_journal_reader_shutdown ();
 
-		tracker_db_journal_get_rotating (&do_rotating, &chunk_size);
-
-		tracker_db_journal_init (NULL, FALSE, do_rotating, chunk_size);
+		tracker_db_journal_init (NULL, FALSE);
 		tracker_db_journal_truncate (size);
 		tracker_db_journal_shutdown ();
 
diff --git a/src/libtracker-db/Makefile.am b/src/libtracker-db/Makefile.am
index 3376aaf..43fa0af 100644
--- a/src/libtracker-db/Makefile.am
+++ b/src/libtracker-db/Makefile.am
@@ -19,7 +19,8 @@ libtracker_db_la_SOURCES = 						\
 	tracker-db-interface.c						\
 	tracker-db-interface-sqlite.c					\
 	tracker-db-manager.c						\
-	tracker-db-journal.c						
+	tracker-db-journal.c						\
+	tracker-db-config.c
 
 noinst_HEADERS =							\
 	tracker-db.h							\
@@ -27,7 +28,8 @@ noinst_HEADERS =							\
 	tracker-db-interface.h						\
 	tracker-db-interface-sqlite.h					\
 	tracker-db-manager.h 						\
-	tracker-db-journal.h
+	tracker-db-journal.h						\
+	tracker-db-config.h
 
 libtracker_db_la_LIBADD = 						\
 	$(top_builddir)/src/libtracker-common/libtracker-common.la	\
diff --git a/src/libtracker-db/tracker-db-config.c b/src/libtracker-db/tracker-db-config.c
new file mode 100644
index 0000000..14502aa
--- /dev/null
+++ b/src/libtracker-db/tracker-db-config.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2009, Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ *
+ * Authors:
+ * Philip Van Hoof <philip codeminded be>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libtracker-common/tracker-keyfile-object.h>
+
+#include "tracker-db-config.h"
+
+#define TRACKER_DB_CONFIG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_DB_CONFIG, TrackerDBConfigPrivate))
+
+/* GKeyFile defines */
+#define GROUP_JOURNAL     "Journal"
+
+/* Default values */
+#define DEFAULT_JOURNAL_CHUNK_SIZE           500
+#define DEFAULT_JOURNAL_ROTATE_DESTINATION   ""
+
+typedef struct {
+	/* Journal */
+	gint journal_chunk_size;
+	gchar *journal_rotate_destination;
+}  TrackerDBConfigPrivate;
+
+typedef struct {
+	GType  type;
+	const gchar *property;
+	const gchar *group;
+	const gchar *key;
+} ObjectToKeyFile;
+
+static void config_set_property         (GObject       *object,
+                                         guint          param_id,
+                                         const GValue  *value,
+                                         GParamSpec    *pspec);
+static void config_get_property         (GObject       *object,
+                                         guint          param_id,
+                                         GValue        *value,
+                                         GParamSpec    *pspec);
+static void config_finalize             (GObject       *object);
+static void config_constructed          (GObject       *object);
+static void config_create_with_defaults (TrackerDBConfig *config,
+                                         GKeyFile      *key_file,
+                                         gboolean       overwrite);
+static void config_load                 (TrackerDBConfig *config);
+
+enum {
+	PROP_0,
+
+	/* Journal */
+	PROP_JOURNAL_CHUNK_SIZE,
+	PROP_JOURNAL_ROTATE_DESTINATION
+};
+
+static ObjectToKeyFile conversions[] = {
+	{ G_TYPE_INT,     "journal-chunk-size",         GROUP_JOURNAL,  "JournalChunkSize"         },
+	{ G_TYPE_STRING,  "journal-rotate-destination", GROUP_JOURNAL,  "JournalRotateDestination" },
+};
+
+G_DEFINE_TYPE (TrackerDBConfig, tracker_db_config, TRACKER_TYPE_CONFIG_FILE);
+
+static void
+tracker_db_config_class_init (TrackerDBConfigClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->set_property = config_set_property;
+	object_class->get_property = config_get_property;
+	object_class->finalize     = config_finalize;
+	object_class->constructed  = config_constructed;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_JOURNAL_CHUNK_SIZE,
+	                                 g_param_spec_int ("journal-chunk-size",
+	                                                   "Journal chunk size",
+	                                                   " Size of the journal at rotation in MB. Use -1 to disable rotating",
+	                                                   -1,
+	                                                   G_MAXINT,
+	                                                   DEFAULT_JOURNAL_CHUNK_SIZE,
+	                                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_JOURNAL_ROTATE_DESTINATION,
+	                                 g_param_spec_string ("journal-rotate-destination",
+	                                                      "Journal rotate destination",
+	                                                      " Destination to rotate journal chunks to",
+	                                                      DEFAULT_JOURNAL_ROTATE_DESTINATION,
+	                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	g_type_class_add_private (object_class, sizeof (TrackerDBConfigPrivate));
+}
+
+static void
+tracker_db_config_init (TrackerDBConfig *object)
+{
+}
+
+static void
+config_set_property (GObject      *object,
+                     guint         param_id,
+                     const GValue *value,
+                     GParamSpec           *pspec)
+{
+	switch (param_id) {
+		/* Journal */
+	case PROP_JOURNAL_CHUNK_SIZE:
+		tracker_db_config_set_journal_chunk_size (TRACKER_DB_CONFIG (object),
+		                                          g_value_get_int(value));
+		break;
+	case PROP_JOURNAL_ROTATE_DESTINATION:
+		tracker_db_config_set_journal_rotate_destination (TRACKER_DB_CONFIG (object),
+		                                                  g_value_get_string(value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void
+config_get_property (GObject    *object,
+                     guint       param_id,
+                     GValue     *value,
+                     GParamSpec *pspec)
+{
+	TrackerDBConfigPrivate *priv;
+
+	priv = TRACKER_DB_CONFIG_GET_PRIVATE (object);
+
+	switch (param_id) {
+	case PROP_JOURNAL_CHUNK_SIZE:
+		g_value_set_int (value, priv->journal_chunk_size);
+		break;
+	case PROP_JOURNAL_ROTATE_DESTINATION:
+		g_value_set_string (value, priv->journal_rotate_destination);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void
+config_finalize (GObject *object)
+{
+	TrackerDBConfigPrivate *priv;
+
+	priv = TRACKER_DB_CONFIG_GET_PRIVATE (object);
+
+	g_free (priv->journal_rotate_destination);
+
+	(G_OBJECT_CLASS (tracker_db_config_parent_class)->finalize) (object);
+}
+
+static void
+config_constructed (GObject *object)
+{
+	(G_OBJECT_CLASS (tracker_db_config_parent_class)->constructed) (object);
+
+	config_load (TRACKER_DB_CONFIG (object));
+}
+
+static void
+config_create_with_defaults (TrackerDBConfig *config,
+                             GKeyFile      *key_file,
+                             gboolean       overwrite)
+{
+	gint i;
+
+	g_message ("Loading defaults into GKeyFile...");
+
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+
+		has_key = g_key_file_has_key (key_file,
+		                              conversions[i].group,
+		                              conversions[i].key,
+		                              NULL);
+		if (!overwrite && has_key) {
+			continue;
+		}
+
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			g_key_file_set_integer (key_file,
+			                        conversions[i].group,
+			                        conversions[i].key,
+			                        tracker_keyfile_object_default_int (config,
+			                                                            conversions[i].property));
+			break;
+
+		case G_TYPE_STRING:
+			g_key_file_set_string (key_file,
+			                       conversions[i].group,
+			                       conversions[i].key,
+			                       tracker_keyfile_object_default_string (config,
+			                                                              conversions[i].property));
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
+
+		g_key_file_set_comment (key_file,
+		                        conversions[i].group,
+		                        conversions[i].key,
+		                        tracker_keyfile_object_blurb (config,
+		                                                      conversions[i].property),
+		                        NULL);
+	}
+}
+
+static void
+config_load (TrackerDBConfig *config)
+{
+	TrackerConfigFile *file;
+	gint i;
+
+	file = TRACKER_CONFIG_FILE (config);
+	config_create_with_defaults (config, file->key_file, FALSE);
+
+	if (!file->file_exists) {
+		tracker_config_file_save (file);
+	}
+
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+
+		has_key = g_key_file_has_key (file->key_file,
+		                              conversions[i].group,
+		                              conversions[i].key,
+		                              NULL);
+
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_keyfile_object_load_int (G_OBJECT (file),
+			                                 conversions[i].property,
+			                                 file->key_file,
+			                                 conversions[i].group,
+			                                 conversions[i].key);
+			break;
+
+		case G_TYPE_STRING:
+			tracker_keyfile_object_load_string (G_OBJECT (file),
+			                                    conversions[i].property,
+			                                    file->key_file,
+			                                    conversions[i].group,
+			                                    conversions[i].key);
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
+	}
+}
+
+static gboolean
+config_save (TrackerDBConfig *config)
+{
+	TrackerConfigFile *file;
+	gint i;
+
+	file = TRACKER_CONFIG_FILE (config);
+
+	if (!file->key_file) {
+		g_critical ("Could not save config, GKeyFile was NULL, has the config been loaded?");
+
+		return FALSE;
+	}
+
+	g_message ("Setting details to GKeyFile object...");
+
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_keyfile_object_save_int (file,
+			                                 conversions[i].property,
+			                                 file->key_file,
+			                                 conversions[i].group,
+			                                 conversions[i].key);
+			break;
+
+		case G_TYPE_STRING:
+			tracker_keyfile_object_save_string (file,
+			                                    conversions[i].property,
+			                                    file->key_file,
+			                                    conversions[i].group,
+			                                    conversions[i].key);
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
+	}
+
+	return tracker_config_file_save (TRACKER_CONFIG_FILE (config));
+}
+
+TrackerDBConfig *
+tracker_db_config_new (void)
+{
+	return g_object_new (TRACKER_TYPE_DB_CONFIG,
+	                     "domain", "tracker-db",
+	                     NULL);
+}
+
+gboolean
+tracker_db_config_save (TrackerDBConfig *config)
+{
+	g_return_val_if_fail (TRACKER_IS_DB_CONFIG (config), FALSE);
+
+	return config_save (config);
+}
+
+
+gint
+tracker_db_config_get_journal_chunk_size (TrackerDBConfig *config)
+{
+	TrackerDBConfigPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_DB_CONFIG (config), DEFAULT_JOURNAL_CHUNK_SIZE);
+
+	priv = TRACKER_DB_CONFIG_GET_PRIVATE (config);
+
+	return priv->journal_chunk_size;
+}
+
+const gchar *
+tracker_db_config_get_journal_rotate_destination (TrackerDBConfig *config)
+{
+	TrackerDBConfigPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_DB_CONFIG (config), DEFAULT_JOURNAL_ROTATE_DESTINATION);
+
+	priv = TRACKER_DB_CONFIG_GET_PRIVATE (config);
+
+	return priv->journal_rotate_destination;
+}
+
+void
+tracker_db_config_set_journal_chunk_size (TrackerDBConfig *config,
+                                          gint             value)
+{
+	TrackerDBConfigPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_DB_CONFIG (config));
+
+	if (!tracker_keyfile_object_validate_int (config, "journal-chunk-size", value)) {
+		return;
+	}
+
+	priv = TRACKER_DB_CONFIG_GET_PRIVATE (config);
+
+	priv->journal_chunk_size = value;
+	g_object_notify (G_OBJECT (config), "journal-chunk-size");
+}
+
+void
+tracker_db_config_set_journal_rotate_destination (TrackerDBConfig *config,
+                                                  const gchar     *value)
+{
+	TrackerDBConfigPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_DB_CONFIG (config));
+
+	priv = TRACKER_DB_CONFIG_GET_PRIVATE (config);
+
+	g_free (priv->journal_rotate_destination);
+	priv->journal_rotate_destination = g_strdup (value);
+
+	g_object_notify (G_OBJECT (config), "journal-rotate-destination");
+}
diff --git a/src/libtracker-db/tracker-db-config.h b/src/libtracker-db/tracker-db-config.h
new file mode 100644
index 0000000..ff573a2
--- /dev/null
+++ b/src/libtracker-db/tracker-db-config.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009, Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ *
+ * Authors:
+ * Philip Van Hoof <philip codeminded be>
+ */
+
+#ifndef __TRACKER_DB_CONFIG_H__
+#define __TRACKER_DB_CONFIG_H__
+
+#if !defined (__LIBTRACKER_DB_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-db/tracker-db.h> must be included directly."
+#endif
+
+#include <glib-object.h>
+
+#include <libtracker-common/tracker-config-file.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_DB_CONFIG         (tracker_db_config_get_type ())
+#define TRACKER_DB_CONFIG(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DB_CONFIG, TrackerDBConfig))
+#define TRACKER_DB_CONFIG_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_DB_CONFIG, TrackerDBConfigClass))
+#define TRACKER_IS_DB_CONFIG(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DB_CONFIG))
+#define TRACKER_IS_DB_CONFIG_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_DB_CONFIG))
+#define TRACKER_DB_CONFIG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DB_CONFIG, TrackerDBConfigClass))
+
+typedef struct TrackerDBConfig              TrackerDBConfig;
+typedef struct TrackerDBConfigClass TrackerDBConfigClass;
+
+struct TrackerDBConfig {
+	TrackerConfigFile parent;
+};
+
+struct TrackerDBConfigClass {
+	TrackerConfigFileClass parent_class;
+};
+
+GType            tracker_db_config_get_type                       (void) G_GNUC_CONST;
+
+TrackerDBConfig *tracker_db_config_new                            (void);
+gboolean         tracker_db_config_save                           (TrackerDBConfig *config);
+
+gint             tracker_db_config_get_journal_chunk_size         (TrackerDBConfig *config);
+const gchar *    tracker_db_config_get_journal_rotate_destination (TrackerDBConfig *config);
+
+void             tracker_db_config_set_journal_chunk_size         (TrackerDBConfig *config,
+                                                                   gint             value);
+void             tracker_db_config_set_journal_rotate_destination (TrackerDBConfig *config,
+                                                                   const gchar     *value);
+
+G_END_DECLS
+
+#endif /* __TRACKER_DB_CONFIG_H__ */
+
diff --git a/src/libtracker-db/tracker-db-journal.c b/src/libtracker-db/tracker-db-journal.c
index 5db144d..8b95ba0 100644
--- a/src/libtracker-db/tracker-db-journal.c
+++ b/src/libtracker-db/tracker-db-journal.c
@@ -66,7 +66,7 @@ typedef enum {
 	TRANSACTION_FORMAT_ONTOLOGY  = 1 << 1,
 } TransactionFormat;
 
-static struct {
+typedef struct {
 	gchar *filename;
 	GMappedFile *file;
 	const gchar *current;
@@ -85,9 +85,10 @@ static struct {
 	gint o_id;
 	const gchar *object;
 	guint current_file;
-} reader;
+	gchar *rotate_to;
+} JournalReader;
 
-static struct {
+typedef struct {
 	gchar *journal_filename;
 	int journal;
 	gsize cur_size;
@@ -96,9 +97,18 @@ static struct {
 	gchar *cur_block;
 	guint cur_entry_amount;
 	guint cur_pos;
+} JournalWriter;
+
+static struct {
 	gsize chunk_size;
 	gboolean do_rotating;
-} writer;
+	gchar *rotate_to;
+} rotating_settings = {0};
+
+static JournalReader reader = {0};
+static JournalWriter writer = {0};
+
+static gboolean tracker_db_journal_rotate (void);
 
 static guint32
 read_uint32 (const guint8 *data)
@@ -109,6 +119,35 @@ read_uint32 (const guint8 *data)
 	       data[3];
 }
 
+void
+tracker_db_journal_get_rotating (gboolean *do_rotating,
+                                 gsize    *chunk_size,
+                                 gchar   **rotate_to)
+{
+	*do_rotating = rotating_settings.do_rotating;
+	*chunk_size = rotating_settings.chunk_size;
+	if (rotating_settings.rotate_to) {
+		*rotate_to = g_strdup (rotating_settings.rotate_to);
+	} else {
+		*rotate_to = NULL;
+	}
+}
+
+void
+tracker_db_journal_set_rotating (gboolean     do_rotating,
+                                 gsize        chunk_size,
+                                 const gchar *rotate_to)
+{
+	rotating_settings.do_rotating = do_rotating;
+	rotating_settings.chunk_size = chunk_size;
+	g_free (rotating_settings.rotate_to);
+	if (rotate_to) {
+		rotating_settings.rotate_to = g_strdup (rotate_to);
+	} else {
+		rotating_settings.rotate_to = NULL;
+	}
+}
+
 static gint
 nearest_pow (gint num)
 {
@@ -119,28 +158,28 @@ nearest_pow (gint num)
 }
 
 static void
-cur_block_maybe_expand (guint len)
+cur_block_maybe_expand (JournalWriter *jwriter, guint len)
 {
-	guint want_alloc = writer.cur_block_len + len;
+	guint want_alloc = jwriter->cur_block_len + len;
 
-	if (want_alloc > writer.cur_block_alloc) {
+	if (want_alloc > jwriter->cur_block_alloc) {
 		want_alloc = nearest_pow (want_alloc);
 		want_alloc = MAX (want_alloc, MIN_BLOCK_SIZE);
-		writer.cur_block = g_realloc (writer.cur_block, want_alloc);
-		writer.cur_block_alloc = want_alloc;
+		jwriter->cur_block = g_realloc (jwriter->cur_block, want_alloc);
+		jwriter->cur_block_alloc = want_alloc;
 	}
 }
 
 static void
-cur_block_kill (void)
+cur_block_kill (JournalWriter *jwriter)
 {
-	writer.cur_block_len = 0;
-	writer.cur_pos = 0;
-	writer.cur_entry_amount = 0;
-	writer.cur_block_alloc = 0;
+	jwriter->cur_block_len = 0;
+	jwriter->cur_pos = 0;
+	jwriter->cur_entry_amount = 0;
+	jwriter->cur_block_alloc = 0;
 
-	g_free (writer.cur_block);
-	writer.cur_block = NULL;
+	g_free (jwriter->cur_block);
+	jwriter->cur_block = NULL;
 }
 
 static void
@@ -205,17 +244,17 @@ tracker_db_journal_error_quark (void)
 }
 
 static gboolean
-tracker_db_journal_init_file (gboolean truncate)
+db_journal_init_file (JournalWriter *jwriter, gboolean truncate)
 {
 	struct stat st;
 	int flags;
 	int mode;
 
-	writer.cur_block_len = 0;
-	writer.cur_pos = 0;
-	writer.cur_entry_amount = 0;
-	writer.cur_block_alloc = 0;
-	writer.cur_block = NULL;
+	jwriter->cur_block_len = 0;
+	jwriter->cur_pos = 0;
+	jwriter->cur_entry_amount = 0;
+	jwriter->cur_block_alloc = 0;
+	jwriter->cur_block = NULL;
 
 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
 	flags = O_WRONLY | O_APPEND | O_CREAT | O_LARGEFILE;
@@ -227,117 +266,134 @@ tracker_db_journal_init_file (gboolean truncate)
 		 */
 		flags |= O_TRUNC;
 	}
-	writer.journal = g_open (writer.journal_filename, flags, mode);
 
-	if (writer.journal == -1) {
+	jwriter->journal = g_open (jwriter->journal_filename, flags, mode);
+
+	if (jwriter->journal == -1) {
 		g_critical ("Could not open journal for writing, %s", 
 		            g_strerror (errno));
 
-		g_free (writer.journal_filename);
-		writer.journal_filename = NULL;
+		g_free (jwriter->journal_filename);
+		jwriter->journal_filename = NULL;
 		return FALSE;
 	}
 
-	if (g_stat (writer.journal_filename, &st) == 0) {
-		writer.cur_size = (gsize) st.st_size;
+	if (g_stat (jwriter->journal_filename, &st) == 0) {
+		jwriter->cur_size = (gsize) st.st_size;
 	}
 
-	if (writer.cur_size == 0) {
-		g_assert (writer.cur_block_len == 0);
-		g_assert (writer.cur_block_alloc == 0);
-		g_assert (writer.cur_block == NULL);
-		g_assert (writer.cur_block == NULL);
-
-		cur_block_maybe_expand (8);
-
-		writer.cur_block[0] = 't';
-		writer.cur_block[1] = 'r';
-		writer.cur_block[2] = 'l';
-		writer.cur_block[3] = 'o';
-		writer.cur_block[4] = 'g';
-		writer.cur_block[5] = '\0';
-		writer.cur_block[6] = '0';
-		writer.cur_block[7] = '3';
-
-		if (!write_all_data (writer.journal, writer.cur_block, 8)) {
-			g_free (writer.journal_filename);
-			writer.journal_filename = NULL;
+	if (jwriter->cur_size == 0) {
+		g_assert (jwriter->cur_block_len == 0);
+		g_assert (jwriter->cur_block_alloc == 0);
+		g_assert (jwriter->cur_block == NULL);
+		g_assert (jwriter->cur_block == NULL);
+
+		cur_block_maybe_expand (jwriter, 8);
+
+		jwriter->cur_block[0] = 't';
+		jwriter->cur_block[1] = 'r';
+		jwriter->cur_block[2] = 'l';
+		jwriter->cur_block[3] = 'o';
+		jwriter->cur_block[4] = 'g';
+		jwriter->cur_block[5] = '\0';
+		jwriter->cur_block[6] = '0';
+		jwriter->cur_block[7] = '3';
+
+		if (!write_all_data (jwriter->journal, jwriter->cur_block, 8)) {
+			g_free (jwriter->journal_filename);
+			jwriter->journal_filename = NULL;
 			return FALSE;
 		}
 
-		writer.cur_size += 8;
-		cur_block_kill ();
+		jwriter->cur_size += 8;
+		cur_block_kill (jwriter);
 	}
 
 	return TRUE;
 }
 
-gboolean
-tracker_db_journal_init (const gchar *filename,
-                         gboolean     truncate,
-                         gboolean     do_rotating,
-                         gsize        chunk_size)
+static gboolean
+db_journal_writer_init (JournalWriter *jwriter,
+                        gboolean       truncate,
+                        gboolean       global_writer,
+                        const gchar   *filename)
 {
 	gchar *directory;
-	int mode;
+	gint mode;
 
-	g_return_val_if_fail (writer.journal == 0, FALSE);
-
-	/* Used mostly for testing */
-	if (G_UNLIKELY (filename)) {
-		writer.journal_filename = g_strdup (filename);
-	} else {
-		writer.journal_filename = g_build_filename (g_get_user_data_dir (),
-		                                            "tracker",
-		                                            "data",
-		                                            TRACKER_DB_JOURNAL_FILENAME,
-		                                            NULL);
-	}
-
-	directory = g_path_get_dirname (writer.journal_filename);
+	directory = g_path_get_dirname (filename);
 	if (g_strcmp0 (directory, ".")) {
 		mode = S_IRWXU | S_IRWXG | S_IRWXO;
 		if (g_mkdir_with_parents (directory, mode)) {
 			g_critical ("tracker data directory does not exist and "
 			            "could not be created: %s",
 			            g_strerror (errno));
-
 			g_free (directory);
-			g_free (writer.journal_filename);
-			writer.journal_filename = NULL;
-
 			return FALSE;
 		}
 	}
 	g_free (directory);
 
-	writer.do_rotating = do_rotating;
-	writer.chunk_size = chunk_size;
+	jwriter->journal_filename = g_strdup (filename);
 
-	return tracker_db_journal_init_file (truncate);
+	return db_journal_init_file (jwriter, truncate);
 }
 
 gboolean
-tracker_db_journal_shutdown (void)
+tracker_db_journal_init (const gchar *filename,
+                         gboolean     truncate)
+{
+	gboolean ret;
+	const gchar *filename_use;
+	gchar *filename_free = NULL;
+
+	g_return_val_if_fail (writer.journal == 0, FALSE);
+
+	if (filename == NULL) {
+		/* Used mostly for testing */
+		filename_use = g_build_filename (g_get_user_data_dir (),
+		                                 "tracker",
+		                                 "data",
+		                                 TRACKER_DB_JOURNAL_FILENAME,
+		                                 NULL);
+		filename_free = (gchar *) filename_use;
+	} else {
+		filename_use = filename;
+	}
+
+	ret = db_journal_writer_init (&writer, truncate, TRUE, filename_use);
+	g_free (filename_free);
+
+	return ret;
+}
+
+static gboolean
+db_journal_writer_shutdown (JournalWriter *jwriter)
 {
-	if (writer.journal == 0) {
+	g_free (jwriter->journal_filename);
+	jwriter->journal_filename = NULL;
+
+	if (jwriter->journal == 0) {
 		return TRUE;
 	}
 
-	if (close (writer.journal) != 0) {
+	if (close (jwriter->journal) != 0) {
 		g_warning ("Could not close journal, %s", 
 		           g_strerror (errno));
 		return FALSE;
 	}
 
-	writer.journal = 0;
-
-	g_free (writer.journal_filename);
-	writer.journal_filename = NULL;
+	jwriter->journal = 0;
 
 	return TRUE;
 }
 
+gboolean
+tracker_db_journal_shutdown (void)
+{
+	return db_journal_writer_shutdown (&writer);
+}
+
 gsize
 tracker_db_journal_get_size (void)
 {
@@ -354,82 +410,66 @@ tracker_db_journal_get_filename (void)
 	return (const gchar*) writer.journal_filename;
 }
 
-gboolean
-tracker_db_journal_start_transaction (time_t time)
+static gboolean
+db_journal_writer_start_transaction (JournalWriter    *jwriter,
+                                     time_t            time,
+                                     TransactionFormat kind)
 {
 	guint size;
 
-	g_return_val_if_fail (writer.journal > 0, FALSE);
+	g_return_val_if_fail (jwriter->journal > 0, FALSE);
 
 	size = sizeof (guint32) * 3;
-	cur_block_maybe_expand (size);
+	cur_block_maybe_expand (jwriter, size);
 
 	/* Leave space for size, amount and crc
 	 * Check and keep in sync the offset variable at
 	 * tracker_db_journal_commit_db_transaction too */
 
-	memset (writer.cur_block, 0, size);
+	memset (jwriter->cur_block, 0, size);
 
-	writer.cur_pos = writer.cur_block_len = size;
-	writer.cur_entry_amount = 0;
+	jwriter->cur_pos = jwriter->cur_block_len = size;
+	jwriter->cur_entry_amount = 0;
 
 	/* add timestamp */
-	cur_block_maybe_expand (sizeof (gint32));
-	cur_setnum (writer.cur_block, &writer.cur_pos, time);
-	writer.cur_block_len += sizeof (gint32);
+	cur_block_maybe_expand (jwriter, sizeof (gint32));
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), time);
+	jwriter->cur_block_len += sizeof (gint32);
 
 	/* Add format */
-	cur_block_maybe_expand (sizeof (gint32));
-	cur_setnum (writer.cur_block, &writer.cur_pos, TRANSACTION_FORMAT_DATA);
-	writer.cur_block_len += sizeof (gint32);
+	cur_block_maybe_expand (jwriter, sizeof (gint32));
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), kind);
+	jwriter->cur_block_len += sizeof (gint32);
 
 	return TRUE;
 }
 
+gboolean
+tracker_db_journal_start_transaction (time_t time)
+{
+	return db_journal_writer_start_transaction (&writer, time,
+	                                            TRANSACTION_FORMAT_DATA);
+}
 
 gboolean
 tracker_db_journal_start_ontology_transaction (time_t time)
 {
-	guint size;
-
-	g_return_val_if_fail (writer.journal > 0, FALSE);
-
-	size = sizeof (guint32) * 3;
-	cur_block_maybe_expand (size);
-
-	/* Leave space for size, amount and crc
-	 * Check and keep in sync the offset variable at
-	 * tracker_db_journal_commit_db_transaction too */
-
-	memset (writer.cur_block, 0, size);
-
-	writer.cur_pos = writer.cur_block_len = size;
-	writer.cur_entry_amount = 0;
-
-	/* add timestamp */
-	cur_block_maybe_expand (sizeof (gint32));
-	cur_setnum (writer.cur_block, &writer.cur_pos, time);
-	writer.cur_block_len += sizeof (gint32);
-
-	/* Add format */
-	cur_block_maybe_expand (sizeof (gint32));
-	cur_setnum (writer.cur_block, &writer.cur_pos, TRANSACTION_FORMAT_ONTOLOGY);
-	writer.cur_block_len += sizeof (gint32);
-
-	return TRUE;
+	return db_journal_writer_start_transaction (&writer, time,
+	                                            TRANSACTION_FORMAT_ONTOLOGY);
 }
 
-gboolean
-tracker_db_journal_append_delete_statement (gint         g_id,
-                                            gint         s_id,
-                                            gint         p_id,
-                                            const gchar *object)
+static gboolean
+db_journal_writer_append_delete_statement (JournalWriter *jwriter,
+                                           gint           g_id,
+                                           gint           s_id,
+                                           gint           p_id,
+                                           const gchar   *object)
 {
 	gint o_len;
 	DataFormat df;
 	gint size;
 
-	g_return_val_if_fail (writer.journal > 0, FALSE);
+	g_return_val_if_fail (jwriter->journal > 0, FALSE);
 	g_return_val_if_fail (g_id >= 0, FALSE);
 	g_return_val_if_fail (s_id > 0, FALSE);
 	g_return_val_if_fail (p_id > 0, FALSE);
@@ -444,32 +484,43 @@ tracker_db_journal_append_delete_statement (gint         g_id,
 		size = (sizeof (guint32) * 4) + o_len + 1;
 	}
 
-	cur_block_maybe_expand (size);
+	cur_block_maybe_expand (jwriter, size);
 
-	cur_setnum (writer.cur_block, &writer.cur_pos, df);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), df);
 	if (g_id > 0) {
-		cur_setnum (writer.cur_block, &writer.cur_pos, g_id);
+		cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), g_id);
 	}
-	cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
-	cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
-	cur_setstr (writer.cur_block, &writer.cur_pos, object, o_len);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), s_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), p_id);
+	cur_setstr (jwriter->cur_block, &(jwriter->cur_pos), object, o_len);
 
-	writer.cur_entry_amount++;
-	writer.cur_block_len += size;
+	jwriter->cur_entry_amount++;
+	jwriter->cur_block_len += size;
 
 	return TRUE;
 }
 
 gboolean
-tracker_db_journal_append_delete_statement_id (gint g_id,
-                                               gint s_id,
-                                               gint p_id,
-                                               gint o_id)
+tracker_db_journal_append_delete_statement (gint         g_id,
+                                            gint         s_id,
+                                            gint         p_id,
+                                            const gchar *object)
+{
+	return db_journal_writer_append_delete_statement (&writer,
+	                                                  g_id, s_id, p_id, object);
+}
+
+static gboolean
+db_journal_writer_append_delete_statement_id  (JournalWriter *jwriter,
+                                               gint           g_id,
+                                               gint           s_id,
+                                               gint           p_id,
+                                               gint           o_id)
 {
 	DataFormat df;
 	gint size;
 
-	g_return_val_if_fail (writer.journal > 0, FALSE);
+	g_return_val_if_fail (jwriter->journal > 0, FALSE);
 	g_return_val_if_fail (g_id >= 0, FALSE);
 	g_return_val_if_fail (s_id > 0, FALSE);
 	g_return_val_if_fail (p_id > 0, FALSE);
@@ -483,33 +534,44 @@ tracker_db_journal_append_delete_statement_id (gint g_id,
 		size = sizeof (guint32) * 5;
 	}
 
-	cur_block_maybe_expand (size);
+	cur_block_maybe_expand (jwriter, size);
 
-	cur_setnum (writer.cur_block, &writer.cur_pos, df);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), df);
 	if (g_id > 0) {
-		cur_setnum (writer.cur_block, &writer.cur_pos, g_id);
+		cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), g_id);
 	}
-	cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
-	cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
-	cur_setnum (writer.cur_block, &writer.cur_pos, o_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), s_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), p_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), o_id);
 
-	writer.cur_entry_amount++;
-	writer.cur_block_len += size;
+	jwriter->cur_entry_amount++;
+	jwriter->cur_block_len += size;
 
 	return TRUE;
 }
 
 gboolean
-tracker_db_journal_append_insert_statement (gint         g_id,
-                                            gint         s_id,
-                                            gint         p_id,
-                                            const gchar *object)
+tracker_db_journal_append_delete_statement_id (gint g_id,
+                                               gint s_id,
+                                               gint p_id,
+                                               gint o_id)
+{
+	return db_journal_writer_append_delete_statement_id (&writer,
+	                                                     g_id, s_id, p_id, o_id);
+}
+
+static gboolean
+db_journal_writer_append_insert_statement (JournalWriter *jwriter,
+                                           gint           g_id,
+                                           gint           s_id,
+                                           gint           p_id,
+                                           const gchar   *object)
 {
 	gint o_len;
 	DataFormat df;
 	gint size;
 
-	g_return_val_if_fail (writer.journal > 0, FALSE);
+	g_return_val_if_fail (jwriter->journal > 0, FALSE);
 	g_return_val_if_fail (g_id >= 0, FALSE);
 	g_return_val_if_fail (s_id > 0, FALSE);
 	g_return_val_if_fail (p_id > 0, FALSE);
@@ -524,32 +586,43 @@ tracker_db_journal_append_insert_statement (gint         g_id,
 		size = (sizeof (guint32) * 4) + o_len + 1;
 	}
 
-	cur_block_maybe_expand (size);
+	cur_block_maybe_expand (jwriter, size);
 
-	cur_setnum (writer.cur_block, &writer.cur_pos, df);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), df);
 	if (g_id > 0) {
-		cur_setnum (writer.cur_block, &writer.cur_pos, g_id);
+		cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), g_id);
 	}
-	cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
-	cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
-	cur_setstr (writer.cur_block, &writer.cur_pos, object, o_len);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), s_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), p_id);
+	cur_setstr (jwriter->cur_block, &(jwriter->cur_pos), object, o_len);
 
-	writer.cur_entry_amount++;
-	writer.cur_block_len += size;
+	jwriter->cur_entry_amount++;
+	jwriter->cur_block_len += size;
 
 	return TRUE;
 }
 
 gboolean
-tracker_db_journal_append_insert_statement_id (gint g_id,
-                                               gint s_id,
-                                               gint p_id,
-                                               gint o_id)
+tracker_db_journal_append_insert_statement (gint         g_id,
+                                            gint         s_id,
+                                            gint         p_id,
+                                            const gchar *object)
+{
+	return db_journal_writer_append_insert_statement (&writer,
+	                                                  g_id, s_id, p_id, object);
+}
+
+static gboolean
+db_journal_writer_append_insert_statement_id (JournalWriter *jwriter,
+                                              gint           g_id,
+                                              gint           s_id,
+                                              gint           p_id,
+                                              gint           o_id)
 {
 	DataFormat df;
 	gint size;
 
-	g_return_val_if_fail (writer.journal > 0, FALSE);
+	g_return_val_if_fail (jwriter->journal > 0, FALSE);
 	g_return_val_if_fail (g_id >= 0, FALSE);
 	g_return_val_if_fail (s_id > 0, FALSE);
 	g_return_val_if_fail (p_id > 0, FALSE);
@@ -563,54 +636,72 @@ tracker_db_journal_append_insert_statement_id (gint g_id,
 		size = sizeof (guint32) * 5;
 	}
 
-	cur_block_maybe_expand (size);
+	cur_block_maybe_expand (jwriter, size);
 
-	cur_setnum (writer.cur_block, &writer.cur_pos, df);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), df);
 	if (g_id > 0) {
-		cur_setnum (writer.cur_block, &writer.cur_pos, g_id);
+		cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), g_id);
 	}
-	cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
-	cur_setnum (writer.cur_block, &writer.cur_pos, p_id);
-	cur_setnum (writer.cur_block, &writer.cur_pos, o_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), s_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), p_id);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), o_id);
 
-	writer.cur_entry_amount++;
-	writer.cur_block_len += size;
+	jwriter->cur_entry_amount++;
+	jwriter->cur_block_len += size;
 
 	return TRUE;
 }
 
 gboolean
-tracker_db_journal_append_resource (gint         s_id,
-                                    const gchar *uri)
+tracker_db_journal_append_insert_statement_id (gint g_id,
+                                               gint s_id,
+                                               gint p_id,
+                                               gint o_id)
+{
+	return db_journal_writer_append_insert_statement_id (&writer,
+	                                                     g_id, s_id, p_id, o_id);
+}
+
+static gboolean
+db_journal_writer_append_resource (JournalWriter *jwriter,
+                                   gint           s_id,
+                                   const gchar   *uri)
 {
 	gint o_len;
 	DataFormat df;
 	gint size;
 
-	g_return_val_if_fail (writer.journal > 0, FALSE);
+	g_return_val_if_fail (jwriter->journal > 0, FALSE);
 
 	o_len = strlen (uri);
 	df = DATA_FORMAT_RESOURCE_INSERT;
 	size = (sizeof (guint32) * 2) + o_len + 1;
 
-	cur_block_maybe_expand (size);
+	cur_block_maybe_expand (jwriter, size);
 
-	cur_setnum (writer.cur_block, &writer.cur_pos, df);
-	cur_setnum (writer.cur_block, &writer.cur_pos, s_id);
-	cur_setstr (writer.cur_block, &writer.cur_pos, uri, o_len);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), df);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), s_id);
+	cur_setstr (jwriter->cur_block, &(jwriter->cur_pos), uri, o_len);
 
-	writer.cur_entry_amount++;
-	writer.cur_block_len += size;
+	jwriter->cur_entry_amount++;
+	jwriter->cur_block_len += size;
 
 	return TRUE;
 }
 
 gboolean
+tracker_db_journal_append_resource (gint         s_id,
+                                    const gchar *uri)
+{
+	return db_journal_writer_append_resource (&writer, s_id, uri);
+}
+
+gboolean
 tracker_db_journal_rollback_transaction (void)
 {
 	g_return_val_if_fail (writer.journal > 0, FALSE);
 
-	cur_block_kill ();
+	cur_block_kill (&writer);
 
 	return TRUE;
 }
@@ -623,127 +714,71 @@ tracker_db_journal_truncate (gsize new_size)
 	return (ftruncate (writer.journal, new_size) != -1);
 }
 
-void
-tracker_db_journal_get_rotating (gboolean *do_rotating,
-                                 gsize    *chunk_size)
-{
-	*do_rotating = writer.do_rotating;
-	*chunk_size = writer.chunk_size;
-}
-
 static gboolean
-tracker_db_journal_rotate (void)
-{
-	gchar *fullpath;
-	static guint max = 0;
-
-	if (max == 0) {
-		gchar *directory;
-		GDir *journal_dir;
-		const gchar *f_name;
-
-		directory = g_path_get_dirname (writer.journal_filename);
-
-		journal_dir = g_dir_open (directory, 0, NULL);
-
-		f_name = g_dir_read_name (journal_dir);
-
-		while (f_name) {
-			gchar *ptr;
-			guint cur;
-
-			if (f_name) {
-
-				if (!g_str_has_prefix (f_name, TRACKER_DB_JOURNAL_FILENAME ".")) {
-					f_name = g_dir_read_name (journal_dir);
-					continue;
-				}
-
-				ptr = strrchr (f_name, '.');
-				if (ptr) {
-					ptr++;
-					cur = atoi (ptr);
-					max = MAX (cur, max);
-				}
-			} 
-
-			f_name = g_dir_read_name (journal_dir);
-		}
-
-		g_dir_close (journal_dir);
-		g_free (directory);
-	}
-
-	tracker_db_journal_fsync ();
-
-	if (close (writer.journal) != 0) {
-		g_warning ("Could not close journal, %s", 
-		           g_strerror (errno));
-		return FALSE;
-	}
-
-	fullpath = g_strdup_printf ("%s.%d", writer.journal_filename, ++max);
-
-	g_rename (writer.journal_filename, fullpath);
-
-	g_free (fullpath);
-
-	return tracker_db_journal_init_file (TRUE);
-}
-
-gboolean
-tracker_db_journal_commit_db_transaction (void)
+db_journal_writer_commit_db_transaction (JournalWriter *jwriter)
 {
 	guint32 crc;
 	guint begin_pos;
 	guint size;
 	guint offset;
 
-	g_return_val_if_fail (writer.journal > 0, FALSE);
+	g_return_val_if_fail (jwriter->journal > 0, FALSE);
 
 	begin_pos = 0;
 	size = sizeof (guint32);
 	offset = sizeof (guint32) * 3;
 
 	/* Expand by uint32 for the size check at the end of the entry */
-	cur_block_maybe_expand (size);
+	cur_block_maybe_expand (jwriter, size);
 
-	writer.cur_block_len += size;
+	jwriter->cur_block_len += size;
 
 	/* Write size and amount */
-	cur_setnum (writer.cur_block, &begin_pos, writer.cur_block_len);
-	cur_setnum (writer.cur_block, &begin_pos, writer.cur_entry_amount);
+	cur_setnum (jwriter->cur_block, &begin_pos, jwriter->cur_block_len);
+	cur_setnum (jwriter->cur_block, &begin_pos, jwriter->cur_entry_amount);
 
 	/* Write size check to end of current journal data */
-	cur_setnum (writer.cur_block, &writer.cur_pos, writer.cur_block_len);
+	cur_setnum (jwriter->cur_block, &(jwriter->cur_pos), jwriter->cur_block_len);
 
 	/* Calculate CRC from entry triples start (i.e. without size,
 	 * amount and crc) until the end of the entry block.
 	 *
 	 * NOTE: the size check at the end is included in the CRC!
 	 */
-	crc = tracker_crc32 (writer.cur_block + offset, writer.cur_block_len - offset);
-	cur_setnum (writer.cur_block, &begin_pos, crc);
+	crc = tracker_crc32 (jwriter->cur_block + offset, jwriter->cur_block_len - offset);
+	cur_setnum (jwriter->cur_block, &begin_pos, crc);
 
-	if (!write_all_data (writer.journal, writer.cur_block, writer.cur_block_len)) {
+	if (!write_all_data (jwriter->journal, jwriter->cur_block, jwriter->cur_block_len)) {
 		g_critical ("Could not write to journal, %s", g_strerror (errno));
 		return FALSE;
 	}
 
 	/* Update journal size */
-	writer.cur_size += writer.cur_block_len;
+	jwriter->cur_size += jwriter->cur_block_len;
 
 	/* Clean up for next transaction */
-	cur_block_kill ();
+	cur_block_kill (jwriter);
 
-	if (writer.do_rotating && (writer.cur_size > writer.chunk_size)) {
-		if (!tracker_db_journal_rotate ()) {
-			g_critical ("Could not rotate journal, %s", g_strerror (errno));
-			return FALSE;
+	return TRUE;
+}
+
+gboolean
+tracker_db_journal_commit_db_transaction (void)
+{
+	gboolean ret;
+
+	ret = db_journal_writer_commit_db_transaction (&writer);
+
+	if (ret) {
+		if (rotating_settings.do_rotating && (writer.cur_size > rotating_settings.chunk_size)) {
+			if (!tracker_db_journal_rotate ()) {
+				g_critical ("Could not rotate journal, %s", g_strerror (errno));
+				ret = FALSE;
+			}
 		}
 	}
 
-	return TRUE;
+	return ret;
 }
 
 gboolean
@@ -757,15 +792,58 @@ tracker_db_journal_fsync (void)
 /*
  * Reader API
  */
-gboolean
-tracker_db_journal_reader_init (const gchar *filename)
+
+
+static gchar*
+reader_get_next_filepath (JournalReader *jreader)
+{
+	gchar *filename_open = NULL;
+	gchar *test;
+
+	test = g_strdup_printf ("%s.%d", jreader->filename, jreader->current_file + 1);
+
+	if (g_file_test (test, G_FILE_TEST_EXISTS)) {
+		jreader->current_file++;
+		filename_open = test;
+	} else if (rotating_settings.rotate_to != NULL) {
+		gchar *filename;
+		GFile *dest_dir, *possible;
+
+		/* This is where chunks are being rotated to */
+		dest_dir = g_file_new_for_path (rotating_settings.rotate_to);
+
+		filename = g_path_get_basename (test);
+		g_free (test);
+		possible = g_file_get_child (dest_dir, filename);
+		g_object_unref (dest_dir);
+		g_free (filename);
+
+		if (g_file_query_exists (possible, NULL)) {
+			jreader->current_file++;
+			filename_open = g_file_get_path (possible);
+		}
+		g_object_unref (possible);
+	}
+
+	if (filename_open == NULL) {
+		filename_open = g_strdup (jreader->filename);
+		/* Last file is the active journal file */
+		jreader->current_file = 0;
+	}
+
+	return filename_open;
+}
+
+static gboolean
+db_journal_reader_init (JournalReader *jreader,
+                        gboolean global_reader,
+                        const gchar *filename)
 {
 	GError *error = NULL;
 	gchar *filename_used;
 	gchar *filename_open;
-	gchar *test;
 
-	g_return_val_if_fail (reader.file == NULL, FALSE);
+	g_return_val_if_fail (jreader->file == NULL, FALSE);
 
 	/* Used mostly for testing */
 	if (G_UNLIKELY (filename)) {
@@ -778,20 +856,17 @@ tracker_db_journal_reader_init (const gchar *filename)
 		                                  NULL);
 	}
 
-	test = g_strdup_printf ("%s.1", filename_used);
+	jreader->filename = filename_used;
 
-	if (g_file_test (test, G_FILE_TEST_EXISTS)) {
-		filename_open = test;
-		reader.current_file = 1;
+	reader.current_file = 0;
+	if (global_reader) {
+		filename_open = reader_get_next_filepath (jreader);
 	} else {
-		g_free (test);
 		filename_open = g_strdup (filename_used);
-		reader.current_file = 0;
 	}
 
-	reader.type = TRACKER_DB_JOURNAL_START;
-	reader.filename = filename_used;
-	reader.file = g_mapped_file_new (filename_open, FALSE, &error);
+	jreader->type = TRACKER_DB_JOURNAL_START;
+	jreader->file = g_mapped_file_new (filename_open, FALSE, &error);
 
 	g_free (filename_open);
 
@@ -799,37 +874,43 @@ tracker_db_journal_reader_init (const gchar *filename)
 		if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
 			/* do not warn if the file does not exist, just return FALSE */
 			g_warning ("Could not create TrackerDBJournalReader for file '%s', %s",
-			           reader.filename,
+			           jreader->filename,
 			           error->message ? error->message : "no error given");
 		}
 		g_error_free (error);
-		g_free (reader.filename);
-		reader.filename = NULL;
+		g_free (jreader->filename);
+		jreader->filename = NULL;
 
 		return FALSE;
 	}
 
-	reader.last_success = reader.start = reader.current = 
-		g_mapped_file_get_contents (reader.file);
+	jreader->last_success = jreader->start = jreader->current = 
+		g_mapped_file_get_contents (jreader->file);
 
-	reader.end = reader.current + g_mapped_file_get_length (reader.file);
+	jreader->end = jreader->current + g_mapped_file_get_length (jreader->file);
 
 	/* verify journal file header */
-	if (reader.end - reader.current < 8) {
+	if (jreader->end - jreader->current < 8) {
 		tracker_db_journal_reader_shutdown ();
 		return FALSE;
 	}
 
-	if (memcmp (reader.current, "trlog\00003", 8)) {
+	if (memcmp (jreader->current, "trlog\00003", 8)) {
 		tracker_db_journal_reader_shutdown ();
 		return FALSE;
 	}
 
-	reader.current += 8;
+	jreader->current += 8;
 
 	return TRUE;
 }
 
+gboolean
+tracker_db_journal_reader_init (const gchar *filename)
+{
+	return db_journal_reader_init (&reader, TRUE, filename);
+}
+
 gsize
 tracker_db_journal_reader_get_size_of_correct (void)
 {
@@ -842,19 +923,9 @@ static gboolean
 reader_next_file (GError **error)
 {
 	gchar *filename_open;
-	gchar *test;
 	GError *new_error = NULL;
 
-	test = g_strdup_printf ("%s.%d", reader.filename, ++reader.current_file);
-
-	if (g_file_test (test, G_FILE_TEST_EXISTS)) {
-		filename_open = test;
-	} else {
-		g_free (test);
-		filename_open = g_strdup (reader.filename);
-		/* Last file is the active journal file */
-		reader.current_file = 0;
-	}
+	filename_open = reader_get_next_filepath (&reader);
 
 #if GLIB_CHECK_VERSION(2,22,0)
 	g_mapped_file_unref (reader.file);
@@ -902,40 +973,46 @@ reader_next_file (GError **error)
 	return TRUE;
 }
 
-gboolean
-tracker_db_journal_reader_shutdown (void)
+static gboolean
+db_journal_reader_shutdown (JournalReader *jreader)
 {
-	g_return_val_if_fail (reader.file != NULL, FALSE);
+	g_return_val_if_fail (jreader->file != NULL, FALSE);
 
 #if GLIB_CHECK_VERSION(2,22,0)
-	g_mapped_file_unref (reader.file);
+	g_mapped_file_unref (jreader->file);
 #else
-	g_mapped_file_free (reader.file);
+	g_mapped_file_free (jreader->file);
 #endif
 
-	reader.file = NULL;
-
-	g_free (reader.filename);
-	reader.filename = NULL;
-
-	reader.last_success = NULL;
-	reader.start = NULL;
-	reader.current = NULL;
-	reader.end = NULL;
-	reader.entry_begin = NULL;
-	reader.entry_end = NULL;
-	reader.amount_of_triples = 0;
-	reader.type = TRACKER_DB_JOURNAL_START;
-	reader.uri = NULL;
-	reader.g_id = 0;
-	reader.s_id = 0;
-	reader.p_id = 0;
-	reader.o_id = 0;
-	reader.object = NULL;
+	jreader->file = NULL;
+
+	g_free (jreader->filename);
+	jreader->filename = NULL;
+
+	jreader->last_success = NULL;
+	jreader->start = NULL;
+	jreader->current = NULL;
+	jreader->end = NULL;
+	jreader->entry_begin = NULL;
+	jreader->entry_end = NULL;
+	jreader->amount_of_triples = 0;
+	jreader->type = TRACKER_DB_JOURNAL_START;
+	jreader->uri = NULL;
+	jreader->g_id = 0;
+	jreader->s_id = 0;
+	jreader->p_id = 0;
+	jreader->o_id = 0;
+	jreader->object = NULL;
 
 	return TRUE;
 }
 
+gboolean
+tracker_db_journal_reader_shutdown (void)
+{
+	return db_journal_reader_shutdown (&reader);
+}
+
 TrackerDBJournalEntryType
 tracker_db_journal_reader_get_type (void)
 {
@@ -944,34 +1021,10 @@ tracker_db_journal_reader_get_type (void)
 	return reader.type;
 }
 
-gboolean
-tracker_db_journal_reader_verify_last (GError **error)
-{
-	guint32 entry_size_check;
-	gboolean success = FALSE;
-
-	if (tracker_db_journal_reader_init (NULL)) {
-		entry_size_check = read_uint32 (reader.end - 4);
-
-		if (reader.end - entry_size_check < reader.current) {
-			g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
-			             "Damaged journal entry at end of journal");
-			tracker_db_journal_reader_shutdown ();
-			return FALSE;
-		}
-
-		reader.current = reader.end - entry_size_check;
-		success = tracker_db_journal_reader_next (NULL);
-		tracker_db_journal_reader_shutdown ();
-	}
-
-	return success;
-}
-
-gboolean
-tracker_db_journal_reader_next (GError **error)
+static gboolean
+db_journal_reader_next (JournalReader *jreader, gboolean global_reader, GError **error)
 {
-	g_return_val_if_fail (reader.file != NULL, FALSE);
+	g_return_val_if_fail (jreader->file != NULL, FALSE);
 
 	/*
 	 * Visual layout of the data in the binary journal:
@@ -999,8 +1052,8 @@ tracker_db_journal_reader_next (GError **error)
 	 * of the reader, we move past the [magic] and the [version].
 	 */
 
-	if (reader.type == TRACKER_DB_JOURNAL_START ||
-	    reader.type == TRACKER_DB_JOURNAL_END_TRANSACTION) {
+	if (jreader->type == TRACKER_DB_JOURNAL_START ||
+	    jreader->type == TRACKER_DB_JOURNAL_END_TRANSACTION) {
 		/* Expect new transaction or end of file */
 		guint32 entry_size;
 		guint32 entry_size_check;
@@ -1009,27 +1062,27 @@ tracker_db_journal_reader_next (GError **error)
 		TransactionFormat t_kind;
 
 		/* Check the end is not before where we currently are */
-		if (reader.current >= reader.end) {
-			/* Return FALSE as there is no further entry but
-			 * do not set error as it's not an error case. */
-			if (reader.current_file != 0)
-				return reader_next_file (error);
-			else
-				return FALSE;
+		if (jreader->current >= jreader->end) {
+				/* Return FALSE as there is no further entry but
+				 * do not set error as it's not an error case. */
+				if (global_reader && jreader->current_file != 0)
+					return reader_next_file (error);
+				else
+					return FALSE;
 		}
 
 		/* Check the end is not smaller than the first uint32
 		 * for reading the entry size.
 		 */
-		if (reader.end - reader.current < sizeof (guint32)) {
+		if (jreader->end - jreader->current < sizeof (guint32)) {
 			g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 			             "Damaged journal entry, %d < sizeof(guint32) at start/end of journal",
-			             (gint) (reader.end - reader.current));
+			             (gint) (jreader->end - jreader->current));
 			return FALSE;
 		}
 
 		/* Read the first uint32 which contains the size */
-		entry_size = read_uint32 (reader.current);
+		entry_size = read_uint32 (jreader->current);
 
 		/* Check that entry is big enough for header and footer */
 		if (entry_size < 5 * sizeof (guint32)) {
@@ -1040,13 +1093,13 @@ tracker_db_journal_reader_next (GError **error)
 		}
 
 		/* Set the bounds for the entry */
-		reader.entry_begin = reader.current;
-		reader.entry_end = reader.entry_begin + entry_size;
+		jreader->entry_begin = jreader->current;
+		jreader->entry_end = jreader->entry_begin + entry_size;
 
 		/* Check the end of the entry does not exceed the end
 		 * of the journal.
 		 */
-		if (reader.end < reader.entry_end) {
+		if (jreader->end < jreader->entry_end) {
 			g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 			             "Damaged journal entry, end < entry end");
 			return FALSE;
@@ -1055,10 +1108,10 @@ tracker_db_journal_reader_next (GError **error)
 		/* Move the current potision of the journal past the
 		 * entry size we read earlier.
 		 */
-		reader.current += 4;
+		jreader->current += 4;
 
 		/* Read entry size check at the end of the entry */
-		entry_size_check = read_uint32 (reader.entry_end - 4);
+		entry_size_check = read_uint32 (jreader->entry_end - 4);
 
 		if (entry_size != entry_size_check) {
 			/* damaged journal entry */
@@ -1070,15 +1123,15 @@ tracker_db_journal_reader_next (GError **error)
 		}
 
 		/* Read the amount of triples */
-		reader.amount_of_triples = read_uint32 (reader.current);
-		reader.current += 4;
+		jreader->amount_of_triples = read_uint32 (jreader->current);
+		jreader->current += 4;
 
 		/* Read the crc */
-		crc_check = read_uint32 (reader.current);
-		reader.current += 4;
+		crc_check = read_uint32 (jreader->current);
+		jreader->current += 4;
 
 		/* Calculate the crc */
-		crc = tracker_crc32 (reader.entry_begin + (sizeof (guint32) * 3), entry_size - (sizeof (guint32) * 3));
+		crc = tracker_crc32 (jreader->entry_begin + (sizeof (guint32) * 3), entry_size - (sizeof (guint32) * 3));
 
 		/* Verify checksum */
 		if (crc != crc_check) {
@@ -1091,66 +1144,66 @@ tracker_db_journal_reader_next (GError **error)
 		}
 
 		/* Read the timestamp */
-		reader.time = read_uint32 (reader.current);
-		reader.current += 4;
+		jreader->time = read_uint32 (jreader->current);
+		jreader->current += 4;
 
-		t_kind = read_uint32 (reader.current);
-		reader.current += 4;
+		t_kind = read_uint32 (jreader->current);
+		jreader->current += 4;
 
 		if (t_kind == TRANSACTION_FORMAT_DATA)
-			reader.type = TRACKER_DB_JOURNAL_START_TRANSACTION;
+			jreader->type = TRACKER_DB_JOURNAL_START_TRANSACTION;
 		else
-			reader.type = TRACKER_DB_JOURNAL_START_ONTOLOGY_TRANSACTION;
+			jreader->type = TRACKER_DB_JOURNAL_START_ONTOLOGY_TRANSACTION;
 
 		return TRUE;
-	} else if (reader.amount_of_triples == 0) {
+	} else if (jreader->amount_of_triples == 0) {
 		/* end of transaction */
 
-		reader.current += 4;
-		if (reader.current != reader.entry_end) {
+		jreader->current += 4;
+		if (jreader->current != jreader->entry_end) {
 			/* damaged journal entry */
 			g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 			             "Damaged journal entry, %p != %p (end of transaction with 0 triples)",
-			             reader.current,
-			             reader.entry_end);
+			             jreader->current,
+			             jreader->entry_end);
 			return FALSE;
 		}
 
-		reader.type = TRACKER_DB_JOURNAL_END_TRANSACTION;
-		reader.last_success = reader.current;
+		jreader->type = TRACKER_DB_JOURNAL_END_TRANSACTION;
+		jreader->last_success = jreader->current;
 
 		return TRUE;
 	} else {
 		DataFormat df;
 		gsize str_length;
 
-		if (reader.end - reader.current < sizeof (guint32)) {
+		if (jreader->end - jreader->current < sizeof (guint32)) {
 			/* damaged journal entry */
 			g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 			             "Damaged journal entry, %d < sizeof(guint32)",
-			             (gint) (reader.end - reader.current));
+			             (gint) (jreader->end - jreader->current));
 			return FALSE;
 		}
 
-		df = read_uint32 (reader.current);
-		reader.current += 4;
+		df = read_uint32 (jreader->current);
+		jreader->current += 4;
 
 		if (df == DATA_FORMAT_RESOURCE_INSERT) {
-			reader.type = TRACKER_DB_JOURNAL_RESOURCE;
+			jreader->type = TRACKER_DB_JOURNAL_RESOURCE;
 
-			if (reader.end - reader.current < sizeof (guint32) + 1) {
+			if (jreader->end - jreader->current < sizeof (guint32) + 1) {
 				/* damaged journal entry */
 				g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 				             "Damaged journal entry, %d < sizeof(guint32) + 1 for resource",
-				             (gint) (reader.end - reader.current));
+				             (gint) (jreader->end - jreader->current));
 				return FALSE;
 			}
 
-			reader.s_id = read_uint32 (reader.current);
-			reader.current += 4;
+			jreader->s_id = read_uint32 (jreader->current);
+			jreader->current += 4;
 
-			str_length = strnlen (reader.current, reader.end - reader.current);
-			if (str_length == reader.end - reader.current) {
+			str_length = strnlen (jreader->current, jreader->end - jreader->current);
+			if (str_length == jreader->end - jreader->current) {
 				/* damaged journal entry (no terminating '\0' character) */
 				g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 				             "Damaged journal entry, no terminating zero found for resource");
@@ -1158,102 +1211,102 @@ tracker_db_journal_reader_next (GError **error)
 
 			}
 
-			if (!g_utf8_validate (reader.current, -1, NULL)) {
+			if (!g_utf8_validate (jreader->current, -1, NULL)) {
 				/* damaged journal entry (invalid UTF-8) */
 				g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 				             "Damaged journal entry, invalid UTF-8 for resource");
 				return FALSE;
 			}
 
-			reader.uri = reader.current;
-			reader.current += str_length + 1;
+			jreader->uri = jreader->current;
+			jreader->current += str_length + 1;
 		} else {
 			if (df & DATA_FORMAT_OPERATION_DELETE) {
 				if (df & DATA_FORMAT_OBJECT_ID) {
-					reader.type = TRACKER_DB_JOURNAL_DELETE_STATEMENT_ID;
+					jreader->type = TRACKER_DB_JOURNAL_DELETE_STATEMENT_ID;
 				} else {
-					reader.type = TRACKER_DB_JOURNAL_DELETE_STATEMENT;
+					jreader->type = TRACKER_DB_JOURNAL_DELETE_STATEMENT;
 				}
 			} else {
 				if (df & DATA_FORMAT_OBJECT_ID) {
-					reader.type = TRACKER_DB_JOURNAL_INSERT_STATEMENT_ID;
+					jreader->type = TRACKER_DB_JOURNAL_INSERT_STATEMENT_ID;
 				} else {
-					reader.type = TRACKER_DB_JOURNAL_INSERT_STATEMENT;
+					jreader->type = TRACKER_DB_JOURNAL_INSERT_STATEMENT;
 				}
 			}
 
 			if (df & DATA_FORMAT_GRAPH) {
-				if (reader.end - reader.current < sizeof (guint32)) {
+				if (jreader->end - jreader->current < sizeof (guint32)) {
 					/* damaged journal entry */
 					g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 						     "Damaged journal entry, %d < sizeof(guint32)",
-						     (gint) (reader.end - reader.current));
+						     (gint) (jreader->end - jreader->current));
 					return FALSE;
 				}
 
 				/* named graph */
-				reader.g_id = read_uint32 (reader.current);
-				reader.current += 4;
+				jreader->g_id = read_uint32 (jreader->current);
+				jreader->current += 4;
 			} else {
 				/* default graph */
-				reader.g_id = 0;
+				jreader->g_id = 0;
 			}
 
-			if (reader.end - reader.current < 2 * sizeof (guint32)) {
+			if (jreader->end - jreader->current < 2 * sizeof (guint32)) {
 				/* damaged journal entry */
 				g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 				             "Damaged journal entry, %d < 2 * sizeof(guint32)",
-				             (gint) (reader.end - reader.current));
+				             (gint) (jreader->end - jreader->current));
 				return FALSE;
 			}
 
-			reader.s_id = read_uint32 (reader.current);
-			reader.current += 4;
+			jreader->s_id = read_uint32 (jreader->current);
+			jreader->current += 4;
 
-			reader.p_id = read_uint32 (reader.current);
-			reader.current += 4;
+			jreader->p_id = read_uint32 (jreader->current);
+			jreader->current += 4;
 
 			if (df & DATA_FORMAT_OBJECT_ID) {
-				if (reader.end - reader.current < sizeof (guint32)) {
+				if (jreader->end - jreader->current < sizeof (guint32)) {
 					/* damaged journal entry */
 					g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 					             "Damaged journal entry, %d < sizeof(guint32) for data format 2",
-					             (gint) (reader.end - reader.current));
+					             (gint) (jreader->end - jreader->current));
 					return FALSE;
 				}
 
-				reader.o_id = read_uint32 (reader.current);
-				reader.current += 4;
+				jreader->o_id = read_uint32 (jreader->current);
+				jreader->current += 4;
 			} else {
-				if (reader.end - reader.current < 1) {
+				if (jreader->end - jreader->current < 1) {
 					/* damaged journal entry */
 					g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 					             "Damaged journal entry, %d < 1",
-					             (gint) (reader.end - reader.current));
+					             (gint) (jreader->end - jreader->current));
 					return FALSE;
 				}
 
-				str_length = strnlen (reader.current, reader.end - reader.current);
-				if (str_length == reader.end - reader.current) {
+				str_length = strnlen (jreader->current, jreader->end - jreader->current);
+				if (str_length == jreader->end - jreader->current) {
 					/* damaged journal entry (no terminating '\0' character) */
 					g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 					             "Damaged journal entry, no terminating zero found");
 					return FALSE;
 				}
 
-				if (!g_utf8_validate (reader.current, -1, NULL)) {
+				if (!g_utf8_validate (jreader->current, -1, NULL)) {
 					/* damaged journal entry (invalid UTF-8) */
 					g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
 					             "Damaged journal entry, invalid UTF-8");
 					return FALSE;
 				}
 
-				reader.object = reader.current;
-				reader.current += str_length + 1;
+				jreader->object = jreader->current;
+				jreader->current += str_length + 1;
 			}
 		}
 
-		reader.amount_of_triples--;
+		jreader->amount_of_triples--;
 		return TRUE;
 	}
 
@@ -1262,6 +1315,38 @@ tracker_db_journal_reader_next (GError **error)
 	return FALSE;
 }
 
+gboolean
+tracker_db_journal_reader_next (GError **error)
+{
+	return db_journal_reader_next (&reader, TRUE, error);
+}
+
+gboolean
+tracker_db_journal_reader_verify_last (const gchar  *filename,
+                                       GError      **error)
+{
+	guint32 entry_size_check;
+	gboolean success = FALSE;
+	JournalReader jreader = { 0 };
+
+	if (db_journal_reader_init (&jreader, FALSE, filename)) {
+		entry_size_check = read_uint32 (jreader.end - 4);
+
+		if (jreader.end - entry_size_check < jreader.current) {
+			g_set_error (error, TRACKER_DB_JOURNAL_ERROR, 0, 
+			             "Damaged journal entry at end of journal");
+			db_journal_reader_shutdown (&jreader);
+			return FALSE;
+		}
+
+		jreader.current = jreader.end - entry_size_check;
+		success = db_journal_reader_next (&jreader, FALSE, NULL);
+		db_journal_reader_shutdown (&jreader);
+	}
+
+	return success;
+}
+
 gint64
 tracker_db_journal_reader_get_time (void)
 {
@@ -1331,3 +1416,102 @@ tracker_db_journal_reader_get_progress (void)
 	return (((gdouble)(reader.current - reader.start)) / percent);
 }
 
+static void
+on_chunk_copied_delete (GObject      *source_object,
+                        GAsyncResult *res,
+                        gpointer      user_data)
+{
+	GFile *source = G_FILE (source_object);
+	GError *error = NULL;
+
+	if (g_file_copy_finish (source, res, &error)) {
+		g_file_delete (G_FILE (source_object), NULL, &error);
+	}
+
+	if (error) {
+		g_critical ("Error moving rotated journal chunk: '%s'", error->message);
+		g_error_free (error);
+	}
+}
+
+static gboolean
+tracker_db_journal_rotate (void)
+{
+	gchar *fullpath;
+	static gint max = -1;
+	static gboolean needs_move;
+
+	if (max == -1) {
+		gchar *directory;
+		GDir *journal_dir;
+		const gchar *f_name;
+
+		directory = g_path_get_dirname (writer.journal_filename);
+		needs_move = (g_strcmp0 (rotating_settings.rotate_to, directory) != 0);
+		journal_dir = g_dir_open (directory, 0, NULL);
+
+		f_name = g_dir_read_name (journal_dir);
+
+		while (f_name) {
+			gchar *ptr;
+			guint cur;
+
+			if (f_name) {
+
+				if (!g_str_has_prefix (f_name, TRACKER_DB_JOURNAL_FILENAME ".")) {
+					f_name = g_dir_read_name (journal_dir);
+					continue;
+				}
+
+				ptr = strrchr (f_name, '.');
+				if (ptr) {
+					ptr++;
+					cur = atoi (ptr);
+					max = MAX (cur, max);
+				}
+			} 
+
+			f_name = g_dir_read_name (journal_dir);
+		}
+
+		g_dir_close (journal_dir);
+		g_free (directory);
+	}
+
+	tracker_db_journal_fsync ();
+
+	if (close (writer.journal) != 0) {
+		g_warning ("Could not close journal, %s", 
+		           g_strerror (errno));
+		return FALSE;
+	}
+
+	fullpath = g_strdup_printf ("%s.%d", writer.journal_filename, ++max);
+
+	g_rename (writer.journal_filename, fullpath);
+
+	g_free (fullpath);
+
+	if (max > 1 && needs_move) {
+		GFile *source, *destination;
+		GFile *dest_dir;
+		gchar *filename;
+
+		fullpath = g_strdup_printf ("%s.%d", writer.journal_filename, max - 1);
+		source = g_file_new_for_path (fullpath);
+		dest_dir = g_file_new_for_path (rotating_settings.rotate_to);
+		filename = g_path_get_basename (fullpath);
+		destination = g_file_get_child (dest_dir, filename);
+		g_object_unref (dest_dir);
+		g_free (filename);
+
+		g_file_copy_async (source, destination, G_FILE_COPY_OVERWRITE, 0,
+		                   NULL, NULL, NULL, on_chunk_copied_delete, NULL);
+
+		g_object_unref (destination);
+		g_object_unref (source);
+		g_free (fullpath);
+	}
+
+	return db_journal_init_file (&writer, TRUE);
+}
diff --git a/src/libtracker-db/tracker-db-journal.h b/src/libtracker-db/tracker-db-journal.h
index fefd515..6783aff 100644
--- a/src/libtracker-db/tracker-db-journal.h
+++ b/src/libtracker-db/tracker-db-journal.h
@@ -49,15 +49,19 @@ GQuark       tracker_db_journal_error_quark                  (void);
  * Writer API
  */
 gboolean     tracker_db_journal_init                         (const gchar *filename,
-                                                              gboolean     truncate,
-                                                              gboolean     do_rotating,
-                                                              gsize        chunk_size);
+                                                              gboolean     truncate);
 gboolean     tracker_db_journal_shutdown                     (void);
 
 const gchar* tracker_db_journal_get_filename                 (void);
 gsize        tracker_db_journal_get_size                     (void);
+
+void         tracker_db_journal_set_rotating                 (gboolean     do_rotating,
+                                                              gsize        chunk_size,
+                                                              const gchar *rotate_to);
+
 void         tracker_db_journal_get_rotating                 (gboolean    *do_rotating,
-                                                              gsize       *chunk_size);
+                                                              gsize       *chunk_size,
+                                                              gchar      **rotate_to);
 
 gboolean     tracker_db_journal_start_transaction            (time_t       time);
 gboolean     tracker_db_journal_start_ontology_transaction   (time_t       time);
@@ -110,7 +114,8 @@ gboolean     tracker_db_journal_reader_get_statement_id      (gint         *g_id
 gsize        tracker_db_journal_reader_get_size_of_correct   (void);
 gdouble      tracker_db_journal_reader_get_progress          (void);
 
-gboolean     tracker_db_journal_reader_verify_last           (GError **error);
+gboolean     tracker_db_journal_reader_verify_last           (const gchar  *filename,
+                                                              GError      **error);
 
 G_END_DECLS
 
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 3a32f58..f939104 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -438,40 +438,55 @@ db_manager_remove_all (gboolean rm_journal)
 		if (opath) {
 			GFile *file;
 			gchar *cpath;
-			gchar *directory;
-			GDir *journal_dir;
-			const gchar *f_name;
+			gchar *directory, *rotate_to = NULL;
+			gsize chunk_size;
+			gboolean do_rotate = FALSE;
+			const gchar *dirs[3] = { NULL, NULL, NULL };
 
 			cpath = g_strdup (opath);
-			tracker_db_journal_shutdown ();
 
 			g_message ("  Removing journal:'%s'", cpath);
 
 			directory = g_path_get_dirname (cpath);
-			journal_dir = g_dir_open (directory, 0, NULL);
-			f_name = g_dir_read_name (journal_dir);
 
-			/* Remove rotated chunks */
-			while (f_name) {
-				gchar *fullpath;
+			tracker_db_journal_get_rotating (&do_rotate, &chunk_size, &rotate_to);
 
-				if (f_name) {
-					if (!g_str_has_prefix (f_name, TRACKER_DB_JOURNAL_FILENAME ".")) {
-						f_name = g_dir_read_name (journal_dir);
-						continue;
-					}
-				}
+			tracker_db_journal_shutdown ();
+
+			dirs[0] = directory;
+			dirs[1] = do_rotate ? rotate_to : NULL;
 
-				fullpath = g_build_filename (directory, f_name, NULL);
-				file = g_file_new_for_path (fullpath);
-				g_file_delete (file, NULL, NULL);
-				g_object_unref (file);
-				g_free (fullpath);
+			for (i = 0; dirs[i] != NULL; i++) {
+				GDir *journal_dir;
+				const gchar *f_name;
 
+				journal_dir = g_dir_open (dirs[i], 0, NULL);
 				f_name = g_dir_read_name (journal_dir);
+
+				/* Remove rotated chunks */
+				while (f_name) {
+					gchar *fullpath;
+
+					if (f_name) {
+						if (!g_str_has_prefix (f_name, TRACKER_DB_JOURNAL_FILENAME ".")) {
+							f_name = g_dir_read_name (journal_dir);
+							continue;
+						}
+					}
+
+					fullpath = g_build_filename (dirs[i], f_name, NULL);
+					file = g_file_new_for_path (fullpath);
+					g_file_delete (file, NULL, NULL);
+					g_object_unref (file);
+					g_free (fullpath);
+
+					f_name = g_dir_read_name (journal_dir);
+				}
+
+				g_dir_close (journal_dir);
 			}
 
-			g_dir_close (journal_dir);
+			g_free (rotate_to);
 			g_free (directory);
 
 			/* Remove active journal */
@@ -876,11 +891,21 @@ tracker_db_manager_init (TrackerDBManagerFlags  flags,
 
 	} else {
 		gboolean must_recreate;
+		gchar *journal_filename;
 
 		/* Load databases */
 		g_message ("Loading databases files...");
 
-		must_recreate = !tracker_db_journal_reader_verify_last (NULL);
+		journal_filename = g_build_filename (g_get_user_data_dir (),
+		                                     "tracker",
+		                                     "data",
+		                                     TRACKER_DB_JOURNAL_FILENAME,
+		                                     NULL);
+
+		must_recreate = !tracker_db_journal_reader_verify_last (journal_filename,
+		                                                        NULL);
+
+		g_free (journal_filename);
 
 		if (!must_recreate && g_file_test (in_use_filename, G_FILE_TEST_EXISTS)) {
 			gsize size = 0;
@@ -1078,9 +1103,10 @@ tracker_db_manager_move_to_temp (void)
 {
 	guint i;
 	gchar *cpath, *new_filename;
-	gchar *directory;
-	GDir *journal_dir;
-	const gchar *f_name;
+	gchar *directory, *rotate_to = NULL;
+	const gchar *dirs[3] = { NULL, NULL, NULL };
+	gsize chunk_size = 0;
+	gboolean do_rotate = FALSE;
 
 	g_return_if_fail (initialized != FALSE);
 
@@ -1097,28 +1123,41 @@ tracker_db_manager_move_to_temp (void)
 	cpath = g_strdup (tracker_db_journal_get_filename ());
 
 	directory = g_path_get_dirname (cpath);
-	journal_dir = g_dir_open (directory, 0, NULL);
-	f_name = g_dir_read_name (journal_dir);
 
-	while (f_name) {
-		gchar *fullpath;
+	tracker_db_journal_get_rotating (&do_rotate, &chunk_size, &rotate_to);
 
-		if (f_name) {
-			if (!g_str_has_prefix (f_name, TRACKER_DB_JOURNAL_FILENAME ".")) {
-				f_name = g_dir_read_name (journal_dir);
-				continue;
+	dirs[0] = directory;
+	dirs[1] = do_rotate ? rotate_to : NULL;
+
+	for (i = 0; dirs[i] != NULL; i++) {
+		GDir *journal_dir;
+		const gchar *f_name;
+
+		journal_dir = g_dir_open (dirs[i], 0, NULL);
+		f_name = g_dir_read_name (journal_dir);
+
+		while (f_name) {
+			gchar *fullpath;
+
+			if (f_name) {
+				if (!g_str_has_prefix (f_name, TRACKER_DB_JOURNAL_FILENAME ".")) {
+					f_name = g_dir_read_name (journal_dir);
+					continue;
+				}
 			}
+
+			fullpath = g_build_filename (dirs[i], f_name, NULL);
+			new_filename = g_strdup_printf ("%s.tmp", fullpath);
+			g_rename (fullpath, new_filename);
+			g_free (new_filename);
+			g_free (fullpath);
+			f_name = g_dir_read_name (journal_dir);
 		}
 
-		fullpath = g_build_filename (directory, f_name, NULL);
-		new_filename = g_strdup_printf ("%s.tmp", fullpath);
-		g_rename (fullpath, new_filename);
-		g_free (new_filename);
-		g_free (fullpath);
-		f_name = g_dir_read_name (journal_dir);
+		g_dir_close (journal_dir);
 	}
 
-	g_dir_close (journal_dir);
+	g_free (rotate_to);
 	g_free (directory);
 
 	new_filename = g_strdup_printf ("%s.tmp", cpath);
@@ -1135,9 +1174,10 @@ tracker_db_manager_restore_from_temp (void)
 {
 	guint i;
 	gchar *cpath, *new_filename;
-	gchar *directory;
-	GDir *journal_dir;
-	const gchar *f_name;
+	gchar *directory, *rotate_to = NULL;
+	const gchar *dirs[3] = { NULL, NULL, NULL };
+	gsize chunk_size = 0;
+	gboolean do_rotate = FALSE;
 
 	g_return_if_fail (locations_initialized != FALSE);
 
@@ -1159,32 +1199,43 @@ tracker_db_manager_restore_from_temp (void)
 	g_free (new_filename);
 
 	directory = g_path_get_dirname (cpath);
-	journal_dir = g_dir_open (directory, 0, NULL);
-	f_name = g_dir_read_name (journal_dir);
+	tracker_db_journal_get_rotating (&do_rotate, &chunk_size, &rotate_to);
 
-	while (f_name) {
-		gchar *fullpath, *ptr;
+	dirs[0] = directory;
+	dirs[1] = do_rotate ? rotate_to : NULL;
 
-		if (f_name) {
-			if (!g_str_has_suffix (f_name, ".tmp")) {
-				f_name = g_dir_read_name (journal_dir);
-				continue;
+	for (i = 0; dirs[i] != NULL; i++) {
+		GDir *journal_dir;
+		const gchar *f_name;
+
+		journal_dir = g_dir_open (dirs[i], 0, NULL);
+		f_name = g_dir_read_name (journal_dir);
+
+		while (f_name) {
+			gchar *fullpath, *ptr;
+
+			if (f_name) {
+				if (!g_str_has_suffix (f_name, ".tmp")) {
+					f_name = g_dir_read_name (journal_dir);
+					continue;
+				}
 			}
-		}
 
-		fullpath = g_build_filename (directory, f_name, NULL);
-		new_filename = g_strdup (fullpath);
-		ptr = strstr (new_filename, ".tmp");
-		if (ptr) {
-			*ptr = '\0';
-			g_rename (fullpath, new_filename);
+			fullpath = g_build_filename (dirs[i], f_name, NULL);
+			new_filename = g_strdup (fullpath);
+			ptr = strstr (new_filename, ".tmp");
+			if (ptr) {
+				*ptr = '\0';
+				g_rename (fullpath, new_filename);
+			}
+			g_free (new_filename);
+			g_free (fullpath);
+			f_name = g_dir_read_name (journal_dir);
 		}
-		g_free (new_filename);
-		g_free (fullpath);
-		f_name = g_dir_read_name (journal_dir);
+		g_dir_close (journal_dir);
 	}
 
-	g_dir_close (journal_dir);
+	g_free (rotate_to);
 	g_free (directory);
 	g_free (cpath);
 }
@@ -1194,9 +1245,10 @@ tracker_db_manager_remove_temp (void)
 {
 	guint i;
 	gchar *cpath, *new_filename;
-	gchar *directory;
-	GDir *journal_dir;
-	const gchar *f_name;
+	gchar *directory, *rotate_to = NULL;
+	gsize chunk_size = 0;
+	gboolean do_rotate = FALSE;
+	const gchar *dirs[3] = { NULL, NULL, NULL };
 
 	g_return_if_fail (locations_initialized != FALSE);
 
@@ -1218,25 +1270,37 @@ tracker_db_manager_remove_temp (void)
 	g_free (new_filename);
 
 	directory = g_path_get_dirname (cpath);
-	journal_dir = g_dir_open (directory, 0, NULL);
-	f_name = g_dir_read_name (journal_dir);
+	tracker_db_journal_get_rotating (&do_rotate, &chunk_size, &rotate_to);
 
-	while (f_name) {
-		if (f_name) {
-			if (!g_str_has_suffix (f_name, ".tmp")) {
-				f_name = g_dir_read_name (journal_dir);
-				continue;
-			}
-		}
+	dirs[0] = directory;
+	dirs[1] = do_rotate ? rotate_to : NULL;
 
-		new_filename = g_build_filename (directory, f_name, NULL);
-		g_unlink (new_filename);
-		g_free (new_filename);
+	for (i = 0; dirs[i] != NULL; i++) {
+		GDir *journal_dir;
+		const gchar *f_name;
 
+		journal_dir = g_dir_open (dirs[i], 0, NULL);
 		f_name = g_dir_read_name (journal_dir);
+
+		while (f_name) {
+			if (f_name) {
+				if (!g_str_has_suffix (f_name, ".tmp")) {
+					f_name = g_dir_read_name (journal_dir);
+					continue;
+				}
+			}
+
+			new_filename = g_build_filename (dirs[i], f_name, NULL);
+			g_unlink (new_filename);
+			g_free (new_filename);
+
+			f_name = g_dir_read_name (journal_dir);
+		}
+
+		g_dir_close (journal_dir);
 	}
 
-	g_dir_close (journal_dir);
+	g_free (rotate_to);
 	g_free (directory);
 	g_free (cpath);
 }
diff --git a/src/libtracker-db/tracker-db.h b/src/libtracker-db/tracker-db.h
index 5af852f..ea11902 100644
--- a/src/libtracker-db/tracker-db.h
+++ b/src/libtracker-db/tracker-db.h
@@ -33,6 +33,7 @@ G_BEGIN_DECLS
 #include "tracker-db-interface-sqlite.h"
 #include "tracker-db-journal.h"
 #include "tracker-db-manager.h"
+#include "tracker-db-config.h"
 
 #undef __LIBTRACKER_DB_INSIDE__
 
diff --git a/src/tracker-control/tracker-control.c b/src/tracker-control/tracker-control.c
index 380b121..21f1d82 100644
--- a/src/tracker-control/tracker-control.c
+++ b/src/tracker-control/tracker-control.c
@@ -401,6 +401,13 @@ main (int argc, char **argv)
 
 	if (hard_reset || soft_reset) {
 		guint log_handler_id;
+		const gchar *rotate_to = NULL;
+		TrackerDBConfig *db_config;
+		gsize chunk_size;
+		gint chunk_size_mb;
+
+
+		db_config = tracker_db_config_new ();
 
 		/* Set log handler for library messages */
 		log_handler_id = g_log_set_handler (NULL,
@@ -410,8 +417,18 @@ main (int argc, char **argv)
 
 		g_log_set_default_handler (log_handler, NULL);
 
+		chunk_size_mb = tracker_db_config_get_journal_chunk_size (db_config);
+		chunk_size = (gsize) ((gsize) chunk_size_mb * (gsize) 1024 * (gsize) 1024);
+		rotate_to = tracker_db_config_get_journal_rotate_destination (db_config);
+
 		/* This call is needed to set the journal's filename */
-		tracker_db_journal_init (NULL, FALSE, FALSE, G_MAXSIZE);
+
+		tracker_db_journal_set_rotating ((chunk_size_mb != -1),
+		                                 chunk_size, rotate_to);
+
+		tracker_db_journal_init (NULL, FALSE);
+
+		g_object_unref (db_config);
 
 		/* Clean up */
 		if (!tracker_db_manager_init (TRACKER_DB_MANAGER_REMOVE_ALL, NULL, FALSE)) {
diff --git a/src/tracker-store/tracker-config.c b/src/tracker-store/tracker-config.c
index 5a5321a..349b9e8 100644
--- a/src/tracker-store/tracker-config.c
+++ b/src/tracker-store/tracker-config.c
@@ -33,21 +33,15 @@
 
 /* GKeyFile defines */
 #define GROUP_GENERAL     "General"
-#define GROUP_JOURNAL     "Journal"
 
 /* Default values */
-#define DEFAULT_VERBOSITY                 2
-#define DEFAULT_JOURNAL_CHUNK_SIZE        500
-#define DEFAULT_ENABLE_JOURNAL_ROTATING   TRUE
+#define DEFAULT_VERBOSITY                    2
 
 /* typedef struct TrackerConfigPrivate TrackerConfigPrivate; */
 
 typedef struct {
 	/* General */
 	gint verbosity;
-
-	/* Journal */
-	gint journal_chunk_size;
 } TrackerConfigPrivate;
 
 typedef struct {
@@ -77,14 +71,10 @@ enum {
 
 	/* General */
 	PROP_VERBOSITY,
-	/* Journal */
-	PROP_JOURNAL_CHUNK_SIZE,
-	PROP_ENABLE_JOURNAL_ROTATING
 };
 
 static ObjectToKeyFile conversions[] = {
-	{ G_TYPE_INT,     "verbosity",               GROUP_GENERAL,  "Verbosity"             },
-	{ G_TYPE_INT,     "journal-chunk-size",      GROUP_JOURNAL,  "JournalChunkSize"      },
+	{ G_TYPE_INT, "verbosity", GROUP_GENERAL,  "Verbosity" },
 };
 
 G_DEFINE_TYPE (TrackerConfig, tracker_config, TRACKER_TYPE_CONFIG_FILE);
@@ -110,16 +100,6 @@ tracker_config_class_init (TrackerConfigClass *klass)
 	                                                   DEFAULT_VERBOSITY,
 	                                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
-	g_object_class_install_property (object_class,
-	                                 PROP_JOURNAL_CHUNK_SIZE,
-	                                 g_param_spec_int    ("journal-chunk-size",
-	                                                      "Journal chunk size",
-	                                                      " Size of the journal at rotation in MB. Use -1 to disable rotating",
-	                                                      -1,
-	                                                      G_MAXINT,
-	                                                      DEFAULT_JOURNAL_CHUNK_SIZE,
-	                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
 	g_type_class_add_private (object_class, sizeof (TrackerConfigPrivate));
 }
 
@@ -140,11 +120,6 @@ config_set_property (GObject      *object,
 		tracker_config_set_verbosity (TRACKER_CONFIG (object),
 		                              g_value_get_int (value));
 		break;
-		/* Journal */
-	case PROP_JOURNAL_CHUNK_SIZE:
-		tracker_config_set_journal_chunk_size (TRACKER_CONFIG (object),
-		                                       g_value_get_int(value));
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -166,9 +141,6 @@ config_get_property (GObject    *object,
 	case PROP_VERBOSITY:
 		g_value_set_int (value, priv->verbosity);
 		break;
-	case PROP_JOURNAL_CHUNK_SIZE:
-		g_value_set_int (value, priv->journal_chunk_size);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -358,36 +330,6 @@ tracker_config_get_verbosity (TrackerConfig *config)
 	return priv->verbosity;
 }
 
-gint
-tracker_config_get_journal_chunk_size (TrackerConfig *config)
-{
-	TrackerConfigPrivate *priv;
-
-	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_JOURNAL_CHUNK_SIZE);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	return priv->journal_chunk_size;
-}
-
-void
-tracker_config_set_journal_chunk_size (TrackerConfig *config,
-                                       gint           value)
-{
-	TrackerConfigPrivate *priv;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-
-	if (!tracker_keyfile_object_validate_int (config, "journal-chunk-size", value)) {
-		return;
-	}
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	priv->journal_chunk_size = value;
-	g_object_notify (G_OBJECT (config), "journal-chunk-size");
-}
-
 void
 tracker_config_set_verbosity (TrackerConfig *config,
                               gint           value)
@@ -405,3 +347,4 @@ tracker_config_set_verbosity (TrackerConfig *config,
 	priv->verbosity = value;
 	g_object_notify (G_OBJECT (config), "verbosity");
 }
+
diff --git a/src/tracker-store/tracker-config.h b/src/tracker-store/tracker-config.h
index bde3cbc..a7dbe6b 100644
--- a/src/tracker-store/tracker-config.h
+++ b/src/tracker-store/tracker-config.h
@@ -49,12 +49,9 @@ GType          tracker_config_get_type                             (void) G_GNUC
 TrackerConfig *tracker_config_new                                  (void);
 gboolean       tracker_config_save                                 (TrackerConfig *config);
 gint           tracker_config_get_verbosity                        (TrackerConfig *config);
-gint           tracker_config_get_journal_chunk_size               (TrackerConfig *config);
 
 void           tracker_config_set_verbosity                        (TrackerConfig *config,
                                                                     gint           value);
-void           tracker_config_set_journal_chunk_size               (TrackerConfig *config,
-                                                                    gint           value);
 
 G_END_DECLS
 
diff --git a/src/tracker-store/tracker-main.c b/src/tracker-store/tracker-main.c
index 7006377..6ca37a4 100644
--- a/src/tracker-store/tracker-main.c
+++ b/src/tracker-store/tracker-main.c
@@ -44,6 +44,8 @@
 
 #include <libtracker-db/tracker-db-manager.h>
 #include <libtracker-db/tracker-db-dbus.h>
+#include <libtracker-db/tracker-db-config.h>
+#include <libtracker-db/tracker-db-journal.h>
 
 #include <libtracker-data/tracker-data-manager.h>
 #include <libtracker-data/tracker-data-backup.h>
@@ -335,6 +337,8 @@ main (gint argc, gchar *argv[])
 	TrackerBusyCallback busy_callback;
 	gint chunk_size_mb;
 	gsize chunk_size;
+	const gchar *rotate_to;
+	TrackerDBConfig *db_config;
 
 	g_type_init ();
 
@@ -400,6 +404,7 @@ main (gint argc, gchar *argv[])
 
 	/* Initialize major subsystems */
 	config = tracker_config_new ();
+	db_config = tracker_db_config_new ();
 
 	g_signal_connect (config, "notify::verbosity",
 	                  G_CALLBACK (config_verbosity_changed_cb),
@@ -416,6 +421,7 @@ main (gint argc, gchar *argv[])
 	initialize_directories ();
 
 	if (!tracker_dbus_init ()) {
+		g_object_unref (db_config);
 		return EXIT_FAILURE;
 	}
 
@@ -439,12 +445,16 @@ main (gint argc, gchar *argv[])
 	busy_callback = tracker_status_get_callback (notifier, 
 	                                            &busy_user_data);
 
-	chunk_size_mb = tracker_config_get_journal_chunk_size (config);
+	chunk_size_mb = tracker_db_config_get_journal_chunk_size (db_config);
 	chunk_size = (gsize) ((gsize) chunk_size_mb * (gsize) 1024 * (gsize) 1024);
+	rotate_to = tracker_db_config_get_journal_rotate_destination (db_config);
+
+	if (rotate_to[0] == '\0')
+		rotate_to = NULL;
+
+	tracker_db_journal_set_rotating ((chunk_size_mb != -1), chunk_size, rotate_to);
 
 	if (!tracker_data_manager_init (flags,
-	                                chunk_size_mb != -1,
-	                                chunk_size,
 	                                NULL,
 	                                &is_first_time_index,
 	                                TRUE,
@@ -452,10 +462,12 @@ main (gint argc, gchar *argv[])
 	                                busy_user_data,
 	                                "Journal replaying")) {
 
+		g_object_unref (db_config);
 		g_object_unref (notifier);
 		return EXIT_FAILURE;
 	}
 
+	g_object_unref (db_config);
 	g_object_unref (notifier);
 
 	tracker_store_init ();
@@ -511,6 +523,9 @@ main (gint argc, gchar *argv[])
 	g_signal_handlers_disconnect_by_func (config, config_verbosity_changed_cb, NULL);
 	g_object_unref (config);
 
+	/* This will free rotate_to up in the journal code */
+	tracker_db_journal_set_rotating ((chunk_size_mb != -1), chunk_size, NULL);
+
 	g_print ("\nOK\n\n");
 
 	return EXIT_SUCCESS;
diff --git a/tests/libtracker-data/tracker-backup-test.c b/tests/libtracker-data/tracker-backup-test.c
index 257edc0..a6acb8a 100644
--- a/tests/libtracker-data/tracker-backup-test.c
+++ b/tests/libtracker-data/tracker-backup-test.c
@@ -105,8 +105,9 @@ test_backup_and_restore_helper (gboolean journal)
 	test_schemas[2] = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", "ontologies", "90-tracker", NULL);
 	test_schemas[3] = data_prefix;
 
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           FALSE, G_MAXSIZE,
 	                           (const gchar **) test_schemas,
 	                           NULL, FALSE, NULL, NULL, NULL);
 
@@ -158,8 +159,9 @@ test_backup_and_restore_helper (gboolean journal)
 	g_unlink (meta_db);
 	g_free (meta_db);
 
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           FALSE, G_MAXSIZE,
 	                           (const gchar **) test_schemas,
 	                           NULL, FALSE, NULL, NULL, NULL);
 	check_content_in_db (0, 0);
diff --git a/tests/libtracker-data/tracker-ontology-test.c b/tests/libtracker-data/tracker-ontology-test.c
index a6f9c06..c7ae953 100644
--- a/tests/libtracker-data/tracker-ontology-test.c
+++ b/tests/libtracker-data/tracker-ontology-test.c
@@ -264,7 +264,9 @@ test_ontology_change (void)
 
                 g_chmod (ontology_file, 0666);
 
-		tracker_data_manager_init (0, FALSE, G_MAXSIZE, (const gchar **) test_schemas,
+		tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
+		tracker_data_manager_init (0, (const gchar **) test_schemas,
 		                           NULL, FALSE, NULL, NULL, NULL);
 
 		if (g_file_get_contents (update, &queries, NULL, NULL)) {
@@ -290,7 +292,9 @@ test_ontology_change (void)
 
 	delete_db (FALSE);
 
-	tracker_data_manager_init (0, FALSE, G_MAXSIZE, (const gchar **) test_schemas,
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
+	tracker_data_manager_init (0, (const gchar **) test_schemas,
 	                           NULL, TRUE, NULL, NULL, NULL);
 
 	for (i = 0; change_tests[i].test_name != NULL; i++) {
@@ -324,9 +328,10 @@ test_ontology_change (void)
 static void
 test_ontology_init (void)
 {
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
 	/* first-time initialization */
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           FALSE, G_MAXSIZE,
 	                           NULL,
 	                           NULL,
 	                           FALSE,
@@ -336,8 +341,10 @@ test_ontology_init (void)
 
 	tracker_data_manager_shutdown ();
 
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
 	/* initialization from existing database */
-	tracker_data_manager_init (0, FALSE, G_MAXSIZE,
+	tracker_data_manager_init (0,
 	                           NULL,
 	                           NULL,
 	                           FALSE,
@@ -367,9 +374,10 @@ test_query (gconstpointer test_data)
 	test_prefix = g_build_filename (prefix, test_info->test_name, NULL);
 	g_free (prefix);
 
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
 	/* initialization */
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           FALSE, G_MAXSIZE,
 	                           NULL,
 	                           NULL, 
 	                           FALSE,
diff --git a/tests/libtracker-data/tracker-sparql-blank-test.c b/tests/libtracker-data/tracker-sparql-blank-test.c
index 73d1807..8340a21 100644
--- a/tests/libtracker-data/tracker-sparql-blank-test.c
+++ b/tests/libtracker-data/tracker-sparql-blank-test.c
@@ -40,9 +40,10 @@ test_blank (void)
 
 	error = NULL;
 
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
 	/* initialization */
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           FALSE, G_MAXSIZE,
 	                           NULL,
 	                           NULL,
 	                           FALSE,
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index 25ed6ed..ba2d57e 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -239,8 +239,10 @@ test_sparql_query (gconstpointer test_data)
 	g_free (prefix);
 
 	test_schemas[0] = data_prefix;
+
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           FALSE, G_MAXSIZE,
 	                           test_schemas,
 	                           NULL, FALSE, NULL, NULL, NULL);
 
diff --git a/tests/libtracker-db/tracker-db-journal.c b/tests/libtracker-db/tracker-db-journal.c
index 5a2c623..b2631a0 100644
--- a/tests/libtracker-db/tracker-db-journal.c
+++ b/tests/libtracker-db/tracker-db-journal.c
@@ -29,13 +29,15 @@ test_init_and_shutdown (void)
 	gboolean result;
 
 	/* check double init/shutdown */
-	result = tracker_db_journal_init (NULL, FALSE, FALSE, G_MAXSIZE);
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+	result = tracker_db_journal_init (NULL, FALSE);
 	g_assert (result == TRUE);
 
 	result = tracker_db_journal_shutdown ();
 	g_assert (result == TRUE);
 
-	result = tracker_db_journal_init (NULL, FALSE, FALSE, G_MAXSIZE);
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+	result = tracker_db_journal_init (NULL, FALSE);
 	g_assert (result == TRUE);
 
 	result = tracker_db_journal_shutdown ();
@@ -53,9 +55,10 @@ test_write_functions (void)
 	path = g_build_filename (TOP_BUILDDIR, "tests", "libtracker-db", "tracker-store.journal", NULL);
 	g_unlink (path);
 
-	tracker_db_journal_init (path, FALSE, FALSE, G_MAXSIZE);
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
+	tracker_db_journal_init (path, FALSE);
 
-        filename = tracker_db_journal_get_filename ();
+	filename = tracker_db_journal_get_filename ();
 	g_assert (filename != NULL);
 	g_assert_cmpstr (filename, ==, path);
 
diff --git a/tests/libtracker-fts/tracker-fts-test.c b/tests/libtracker-fts/tracker-fts-test.c
index fb9aecd..8cc5a9e 100644
--- a/tests/libtracker-fts/tracker-fts-test.c
+++ b/tests/libtracker-fts/tracker-fts-test.c
@@ -72,8 +72,8 @@ test_sparql_query (gconstpointer test_data)
 	g_free (prefix);
 
 	test_schemas[0] = data_prefix;
+	tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           FALSE, G_MAXSIZE,
 	                           test_schemas,
 	                           NULL, FALSE, NULL, NULL, NULL);
 



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