Improved the way account temporaries are managed

This commit is contained in:
John Wiegley 2009-11-01 21:14:05 -05:00
parent 48f024a42a
commit 6b6ca6d4c7
4 changed files with 54 additions and 17 deletions

View file

@ -42,10 +42,9 @@ account_t::~account_t()
{
TRACE_DTOR(account_t);
foreach (accounts_map::value_type& pair, accounts) {
assert(! pair.second->has_flags(ACCOUNT_TEMP));
checked_delete(pair.second);
}
foreach (accounts_map::value_type& pair, accounts)
if (! pair.second->has_flags(ACCOUNT_TEMP))
checked_delete(pair.second);
}
account_t * account_t::find_account(const string& name,

View file

@ -133,6 +133,40 @@ void sort_posts::post_accumulated_posts()
posts.clear();
}
namespace {
void split_string(const string& str, const char ch,
std::list<string>& strings)
{
const char * b = str.c_str();
for (const char * p = b; *p; p++) {
if (*p == ch) {
strings.push_back(string(b, p - b));
b = p + 1;
}
}
strings.push_back(string(b));
}
account_t * create_temp_account_from_path(std::list<string>& account_names,
temporaries_t& temps,
account_t * master)
{
account_t * new_account = NULL;
foreach (const string& name, account_names) {
if (new_account) {
new_account = new_account->find_account(name);
} else {
new_account = master->find_account(name, false);
if (! new_account)
new_account = &temps.create_account(name, master);
}
}
assert(new_account != NULL);
return new_account;
}
}
void anonymize_posts::operator()(post_t& post)
{
SHA1 sha;
@ -158,27 +192,19 @@ void anonymize_posts::operator()(post_t& post)
}
std::list<string> account_names;
account_t * new_account = NULL;
for (account_t * acct = post.account;
acct;
acct = acct->parent) {
if (! acct->parent) {
new_account = acct;
break;
}
sha.Reset();
sha << acct->name.c_str();
sha.Result(message_digest);
account_names.push_front(to_hex(message_digest));
}
assert(new_account);
foreach (const string& name, account_names)
new_account = new_account->find_account(name);
account_t * new_account =
create_temp_account_from_path(account_names, temps, xact.journal->master);
post_t& temp = temps.copy_post(post, xact, new_account);
temp.note = none;
@ -685,11 +711,15 @@ void transfer_details::operator()(post_t& post)
case SET_PAYEE:
xact.payee = expr.calc(bound_scope).to_string();
break;
case SET_ACCOUNT:
case SET_ACCOUNT: {
std::list<string> account_names;
temp.account->remove_post(&temp);
temp.account = master->find_account(expr.calc(bound_scope).to_string());
split_string(expr.calc(bound_scope).to_string(), ':', account_names);
temp.account = create_temp_account_from_path(account_names, temps,
xact.journal->master);
temp.account->add_post(&temp);
break;
}
default:
assert(false);
break;

View file

@ -48,6 +48,11 @@ temporaries_t::~temporaries_t()
if (! post.account->has_flags(ACCOUNT_TEMP))
post.account->remove_post(&post);
}
foreach (account_t& acct, *acct_temps) {
if (! acct.has_flags(ACCOUNT_TEMP))
acct.remove_account(&acct);
}
}
}
@ -120,6 +125,9 @@ account_t& temporaries_t::create_account(const string& name,
acct_temps->push_back(account_t(parent, name));
account_t& temp(acct_temps->back());
if (parent)
parent->add_account(&temp);
temp.add_flags(ACCOUNT_TEMP);
return temp;
}

View file

@ -68,7 +68,7 @@ public:
post_t& last_post() {
return post_temps->back();
}
account_t& create_account(const string& name,
account_t& create_account(const string& name = "",
account_t * parent = NULL);
account_t& last_account() {
return acct_temps->back();