diff options
author | John Wiegley <johnw@newartisans.com> | 2014-04-13 23:25:31 -0500 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2014-04-13 23:26:14 -0500 |
commit | 8f8a94c28e26c0b46a43e89d566c941994645de7 (patch) | |
tree | 3cbd52816734c55fb6233b9a3f7fb35cb0b36fd9 /src | |
parent | 634aa589cd97d088524ae2fb68ec6120d5e4a873 (diff) | |
download | fork-ledger-8f8a94c28e26c0b46a43e89d566c941994645de7.tar.gz fork-ledger-8f8a94c28e26c0b46a43e89d566c941994645de7.tar.bz2 fork-ledger-8f8a94c28e26c0b46a43e89d566c941994645de7.zip |
Add the concept of "deferred postings"
This is pretty much exclusively for allowing one to use balance
assertions with replicated transactions across multiple files.
Diffstat (limited to 'src')
-rw-r--r-- | src/account.cc | 15 | ||||
-rw-r--r-- | src/account.h | 17 | ||||
-rw-r--r-- | src/journal.cc | 17 | ||||
-rw-r--r-- | src/post.h | 1 | ||||
-rw-r--r-- | src/textual.cc | 6 | ||||
-rw-r--r-- | src/xact.cc | 5 |
6 files changed, 52 insertions, 9 deletions
diff --git a/src/account.cc b/src/account.cc index 4b3a4e97..a702cf11 100644 --- a/src/account.cc +++ b/src/account.cc @@ -139,6 +139,21 @@ void account_t::add_post(post_t * post) } } +void account_t::add_deferred_post(const string& uuid, post_t * post) +{ + if (! deferred_posts) + deferred_posts = deferred_posts_map_t(); + + deferred_posts_map_t::iterator i = deferred_posts->find(uuid); + if (i == deferred_posts->end()) { + posts_list lst; + lst.push_back(post); + deferred_posts->insert(deferred_posts_map_t::value_type(uuid, lst)); + } else { + (*i).second.push_back(post); + } +} + bool account_t::remove_post(post_t * post) { // It's possible that 'post' wasn't yet in this account, but try to diff --git a/src/account.h b/src/account.h index f6f764cc..3ce93fba 100644 --- a/src/account.h +++ b/src/account.h @@ -52,6 +52,7 @@ class post_t; typedef std::list<post_t *> posts_list; typedef std::map<string, account_t *> accounts_map; +typedef std::map<string, posts_list> deferred_posts_map_t; class account_t : public supports_flags<>, public scope_t { @@ -61,13 +62,14 @@ class account_t : public supports_flags<>, public scope_t #define ACCOUNT_GENERATED 0x04 // account never actually existed public: - account_t * parent; - string name; - optional<string> note; - unsigned short depth; - accounts_map accounts; - posts_list posts; - optional<expr_t> value_expr; + account_t * parent; + string name; + optional<string> note; + unsigned short depth; + accounts_map accounts; + posts_list posts; + optional<deferred_posts_map_t> deferred_posts; + optional<expr_t> value_expr; mutable string _fullname; #if DOCUMENT_MODEL @@ -136,6 +138,7 @@ public: } void add_post(post_t * post); + void add_deferred_post(const string& uuid, post_t * post); bool remove_post(post_t * post); posts_list::iterator posts_begin() { diff --git a/src/journal.cc b/src/journal.cc index ef35722c..94a535d7 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -385,9 +385,24 @@ bool journal_t::add_xact(xact_t * xact) // will have been performed by extend_xact, so asserts can still be // applied to it. if (optional<value_t> ref = xact->get_tag(_("UUID"))) { + std::string uuid = ref->to_string(); std::pair<checksum_map_t::iterator, bool> result - = checksum_map.insert(checksum_map_t::value_type(ref->to_string(), xact)); + = checksum_map.insert(checksum_map_t::value_type(uuid, xact)); if (! result.second) { + // This UUID has been seen before; apply any postings which the + // earlier version may have deferred. + foreach (post_t * post, xact->posts) { + account_t * acct = post->account; + if (acct->deferred_posts) { + deferred_posts_map_t::iterator + i = acct->deferred_posts->find(uuid); + if (i != acct->deferred_posts->end()) { + foreach (post_t * rpost, (*i).second) + acct->add_post(rpost); + } + } + } + // jww (2012-02-27): Confirm that the xact in // (*result.first).second is exact match in its significant // details to xact. @@ -60,6 +60,7 @@ public: #define POST_COST_FIXATED 0x0200 // cost is fixed using = indicator #define POST_COST_VIRTUAL 0x0400 // cost is virtualized: (@) #define POST_ANONYMIZED 0x0800 // a temporary, anonymous posting +#define POST_DEFERRED 0x1000 // the account was specified with <angles> xact_t * xact; // only set for posts of regular xacts account_t * account; diff --git a/src/textual.cc b/src/textual.cc index fa84d6de..6f8f0492 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1432,6 +1432,12 @@ post_t * instance_t::parse_post(char * line, } p++; e--; } + else if (*p == '<' && *(e - 1) == '>') { + post->add_flags(POST_DEFERRED); + DEBUG("textual.parse", "line " << context.linenum << ": " + << "Parsed a deferred account name"); + p++; e--; + } string name(p, static_cast<string::size_type>(e - p)); DEBUG("textual.parse", "line " << context.linenum << ": " diff --git a/src/xact.cc b/src/xact.cc index 58d2ac33..c7a9c6e3 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -393,7 +393,10 @@ bool xact_base_t::finalize() some_null = true; } - post->account->add_post(post); + if (post->has_flags(POST_DEFERRED)) + post->account->add_deferred_post(id(), post); + else + post->account->add_post(post); post->xdata().add_flags(POST_EXT_VISITED); post->account->xdata().add_flags(ACCOUNT_EXT_VISITED); |