[tracker/urho-sync: 9/9] Backup and restore support



commit 142a32f01e4a43275d954e48b1134ba4a7a965db
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Aug 20 12:47:04 2009 +0200

    Backup and restore support

 INSTALL                                         |   94 ++++++++--
 data/dbus/tracker-backup.xml                    |    6 +-
 src/libtracker-data/tracker-data-backup.c       |  224 ++++++++++++++++++++---
 src/libtracker-data/tracker-data-backup.h       |   16 +-
 src/libtracker-db/Makefile.am                   |    2 +-
 src/libtracker-db/tracker-db-backup.c           |    4 +-
 src/libtracker-db/tracker-db-backup.h           |    4 +-
 src/libtracker-db/tracker-db-interface-sqlite.c |   90 +++++++---
 src/libtracker-db/tracker-db-interface.c        |   18 ++
 src/libtracker-db/tracker-db-interface.h        |    4 +
 src/libtracker-db/tracker-db-journal.c          |    9 +
 src/libtracker-db/tracker-db-journal.h          |    2 +-
 src/libtracker-db/tracker-db-manager.c          |   56 ++++++-
 src/libtracker-db/tracker-db-manager.h          |    8 +-
 src/tracker-store/tracker-backup.c              |   51 +++---
 src/tracker-store/tracker-backup.h              |    6 +-
 16 files changed, 472 insertions(+), 122 deletions(-)
---
diff --git a/INSTALL b/INSTALL
index d3c5b40..8b82ade 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2,15 +2,15 @@ Installation Instructions
 *************************
 
 Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007 Free Software Foundation, Inc.
+2006, 2007, 2008 Free Software Foundation, Inc.
 
-This file is free documentation; the Free Software Foundation gives
+   This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
 
 Basic Installation
 ==================
 
-Briefly, the shell commands `./configure; make; make install' should
+   Briefly, the shell commands `./configure; make; make install' should
 configure, build, and install this package.  The following
 more-detailed instructions are generic; see the `README' file for
 instructions specific to this package.
@@ -73,9 +73,9 @@ The simplest way to compile this package is:
 Compilers and Options
 =====================
 
-Some systems require unusual options for compilation or linking that the
-`configure' script does not know about.  Run `./configure --help' for
-details on some of the pertinent environment variables.
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
 
    You can give `configure' initial values for configuration parameters
 by setting variables in the command line or in the environment.  Here
@@ -88,7 +88,7 @@ is an example:
 Compiling For Multiple Architectures
 ====================================
 
-You can compile the package for more than one kind of computer at the
+   You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
 own directory.  To do this, you can use GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
@@ -100,10 +100,24 @@ architecture at a time in the source code directory.  After you have
 installed the package for one architecture, use `make distclean' before
 reconfiguring for another architecture.
 
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
 Installation Names
 ==================
 
-By default, `make install' installs the package's commands under
+   By default, `make install' installs the package's commands under
 `/usr/local/bin', include files under `/usr/local/include', etc.  You
 can specify an installation prefix other than `/usr/local' by giving
 `configure' the option `--prefix=PREFIX'.
@@ -126,7 +140,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
 Optional Features
 =================
 
-Some packages pay attention to `--enable-FEATURE' options to
+   Some packages pay attention to `--enable-FEATURE' options to
 `configure', where FEATURE indicates an optional part of the package.
 They may also pay attention to `--with-PACKAGE' options, where PACKAGE
 is something like `gnu-as' or `x' (for the X Window System).  The
@@ -138,14 +152,36 @@ find the X include and library files automatically, but if it doesn't,
 you can use the `configure' options `--x-includes=DIR' and
 `--x-libraries=DIR' to specify their locations.
 
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
 Specifying the System Type
 ==========================
 
-There may be some features `configure' cannot figure out automatically,
-but needs to determine by the type of machine the package will run on.
-Usually, assuming the package is built to be run on the _same_
-architectures, `configure' can figure that out, but if it prints a
-message saying it cannot guess the machine type, give it the
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
 `--build=TYPE' option.  TYPE can either be a short name for the system
 type, such as `sun4', or a canonical name which has the form:
 
@@ -171,9 +207,9 @@ eventually be run) with `--host=TYPE'.
 Sharing Defaults
 ================
 
-If you want to set default values for `configure' scripts to share, you
-can create a site shell script called `config.site' that gives default
-values for variables like `CC', `cache_file', and `prefix'.
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
 `configure' looks for `PREFIX/share/config.site' if it exists, then
 `PREFIX/etc/config.site' if it exists.  Or, you can set the
 `CONFIG_SITE' environment variable to the location of the site script.
@@ -182,7 +218,7 @@ A warning: not all `configure' scripts look for a site script.
 Defining Variables
 ==================
 
-Variables not defined in a site shell script can be set in the
+   Variables not defined in a site shell script can be set in the
 environment passed to `configure'.  However, some packages may run
 configure again during the build, and the customized values of these
 variables may be lost.  In order to avoid this problem, you should set
@@ -201,11 +237,19 @@ an Autoconf bug.  Until the bug is fixed you can use this workaround:
 `configure' Invocation
 ======================
 
-`configure' recognizes the following options to control how it operates.
+   `configure' recognizes the following options to control how it
+operates.
 
 `--help'
 `-h'
-     Print a summary of the options to `configure', and exit.
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
 
 `--version'
 `-V'
@@ -232,6 +276,16 @@ an Autoconf bug.  Until the bug is fixed you can use this workaround:
      Look for the package's source code in directory DIR.  Usually
      `configure' can determine that directory automatically.
 
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *Note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
 `configure' also accepts some other, not widely useful, options.  Run
 `configure --help' for more details.
 
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..bbc29a9 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;
+} 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_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);
+	const gchar *db_file = tracker_db_manager_get_file (TRACKER_DB_METADATA);
+	GFile *file, *parent;
+	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;
+	
+	file = g_file_new_for_path (db_file);
+	parent = g_file_get_parent (file);
+	g_object_unref (file);
+	info->file = g_file_get_child (parent, TRACKER_DB_BACKUP_META_FILENAME);
+	g_object_unref (parent);
+
+	if (g_file_query_exists (info->file, NULL)) {
+		save_copy_procedure (info);
+	} else {
+		tracker_db_backup_save (on_backup_finished, 
+		                        info, NULL);
+	}
+}
+
+static void
+on_journald_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->destination, info->file,
+		                   G_FILE_COPY_OVERWRITE, 
+		                   G_PRIORITY_HIGH,
+		                   NULL, NULL, NULL,
+		                   on_meta_copied,
+		                   info);
+	}
+
+	g_clear_error (&error);
+}
+
+static void
+restore_copy_procedure (BackupSaveInfo *info)
+{
+	GFile *journal_d;
+	journal_d = g_file_new_for_path (tracker_db_journal_filename ());
+
+	if (g_file_query_exists (journal_d, NULL)) {
+		g_file_copy_async (info->journal, journal_d, 
+		                   G_FILE_COPY_OVERWRITE, 
+		                   G_PRIORITY_HIGH,
+		                   NULL, NULL, NULL,
+		                   on_journald_copied,
+		                   info);
+	} else {
+		g_file_copy_async (info->destination, info->file,
+		                   G_FILE_COPY_OVERWRITE, 
+		                   G_PRIORITY_HIGH,
+		                   NULL, NULL, NULL,
+		                   on_meta_copied,
+		                   info);
+	}
 
-	g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
-	                 callback,
-	                 info,
-	                 NULL);
+	g_object_unref (journal_d);
 }
 
+void
+tracker_data_backup_restore (GFile *backup,
+                             GFile *journal,
+                             TrackerDataBackupFinished callback,
+                             gpointer user_data,
+                             GDestroyNotify destroy)
+{
+	const gchar *db_file = tracker_db_manager_get_file (TRACKER_DB_METADATA);
+	GFile *file, *parent;
+	BackupSaveInfo *info;
+
+	tracker_db_manager_disconnect ();
 
+	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;
+
+	file = g_file_new_for_path (db_file);
+	parent = g_file_get_parent (file);
+	g_object_unref (file);
+	info->file = g_file_get_child (parent, TRACKER_DB_BACKUP_META_FILENAME);
+	g_object_unref (parent);
+
+	restore_copy_procedure (info);
+
+	tracker_db_manager_reconnect ();
+}
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-db/Makefile.am b/src/libtracker-db/Makefile.am
index 31eaa25..b86ee77 100644
--- a/src/libtracker-db/Makefile.am
+++ b/src/libtracker-db/Makefile.am
@@ -21,7 +21,7 @@ libtracker_db_la_SOURCES = 						\
 	tracker-db-interface-sqlite.c					\
 	tracker-db-manager.c						\
 	tracker-db-backup.c						\
-	tracker-db-journal.c
+	tracker-db-journal.c						
 
 noinst_HEADERS =							\
 	tracker-db-dbus.h						\
diff --git a/src/libtracker-db/tracker-db-backup.c b/src/libtracker-db/tracker-db-backup.c
index 68fe821..deed8e8 100644
--- a/src/libtracker-db/tracker-db-backup.c
+++ b/src/libtracker-db/tracker-db-backup.c
@@ -39,7 +39,7 @@
 #define TRACKER_DB_BACKUP_META_FILENAME_T	"meta-backup.db.tmp"
 
 typedef struct {
-	TrackerBackupFinished callback;
+	TrackerDBBackupFinished callback;
 	GDestroyNotify destroy;
 	gpointer user_data;
 	GError *error;
@@ -186,7 +186,7 @@ on_backup_temp_finished (gpointer user_data)
 
 
 void
-tracker_db_backup_save (TrackerBackupFinished callback,
+tracker_db_backup_save (TrackerDBBackupFinished callback,
                         gpointer user_data,
                         GDestroyNotify destroy)
 {
diff --git a/src/libtracker-db/tracker-db-backup.h b/src/libtracker-db/tracker-db-backup.h
index c67d6dc..91e4c36 100644
--- a/src/libtracker-db/tracker-db-backup.h
+++ b/src/libtracker-db/tracker-db-backup.h
@@ -36,11 +36,11 @@ typedef enum {
 	TRACKER_DB_BACKUP_ERROR_UNKNOWN,
 } TrackerDBBackupError;
 
-typedef void (*TrackerBackupFinished)   (GError *error, gpointer user_data);
+typedef void (*TrackerDBBackupFinished)   (GError *error, gpointer user_data);
 
 GQuark    tracker_db_backup_error_quark (void);
 
-void      tracker_db_backup_save        (TrackerBackupFinished callback,
+void      tracker_db_backup_save        (TrackerDBBackupFinished callback,
                                          gpointer user_data,
                                          GDestroyNotify destroy);
 
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index 68e8beb..c7f114a 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -71,6 +71,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 +99,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) {
@@ -150,6 +144,22 @@ tracker_db_interface_sqlite_constructor (GType			type,
 	} else {
 		g_message ("Loaded 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;
 }
@@ -205,14 +215,9 @@ 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);
@@ -222,6 +227,17 @@ tracker_db_interface_sqlite_finalize (GObject *object)
 	g_slist_free (priv->aggregate_data);
 
 	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);
@@ -264,19 +280,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
@@ -683,6 +706,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 *
@@ -881,6 +906,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
index a704531..2672dcb 100644
--- a/src/libtracker-db/tracker-db-journal.c
+++ b/src/libtracker-db/tracker-db-journal.c
@@ -31,6 +31,8 @@
 static gchar *filename = NULL;
 static FILE *journal = NULL;
 
+#define TRACKER_DB_JOURNAL_LOG_FILENAME		"log.sparql.txt"
+
 static void
 get_filename (void)
 {
@@ -41,6 +43,13 @@ get_filename (void)
 	}
 }
 
+const gchar*
+tracker_db_journal_filename (void)
+{
+	get_filename ();
+	return (const gchar *) filename;
+}
+
 void
 tracker_db_journal_open (void)
 {
diff --git a/src/libtracker-db/tracker-db-journal.h b/src/libtracker-db/tracker-db-journal.h
index bb2aeac..6fe017b 100644
--- a/src/libtracker-db/tracker-db-journal.h
+++ b/src/libtracker-db/tracker-db-journal.h
@@ -26,10 +26,10 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-#define TRACKER_DB_JOURNAL_LOG_FILENAME		"log.sparql.txt"
 
 G_BEGIN_DECLS
 
+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);
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index b4fc682..484450a 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -38,6 +38,7 @@
 #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
@@ -153,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;
@@ -1260,9 +1263,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)
 {
@@ -1373,7 +1425,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;
@@ -1407,7 +1459,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 9dc067d..eddf10f 100644
--- a/src/libtracker-db/tracker-db-manager.h
+++ b/src/libtracker-db/tracker-db-manager.h
@@ -57,12 +57,12 @@ void	     tracker_db_manager_remove_all		    (void);
 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..7fb005a 100644
--- a/src/tracker-store/tracker-backup.c
+++ b/src/tracker-store/tracker-backup.c
@@ -81,74 +81,67 @@ backup_callback (GError *error, gpointer user_data)
 
 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;
+	GFile *destination, *journal;
 
 	request_id = tracker_dbus_get_next_request_id ();
 
 	tracker_dbus_request_new (request_id,
 	                          "DBus request to save backup into '%s'",
-	                          uri);
+	                          destination_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 = g_file_new_for_uri (destination_uri);
+	journal = g_file_new_for_uri (journal_uri);
 
 	info = g_slice_new (TrackerDBusMethodInfo);
 
 	info->request_id = request_id;
 	info->context = context;
 
-	tracker_data_backup_save (file, backup_callback,
+	tracker_data_backup_save (destination, journal,
+	                          backup_callback,
 	                          info, destroy_method_info);
 
-	g_object_unref (file);
+	g_object_unref (destination);
+	g_object_unref (journal);
 }
 
 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);
+	                          backup_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 = g_file_new_for_uri (backup_uri);
+	journal = g_file_new_for_uri (journal_uri);
 
 	info = g_slice_new (TrackerDBusMethodInfo);
 
 	info->request_id = request_id;
 	info->context = context;
 
-	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);
 



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