r18527 - gnucash/trunk/src/engine - Free accounts/lots/splits/transactions when closing a book
Phil Longstaff
plongstaff at code.gnucash.org
Fri Dec 18 14:45:58 EST 2009
Author: plongstaff
Date: 2009-12-18 14:45:57 -0500 (Fri, 18 Dec 2009)
New Revision: 18527
Trac: http://svn.gnucash.org/trac/changeset/18527
Modified:
gnucash/trunk/src/engine/Account.c
gnucash/trunk/src/engine/Split.c
gnucash/trunk/src/engine/Transaction.c
gnucash/trunk/src/engine/gnc-lot.c
Log:
Free accounts/lots/splits/transactions when closing a book
Modified: gnucash/trunk/src/engine/Account.c
===================================================================
--- gnucash/trunk/src/engine/Account.c 2009-12-18 12:39:15 UTC (rev 18526)
+++ gnucash/trunk/src/engine/Account.c 2009-12-18 19:45:57 UTC (rev 18527)
@@ -997,6 +997,7 @@
{
AccountPrivate *priv;
GList *lp;
+ gboolean shutting_down = qof_book_shutting_down(qof_instance_get_book(acc));
g_return_if_fail(GNC_IS_ACCOUNT(acc));
@@ -1015,13 +1016,16 @@
/* remove lots -- although these should be gone by now. */
if (priv->lots)
{
- PERR (" instead of calling xaccFreeAccount(), please call \n"
- " xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
+ /* If shutting down, just drop lots - don't worry about nicities. */
+ if (!shutting_down) {
+ PERR (" instead of calling xaccFreeAccount(), please call \n"
+ " xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
- for (lp=priv->lots; lp; lp=lp->next)
- {
- GNCLot *lot = lp->data;
- gnc_lot_destroy (lot);
+ for (lp=priv->lots; lp; lp=lp->next)
+ {
+ GNCLot *lot = lp->data;
+ gnc_lot_destroy (lot);
+ }
}
g_list_free (priv->lots);
priv->lots = NULL;
@@ -1033,20 +1037,34 @@
* check once we know the warning isn't occurring any more. */
if (priv->splits)
{
- GList *slist;
- PERR (" instead of calling xaccFreeAccount(), please call \n"
- " xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
+ GList *slist = priv->splits;
+
+ /* If shutting down, just drop lots - don't worry about nicities. */
+ if (!shutting_down) {
+ PERR (" instead of calling xaccFreeAccount(), please call \n"
+ " xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
- qof_instance_reset_editlevel(acc);
+ qof_instance_reset_editlevel(acc);
- slist = g_list_copy(priv->splits);
- for (lp = slist; lp; lp = lp->next) {
- Split *s = (Split *) lp->data;
- g_assert(xaccSplitGetAccount(s) == acc);
- xaccSplitDestroy (s);
+ slist = g_list_copy(priv->splits);
+ for (lp = slist; lp; lp = lp->next) {
+ Split *s = (Split *) lp->data;
+ g_assert(xaccSplitGetAccount(s) == acc);
+ xaccSplitDestroy (s);
+ }
+ } else {
+ /* The book is being shut down. Just break the link from the split
+ to this account. */
+ for (lp = priv->splits; lp; lp = lp->next) {
+ Split *s = (Split *) lp->data;
+ s->acc = NULL;
+ s->orig_acc = NULL;
+ }
+ }
+ g_list_free(slist);
+ if (!shutting_down && priv->splits != NULL) {
+ PERR("priv->splits != NULL\n");
}
- g_list_free(slist);
- g_assert(priv->splits == NULL);
}
CACHE_REPLACE(priv->accountName, NULL);
@@ -1135,8 +1153,11 @@
{
GList *lp, *slist;
QofCollection *col;
+ gboolean shutting_down;
qof_instance_increase_editlevel(acc);
+ book = qof_instance_get_book(acc);
+ shutting_down = qof_book_shutting_down(book);
/* First, recursively free children */
xaccFreeAccountChildren(acc);
@@ -1145,10 +1166,12 @@
acc, priv->accountName ? priv->accountName : "(null)");
slist = g_list_copy(priv->splits);
- for (lp = slist; lp; lp = lp->next)
- {
- Split *s = lp->data;
- xaccSplitDestroy (s);
+ if (!shutting_down) {
+ for (lp = slist; lp; lp = lp->next)
+ {
+ Split *s = lp->data;
+ xaccSplitDestroy (s);
+ }
}
g_list_free(slist);
/* It turns out there's a case where this assertion does not hold:
@@ -1159,8 +1182,7 @@
g_assert(priv->splits == NULL || qof_book_shutting_down(acc->inst.book));
*/
- book = qof_instance_get_book(acc);
- if (!qof_book_shutting_down(book)) {
+ if (!shutting_down) {
col = qof_book_get_collection(book, GNC_ID_TRANS);
qof_collection_foreach(col, destroy_pending_splits_for_account, acc);
}
@@ -1566,8 +1588,10 @@
// And send the account-based event, too
qof_event_gen(&acc->inst, GNC_EVENT_ITEM_REMOVED, s);
- priv->balance_dirty = TRUE;
- xaccAccountRecomputeBalance(acc);
+ if (!qof_book_shutting_down(qof_instance_get_book(acc))) {
+ priv->balance_dirty = TRUE;
+ xaccAccountRecomputeBalance(acc);
+ }
return TRUE;
}
@@ -4608,6 +4632,22 @@
return xaccAccountStagedTransactionTraversal(acc, 42, proc, data);
}
+static void
+account_book_end(QofBook* book)
+{
+ QofCollection *col;
+ Account *root;
+
+ col = qof_book_get_collection (book, GNC_ID_ROOT_ACCOUNT);
+ root = gnc_coll_get_root_account (col);
+ if (root != NULL) {
+ xaccAccountBeginEdit(root);
+ xaccAccountDestroy(root);
+ }
+ col = qof_book_get_collection (book, GNC_ID_ACCOUNT);
+ printf("Accounts left: %d\n", qof_collection_count(col));
+}
+
/* ================================================================ */
/* QofObject function implementation and registration */
@@ -4617,7 +4657,7 @@
.type_label = "Account",
.create = (gpointer)xaccMallocAccount,
.book_begin = NULL,
- .book_end = NULL,
+ .book_end = account_book_end,
.is_dirty = qof_collection_is_dirty,
.mark_clean = qof_collection_mark_clean,
.foreach = qof_collection_foreach,
Modified: gnucash/trunk/src/engine/Split.c
===================================================================
--- gnucash/trunk/src/engine/Split.c 2009-12-18 12:39:15 UTC (rev 18526)
+++ gnucash/trunk/src/engine/Split.c 2009-12-18 19:45:57 UTC (rev 18527)
@@ -514,27 +514,30 @@
xaccSplitCommitEdit(Split *s)
{
Account *acc, *orig_acc;
+ gboolean shutting_down = qof_book_shutting_down(qof_instance_get_book(s));
g_return_if_fail(s);
- if (!qof_instance_is_dirty(QOF_INSTANCE(s)))
+ if (!qof_instance_is_dirty(QOF_INSTANCE(s)) && !shutting_down) {
return;
+ }
orig_acc = s->orig_acc;
acc = s->acc;
/* Remove from lot (but only if it hasn't been moved to
new lot already) */
- if (s->lot && (s->lot->account != acc || qof_instance_get_destroying(s)))
+ if (s->lot && (s->lot->account != acc || qof_instance_get_destroying(s))) {
gnc_lot_remove_split (s->lot, s);
+ }
/* Possibly remove the split from the original account... */
if (orig_acc && (orig_acc != acc || qof_instance_get_destroying(s))) {
if (!gnc_account_remove_split(orig_acc, s)) {
PERR("Account lost track of moved or deleted split.");
}
- }
+ }
/* ... and insert it into the new account if needed */
- if (acc && (orig_acc != acc) && !qof_instance_get_destroying(s)) {
+ if (acc && (orig_acc != acc) && !qof_instance_get_destroying(s) && !shutting_down) {
if (gnc_account_insert_split(acc, s)) {
/* If the split's lot belonged to some other account, we
leave it so. */
@@ -565,7 +568,7 @@
qof_commit_edit_part2(QOF_INSTANCE(s), commit_err, NULL,
(void (*) (QofInstance *)) xaccFreeSplit);
- if (acc) {
+ if (acc && !shutting_down) {
g_object_set(acc, "sort-dirty", TRUE, "balance-dirty", TRUE, NULL);
xaccAccountRecomputeBalance(acc);
}
@@ -1116,8 +1119,10 @@
acc = split->acc;
trans = split->parent;
if (acc && !qof_instance_get_destroying(acc)
- && xaccTransGetReadOnly(trans))
+ && xaccTransGetReadOnly(trans)
+ && !qof_book_shutting_down(qof_instance_get_book(split))) {
return FALSE;
+ }
xaccTransBeginEdit(trans);
ed.node = split;
Modified: gnucash/trunk/src/engine/Transaction.c
===================================================================
--- gnucash/trunk/src/engine/Transaction.c 2009-12-18 12:39:15 UTC (rev 18526)
+++ gnucash/trunk/src/engine/Transaction.c 2009-12-18 19:45:57 UTC (rev 18527)
@@ -334,6 +334,11 @@
GList *node, *new_list = NULL;
Split *split;
+ /* Don't bother if shutting down */
+ if (qof_book_shutting_down(qof_instance_get_book(trans))) {
+ return;
+ }
+
/* first debits */
for (node = trans->splits; node; node = node->next) {
split = node->data;
@@ -451,6 +456,8 @@
{
GList *node;
+ if (qof_book_shutting_down(qof_instance_get_book(trans)))
+ PINFO("xaccFreeTransaction(%p)\n", trans);
if (!trans) return;
ENTER ("(addr=%p)", trans);
@@ -957,10 +964,14 @@
{
if (!trans) return;
+ if (qof_book_shutting_down(qof_instance_get_book(trans)))
+ PINFO("xaccTransDestroy(%p)\n", trans);
if (!xaccTransGetReadOnly (trans) ||
qof_book_shutting_down(qof_instance_get_book(trans))) {
xaccTransBeginEdit(trans);
qof_instance_set_destroying(trans, TRUE);
+ if (qof_book_shutting_down(qof_instance_get_book(trans)))
+ PINFO("xaccTransDestroy(%p): set destroying\n", trans);
xaccTransCommitEdit(trans);
}
}
@@ -991,6 +1002,9 @@
SplitList *node;
gboolean shutting_down = qof_book_shutting_down(qof_instance_get_book(trans));
+ if (shutting_down)
+ PINFO("do_destroy(%p)\n", trans);
+
/* If there are capital-gains transactions associated with this,
* they need to be destroyed too. */
destroy_gains (trans);
@@ -1002,13 +1016,24 @@
qof_event_gen (&trans->inst, QOF_EVENT_DESTROY, NULL);
/* We only own the splits that still think they belong to us. */
- trans->splits = g_list_copy(trans->splits);
- for (node = trans->splits; node; node = node->next) {
- Split *s = node->data;
- if (s->parent == trans) {
- xaccSplitDestroy(s);
- xaccSplitCommitEdit(s);
+ if (shutting_down) {
+ while (trans->splits != NULL) {
+ Split* s;
+ node = g_list_first(trans->splits);
+ s = node->data;
+ trans->splits = g_list_remove_link(trans->splits, node);
+ xaccSplitDestroy(s);
+ xaccSplitCommitEdit(s);
}
+ } else {
+ // trans->splits = g_list_copy(trans->splits);
+ for (node = trans->splits; node; node = node->next) {
+ Split *s = node->data;
+ if (s->parent == trans) {
+ xaccSplitDestroy(s);
+ xaccSplitCommitEdit(s);
+ }
+ }
}
g_list_free (trans->splits);
trans->splits = NULL;
@@ -1018,7 +1043,7 @@
/********************************************************************\
\********************************************************************/
-/* Temporary hack for data consitency */
+/* Temporary hack for data consistency */
static int scrub_data = 1;
void xaccEnableDataScrubbing(void) { scrub_data = 1; }
void xaccDisableDataScrubbing(void) { scrub_data = 0; }
@@ -1126,7 +1151,7 @@
* change the number of splits in this transaction, and the
* transaction itself might be deleted. This is also why
* we can't really enforce these constraints elsewhere: they
- * can cause pointers to splits and transactions to disapear out
+ * can cause pointers to splits and transactions to disappear out
* from under the holder.
*/
if (!qof_instance_get_destroying(trans) && scrub_data &&
@@ -2013,6 +2038,42 @@
return NULL;
}
+static void
+trans_destroy(Transaction* trans)
+{
+ ENTER("trans=%p", trans);
+ xaccTransDestroy(trans);
+ LEAVE("trans=%p", trans);
+}
+
+static void
+trans_xy(Transaction* trans)
+{
+ xaccTransDestroy(trans);
+}
+
+static void
+trans_book_end(QofBook* book)
+{
+ guint old_count = 0;
+ guint count;
+
+ QofCollection *col;
+ col = qof_book_get_collection (book, GNC_ID_TRANS);
+ count = qof_collection_count(col);
+ if( count == 0 ) return;
+
+ printf( "Transactions left: %d\n", count);
+ qof_collection_foreach(col, (QofInstanceForeachCB)trans_destroy, NULL);
+ printf( "Transactions left: %d\n", count);
+ while( old_count != count ) {
+ old_count = count;
+ qof_collection_foreach(col, (QofInstanceForeachCB)trans_destroy, NULL);
+ count = qof_collection_count(col);
+ printf( "Transactions left: %d\n", count);
+ }
+}
+
/********************************************************************\
\********************************************************************/
/* QofObject function implementation */
@@ -2024,7 +2085,7 @@
.type_label = "Transaction",
.create = (gpointer)xaccMallocTransaction,
.book_begin = NULL,
- .book_end = NULL,
+ .book_end = trans_book_end,
.is_dirty = qof_collection_is_dirty,
.mark_clean = qof_collection_mark_clean,
.foreach = qof_collection_foreach,
Modified: gnucash/trunk/src/engine/gnc-lot.c
===================================================================
--- gnucash/trunk/src/engine/gnc-lot.c 2009-12-18 12:39:15 UTC (rev 18526)
+++ gnucash/trunk/src/engine/gnc-lot.c 2009-12-18 19:45:57 UTC (rev 18527)
@@ -450,8 +450,16 @@
lot_book_end(QofBook* book)
{
QofCollection *col;
+ guint count;
+
col = qof_book_get_collection (book, GNC_ID_LOT);
- qof_collection_foreach(col, (QofInstanceForeachCB)lot_destroy_book_end, NULL);
+ count = qof_collection_count(col);
+ printf( "Book end: Lots left: %d\n", count);
+ while(count > 0) {
+ qof_collection_foreach(col, (QofInstanceForeachCB)lot_destroy_book_end, NULL);
+ count = qof_collection_count(col);
+ printf( "Lots left: %d\n", count);
+ }
}
/* ============================================================= */
More information about the gnucash-changes
mailing list