[tracker/binary-log-2: 56/56] Reimplemented backup and restore support
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/binary-log-2: 56/56] Reimplemented backup and restore support
- Date: Fri, 8 Jan 2010 10:37:16 +0000 (UTC)
commit 5969e12a866cac6bfcc9b4f548470f94bb1f15f2
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Jan 7 12:36:13 2010 +0100
Reimplemented backup and restore support
src/libtracker-data/tracker-data-backup.c | 52 +++++--
src/libtracker-data/tracker-data-backup.h | 3 +
src/libtracker-db/tracker-db-interface-sqlite.c | 24 ---
src/libtracker-db/tracker-db-interface.c | 15 --
src/libtracker-db/tracker-db-interface.h | 4 -
src/libtracker-db/tracker-db-manager.c | 215 ++++++++++++++++-------
src/libtracker-db/tracker-db-manager.h | 27 ++--
7 files changed, 214 insertions(+), 126 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-backup.c b/src/libtracker-data/tracker-data-backup.c
index cdff110..869fb54 100644
--- a/src/libtracker-data/tracker-data-backup.c
+++ b/src/libtracker-data/tracker-data-backup.c
@@ -24,6 +24,7 @@
#include <libtracker-db/tracker-db-manager.h>
#include <libtracker-db/tracker-db-journal.h>
+#include <libtracker-data/tracker-data-manager.h>
#include "tracker-data-backup.h"
@@ -35,6 +36,12 @@ typedef struct {
GError *error;
} BackupSaveInfo;
+GQuark
+tracker_data_backup_error_quark (void)
+{
+ return g_quark_from_static_string (TRACKER_DATA_BACKUP_ERROR_DOMAIN);
+}
+
static void
free_backup_save_info (BackupSaveInfo *info)
{
@@ -89,6 +96,10 @@ tracker_data_backup_save (GFile *destination,
info->user_data = user_data;
info->destroy = destroy;
+ /* It's fine to copy this asynchronous: the journal replay code can or
+ * should cope with unfinished entries at the end of the file, while
+ * restoring a backup made this way. */
+
g_file_copy_async (info->journal, info->destination,
G_FILE_COPY_OVERWRITE,
G_PRIORITY_HIGH,
@@ -119,9 +130,6 @@ tracker_data_backup_restore (GFile *journal,
{
BackupSaveInfo *info;
- tracker_db_manager_disconnect ();
- tracker_db_journal_shutdown ();
-
info = g_new0 (BackupSaveInfo, 1);
info->destination = g_file_new_for_path (tracker_db_journal_get_filename ());
info->journal = g_object_ref (journal);
@@ -129,18 +137,38 @@ tracker_data_backup_restore (GFile *journal,
info->user_data = user_data;
info->destroy = destroy;
- /* TODO, this depends on Jürg's replay APIs */
+ if (g_file_query_exists (info->journal, NULL)) {
+ TrackerDBManagerFlags flags = tracker_db_manager_get_flags ();
+ gboolean is_first;
+
+ tracker_db_manager_move_to_temp ();
+ tracker_data_manager_shutdown ();
- g_file_copy (info->journal, info->destination,
- G_FILE_COPY_OVERWRITE,
- NULL, NULL, NULL,
- &info->error);
+ /* Synchronous: we don't want the mainloop to run while copying the
+ * journal, as nobody should be writing anything at this point */
- tracker_db_journal_init (NULL);
- /* tracker_db_journal_replay (); */
- tracker_db_manager_reconnect ();
+ g_file_copy (info->journal, info->destination,
+ G_FILE_COPY_OVERWRITE,
+ NULL, NULL, NULL,
+ &info->error);
- tracker_db_backup_sync_fts ();
+ tracker_db_manager_init_locations ();
+ tracker_db_journal_init (NULL);
+
+ if (info->error) {
+ tracker_db_manager_restore_from_temp ();
+ } else {
+ tracker_db_manager_remove_temp ();
+ }
+
+ tracker_db_journal_shutdown ();
+
+ tracker_data_manager_init (flags, NULL, &is_first);
+
+ } else {
+ g_set_error (&info->error, TRACKER_DATA_BACKUP_ERROR, 0,
+ "Backup file doesn't exist");
+ }
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 c5abf06..8dc4acf 100644
--- a/src/libtracker-data/tracker-data-backup.h
+++ b/src/libtracker-data/tracker-data-backup.h
@@ -30,6 +30,9 @@ G_BEGIN_DECLS
#error "only <libtracker-data/tracker-data.h> must be included directly."
#endif
+#define TRACKER_DATA_BACKUP_ERROR_DOMAIN "TrackerBackup"
+#define TRACKER_DATA_BACKUP_ERROR tracker_data_backup_error_quark()
+
typedef void (*TrackerDataBackupFinished) (GError *error, gpointer user_data);
GQuark tracker_data_backup_error_quark (void);
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index 144c20d..5420e32 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -125,8 +125,6 @@ static GType tracker_db_statement_sqlite_get_type (void);
static void tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface);
static void tracker_db_statement_sqlite_iface_init (TrackerDBStatementIface *iface);
static void tracker_db_cursor_sqlite_iface_init (TrackerDBCursorIface *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);
@@ -754,8 +752,6 @@ 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 *
@@ -1156,26 +1152,6 @@ tracker_db_cursor_sqlite_get_string (TrackerDBCursor *cursor, guint column)
return (const gchar *) sqlite3_column_text (priv->stmt, column);
}
-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,
diff --git a/src/libtracker-db/tracker-db-interface.c b/src/libtracker-db/tracker-db-interface.c
index db296b2..881c9e7 100644
--- a/src/libtracker-db/tracker-db-interface.c
+++ b/src/libtracker-db/tracker-db-interface.c
@@ -390,21 +390,6 @@ tracker_db_interface_end_transaction (TrackerDBInterface *interface)
return TRUE;
}
-void
-tracker_db_interface_disconnect (TrackerDBInterface *interface)
-{
- g_return_if_fail (TRACKER_IS_DB_INTERFACE (interface));
-
- TRACKER_DB_INTERFACE_GET_IFACE (interface)->disconnect (interface);
-}
-
-void
-tracker_db_interface_reconnect (TrackerDBInterface *interface)
-{
- g_return_if_fail (TRACKER_IS_DB_INTERFACE (interface));
-
- TRACKER_DB_INTERFACE_GET_IFACE (interface)->reconnect (interface);
-}
void
tracker_db_statement_bind_double (TrackerDBStatement *stmt,
diff --git a/src/libtracker-db/tracker-db-interface.h b/src/libtracker-db/tracker-db-interface.h
index 7c466a8..7b38b73 100644
--- a/src/libtracker-db/tracker-db-interface.h
+++ b/src/libtracker-db/tracker-db-interface.h
@@ -76,8 +76,6 @@ struct TrackerDBInterfaceIface {
TrackerDBResultSet * (* execute_query) (TrackerDBInterface *interface,
GError **error,
const gchar *query);
- void (* disconnect) (TrackerDBInterface *interface);
- void (* reconnect) (TrackerDBInterface *interface);
};
struct TrackerDBStatementIface {
@@ -157,8 +155,6 @@ 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,
double value);
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 913db90..8ace824 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -146,20 +146,22 @@ static TrackerDBDefinition dbs[] = {
0 },
};
-static gboolean db_exec_no_reply (TrackerDBInterface *iface,
- const gchar *query,
- ...);
+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;
-static gchar *data_dir;
-static gchar *user_data_dir;
-static gchar *sys_tmp_dir;
-static gpointer db_type_enum_class_pointer;
-static TrackerDBInterface *resources_iface;
+static gboolean initialized;
+static gboolean locations_initialized;
+static gchar *sql_dir;
+static gchar *data_dir = NULL;
+static gchar *user_data_dir = NULL;
+static gchar *sys_tmp_dir = NULL;
+static gpointer db_type_enum_class_pointer;
+static TrackerDBInterface *resources_iface;
+static TrackerDBManagerFlags old_flags = 0;
static const gchar *
location_to_directory (TrackerDBLocation location)
@@ -297,6 +299,12 @@ function_regexp (TrackerDBInterface *interface,
return result;
}
+TrackerDBManagerFlags
+tracker_db_manager_get_flags (void)
+{
+ return old_flags;
+}
+
static void
function_group_concat_step (TrackerDBInterface *interface,
void *aggregate_context,
@@ -847,7 +855,7 @@ db_interface_create (TrackerDB db)
}
static void
-db_manager_remove_all (gboolean rm_backup_and_log)
+db_manager_remove_all (gboolean rm_journal)
{
guint i;
@@ -863,7 +871,7 @@ db_manager_remove_all (gboolean rm_backup_and_log)
g_unlink (dbs[i].abs_filename);
}
- if (rm_backup_and_log) {
+ if (rm_journal) {
GFile *file;
gchar *cpath;
@@ -1053,6 +1061,38 @@ db_recreate_all (void)
}
}
+void
+tracker_db_manager_init_locations (void)
+{
+ const gchar *dir;
+ guint i;
+ gchar *filename;
+
+ filename = g_strdup_printf ("tracker-%s", g_get_user_name ());
+ sys_tmp_dir = g_build_filename (g_get_tmp_dir (), filename, NULL);
+ g_free (filename);
+
+ user_data_dir = g_build_filename (g_get_user_data_dir (),
+ "tracker",
+ "data",
+ NULL);
+
+ data_dir = g_build_filename (g_get_user_cache_dir (),
+ "tracker",
+ NULL);
+
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ dir = location_to_directory (dbs[i].location);
+ dbs[i].abs_filename = g_build_filename (dir, dbs[i].file, NULL);
+
+ if (old_flags & TRACKER_DB_MANAGER_LOW_MEMORY_MODE) {
+ dbs[i].cache_size /= 2;
+ }
+ }
+
+ locations_initialized = TRUE;
+}
+
gboolean
tracker_db_manager_init (TrackerDBManagerFlags flags,
gboolean *first_time,
@@ -1094,7 +1134,11 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
/* Set up locations */
g_message ("Setting database locations");
+ old_flags = flags;
+
filename = g_strdup_printf ("tracker-%s", g_get_user_name ());
+ if (sys_tmp_dir)
+ g_free (sys_tmp_dir);
sys_tmp_dir = g_build_filename (g_get_tmp_dir (), filename, NULL);
g_free (filename);
@@ -1108,11 +1152,17 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
sql_dir = g_strdup (env_path);
}
+ if (user_data_dir)
+ g_free (user_data_dir);
+
user_data_dir = g_build_filename (g_get_user_data_dir (),
"tracker",
"data",
NULL);
+ if (data_dir)
+ g_free (data_dir);
+
data_dir = g_build_filename (g_get_user_cache_dir (),
"tracker",
NULL);
@@ -1142,6 +1192,8 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
/* Fill absolute path for the database */
dir = location_to_directory (dbs[i].location);
+ if (dbs[i].abs_filename)
+ g_free (dbs[i].abs_filename);
dbs[i].abs_filename = g_build_filename (dir, dbs[i].file, NULL);
if (flags & TRACKER_DB_MANAGER_LOW_MEMORY_MODE) {
@@ -1166,6 +1218,8 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
}
}
+ locations_initialized = TRUE;
+
/* If we are just initializing to remove the databases,
* return here.
*/
@@ -1316,52 +1370,6 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
}
void
-tracker_db_manager_disconnect (void)
-{
- if (resources_iface) {
- guint i;
- TrackerDB attachments[2] = { TRACKER_DB_FULLTEXT,
- TRACKER_DB_CONTENTS };
-
- for (i = 0; i < 2; 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[2] = { TRACKER_DB_FULLTEXT,
- TRACKER_DB_CONTENTS };
-
- 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 < 2; 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)
{
guint i;
@@ -1384,8 +1392,11 @@ tracker_db_manager_shutdown (void)
}
g_free (data_dir);
+ data_dir = NULL;
g_free (user_data_dir);
+ user_data_dir = NULL;
g_free (sys_tmp_dir);
+ sys_tmp_dir = NULL;
g_free (sql_dir);
if (resources_iface) {
@@ -1410,6 +1421,7 @@ tracker_db_manager_shutdown (void)
tracker_ontology_shutdown ();
initialized = FALSE;
+ locations_initialized = FALSE;
in_use_filename = g_build_filename (g_get_user_data_dir (),
"tracker",
@@ -1423,11 +1435,94 @@ tracker_db_manager_shutdown (void)
}
void
-tracker_db_manager_remove_all (gboolean rm_backup_and_log)
+tracker_db_manager_remove_all (gboolean rm_journal)
{
g_return_if_fail (initialized != FALSE);
- db_manager_remove_all (rm_backup_and_log);
+ db_manager_remove_all (rm_journal);
+}
+
+
+void
+tracker_db_manager_move_to_temp (void)
+{
+ guint i;
+ gchar *cpath, *new_filename;
+
+ g_return_if_fail (initialized != FALSE);
+
+ g_message ("Moving all database files");
+
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ new_filename = g_strdup_printf ("%s.tmp", dbs[i].abs_filename);
+ g_message (" Renaming database:'%s' -> '%s'",
+ dbs[i].abs_filename, new_filename);
+ g_rename (dbs[i].abs_filename, new_filename);
+ g_free (new_filename);
+ }
+
+ cpath = g_strdup (tracker_db_journal_get_filename ());
+ new_filename = g_strdup_printf ("%s.tmp", cpath);
+ g_message (" Renaming journal:'%s' -> '%s'",
+ cpath, new_filename);
+ g_rename (cpath, new_filename);
+ g_free (cpath);
+ g_free (new_filename);
+}
+
+
+void
+tracker_db_manager_restore_from_temp (void)
+{
+ guint i;
+ gchar *cpath, *new_filename;
+
+ g_return_if_fail (locations_initialized != FALSE);
+
+ g_message ("Moving all database files");
+
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ new_filename = g_strdup_printf ("%s.tmp", dbs[i].abs_filename);
+ g_message (" Renaming database:'%s' -> '%s'",
+ dbs[i].abs_filename, new_filename);
+ g_rename (dbs[i].abs_filename, new_filename);
+ g_free (new_filename);
+ }
+
+ cpath = g_strdup (tracker_db_journal_get_filename ());
+ new_filename = g_strdup_printf ("%s.tmp", cpath);
+ g_message (" Renaming journal:'%s' -> '%s'",
+ cpath, new_filename);
+ g_rename (cpath, new_filename);
+ g_free (cpath);
+ g_free (new_filename);
+}
+
+void
+tracker_db_manager_remove_temp (void)
+{
+ guint i;
+ gchar *cpath, *new_filename;
+
+ g_return_if_fail (locations_initialized != FALSE);
+
+ g_message ("Removing all temp database files");
+
+ for (i = 1; i < G_N_ELEMENTS (dbs); i++) {
+ new_filename = g_strdup_printf ("%s.tmp", dbs[i].abs_filename);
+ g_message (" Removing temp database:'%s'",
+ new_filename);
+ g_unlink (new_filename);
+ g_free (new_filename);
+ }
+
+ cpath = g_strdup (tracker_db_journal_get_filename ());
+ new_filename = g_strdup_printf ("%s.tmp", cpath);
+ g_message (" Removing temp journal:'%s'",
+ new_filename);
+ g_unlink (new_filename);
+ g_free (cpath);
+ g_free (new_filename);
}
void
diff --git a/src/libtracker-db/tracker-db-manager.h b/src/libtracker-db/tracker-db-manager.h
index f7c6636..5947652 100644
--- a/src/libtracker-db/tracker-db-manager.h
+++ b/src/libtracker-db/tracker-db-manager.h
@@ -47,17 +47,22 @@ typedef enum {
TRACKER_DB_MANAGER_READONLY = 1 << 5
} TrackerDBManagerFlags;
-GType tracker_db_get_type (void) G_GNUC_CONST;
-gboolean tracker_db_manager_init (TrackerDBManagerFlags flags,
- gboolean *first_time,
- gboolean shared_cache);
-void tracker_db_manager_shutdown (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);
-void tracker_db_manager_disconnect (void);
-void tracker_db_manager_reconnect (void);
+GType tracker_db_get_type (void) G_GNUC_CONST;
+gboolean tracker_db_manager_init (TrackerDBManagerFlags flags,
+ gboolean *first_time,
+ gboolean shared_cache);
+void tracker_db_manager_shutdown (void);
+void tracker_db_manager_remove_all (gboolean rm_journal);
+void tracker_db_manager_optimize (void);
+const gchar * tracker_db_manager_get_file (TrackerDB db);
+TrackerDBInterface *tracker_db_manager_get_db_interface (void);
+void tracker_db_manager_remove_temp (void);
+void tracker_db_manager_move_to_temp (void);
+void tracker_db_manager_restore_from_temp (void);
+void tracker_db_manager_init_locations (void);
+
+TrackerDBManagerFlags
+ tracker_db_manager_get_flags (void);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]