[glom] Backup: Simplify the code and fix the problem with groups.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Backup: Simplify the code and fix the problem with groups.
- Date: Tue, 28 Jan 2014 11:03:20 +0000 (UTC)
commit 93f8e43e4874fb17f5554627cd349cb6c33898d5
Author: Murray Cumming <murrayc murrayc com>
Date: Tue Jan 28 10:56:44 2014 +0100
Backup: Simplify the code and fix the problem with groups.
* glom/libglom/connectionpool.[h|cc]: convert_backup():
Take a path to the (postgres-specific) backup data file instead
of a path to the parent directory, so we do not need to
guess the actual path.
* glom/libglom/connectionpool_backends/backend.h
* glom/libglom/connectionpool_backends/mysql.[h|cc]:
* glom/libglom/connectionpool_backends/postgres.[h|cc]:
* glom/libglom/connectionpool_backends/sqlite.[h|cc]: convert_backup():
Rename path_backup to backup_data_file_path to make it clearer.
* glom/libglom/document/document.[h|cc]: extract_backup_file():
Take a path to the (postgres-specific) backup data file,
* glom/appwindow.[h|cc]:
do_restore_backup(): Store the path to the backup data file in
m_backup_data_filepath temporarily.
on_document_load(): Pass m_backup_data_filepath to
recreate_database_from_example().
recreate_database_from_example(): Take a path to the backup data
instead of a URI to the .glom file, and pass that path to
ConnectionPool::convert_backup().
Also add groups before restoring the backup data, because it needs
these groups to exist already.
* glom/libglom/db_utils.cc: add_group(): Do not fail if the
autoincrements table does not exist yet, because this can happen
while restoring data from a backup.
* tests/test_selfhosting_new_then_backup_restore.cc: Adapted.
glom/appwindow.cc | 72 +++++---------
glom/appwindow.h | 5 +-
glom/libglom/connectionpool.cc | 12 +--
glom/libglom/connectionpool.h | 4 +-
glom/libglom/connectionpool_backends/backend.h | 2 +-
glom/libglom/connectionpool_backends/mysql.cc | 7 +-
glom/libglom/connectionpool_backends/mysql.h | 2 +-
glom/libglom/connectionpool_backends/postgres.cc | 11 +-
glom/libglom/connectionpool_backends/postgres.h | 3 +-
glom/libglom/connectionpool_backends/sqlite.cc | 2 +-
glom/libglom/connectionpool_backends/sqlite.h | 2 +-
glom/libglom/db_utils.cc | 5 +
glom/libglom/document/document.cc | 103 ++++++++++++++-------
glom/libglom/document/document.h | 7 +-
tests/test_selfhosting_new_then_backup_restore.cc | 8 +-
15 files changed, 132 insertions(+), 113 deletions(-)
---
diff --git a/glom/appwindow.cc b/glom/appwindow.cc
index 7c2129d..de150ed 100644
--- a/glom/appwindow.cc
+++ b/glom/appwindow.cc
@@ -893,6 +893,9 @@ bool AppWindow::on_document_load()
const bool is_example = pDocument->get_is_example_file();
const bool is_backup = pDocument->get_is_backup_file();
#endif // !GLOM_ENABLE_CLIENT_ONLY
+
+ //Note that the URI will be empty if we are loading from data,
+ //such as when loading a backup.
const std::string original_uri = pDocument->get_file_uri();
if(is_example || is_backup)
@@ -1070,7 +1073,10 @@ bool AppWindow::on_document_load()
if(is_example)
test = recreate_database_from_example(user_cancelled);
else
- test = recreate_database_from_backup(original_uri, user_cancelled);
+ {
+ test = recreate_database_from_backup(m_backup_data_filepath, user_cancelled);
+ m_backup_data_filepath.clear();
+ }
if(!test)
{
@@ -1668,8 +1674,14 @@ bool AppWindow::recreate_database_from_example(bool& user_cancelled)
}
//TODO: Remove duplication with recreate_database_from_example().
-bool AppWindow::recreate_database_from_backup(const Glib::ustring& backup_uri, bool& user_cancelled)
+bool AppWindow::recreate_database_from_backup(const std::string& backup_data_file_path, bool& user_cancelled)
{
+ if(backup_data_file_path.empty())
+ {
+ std::cerr << G_STRFUNC << ": backup_data_file_path is empty." << std::endl;
+ return false;
+ }
+
ShowProgressMessage progress_message(_("Creating Glom database from backup file."));
//Create a database, based on the information in the current document:
@@ -1777,42 +1789,17 @@ bool AppWindow::recreate_database_from_backup(const Glib::ustring& backup_uri, b
//m_pFrame->add_standard_tables(); //Add internal, hidden, tables.
- //Restore the backup into the database:
- std::string original_dir_path;
-
- Glib::RefPtr<Gio::File> gio_file = Gio::File::create_for_uri(backup_uri);
- if(gio_file)
- {
- Glib::RefPtr<Gio::File> parent = gio_file->get_parent();
- if(parent)
- {
- try
- {
- original_dir_path = Glib::filename_from_uri(parent->get_uri());
- }
- catch(const Glib::Error& ex)
- {
- std::cerr << G_STRFUNC << ": Glib::filename_from_uri() failed: " << ex.what() << std::endl;
- }
- }
- }
-
- std::cout << G_STRFUNC << ": debug 6" << std::endl;
-
- if(original_dir_path.empty())
- {
- std::cerr << G_STRFUNC << ": original_dir_path is empty." << std::endl;
+ //Add any extra groups from the example file.
+ //The backup file refers to these,
+ //so the restore will fail if they are not present.
+ pulse_progress_message();
+ test = DbUtils::add_groups_from_document(pDocument);
+ if(!test)
return false;
- }
-
- std::cout << G_STRFUNC << ": debug b1" << std::endl;
- //Restore the database from the backup:
- //std::cout << "DEBUG: original_dir_path=" << original_dir_path << std::endl;
+ //Restore the backup into the database:
const bool restored = connection_pool->convert_backup(
- sigc::mem_fun(*this, &AppWindow::on_connection_convert_backup_progress), original_dir_path);
-
- std::cout << G_STRFUNC << ": debug b2: result=" << restored << std::endl;
+ sigc::mem_fun(*this, &AppWindow::on_connection_convert_backup_progress), backup_data_file_path);
if(!restored)
{
@@ -1820,13 +1807,6 @@ bool AppWindow::recreate_database_from_backup(const Glib::ustring& backup_uri, b
return false;
}
- //TODO: Is this necessary?
- //Add any extra groups from the example file:
- pulse_progress_message();
- test = DbUtils::add_groups_from_document(pDocument);
- if(!test)
- return false;
-
return true; //Restore successfully.
}
#endif // !GLOM_ENABLE_CLIENT_ONLY
@@ -2500,17 +2480,17 @@ bool AppWindow::do_restore_backup(const Glib::ustring& backup_uri)
return false;
ShowProgressMessage progress_message(_("Restoring backup"));
- const Glib::ustring backup_file_contents = Glom::Document::extract_backup_file(
- backup_uri,
+ const Glib::ustring backup_glom_file_contents = Glom::Document::extract_backup_file(
+ backup_uri, m_backup_data_filepath,
sigc::mem_fun(*this, &AppWindow::on_connection_convert_backup_progress));
- if(backup_file_contents.empty())
+ if(backup_glom_file_contents.empty() || m_backup_data_filepath.empty())
{
ui_warning(_("Restore Backup failed."), _("There was an error while extracting the backup."));
return false;
}
- return open_document_from_data((const guchar*)backup_file_contents.c_str(), backup_file_contents.bytes());
+ return open_document_from_data((const guchar*)backup_glom_file_contents.c_str(),
backup_glom_file_contents.bytes());
}
void AppWindow::on_menu_developer_enable_layout_drag_and_drop()
diff --git a/glom/appwindow.h b/glom/appwindow.h
index 9fb5302..c7baa5d 100644
--- a/glom/appwindow.h
+++ b/glom/appwindow.h
@@ -260,7 +260,7 @@ private:
Document* on_connection_pool_get_document();
bool recreate_database_from_example(bool& user_cancelled); //return indicates success.
- bool recreate_database_from_backup(const Glib::ustring& backup_uri, bool& user_cancelled); //return
indicates success.
+ bool recreate_database_from_backup(const std::string& backup_data_file_path, bool& user_cancelled);
//return indicates success.
void on_recreate_database_progress();
void stop_self_hosting_of_document_database();
@@ -349,6 +349,9 @@ private:
//so we can use them again when connecting directly to the database:
Glib::ustring m_temp_username, m_temp_password;
+ //This is set temporarily while restoring a backup.
+ std::string m_backup_data_filepath;
+
bool m_show_sql_debug;
static Glib::ustring m_current_locale, m_original_locale;
diff --git a/glom/libglom/connectionpool.cc b/glom/libglom/connectionpool.cc
index 9572c9e..8907f5d 100644
--- a/glom/libglom/connectionpool.cc
+++ b/glom/libglom/connectionpool.cc
@@ -455,19 +455,11 @@ bool ConnectionPool::save_backup(const SlotProgress& slot_progress, const std::s
return result;
}
-bool ConnectionPool::convert_backup(const SlotProgress& slot_progress, const std::string& path_dir)
+bool ConnectionPool::convert_backup(const SlotProgress& slot_progress, const std::string&
backup_data_file_path)
{
g_assert(m_backend.get());
- //TODO_MySQL:
- //TODO: Avoid this copy/paste of the directory name:
- std::string path_dir_to_use = path_dir;
- if(!path_dir_to_use.empty())
- {
- path_dir_to_use = Glib::build_filename(path_dir, "glom_postgres_data");
- }
-
- const bool result = m_backend->convert_backup(slot_progress, path_dir_to_use, m_user, m_password,
m_database);
+ const bool result = m_backend->convert_backup(slot_progress, backup_data_file_path, m_user, m_password,
m_database);
if(!result)
return false;
diff --git a/glom/libglom/connectionpool.h b/glom/libglom/connectionpool.h
index b485a78..accd749 100644
--- a/glom/libglom/connectionpool.h
+++ b/glom/libglom/connectionpool.h
@@ -179,10 +179,10 @@ public:
/** Use a backup of the database in a tarball to create tables and data in an existing empty database.
* The database (server) should already have the necessary groups and users.
*
- * @param path_dir The top-level directory for the backup file, using the normal directory structure.
+ * @param path_dir The path to the database-server-specific backup file.
* See save_backup().
*/
- bool convert_backup(const SlotProgress& slot_progress, const std::string& path_dir);
+ bool convert_backup(const SlotProgress& slot_progress, const std::string& backup_data_file_path);
void set_user(const Glib::ustring& value);
void set_password(const Glib::ustring& value);
diff --git a/glom/libglom/connectionpool_backends/backend.h b/glom/libglom/connectionpool_backends/backend.h
index 7e23686..08e8ffa 100644
--- a/glom/libglom/connectionpool_backends/backend.h
+++ b/glom/libglom/connectionpool_backends/backend.h
@@ -195,7 +195,7 @@ protected:
* The database (server) should already have the necessary groups and users.
* See save_backup().
*/
- virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& base_directory_uri,
const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name) = 0;
+ virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& backup_data_file_path,
const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name) = 0;
protected:
std::string m_database_directory_uri;
diff --git a/glom/libglom/connectionpool_backends/mysql.cc b/glom/libglom/connectionpool_backends/mysql.cc
index e05d6be..87571c6 100644
--- a/glom/libglom/connectionpool_backends/mysql.cc
+++ b/glom/libglom/connectionpool_backends/mysql.cc
@@ -595,7 +595,7 @@ bool MySQL::save_backup(const SlotProgress& slot_progress, const Glib::ustring&
return result;
}
-bool MySQL::convert_backup(const SlotProgress& slot_progress, const std::string& base_directory, const
Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& /* database_name */)
+bool MySQL::convert_backup(const SlotProgress& slot_progress, const std::string& backup_data_file_path,
const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& /* database_name */)
{
/* TODO:
if(m_network_shared && !running)
@@ -631,10 +631,9 @@ bool MySQL::convert_backup(const SlotProgress& slot_progress, const std::string&
}
//Make sure the path exists:
- const std::string path_backup = get_self_hosting_backup_path(base_directory);
- if(path_backup.empty() || !file_exists_filepath(path_backup))
+ if(backup_data_file_path.empty() || !file_exists_filepath(backup_data_file_path))
{
- std::cerr << G_STRFUNC << ": Backup file not found: " << path_backup << std::endl;
+ std::cerr << G_STRFUNC << ": Backup file not found: " << backup_data_file_path << std::endl;
return false;
}
diff --git a/glom/libglom/connectionpool_backends/mysql.h b/glom/libglom/connectionpool_backends/mysql.h
index 218cccc..59a7f82 100644
--- a/glom/libglom/connectionpool_backends/mysql.h
+++ b/glom/libglom/connectionpool_backends/mysql.h
@@ -49,7 +49,7 @@ public:
*/
virtual bool save_backup(const SlotProgress& slot_progress, const Glib::ustring& username, const
Glib::ustring& password, const Glib::ustring& database_name);
- virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& base_directory, const
Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
+ virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& backup_data_file_path,
const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
/** Return the quoted path to the specified PostgreSQL utility.
*/
diff --git a/glom/libglom/connectionpool_backends/postgres.cc
b/glom/libglom/connectionpool_backends/postgres.cc
index 98f0770..04fe6c2 100644
--- a/glom/libglom/connectionpool_backends/postgres.cc
+++ b/glom/libglom/connectionpool_backends/postgres.cc
@@ -660,7 +660,7 @@ bool Postgres::save_backup(const SlotProgress& slot_progress, const Glib::ustrin
return result;
}
-bool Postgres::convert_backup(const SlotProgress& slot_progress, const std::string& base_directory, const
Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name)
+bool Postgres::convert_backup(const SlotProgress& slot_progress, const std::string& backup_data_file_path,
const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name)
{
/* TODO:
if(m_network_shared && !running)
@@ -696,10 +696,9 @@ bool Postgres::convert_backup(const SlotProgress& slot_progress, const std::stri
}
//Make sure the path exists:
- const std::string path_backup = get_self_hosting_backup_path(base_directory);
- if(path_backup.empty() || !file_exists_filepath(path_backup))
+ if(backup_data_file_path.empty() || !file_exists_filepath(backup_data_file_path))
{
- std::cerr << G_STRFUNC << ": Backup file not found: " << path_backup << std::endl;
+ std::cerr << G_STRFUNC << ": Backup file not found: " << backup_data_file_path << std::endl;
return false;
}
@@ -720,9 +719,9 @@ bool Postgres::convert_backup(const SlotProgress& slot_progress, const std::stri
" --host=" + Glib::shell_quote(m_host) +
" --port=" + port_as_string(m_port) +
" --username=" + Glib::shell_quote(username) +
- " " + path_backup;
+ " " + backup_data_file_path;
- std::cout << "DEBUG: command_restore=" << command_restore << std::endl;
+ std::cout << G_STRFUNC << "DEBUG: command_restore=" << command_restore << std::endl;
//TODO: Put the password in .pgpass
diff --git a/glom/libglom/connectionpool_backends/postgres.h b/glom/libglom/connectionpool_backends/postgres.h
index d558612..8c84153 100644
--- a/glom/libglom/connectionpool_backends/postgres.h
+++ b/glom/libglom/connectionpool_backends/postgres.h
@@ -49,7 +49,7 @@ public:
*/
virtual bool save_backup(const SlotProgress& slot_progress, const Glib::ustring& username, const
Glib::ustring& password, const Glib::ustring& database_name);
- virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& base_directory, const
Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
+ virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& backup_data_file_path,
const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
/** Return the quoted path to the specified PostgreSQL utility.
*/
@@ -82,6 +82,7 @@ protected:
*/
std::string get_self_hosting_data_path(bool create = false);
+ //TODO: Remove this?
/** Get the path to the backup file, regardless of whether it exists.
* @param base_directory Where to find the backup file, under a normal Glom directory structure.
* If @a base_directory is empty then it uses get_database_directory_uri().
diff --git a/glom/libglom/connectionpool_backends/sqlite.cc b/glom/libglom/connectionpool_backends/sqlite.cc
index 272862b..86371e6 100644
--- a/glom/libglom/connectionpool_backends/sqlite.cc
+++ b/glom/libglom/connectionpool_backends/sqlite.cc
@@ -412,7 +412,7 @@ bool Sqlite::save_backup(const SlotProgress& /* slot_progress */, const Glib::us
return false;
}
-bool Sqlite::convert_backup(const SlotProgress& /* slot_progress */, const std::string& /* base_directory
*/, const Glib::ustring& /* username */, const Glib::ustring& /* password */, const Glib::ustring& /*
database_name */)
+bool Sqlite::convert_backup(const SlotProgress& /* slot_progress */, const std::string& /*
backup_data_file_path */, const Glib::ustring& /* username */, const Glib::ustring& /* password */, const
Glib::ustring& /* database_name */)
{
//TODO:
std::cerr << G_STRFUNC << ": Not implemented.";
diff --git a/glom/libglom/connectionpool_backends/sqlite.h b/glom/libglom/connectionpool_backends/sqlite.h
index 6726743..b85de41 100644
--- a/glom/libglom/connectionpool_backends/sqlite.h
+++ b/glom/libglom/connectionpool_backends/sqlite.h
@@ -62,7 +62,7 @@ private:
virtual bool create_database(const SlotProgress& slot_progress, const Glib::ustring& database_name, const
Glib::ustring& username, const Glib::ustring& password);
virtual bool save_backup(const SlotProgress& slot_progress, const Glib::ustring& username, const
Glib::ustring& password, const Glib::ustring& database_name);
- virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& base_directory, const
Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
+ virtual bool convert_backup(const SlotProgress& slot_progress, const std::string& backup_data_file_path,
const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
};
} //namespace ConnectionPoolBackends
diff --git a/glom/libglom/db_utils.cc b/glom/libglom/db_utils.cc
index 66b7847..6ce47d9 100644
--- a/glom/libglom/db_utils.cc
+++ b/glom/libglom/db_utils.cc
@@ -2202,6 +2202,10 @@ bool add_group(const Document* document, const Glib::ustring& group, bool superu
}
//Let them edit the autoincrements too:
+ //Do not fail if the autoincrements table does not yet exist, because this can happen during restoring of
a backup.
+ if(std::find(table_list.begin(), table_list.end(), GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME) ==
table_list.end())
+ return true;
+
if(!Privs::set_table_privileges(group, GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME, priv))
{
std::cerr << G_STRFUNC << "Privs::set_table_privileges() failed." << std::endl;
@@ -2211,6 +2215,7 @@ bool add_group(const Document* document, const Glib::ustring& group, bool superu
return true;
}
+
bool remove_user(const Glib::ustring& user)
{
if(user.empty())
diff --git a/glom/libglom/document/document.cc b/glom/libglom/document/document.cc
index 6a6dc72..1cb6dcd 100644
--- a/glom/libglom/document/document.cc
+++ b/glom/libglom/document/document.cc
@@ -37,6 +37,7 @@
#include <libglom/translations_po.h>
#include <giomm/file.h>
#include <glibmm/miscutils.h>
+#include <glibmm/fileutils.h>
#include <glibmm/convert.h>
#include <libglom/connectionpool.h>
@@ -5064,8 +5065,44 @@ Glib::ustring Document::save_backup_file(const Glib::ustring& uri, const SlotPro
return Glib::filename_to_uri(tarball_path);
}
-Glib::ustring Document::extract_backup_file(const Glib::ustring& backup_uri, const SlotProgress&
slot_progress)
+namespace { //anonymous namespace
+
+void read_archive_entry_file_contents(archive* a, archive_entry* entry, std::string& file_contents)
+{
+ file_contents.clear();
+
+ const size_t size = archive_entry_size(entry);
+ const Glib::ScopedPtr<char> buf ((char*) g_malloc(size + 1));
+
+ const ssize_t r = archive_read_data(a, buf.get(), size);
+
+ if((r == ARCHIVE_FATAL) || (r == ARCHIVE_WARN) ||
+ (r == ARCHIVE_RETRY)) //0 or a number of bytes read are the signs of success.
+ {
+ std::cerr << G_STRFUNC << ": Error while reading data from archive entry. r=" << r << std::endl;
+ handle_archive_error(a);
+ return;
+ }
+
+ try
+ {
+ //For std::string, size is number of characters. For ustring it would be number of characters.
+ file_contents += std::string(buf.get(), r);
+ }
+ catch(const std::exception& ex)
+ {
+ std::cerr << G_STRFUNC << ": std::exception error while concatenating archive data: "
+ << ex.what() << std::endl;
+ return;
+ }
+}
+
+} //anonymous namespaces
+
+Glib::ustring Document::extract_backup_file(const Glib::ustring& backup_uri, std::string& backup_path, const
SlotProgress& slot_progress)
{
+ backup_path.clear();
+
// We cannot use an uri here, because we cannot untar remote files.
const std::string filename_tarball = Glib::filename_from_uri(backup_uri);
@@ -5096,15 +5133,7 @@ Glib::ustring Document::extract_backup_file(const Glib::ustring& backup_uri, con
slot_progress();
- //We expect just one file:
- struct archive_entry* entry = 0;
- if(archive_read_next_header(a, &entry) != ARCHIVE_OK)
- {
- std::cerr << G_STRFUNC << ": Could not read next archive entry." << std::endl;
- handle_archive_error(a);
- return Glib::ustring();
- }
-
+
//const char *name = archive_entry_pathname(entry);
//std::cout << "debug: name=" << name << std::endl;
@@ -5115,37 +5144,43 @@ Glib::ustring Document::extract_backup_file(const Glib::ustring& backup_uri, con
//Read the whole file in one go,
//We'd have to keep it all in memory anyway as we concatentated it,
//if we did it in chunks.
- //TODO: Backup files will, of course, often have large amounts of (example) data.
- //So we should, elsewhere, make it possible to load that data progressively,
- //maybe discarding it during a first read, and adapt this code to that new API.
slot_progress();
- const size_t size = archive_entry_size(entry);
- const Glib::ScopedPtr<char> buf ((char*) g_malloc(size + 1));
- const ssize_t r = archive_read_data(a, buf.get(), size);
-
- if((r == ARCHIVE_FATAL) || (r == ARCHIVE_WARN) ||
- (r == ARCHIVE_RETRY)) //0 or a number of bytes read are the signs of success.
- {
- std::cerr << G_STRFUNC << ": Error while reading data from archive entry. r=" << r << std::endl;
- handle_archive_error(a);
- return Glib::ustring();
- }
- try
- {
- //For std::string, size is number of characters. For ustring it would be number of characters.
- contents += std::string(buf.get(), r);
- }
- catch(const std::exception& ex)
+ std::string contents_glom_file;
+
+ struct archive_entry* entry = 0;
+ while(archive_read_next_header(a, &entry) == ARCHIVE_OK)
{
- std::cerr << G_STRFUNC << ": std::exception error while concatenating archive data: "
- << ex.what() << std::endl;
- return Glib::ustring();
+ const char* pathname = archive_entry_pathname(entry);
+ if(!pathname)
+ continue;
+
+ const std::string basename = Glib::path_get_basename(pathname);
+ //std::cout << G_STRFUNC << ": debug: basename=" << basename << std::endl;
+
+ bool is_glom_file = false;
+ const std::string without_suffix = Glom::Utils::string_remove_suffix(basename, ".glom");
+ if(without_suffix != basename)
+ is_glom_file = true;
+
+ if(is_glom_file)
+ {
+ read_archive_entry_file_contents(a, entry, contents_glom_file);
+ }
+ else if(basename == "backup")
+ {
+ std::string contents_backup_file;
+ read_archive_entry_file_contents(a, entry, contents_backup_file);
+
+ backup_path = Utils::get_temp_file_path("glom_backup");
+ Glib::file_set_contents(backup_path, contents_backup_file);
+ //std::cout << "debug: backup data path: " << backup_path << std::endl;
+ }
}
- return contents;
+ return contents_glom_file;
}
diff --git a/glom/libglom/document/document.h b/glom/libglom/document/document.h
index daacd57..3522ea9 100644
--- a/glom/libglom/document/document.h
+++ b/glom/libglom/document/document.h
@@ -464,11 +464,14 @@ public:
*/
Glib::ustring save_backup_file(const Glib::ustring& uri, const SlotProgress& slot_progress);
- /**
+ /** Extract the .glom file and backup data from a .tar.gz archive.
+ * The backup data must be stored temporarily on disk because pg_restore requires a file on disk.
+ *
* @param backup_uri: The URI of a .tar.gz backup file.
+ * @param backup_path This will be set to the path of a temporary file for use with pg_restore.
* @result The contents of the .glom file from the .tar.gz file.
*/
- static Glib::ustring extract_backup_file(const Glib::ustring& backup_uri, const SlotProgress&
slot_progress);
+ static Glib::ustring extract_backup_file(const Glib::ustring& backup_uri, std::string& backup_path, const
SlotProgress& slot_progress);
protected:
diff --git a/tests/test_selfhosting_new_then_backup_restore.cc
b/tests/test_selfhosting_new_then_backup_restore.cc
index 0a21756..8a22c33 100644
--- a/tests/test_selfhosting_new_then_backup_restore.cc
+++ b/tests/test_selfhosting_new_then_backup_restore.cc
@@ -62,11 +62,13 @@ static bool test(Glom::Document::HostingMode hosting_mode)
//Create a new document from the backup:
{
- const Glib::ustring backup_file_contents =
+ std::string backup_data_file_path;
+ const Glib::ustring backup_glom_file_contents =
Glom::Document::extract_backup_file(
backup_uri_tarball,
+ backup_data_file_path,
sigc::ptr_fun(&on_backup_progress));
- if(backup_file_contents.empty())
+ if(backup_glom_file_contents.empty())
{
std::cerr << G_STRFUNC << ": Extraction from the backup file failed." << std::endl;
return false;
@@ -76,7 +78,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
//std::cout << "debug: recreated_uri=" << recreated_uri << std::endl;
Glom::Document document;
const bool recreated =
- test_create_and_selfhost_from_data(backup_file_contents, document, hosting_mode);
+ test_create_and_selfhost_from_data(backup_glom_file_contents, document, hosting_mode);
if(!recreated)
{
std::cerr << G_STRFUNC << ": Recreation from the backup failed." << std::endl;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]