r21841 - gnucash/branches/2.4/src - [r21832][Bug 666329] - Empty database after a little while

John Ralls jralls at code.gnucash.org
Tue Jan 10 18:29:05 EST 2012


Author: jralls
Date: 2012-01-10 18:29:05 -0500 (Tue, 10 Jan 2012)
New Revision: 21841
Trac: http://svn.gnucash.org/trac/changeset/21841

Modified:
   gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c
   gnucash/branches/2.4/src/backend/xml/gnc-backend-xml.c
   gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c
   gnucash/branches/2.4/src/gnome-utils/gnc-file.c
   gnucash/branches/2.4/src/gnome-utils/gnc-main-window.c
   gnucash/branches/2.4/src/import-export/aqbanking/gnc-ab-kvp.c
   gnucash/branches/2.4/src/libqof/qof/qofbook.c
   gnucash/branches/2.4/src/libqof/qof/qofbook.h
Log:
[r21832][Bug 666329] - Empty database after a little while

Separate the two uses of QofBook::dirty -- indicating that the book object
itself has been edited and indicating that some object in the dataset has
been changed -- into two separate variables with separate getters & setters.

The latter purpose, indicating that some object has been changed, is moved
to a new member variable of QofBook, session_dirty. Its new setter
qof_book_mark_session_dirty() and canceler qof_book_mark_session_saved()
are called only from the xml backend or gnc-autosave(). Its tester,
qof_book_session_not_saved() is used to check for the need to autosave
and to activate FileSaveAction.

Modified: gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c
===================================================================
--- gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c	2012-01-10 23:29:05 UTC (rev 21841)
@@ -270,8 +270,10 @@
 
     be->loading = FALSE;
 
-    // Mark the book as clean
-    qof_book_mark_saved( book );
+    /* Mark the sessoion as clean -- though it should never be marked
+     * dirty with this backend
+     */
+    qof_book_mark_session_saved( book );
     finish_progress( be );
 
     LEAVE( "" );
@@ -545,8 +547,10 @@
     {
         be->is_pristine_db = FALSE;
 
-        // Mark the book as clean
-        qof_book_mark_saved( book );
+        /* Mark the session as clean -- though it shouldn't ever get
+	 * marked dirty with this backend
+	 */
+        qof_book_mark_session_saved( book );
     }
     else
     {
@@ -631,8 +635,8 @@
     // The engine has a PriceDB object but it isn't in the database
     if ( strcmp( inst->e_type, "PriceDB" ) == 0 )
     {
+        qof_book_mark_session_saved( be->book );
         qof_instance_mark_clean( inst );
-        qof_book_mark_saved( be->primary_book );
         return;
     }
 
@@ -672,7 +676,7 @@
         (void)gnc_sql_connection_rollback_transaction( be->conn );
 
         // Don't let unknown items still mark the book as being dirty
-        qof_book_mark_saved( be->primary_book );
+        qof_book_mark_session_saved( be->book );
         qof_instance_mark_clean(inst);
         LEAVE( "Rolled back - unknown object type" );
         return;
@@ -689,7 +693,7 @@
 
     (void)gnc_sql_connection_commit_transaction( be->conn );
 
-    qof_book_mark_saved( be->primary_book );
+    qof_book_mark_session_saved( be->book );
     qof_instance_mark_clean(inst);
 
     LEAVE( "" );

Modified: gnucash/branches/2.4/src/backend/xml/gnc-backend-xml.c
===================================================================
--- gnucash/branches/2.4/src/backend/xml/gnc-backend-xml.c	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/backend/xml/gnc-backend-xml.c	2012-01-10 23:29:05 UTC (rev 21841)
@@ -655,7 +655,7 @@
 
     /* If the book is 'clean', recently saved, then don't save again. */
     /* XXX this is currently broken due to faulty 'Save As' logic. */
-    /* if (FALSE == qof_book_not_saved (book)) return FALSE; */
+    /* if (FALSE == qof_book_session_not_saved (book)) return FALSE; */
 
     tmp_name = g_new(char, strlen(datafile) + 12);
     strcpy(tmp_name, datafile);
@@ -757,7 +757,7 @@
 
         /* Since we successfully saved the book,
          * we should mark it clean. */
-        qof_book_mark_saved (book);
+        qof_book_mark_session_saved (book);
         LEAVE (" successful save of book=%p to file=%s", book, datafile);
         return TRUE;
     }
@@ -1019,7 +1019,7 @@
             !(qof_instance_get_infant(inst) && qof_instance_get_destroying(inst)))
     {
         qof_collection_mark_dirty(qof_instance_get_collection(inst));
-        qof_book_mark_dirty(qof_instance_get_book(inst));
+        qof_book_mark_session_dirty(qof_instance_get_book(inst));
     }
 #if BORKEN_FOR_NOW
     FileBackend *fbe = (FileBackend *) be;
@@ -1111,7 +1111,7 @@
     }
 
     /* We just got done loading, it can't possibly be dirty !! */
-    qof_book_mark_saved (book);
+    qof_book_mark_session_saved (book);
 }
 
 /* ---------------------------------------------------------------------- */

Modified: gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c
===================================================================
--- gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c	2012-01-10 23:29:05 UTC (rev 21841)
@@ -783,8 +783,8 @@
 
     xaccEnableDataScrubbing();
 
-    /* Mark the book as saved */
-    qof_book_mark_saved (book);
+    /* Mark the session as saved */
+    qof_book_mark_session_saved (book);
 
     /* Call individual scrub functions */
     memset(&be_data, 0, sizeof(be_data));

Modified: gnucash/branches/2.4/src/gnome-utils/gnc-file.c
===================================================================
--- gnucash/branches/2.4/src/gnome-utils/gnc-file.c	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/gnome-utils/gnc-file.c	2012-01-10 23:29:05 UTC (rev 21841)
@@ -551,7 +551,7 @@
      * up the file-selection dialog, we don't blow him out of the water;
      * instead, give them another chance to say "no" to the verify box.
      */
-    while (qof_book_not_saved(current_book))
+    while (qof_book_session_not_saved(current_book))
     {
         GtkWidget *dialog;
         gint response;
@@ -567,7 +567,7 @@
                                         GTK_MESSAGE_QUESTION,
                                         GTK_BUTTONS_NONE,
                                         "%s", title);
-        oldest_change = qof_book_get_dirty_time(current_book);
+        oldest_change = qof_book_get_session_dirty_time(current_book);
         minutes = (time(NULL) - oldest_change) / 60 + 1;
         gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
                 message, minutes);

Modified: gnucash/branches/2.4/src/gnome-utils/gnc-main-window.c
===================================================================
--- gnucash/branches/2.4/src/gnome-utils/gnc-main-window.c	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/gnome-utils/gnc-main-window.c	2012-01-10 23:29:05 UTC (rev 21841)
@@ -1150,7 +1150,7 @@
                                     GTK_BUTTONS_NONE,
                                     title,
                                     filename);
-    oldest_change = qof_book_get_dirty_time(book);
+    oldest_change = qof_book_get_session_dirty_time(book);
     minutes = (time(NULL) - oldest_change) / 60 + 1;
     hours = minutes / 60;
     minutes = minutes % 60;
@@ -1187,7 +1187,7 @@
         return FALSE;
 
     case GTK_RESPONSE_CLOSE:
-        qof_book_mark_saved(book);
+        qof_book_mark_session_saved(book);
         return FALSE;
 
     default:
@@ -1242,7 +1242,7 @@
     gboolean needs_save, do_shutdown;
 
     session = gnc_get_current_session();
-    needs_save = qof_book_not_saved(qof_session_get_book(session)) &&
+    needs_save = qof_book_session_not_saved(qof_session_get_book(session)) &&
                  !gnc_file_save_in_progress();
     do_shutdown = !needs_save ||
                   (needs_save && !gnc_main_window_prompt_for_save(GTK_WIDGET(window)));
@@ -1372,7 +1372,7 @@
     {
         book_id = qof_session_get_url (gnc_get_current_session ());
         book = gnc_get_current_book();
-        if (qof_instance_is_dirty(QOF_INSTANCE(book)))
+        if (qof_book_session_not_saved (book))
         {
             dirty = "*";
             if (action != NULL)
@@ -3407,7 +3407,7 @@
         return TRUE;
     }
     session = gnc_get_current_session();
-    needs_save = qof_book_not_saved(qof_session_get_book(session)) &&
+    needs_save = qof_book_session_not_saved(qof_session_get_book(session)) &&
                  !gnc_file_save_in_progress();
     if (needs_save && gnc_main_window_prompt_for_save(GTK_WIDGET(window)))
         return TRUE;

Modified: gnucash/branches/2.4/src/import-export/aqbanking/gnc-ab-kvp.c
===================================================================
--- gnucash/branches/2.4/src/import-export/aqbanking/gnc-ab-kvp.c	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/import-export/aqbanking/gnc-ab-kvp.c	2012-01-10 23:29:05 UTC (rev 21841)
@@ -133,10 +133,8 @@
 {
     kvp_frame *frame = gnc_ab_get_book_kvp(b, TRUE);
     kvp_value *value = kvp_value_new_glist_nc(template_list);
-    qof_book_begin_edit(b);
     kvp_frame_set_slot_nc(frame, AB_TEMPLATES, value);
-    qof_book_mark_dirty(b);
-    qof_book_commit_edit(b);
+    qof_book_kvp_changed (b);
 }
 
 static kvp_frame *

Modified: gnucash/branches/2.4/src/libqof/qof/qofbook.c
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qofbook.c	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/libqof/qof/qofbook.c	2012-01-10 23:29:05 UTC (rev 21841)
@@ -77,6 +77,7 @@
 
     book->book_open = 'y';
     book->read_only = FALSE;
+    book->session_dirty = FALSE;
     book->version = 0;
 }
 
@@ -166,41 +167,35 @@
 /* ====================================================================== */
 
 gboolean
-qof_book_not_saved (const QofBook *book)
+qof_book_session_not_saved (const QofBook *book)
 {
     if (!book) return FALSE;
+    return book->session_dirty;
 
-    return(qof_instance_get_dirty_flag(book) || qof_object_is_dirty(book));
 }
 
 void
-qof_book_mark_saved (QofBook *book)
+qof_book_mark_session_saved (QofBook *book)
 {
-    gboolean was_dirty;
-
     if (!book) return;
 
-    was_dirty = qof_instance_get_dirty_flag(book);
-    qof_instance_set_dirty_flag(book, FALSE);
     book->dirty_time = 0;
-    qof_object_mark_clean (book);
-    if (was_dirty)
+    if (book->session_dirty)
     {
+/* Set the session clean upfront, because the callback will check. */
+	book->session_dirty = FALSE;
         if (book->dirty_cb)
             book->dirty_cb(book, FALSE, book->dirty_data);
     }
 }
 
-void qof_book_mark_dirty (QofBook *book)
+void qof_book_mark_session_dirty (QofBook *book)
 {
-    gboolean was_dirty;
-
     if (!book) return;
-
-    was_dirty = qof_instance_get_dirty_flag(book);
-    qof_instance_set_dirty_flag(book, TRUE);
-    if (!was_dirty)
+    if (!book->session_dirty)
     {
+/* Set the session dirty upfront, because the callback will check. */
+	book->session_dirty = TRUE;
         book->dirty_time = time(NULL);
         if (book->dirty_cb)
             book->dirty_cb(book, TRUE, book->dirty_data);
@@ -217,7 +212,7 @@
 }
 
 time_t
-qof_book_get_dirty_time (const QofBook *book)
+qof_book_get_session_dirty_time (const QofBook *book)
 {
     return book->dirty_time;
 }
@@ -264,7 +259,7 @@
 void qof_book_kvp_changed (QofBook *book)
 {
     qof_book_begin_edit(book);
-    qof_book_mark_dirty(book);
+    qof_instance_set_dirty (QOF_INSTANCE (book));
     qof_book_commit_edit(book);
 }
 
@@ -489,7 +484,7 @@
     value = kvp_value_new_gint64 (counter);
     kvp_frame_set_slot_path (kvp, value, "counters", counter_name, NULL);
     kvp_value_delete (value);
-    qof_book_mark_dirty(book);
+    qof_instance_set_dirty (QOF_INSTANCE (book));
     qof_book_commit_edit(book);
 
     format = qof_book_get_counter_format(book, counter_name);
@@ -705,7 +700,7 @@
 {
     qof_book_begin_edit(book);
     kvp_frame_set_string(qof_book_get_slots(book), opt_name, opt_val);
-    qof_book_mark_dirty(book);
+    qof_instance_set_dirty (QOF_INSTANCE (book));
     qof_book_commit_edit(book);
 }
 

Modified: gnucash/branches/2.4/src/libqof/qof/qofbook.h
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qofbook.h	2012-01-10 21:34:56 UTC (rev 21840)
+++ gnucash/branches/2.4/src/libqof/qof/qofbook.h	2012-01-10 23:29:05 UTC (rev 21841)
@@ -69,8 +69,18 @@
 {
     QofInstance   inst;     /* Unique guid for this book. */
 
+    /* Boolean indicates that the session is dirty -- that is, it has
+     * not yet been written out to disk after the last time the
+     * backend ran commit_edit(). This is distinct from the inherited
+     * QofInstance::dirty, which indicates that some persisitent
+     * property of the book object itself has been edited and not
+     * committed. Some backends write data out as part of
+     * commit_edit() and so don't use this flag.
+     */
+    gboolean session_dirty;
+
     /* The time when the book was first dirtied.  This is a secondary
-     * indicator. It should only be used when inst.dirty is TRUE. */
+     * indicator. It should only be used when session_saved is FALSE. */
     time_t dirty_time;
 
     /* This callback function is called any time the book dirty flag
@@ -97,7 +107,7 @@
     GHashTable *data_table_finalizers;
 
     /* Boolean indicates whether book is safe to write to (true means
-     * that it isn't. The usual reason will be a database version
+     * that it isn't). The usual reason will be a database version
      * mismatch with the running instance of Gnucash.
      */
     gboolean read_only;
@@ -241,15 +251,14 @@
 /** Is the book shutting down? */
 gboolean qof_book_shutting_down (const QofBook *book);
 
-/** qof_book_not_saved() will return TRUE if any
- *    data in the book hasn't been saved to long-term storage.
- *    (Actually, that's not quite true.  The book doesn't know
- *    anything about saving.  Its just that whenever data is modified,
- *    the 'dirty' flag is set.  This routine returns the value of the
- *    'dirty' flag.  Its up to the backend to periodically reset this
- *    flag, when it actually does save the data.)
+/** qof_book_not_saved() returns the value of the session_dirty flag,
+ * set when changes to any object in the book are committed
+ * (qof_backend->commit_edit has been called) and the backend hasn't
+ * yet written out the changes. (Note that SQL backends write commits
+ * out immediately; file backends don't, and use the flag to control
+ * an autosave timer.)
  */
-gboolean qof_book_not_saved (const QofBook *book);
+gboolean qof_book_session_not_saved (const QofBook *book);
 
 /* The following functions are not useful in scripting languages */
 #ifndef SWIG
@@ -259,13 +268,13 @@
  *    notsaved flag as FALSE just after loading.  Can also be used
  *    by the frontend when the used has said to abandon any changes.
  */
-void qof_book_mark_saved(QofBook *book);
+void qof_book_mark_session_saved(QofBook *book);
 
 /** The qof_book_mark_dirty() routine marks the book as having been
  *    modified. It can be used by frontend when the used has made a
  *    change at the book level.
  */
-void qof_book_mark_dirty(QofBook *book);
+void qof_book_mark_session_dirty(QofBook *book);
 
 /** This debugging function can be used to traverse the book structure
  *    and all subsidiary structures, printing out which structures
@@ -274,7 +283,7 @@
 void qof_book_print_dirty (const QofBook *book);
 
 /** Retrieve the earliest modification time on the book. */
-time_t qof_book_get_dirty_time(const QofBook *book);
+time_t qof_book_get_session_dirty_time(const QofBook *book);
 
 /** Set the function to call when a book transitions from clean to
  *    dirty, or vice versa.



More information about the gnucash-changes mailing list