gnucash master: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Thu Jun 4 17:11:02 EDT 2020
Updated via https://github.com/Gnucash/gnucash/commit/b8d514e1 (commit)
via https://github.com/Gnucash/gnucash/commit/6a1cb5ee (commit)
via https://github.com/Gnucash/gnucash/commit/c73a1bd4 (commit)
via https://github.com/Gnucash/gnucash/commit/a320035f (commit)
via https://github.com/Gnucash/gnucash/commit/65e2639d (commit)
from https://github.com/Gnucash/gnucash/commit/0281ef2f (commit)
commit b8d514e157fb7bbd1e175b19eb13a3bca0921788
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Jun 4 14:07:20 2020 -0700
Don't try to unlock the GncDbiSqlConnection when it was connected read-only.
If it's locked it's not *our* lock.
diff --git a/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp b/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp
index 8414a904e..16e2c63c1 100644
--- a/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp
+++ b/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp
@@ -89,9 +89,11 @@ GncDbiSqlConnection::GncDbiSqlConnection (DbType type, QofBackend* qbe,
make_dbi_provider<DbType::DBI_MYSQL>() :
make_dbi_provider<DbType::DBI_PGSQL>()},
m_conn_ok{true}, m_last_error{ERR_BACKEND_NO_ERR}, m_error_repeat{0},
- m_retry{false}, m_sql_savepoint{0}
+ m_retry{false}, m_sql_savepoint{0}, m_readonly{false}
{
- if (mode != SESSION_READ_ONLY && !lock_database(mode == SESSION_BREAK_LOCK))
+ if (mode == SESSION_READ_ONLY)
+ m_readonly = true;
+ else if (!lock_database(mode == SESSION_BREAK_LOCK))
throw std::runtime_error("Failed to lock database!");
if (!check_and_rollback_failed_save())
{
@@ -174,6 +176,7 @@ void
GncDbiSqlConnection::unlock_database ()
{
if (m_conn == nullptr) return;
+ if (m_readonly) return;
g_return_if_fail (dbi_conn_error (m_conn, nullptr) == 0);
auto tables = m_provider->get_table_list (m_conn, lock_table);
diff --git a/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp b/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp
index 5ac6d9c62..7865bd216 100644
--- a/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp
+++ b/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp
@@ -108,6 +108,7 @@ private:
*/
bool m_retry;
unsigned int m_sql_savepoint;
+ bool m_readonly;
bool lock_database(bool break_lock);
void unlock_database();
bool rename_table(const std::string& old_name, const std::string& new_name);
diff --git a/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp b/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
index 3e5ed83ac..b23e69a33 100644
--- a/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
+++ b/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
@@ -541,7 +541,7 @@ test_dbi_version_control (Fixture* fixture, gconstpointer pData)
qof_session_end (sess);
qof_session_destroy (sess);
sess = qof_session_new (qof_book_new());
- qof_session_begin (sess, url, SESSION_NORMAL_OPEN);
+ qof_session_begin (sess, url, SESSION_READ_ONLY);
qof_session_load (sess, NULL);
err = qof_session_pop_error (sess);
g_assert_cmpint (err, == , ERR_SQL_DB_TOO_OLD);
@@ -554,7 +554,7 @@ test_dbi_version_control (Fixture* fixture, gconstpointer pData)
qof_session_end (sess);
qof_session_destroy (sess);
sess = qof_session_new (qof_book_new());
- qof_session_begin (sess, url, SESSION_NORMAL_OPEN);
+ qof_session_begin (sess, url, SESSION_READ_ONLY);
qof_session_load (sess, NULL);
qof_session_ensure_all_data_loaded (sess);
err = qof_session_pop_error (sess);
commit 6a1cb5eecd794d65ab0d15161b1628750b29acb6
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Jun 4 13:05:55 2020 -0700
Replace the three bool parameters to qof_session_begin to an enum.
For clarity. In so doing found the backend behavior a bit inconsistent
so it's modified to do what the enum values indicate.
In the course of changing the various calls I found some implementation
errors in the back end and corrected them.
diff --git a/bindings/python/sqlite3test.c b/bindings/python/sqlite3test.c
index a1e626952..b8c41889f 100644
--- a/bindings/python/sqlite3test.c
+++ b/bindings/python/sqlite3test.c
@@ -32,7 +32,7 @@ int main()
gnc_engine_init(0, no_args);
s = qof_session_new(NULL);
- qof_session_begin(s, testurl, 0, 1, 0);
+ qof_session_begin(s, testurl, SESSION_NEW_STORE);
qof_session_load(s, NULL);
qof_session_save(s, NULL);
qof_session_end(s);
diff --git a/gnucash/gnome-utils/assistant-xml-encoding.c b/gnucash/gnome-utils/assistant-xml-encoding.c
index d70222670..86b62fc25 100644
--- a/gnucash/gnome-utils/assistant-xml-encoding.c
+++ b/gnucash/gnome-utils/assistant-xml-encoding.c
@@ -1082,7 +1082,7 @@ gxi_parse_file (GncXmlImportData *data)
gxi_session_destroy (data);
session = qof_session_new (NULL);
data->session = session;
- qof_session_begin (session, data->filename, TRUE, FALSE, FALSE);
+ qof_session_begin (session, data->filename, SESSION_READ_ONLY);
io_err = qof_session_get_error (session);
if (io_err != ERR_BACKEND_NO_ERR)
{
diff --git a/gnucash/gnome-utils/gnc-file.c b/gnucash/gnome-utils/gnc-file.c
index 33ea97f77..e601f9b89 100644
--- a/gnucash/gnome-utils/gnc-file.c
+++ b/gnucash/gnome-utils/gnc-file.c
@@ -790,7 +790,8 @@ RESTART:
new_session = qof_session_new (qof_book_new());
// Begin the new session. If we are in read-only mode, ignore the locks.
- qof_session_begin (new_session, newfile, is_readonly, FALSE, FALSE);
+ qof_session_begin (new_session, newfile,
+ is_readonly ? SESSION_READ_ONLY : SESSION_NORMAL_OPEN);
io_err = qof_session_get_error (new_session);
if (ERR_BACKEND_BAD_URL == io_err)
@@ -872,11 +873,11 @@ RESTART:
case RESPONSE_READONLY:
is_readonly = TRUE;
/* user told us to open readonly. We do ignore locks (just as before), but now also force the opening. */
- qof_session_begin (new_session, newfile, is_readonly, FALSE, TRUE);
+ qof_session_begin (new_session, newfile, SESSION_READ_ONLY);
break;
case RESPONSE_OPEN:
/* user told us to ignore locks. So ignore them. */
- qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_BREAK_LOCK);
break;
default:
/* Can't use the given file, so just create a new
@@ -895,7 +896,7 @@ RESTART:
/* user told us to create a new database. Do it. We
* shouldn't have to worry about locking or clobbering,
* it's supposed to be new. */
- qof_session_begin (new_session, newfile, FALSE, TRUE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_NEW_STORE);
}
}
@@ -1286,7 +1287,7 @@ gnc_file_do_export(GtkWindow *parent, const char * filename)
/* -- this session code is NOT identical in FileOpen and FileSaveAs -- */
new_session = qof_session_new (NULL);
- qof_session_begin (new_session, newfile, FALSE, TRUE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_NEW_STORE);
io_err = qof_session_get_error (new_session);
/* If the file exists and would be clobbered, ask the user */
@@ -1305,7 +1306,7 @@ gnc_file_do_export(GtkWindow *parent, const char * filename)
{
return;
}
- qof_session_begin (new_session, newfile, FALSE, TRUE, TRUE);
+ qof_session_begin (new_session, newfile, SESSION_NEW_OVERWRITE);
}
/* if file appears to be locked, ask the user ... */
if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
@@ -1313,7 +1314,7 @@ gnc_file_do_export(GtkWindow *parent, const char * filename)
if (!show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_EXPORT))
{
/* user told us to ignore locks. So ignore them. */
- qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_BREAK_LOCK);
}
}
@@ -1532,7 +1533,7 @@ gnc_file_do_save_as (GtkWindow *parent, const char* filename)
save_in_progress++;
new_session = qof_session_new (NULL);
- qof_session_begin (new_session, newfile, FALSE, TRUE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_NEW_STORE);
io_err = qof_session_get_error (new_session);
@@ -1558,15 +1559,15 @@ gnc_file_do_save_as (GtkWindow *parent, const char* filename)
save_in_progress--;
return;
}
- qof_session_begin (new_session, newfile, FALSE, TRUE, TRUE);
+ qof_session_begin (new_session, newfile, SESSION_NEW_OVERWRITE);
}
/* if file appears to be locked, ask the user ... */
else if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
{
if (!show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_SAVE))
{
- /* user told us to ignore locks. So ignore them. */
- qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
+ // User wants to replace the file.
+ qof_session_begin (new_session, newfile, SESSION_BREAK_LOCK);
}
}
@@ -1578,7 +1579,7 @@ gnc_file_do_save_as (GtkWindow *parent, const char* filename)
if (!show_session_error (parent, io_err, newfile, GNC_FILE_DIALOG_SAVE))
{
/* user told us to create a new database. Do it. */
- qof_session_begin (new_session, newfile, FALSE, TRUE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_NEW_STORE);
}
}
diff --git a/gnucash/gnucash-commands.cpp b/gnucash/gnucash-commands.cpp
index 6ac7c3eeb..d6aa71b57 100644
--- a/gnucash/gnucash-commands.cpp
+++ b/gnucash/gnucash-commands.cpp
@@ -95,7 +95,7 @@ scm_add_quotes(void *data, [[maybe_unused]] int argc, [[maybe_unused]] char **ar
if (!session)
scm_cleanup_and_exit_with_failure (session);
- qof_session_begin(session, add_quotes_file->c_str(), FALSE, FALSE, FALSE);
+ qof_session_begin(session, add_quotes_file->c_str(), SESSION_NORMAL_OPEN);
if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR)
scm_cleanup_and_exit_with_failure (session);
@@ -175,7 +175,7 @@ scm_run_report (void *data,
if (!session)
scm_cleanup_and_exit_with_failure (session);
- qof_session_begin (session, datafile, FALSE, FALSE, FALSE);
+ qof_session_begin (session, datafile, SESSION_NORMAL_OPEN);
if (qof_session_get_error (session) != ERR_BACKEND_NO_ERR)
scm_cleanup_and_exit_with_failure (session);
diff --git a/gnucash/import-export/aqb/test/test-kvp.c b/gnucash/import-export/aqb/test/test-kvp.c
index 62458e08b..dce9fb614 100644
--- a/gnucash/import-export/aqb/test/test-kvp.c
+++ b/gnucash/import-export/aqb/test/test-kvp.c
@@ -68,7 +68,7 @@ test_qofsession_aqb_kvp( void )
QofSession *new_session = qof_session_new (book);
char *newfile = g_strdup_printf("file://%s", file1);
- qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_READ_ONLY);
io_err = qof_session_get_error (new_session);
//printf("io_err1 = %d\n", io_err);
g_assert(io_err != ERR_BACKEND_NO_HANDLER); // Do not have no handler
@@ -97,7 +97,7 @@ test_qofsession_aqb_kvp( void )
QofSession *new_session = qof_session_new (book);
char *newfile = g_strdup_printf("file://%s", file2);
- qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
+ qof_session_begin (new_session, newfile, SESSION_READ_ONLY);
io_err = qof_session_get_error (new_session);
//printf("io_err1 = %d\n", io_err);
g_assert(io_err != ERR_BACKEND_NO_HANDLER); // Do not have no handler
diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.cpp b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
index d84bf39e2..25699e5ca 100644
--- a/libgnucash/backend/dbi/gnc-backend-dbi.cpp
+++ b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
@@ -377,8 +377,7 @@ error_handler<DbType::DBI_SQLITE> (dbi_conn conn, void* user_data)
template <> void
GncDbiBackend<DbType::DBI_SQLITE>::session_begin(QofSession* session,
const char* new_uri,
- bool ignore_lock,
- bool create, bool force)
+ SessionOpenMode mode)
{
gboolean file_exists;
PairVec options;
@@ -395,6 +394,7 @@ GncDbiBackend<DbType::DBI_SQLITE>::session_begin(QofSession* session,
GFileTest ftest = static_cast<decltype (ftest)> (
G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS) ;
file_exists = g_file_test (filepath.c_str(), ftest);
+ bool create{mode == SESSION_NEW_STORE || mode == SESSION_NEW_OVERWRITE};
if (!create && !file_exists)
{
set_error (ERR_FILEIO_FILE_NOT_FOUND);
@@ -407,12 +407,12 @@ GncDbiBackend<DbType::DBI_SQLITE>::session_begin(QofSession* session,
if (create && file_exists)
{
- if (force)
+ if (mode == SESSION_NEW_OVERWRITE)
g_unlink (filepath.c_str());
else
{
set_error (ERR_BACKEND_STORE_EXISTS);
- auto msg = "Might clobber, no force";
+ auto msg = "Might clobber, mode not SESSION_NEW_OVERWRITE";
PWARN ("%s", msg);
LEAVE("Error");
return;
@@ -466,7 +466,7 @@ GncDbiBackend<DbType::DBI_SQLITE>::session_begin(QofSession* session,
try
{
connect(new GncDbiSqlConnection(DbType::DBI_SQLITE,
- this, conn, ignore_lock));
+ this, conn, mode));
}
catch (std::runtime_error& err)
{
@@ -677,6 +677,7 @@ GncDbiBackend<Type>::session_begin (QofSession* session, const char* new_uri,
}
connect(nullptr);
+ bool create{mode == SESSION_NEW_STORE || mode == SESSION_NEW_OVERWRITE};
auto conn = conn_setup(options, uri);
if (conn == nullptr)
{
@@ -696,26 +697,15 @@ GncDbiBackend<Type>::session_begin (QofSession* session, const char* new_uri,
LEAVE("Error");
return;
}
- if (create && save_may_clobber_data<Type>(conn,
- uri.quote_dbname(Type)))
+ bool create = (mode == SESSION_NEW_STORE ||
+ mode == SESSION_NEW_OVERWRITE);
+ if (create && save_may_clobber_data<Type>(conn, uri.quote_dbname(Type)))
{
- if (force)
+ if (mode == SESSION_NEW_OVERWRITE)
{
- // Drop DB
- const char *root_db;
- if (Type == DbType::DBI_PGSQL)
- {
- root_db = "template1";
- }
- else if (Type == DbType::DBI_MYSQL)
- {
- root_db = "mysql";
- }
- else
- {
if (!drop_database<Type>(conn, uri))
return;
- }
+ }
else
{
set_error (ERR_BACKEND_STORE_EXISTS);
@@ -782,7 +772,7 @@ GncDbiBackend<Type>::session_begin (QofSession* session, const char* new_uri,
connect(nullptr);
try
{
- connect(new GncDbiSqlConnection(Type, this, conn, ignore_lock));
+ connect(new GncDbiSqlConnection(Type, this, conn, mode));
}
catch (std::runtime_error& err)
{
diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.hpp b/libgnucash/backend/dbi/gnc-backend-dbi.hpp
index cdcfdf93b..f02d59007 100644
--- a/libgnucash/backend/dbi/gnc-backend-dbi.hpp
+++ b/libgnucash/backend/dbi/gnc-backend-dbi.hpp
@@ -92,7 +92,7 @@ public:
GncDbiBackend(GncSqlConnection *conn, QofBook* book) :
GncSqlBackend(conn, book), m_exists{false} {}
~GncDbiBackend();
- void session_begin(QofSession*, const char*, bool, bool, bool) override;
+ void session_begin(QofSession*, const char*, SessionOpenMode) override;
void session_end() override;
void load(QofBook*, QofBackendLoadType) override;
void safe_sync(QofBook*) override;
diff --git a/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp b/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp
index 2577fe6ad..8414a904e 100644
--- a/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp
+++ b/libgnucash/backend/dbi/gnc-dbisqlconnection.cpp
@@ -81,7 +81,7 @@ GncDbiSqlStatement::add_where_cond(QofIdTypeConst type_name,
}
GncDbiSqlConnection::GncDbiSqlConnection (DbType type, QofBackend* qbe,
- dbi_conn conn, bool ignore_lock) :
+ dbi_conn conn, SessionOpenMode mode) :
m_qbe{qbe}, m_conn{conn},
m_provider{type == DbType::DBI_SQLITE ?
make_dbi_provider<DbType::DBI_SQLITE>() :
@@ -91,7 +91,7 @@ GncDbiSqlConnection::GncDbiSqlConnection (DbType type, QofBackend* qbe,
m_conn_ok{true}, m_last_error{ERR_BACKEND_NO_ERR}, m_error_repeat{0},
m_retry{false}, m_sql_savepoint{0}
{
- if (!lock_database(ignore_lock))
+ if (mode != SESSION_READ_ONLY && !lock_database(mode == SESSION_BREAK_LOCK))
throw std::runtime_error("Failed to lock database!");
if (!check_and_rollback_failed_save())
{
@@ -101,7 +101,7 @@ GncDbiSqlConnection::GncDbiSqlConnection (DbType type, QofBackend* qbe,
}
bool
-GncDbiSqlConnection::lock_database (bool ignore_lock)
+GncDbiSqlConnection::lock_database (bool break_lock)
{
const char *errstr;
/* Protect everything with a single transaction to prevent races */
@@ -127,7 +127,7 @@ GncDbiSqlConnection::lock_database (bool ignore_lock)
}
}
- /* Check for an existing entry; delete it if ignore_lock is true, otherwise fail */
+ /* Check for an existing entry; delete it if break_lock is true, otherwise fail */
char hostname[ GNC_HOST_NAME_MAX + 1 ];
auto result = dbi_conn_queryf (m_conn, "SELECT * FROM %s",
lock_table.c_str());
@@ -135,7 +135,7 @@ GncDbiSqlConnection::lock_database (bool ignore_lock)
{
dbi_result_free (result);
result = nullptr;
- if (!ignore_lock)
+ if (!break_lock)
{
qof_backend_set_error (m_qbe, ERR_BACKEND_LOCKED);
/* FIXME: After enhancing the qof_backend_error mechanism, report in the dialog what is the hostname of the machine holding the lock. */
diff --git a/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp b/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp
index bb71a9636..5ac6d9c62 100644
--- a/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp
+++ b/libgnucash/backend/dbi/gnc-dbisqlconnection.hpp
@@ -42,7 +42,7 @@ class GncDbiSqlConnection : public GncSqlConnection
{
public:
GncDbiSqlConnection (DbType type, QofBackend* qbe, dbi_conn conn,
- bool ignore_lock);
+ SessionOpenMode mode);
~GncDbiSqlConnection() override;
GncSqlResultPtr execute_select_statement (const GncSqlStatementPtr&)
noexcept override;
@@ -108,7 +108,7 @@ private:
*/
bool m_retry;
unsigned int m_sql_savepoint;
- bool lock_database(bool ignore_lock);
+ bool lock_database(bool break_lock);
void unlock_database();
bool rename_table(const std::string& old_name, const std::string& new_name);
bool drop_table(const std::string& table);
diff --git a/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp b/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
index 994c5e8c4..3e5ed83ac 100644
--- a/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
+++ b/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
@@ -97,8 +97,8 @@ setup (Fixture* fixture, gconstpointer pData)
* prevents creating the lock file. Force the session to get
* around that.
*/
- qof_session_begin (fixture->session, DBI_TEST_XML_FILENAME, TRUE,
- FALSE, TRUE);
+ qof_session_begin (fixture->session, DBI_TEST_XML_FILENAME,
+ SESSION_BREAK_LOCK);
g_assert_cmpint (qof_session_get_error (fixture->session), == ,
ERR_BACKEND_NO_ERR);
qof_session_load (fixture->session, NULL);
@@ -394,7 +394,7 @@ test_dbi_store_and_reload (Fixture* fixture, gconstpointer pData)
// Save the session data
auto book2{qof_book_new()};
auto session_2 = qof_session_new (book2);
- qof_session_begin (session_2, url, FALSE, TRUE, TRUE);
+ qof_session_begin (session_2, url, SESSION_NEW_OVERWRITE);
g_assert (session_2 != NULL);
g_assert_cmpint (qof_session_get_error (session_2), == , ERR_BACKEND_NO_ERR);
qof_session_swap_data (fixture->session, session_2);
@@ -407,7 +407,7 @@ test_dbi_store_and_reload (Fixture* fixture, gconstpointer pData)
auto book3{qof_book_new()};
auto session_3 = qof_session_new (book3);
g_assert (session_3 != NULL);
- qof_session_begin (session_3, url, TRUE, FALSE, FALSE);
+ qof_session_begin (session_3, url, SESSION_READ_ONLY);
g_assert (session_3 != NULL);
g_assert_cmpint (qof_session_get_error (session_3), == , ERR_BACKEND_NO_ERR);
qof_session_load (session_3, NULL);
@@ -447,7 +447,7 @@ test_dbi_safe_save (Fixture* fixture, gconstpointer pData)
// Load the session data
auto book1{qof_book_new()};
auto session_1 = qof_session_new (book1);
- qof_session_begin (session_1, url, FALSE, TRUE, TRUE);
+ qof_session_begin (session_1, url, SESSION_NEW_OVERWRITE);
if (session_1 &&
qof_session_get_error (session_1) != ERR_BACKEND_NO_ERR)
{
@@ -473,7 +473,7 @@ test_dbi_safe_save (Fixture* fixture, gconstpointer pData)
/* Destroy the session and reload it */
session_2 = qof_session_new (qof_book_new());
- qof_session_begin (session_2, url, TRUE, FALSE, FALSE);
+ qof_session_begin (session_2, url, SESSION_READ_ONLY);
if (session_2 &&
qof_session_get_error (session_2) != ERR_BACKEND_NO_ERR)
{
@@ -521,7 +521,7 @@ test_dbi_version_control (Fixture* fixture, gconstpointer pData)
if (fixture->filename)
url = fixture->filename;
auto sess = qof_session_new (nullptr);
- qof_session_begin (sess, url, FALSE, TRUE, TRUE);
+ qof_session_begin (sess, url, SESSION_NEW_OVERWRITE);
if (sess && qof_session_get_error (sess) != ERR_BACKEND_NO_ERR)
{
g_warning ("Session Error: %d, %s", qof_session_get_error (sess),
@@ -541,7 +541,7 @@ test_dbi_version_control (Fixture* fixture, gconstpointer pData)
qof_session_end (sess);
qof_session_destroy (sess);
sess = qof_session_new (qof_book_new());
- qof_session_begin (sess, url, TRUE, FALSE, FALSE);
+ qof_session_begin (sess, url, SESSION_NORMAL_OPEN);
qof_session_load (sess, NULL);
err = qof_session_pop_error (sess);
g_assert_cmpint (err, == , ERR_SQL_DB_TOO_OLD);
@@ -554,7 +554,7 @@ test_dbi_version_control (Fixture* fixture, gconstpointer pData)
qof_session_end (sess);
qof_session_destroy (sess);
sess = qof_session_new (qof_book_new());
- qof_session_begin (sess, url, TRUE, FALSE, FALSE);
+ qof_session_begin (sess, url, SESSION_NORMAL_OPEN);
qof_session_load (sess, NULL);
qof_session_ensure_all_data_loaded (sess);
err = qof_session_pop_error (sess);
@@ -583,14 +583,14 @@ test_dbi_business_store_and_reload (Fixture* fixture, gconstpointer pData)
url = fixture->filename;
// Save the session data
auto session_2 = qof_session_new (qof_book_new());
- qof_session_begin (session_2, url, FALSE, TRUE, TRUE);
+ qof_session_begin (session_2, url, SESSION_NEW_OVERWRITE);
qof_session_swap_data (fixture->session, session_2);
qof_book_mark_session_dirty (qof_session_get_book (session_2));
qof_session_save (session_2, NULL);
// Reload the session data
auto session_3 = qof_session_new (qof_book_new());
- qof_session_begin (session_3, url, TRUE, FALSE, FALSE);
+ qof_session_begin (session_3, url, SESSION_READ_ONLY);
qof_session_load (session_3, NULL);
// Compare with the original data
diff --git a/libgnucash/backend/sql/test/utest-gnc-backend-sql.cpp b/libgnucash/backend/sql/test/utest-gnc-backend-sql.cpp
index 253bd1c6e..b89cde9a7 100644
--- a/libgnucash/backend/sql/test/utest-gnc-backend-sql.cpp
+++ b/libgnucash/backend/sql/test/utest-gnc-backend-sql.cpp
@@ -40,7 +40,7 @@ class GncMockSqlBackend : public GncSqlBackend
public:
GncMockSqlBackend(GncSqlConnection* conn, QofBook* book) :
GncSqlBackend(conn, book) {}
- void session_begin(QofSession*, const char*, bool, bool, bool) override {}
+ void session_begin(QofSession*, const char*, SessionOpenMode) override {}
void session_end() override {}
void safe_sync(QofBook* book) override { sync(book); }
};
diff --git a/libgnucash/backend/xml/gnc-xml-backend.cpp b/libgnucash/backend/xml/gnc-xml-backend.cpp
index 3984d4d8a..28e9939ec 100644
--- a/libgnucash/backend/xml/gnc-xml-backend.cpp
+++ b/libgnucash/backend/xml/gnc-xml-backend.cpp
@@ -107,7 +107,7 @@ GncXmlBackend::check_path (const char* fullpath, bool create)
void
GncXmlBackend::session_begin(QofSession* session, const char* new_uri,
- bool ignore_lock, bool create, bool force)
+ SessionOpenMode mode)
{
/* Make sure the directory is there */
m_fullpath = gnc_uri_get_path (new_uri);
@@ -118,14 +118,15 @@ GncXmlBackend::session_begin(QofSession* session, const char* new_uri,
set_message("No path specified");
return;
}
- if (create && !force && save_may_clobber_data())
+ if (mode == SESSION_NEW_STORE && save_may_clobber_data())
{
set_error(ERR_BACKEND_STORE_EXISTS);
PWARN ("Might clobber, no force");
return;
}
- if (!check_path(m_fullpath.c_str(), create))
+ if (!check_path(m_fullpath.c_str(),
+ SESSION_NEW_STORE || mode == SESSION_NEW_OVERWRITE))
return;
m_dirname = g_path_get_dirname (m_fullpath.c_str());
@@ -137,34 +138,19 @@ GncXmlBackend::session_begin(QofSession* session, const char* new_uri,
xaccLogSetBaseName (m_fullpath.c_str());
PINFO ("logpath=%s", m_fullpath.empty() ? "(null)" : m_fullpath.c_str());
- /* And let's see if we can get a lock on it. */
- m_lockfile = m_fullpath + ".LCK";
+ if (mode == SESSION_READ_ONLY)
+ return; // Read-only, don't care about locks.
- if (!ignore_lock && !get_file_lock())
+ /* Set the lock file */
+ m_lockfile = m_fullpath + ".LCK";
+ auto locked = get_file_lock();
+ if (mode == SESSION_BREAK_LOCK && !locked)
{
- // We should not ignore the lock, but couldn't get it. The
- // be_get_file_lock() already set the appropriate backend_error in this
- // case, so we just return here.
- m_lockfile.clear();
-
- if (force)
- {
- QofBackendError berror = get_error();
- if (berror == ERR_BACKEND_LOCKED || berror == ERR_BACKEND_READONLY)
- {
- // Even though we couldn't get the lock, we were told to force
- // the opening. This is ok because the FORCE argument is
- // changed only if the caller wants a read-only book.
- }
- else
- {
- // Unknown error. Push it again on the error stack.
- set_error(berror);
- return;
- }
- }
+ // Don't pass on locked or readonly errors.
+ QofBackendError berror = get_error();
+ if (!(berror == ERR_BACKEND_LOCKED || berror == ERR_BACKEND_READONLY))
+ set_error(berror);
}
- m_book = nullptr;
}
void
diff --git a/libgnucash/backend/xml/gnc-xml-backend.hpp b/libgnucash/backend/xml/gnc-xml-backend.hpp
index aeb04a3e0..362038452 100644
--- a/libgnucash/backend/xml/gnc-xml-backend.hpp
+++ b/libgnucash/backend/xml/gnc-xml-backend.hpp
@@ -36,7 +36,7 @@ public:
GncXmlBackend operator=(const GncXmlBackend&&) = delete;
~GncXmlBackend() = default;
void session_begin(QofSession* session, const char* new_uri,
- bool ignore_lock, bool create, bool force) override;
+ SessionOpenMode mode) override;
void session_end() override;
void load(QofBook* book, QofBackendLoadType loadType) override;
/* The XML backend isn't able to do anything with individual instances. */
diff --git a/libgnucash/backend/xml/test/test-load-xml2.cpp b/libgnucash/backend/xml/test/test-load-xml2.cpp
index 2daa106c2..f1e3cfdff 100644
--- a/libgnucash/backend/xml/test/test-load-xml2.cpp
+++ b/libgnucash/backend/xml/test/test-load-xml2.cpp
@@ -97,7 +97,8 @@ test_load_file (const char* filename)
ignore_lock = (g_strcmp0 (g_getenv ("SRCDIR"), ".") != 0);
/* gnc_prefs_set_file_save_compressed(FALSE); */
- qof_session_begin (session, filename, ignore_lock, FALSE, TRUE);
+ qof_session_begin (session, filename,
+ ignore_lock ? SESSION_READ_ONLY : SESSION_NORMAL_OPEN);
qof_session_load (session, NULL);
auto book = qof_session_get_book (session);
diff --git a/libgnucash/backend/xml/test/test-save-in-lang.cpp b/libgnucash/backend/xml/test/test-save-in-lang.cpp
index e6a3919b6..8501a7c88 100644
--- a/libgnucash/backend/xml/test/test-save-in-lang.cpp
+++ b/libgnucash/backend/xml/test/test-save-in-lang.cpp
@@ -100,7 +100,7 @@ test_file (const char* filename)
auto session = qof_session_new (nullptr);
- qof_session_begin (session, filename, TRUE, FALSE, FALSE);
+ qof_session_begin (session, filename, SESSION_READ_ONLY);
err = qof_session_pop_error (session);
if (err)
{
@@ -121,7 +121,7 @@ test_file (const char* filename)
auto new_session = qof_session_new (nullptr);
- qof_session_begin (new_session, new_file, FALSE, FALSE, FALSE);
+ qof_session_begin (new_session, new_file, SESSION_NORMAL_OPEN);
err = qof_session_pop_error (new_session);
if (err)
{
diff --git a/libgnucash/engine/qof-backend.hpp b/libgnucash/engine/qof-backend.hpp
index ee424937c..f2e898508 100644
--- a/libgnucash/engine/qof-backend.hpp
+++ b/libgnucash/engine/qof-backend.hpp
@@ -186,25 +186,10 @@ public:
* Open the file or connect to the server.
* @param session The QofSession that will control the backend.
* @param new_uri The location of the data store that the backend will use.
- * @param ignore_lock indicates whether the single-user lock on the backend
- * should be cleared. The typical GUI sequence leading to this is:
- * (1) GUI attempts to open the backend by calling this routine with
- * ignore_lock false.
- * (2) If backend error'ed BACKEND_LOCK, then GUI asks user what to do.
- * (3) if user answers 'break & enter' then this routine is called again with
- * ignore_lock true.
- * @param create indicates whether this routine should create a new
- * 'database', if it doesn't already exist. For example, for a file-backend,
- * this would create the file, if it didn't already exist. For an SQL
- * backend, this would create the database (the schema) if it didn't already
- * exist. This flag is used to implement the 'SaveAs' GUI, where the user
- * requests to save data to a new backend.
- *
- * @param force works with create to force creating a new database even if
- * one already exists at the same URI.
+ * @param mode The session open mode. See qof_session_begin().
*/
virtual void session_begin(QofSession *session, const char* new_uri,
- bool ignore_lock, bool create, bool force) = 0;
+ SessionOpenMode mode) = 0;
virtual void session_end() = 0;
/**
* Load the minimal set of application data needed for the application to be
diff --git a/libgnucash/engine/qofsession.cpp b/libgnucash/engine/qofsession.cpp
index 3371d8465..7e3ad9420 100644
--- a/libgnucash/engine/qofsession.cpp
+++ b/libgnucash/engine/qofsession.cpp
@@ -20,7 +20,7 @@
\********************************************************************/
/**
- * @file qofsession.c
+ * @file qofsession.cpp
* @brief Encapsulate a connection to a storage backend.
*
* HISTORY:
@@ -250,11 +250,11 @@ QofSessionImpl::load (QofPercentageFunc percentage_func) noexcept
}
void
-QofSessionImpl::begin (const char* new_uri, bool ignore_lock,
- bool create, bool force) noexcept
+QofSessionImpl::begin (const char* new_uri, SessionOpenMode mode) noexcept
{
- ENTER (" sess=%p ignore_lock=%d, book-id=%s",
- this, ignore_lock, new_uri);
+
+
+ ENTER (" sess=%p mode=%d, URI=%s", this, mode, new_uri);
clear_error ();
/* Check to see if this session is already open */
if (m_uri.size ())
@@ -294,7 +294,7 @@ QofSessionImpl::begin (const char* new_uri, bool ignore_lock,
destroy_backend ();
/* Store the session URL */
m_uri = new_uri;
- m_creating = create;
+ m_creating = mode == SESSION_NEW_STORE || mode == SESSION_NEW_OVERWRITE;
if (filename)
load_backend ("file");
else /* access method found, load appropriate backend */
@@ -314,8 +314,7 @@ QofSessionImpl::begin (const char* new_uri, bool ignore_lock,
}
/* If there's a begin method, call that. */
- m_backend->session_begin(this, m_uri.c_str(),
- ignore_lock, create, force);
+ m_backend->session_begin(this, m_uri.c_str(), mode);
PINFO ("Done running session_begin on backend");
QofBackendError const err {m_backend->get_error()};
auto msg (m_backend->get_message());
@@ -610,11 +609,10 @@ qof_session_get_backend (const QofSession *session)
}
void
-qof_session_begin (QofSession *session, const char * new_uri,
- gboolean ignore_lock, gboolean create, gboolean force)
+qof_session_begin (QofSession *session, const char * uri, SessionOpenMode mode)
{
if (!session) return;
- session->begin((new_uri ? new_uri : ""), ignore_lock, create, force);
+ session->begin(uri, mode);
}
void
diff --git a/libgnucash/engine/qofsession.h b/libgnucash/engine/qofsession.h
index 9611cc2a2..5836d879c 100644
--- a/libgnucash/engine/qofsession.h
+++ b/libgnucash/engine/qofsession.h
@@ -109,6 +109,27 @@ extern "C"
#endif
#define QOF_MOD_SESSION "qof.session"
+/**
+ * Mode for opening sessions.
+ */
+/* This replaces three booleans that were passed in order: ignore_lock, create,
+ * and force. It's structured so that one can use it as a bit field with the
+ * values in the same order, i.e. ignore_lock = 1 << 2, create = 1 << 1, and
+ * force = 1.
+ */
+typedef enum
+{
+ SESSION_NORMAL_OPEN = 0, // All False
+ /** Open will fail if the URI doesn't exist or is locked. */
+ SESSION_NEW_STORE = 2, // False, True, False (create)
+ /** Create a new store at the URI. It will fail if the store already exists and is found to contain data that would be overwritten. */
+ SESSION_NEW_OVERWRITE = 3, // False, True, True (create | force)
+ /** Create a new store at the URI even if a store already exists there. */
+ SESSION_READ_ONLY = 4, // True, False, False (ignore_lock)
+ /** Open the session read-only, ignoring any existing lock and not creating one if the URI isn't locked. */
+ SESSION_BREAK_LOCK = 5 // True, False, True (ignore_lock | force)
+ /** Open the session, taking over any existing lock. */
+} SessionOpenMode;
/* PROTOTYPES ******************************************************/
@@ -122,39 +143,41 @@ void qof_session_destroy (QofSession *session);
* for 'Save As' type functionality. */
void qof_session_swap_data (QofSession *session_1, QofSession *session_2);
-/** The qof_session_begin () method begins a new session.
- * It takes as an argument the book id. The book id must be a string
- * in the form of a URI/URL. The access method specified depends
- * on the loaded backends. Paths may be relative or absolute.
- * If the path is relative; that is, if the argument is "file://somefile.xml"
- * then the current working directory is assumed. Customized backends can
- * choose to search other, application-specific, directories as well.
+/** Begins a new session.
+ *
+ * @param session Newly-allocated with qof_session_new.
*
- * The 'ignore_lock' argument, if set to TRUE, will cause this routine
- * to ignore any global-datastore locks (e.g. file locks) that it finds.
- * If set to FALSE, then file/database-global locks will be tested and
- * obeyed.
+ * @param uri must be a string in the form of a URI/URL. The access method
+ * specified depends on the loaded backends. Paths may be relative or
+ * absolute. If the path is relative, that is if the argument is
+ * "file://somefile.xml", then the current working directory is
+ * assumed. Customized backends can choose to search other
+ * application-specific directories or URI schemes as well.
*
- * If the datastore exists, can be reached (e.g over the net),
- * connected to, opened and read, and a lock can be obtained then a
- * lock will be obtained. Note that while multi-user datastores
- * (e.g. the SQL backend) typically will have record-level locking
- * and therefor should not need to get a global lock, qof works by
- * having a local copy of the whole database and can't be trusted
- * to handle multiple users writing data, so we lock the database
- * anyway.
+ * @param mode The SessionMode.
*
- * If qof_session_begin is called with create == TRUE, then it will
- * check for the existence of the file or database and return after
- * posting a QOF_BACKEND_STORE_EXISTS error if it exists, unless
- * force is also set to true.
+ * ==== SessionMode ====
+ * `SESSION_NORMAL`: Find an existing file or database at the provided uri and
+ * open it if it is unlocked. If it is locked post a QOF_BACKEND_LOCKED error.
+ * `SESSION_NEW_STORE`: Check for an existing file or database at the provided
+ * uri and if none is found, create it. If the file or database exists post a
+ * QOF_BACKED_STORE_EXISTS and return.
+ * `SESSION_READ_ONLY`: Find an existing file or database and open it without
+ * disturbing the lock if it exists or setting one if not. This will also set a
+ * flag on the book that will prevent many elements from being edited and will
+ * prevent the backend from saving any edits.
+ * `SESSION_OVERWRITE`: Create a new file or database at the provided uri,
+ * deleting any existing file or database.
+ * `SESSION_BREAK_LOCK1: Find an existing file or database, lock it, and open
+ * it. If there is already a lock replace it with a new one for this session.
*
- * If an error occurs, it will be pushed onto the session error
- * stack, and that is where it should be examined.
+ * ==== Errors ====
+ * This function signals failure by queuing errors. After it completes use
+ * qof_session_get_error() and test that the value is `ERROR_BACKEND_NONE` to
+ * determine that the session began successfully.
*/
void qof_session_begin (QofSession *session, const char * new_uri,
- gboolean ignore_lock, gboolean create,
- gboolean force);
+ SessionOpenMode mode);
/**
* The qof_session_load() method causes the QofBook to be made ready to
diff --git a/libgnucash/engine/qofsession.hpp b/libgnucash/engine/qofsession.hpp
index df4e02ab8..9029320c3 100644
--- a/libgnucash/engine/qofsession.hpp
+++ b/libgnucash/engine/qofsession.hpp
@@ -41,7 +41,7 @@ struct QofSessionImpl
~QofSessionImpl () noexcept;
/** Begin this session. */
- void begin (const char* new_uri, bool ignore_lock, bool create, bool force) noexcept;
+ void begin (const char* new_uri, SessionOpenMode mode) noexcept;
/** Swap books with another session */
void swap_books (QofSessionImpl &) noexcept;
diff --git a/libgnucash/engine/test/test-qofinstance.cpp b/libgnucash/engine/test/test-qofinstance.cpp
index 6e04b49bc..301c7e289 100644
--- a/libgnucash/engine/test/test-qofinstance.cpp
+++ b/libgnucash/engine/test/test-qofinstance.cpp
@@ -55,8 +55,8 @@ public:
QofInstMockBackend() : m_qof_error{ERR_BACKEND_NO_ERR} {
commit_test.m_be = this;
}
- void session_begin(QofSession* sess, const char* book_name,
- bool ignore_lock, bool create, bool force) override {}
+ void session_begin(QofSession* sess, const char* uri,
+ SessionOpenMode mode) override {}
void session_end() override {}
void load(QofBook*, QofBackendLoadType) override {}
void sync(QofBook* book) override {}
diff --git a/libgnucash/engine/test/test-qofsession-old.cpp b/libgnucash/engine/test/test-qofsession-old.cpp
index f10b64fa9..2282c0df5 100644
--- a/libgnucash/engine/test/test-qofsession-old.cpp
+++ b/libgnucash/engine/test/test-qofsession-old.cpp
@@ -287,7 +287,7 @@ static struct
static void
mock_session_begin (QofBackend *be, QofSession *session, const char *uri,
- gboolean ignore_lock, gboolean create, gboolean force)
+ SessionOpenMode mode)
{
g_assert (be);
g_assert (be == session_begin_struct.be);
@@ -295,9 +295,7 @@ mock_session_begin (QofBackend *be, QofSession *session, const char *uri,
g_assert (session == session_begin_struct.session);
g_assert (uri);
g_assert_cmpstr (uri, == , session_begin_struct.uri);
- g_assert (ignore_lock);
- g_assert (!create);
- g_assert (force);
+ g_assert (mode == SESSION_BREAK_LOCK);
if (session_begin_struct.produce_error)
{
qof_backend_set_error (be, ERR_BACKEND_DATA_CORRUPT);
@@ -336,13 +334,10 @@ QofMockSessBackendProvider::create_backend (void)
static void
test_qof_session_begin (Fixture *fixture, gconstpointer pData)
{
- gboolean ignore_lock, create, force;
QofBackend *be = NULL;
/* setup */
- ignore_lock = TRUE;
- create = FALSE;
- force = TRUE;
+ SessionOpenMode mode{SESSION_BREAK_LOCK};
be = g_new0 (QofBackend, 1);
g_assert (be);
@@ -352,12 +347,12 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
g_test_message ("Test when uri is set backend is not changed");
qof_book_set_backend (qof_session_get_book (fixture->session), be);
p_qof_session_set_uri (fixture->session, "my book");
- qof_session_begin (fixture->session, "my book", ignore_lock, create, force);
+ qof_session_begin (fixture->session, "my book", mode);
g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == be);
g_test_message ("Test when session uri is not set and uri passed is null backend is not changed");
p_qof_session_set_uri (fixture->session, NULL);
- qof_session_begin (fixture->session, NULL, ignore_lock, create, force);
+ qof_session_begin (fixture->session, NULL, mode);
g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == be);
g_test_message ("Test default access_method parsing");
@@ -365,13 +360,13 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
* parse access_method as 'file' and try to find backend
* as there is no backend registered error will be raised
*/
- qof_session_begin (fixture->session, "default_should_be_file", ignore_lock, create, force);
+ qof_session_begin (fixture->session, "default_should_be_file", mode);
g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == NULL);
g_assert (!strlen (qof_session_get_url (fixture->session)));
g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
g_test_message ("Test access_method parsing");
- qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force);
+ qof_session_begin (fixture->session, "postgres://localhost:8080", mode);
g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == NULL);
g_assert (!strlen (qof_session_get_url (fixture->session)));
g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
@@ -386,7 +381,7 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
"postgres"));
qof_backend_register_provider (std::move(prov));
- qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force);
+ qof_session_begin (fixture->session, "postgres://localhost:8080", mode);
g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)));
g_assert (session_begin_struct.be == qof_book_get_backend (qof_session_get_book (fixture->session)));
g_assert (session_begin_struct.backend_new_called == TRUE);
diff --git a/libgnucash/engine/test/test-qofsession.cpp b/libgnucash/engine/test/test-qofsession.cpp
index 0179f830d..72b701df8 100644
--- a/libgnucash/engine/test/test-qofsession.cpp
+++ b/libgnucash/engine/test/test-qofsession.cpp
@@ -44,7 +44,7 @@ public:
QofSessionMockBackend(const QofSessionMockBackend&) = delete;
QofSessionMockBackend(const QofSessionMockBackend&&) = delete;
virtual ~QofSessionMockBackend() = default;
- void session_begin(QofSession*, const char*, bool, bool, bool) {}
+ void session_begin(QofSession*, const char*, SessionOpenMode) {}
void session_end() {}
void load(QofBook*, QofBackendLoadType);
void sync(QofBook*);
@@ -106,9 +106,9 @@ TEST (QofSessionTest, swap_books)
{
qof_backend_register_provider (get_provider ());
QofSession s1(qof_book_new());
- s1.begin ("book1", false, false, false);
+ s1.begin ("book1", SESSION_NORMAL_OPEN);
QofSession s2(qof_book_new());
- s2.begin ("book2", false, false, false);
+ s2.begin ("book2", SESSION_NORMAL_OPEN);
QofBook * b1 {s1.get_book ()};
QofBook * b2 {s2.get_book ()};
ASSERT_NE (b1, b2);
@@ -122,7 +122,7 @@ TEST (QofSessionTest, ensure_all_data_loaded)
{
qof_backend_register_provider (get_provider ());
QofSession s(qof_book_new());
- s.begin ("book1", false, false, false);
+ s.begin ("book1", SESSION_NORMAL_OPEN);
data_loaded = false;
s.ensure_all_data_loaded ();
EXPECT_EQ (data_loaded, true);
@@ -133,7 +133,7 @@ TEST (QofSessionTest, get_error)
{
qof_backend_register_provider (get_provider ());
QofSession s(qof_book_new());
- s.begin ("book1", false, false, false);
+ s.begin ("book1", SESSION_NORMAL_OPEN);
s.ensure_all_data_loaded ();
EXPECT_NE (s.get_error (), ERR_BACKEND_NO_ERR);
//get_error should not clear the error.
@@ -145,7 +145,7 @@ TEST (QofSessionTest, pop_error)
{
qof_backend_register_provider (get_provider ());
QofSession s(qof_book_new());
- s.begin ("book1", false, false, false);
+ s.begin ("book1", SESSION_NORMAL_OPEN);
//We run the test first, and make sure there is an error condition.
s.ensure_all_data_loaded ();
EXPECT_NE (s.pop_error (), ERR_BACKEND_NO_ERR);
@@ -157,7 +157,7 @@ TEST (QofSessionTest, clear_error)
{
qof_backend_register_provider (get_provider ());
QofSession s(qof_book_new());
- s.begin ("book1", false, false, false);
+ s.begin ("book1", SESSION_NORMAL_OPEN);
//We run the test first, and make sure there is an error condition.
s.ensure_all_data_loaded ();
EXPECT_NE (s.get_error (), ERR_BACKEND_NO_ERR);
@@ -176,7 +176,7 @@ TEST (QofSessionTest, load)
*/
qof_backend_register_provider (get_provider ());
QofSession s{qof_book_new()};
- s.begin ("book1", false, false, false);
+ s.begin ("book1", SESSION_NORMAL_OPEN);
char *guidstr1 = guid_to_string(qof_instance_get_guid(s.get_book ()));
s.load (nullptr);
char *guidstr2 = guid_to_string(qof_instance_get_guid(s.get_book ()));
@@ -206,7 +206,7 @@ TEST (QofSessionTest, save)
{
qof_backend_register_provider (get_provider ());
QofSession s(qof_book_new());
- s.begin ("book1", false, false, false);
+ s.begin ("book1", SESSION_NORMAL_OPEN);
load_error = false;
s.load (nullptr);
qof_book_mark_session_dirty (s.get_book ());
@@ -221,7 +221,7 @@ TEST (QofSessionTest, safe_save)
{
qof_backend_register_provider (get_provider ());
QofSession s(qof_book_new());
- s.begin ("book1", false, false, false);
+ s.begin ("book1", SESSION_NORMAL_OPEN);
s.safe_save (nullptr);
EXPECT_EQ (safe_sync_called, true);
qof_backend_unregister_all_providers ();
@@ -233,11 +233,11 @@ TEST (QofSessionTest, export_session)
qof_backend_register_provider (get_provider ());
auto b1 = qof_book_new();
QofSession s1(b1);
- s1.begin ("book1", false, false, false);
+ s1.begin ("book1", SESSION_NORMAL_OPEN);
qof_book_set_backend(b1, s1.get_backend());
auto b2 = qof_book_new();
QofSession s2(b2);
- s2.begin ("book2", false, false, false);
+ s2.begin ("book2", SESSION_NORMAL_OPEN);
qof_book_set_backend(b2, s2.get_backend());
s2.export_session (s1, nullptr);
EXPECT_EQ (exported_book, b1);
diff --git a/libgnucash/engine/test/utest-Transaction.cpp b/libgnucash/engine/test/utest-Transaction.cpp
index 21b512282..ac6effbe6 100644
--- a/libgnucash/engine/test/utest-Transaction.cpp
+++ b/libgnucash/engine/test/utest-Transaction.cpp
@@ -86,7 +86,7 @@ class TransMockBackend : public QofBackend
public:
TransMockBackend() : QofBackend(), m_last_call{"Constructor"},
m_result_err{ERR_BACKEND_NO_ERR} {}
- void session_begin(QofSession*, const char*, bool, bool, bool) override {
+ void session_begin(QofSession*, const char*, SessionOpenMode) override {
m_last_call = "session_begin";
}
void session_end() override {
commit c73a1bd4751687a18fb5a35fc63f9943a66cf580
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Jun 4 11:00:52 2020 -0700
Extract function template drop_database.
diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.cpp b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
index c17a5e039..d84bf39e2 100644
--- a/libgnucash/backend/dbi/gnc-backend-dbi.cpp
+++ b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
@@ -609,10 +609,46 @@ adjust_sql_options (dbi_conn connection)
}
}
+template <DbType Type> bool
+drop_database(dbi_conn conn, const UriStrings& uri)
+{
+ const char *root_db;
+ if (Type == DbType::DBI_PGSQL)
+ {
+ root_db = "template1";
+ }
+ else if (Type == DbType::DBI_MYSQL)
+ {
+ root_db = "mysql";
+ }
+ else
+ {
+ PERR ("Unknown database type, can't proceed.");
+ LEAVE("Error");
+ return false;
+ }
+ if (dbi_conn_select_db (conn, root_db) == -1)
+ {
+ PERR ("Failed to switch out of %s, drop will fail.",
+ uri.quote_dbname(Type).c_str());
+ LEAVE ("Error");
+ return false;
+ }
+ if (!dbi_conn_queryf (conn, "DROP DATABASE %s",
+ uri.quote_dbname(Type).c_str()))
+ {
+ PERR ("Failed to drop database %s prior to recreating it."
+ "Proceeding would combine old and new data.",
+ uri.quote_dbname(Type).c_str());
+ LEAVE ("Error");
+ return false;
+ }
+ return true;
+}
template <DbType Type> void
GncDbiBackend<Type>::session_begin (QofSession* session, const char* new_uri,
- bool ignore_lock, bool create, bool force)
+ SessionOpenMode mode)
{
GncDbiTestResult dbi_test_result = GNC_DBI_PASS;
PairVec options;
@@ -677,27 +713,9 @@ GncDbiBackend<Type>::session_begin (QofSession* session, const char* new_uri,
}
else
{
- PERR ("Unknown database type, can't proceed.");
- LEAVE("Error");
+ if (!drop_database<Type>(conn, uri))
return;
}
- if (dbi_conn_select_db (conn, root_db) == -1)
- {
- PERR ("Failed to switch out of %s, drop will fail.",
- uri.quote_dbname(Type).c_str());
- LEAVE ("Error");
- return;
- }
- if (!dbi_conn_queryf (conn, "DROP DATABASE %s",
- uri.quote_dbname(Type).c_str()))
- {
- PERR ("Failed to drop database %s prior to recreating it."
- "Proceeding would combine old and new data.",
- uri.quote_dbname(Type).c_str());
- LEAVE ("Error");
- return;
- }
- }
else
{
set_error (ERR_BACKEND_STORE_EXISTS);
commit a320035f42f556bd1ce8961c5d8fd11ce985769a
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Jun 2 11:48:33 2020 -0700
QofSession, QofBackend: Change book_id to uri.
It's more descriptive and less likely to be confused with the book:id value
in XML files that is the book's GUID.
Also changed the QofSessionImpl::begin new_uri parameter from std::string to
const char*. There's no point in allocating a string just to call
new_uri.c_str() all over the place.
diff --git a/gnucash/gnome-utils/gnc-main-window.c b/gnucash/gnome-utils/gnc-main-window.c
index 300702a56..4829f0154 100644
--- a/gnucash/gnome-utils/gnc-main-window.c
+++ b/gnucash/gnome-utils/gnc-main-window.c
@@ -1499,7 +1499,7 @@ gnc_main_window_generate_title (GncMainWindow *window)
QofBook *book;
gboolean immutable;
gchar *filename = NULL;
- const gchar *book_id = NULL;
+ const gchar *uri = NULL;
const gchar *dirty = "";
const gchar *readonly_text = NULL;
gchar *readonly;
@@ -1507,7 +1507,7 @@ gnc_main_window_generate_title (GncMainWindow *window)
if (gnc_current_session_exist())
{
- book_id = qof_session_get_url (gnc_get_current_session ());
+ uri = qof_session_get_url (gnc_get_current_session ());
book = gnc_get_current_book();
if (qof_book_session_not_saved (book))
dirty = "*";
@@ -1522,15 +1522,15 @@ gnc_main_window_generate_title (GncMainWindow *window)
? g_strdup_printf(" %s", readonly_text)
: g_strdup("");
- if (!book_id || g_strcmp0 (book_id, "") == 0)
+ if (!uri || g_strcmp0 (uri, "") == 0)
filename = g_strdup(_("Unsaved Book"));
else
{
- if (gnc_uri_targets_local_fs (book_id))
+ if (gnc_uri_targets_local_fs (uri))
{
/* The filename is a true file.
* The Gnome HIG 2.0 recommends only the file name (no path) be used. (p15) */
- gchar *path = gnc_uri_get_path ( book_id );
+ gchar *path = gnc_uri_get_path ( uri );
filename = g_path_get_basename ( path );
g_free ( path );
}
@@ -1538,7 +1538,7 @@ gnc_main_window_generate_title (GncMainWindow *window)
{
/* The filename is composed of database connection parameters.
* For this we will show access_method://username@database[:port] */
- filename = gnc_uri_normalize_uri (book_id, FALSE);
+ filename = gnc_uri_normalize_uri (uri, FALSE);
}
}
@@ -1654,22 +1654,22 @@ static gboolean statusbar_notification_off(gpointer user_data_unused)
static gchar *generate_statusbar_lastmodified_message()
{
gchar *message = NULL;
- const gchar *book_id = NULL;
+ const gchar *uri = NULL;
if (gnc_current_session_exist())
{
- book_id = qof_session_get_url (gnc_get_current_session ());
+ uri = qof_session_get_url (gnc_get_current_session ());
}
- if (!(book_id && strlen (book_id)))
+ if (!(uri && strlen (uri)))
return NULL;
else
{
- if (gnc_uri_targets_local_fs (book_id))
+ if (gnc_uri_targets_local_fs (uri))
{
#ifdef HAVE_SYS_STAT_H
/* The filename is a true file. */
- gchar *filepath = gnc_uri_get_path ( book_id );
+ gchar *filepath = gnc_uri_get_path ( uri );
gchar *filename = g_path_get_basename ( filepath );
{
// Access the mtime information through stat(2)
diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.cpp b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
index 748f3afe5..c17a5e039 100644
--- a/libgnucash/backend/dbi/gnc-backend-dbi.cpp
+++ b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
@@ -376,7 +376,7 @@ error_handler<DbType::DBI_SQLITE> (dbi_conn conn, void* user_data)
template <> void
GncDbiBackend<DbType::DBI_SQLITE>::session_begin(QofSession* session,
- const char* book_id,
+ const char* new_uri,
bool ignore_lock,
bool create, bool force)
{
@@ -384,12 +384,12 @@ GncDbiBackend<DbType::DBI_SQLITE>::session_begin(QofSession* session,
PairVec options;
g_return_if_fail (session != nullptr);
- g_return_if_fail (book_id != nullptr);
+ g_return_if_fail (new_uri != nullptr);
ENTER (" ");
/* Remove uri type if present */
- auto path = gnc_uri_get_path (book_id);
+ auto path = gnc_uri_get_path (new_uri);
std::string filepath{path};
g_free(path);
GFileTest ftest = static_cast<decltype (ftest)> (
@@ -441,7 +441,7 @@ GncDbiBackend<DbType::DBI_SQLITE>::session_begin(QofSession* session,
if (result < 0)
{
dbi_conn_close(conn);
- PERR ("Unable to connect to %s: %d\n", book_id, result);
+ PERR ("Unable to connect to %s: %d\n", new_uri, result);
set_error (ERR_BACKEND_BAD_URL);
LEAVE("Error");
return;
@@ -611,21 +611,21 @@ adjust_sql_options (dbi_conn connection)
template <DbType Type> void
-GncDbiBackend<Type>::session_begin (QofSession* session, const char* book_id,
+GncDbiBackend<Type>::session_begin (QofSession* session, const char* new_uri,
bool ignore_lock, bool create, bool force)
{
GncDbiTestResult dbi_test_result = GNC_DBI_PASS;
PairVec options;
g_return_if_fail (session != nullptr);
- g_return_if_fail (book_id != nullptr);
+ g_return_if_fail (new_uri != nullptr);
ENTER (" ");
/* Split the book-id
* Format is protocol://username:password@hostname:port/dbname
where username, password and port are optional) */
- UriStrings uri(book_id);
+ UriStrings uri(new_uri);
if (Type == DbType::DBI_PGSQL)
{
diff --git a/libgnucash/backend/xml/gnc-xml-backend.cpp b/libgnucash/backend/xml/gnc-xml-backend.cpp
index d652b7810..3984d4d8a 100644
--- a/libgnucash/backend/xml/gnc-xml-backend.cpp
+++ b/libgnucash/backend/xml/gnc-xml-backend.cpp
@@ -106,11 +106,11 @@ GncXmlBackend::check_path (const char* fullpath, bool create)
}
void
-GncXmlBackend::session_begin(QofSession* session, const char* book_id,
+GncXmlBackend::session_begin(QofSession* session, const char* new_uri,
bool ignore_lock, bool create, bool force)
{
/* Make sure the directory is there */
- m_fullpath = gnc_uri_get_path (book_id);
+ m_fullpath = gnc_uri_get_path (new_uri);
if (m_fullpath.empty())
{
diff --git a/libgnucash/backend/xml/gnc-xml-backend.hpp b/libgnucash/backend/xml/gnc-xml-backend.hpp
index cc3ff7c55..aeb04a3e0 100644
--- a/libgnucash/backend/xml/gnc-xml-backend.hpp
+++ b/libgnucash/backend/xml/gnc-xml-backend.hpp
@@ -35,7 +35,7 @@ public:
GncXmlBackend(const GncXmlBackend&&) = delete;
GncXmlBackend operator=(const GncXmlBackend&&) = delete;
~GncXmlBackend() = default;
- void session_begin(QofSession* session, const char* book_id,
+ void session_begin(QofSession* session, const char* new_uri,
bool ignore_lock, bool create, bool force) override;
void session_end() override;
void load(QofBook* book, QofBackendLoadType loadType) override;
diff --git a/libgnucash/engine/qof-backend.hpp b/libgnucash/engine/qof-backend.hpp
index ce0df972d..ee424937c 100644
--- a/libgnucash/engine/qof-backend.hpp
+++ b/libgnucash/engine/qof-backend.hpp
@@ -185,7 +185,7 @@ public:
/**
* Open the file or connect to the server.
* @param session The QofSession that will control the backend.
- * @param book_id The book's string identifier.
+ * @param new_uri The location of the data store that the backend will use.
* @param ignore_lock indicates whether the single-user lock on the backend
* should be cleared. The typical GUI sequence leading to this is:
* (1) GUI attempts to open the backend by calling this routine with
@@ -203,7 +203,7 @@ public:
* @param force works with create to force creating a new database even if
* one already exists at the same URI.
*/
- virtual void session_begin(QofSession *session, const char* book_id,
+ virtual void session_begin(QofSession *session, const char* new_uri,
bool ignore_lock, bool create, bool force) = 0;
virtual void session_end() = 0;
/**
diff --git a/libgnucash/engine/qofsession.cpp b/libgnucash/engine/qofsession.cpp
index 03a9c3001..3371d8465 100644
--- a/libgnucash/engine/qofsession.cpp
+++ b/libgnucash/engine/qofsession.cpp
@@ -121,7 +121,7 @@ qof_backend_get_registered_access_method_list(void)
QofSessionImpl::QofSessionImpl (QofBook* book) noexcept
: m_backend {},
m_book {book},
- m_book_id {},
+ m_uri {},
m_saving {false},
m_last_err {},
m_error_message {}
@@ -130,7 +130,7 @@ QofSessionImpl::QofSessionImpl (QofBook* book) noexcept
QofSessionImpl::~QofSessionImpl () noexcept
{
- ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
+ ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
end ();
destroy_backend ();
qof_book_set_backend (m_book, nullptr);
@@ -182,10 +182,10 @@ QofSessionImpl::load_backend (std::string access_method) noexcept
PINFO (" Selected provider %s", prov->provider_name);
// Only do a type check when trying to open an existing file
// When saving over an existing file the contents of the original file don't matter
- if (!m_creating && !prov->type_check (m_book_id.c_str ()))
+ if (!m_creating && !prov->type_check (m_uri.c_str ()))
{
PINFO("Provider, %s, reported not being usable for book, %s.",
- prov->provider_name, m_book_id.c_str ());
+ prov->provider_name, m_uri.c_str ());
continue;
}
m_backend = prov->create_backend();
@@ -203,8 +203,8 @@ QofSessionImpl::load (QofPercentageFunc percentage_func) noexcept
/* We must have an empty book to load into or bad things will happen. */
g_return_if_fail(m_book && qof_book_empty(m_book));
- if (!m_book_id.size ()) return;
- ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
+ if (!m_uri.size ()) return;
+ ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
/* At this point, we should are supposed to have a valid book
* id and a lock on the file. */
@@ -246,18 +246,18 @@ QofSessionImpl::load (QofPercentageFunc percentage_func) noexcept
return;
}
- LEAVE ("sess = %p, book_id=%s", this, m_book_id.c_str ());
+ LEAVE ("sess = %p, uri=%s", this, m_uri.c_str ());
}
void
-QofSessionImpl::begin (std::string new_book_id, bool ignore_lock,
+QofSessionImpl::begin (const char* new_uri, bool ignore_lock,
bool create, bool force) noexcept
{
ENTER (" sess=%p ignore_lock=%d, book-id=%s",
- this, ignore_lock, new_book_id.c_str ());
+ this, ignore_lock, new_uri);
clear_error ();
/* Check to see if this session is already open */
- if (m_book_id.size ())
+ if (m_uri.size ())
{
if (ERR_BACKEND_NO_ERR != get_error ())
push_error (ERR_BACKEND_LOCKED, {});
@@ -266,20 +266,20 @@ QofSessionImpl::begin (std::string new_book_id, bool ignore_lock,
}
/* seriously invalid */
- if (!new_book_id.size ())
+ if (!new_uri)
{
if (ERR_BACKEND_NO_ERR != get_error ())
push_error (ERR_BACKEND_BAD_URL, {});
- LEAVE("push error missing new_book_id");
+ LEAVE("push error missing new_uri");
return;
}
- char * scheme {g_uri_parse_scheme (new_book_id.c_str ())};
+ char * scheme {g_uri_parse_scheme (new_uri)};
char * filename {nullptr};
if (g_strcmp0 (scheme, "file") == 0)
- filename = g_filename_from_uri (new_book_id.c_str (), nullptr, nullptr);
+ filename = g_filename_from_uri (new_uri, nullptr, nullptr);
else if (!scheme)
- filename = g_strdup (new_book_id.c_str ());
+ filename = g_strdup (new_uri);
if (filename && g_file_test (filename, G_FILE_TEST_IS_DIR))
{
@@ -293,7 +293,7 @@ QofSessionImpl::begin (std::string new_book_id, bool ignore_lock,
/* destroy the old backend */
destroy_backend ();
/* Store the session URL */
- m_book_id = new_book_id;
+ m_uri = new_uri;
m_creating = create;
if (filename)
load_backend ("file");
@@ -305,23 +305,23 @@ QofSessionImpl::begin (std::string new_book_id, bool ignore_lock,
/* No backend was found. That's bad. */
if (m_backend == nullptr)
{
- m_book_id = {};
+ m_uri = {};
if (ERR_BACKEND_NO_ERR == get_error ())
push_error (ERR_BACKEND_BAD_URL, {});
LEAVE (" BAD: no backend: sess=%p book-id=%s",
- this, new_book_id.c_str ());
+ this, new_uri);
return;
}
/* If there's a begin method, call that. */
- m_backend->session_begin(this, m_book_id.c_str(),
+ m_backend->session_begin(this, m_uri.c_str(),
ignore_lock, create, force);
PINFO ("Done running session_begin on backend");
QofBackendError const err {m_backend->get_error()};
auto msg (m_backend->get_message());
if (err != ERR_BACKEND_NO_ERR)
{
- m_book_id = {};
+ m_uri = {};
push_error (err, msg);
LEAVE (" backend error %d %s", err, msg.empty() ? "(null)" : msg.c_str());
return;
@@ -331,19 +331,19 @@ QofSessionImpl::begin (std::string new_book_id, bool ignore_lock,
PWARN("%s", msg.c_str());
}
- LEAVE (" sess=%p book-id=%s", this, new_book_id.c_str ());
+ LEAVE (" sess=%p book-id=%s", this, new_uri);
}
void
QofSessionImpl::end () noexcept
{
- ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
+ ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
auto backend = qof_book_get_backend (m_book);
if (backend != nullptr)
backend->session_end();
clear_error ();
- m_book_id.clear();
- LEAVE ("sess=%p book_id=%s", this, m_book_id.c_str ());
+ m_uri.clear();
+ LEAVE ("sess=%p uri=%s", this, m_uri.c_str ());
}
/* error handling functions --------------------------------*/
@@ -424,9 +424,9 @@ QofSessionImpl::get_file_path () const noexcept
}
std::string const &
-QofSessionImpl::get_book_id () const noexcept
+QofSessionImpl::get_uri () const noexcept
{
- return m_book_id;
+ return m_uri;
}
bool
@@ -443,7 +443,7 @@ QofSessionImpl::save (QofPercentageFunc percentage_func) noexcept
if (!qof_book_session_not_saved (m_book)) //Clean book, nothing to do.
return;
m_saving = true;
- ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
+ ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
/* If there is a backend, the book is dirty, and the backend is reachable
* (i.e. we can communicate with it), then synchronize with the backend. If
@@ -490,7 +490,7 @@ QofSessionImpl::safe_save (QofPercentageFunc percentage_func) noexcept
auto msg = m_backend->get_message();
if (err != ERR_BACKEND_NO_ERR)
{
- m_book_id = nullptr;
+ m_uri = "";
push_error (err, msg);
}
}
@@ -540,8 +540,8 @@ QofSessionImpl::export_session (QofSessionImpl & real_session,
QofPercentageFunc percentage_func) noexcept
{
auto real_book = real_session.get_book ();
- ENTER ("tmp_session=%p real_session=%p book=%p book_id=%s",
- this, &real_session, real_book, m_book_id.c_str ());
+ ENTER ("tmp_session=%p real_session=%p book=%p uri=%s",
+ this, &real_session, real_book, m_uri.c_str ());
/* There must be a backend or else. (It should always be the file
* backend too.)
@@ -599,7 +599,7 @@ const char *
qof_session_get_url (const QofSession *session)
{
if (!session) return NULL;
- return session->get_book_id ().c_str ();
+ return session->get_uri ().c_str ();
}
QofBackend *
@@ -610,11 +610,11 @@ qof_session_get_backend (const QofSession *session)
}
void
-qof_session_begin (QofSession *session, const char * book_id,
+qof_session_begin (QofSession *session, const char * new_uri,
gboolean ignore_lock, gboolean create, gboolean force)
{
if (!session) return;
- session->begin((book_id ? book_id : ""), ignore_lock, create, force);
+ session->begin((new_uri ? new_uri : ""), ignore_lock, create, force);
}
void
@@ -706,18 +706,18 @@ qof_session_destroy_backend (QofSession * session)
session->destroy_backend ();
}
-void qof_session_set_book_id (QofSession * session, char const * book_id)
+void qof_session_set_uri (QofSession * session, char const * uri)
{
- if (!book_id)
- session->m_book_id = "";
+ if (!uri)
+ session->m_uri = "";
else
- session->m_book_id = book_id;
+ session->m_uri = uri;
}
void (*p_qof_session_load_backend) (QofSession *, const char * access_method);
void (*p_qof_session_clear_error) (QofSession *);
void (*p_qof_session_destroy_backend) (QofSession *);
-void (*p_qof_session_set_book_id) (QofSession *, char const * book_id);
+void (*p_qof_session_set_uri) (QofSession *, char const * uri);
void
init_static_qofsession_pointers (void)
@@ -725,7 +725,7 @@ init_static_qofsession_pointers (void)
p_qof_session_load_backend = &qof_session_load_backend;
p_qof_session_clear_error = &qof_session_clear_error;
p_qof_session_destroy_backend = &qof_session_destroy_backend;
- p_qof_session_set_book_id = &qof_session_set_book_id;
+ p_qof_session_set_uri = &qof_session_set_uri;
}
QofBackendError
diff --git a/libgnucash/engine/qofsession.h b/libgnucash/engine/qofsession.h
index 371dbcc75..9611cc2a2 100644
--- a/libgnucash/engine/qofsession.h
+++ b/libgnucash/engine/qofsession.h
@@ -152,7 +152,7 @@ void qof_session_swap_data (QofSession *session_1, QofSession *session_2);
* If an error occurs, it will be pushed onto the session error
* stack, and that is where it should be examined.
*/
-void qof_session_begin (QofSession *session, const char * book_id,
+void qof_session_begin (QofSession *session, const char * new_uri,
gboolean ignore_lock, gboolean create,
gboolean force);
diff --git a/libgnucash/engine/qofsession.hpp b/libgnucash/engine/qofsession.hpp
index 12a92b16b..df4e02ab8 100644
--- a/libgnucash/engine/qofsession.hpp
+++ b/libgnucash/engine/qofsession.hpp
@@ -41,7 +41,7 @@ struct QofSessionImpl
~QofSessionImpl () noexcept;
/** Begin this session. */
- void begin (std::string book_id, bool ignore_lock, bool create, bool force) noexcept;
+ void begin (const char* new_uri, bool ignore_lock, bool create, bool force) noexcept;
/** Swap books with another session */
void swap_books (QofSessionImpl &) noexcept;
@@ -62,7 +62,7 @@ struct QofSessionImpl
* We return by reference so that a pointer to the data of the string lives
* long enough to make it back to C code.
*/
- std::string const & get_book_id () const noexcept;
+ std::string const & get_uri () const noexcept;
/**
* Returns and clears the local cached error. If there is no local error, we check
* for an error in the backend.
@@ -92,10 +92,10 @@ private:
/* A book holds pointers to the various types of datasets.
* A session has exactly one book. */
QofBook * m_book;
- /* The requested book id, in the form or a URI, such as
- * file:/some/where, or sql:server.host.com:555
+ /* The requested URI, such as
+ * file://some/where, or sql:server.host.com:555
*/
- std::string m_book_id;
+ std::string m_uri;
bool m_saving;
bool m_creating;
@@ -113,8 +113,8 @@ private:
/* These functions support the old testing infrastructure and should
* be removed when they are no longer necessary.*/
friend void qof_session_load_backend (QofSession *, const char *);
- friend char const * qof_session_get_book_id (QofSession *);
- friend void qof_session_set_book_id (QofSession *, char const *);
+ friend char const * qof_session_get_uri (QofSession *);
+ friend void qof_session_set_uri (QofSession *, char const *);
};
typedef struct qof_instance_copy_data
diff --git a/libgnucash/engine/test/test-qofsession-old.cpp b/libgnucash/engine/test/test-qofsession-old.cpp
index d9be207f3..f10b64fa9 100644
--- a/libgnucash/engine/test/test-qofsession-old.cpp
+++ b/libgnucash/engine/test/test-qofsession-old.cpp
@@ -41,7 +41,6 @@ extern "C" void test_suite_qofsession ( void );
extern void (*p_qof_session_load_backend) (QofSession *, const char * access_method);
extern void (*p_qof_session_clear_error) (QofSession *);
extern void (*p_qof_session_destroy_backend) (QofSession *);
-extern void (*p_qof_session_set_book_id) (QofSession *, const char * book_id);
void init_static_qofsession_pointers (void);
@@ -134,10 +133,10 @@ struct QofMockLoadBackendProvider : public QofBackendProvider
};
bool
-QofMockLoadBackendProvider::type_check (const char* book_id)
+QofMockLoadBackendProvider::type_check (const char* uri)
{
- g_assert (book_id);
- g_assert_cmpstr (book_id, ==, "my book");
+ g_assert (uri);
+ g_assert_cmpstr (uri, ==, "my book");
load_backend_struct.check_data_type_called = true;
return load_backend_struct.data_compatible;
}
@@ -184,7 +183,7 @@ test_qof_session_load_backend (Fixture *fixture, gconstpointer pData)
qof_backend_register_provider (std::move(prov));
load_backend_struct.data_compatible = FALSE;
load_backend_struct.check_data_type_called = FALSE;
- p_qof_session_set_book_id (fixture->session, "my book");
+ p_qof_session_set_uri (fixture->session, "my book");
p_qof_session_load_backend (fixture->session, "file");
g_assert (load_backend_struct.check_data_type_called);
g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER);
@@ -243,7 +242,7 @@ test_qof_session_load (Fixture *fixture, gconstpointer pData)
QofBook *newbook = NULL;
/* init */
- p_qof_session_set_book_id (fixture->session, "my book");
+ p_qof_session_set_uri (fixture->session, "my book");
be = g_new0 (QofBackend, 1);
g_assert (be);
qof_book_set_backend (qof_session_get_book (fixture->session), be);
@@ -280,22 +279,22 @@ static struct
{
QofBackend *be;
QofSession *session;
- const char *book_id;
+ const char *uri;
gboolean backend_new_called;
gboolean session_begin_called;
gboolean produce_error;
} session_begin_struct;
static void
-mock_session_begin (QofBackend *be, QofSession *session, const char *book_id,
+mock_session_begin (QofBackend *be, QofSession *session, const char *uri,
gboolean ignore_lock, gboolean create, gboolean force)
{
g_assert (be);
g_assert (be == session_begin_struct.be);
g_assert (session);
g_assert (session == session_begin_struct.session);
- g_assert (book_id);
- g_assert_cmpstr (book_id, == , session_begin_struct.book_id);
+ g_assert (uri);
+ g_assert_cmpstr (uri, == , session_begin_struct.uri);
g_assert (ignore_lock);
g_assert (!create);
g_assert (force);
@@ -315,9 +314,9 @@ struct QofMockSessBackendProvider : public QofBackendProvider
};
bool
-QofMockSessBackendProvider::type_check (const char* book_id)
+QofMockSessBackendProvider::type_check (const char* uri)
{
- g_assert (book_id);
+ g_assert (uri);
return true;
}
@@ -350,14 +349,14 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
g_assert_cmpint (get_providers().size(), == , 0);
/* run tests */
- g_test_message ("Test when book_id is set backend is not changed");
+ g_test_message ("Test when uri is set backend is not changed");
qof_book_set_backend (qof_session_get_book (fixture->session), be);
- p_qof_session_set_book_id (fixture->session, "my book");
+ p_qof_session_set_uri (fixture->session, "my book");
qof_session_begin (fixture->session, "my book", ignore_lock, create, force);
g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == be);
- g_test_message ("Test when session book_id is not set and book_id passed is null backend is not changed");
- p_qof_session_set_book_id (fixture->session, NULL);
+ g_test_message ("Test when session uri is not set and uri passed is null backend is not changed");
+ p_qof_session_set_uri (fixture->session, NULL);
qof_session_begin (fixture->session, NULL, ignore_lock, create, force);
g_assert (qof_book_get_backend (qof_session_get_book (fixture->session)) == be);
@@ -379,7 +378,7 @@ test_qof_session_begin (Fixture *fixture, gconstpointer pData)
g_test_message ("Test with valid backend returned and session begin set; error is produced");
session_begin_struct.session = fixture->session;
- session_begin_struct.book_id = "postgres://localhost:8080";
+ session_begin_struct.uri = "postgres://localhost:8080";
session_begin_struct.backend_new_called = FALSE;
session_begin_struct.session_begin_called = FALSE;
session_begin_struct.produce_error = TRUE;
@@ -417,7 +416,7 @@ static struct
QofBackend *be;
QofBook *book;
QofSession *session;
- const char *book_id;
+ const char *uri;
gboolean sync_called;
gboolean backend_new_called;
gboolean session_begin_called;
@@ -545,14 +544,14 @@ test_qof_session_end (Fixture *fixture, gconstpointer pData)
{
QofBackend *be = NULL;
- g_test_message ("Test backend is closed, errors cleared and book_id removed");
+ g_test_message ("Test backend is closed, errors cleared and uri removed");
be = g_new0 (QofBackend, 1);
g_assert (be);
be->session_end = mock_session_end;
be->last_err = ERR_BACKEND_DATA_CORRUPT;
be->error_msg = g_strdup("push any error");
qof_book_set_backend (qof_session_get_book (fixture->session), be);
- p_qof_session_set_book_id (fixture->session, "my book");
+ p_qof_session_set_uri (fixture->session, "my book");
session_end_struct.called = FALSE;
session_end_struct.be = be;
qof_session_end (fixture->session);
commit 65e2639de4129d699ea4ad614c8e01da10295b3e
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Jun 2 10:54:09 2020 -0700
Delete QOF_STDOUT.
Apparently a hack for the long-gone QSF backend.
diff --git a/libgnucash/backend/xml/gnc-backend-xml.cpp b/libgnucash/backend/xml/gnc-backend-xml.cpp
index 4dbf00042..10a0d7cd8 100644
--- a/libgnucash/backend/xml/gnc-backend-xml.cpp
+++ b/libgnucash/backend/xml/gnc-backend-xml.cpp
@@ -129,11 +129,6 @@ QofXmlBackendProvider::type_check (const char *uri)
}
filename = gnc_uri_get_path (uri);
- if (0 == g_strcmp0 (filename, QOF_STDOUT))
- {
- result = FALSE;
- goto det_exit;
- }
t = g_fopen (filename, "r");
if (!t)
{
diff --git a/libgnucash/engine/qofsession.h b/libgnucash/engine/qofsession.h
index 88b7b2546..371dbcc75 100644
--- a/libgnucash/engine/qofsession.h
+++ b/libgnucash/engine/qofsession.h
@@ -259,23 +259,6 @@ void qof_session_end (QofSession *session);
/** @}
*/
-/** \brief Allow session data to be printed to stdout
-
-book_id can't be NULL and we do need to have an access_method,
-so use one to solve the other.
-
-To print a session to stdout, use ::qof_session_begin. Example:
-
-\a qof_session_begin(session,QOF_STDOUT,TRUE,FALSE);
-
-When you call qof_session_save(session, NULL), the output will appear
-on stdout and can be piped or redirected to other processes.
-
-Currently, only the QSF backend supports writing to stdout, other
-backends may return a ::QofBackendError.
-*/
-#define QOF_STDOUT ">"
-
/** @name Event Handling
@{ */
Summary of changes:
bindings/python/sqlite3test.c | 2 +-
gnucash/gnome-utils/assistant-xml-encoding.c | 2 +-
gnucash/gnome-utils/gnc-file.c | 25 ++---
gnucash/gnome-utils/gnc-main-window.c | 22 ++---
gnucash/gnucash-commands.cpp | 4 +-
gnucash/import-export/aqb/test/test-kvp.c | 4 +-
libgnucash/backend/dbi/gnc-backend-dbi.cpp | 104 +++++++++++----------
libgnucash/backend/dbi/gnc-backend-dbi.hpp | 2 +-
libgnucash/backend/dbi/gnc-dbisqlconnection.cpp | 15 +--
libgnucash/backend/dbi/gnc-dbisqlconnection.hpp | 5 +-
.../backend/dbi/test/test-backend-dbi-basic.cpp | 22 ++---
.../backend/sql/test/utest-gnc-backend-sql.cpp | 2 +-
libgnucash/backend/xml/gnc-backend-xml.cpp | 5 -
libgnucash/backend/xml/gnc-xml-backend.cpp | 46 ++++-----
libgnucash/backend/xml/gnc-xml-backend.hpp | 4 +-
libgnucash/backend/xml/test/test-load-xml2.cpp | 3 +-
libgnucash/backend/xml/test/test-save-in-lang.cpp | 4 +-
libgnucash/engine/qof-backend.hpp | 23 +----
libgnucash/engine/qofsession.cpp | 88 +++++++++--------
libgnucash/engine/qofsession.h | 96 ++++++++++---------
libgnucash/engine/qofsession.hpp | 14 +--
libgnucash/engine/test/test-qofinstance.cpp | 4 +-
libgnucash/engine/test/test-qofsession-old.cpp | 60 ++++++------
libgnucash/engine/test/test-qofsession.cpp | 24 ++---
libgnucash/engine/test/utest-Transaction.cpp | 2 +-
25 files changed, 280 insertions(+), 302 deletions(-)
More information about the gnucash-changes
mailing list