diff --git a/src/engine/Account.c b/src/engine/Account.c index d3342f5e16..205b72d70a 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -108,6 +108,7 @@ xaccInitAccount (Account * acc) acc->splits = NULL; + acc->version = 0; acc->editlevel = 0; acc->balance_dirty = FALSE; acc->sort_dirty = FALSE; @@ -224,6 +225,7 @@ xaccFreeAccount (Account *acc) acc->currency = NULL; acc->security = NULL; + acc->version = 0; acc->editlevel = 0; acc->balance_dirty = FALSE; acc->sort_dirty = FALSE; @@ -350,6 +352,21 @@ xaccAccountDestroy (Account *acc) xaccAccountCommitEdit (acc); } + +void +xaccAccountSetVersion (Account *acc, gint32 vers) +{ + if (!acc) return; + acc->version = vers; +} + +gint32 +xaccAccountGetVersion (Account *acc) +{ + if (!acc) return 0; + return (acc->version); +} + /********************************************************************\ \********************************************************************/ diff --git a/src/engine/AccountP.h b/src/engine/AccountP.h index 9e7deb5241..82b4b94841 100644 --- a/src/engine/AccountP.h +++ b/src/engine/AccountP.h @@ -124,15 +124,18 @@ struct _account { gnc_numeric share_cleared_balance; gnc_numeric share_reconciled_balance; + /* version number, used for tracking multiuser updates */ + gint32 version; + GList *splits; /* list of split pointers */ /* keep track of nesting level of begin/end edit calls */ gint32 editlevel; - gboolean balance_dirty; - gboolean sort_dirty; + gboolean balance_dirty; /* balances in splits incorrect */ + gboolean sort_dirty; /* sort order of splits is bad */ gboolean core_dirty; /* fields in this struct have changed */ - gboolean do_free; + gboolean do_free; /* in process of being destroyed */ /* The "mark" flag can be used by the user to mark this account * in any way desired. Handy for specialty traversals of the @@ -187,4 +190,13 @@ void xaccAccountSetStartingBalance(Account *account, */ void xaccFreeAccount (Account *account); + +/* The xaccAccountSet/GetVersion() routines set & get the version + * numbers on this account. The version number is used to manage + * multi-user updates. These routines are private because we don't + * want anyone except the backend to mess with them. + */ +void xaccAccountSetVersion (Account*, gint32); +gint32 xaccAccountGetVersion (Account*); + #endif /* __XACC_ACCOUNT_P_H__ */ diff --git a/src/engine/Backend.c b/src/engine/Backend.c index f68efa6668..e5ceb3e3b2 100644 --- a/src/engine/Backend.c +++ b/src/engine/Backend.c @@ -139,8 +139,15 @@ xaccGroupSetBackend (AccountGroup *grp, Backend *be) Backend * xaccGroupGetBackend (AccountGroup *grp) { - if (!grp) return NULL; - return (grp->backend); + while (grp) + { + Account *parent; + if (grp->backend) return (grp->backend); + parent = grp->parent; + if (!parent) return NULL; + grp = parent->parent; + } + return NULL; } /************************* END OF FILE ********************************/ diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 911d23a577..d7ceeb6304 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -48,7 +48,7 @@ libgncengine_la_SOURCES = \ Query-xml-parser-v1.c \ Transaction-xml-parser-v1.c -libgncengine_la_LDFLAGS = -version-info 2:1:1 +libgncengine_la_LDFLAGS = -version-info 2:3:1 noinst_HEADERS = \ Account.h \ diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 7de5ed2fbb..1d73c510ab 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -583,6 +583,7 @@ xaccInitTransaction (Transaction * trans) trans->date_posted.tv_sec = 0; trans->date_posted.tv_nsec = 0; + trans->version = 0; trans->marker = 0; trans->editlevel = 0; trans->do_free = FALSE; @@ -640,6 +641,7 @@ xaccCloneTransaction (Transaction *t) trans->date_posted.tv_sec = t->date_posted.tv_sec; trans->date_posted.tv_nsec = t->date_posted.tv_nsec; + trans->version = t->version; trans->editlevel = 0; trans->do_free = FALSE; trans->orig = NULL; @@ -679,8 +681,7 @@ xaccFreeTransaction (Transaction *trans) /* just in case someone looks up freed memory ... */ trans->num = NULL; trans->description = NULL; - - trans->kvp_data = NULL; + trans->kvp_data = NULL; trans->date_entered.tv_sec = 0; trans->date_entered.tv_nsec = 0; @@ -688,6 +689,7 @@ xaccFreeTransaction (Transaction *trans) trans->date_posted.tv_sec = 0; trans->date_posted.tv_nsec = 0; + trans->version = 0; trans->editlevel = 0; trans->do_free = FALSE; @@ -1018,6 +1020,7 @@ xaccTransGetImbalance (Transaction * trans) /********************************************************************\ \********************************************************************/ + gboolean xaccIsCommonCurrency(const gnc_commodity * currency_1, const gnc_commodity * security_1, @@ -1267,7 +1270,6 @@ xaccTransBeginEdit (Transaction *trans) void xaccTransCommitEdit (Transaction *trans) { - GList *node; Split *split; Backend *be; @@ -1348,8 +1350,12 @@ xaccTransCommitEdit (Transaction *trans) "Please refresh your browser and try again.\n" "(This dialog should be a gui dialog and \n" "should check for errors)\n"); - PERR("Backend asked engine to rollback, but we don't " - "handle this case yet. Return code=%d", rc); + /* hack alert -- we should check for i/o errors from + * the backend too ... + */ + trans->editlevel++; + xaccTransRollbackEdit (trans); + return; } } @@ -1563,6 +1569,20 @@ xaccTransIsOpen (Transaction *trans) return (0 < trans->editlevel); } +void +xaccTransSetVersion (Transaction *trans, gint32 vers) +{ + if (!trans) return; + trans->version = vers; +} + +gint32 +xaccTransGetVersion (Transaction *trans) +{ + if (!trans) return 0; + return (trans->version); +} + /********************************************************************\ \********************************************************************/ diff --git a/src/engine/TransactionP.h b/src/engine/TransactionP.h index 8d9a97151a..12be5388b5 100644 --- a/src/engine/TransactionP.h +++ b/src/engine/TransactionP.h @@ -167,6 +167,9 @@ struct _transaction */ const gnc_commodity *common_currency; + /* version number, used for tracking multiuser updates */ + gint32 version; + GList * splits; /* list of splits */ /* marker is used to track the progress of transaction traversals. @@ -210,4 +213,12 @@ void xaccFreeSplit (Split *split); /* frees memory */ gnc_numeric xaccSplitsComputeValue (GList *splits, Split * skip_me, const gnc_commodity * base_currency); +/* The xaccTransSet/GetVersion() routines set & get the version + * numbers on this transaction. The version number is used to manage + * multi-user updates. These routines are private because we don't + * want anyone except the backend to mess with them. + */ +void xaccTransSetVersion (Transaction*, gint32); +gint32 xaccTransGetVersion (Transaction*); + #endif /* __XACC_TRANSACTION_P_H__ */ diff --git a/src/engine/gnc-book.c b/src/engine/gnc-book.c index 3574228abd..9a26561f3a 100644 --- a/src/engine/gnc-book.c +++ b/src/engine/gnc-book.c @@ -574,6 +574,9 @@ gnc_book_save (GNCBook *book) be = book->backend; if (be && be->sync && book->topgroup) { + /* if invoked as SaveAs(), then backend not yet set */ + xaccGroupSetBackend (book->topgroup, be); + (be->sync)(be, book->topgroup); retval = xaccBackendGetError(be);