[tracker/quad] Implemented backup support in quad
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker/quad] Implemented backup support in quad
- Date: Thu, 23 Jul 2009 10:58:11 +0000 (UTC)
commit 13a1b12a2351ab85730ba8d0fe16470e4a257555
Author: Philip Van Hoof <philip codeminded be>
Date: Thu Jul 23 12:53:44 2009 +0200
Implemented backup support in quad
src/libtracker-db/tracker-db-backup.c | 240 +++++++++++++++++++++++++++++++++
src/libtracker-db/tracker-db-backup.h | 48 +++++++
src/tracker-store/tracker-backup.c | 64 +++++++---
3 files changed, 334 insertions(+), 18 deletions(-)
---
diff --git a/src/libtracker-db/tracker-db-backup.c b/src/libtracker-db/tracker-db-backup.c
new file mode 100644
index 0000000..8947865
--- /dev/null
+++ b/src/libtracker-db/tracker-db-backup.c
@@ -0,0 +1,240 @@
+/* -*- 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 <glib.h>
+#include <glib/gstdio.h>
+
+#include <sqlite3.h>
+
+#include <raptor.h>
+
+#include <libtracker-db/tracker-db-manager.h>
+
+#include "tracker-db-backup.h"
+
+
+typedef struct {
+ TrackerBackupFinished callback;
+ GDestroyNotify destroy;
+ gpointer user_data;
+ GFile *file;
+ GOutputStream *stream;
+ GError *error;
+ sqlite3_stmt *stmt;
+ sqlite3 *db;
+ int result;
+} 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->destroy) {
+ info->destroy (info->user_data);
+ }
+
+ if (info->stream) {
+ g_object_unref (info->stream);
+ }
+
+ g_object_unref (info->file);
+ g_clear_error (&info->error);
+
+ if (info->stmt) {
+ sqlite3_finalize (info->stmt);
+ }
+
+ if (info->db) {
+ sqlite3_close (info->db);
+ }
+
+ g_free (info);
+}
+
+
+static gboolean
+backup_machine_step (gpointer user_data)
+{
+ BackupInfo *info = user_data;
+ gboolean cont = TRUE;
+ guint cnt = 0;
+ gboolean is_uri;
+ gchar *buffer;
+ GError *error = NULL;
+ gsize written;
+
+ while (info->result == SQLITE_OK ||
+ info->result == SQLITE_ROW) {
+
+ info->result = sqlite3_step (info->stmt);
+
+ switch (info->result) {
+ case SQLITE_ERROR:
+ sqlite3_reset (info->stmt);
+ cont = FALSE;
+ break;
+
+ case SQLITE_ROW:
+ is_uri = (gboolean) sqlite3_column_int (info->stmt, 3);
+
+ buffer = g_strdup_printf ("<%s> <%s> %c%s%c .\n",
+ sqlite3_column_text (info->stmt, 0),
+ sqlite3_column_text (info->stmt, 1),
+ is_uri ? '<' : '"',
+ sqlite3_column_text (info->stmt, 2),
+ is_uri ? '>' : '"');
+
+ g_output_stream_write_all (info->stream, buffer,
+ strlen (buffer),
+ &written,
+ NULL, &error);
+
+ if (error) {
+ sqlite3_reset (info->stmt);
+ cont = FALSE;
+ g_propagate_error (info->error, error);
+ }
+
+ g_free (buffer);
+
+ break;
+ default:
+ cont = FALSE;
+ break;
+ }
+
+ if (cnt > 100) {
+ break;
+ }
+
+ cnt++;
+ }
+
+ return cont;
+}
+
+static void
+on_backup_finished (gpointer user_data)
+{
+ BackupInfo *info = user_data;
+
+ 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->db));
+ }
+
+ if (info->stream) {
+ g_output_stream_close (info->stream, NULL, &info->error);
+ }
+
+ perform_callback (info);
+
+ backup_info_free (info);
+}
+
+void
+tracker_db_backup_save (GFile *turtle_file,
+ TrackerBackupFinished callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ BackupInfo *info = g_new0 (BackupInfo, 1);
+ const gchar *db_file = tracker_db_manager_get_file (TRACKER_DB_QUAD);
+ int retval;
+ const gchar *query;
+ GError *error = NULL;
+
+ info->file = g_object_ref (turtle_file);
+ info->callback = callback;
+ info->user_data = user_data;
+ info->destroy = destroy;
+
+ info->stream = g_file_append_to (turtle_file, G_FILE_CREATE_PRIVATE, NULL, &error);
+
+ if (error) {
+ g_propagate_error (info->error, error);
+ g_idle_add_full (G_PRIORITY_DEFAULT, perform_callback, info,
+ backup_info_free);
+ return;
+ }
+
+ 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;
+ }
+
+ query = "SELECT uris.Uri as subject, urip.Uri as predicate, object, 0 as isUri "
+ "FROM statement_string "
+ "INNER JOIN uri as urip ON statement_string.predicate = urip.ID "
+ "INNER JOIN uri as uris ON statement_string.subject = uris.ID "
+ "UNION ALL " /* Always use UNION ALL here, thanks to Benjamin Otte for pointing out */
+ "SELECT uris.Uri as subject, urip.Uri as predicate, urio.Uri as object, 1 as isUri "
+ "FROM statement_uri "
+ "INNER JOIN uri as urip ON statement_uri.predicate = urip.ID "
+ "INNER JOIN uri as uris ON statement_uri.subject = uris.ID "
+ "INNER JOIN uri as urio ON statement_uri.object = urio.ID ";
+
+ retval = sqlite3_prepare_v2 (info->db, query, -1, &info->stmt, NULL);
+
+ if (retval != SQLITE_OK) {
+ g_set_error (&info->error, TRACKER_DB_BACKUP_ERROR, TRACKER_DB_BACKUP_ERROR_UNKNOWN,
+ "%s", sqlite3_errmsg (info->db));
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, perform_callback, info,
+ backup_info_free);
+
+ return;
+ }
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, backup_machine_step, info,
+ on_backup_finished);
+
+ return;
+}
+
diff --git a/src/libtracker-db/tracker-db-backup.h b/src/libtracker-db/tracker-db-backup.h
new file mode 100644
index 0000000..077b798
--- /dev/null
+++ b/src/libtracker-db/tracker-db-backup.h
@@ -0,0 +1,48 @@
+/* -*- 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>
+
+G_BEGIN_DECLS
+
+#define TRACKER_DB_BACKUP_ERROR (tracker_db_backup_error_quark ())
+
+typedef enum {
+ TRACKER_DB_BACKUP_ERROR_UNKNOWN,
+} TrackerDBBackupError;
+
+typedef void (*TrackerBackupFinished) (GError *error, gpointer user_data);
+
+GQuark tracker_db_backup_error_quark (void);
+
+void tracker_db_backup_save (GFile *turtle_file,
+ TrackerBackupFinished callback,
+ gpointer user_data,
+ GDestroyNotify destroy);
+
+G_END_DECLS
+
+#endif /* __TRACKER_DB_BACKUP_H__ */
diff --git a/src/tracker-store/tracker-backup.c b/src/tracker-store/tracker-backup.c
index 0739120..f55bee7 100644
--- a/src/tracker-store/tracker-backup.c
+++ b/src/tracker-store/tracker-backup.c
@@ -55,6 +55,41 @@ tracker_backup_new (void)
return g_object_new (TRACKER_TYPE_BACKUP, NULL);
}
+typedef struct {
+ GFile *file;
+ guint request_id;
+ DBusGMethodInvocation *context;
+} BackupInfo;
+
+static void
+on_backup_destroy (gpointer user_data)
+{
+ BackupInfo *info = user_data;
+ g_object_unref (info->file);
+ g_free (info);
+}
+
+static void
+on_backup_finished (GError *error, gpointer user_data)
+{
+ BackupInfo *info = user_data;
+
+ if (error) {
+ GError *actual_error = NULL;
+
+ tracker_dbus_request_failed (info->request_id,
+ &actual_error,
+ error->message);
+
+ dbus_g_method_return_error (info->context, actual_error);
+
+ g_error_free (actual_error);
+ } else {
+ dbus_g_method_return (info->context);
+ tracker_dbus_request_success (info->request_id);
+ }
+}
+
void
tracker_backup_save (TrackerBackup *object,
const gchar *uri,
@@ -62,8 +97,8 @@ tracker_backup_save (TrackerBackup *object,
GError **error)
{
guint request_id;
- GError *err = NULL;
GFile *file;
+ BackupInfo *info;
request_id = tracker_dbus_get_next_request_id ();
@@ -83,27 +118,19 @@ tracker_backup_save (TrackerBackup *object,
file = g_file_new_for_uri (uri);
}
- //tracker_data_backup_save (file, &err);
-
- g_object_unref (file);
-
- if (err) {
- GError *actual_error = NULL;
+ info = g_new (BackupInfo, 1);
- tracker_dbus_request_failed (request_id,
- &actual_error,
- err->message);
+ info->request_id = request_id;
+ info->file = file;
+ info->context = context;
- dbus_g_method_return_error (context, actual_error);
+ tracker_db_backup_save (file,
+ on_backup_finished,
+ info,
+ on_backup_destroy);
- g_error_free (actual_error);
- g_error_free (err);
- } else {
- dbus_g_method_return (context);
- tracker_dbus_request_success (request_id);
- }
}
-
+#if 0
static void
destroy_method_info (gpointer user_data)
{
@@ -127,6 +154,7 @@ backup_callback (GError *error, gpointer user_data)
tracker_dbus_request_success (info->request_id);
}
+#endif
void
tracker_backup_restore (TrackerBackup *object,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]