[tracker] Squashed commit of the following:
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker] Squashed commit of the following:
- Date: Tue, 25 Aug 2009 13:05:17 +0000 (UTC)
commit 1f19ed577b308c2561277eeec151909c91883f89
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Aug 25 15:01:12 2009 +0200
Squashed commit of the following:
commit 65ef93d8e11f03b2d825f40b41a3bccb821abf07
Merge: 08017cb 54e6080
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Aug 25 14:58:34 2009 +0200
Merge branch 'master' into urho-sync
Conflicts:
tests/libtracker-data/tracker-ontology-test.c
tests/libtracker-data/tracker-sparql-test.c
commit 08017cbb8a3e1a373f88c6842fb526e916009025
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Aug 25 12:45:56 2009 +0200
Limiting the size of the log file
commit 2b6623eae4c52c232d05ae01ab77bdaca0f9d1ba
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 16:29:11 2009 +0200
Added some code comments
commit 28e0498331c6fe0914528cd17f035339931bfa53
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 16:14:44 2009 +0200
Start save of backup over DBus after queue's commit
commit 4c59007564f1138c01a66e2e45f891d157da03e8
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 15:57:19 2009 +0200
Fixed restore on startup of meta.db is missing and meta-backup.db isn't
commit e43ce2eaadda7759c3e5ca7aa73c8e40543343e2
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 15:17:37 2009 +0200
Adding kill to soft-reset
commit b7866eded285c138673c767e2979342c89fa1b37
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 14:50:38 2009 +0200
Made DBus's Restore() synchronous
commit 70eae9cb2c4747d226e687e10452e6e4054fcd27
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 14:23:31 2009 +0200
Fixed path of the meta-backup.db file
commit bbc39e88fa6affbe570676a304b7eee520e7e8e1
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 14:21:25 2009 +0200
Fixed restore after tracker-processes -s
commit a98ac7a5fcc9c4a6957ba292274a2211913ce06d
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 13:31:08 2009 +0200
Revert changes to INSTALL file
commit 0016d9d9a0811abb9a098b49da64db6c1febee86
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 12:39:22 2009 +0200
Code cleanup
commit a10c615c63e35c548d3255cdc93632012ab5ae69
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 12:24:02 2009 +0200
Code cleanup
commit 3de8d7d0a2447840bd4c4168a9993fc78d504ad3
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 12:02:58 2009 +0200
Added transaction barriers to the journal player
commit 6af3250b97b79c4adefa518306081c1e86e42be3
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 12:00:15 2009 +0200
Improvement for tracker-processes util
commit 636d9670bd79ca4f86350acd85818fcd5679527e
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 11:47:16 2009 +0200
Fixed finding location of meta-backup.db
commit d487838385db6ec4b3f7d89fc11440be60813a73
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 24 11:44:40 2009 +0200
Play journal always when meta.db didn't exist
commit 013b277d1f3079d228f20a8fc14b11da8d5f8f6e
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Aug 21 17:11:44 2009 +0200
Changed the format of the log, playing it using mmap
commit a61dbf091354411c093674105039e1546e7a3151
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Aug 21 11:19:23 2009 +0200
No need to do an extra fsync of commit causes one already
commit e329dbca27a1ee5258757a0ff0c051097ecb93a6
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Aug 21 11:12:39 2009 +0200
Fixed logic, the timeout is for backup, the max for fsync
commit ed462a8126c9a2314d4adb516183340067a96b7b
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Aug 21 11:06:14 2009 +0200
Fixed another glitch
commit 67fa0312d568718effb797d77308b5133d3d76e2
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Aug 21 11:00:46 2009 +0200
Make it exact
commit d5ab45435cc1a2e9b56fbafb04a82f150c843e51
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Aug 21 10:58:04 2009 +0200
Make fsync happen less often on the journal
commit 250362370069b56cd0b134fb7db02d9b561c52ef
Author: Jürg Billeter <j bitron ch>
Date: Fri Aug 21 09:37:35 2009 +0200
Remove raptor.h include
commit 18048eeda22eb94030a32e6f59e4c5ca0fa53579
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Aug 20 15:35:30 2009 +0200
Several bugfixes in backup and restore
commit 0bdb823b6b13081ff88a98c0e9bc0bb62d655e24
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Aug 20 15:09:38 2009 +0200
Playing the journal on restore
commit b937a201f7588a4f401bc13f51e47a4754e1e3b2
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Aug 20 14:58:54 2009 +0200
Changed the paths of the meta-backup and the journal
commit 142a32f01e4a43275d954e48b1134ba4a7a965db
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Aug 20 12:47:04 2009 +0200
Backup and restore support
commit 2ef24a4563c2e6fab6f17b0a1926602135639cb4
Merge: a7a7339 8a66865
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Aug 20 10:56:00 2009 +0200
Merge branch 'master' into urho-sync
commit a7a73398baa8d87ecdb32b0228ffb78c5818a36e
Merge: 2c25a57 d8aebcb
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Aug 19 15:39:40 2009 +0200
Merge branch 'master' into urho-sync
Conflicts:
src/tracker-store/tracker-main.c
commit 2c25a572dbadf53ed5d9316d1eb61c0655335e98
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Aug 19 15:30:58 2009 +0200
Atomic rename and journal load
commit a3eec4151daadc9c575edc0174e2e610e50e61e4
Merge: 82003a5 377dc98
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Aug 19 15:16:18 2009 +0200
Merge branch 'master' into urho-sync
commit 82003a5114bb6fd3ee69190be56e251afb7adace
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Aug 5 11:16:47 2009 +0200
Don't perform the check when need_journal isn't passed
commit 57e8168e31fcd5322798bd2b66f1f079b100ed76
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Aug 5 10:43:02 2009 +0200
Refactored the journal code a bit
commit b37be6edbf55d3b43960fa87fd3b0322c9ae121a
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Aug 4 16:42:39 2009 +0200
Fixed a critical warning
commit 06fee84f767a2363c8eac30ccd424ac1f932d975
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Aug 4 16:35:55 2009 +0200
Changed the logic about journal playing and meta-backup.db picking
commit fab94fb68cc9b044ac84641ab4f80fba387233fd
Author: Philip Van Hoof <philip codeminded be>
Date: Tue Aug 4 14:11:21 2009 +0200
Comment with a warning about the journal in a rare case
commit 94ae1fbfa25b6c2faa1e073ec171c5f5bc6cb3d6
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Aug 3 18:28:36 2009 +0200
Restoring the db using a backup on corruption
commit 47e8885909a6b89559788a1f789d2902eedadfb2
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Jul 31 17:45:19 2009 +0200
Setting sync=off as the journal is being made now
commit f697a726b69df2e91b5c5daeb31e9252fa2a3ba2
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Jul 31 17:43:28 2009 +0200
Added missing files
commit 9bcfa4e19b7042c7c315eecb9fb7d7939050bf36
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Jul 31 17:41:43 2009 +0200
Experiment for journal synchronization mode
data/dbus/tracker-backup.xml | 6 +-
src/libtracker-data/tracker-data-backup.c | 224 +++++++++++++++++---
src/libtracker-data/tracker-data-backup.h | 16 +-
src/libtracker-data/tracker-data-manager.c | 5 +-
src/libtracker-data/tracker-data-manager.h | 3 +-
src/libtracker-db/Makefile.am | 8 +-
src/libtracker-db/tracker-db-backup.c | 269 +++++++++++++++++++++++
src/libtracker-db/tracker-db-backup.h | 51 +++++
src/libtracker-db/tracker-db-interface-sqlite.c | 100 +++++++--
src/libtracker-db/tracker-db-interface.c | 18 ++
src/libtracker-db/tracker-db-interface.h | 4 +
src/libtracker-db/tracker-db-journal.c | 167 ++++++++++++++
src/libtracker-db/tracker-db-journal.h | 47 ++++
src/libtracker-db/tracker-db-manager.c | 169 +++++++++++++-
src/libtracker-db/tracker-db-manager.h | 13 +-
src/tracker-store/tracker-backup.c | 98 ++++++---
src/tracker-store/tracker-backup.h | 6 +-
src/tracker-store/tracker-main.c | 11 +-
src/tracker-store/tracker-resources.c | 4 +
src/tracker-store/tracker-store.c | 136 +++++++++++-
src/tracker-store/tracker-store.h | 5 +-
src/tracker-utils/tracker-processes.c | 15 +-
tests/libtracker-data/tracker-ontology-test.c | 2 +-
tests/libtracker-data/tracker-sparql-test.c | 2 +-
24 files changed, 1242 insertions(+), 137 deletions(-)
---
diff --git a/data/dbus/tracker-backup.xml b/data/dbus/tracker-backup.xml
index 7ba81d2..44f93f0 100644
--- a/data/dbus/tracker-backup.xml
+++ b/data/dbus/tracker-backup.xml
@@ -4,11 +4,13 @@
<interface name="org.freedesktop.Tracker1.Backup">
<method name="Save">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg type="s" name="turtle-file-uri" direction="in" />
+ <arg type="s" name="destination-uri" direction="in" />
+ <arg type="s" name="journal-uri" direction="in" />
</method>
<method name="Restore">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg type="s" name="turtle-file-uri" direction="in" />
+ <arg type="s" name="backup-uri" direction="in" />
+ <arg type="s" name="journal-uri" direction="in" />
</method>
</interface>
</node>
diff --git a/src/libtracker-data/tracker-data-backup.c b/src/libtracker-data/tracker-data-backup.c
index 9a548ae..fc2ddc3 100644
--- a/src/libtracker-data/tracker-data-backup.c
+++ b/src/libtracker-data/tracker-data-backup.c
@@ -23,63 +23,235 @@
#include <glib.h>
#include <glib/gstdio.h>
-#include <libtracker-data/tracker-data-query.h>
+#include <libtracker-db/tracker-db-manager.h>
+#include <libtracker-db/tracker-db-journal.h>
+#include <libtracker-db/tracker-db-backup.h>
#include "tracker-data-backup.h"
typedef struct {
- TrackerBackupFinished callback;
+ GFile *destination, *journal, *file;
+ TrackerDataBackupFinished callback;
gpointer user_data;
GDestroyNotify destroy;
-} UnImplementedInfo;
+ GError *error;
+} BackupSaveInfo;
-GQuark
-tracker_data_backup_error_quark (void)
+static void
+free_backup_save_info (BackupSaveInfo *info)
{
- return g_quark_from_static_string ("tracker-data-backup-error-quark");
+ if (info->destination) {
+ g_object_unref (info->destination);
+ }
+ if (info->journal) {
+ g_object_unref (info->journal);
+ }
+ if (info->file) {
+ g_object_unref (info->file);
+ }
+
+ if (info->destroy) {
+ info->destroy (info->user_data);
+ }
+
+ g_clear_error (&info->error);
+
+ g_free (info);
}
-static gboolean
-unimplemented (gpointer user_data)
+
+static void
+on_meta_copied (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- UnImplementedInfo *info = user_data;
+ BackupSaveInfo *info = user_data;
+ GError *error = NULL;
- g_warning ("tracker_data_backup_save is unimplemented");
+ g_file_copy_finish (info->file, res, &error);
if (info->callback) {
- GError *error = NULL;
+ info->callback (error, info->user_data);
+ }
- g_set_error (&error,
- TRACKER_DB_BACKUP_ERROR,
- TRACKER_DB_BACKUP_ERROR_UNKNOWN,
- "tracker_data_backup_save is unimplemented");
+ free_backup_save_info (info);
- info->callback (error, info->user_data);
- g_clear_error (&error);
+ g_clear_error (&error);
+}
+
+static void
+on_journal_copied (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ BackupSaveInfo *info = user_data;
+ GError *error = NULL;
+
+ if (!g_file_copy_finish (info->journal, res, &error)) {
+ if (info->callback) {
+ info->callback (error, info->user_data);
+ }
+ free_backup_save_info (info);
+ } else {
+ g_file_copy_async (info->file, info->destination,
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_HIGH,
+ NULL, NULL, NULL,
+ on_meta_copied,
+ info);
}
- if (info->destroy) {
- info->destroy (info->user_data);
+ g_clear_error (&error);
+}
+
+static void
+save_copy_procedure (BackupSaveInfo *info)
+{
+ GFile *journal_o;
+
+ journal_o = g_file_new_for_path (tracker_db_journal_filename ());
+
+ if (g_file_query_exists (journal_o, NULL)) {
+ g_file_copy_async (journal_o, info->journal,
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_HIGH,
+ NULL, NULL, NULL,
+ on_journal_copied,
+ info);
+ } else {
+ g_file_copy_async (info->file, info->destination,
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_HIGH,
+ NULL, NULL, NULL,
+ on_meta_copied,
+ info);
}
+ g_object_unref (journal_o);
+}
+
+static void
+on_backup_finished (GError *error, gpointer user_data)
+{
+ BackupSaveInfo *info = user_data;
+
+ if (error) {
+ if (info->callback) {
+ info->callback (error, info->user_data);
+ }
+ free_backup_save_info (info);
+ return;
+ }
+
+ save_copy_procedure (info);
}
void
-tracker_data_backup_save (GFile *turtle_file,
- TrackerBackupFinished callback,
+tracker_data_backup_save (GFile *destination,
+ GFile *journal,
+ TrackerDataBackupFinished callback,
gpointer user_data,
GDestroyNotify destroy)
{
- UnImplementedInfo *info = g_new(UnImplementedInfo, 1);
+ BackupSaveInfo *info;
+ info = g_new0 (BackupSaveInfo, 1);
+ info->destination = g_object_ref (destination);
+ info->journal = g_object_ref (journal);
info->callback = callback;
info->user_data = user_data;
info->destroy = destroy;
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- callback,
- info,
- NULL);
+ info->file = tracker_db_backup_file (NULL, TRACKER_DB_BACKUP_META_FILENAME);
+
+ if (g_file_query_exists (info->file, NULL)) {
+ /* Making a backup just means copying meta-backup.db */
+ save_copy_procedure (info);
+ } else {
+ /* If we don't have a meta-backup.db yet, we first make one */
+ tracker_db_backup_save (on_backup_finished,
+ info, NULL);
+ }
}
+static gboolean
+on_restore_done (gpointer user_data)
+{
+ BackupSaveInfo *info = user_data;
+ if (info->callback) {
+ info->callback (info->error, info->user_data);
+ }
+
+ free_backup_save_info (info);
+
+ return FALSE;
+}
+
+static void
+restore_copy_procedure (BackupSaveInfo *info)
+{
+ GFile *journal_d;
+ GError *error = NULL;
+
+ /* Restore should block the mainloop until finished */
+
+ journal_d = g_file_new_for_path (tracker_db_journal_filename ());
+
+ if (g_file_query_exists (journal_d, NULL)) {
+ g_file_copy (info->journal, journal_d,
+ G_FILE_COPY_OVERWRITE,
+ NULL, NULL, NULL,
+ &error);
+ }
+
+ g_object_unref (journal_d);
+
+ if (error) {
+ goto error_handle;
+ }
+
+ g_file_copy (info->destination, info->file,
+ G_FILE_COPY_OVERWRITE,
+ NULL, NULL, NULL,
+ &error);
+
+ if (error) {
+ goto error_handle;
+ }
+
+error_handle:
+
+ info->error = error;
+}
+
+void
+tracker_data_backup_restore (GFile *backup,
+ GFile *journal,
+ TrackerDataBackupFinished callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ BackupSaveInfo *info;
+
+ tracker_db_manager_disconnect ();
+ tracker_db_journal_close ();
+
+ info = g_new0 (BackupSaveInfo, 1);
+ info->destination = g_object_ref (backup);
+ info->journal = g_object_ref (journal);
+ info->callback = callback;
+ info->user_data = user_data;
+ info->destroy = destroy;
+
+ info->file = tracker_db_backup_file (NULL, TRACKER_DB_BACKUP_META_FILENAME);
+
+ /* This is all synchronous, blocking the mainloop indeed */
+
+ restore_copy_procedure (info);
+
+ tracker_db_journal_open ();
+ tracker_db_manager_reconnect ();
+
+ g_idle_add (on_restore_done, info);
+}
diff --git a/src/libtracker-data/tracker-data-backup.h b/src/libtracker-data/tracker-data-backup.h
index e0dc7ad..11ab5ab 100644
--- a/src/libtracker-data/tracker-data-backup.h
+++ b/src/libtracker-data/tracker-data-backup.h
@@ -26,18 +26,16 @@
G_BEGIN_DECLS
-#define TRACKER_DB_BACKUP_ERROR (tracker_data_backup_error_quark ())
-
-typedef enum {
- TRACKER_DB_BACKUP_ERROR_UNKNOWN,
-} TrackerDBBackupError;
-
-typedef void (*TrackerBackupFinished) (GError *error, gpointer user_data);
+typedef void (*TrackerDataBackupFinished) (GError *error, gpointer user_data);
GQuark tracker_data_backup_error_quark (void);
-void tracker_data_backup_save (GFile *turtle_file,
- TrackerBackupFinished callback,
+void tracker_data_backup_save (GFile *destination, GFile *journal,
+ TrackerDataBackupFinished callback,
+ gpointer user_data,
+ GDestroyNotify destroy);
+void tracker_data_backup_restore (GFile *backup, GFile *journal,
+ TrackerDataBackupFinished callback,
gpointer user_data,
GDestroyNotify destroy);
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 4c63d59..a35fc2d 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -747,7 +747,8 @@ create_fts_table (TrackerDBInterface *iface)
gboolean
tracker_data_manager_init (TrackerDBManagerFlags flags,
const gchar *test_schema,
- gboolean *first_time)
+ gboolean *first_time,
+ gboolean *need_journal)
{
TrackerDBInterface *iface;
gboolean is_first_time_index;
@@ -756,7 +757,7 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
return TRUE;
}
- tracker_db_manager_init (flags, &is_first_time_index, FALSE);
+ tracker_db_manager_init (flags, &is_first_time_index, FALSE, need_journal);
if (first_time != NULL) {
*first_time = is_first_time_index;
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index e0cfe40..2a7c7e9 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -36,7 +36,8 @@ G_BEGIN_DECLS
gboolean tracker_data_manager_init (TrackerDBManagerFlags flags,
const gchar *test_schema,
- gboolean *first_time);
+ gboolean *first_time,
+ gboolean *need_journal);
void tracker_data_manager_shutdown (void);
gint64 tracker_data_manager_get_db_option_int64 (const gchar *option);
diff --git a/src/libtracker-db/Makefile.am b/src/libtracker-db/Makefile.am
index 951359b..cbbfd00 100644
--- a/src/libtracker-db/Makefile.am
+++ b/src/libtracker-db/Makefile.am
@@ -18,13 +18,17 @@ libtracker_db_la_SOURCES = \
tracker-db-dbus.c \
tracker-db-interface.c \
tracker-db-interface-sqlite.c \
- tracker-db-manager.c
+ tracker-db-manager.c \
+ tracker-db-backup.c \
+ tracker-db-journal.c
noinst_HEADERS = \
tracker-db-dbus.h \
tracker-db-interface.h \
tracker-db-interface-sqlite.h \
- tracker-db-manager.h
+ tracker-db-manager.h \
+ tracker-db-backup.h \
+ tracker-db-journal.h
libtracker_db_la_LIBADD = \
$(top_builddir)/src/libtracker-common/libtracker-common.la \
diff --git a/src/libtracker-db/tracker-db-backup.c b/src/libtracker-db/tracker-db-backup.c
new file mode 100644
index 0000000..e278eef
--- /dev/null
+++ b/src/libtracker-db/tracker-db-backup.c
@@ -0,0 +1,269 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <sqlite3.h>
+
+#include <libtracker-common/tracker-ontology.h>
+#include <libtracker-db/tracker-db-manager.h>
+#include <libtracker-db/tracker-db-interface-sqlite.h>
+
+#include "tracker-db-backup.h"
+
+#define TRACKER_DB_BACKUP_META_FILENAME_T "meta-backup.db.tmp"
+
+typedef struct {
+ TrackerDBBackupFinished callback;
+ GDestroyNotify destroy;
+ gpointer user_data;
+ GError *error;
+ sqlite3_stmt *stmt;
+ sqlite3 *db, *backup_temp;
+ sqlite3_backup *backup_db;
+ gchar *backup_fname;
+ int result;
+ GFile *parent;
+} BackupInfo;
+
+GQuark
+tracker_db_backup_error_quark (void)
+{
+ return g_quark_from_static_string ("tracker-db-backup-error-quark");
+}
+
+static gboolean
+perform_callback (gpointer user_data)
+{
+ BackupInfo *info = user_data;
+
+ if (info->callback) {
+ info->callback (info->error, info->user_data);
+ }
+
+ return FALSE;
+}
+
+static void
+backup_info_free (gpointer user_data)
+{
+ BackupInfo *info = user_data;
+
+ if (info->parent) {
+ g_object_unref (info->parent);
+ }
+
+ if (info->destroy) {
+ info->destroy (info->user_data);
+ }
+
+ g_clear_error (&info->error);
+
+ if (info->stmt) {
+ sqlite3_finalize (info->stmt);
+ }
+
+ if (info->backup_db) {
+ sqlite3_backup_finish (info->backup_db);
+ info->backup_db = NULL;
+ }
+
+ if (info->backup_temp) {
+ sqlite3_close (info->backup_temp);
+ }
+
+ if (info->db) {
+ sqlite3_close (info->db);
+ }
+
+ if (info->backup_fname) {
+ g_free (info->backup_fname);
+ }
+
+ g_free (info);
+}
+
+
+static gboolean
+backup_file_step (gpointer user_data)
+{
+ BackupInfo *info = user_data;
+ guint cnt = 0;
+ gboolean cont = TRUE;
+
+ while (cont && info->result == SQLITE_OK) {
+
+ info->result = sqlite3_backup_step(info->backup_db, 5);
+
+ switch (info->result) {
+ case SQLITE_OK:
+ break;
+
+ case SQLITE_ERROR:
+ default:
+ cont = FALSE;
+ break;
+ }
+
+ if (cnt > 100) {
+ break;
+ }
+
+ cnt++;
+ }
+
+ return cont;
+}
+
+static void
+on_backup_temp_finished (gpointer user_data)
+{
+ BackupInfo *info = user_data;
+
+ if (info->backup_db) {
+ sqlite3_backup_finish (info->backup_db);
+ info->backup_db = NULL;
+ }
+
+ if (info->db) {
+ sqlite3_close (info->db);
+ info->db = NULL;
+ }
+
+
+ if (!info->error && info->result != SQLITE_DONE) {
+ g_set_error (&info->error, TRACKER_DB_BACKUP_ERROR,
+ TRACKER_DB_BACKUP_ERROR_UNKNOWN,
+ "%s", sqlite3_errmsg (info->backup_temp));
+ }
+
+ if (!info->error) {
+ GFile *from_file, *to_file;
+
+ from_file = g_file_get_child (info->parent, TRACKER_DB_BACKUP_META_FILENAME_T);
+ to_file = g_file_get_child (info->parent, TRACKER_DB_BACKUP_META_FILENAME);
+
+ g_file_move (from_file, to_file,
+ G_FILE_COPY_OVERWRITE,
+ NULL, NULL, NULL,
+ &info->error);
+
+ g_object_unref (from_file);
+ g_object_unref (to_file);
+ }
+
+ perform_callback (info);
+
+ backup_info_free (info);
+
+ return;
+}
+
+GFile *
+tracker_db_backup_file (GFile **parent_out, const gchar *type)
+{
+ GFile *file, *parent;
+ gchar *parent_path;
+
+ parent_path = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ NULL);
+
+ parent = g_file_new_for_path (parent_path);
+ file = g_file_get_child (parent, type);
+
+ if (parent_out) {
+ *parent_out = parent;
+ } else {
+ g_object_unref (parent);
+ }
+
+ g_free (parent_path);
+
+ return file;
+}
+
+
+void
+tracker_db_backup_save (TrackerDBBackupFinished callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ const gchar *db_file = tracker_db_manager_get_file (TRACKER_DB_METADATA);
+ BackupInfo *info = g_new0 (BackupInfo, 1);
+ GFile *file;
+
+ /* This procedure makes a meta-backup.db using sqlite3_backup API */
+
+ info->callback = callback;
+ info->user_data = user_data;
+ info->destroy = destroy;
+
+ file = tracker_db_backup_file (&info->parent, TRACKER_DB_BACKUP_META_FILENAME_T);
+ info->backup_fname = g_file_get_path (file);
+ g_object_unref (file);
+
+ if (sqlite3_open_v2 (db_file, &info->db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) {
+ g_set_error (&info->error, TRACKER_DB_BACKUP_ERROR, TRACKER_DB_BACKUP_ERROR_UNKNOWN,
+ "Could not open sqlite3 database:'%s'", db_file);
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, perform_callback, info,
+ backup_info_free);
+
+ return;
+ }
+
+ if (sqlite3_open (info->backup_fname, &info->backup_temp) != SQLITE_OK) {
+ g_set_error (&info->error, TRACKER_DB_BACKUP_ERROR, TRACKER_DB_BACKUP_ERROR_UNKNOWN,
+ "Could not open sqlite3 database:'%s'", info->backup_fname);
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, perform_callback, info,
+ backup_info_free);
+
+ return;
+ }
+
+ info->backup_db = sqlite3_backup_init (info->backup_temp, "main",
+ info->db, "main");
+
+ if (!info->backup_db) {
+ g_set_error (&info->error, TRACKER_DB_BACKUP_ERROR, TRACKER_DB_BACKUP_ERROR_UNKNOWN,
+ "Unknown error creating backup db: '%s'", info->backup_fname);
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, perform_callback, info,
+ backup_info_free);
+
+ return;
+ }
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, backup_file_step, info,
+ on_backup_temp_finished);
+}
+
+
+
+
diff --git a/src/libtracker-db/tracker-db-backup.h b/src/libtracker-db/tracker-db-backup.h
new file mode 100644
index 0000000..1769f96
--- /dev/null
+++ b/src/libtracker-db/tracker-db-backup.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+
+#ifndef __TRACKER_DB_BACKUP_H__
+#define __TRACKER_DB_BACKUP_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#define TRACKER_DB_BACKUP_META_FILENAME "meta-backup.db"
+
+G_BEGIN_DECLS
+
+#define TRACKER_DB_BACKUP_ERROR (tracker_db_backup_error_quark ())
+
+typedef enum {
+ TRACKER_DB_BACKUP_ERROR_UNKNOWN,
+} TrackerDBBackupError;
+
+typedef void (*TrackerDBBackupFinished) (GError *error, gpointer user_data);
+
+GQuark tracker_db_backup_error_quark (void);
+
+void tracker_db_backup_save (TrackerDBBackupFinished callback,
+ gpointer user_data,
+ GDestroyNotify destroy);
+GFile * tracker_db_backup_file (GFile **parent_out,
+ const gchar *type);
+
+G_END_DECLS
+
+#endif /* __TRACKER_DB_BACKUP_H__ */
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index ac869a3..921f3c0 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -21,8 +21,10 @@
#include "config.h"
#include <glib/gstdio.h>
+
#include <sqlite3.h>
#include <stdlib.h>
+#include <libtracker-common/tracker-common.h>
#include <tracker-fts/tracker-fts.h>
@@ -71,6 +73,8 @@ struct SqliteAggregateData {
static void tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface);
static void tracker_db_statement_sqlite_iface_init (TrackerDBStatementIface *iface);
+static void tracker_db_interface_sqlite_disconnect (TrackerDBInterface *db_interface);
+static void tracker_db_interface_sqlite_reconnect (TrackerDBInterface *db_interface);
static TrackerDBStatementSqlite * tracker_db_statement_sqlite_new (TrackerDBInterfaceSqlite *db_interface,
sqlite3_stmt *sqlite_stmt);
@@ -97,20 +101,12 @@ tracker_db_interface_sqlite_enable_shared_cache (void)
sqlite3_enable_shared_cache (1);
}
-static GObject *
-tracker_db_interface_sqlite_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_params)
+static void
+open_database (TrackerDBInterfaceSqlitePrivate *priv)
{
- GObject *object;
- TrackerDBInterfaceSqlitePrivate *priv;
gchar *err_msg = NULL;
const gchar *env_path;
- object = (* G_OBJECT_CLASS (tracker_db_interface_sqlite_parent_class)->constructor) (type,
- n_construct_properties,
- construct_params);
- priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
g_assert (priv->filename != NULL);
if (!priv->ro) {
@@ -135,6 +131,22 @@ tracker_db_interface_sqlite_constructor (GType type,
} else {
g_message ("Initialized tracker fts extension");
}
+}
+
+static GObject *
+tracker_db_interface_sqlite_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ TrackerDBInterfaceSqlitePrivate *priv;
+
+ object = (* G_OBJECT_CLASS (tracker_db_interface_sqlite_parent_class)->constructor) (type,
+ n_construct_properties,
+ construct_params);
+ priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
+
+ open_database (priv);
return object;
}
@@ -190,23 +202,31 @@ tracker_db_interface_sqlite_get_property (GObject *object,
}
static void
-tracker_db_interface_sqlite_finalize (GObject *object)
+close_database (TrackerDBInterfaceSqlitePrivate *priv)
{
- TrackerDBInterfaceSqlitePrivate *priv;
-
- priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
-
g_hash_table_destroy (priv->dynamic_statements);
-
g_hash_table_destroy (priv->statements);
g_slist_foreach (priv->function_data, (GFunc) g_free, NULL);
g_slist_free (priv->function_data);
+ priv->function_data = NULL;
g_slist_foreach (priv->aggregate_data, (GFunc) g_free, NULL);
g_slist_free (priv->aggregate_data);
+ priv->aggregate_data = NULL;
sqlite3_close (priv->db);
+}
+
+static void
+tracker_db_interface_sqlite_finalize (GObject *object)
+{
+ TrackerDBInterfaceSqlitePrivate *priv;
+
+ priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
+
+ close_database (priv);
+
g_message ("Closed sqlite3 database:'%s'", priv->filename);
g_free (priv->filename);
@@ -249,19 +269,26 @@ tracker_db_interface_sqlite_class_init (TrackerDBInterfaceSqliteClass *class)
}
static void
-tracker_db_interface_sqlite_init (TrackerDBInterfaceSqlite *db_interface)
+prepare_database (TrackerDBInterfaceSqlitePrivate *priv)
{
- TrackerDBInterfaceSqlitePrivate *priv;
-
- priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
-
- priv->ro = FALSE;
priv->dynamic_statements = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) g_object_unref);
priv->statements = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) sqlite3_finalize);
+
+}
+
+static void
+tracker_db_interface_sqlite_init (TrackerDBInterfaceSqlite *db_interface)
+{
+ TrackerDBInterfaceSqlitePrivate *priv;
+
+ priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+
+ priv->ro = FALSE;
+ prepare_database (priv);
}
static void
@@ -586,17 +613,19 @@ create_result_set_from_stmt (TrackerDBInterfaceSqlite *interface,
if (sqlite3_errcode (priv->db) == SQLITE_IOERR ||
sqlite3_errcode (priv->db) == SQLITE_CORRUPT ||
sqlite3_errcode (priv->db) == SQLITE_NOTADB) {
+
sqlite3_finalize (stmt);
sqlite3_close (priv->db);
-
+
g_unlink (priv->filename);
-
+
g_error ("SQLite experienced an error with file:'%s'. "
"It is either NOT a SQLite database or it is "
"corrupt or there was an IO error accessing the data. "
"This file has now been removed and will be recreated on the next start. "
"Shutting down now.",
priv->filename);
+
return NULL;
}
@@ -666,6 +695,8 @@ tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface)
{
iface->create_statement = tracker_db_interface_sqlite_create_statement;
iface->execute_query = tracker_db_interface_sqlite_execute_query;
+ iface->disconnect = tracker_db_interface_sqlite_disconnect;
+ iface->reconnect = tracker_db_interface_sqlite_reconnect;
}
TrackerDBInterface *
@@ -864,6 +895,27 @@ tracker_db_statement_sqlite_bind_text (TrackerDBStatement *stmt,
sqlite3_bind_text (priv->stmt, index + 1, value, -1, SQLITE_TRANSIENT);
}
+static void
+tracker_db_interface_sqlite_disconnect (TrackerDBInterface *db_interface)
+{
+ TrackerDBInterfaceSqlitePrivate *priv;
+
+ priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+
+ close_database (priv);
+}
+
+static void
+tracker_db_interface_sqlite_reconnect (TrackerDBInterface *db_interface)
+{
+ TrackerDBInterfaceSqlitePrivate *priv;
+
+ priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (db_interface);
+
+ open_database (priv);
+ prepare_database (priv);
+}
+
static TrackerDBResultSet *
tracker_db_statement_sqlite_execute (TrackerDBStatement *stmt,
GError **error)
diff --git a/src/libtracker-db/tracker-db-interface.c b/src/libtracker-db/tracker-db-interface.c
index 5bcb2d4..4cc6df6 100644
--- a/src/libtracker-db/tracker-db-interface.c
+++ b/src/libtracker-db/tracker-db-interface.c
@@ -373,6 +373,24 @@ tracker_db_interface_end_transaction (TrackerDBInterface *interface)
}
void
+tracker_db_interface_disconnect (TrackerDBInterface *interface)
+{
+ TrackerDBInterfaceIface *iface;
+ g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (interface), NULL);
+ iface = TRACKER_DB_INTERFACE_GET_IFACE (interface);
+ iface->disconnect (interface);
+}
+
+void
+tracker_db_interface_reconnect (TrackerDBInterface *interface)
+{
+ TrackerDBInterfaceIface *iface;
+ g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (interface), NULL);
+ iface = TRACKER_DB_INTERFACE_GET_IFACE (interface);
+ iface->reconnect (interface);
+}
+
+void
tracker_db_statement_bind_double (TrackerDBStatement *stmt,
int idx,
double value)
diff --git a/src/libtracker-db/tracker-db-interface.h b/src/libtracker-db/tracker-db-interface.h
index 4ced292..3d2cde4 100644
--- a/src/libtracker-db/tracker-db-interface.h
+++ b/src/libtracker-db/tracker-db-interface.h
@@ -66,6 +66,8 @@ struct TrackerDBInterfaceIface {
TrackerDBResultSet * (* execute_query) (TrackerDBInterface *interface,
GError **error,
const gchar *query);
+ void (* disconnect) (TrackerDBInterface *interface);
+ void (* reconnect) (TrackerDBInterface *interface);
};
@@ -120,6 +122,8 @@ TrackerDBResultSet * tracker_db_interface_execute_query (TrackerDBInterface *
gboolean tracker_db_interface_start_transaction (TrackerDBInterface *interface);
gboolean tracker_db_interface_end_transaction (TrackerDBInterface *interface);
+void tracker_db_interface_disconnect (TrackerDBInterface *interface);
+void tracker_db_interface_reconnect (TrackerDBInterface *interface);
void tracker_db_statement_bind_double (TrackerDBStatement *stmt,
int index,
diff --git a/src/libtracker-db/tracker-db-journal.c b/src/libtracker-db/tracker-db-journal.c
new file mode 100644
index 0000000..fdcfa76
--- /dev/null
+++ b/src/libtracker-db/tracker-db-journal.c
@@ -0,0 +1,167 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+#include "config.h"
+
+#define _GNU_SOURCE
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "tracker-db-journal.h"
+
+static gchar *filename = NULL;
+static FILE *journal = NULL;
+static GMappedFile *mapped = NULL;
+static gsize current_size = 0;
+
+#define TRACKER_DB_JOURNAL_LOG_FILENAME "log.sparql.txt"
+
+static void
+get_filename (void)
+{
+ if (!filename) {
+ filename = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ TRACKER_DB_JOURNAL_LOG_FILENAME,
+ NULL);
+ }
+}
+
+gsize
+tracker_db_journal_get_size (void)
+{
+ return current_size;
+}
+
+const gchar*
+tracker_db_journal_filename (void)
+{
+ get_filename ();
+ return (const gchar *) filename;
+}
+
+void
+tracker_db_journal_open (void)
+{
+ struct stat st;
+
+ get_filename ();
+
+ journal = fopen (filename, "a");
+
+ if (stat (filename, &st) == 0) {
+ current_size = (gsize) st.st_size;
+ }
+}
+
+void
+tracker_db_journal_log (const gchar *query)
+{
+ if (journal) {
+ size_t len = strlen (query);
+ write (fileno (journal), query, len);
+ write (fileno (journal), "\n\0", 2);
+ current_size += (len + 2);
+ }
+}
+
+void
+tracker_db_journal_fsync (void)
+{
+ if (journal) {
+ fsync (fileno (journal));
+ }
+}
+
+void
+tracker_db_journal_truncate (void)
+{
+ if (journal) {
+ ftruncate(fileno (journal), 0);
+ current_size = 0;
+ fsync (fileno (journal));
+ }
+}
+
+void
+tracker_db_journal_close (void)
+{
+ if (journal) {
+ fclose (journal);
+ journal = NULL;
+ }
+
+ g_free (filename);
+ filename = NULL;
+}
+
+TrackerJournalContents*
+tracker_db_journal_get_contents (guint transaction_size)
+{
+ GPtrArray *lines;
+ gsize max_pos, next_len;
+ gchar *cur;
+
+ get_filename ();
+
+ if (!mapped) {
+ GError *error = NULL;
+
+ mapped = g_mapped_file_new (filename, FALSE, &error);
+
+ if (error) {
+ g_warning ("Journal read: %s", error->message);
+ g_clear_error (&error);
+ mapped = NULL;
+ return NULL;
+ }
+ }
+
+ lines = g_ptr_array_sized_new (transaction_size > 0 ? transaction_size : 2000);
+
+ cur = g_mapped_file_get_contents (mapped);
+ max_pos = (gsize) (cur + g_mapped_file_get_length (mapped));
+
+ while (((gsize)cur) < max_pos) {
+ next_len = strnlen (cur, max_pos - ((gsize)cur)) + 1;
+ g_ptr_array_add (lines, cur);
+ cur += next_len;
+ }
+
+ return (TrackerJournalContents *) lines;
+}
+
+void
+tracker_db_journal_free_contents (TrackerJournalContents *contents)
+{
+ if (mapped) {
+ g_mapped_file_free (mapped);
+ mapped = NULL;
+ }
+
+ g_ptr_array_free ((GPtrArray *)contents, TRUE);
+}
diff --git a/src/libtracker-db/tracker-db-journal.h b/src/libtracker-db/tracker-db-journal.h
new file mode 100644
index 0000000..552aee3
--- /dev/null
+++ b/src/libtracker-db/tracker-db-journal.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Philip Van Hoof <philip codeminded be>
+ */
+
+#ifndef __TRACKER_DB_JOURNAL_H__
+#define __TRACKER_DB_JOURNAL_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#define TRACKER_DB_JOURNAL_MAX_SIZE 52428800
+
+G_BEGIN_DECLS
+
+typedef GPtrArray TrackerJournalContents;
+
+const gchar* tracker_db_journal_filename (void);
+void tracker_db_journal_open (void);
+void tracker_db_journal_log (const gchar *query);
+void tracker_db_journal_truncate (void);
+void tracker_db_journal_close (void);
+TrackerJournalContents* tracker_db_journal_get_contents (guint transaction_size);
+void tracker_db_journal_free_contents (TrackerJournalContents *contents);
+void tracker_db_journal_fsync (void);
+gsize tracker_db_journal_get_size (void);
+
+G_END_DECLS
+
+#endif /* __TRACKER_DB_JOURNAL_H__ */
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 0e709c8..32e078f 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -35,8 +35,10 @@
#include <libtracker-common/tracker-type-utils.h>
#include <libtracker-common/tracker-utils.h>
+#include "tracker-db-backup.h"
#include "tracker-db-manager.h"
#include "tracker-db-interface-sqlite.h"
+#include "tracker-db-interface.h"
/* ZLib buffer settings */
#define ZLIB_BUF_SIZE 8192
@@ -152,6 +154,8 @@ static gboolean db_exec_no_reply (TrackerDBInterface *iface,
const gchar *query,
...);
static TrackerDBInterface *db_interface_create (TrackerDB db);
+static TrackerDBInterface *tracker_db_manager_get_db_interfaces (gint num, ...);
+static TrackerDBInterface *tracker_db_manager_get_db_interfaces_ro (gint num, ...);
static gboolean initialized;
static gchar *sql_dir;
@@ -656,7 +660,7 @@ db_set_params (TrackerDBInterface *iface,
gint page_size,
gboolean add_functions)
{
- tracker_db_interface_execute_query (iface, NULL, "PRAGMA synchronous = NORMAL;");
+ tracker_db_interface_execute_query (iface, NULL, "PRAGMA synchronous = OFF;");
tracker_db_interface_execute_query (iface, NULL, "PRAGMA count_changes = 0;");
tracker_db_interface_execute_query (iface, NULL, "PRAGMA temp_store = FILE;");
tracker_db_interface_execute_query (iface, NULL, "PRAGMA encoding = \"UTF-8\"");
@@ -861,7 +865,7 @@ db_interface_create (TrackerDB db)
}
static void
-db_manager_remove_all (void)
+db_manager_remove_all (gboolean rm_backup_and_log, gboolean not_meta)
{
guint i;
@@ -871,10 +875,34 @@ db_manager_remove_all (void)
* calculate the absolute directories here.
*/
for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+
+ if (not_meta && i == TRACKER_DB_METADATA) {
+ continue;
+ }
+
g_message (" Removing database:'%s'",
dbs[i].abs_filename);
g_unlink (dbs[i].abs_filename);
}
+
+ if (rm_backup_and_log) {
+ GFile *file;
+ gchar *path;
+
+ file = tracker_db_backup_file (NULL, TRACKER_DB_BACKUP_META_FILENAME);
+ path = g_file_get_path (file);
+ g_message (" Removing database:'%s'",
+ path);
+ g_free (path);
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+ path = tracker_db_journal_filename ();
+ g_message (" Removing database:'%s'",
+ path);
+ file = g_file_new_for_path (path);
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+ }
}
static TrackerDBVersion
@@ -1016,17 +1044,78 @@ tracker_db_manager_ensure_locale (void)
g_free (stored_locale);
}
+static gboolean
+check_meta_backup (gboolean *did_copy)
+{
+ const gchar *meta_filename;
+ gboolean retval = FALSE;
+
+ /* This is currently the only test for need_journal. We should add a
+ * couple tests that test meta.db against consistenty, and if not
+ * good, copy meta-backup.db over and set need_journal (being less
+ * conservative about using the backup, and not trusting the meta.db
+ * as much as we do right now) */
+
+ meta_filename = dbs[TRACKER_DB_METADATA].abs_filename;
+
+ if (meta_filename) {
+ GFile *file;
+
+ file = g_file_new_for_path (meta_filename);
+
+ /* (more) Checks for a healthy meta.db should happen here */
+
+ if (!g_file_query_exists (file, NULL)) {
+ GFile *backup;
+
+ backup = tracker_db_backup_file (NULL, TRACKER_DB_BACKUP_META_FILENAME);
+
+ if (g_file_query_exists (backup, NULL)) {
+ GError *error = NULL;
+
+ /* Note that we leave meta-backup.db as is, it'll
+ * be overwritten first-next time tracker-store.c's
+ * sync_idle_handler will instruct this. */
+
+ g_file_copy (backup, file, G_FILE_COPY_OVERWRITE,
+ NULL, NULL, NULL, &error);
+
+ if (!error && did_copy) {
+ *did_copy = TRUE;
+ }
+
+ g_clear_error (&error);
+ }
+
+ /* We always play the journal in case meta.db wasn't
+ * healthy. Also if meta-backup.db didn't exist: that
+ * just means that tracker-store.c's sync_idle_handler
+ * didn't yet ran (meanwhile a first log-file is yet
+ * already being made) */
+
+ retval = TRUE;
+
+ g_object_unref (backup);
+ }
+
+ g_object_unref (file);
+ }
+
+ return retval;
+}
+
gboolean
tracker_db_manager_init (TrackerDBManagerFlags flags,
gboolean *first_time,
- gboolean shared_cache)
+ gboolean shared_cache,
+ gboolean *need_journal)
{
GType etype;
TrackerDBVersion version;
gchar *filename;
const gchar *dir;
const gchar *env_path;
- gboolean need_reindex;
+ gboolean need_reindex, did_copy = FALSE;
guint i;
if (first_time) {
@@ -1126,6 +1215,13 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
}
}
+ if (need_journal) {
+ /* That did_copy is used for called db_manager_remove_all, we
+ * don't want it to also remove our freshly copied meta.db file. */
+
+ *need_journal = check_meta_backup (&did_copy);
+ }
+
/* If we are just initializing to remove the databases,
* return here.
*/
@@ -1158,11 +1254,15 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
* will cause errors and do nothing.
*/
g_message ("Cleaning up database files for reindex");
- db_manager_remove_all ();
+
+ /* Remove all but the meta.db in case of did_copy, else remove
+ * all (only in case meta-backup.db was not restored) */
+
+ db_manager_remove_all (FALSE, did_copy);
/* In cases where we re-init this module, make sure
* we have cleaned up the ontology before we load all
- * new databases.
+ * new databases.
*/
tracker_ontology_shutdown ();
@@ -1214,9 +1314,58 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
TRACKER_DB_CONTENTS,
TRACKER_DB_COMMON);
}
+
return TRUE;
}
+void
+tracker_db_manager_disconnect (void)
+{
+ if (resources_iface) {
+ guint i;
+ TrackerDB attachments[3] = { TRACKER_DB_FULLTEXT,
+ TRACKER_DB_CONTENTS,
+ TRACKER_DB_COMMON };
+
+ for (i = 0; i < 3; i++) {
+ TrackerDB db = attachments [i];
+
+ db_exec_no_reply (resources_iface,
+ "DETACH '%s'",
+ dbs[db].name);
+ }
+
+ tracker_db_interface_disconnect (resources_iface);
+ }
+}
+
+void
+tracker_db_manager_reconnect (void)
+{
+ if (resources_iface) {
+ guint i;
+ TrackerDB attachments[3] = { TRACKER_DB_FULLTEXT,
+ TRACKER_DB_CONTENTS,
+ TRACKER_DB_COMMON };
+
+ tracker_db_interface_reconnect (resources_iface);
+
+ db_set_params (resources_iface,
+ dbs[TRACKER_DB_METADATA].cache_size,
+ dbs[TRACKER_DB_METADATA].page_size,
+ TRUE);
+
+ for (i = 0; i < 3; i++) {
+ TrackerDB db = attachments [i];
+
+ db_exec_no_reply (resources_iface,
+ "ATTACH '%s' as '%s'",
+ dbs[db].abs_filename,
+ dbs[db].name);
+ }
+ }
+}
+
void
tracker_db_manager_shutdown (void)
{
@@ -1268,11 +1417,11 @@ tracker_db_manager_shutdown (void)
}
void
-tracker_db_manager_remove_all (void)
+tracker_db_manager_remove_all (gboolean rm_backup_and_log)
{
g_return_if_fail (initialized != FALSE);
- db_manager_remove_all ();
+ db_manager_remove_all (rm_backup_and_log, FALSE);
}
void
@@ -1327,7 +1476,7 @@ tracker_db_manager_get_file (TrackerDB db)
*
* returns: (caller-owns): a database connection
**/
-TrackerDBInterface *
+static TrackerDBInterface *
tracker_db_manager_get_db_interfaces (gint num, ...)
{
gint n_args;
@@ -1361,7 +1510,7 @@ tracker_db_manager_get_db_interfaces (gint num, ...)
return connection;
}
-TrackerDBInterface *
+static TrackerDBInterface *
tracker_db_manager_get_db_interfaces_ro (gint num, ...)
{
gint n_args;
diff --git a/src/libtracker-db/tracker-db-manager.h b/src/libtracker-db/tracker-db-manager.h
index d7701ba..95f0dd4 100644
--- a/src/libtracker-db/tracker-db-manager.h
+++ b/src/libtracker-db/tracker-db-manager.h
@@ -49,19 +49,20 @@ GType tracker_db_get_type (void) G_GNUC_CONST;
gboolean tracker_db_manager_init (TrackerDBManagerFlags flags,
gboolean *first_time,
- gboolean shared_cache);
+ gboolean shared_cache,
+ gboolean *need_journal);
void tracker_db_manager_shutdown (void);
-void tracker_db_manager_remove_all (void);
+void tracker_db_manager_remove_all (gboolean rm_backup_and_log);
void tracker_db_manager_optimize (void);
const gchar *tracker_db_manager_get_file (TrackerDB db);
+
TrackerDBInterface *
tracker_db_manager_get_db_interface (void);
-TrackerDBInterface *
- tracker_db_manager_get_db_interfaces (gint num, ...);
-TrackerDBInterface *
- tracker_db_manager_get_db_interfaces_ro (gint num, ...);
+
+void tracker_db_manager_disconnect (void);
+void tracker_db_manager_reconnect (void);
G_END_DECLS
diff --git a/src/tracker-store/tracker-backup.c b/src/tracker-store/tracker-backup.c
index f2b7d36..50d7f67 100644
--- a/src/tracker-store/tracker-backup.c
+++ b/src/tracker-store/tracker-backup.c
@@ -35,6 +35,8 @@
typedef struct {
DBusGMethodInvocation *context;
guint request_id;
+ gboolean play_journal;
+ GFile *destination, *journal;
} TrackerDBusMethodInfo;
G_DEFINE_TYPE (TrackerBackup, tracker_backup, G_TYPE_OBJECT)
@@ -58,7 +60,17 @@ tracker_backup_new (void)
static void
destroy_method_info (gpointer user_data)
{
- g_slice_free (TrackerDBusMethodInfo, user_data);
+ TrackerDBusMethodInfo *info = user_data;
+
+ if (info->destination) {
+ g_object_unref (info->destination);
+ }
+
+ if (info->journal) {
+ g_object_unref (info->journal);
+ }
+
+ g_free (info);
}
static void
@@ -74,81 +86,99 @@ backup_callback (GError *error, gpointer user_data)
return;
}
+ if (info->play_journal) {
+ tracker_store_play_journal ();
+ }
+
dbus_g_method_return (info->context);
tracker_dbus_request_success (info->request_id);
}
+static void
+on_batch_commit (gpointer user_data)
+{
+ TrackerDBusMethodInfo *info = user_data;
+
+ /* At this point no transactions are left open, we can now start the
+ * sqlite3_backup API, which will run itself as a GSource within the
+ * mainloop after it got initialized (which will reopen the mainloop) */
+
+ tracker_data_backup_save (info->destination, info->journal,
+ backup_callback,
+ info, destroy_method_info);
+}
+
void
tracker_backup_save (TrackerBackup *object,
- const gchar *uri,
+ const gchar *destination_uri,
+ const gchar *journal_uri,
DBusGMethodInvocation *context,
GError **error)
{
guint request_id;
TrackerDBusMethodInfo *info;
- GFile *file;
request_id = tracker_dbus_get_next_request_id ();
tracker_dbus_request_new (request_id,
"DBus request to save backup into '%s'",
- uri);
-
- /* Previous DBus API accepted paths. For this reason I decided to try
- * to support both paths and uris. Perhaps we should just remove the
- * support for paths here? */
-
- if (!strchr (uri, ':')) {
- file = g_file_new_for_path (uri);
- } else {
- file = g_file_new_for_uri (uri);
- }
+ destination_uri);
- info = g_slice_new (TrackerDBusMethodInfo);
+ info = g_new0 (TrackerDBusMethodInfo, 1);
info->request_id = request_id;
info->context = context;
+ info->play_journal = FALSE;
+ info->destination = g_file_new_for_uri (destination_uri);
+ info->journal = g_file_new_for_uri (journal_uri);
- tracker_data_backup_save (file, backup_callback,
- info, destroy_method_info);
+ /* The sqlite3_backup API apparently doesn't much like open transactions,
+ * this queue_commit will first call the currently open transaction
+ * of the open batch (if any), and then in the callback we'll idd
+ * continue with making the backup itself (using sqlite3_backup's API) */
- g_object_unref (file);
+ tracker_store_queue_commit (on_batch_commit, info, NULL);
}
void
tracker_backup_restore (TrackerBackup *object,
- const gchar *uri,
+ const gchar *backup_uri,
+ const gchar *journal_uri,
DBusGMethodInvocation *context,
GError **error)
{
guint request_id;
TrackerDBusMethodInfo *info;
- GFile *file;
+ GFile *destination, *journal;
request_id = tracker_dbus_get_next_request_id ();
tracker_dbus_request_new (request_id,
"DBus request to restore backup from '%s'",
- uri);
-
- /* Previous DBus API accepted paths. For this reason I decided to try
- * to support both paths and uris. Perhaps we should just remove the
- * support for paths here? */
+ backup_uri);
- if (!strchr (uri, ':')) {
- file = g_file_new_for_path (uri);
- } else {
- file = g_file_new_for_uri (uri);
- }
+ destination = g_file_new_for_uri (backup_uri);
+ journal = g_file_new_for_uri (journal_uri);
- info = g_slice_new (TrackerDBusMethodInfo);
+ info = g_new0 (TrackerDBusMethodInfo, 1);
info->request_id = request_id;
info->context = context;
+ info->play_journal = TRUE;
+
+ /* This call is mostly synchronous, because we want to block the
+ * mainloop during a restore procedure (you're switching the active
+ * database here, let's not allow queries during this time)
+ *
+ * No need for commits or anything. Whatever is in the current db will
+ * be eliminated in favor of the data in `backup_uri` and `journal_uri`. */
- tracker_store_queue_turtle_import (file, backup_callback,
- info, destroy_method_info);
+ tracker_data_backup_restore (destination, journal,
+ backup_callback,
+ info, destroy_method_info);
- g_object_unref (file);
+ g_object_unref (destination);
+ g_object_unref (journal);
}
+
diff --git a/src/tracker-store/tracker-backup.h b/src/tracker-store/tracker-backup.h
index 0b663b0..54b248a 100644
--- a/src/tracker-store/tracker-backup.h
+++ b/src/tracker-store/tracker-backup.h
@@ -53,11 +53,13 @@ GType tracker_backup_get_type (void) G_GNUC_CONST;
TrackerBackup *tracker_backup_new (void);
void tracker_backup_save (TrackerBackup *object,
- const gchar *path,
+ const gchar *destination_uri,
+ const gchar *journal_uri,
DBusGMethodInvocation *context,
GError **error);
void tracker_backup_restore (TrackerBackup *object,
- const gchar *path,
+ const gchar *backup_uri,
+ const gchar *journal_uri,
DBusGMethodInvocation *context,
GError **error);
diff --git a/src/tracker-store/tracker-main.c b/src/tracker-store/tracker-main.c
index 5421b06..d7750b6 100644
--- a/src/tracker-store/tracker-main.c
+++ b/src/tracker-store/tracker-main.c
@@ -491,7 +491,7 @@ shutdown_directories (void)
/* If we are reindexing, just remove the databases */
if (private->reindex_on_shutdown) {
- tracker_db_manager_remove_all ();
+ tracker_db_manager_remove_all (FALSE);
}
}
@@ -644,7 +644,7 @@ main (gint argc, gchar *argv[])
TrackerPower *hal_power;
TrackerStorage *hal_storage;
TrackerDBManagerFlags flags = 0;
- gboolean is_first_time_index;
+ gboolean is_first_time_index, need_journal = FALSE;
g_type_init ();
@@ -746,8 +746,6 @@ main (gint argc, gchar *argv[])
NULL);
#endif /* HAVE_HAL */
- tracker_store_init ();
-
flags |= TRACKER_DB_MANAGER_REMOVE_CACHE;
if (force_reindex) {
@@ -761,10 +759,13 @@ main (gint argc, gchar *argv[])
flags |= TRACKER_DB_MANAGER_LOW_MEMORY_MODE;
}
- if (!tracker_data_manager_init (flags, NULL, &is_first_time_index)) {
+ if (!tracker_data_manager_init (flags, NULL, &is_first_time_index,
+ &need_journal)) {
return EXIT_FAILURE;
}
+ tracker_store_init (need_journal);
+
#ifdef HAVE_HAL
/* We set up the mount points here. For the mount points, this
* means contacting the Indexer. This means that we have to
diff --git a/src/tracker-store/tracker-resources.c b/src/tracker-store/tracker-resources.c
index 52bb1ed..ebe985d 100644
--- a/src/tracker-store/tracker-resources.c
+++ b/src/tracker-store/tracker-resources.c
@@ -399,6 +399,10 @@ on_statements_committed (gpointer user_data)
priv = TRACKER_RESOURCES_GET_PRIVATE (user_data);
+ /* For more information about this call, look at the function end_batch
+ * of tracker-store.c */
+ tracker_store_flush_journal ();
+
events = tracker_events_get_pending ();
if (events) {
diff --git a/src/tracker-store/tracker-store.c b/src/tracker-store/tracker-store.c
index a6838e3..78e638f 100644
--- a/src/tracker-store/tracker-store.c
+++ b/src/tracker-store/tracker-store.c
@@ -22,8 +22,15 @@
#include "config.h"
+#include <unistd.h>
+#include <sys/types.h>
+
#include <libtracker-common/tracker-dbus.h>
#include <libtracker-db/tracker-db-dbus.h>
+#include <libtracker-db/tracker-db-backup.h>
+#include <libtracker-db/tracker-db-journal.h>
+#include <libtracker-db/tracker-db-interface-sqlite.h>
+#include <libtracker-db/tracker-db-journal.h>
#include <libtracker-data/tracker-data-update.h>
#include <libtracker-data/tracker-data-query.h>
@@ -31,14 +38,15 @@
#include "tracker-store.h"
-#define TRACKER_STORE_TRANSACTION_MAX 4000
+#define TRACKER_STORE_TRANSACTION_MAX 4000 /* At commit is journal fsynced too */
+#define TRACKER_STORE_JOURNAL_TIMEOUT_BEFORE_BACKUP (60 * 60 * 2) /* Two hours before backup */
typedef struct {
- gboolean have_handler;
- gboolean batch_mode;
+ gboolean have_handler, have_sync_handler;
+ gboolean batch_mode, start_log;
guint batch_count;
GQueue *queue;
- guint handler;
+ guint handler, sync_handler;
} TrackerStorePrivate;
typedef enum {
@@ -145,11 +153,35 @@ end_batch (TrackerStorePrivate *private)
if (private->batch_mode) {
/* commit pending batch items */
tracker_data_commit_transaction ();
+
+ /* The on_statements_committed in tracker-resources.c performs
+ * the flush on the journal, I can only register one callback
+ * for this atm, so that's why it's called over there as a
+ * tracker_store_flush_journal */
+
private->batch_mode = FALSE;
private->batch_count = 0;
}
}
+static void
+on_backup_done (GError *error, gpointer user_data)
+{
+ if (!error) {
+ tracker_db_journal_truncate ();
+ }
+}
+
+static void
+log_to_journal (TrackerStorePrivate *private, const gchar *query)
+{
+ tracker_db_journal_log (query);
+
+ if (tracker_db_journal_get_size () > TRACKER_DB_JOURNAL_MAX_SIZE) {
+ tracker_db_backup_save (on_backup_done, NULL, NULL);
+ }
+}
+
static gboolean
queue_idle_handler (gpointer user_data)
{
@@ -165,6 +197,11 @@ queue_idle_handler (gpointer user_data)
begin_batch (private);
tracker_data_update_sparql (task->data.query, &error);
+
+ if (private->start_log) {
+ log_to_journal (private, task->data.query);
+ }
+
if (!error) {
private->batch_count++;
if (private->batch_count >= TRACKER_STORE_TRANSACTION_MAX) {
@@ -235,6 +272,14 @@ queue_idle_handler (gpointer user_data)
return !g_queue_is_empty (private->queue);
}
+static gboolean
+sync_idle_handler (gpointer user_data)
+{
+ tracker_db_backup_save (on_backup_done, NULL, NULL);
+
+ return TRUE;
+}
+
static void
queue_idle_destroy (gpointer user_data)
{
@@ -243,8 +288,65 @@ queue_idle_destroy (gpointer user_data)
private->have_handler = FALSE;
}
+
+static void
+sync_idle_destroy (gpointer user_data)
+{
+ TrackerStorePrivate *private = user_data;
+
+ tracker_db_journal_close ();
+
+ private->have_sync_handler = FALSE;
+}
+
+void
+tracker_store_flush_journal (void)
+{
+ TrackerStorePrivate *private;
+
+ private = g_static_private_get (&private_key);
+ g_return_if_fail (private != NULL);
+
+ tracker_db_journal_fsync ();
+}
+
+static void
+internal_play_journal (TrackerStorePrivate *private)
+{
+ TrackerJournalContents *lines;
+
+ lines = tracker_db_journal_get_contents (TRACKER_STORE_TRANSACTION_MAX);
+
+ if (lines) {
+ guint i;
+
+ tracker_data_begin_transaction ();
+ private->start_log = FALSE;
+ for (i = 0; i < lines->len; i++) {
+ const gchar *line = g_ptr_array_index (lines, i);
+ tracker_store_sparql_update (line, NULL);
+ }
+ tracker_db_journal_truncate ();
+ private->start_log = TRUE;
+ tracker_data_commit_transaction ();
+
+ tracker_db_journal_free_contents (lines);
+ }
+}
+
+void
+tracker_store_play_journal (void)
+{
+ TrackerStorePrivate *private;
+
+ private = g_static_private_get (&private_key);
+ g_return_if_fail (private != NULL);
+
+ internal_play_journal (private);
+}
+
void
-tracker_store_init (void)
+tracker_store_init (gboolean load_journal)
{
TrackerStorePrivate *private;
@@ -255,6 +357,20 @@ tracker_store_init (void)
g_static_private_set (&private_key,
private,
private_free);
+
+ if (load_journal) {
+ internal_play_journal (private);
+ }
+
+ tracker_db_journal_open ();
+
+ private->start_log = TRUE;
+
+ private->sync_handler = g_timeout_add_seconds_full (G_PRIORITY_LOW,
+ TRACKER_STORE_JOURNAL_TIMEOUT_BEFORE_BACKUP,
+ sync_idle_handler,
+ private,
+ sync_idle_destroy);
}
void
@@ -270,6 +386,11 @@ tracker_store_shutdown (void)
private->have_handler = FALSE;
}
+ if (private->have_sync_handler) {
+ g_source_remove (private->sync_handler);
+ private->have_sync_handler = FALSE;
+ }
+
g_static_private_set (&private_key, NULL, NULL);
}
@@ -384,6 +505,11 @@ tracker_store_sparql_update (const gchar *sparql,
}
tracker_data_update_sparql (sparql, error);
+
+ if (private->start_log) {
+ log_to_journal (private, sparql);
+ }
+
}
TrackerDBResultSet*
diff --git a/src/tracker-store/tracker-store.h b/src/tracker-store/tracker-store.h
index 27f7eb6..a87320a 100644
--- a/src/tracker-store/tracker-store.h
+++ b/src/tracker-store/tracker-store.h
@@ -36,7 +36,7 @@ typedef void (* TrackerStoreCommitCallback) (gpointer user_data);
typedef void (* TrackerStoreTurtleCallback) (GError *error,
gpointer user_data);
-void tracker_store_init (void);
+void tracker_store_init (gboolean load_journal);
void tracker_store_shutdown (void);
void tracker_store_queue_commit (TrackerStoreCommitCallback callback,
gpointer user_data,
@@ -63,6 +63,9 @@ TrackerDBResultSet*
guint tracker_store_get_queue_size (void);
+void tracker_store_play_journal (void);
+void tracker_store_flush_journal (void);
+
G_END_DECLS
#endif /* __TRACKER_STORE_H__ */
diff --git a/src/tracker-utils/tracker-processes.c b/src/tracker-utils/tracker-processes.c
index 020e079..76f11ea 100644
--- a/src/tracker-utils/tracker-processes.c
+++ b/src/tracker-utils/tracker-processes.c
@@ -37,7 +37,7 @@
static gboolean should_kill;
static gboolean should_terminate;
-static gboolean hard_reset;
+static gboolean hard_reset, soft_reset;
static GOptionEntry entries[] = {
{ "kill", 'k', 0, G_OPTION_ARG_NONE, &should_kill,
@@ -47,6 +47,9 @@ static GOptionEntry entries[] = {
N_("Use SIGTERM to stop all tracker processes found"),
NULL
},
+ { "soft-reset", 's', 0, G_OPTION_ARG_NONE, &soft_reset,
+ N_("This will kill all Tracker processes and remove all databases except the backup and journal (a restart will restore the data)"),
+ NULL },
{ "hard-reset", 'r', 0, G_OPTION_ARG_NONE, &hard_reset,
N_("This will kill all Tracker processes and remove all databases"),
NULL },
@@ -144,13 +147,13 @@ main (int argc, char **argv)
g_printerr ("%s\n",
_("You can not use the --kill and --terminate arguments together"));
return EXIT_FAILURE;
- } else if (hard_reset && should_terminate) {
+ } else if ((hard_reset || soft_reset) && should_terminate) {
g_printerr ("%s\n",
_("You can not use the --terminate with --hard-reset, --kill is implied"));
return EXIT_FAILURE;
}
- if (hard_reset) {
+ if (hard_reset || soft_reset) {
/* Imply --kill */
should_kill = TRUE;
}
@@ -235,7 +238,7 @@ main (int argc, char **argv)
g_slist_foreach (pids, (GFunc) g_free, NULL);
g_slist_free (pids);
- if (hard_reset) {
+ if (hard_reset || soft_reset) {
guint log_handler_id;
/* Set log handler for library messages */
@@ -247,11 +250,11 @@ main (int argc, char **argv)
g_log_set_default_handler (log_handler, NULL);
/* Clean up */
- if (!tracker_db_manager_init (TRACKER_DB_MANAGER_REMOVE_ALL, NULL, FALSE)) {
+ if (!tracker_db_manager_init (TRACKER_DB_MANAGER_REMOVE_ALL, NULL, FALSE, NULL)) {
return EXIT_FAILURE;
}
- tracker_db_manager_remove_all ();
+ tracker_db_manager_remove_all (hard_reset);
tracker_db_manager_shutdown ();
/* Unset log handler */
diff --git a/tests/libtracker-data/tracker-ontology-test.c b/tests/libtracker-data/tracker-ontology-test.c
index def14d9..a75f352 100644
--- a/tests/libtracker-data/tracker-ontology-test.c
+++ b/tests/libtracker-data/tracker-ontology-test.c
@@ -94,7 +94,7 @@ test_query (gconstpointer test_data)
/* initialization */
tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
NULL,
- NULL);
+ NULL, NULL);
/* load data set */
data_filename = g_strconcat (data_prefix, ".ttl", NULL);
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index 28718f0..d9635ee 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -107,7 +107,7 @@ test_sparql_query (gconstpointer test_data)
tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
data_prefix,
- NULL);
+ NULL, NULL);
/* data_path = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL); */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]