r19798 - gnucash/trunk/src - Bug 634392: New sql database raises clobber warning
John Ralls
jralls at code.gnucash.org
Thu Nov 11 01:12:20 EST 2010
Author: jralls
Date: 2010-11-11 01:12:20 -0500 (Thu, 11 Nov 2010)
New Revision: 19798
Trac: http://svn.gnucash.org/trac/changeset/19798
Modified:
gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
gnucash/trunk/src/backend/dbi/test/test-dbi-business-stuff.c
gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c
gnucash/trunk/src/backend/dbi/test/test-dbi.c
gnucash/trunk/src/backend/xml/gnc-backend-xml.c
gnucash/trunk/src/backend/xml/test/test-load-xml2.c
gnucash/trunk/src/backend/xml/test/test-save-in-lang.c
gnucash/trunk/src/bin/gnucash-bin.c
gnucash/trunk/src/business/business-core/test/test-customer.c
gnucash/trunk/src/business/business-core/test/test-employee.c
gnucash/trunk/src/business/business-core/test/test-job.c
gnucash/trunk/src/business/business-core/test/test-vendor.c
gnucash/trunk/src/engine/test/test-recursive.c
gnucash/trunk/src/gnome-utils/druid-gnc-xml-import.c
gnucash/trunk/src/gnome-utils/gnc-file.c
gnucash/trunk/src/libqof/qof/qofbackend-p.h
gnucash/trunk/src/libqof/qof/qofbackend.h
gnucash/trunk/src/libqof/qof/qofsession.c
gnucash/trunk/src/libqof/qof/qofsession.h
Log:
Bug 634392: New sql database raises clobber warning
A fairly extensive change, because I changed may_clobber from a global
qof function (which passed through qofbackend and fetched up in the
actual backends) to a local static in the individual backends which
raise a new qof_backend_error, QOF_ABCKEND_STORE_EXISTS. This was
necessary to reorder the existence check before the lock, because with
the sql backends, locking creates the database... which then would
return may_clobber as true, even though it really wasn't.
New parameter "force" added to session_begin() functions, and
"create_if_nonexistant" is renamed to simply "create". The reason for
the latter is that the file/database is created regardless of whether it
already exists; that's what the clobber check is about. The new "force"
parameter is set to true the second time through, after the user has
responded to the clobber dialog indicating that the data should be
destroyed.
Many of the extraneous changes are just adding the new parameter to the
session_begin() calls.
gnc-file changes to handle the error in favor of calling the
no-longer-existing qof_check_may_clobber_data() call after
session_begin().
Two minor changes to gnc_file_do_save_as: gnc_add_history and
gnc_hook_run are now called on new_session instead of old_session; this
ensures that the new file/database is used at the next startup of
gnucash. Second, the filename/url is filtered before displaying the
"may_clobber" dialog box to prevent displaying plaintext database
passwords.
Modified: gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
===================================================================
--- gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -122,6 +122,7 @@
static void append_pgsql_col_def( GString* ddl, GncSqlColumnInfo* info );
static gboolean gnc_dbi_lock_database( QofBackend *qbe, gboolean ignore_lock );
static void gnc_dbi_unlock( QofBackend *qbe );
+static gboolean save_may_clobber_data( QofBackend* qbe );
static provider_functions_t provider_pgsql =
{
@@ -260,7 +261,7 @@
static void
gnc_dbi_sqlite3_session_begin( QofBackend *qbe, QofSession *session,
const gchar *book_id, gboolean ignore_lock,
- gboolean create_if_nonexistent )
+ gboolean create, gboolean force )
{
GncDbiBackend *be = (GncDbiBackend*)qbe;
gint result;
@@ -277,14 +278,23 @@
/* Remove uri type if present */
filepath = gnc_uri_get_path ( book_id );
- if ( !create_if_nonexistent
- && !g_file_test( filepath, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS ) )
+ if ( !create &&
+ !g_file_test( filepath, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS ) )
{
qof_backend_set_error( qbe, ERR_FILEIO_FILE_NOT_FOUND );
LEAVE(" ");
return;
}
+ if ( create && !force &&
+ g_file_test( filepath, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS ) )
+ {
+ qof_backend_set_error (qbe, ERR_BACKEND_STORE_EXISTS);
+ LEAVE("Might clobber, no force");
+ return;
+ }
+
+
if ( be->conn != NULL )
{
dbi_conn_close( be->conn );
@@ -668,7 +678,7 @@
static void
gnc_dbi_mysql_session_begin( QofBackend* qbe, QofSession *session,
const gchar *book_id, gboolean ignore_lock,
- gboolean create_if_nonexistent )
+ gboolean create, gboolean force )
{
GncDbiBackend *be = (GncDbiBackend*)qbe;
gchar* protocol = NULL;
@@ -692,7 +702,7 @@
gnc_uri_get_components ( book_id, &protocol, &host, &portnum,
&username, &password, &dbname );
- // Try to connect to the db. If it doesn't exist and the create_if_nonexistent
+ // Try to connect to the db. If it doesn't exist and the create
// flag is TRUE, we'll need to connect to the 'mysql' db and execute the
// CREATE DATABASE ddl statement there.
if ( be->conn != NULL )
@@ -715,6 +725,13 @@
result = dbi_conn_connect( be->conn );
if ( result == 0 )
{
+ if (create && !force && save_may_clobber_data( qbe ) )
+ {
+ qof_backend_set_error ( qbe, ERR_BACKEND_STORE_EXISTS );
+ PWARN("Databse already exists, Might clobber it.");
+ goto exit;
+ }
+
success = gnc_dbi_lock_database ( qbe, ignore_lock );
}
else
@@ -728,7 +745,7 @@
}
// The db does not already exist. Connect to the 'mysql' db and try to create it.
- if ( create_if_nonexistent )
+ if ( create )
{
dbi_result dresult;
result = dbi_conn_set_option( be->conn, "dbname", "mysql" );
@@ -862,7 +879,7 @@
static void
gnc_dbi_postgres_session_begin( QofBackend *qbe, QofSession *session,
const gchar *book_id, gboolean ignore_lock,
- gboolean create_if_nonexistent )
+ gboolean create, gboolean force )
{
GncDbiBackend *be = (GncDbiBackend*)qbe;
gint result = 0;
@@ -888,7 +905,7 @@
if ( portnum == 0 )
portnum = PGSQL_DEFAULT_PORT;
- // Try to connect to the db. If it doesn't exist and the create_if_nonexistent
+ // Try to connect to the db. If it doesn't exist and the create
// flag is TRUE, we'll need to connect to the 'postgres' db and execute the
// CREATE DATABASE ddl statement there.
if ( be->conn != NULL )
@@ -911,6 +928,13 @@
result = dbi_conn_connect( be->conn );
if ( result == 0 )
{
+ if (create && !force && save_may_clobber_data( qbe ) )
+ {
+ qof_backend_set_error ( qbe, ERR_BACKEND_STORE_EXISTS );
+ PWARN("Databse already exists, Might clobber it.");
+ goto exit;
+ }
+
success = gnc_dbi_lock_database ( qbe, ignore_lock );
}
else
@@ -924,7 +948,7 @@
}
// The db does not already exist. Connect to the 'postgres' db and try to create it.
- if ( create_if_nonexistent )
+ if ( create )
{
dbi_result dresult;
result = dbi_conn_set_option( be->conn, "dbname", "postgres" );
@@ -1066,29 +1090,22 @@
/* ================================================================= */
static gboolean
-gnc_dbi_save_may_clobber_data( QofBackend* qbe )
+save_may_clobber_data( QofBackend* qbe )
{
GncDbiBackend* be = (GncDbiBackend*)qbe;
const gchar* dbname;
- GSList* table_name_list;
- gint numTables = 0;
- gint status;
+ dbi_result result;
+ gboolean retval = FALSE;
/* Data may be clobbered iff the number of tables != 0 */
dbname = dbi_conn_get_option( be->conn, "dbname" );
- table_name_list = ((GncDbiSqlConnection*)(be->sql_be.conn))->provider->get_table_list( be->conn, dbname );
- if ( table_name_list != NULL )
+ result = dbi_conn_get_table_list( be->conn, dbname, NULL );
+ if ( result )
{
- GSList* node;
- numTables = g_slist_length( table_name_list );
- for ( node = table_name_list; node != NULL; node = node->next )
- {
- g_free( node->data );
- }
- g_slist_free( table_name_list );
+ retval = dbi_result_get_numrows( result ) > 0;
+ dbi_result_free( result );
}
-
- return (numTables != 0);
+ return retval;
}
static void
@@ -1195,7 +1212,6 @@
be->destroy_backend = gnc_dbi_destroy_backend;
be->load = gnc_dbi_load;
- be->save_may_clobber_data = gnc_dbi_save_may_clobber_data;
/* The gda backend treats accounting periods transactionally. */
be->begin = gnc_dbi_begin_edit;
@@ -1223,7 +1239,9 @@
static QofBackend*
new_backend( void (*session_begin)( QofBackend *, QofSession *, const gchar *,
- /*@ unused @*/ gboolean, /*@ unused @*/ gboolean ) )
+ /*@ unused @*/ gboolean,
+ /*@ unused @*/ gboolean,
+ /*@ unused @*/ gboolean ) )
{
GncDbiBackend *dbi_be;
QofBackend *be;
Modified: gnucash/trunk/src/backend/dbi/test/test-dbi-business-stuff.c
===================================================================
--- gnucash/trunk/src/backend/dbi/test/test-dbi-business-stuff.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/backend/dbi/test/test-dbi-business-stuff.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -198,13 +198,13 @@
// Save the session data
session_2 = qof_session_new();
- qof_session_begin( session_2, url, FALSE, TRUE );
+ qof_session_begin( session_2, url, FALSE, TRUE, TRUE );
qof_session_swap_data( session_1, session_2 );
qof_session_save( session_2, NULL );
// Reload the session data
session_3 = qof_session_new();
- qof_session_begin( session_3, url, TRUE, FALSE );
+ qof_session_begin( session_3, url, TRUE, FALSE, FALSE );
qof_session_load( session_3, NULL );
// Compare with the original data
Modified: gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c
===================================================================
--- gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -151,13 +151,13 @@
// Save the session data
session_2 = qof_session_new();
- qof_session_begin( session_2, url, FALSE, TRUE );
+ qof_session_begin( session_2, url, FALSE, TRUE, TRUE );
qof_session_swap_data( session_1, session_2 );
qof_session_save( session_2, NULL );
// Reload the session data
session_3 = qof_session_new();
- qof_session_begin( session_3, url, TRUE, FALSE );
+ qof_session_begin( session_3, url, TRUE, FALSE, FALSE );
qof_session_load( session_3, NULL );
// Compare with the original data
Modified: gnucash/trunk/src/backend/dbi/test/test-dbi.c
===================================================================
--- gnucash/trunk/src/backend/dbi/test/test-dbi.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/backend/dbi/test/test-dbi.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -52,7 +52,7 @@
// Create a session with data
session_1 = qof_session_new();
- qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
+ qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE, FALSE );
qof_session_load( session_1, NULL );
filename = tempnam( "/tmp", "test-sqlite3-" );
@@ -63,7 +63,7 @@
if ( strlen( TEST_MYSQL_URL ) > 0 )
{
session_1 = qof_session_new();
- qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
+ qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE, FALSE );
qof_session_load( session_1, NULL );
test_dbi_store_and_reload( "mysql", session_1, TEST_MYSQL_URL );
}
@@ -72,7 +72,7 @@
if ( strlen( TEST_PGSQL_URL ) > 0 )
{
session_1 = qof_session_new();
- qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
+ qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE, FALSE );
qof_session_load( session_1, NULL );
test_dbi_store_and_reload( "pgsql", session_1, TEST_PGSQL_URL );
}
Modified: gnucash/trunk/src/backend/xml/gnc-backend-xml.c
===================================================================
--- gnucash/trunk/src/backend/xml/gnc-backend-xml.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/backend/xml/gnc-backend-xml.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -108,6 +108,8 @@
GNC_BOOK_XML2_FILE_NO_ENCODING,
} QofBookFileType;
+static gboolean save_may_clobber_data (QofBackend *bend);
+
/* ================================================================= */
static gboolean
@@ -232,8 +234,8 @@
static void
xml_session_begin(QofBackend *be_start, QofSession *session,
- const char *book_id,
- gboolean ignore_lock, gboolean create_if_nonexistent)
+ const char *book_id, gboolean ignore_lock,
+ gboolean create, gboolean force)
{
FileBackend *be = (FileBackend*) be_start;
@@ -248,6 +250,13 @@
LEAVE("");
return;
}
+ if (create && !force && save_may_clobber_data( be_start ) )
+ {
+ qof_backend_set_error (be_start, ERR_BACKEND_STORE_EXISTS);
+ LEAVE("Might clobber, no force");
+ return;
+ }
+
be->be.fullpath = be->fullpath;
be->dirname = g_path_get_dirname (be->fullpath);
@@ -278,7 +287,7 @@
/* Now check whether we can g_stat the file itself */
rc = g_stat (be->fullpath, &statbuf);
- if ((rc != 0) && (!create_if_nonexistent))
+ if ((rc != 0) && (!create))
{
/* Error on stat means the file doesn't exist */
qof_backend_set_error (be_start, ERR_FILEIO_FILE_NOT_FOUND);
@@ -1084,7 +1093,7 @@
/* ---------------------------------------------------------------------- */
static gboolean
-gnc_xml_be_save_may_clobber_data (QofBackend *bend)
+save_may_clobber_data (QofBackend *bend)
{
struct stat statbuf;
if (!bend->fullpath) return FALSE;
@@ -1178,7 +1187,6 @@
be->destroy_backend = xml_destroy_backend;
be->load = gnc_xml_be_load_from_file;
- be->save_may_clobber_data = gnc_xml_be_save_may_clobber_data;
/* The file backend treats accounting periods transactionally. */
be->begin = xml_begin_edit;
Modified: gnucash/trunk/src/backend/xml/test/test-load-xml2.c
===================================================================
--- gnucash/trunk/src/backend/xml/test/test-load-xml2.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/backend/xml/test/test-load-xml2.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -85,7 +85,7 @@
remove_locks(filename);
ignore_lock = (safe_strcmp(g_getenv("SRCDIR"), ".") != 0);
- qof_session_begin(session, filename, ignore_lock, FALSE);
+ qof_session_begin(session, filename, ignore_lock, FALSE, TRUE);
qof_session_load(session, NULL);
book = qof_session_get_book (session);
Modified: gnucash/trunk/src/backend/xml/test/test-save-in-lang.c
===================================================================
--- gnucash/trunk/src/backend/xml/test/test-save-in-lang.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/backend/xml/test/test-save-in-lang.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -79,7 +79,7 @@
session = qof_session_new();
- qof_session_begin(session, filename, TRUE, FALSE);
+ qof_session_begin(session, filename, TRUE, FALSE, FALSE);
err = qof_session_pop_error (session);
if (err)
{
@@ -100,7 +100,7 @@
new_session = qof_session_new();
- qof_session_begin(new_session, new_file, FALSE, FALSE);
+ qof_session_begin(new_session, new_file, FALSE, FALSE, FALSE);
err = qof_session_pop_error (new_session);
if (err)
{
Modified: gnucash/trunk/src/bin/gnucash-bin.c
===================================================================
--- gnucash/trunk/src/bin/gnucash-bin.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/bin/gnucash-bin.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -627,7 +627,7 @@
session = gnc_get_current_session();
if (!session) goto fail;
- qof_session_begin(session, add_quotes_file, FALSE, FALSE);
+ qof_session_begin(session, add_quotes_file, FALSE, FALSE, FALSE);
if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
qof_session_load(session, NULL);
Modified: gnucash/trunk/src/business/business-core/test/test-customer.c
===================================================================
--- gnucash/trunk/src/business/business-core/test/test-customer.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/business/business-core/test/test-customer.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -65,7 +65,7 @@
session = qof_session_new();
be = NULL;
- qof_session_begin(session, FILE_NAME, FALSE, FALSE);
+ qof_session_begin(session, FILE_NAME, FALSE, FALSE, FALSE);
book = qof_session_get_book(session);
be = qof_book_get_backend(book);
Modified: gnucash/trunk/src/business/business-core/test/test-employee.c
===================================================================
--- gnucash/trunk/src/business/business-core/test/test-employee.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/business/business-core/test/test-employee.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -71,7 +71,7 @@
GncEmployee *employee;
session = qof_session_new();
- qof_session_begin(session, FILE_NAME, FALSE, FALSE);
+ qof_session_begin(session, FILE_NAME, FALSE, FALSE, FALSE);
book = qof_session_get_book(session);
be = qof_book_get_backend (book);
Modified: gnucash/trunk/src/business/business-core/test/test-job.c
===================================================================
--- gnucash/trunk/src/business/business-core/test/test-job.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/business/business-core/test/test-job.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -74,7 +74,7 @@
session = qof_session_new();
be = NULL;
- qof_session_begin(session, FILE_NAME, FALSE, FALSE);
+ qof_session_begin(session, FILE_NAME, FALSE, FALSE, FALSE);
book = qof_session_get_book (session);
be = qof_book_get_backend(book);
Modified: gnucash/trunk/src/business/business-core/test/test-vendor.c
===================================================================
--- gnucash/trunk/src/business/business-core/test/test-vendor.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/business/business-core/test/test-vendor.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -73,7 +73,7 @@
session = qof_session_new();
be = NULL;
- qof_session_begin(session, FILE_NAME, FALSE, FALSE);
+ qof_session_begin(session, FILE_NAME, FALSE, FALSE, FALSE);
book = qof_session_get_book (session);
be = qof_book_get_backend(book);
Modified: gnucash/trunk/src/engine/test/test-recursive.c
===================================================================
--- gnucash/trunk/src/engine/test/test-recursive.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/engine/test/test-recursive.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -1169,7 +1169,7 @@
if (debug)
{
/* FIXME XML backend can't handle STDOUT
- * qof_session_begin(copy, QOF_STDOUT, TRUE, FALSE); */
+ * qof_session_begin(copy, QOF_STDOUT, TRUE, FALSE, FALSE); */
}
/* TODO: implement QOF_TYPE_CHOICE testing. */
qof_instance_copy_coll_r(copy, grand_coll);
@@ -1214,7 +1214,7 @@
if (debug)
{
/* FIXME XML backend can't handle STDOUT
- * qof_session_begin(original, QOF_STDOUT, TRUE, FALSE); */
+ * qof_session_begin(original, QOF_STDOUT, TRUE, FALSE, FALSE); */
}
create_data(original, (counter % 5));
test_recursion(original, (counter % 5));
Modified: gnucash/trunk/src/gnome-utils/druid-gnc-xml-import.c
===================================================================
--- gnucash/trunk/src/gnome-utils/druid-gnc-xml-import.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/gnome-utils/druid-gnc-xml-import.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -743,7 +743,7 @@
gxi_session_destroy (data);
session = qof_session_new ();
data->session = session;
- qof_session_begin (session, data->filename, TRUE, FALSE);
+ qof_session_begin (session, data->filename, TRUE, FALSE, FALSE);
io_err = qof_session_get_error (session);
if (io_err != ERR_BACKEND_NO_ERR)
{
Modified: gnucash/trunk/src/gnome-utils/gnc-file.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-file.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/gnome-utils/gnc-file.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -651,7 +651,7 @@
/* but first, check to make sure we've got a session going. */
new_session = qof_session_new ();
- qof_session_begin (new_session, newfile, FALSE, FALSE);
+ qof_session_begin (new_session, newfile, FALSE, FALSE, FALSE);
io_err = qof_session_get_error (new_session);
/* if file appears to be locked, ask the user ... */
if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
@@ -708,7 +708,7 @@
// reports may take some time
gnc_show_splash_screen();
/* user told us to ignore locks. So ignore them. */
- qof_session_begin (new_session, newfile, TRUE, FALSE);
+ qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
}
else
{
@@ -725,8 +725,10 @@
{
if (FALSE == show_session_error (io_err, newfile, GNC_FILE_DIALOG_OPEN))
{
- /* user told us to create a new database. Do it. */
- qof_session_begin (new_session, newfile, FALSE, TRUE);
+ /* 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);
}
}
@@ -1019,37 +1021,38 @@
/* -- this session code is NOT identical in FileOpen and FileSaveAs -- */
new_session = qof_session_new ();
- qof_session_begin (new_session, newfile, FALSE, TRUE);
+ qof_session_begin (new_session, newfile, FALSE, TRUE, FALSE);
io_err = qof_session_get_error (new_session);
+ /* If the file exists and would be clobbered, ask the user */
+ if (ERR_BACKEND_STORE_EXISTS == io_err) {
+ const char *format = _("The file %s already exists. "
+ "Are you sure you want to overwrite it?");
+ const char *name;
+ if ( gnc_uri_is_file_uri ( newfile ) )
+ name = gnc_uri_get_path ( newfile );
+ else
+ name = gnc_uri_normalize_uri ( newfile, FALSE );
+ /* if user says cancel, we should break out */
+ if (!gnc_verify_dialog (NULL, FALSE, format, name))
+ {
+ return;
+ }
+ qof_session_begin (new_session, newfile, FALSE, TRUE, TRUE);
+ }
/* if file appears to be locked, ask the user ... */
if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
{
if (FALSE == show_session_error (io_err, newfile, GNC_FILE_DIALOG_EXPORT))
{
/* user told us to ignore locks. So ignore them. */
- qof_session_begin (new_session, newfile, TRUE, FALSE);
+ qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
}
}
/* --------------- END CORE SESSION CODE -------------- */
- /* oops ... file already exists ... ask user what to do... */
- if (qof_session_save_may_clobber_data (new_session))
- {
- const char *format = _("The file %s already exists. "
- "Are you sure you want to overwrite it?");
-
- /* if user says cancel, we should break out */
- if (!gnc_verify_dialog (NULL, FALSE, format, newfile))
- {
- return;
- }
-
- /* Whoa-ok. Blow away the previous file. */
- }
-
/* use the current session to save to file */
gnc_set_busy_cursor (NULL, TRUE);
gnc_window_show_progress(_("Exporting file..."), 0.0);
@@ -1233,17 +1236,40 @@
save_in_progress++;
new_session = qof_session_new ();
- qof_session_begin (new_session, newfile, FALSE, FALSE);
+ qof_session_begin (new_session, newfile, FALSE, TRUE, FALSE);
io_err = qof_session_get_error (new_session);
/* if file appears to be locked, ask the user ... */
- if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
+ /* If the file exists and would be clobbered, ask the user */
+ if (ERR_BACKEND_STORE_EXISTS == io_err) {
+ const char *format = _("The file %s already exists. "
+ "Are you sure you want to overwrite it?");
+
+ const char *name;
+ if ( gnc_uri_is_file_uri ( newfile ) )
+ name = gnc_uri_get_path ( newfile );
+ else
+ name = gnc_uri_normalize_uri ( newfile, FALSE );
+
+ /* if user says cancel, we should break out */
+ if (!gnc_verify_dialog (NULL, FALSE, format, name ))
+ {
+ xaccLogDisable();
+ qof_session_destroy (new_session);
+ xaccLogEnable();
+ g_free (newfile);
+ save_in_progress--;
+ return;
+ }
+ qof_session_begin (new_session, newfile, FALSE, TRUE, TRUE);
+ }
+ else if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
{
if (FALSE == show_session_error (io_err, newfile, GNC_FILE_DIALOG_SAVE))
{
/* user told us to ignore locks. So ignore them. */
- qof_session_begin (new_session, newfile, TRUE, FALSE);
+ qof_session_begin (new_session, newfile, TRUE, FALSE, FALSE);
}
}
@@ -1255,7 +1281,7 @@
if (FALSE == show_session_error (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);
+ qof_session_begin (new_session, newfile, FALSE, TRUE, FALSE);
}
}
@@ -1275,26 +1301,6 @@
return;
}
- /* oops ... file already exists ... ask user what to do... */
- if (qof_session_save_may_clobber_data (new_session))
- {
- const char *format = _("The file %s already exists. "
- "Are you sure you want to overwrite it?");
-
- /* if user says cancel, we should break out */
- if (!gnc_verify_dialog (NULL, FALSE, format, newfile))
- {
- xaccLogDisable();
- qof_session_destroy (new_session);
- xaccLogEnable();
- g_free (newfile);
- save_in_progress--;
- return;
- }
-
- /* Whoa-ok. Blow away the previous file. */
- }
-
/* If the new "file" is a database, attempt to store the password
* in a keyring. GnuCash itself will not save it.
*/
@@ -1349,8 +1355,8 @@
session = NULL;
xaccReopenLog();
- gnc_add_history (session);
- gnc_hook_run(HOOK_BOOK_SAVED, session);
+ gnc_add_history (new_session);
+ gnc_hook_run(HOOK_BOOK_SAVED, new_session);
}
/* --------------- END CORE SESSION CODE -------------- */
Modified: gnucash/trunk/src/libqof/qof/qofbackend-p.h
===================================================================
--- gnucash/trunk/src/libqof/qof/qofbackend-p.h 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/libqof/qof/qofbackend-p.h 2010-11-11 06:12:20 UTC (rev 19798)
@@ -298,7 +298,8 @@
QofSession *session,
const char *book_id,
gboolean ignore_lock,
- gboolean create_if_nonexistent);
+ gboolean create,
+ gboolean force);
void (*session_end) (QofBackend *);
void (*destroy_backend) (/*@ only @*/ QofBackend *);
@@ -325,20 +326,6 @@
QofBackendProvider *provider;
- /** Detect if the sync operation will overwrite data
- *
- * File based backends tend to consider the original file
- * as 'stale' immediately the data finishes loading. New data
- * only exists in memory and the data in the file is completely
- * replaced when qof_session_save is called. e.g. this routine can be
- * used to detect if a Save As... operation would overwrite a
- * possibly unrelated file. Not all file backends use this function.
- *
- * @return TRUE if the user may need to be warned about possible
- * data loss, otherwise FALSE.
- */
- gboolean (*save_may_clobber_data) (QofBackend *);
-
QofBackendError last_err;
char * error_msg;
Modified: gnucash/trunk/src/libqof/qof/qofbackend.h
===================================================================
--- gnucash/trunk/src/libqof/qof/qofbackend.h 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/libqof/qof/qofbackend.h 2010-11-11 06:12:20 UTC (rev 19798)
@@ -62,6 +62,7 @@
ERR_BACKEND_CANT_CONNECT, /**< bad dbname/login/passwd or network failure */
ERR_BACKEND_CONN_LOST, /**< Lost connection to server */
ERR_BACKEND_LOCKED, /**< in use by another user (ETXTBSY) */
+ ERR_BACKEND_STORE_EXISTS, /**< File exists, data would be destroyed */
ERR_BACKEND_READONLY, /**< cannot write to file/directory */
ERR_BACKEND_TOO_NEW, /**< file/db version newer than what we can read */
ERR_BACKEND_DATA_CORRUPT, /**< data in db is corrupt */
Modified: gnucash/trunk/src/libqof/qof/qofsession.c
===================================================================
--- gnucash/trunk/src/libqof/qof/qofsession.c 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/libqof/qof/qofsession.c 2010-11-11 06:12:20 UTC (rev 19798)
@@ -1098,7 +1098,7 @@
void
qof_session_begin (QofSession *session, const char * book_id,
- gboolean ignore_lock, gboolean create_if_nonexistent)
+ gboolean ignore_lock, gboolean create, gboolean force)
{
gchar **splituri;
@@ -1163,7 +1163,7 @@
(session->backend->session_begin)(session->backend, session,
session->book_id, ignore_lock,
- create_if_nonexistent);
+ create, force);
PINFO("Done running session_begin on backend");
err = qof_backend_get_error(session->backend);
msg = qof_backend_get_message(session->backend);
@@ -1277,16 +1277,6 @@
/* ====================================================================== */
-gboolean
-qof_session_save_may_clobber_data (const QofSession *session)
-{
- if (!session) return FALSE;
- if (!session->backend) return FALSE;
- if (!session->backend->save_may_clobber_data) return FALSE;
-
- return (*(session->backend->save_may_clobber_data)) (session->backend);
-}
-
static gboolean
save_error_handler(QofBackend *be, QofSession *session)
{
@@ -1373,11 +1363,11 @@
{
/* Call begin - backend has been changed,
so make sure a file can be written,
- use ignore_lock and create_if_nonexistent */
+ use ignore_lock and force create */
g_free(session->book_id);
session->book_id = NULL;
(session->backend->session_begin)(session->backend, session,
- book_id, TRUE, TRUE);
+ book_id, TRUE, TRUE, TRUE);
PINFO("Done running session_begin on changed backend");
err = qof_backend_get_error(session->backend);
msg = qof_backend_get_message(session->backend);
Modified: gnucash/trunk/src/libqof/qof/qofsession.h
===================================================================
--- gnucash/trunk/src/libqof/qof/qofsession.h 2010-11-10 19:59:36 UTC (rev 19797)
+++ gnucash/trunk/src/libqof/qof/qofsession.h 2010-11-11 06:12:20 UTC (rev 19798)
@@ -131,20 +131,25 @@
* obeyed.
*
* 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 multi-user datastores
- * (e.g. the SQL backend) typically will not need to get a global
- * lock, and thus, the user will not be locked out. That's the
- * whole point of 'multi-user'.
+ * 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.
*
- * If the file/database doesn't exist, and the create_if_nonexistent
- * flag is set to TRUE, then the database is created.
+ * 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.
*
* 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,
- gboolean ignore_lock, gboolean create_if_nonexistent);
+ gboolean ignore_lock, gboolean create,
+ gboolean force);
/**
@@ -221,9 +226,6 @@
/* gboolean qof_session_not_saved(const QofSession *session); <- unimplemented */
gboolean qof_session_save_in_progress(const QofSession *session);
-/** Allows the backend to warn the user if a dataset already exists. */
-gboolean qof_session_save_may_clobber_data (const QofSession *session);
-
/** The qof_session_save() method will commit all changes that have been
* made to the session. For the file backend, this is nothing
* more than a write to the file of the current Accounts & etc.
More information about the gnucash-changes
mailing list