xact metadata searches get passed up to the entry
That is, if a metadata tag cannot be found in a transaction, look in the parent entry to see if it was set there. Transactions "inherit" notational details from their entries.
This commit is contained in:
parent
67d63366cb
commit
ee5e0600aa
5 changed files with 108 additions and 42 deletions
94
src/item.cc
94
src/item.cc
|
|
@ -37,18 +37,61 @@ bool item_t::use_effective_date = false;
|
|||
|
||||
bool item_t::has_tag(const string& tag) const
|
||||
{
|
||||
if (! metadata)
|
||||
DEBUG("item.meta", "Checking if item has tag: " << tag);
|
||||
if (! metadata) {
|
||||
DEBUG("item.meta", "Item has no metadata at all");
|
||||
return false;
|
||||
}
|
||||
string_map::const_iterator i = metadata->find(tag);
|
||||
if (SHOW_DEBUG("item.meta")) {
|
||||
if (i == metadata->end())
|
||||
DEBUG("item.meta", "Item does not have this tag");
|
||||
else
|
||||
DEBUG("item.meta", "Item has the tag!");
|
||||
}
|
||||
return i != metadata->end();
|
||||
}
|
||||
|
||||
bool item_t::has_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask) const
|
||||
{
|
||||
if (metadata) {
|
||||
foreach (const string_map::value_type& data, *metadata) {
|
||||
if (tag_mask.match(data.first)) {
|
||||
if (! value_mask)
|
||||
return true;
|
||||
else if (data.second)
|
||||
return value_mask->match(*data.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
optional<string> item_t::get_tag(const string& tag) const
|
||||
{
|
||||
DEBUG("item.meta", "Getting item tag: " << tag);
|
||||
if (metadata) {
|
||||
DEBUG("item.meta", "Item has metadata");
|
||||
string_map::const_iterator i = metadata->find(tag);
|
||||
if (i != metadata->end())
|
||||
if (i != metadata->end()) {
|
||||
DEBUG("item.meta", "Found the item!");
|
||||
return (*i).second;
|
||||
}
|
||||
}
|
||||
return none;
|
||||
}
|
||||
|
||||
optional<string> item_t::get_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask) const
|
||||
{
|
||||
if (metadata) {
|
||||
foreach (const string_map::value_type& data, *metadata) {
|
||||
if (tag_mask.match(data.first) &&
|
||||
(! value_mask ||
|
||||
(data.second && value_mask->match(*data.second))))
|
||||
return data.second;
|
||||
}
|
||||
}
|
||||
return none;
|
||||
}
|
||||
|
|
@ -146,48 +189,15 @@ namespace {
|
|||
|
||||
value_t has_tag(call_scope_t& args) {
|
||||
item_t& item(find_scope<item_t>(args));
|
||||
if (! item.metadata)
|
||||
return false;
|
||||
|
||||
IF_DEBUG("item.meta") {
|
||||
foreach (const item_t::string_map::value_type& data, *item.metadata) {
|
||||
*_log_stream << " Tag: " << data.first << "\n";
|
||||
*_log_stream << "Value: ";
|
||||
if (data.second)
|
||||
*_log_stream << *data.second << "\n";
|
||||
else
|
||||
*_log_stream << "<none>\n";
|
||||
}
|
||||
}
|
||||
|
||||
value_t& arg(args[0]);
|
||||
|
||||
if (arg.is_string()) {
|
||||
if (args.size() == 1) {
|
||||
if (args.size() == 1) {
|
||||
if (args[0].is_string())
|
||||
return item.has_tag(args[0].as_string());
|
||||
}
|
||||
else if (optional<string> tag = item.get_tag(args[0].as_string())) {
|
||||
if (args[1].is_string()) {
|
||||
return args[1].as_string() == *tag;
|
||||
}
|
||||
else if (args[1].is_mask()) {
|
||||
return args[1].as_mask().match(*tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (arg.is_mask()) {
|
||||
foreach (const item_t::string_map::value_type& data, *item.metadata) {
|
||||
if (arg.as_mask().match(data.first)) {
|
||||
if (args.size() == 1)
|
||||
return true;
|
||||
else if (data.second) {
|
||||
if (args[1].is_string())
|
||||
return args[1].as_string() == *data.second;
|
||||
else if (args[1].is_mask())
|
||||
return args[1].as_mask().match(*data.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args[0].is_mask())
|
||||
return item.has_tag(args[0].as_mask());
|
||||
} else {
|
||||
return item.has_tag(args[0].to_mask(),
|
||||
args[1].to_mask());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,9 +120,16 @@ public:
|
|||
}
|
||||
|
||||
virtual bool has_tag(const string& tag) const;
|
||||
virtual bool has_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask = none) const;
|
||||
|
||||
virtual optional<string> get_tag(const string& tag) const;
|
||||
virtual optional<string> get_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask = none) const;
|
||||
|
||||
virtual void set_tag(const string& tag,
|
||||
const optional<string>& value = none);
|
||||
|
||||
virtual void parse_tags(const char * p, int current_year = -1);
|
||||
virtual void append_note(const char * p, int current_year = -1);
|
||||
|
||||
|
|
|
|||
|
|
@ -943,6 +943,9 @@ void value_t::in_place_cast(type_t cast_type)
|
|||
case AMOUNT:
|
||||
set_amount(amount_t(as_string()));
|
||||
return;
|
||||
case MASK:
|
||||
set_mask(as_string());
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
38
src/xact.cc
38
src/xact.cc
|
|
@ -36,6 +36,44 @@
|
|||
|
||||
namespace ledger {
|
||||
|
||||
bool xact_t::has_tag(const string& tag) const
|
||||
{
|
||||
if (item_t::has_tag(tag))
|
||||
return true;
|
||||
if (entry)
|
||||
return entry->has_tag(tag);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool xact_t::has_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask) const
|
||||
{
|
||||
if (item_t::has_tag(tag_mask, value_mask))
|
||||
return true;
|
||||
if (entry)
|
||||
return entry->has_tag(tag_mask, value_mask);
|
||||
return false;
|
||||
}
|
||||
|
||||
optional<string> xact_t::get_tag(const string& tag) const
|
||||
{
|
||||
if (optional<string> value = item_t::get_tag(tag))
|
||||
return value;
|
||||
if (entry)
|
||||
return entry->get_tag(tag);
|
||||
return none;
|
||||
}
|
||||
|
||||
optional<string> xact_t::get_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask) const
|
||||
{
|
||||
if (optional<string> value = item_t::get_tag(tag_mask, value_mask))
|
||||
return value;
|
||||
if (entry)
|
||||
return entry->get_tag(tag_mask, value_mask);
|
||||
return none;
|
||||
}
|
||||
|
||||
date_t xact_t::date() const
|
||||
{
|
||||
if (item_t::use_effective_date) {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,14 @@ public:
|
|||
TRACE_DTOR(xact_t);
|
||||
}
|
||||
|
||||
virtual bool has_tag(const string& tag) const;
|
||||
virtual bool has_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask = none) const;
|
||||
|
||||
virtual optional<string> get_tag(const string& tag) const;
|
||||
virtual optional<string> get_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask = none) const;
|
||||
|
||||
virtual date_t date() const;
|
||||
virtual optional<date_t> effective_date() const;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue