Kvp no longer parses entries looking for delimiters

This commit is contained in:
lmat
2017-11-06 14:51:25 -05:00
parent 2cda65e012
commit 5636afc4a2
18 changed files with 212 additions and 323 deletions

View File

@@ -69,7 +69,7 @@ setup_kvp (Fixture *fixture, gconstpointer pData)
"autoreadonly-days", (double)21, "autoreadonly-days", (double)21,
NULL); NULL);
slots->set_path("options/Business/Company Name", slots->set_path({"options", "Business", "Company Name"},
new KvpValue("Bogus Company")); new KvpValue("Bogus Company"));
qof_commit_edit (QOF_INSTANCE (book)); qof_commit_edit (QOF_INSTANCE (book));
} }
@@ -120,10 +120,10 @@ test_option_save (Fixture *fixture, gconstpointer pData)
OPTION_NAME_AUTO_READONLY_DAYS, OPTION_NAME_AUTO_READONLY_DAYS,
17)); 17));
qof_book_save_options (book, gnc_option_db_save, odb, TRUE); qof_book_save_options (book, gnc_option_db_save, odb, TRUE);
g_assert_cmpstr (slots->get_slot("options/Accounts/Use Trading Accounts")->get<const char*>(), == , "t"); g_assert_cmpstr (slots->get_slot({"options", "Accounts", "Use Trading Accounts"})->get<const char*>(), == , "t");
g_assert_cmpstr (slots->get_slot("options/Accounts/Use Split Action Field for Number")->get<const char*>(), == , "t"); g_assert_cmpstr (slots->get_slot({"options", "Accounts", "Use Split Action Field for Number"})->get<const char*>(), == , "t");
g_assert_cmpstr (slots->get_slot("options/Business/Company Name")->get<const char*>(), ==, "Bogus Company"); g_assert_cmpstr (slots->get_slot({"options", "Business", "Company Name"})->get<const char*>(), ==, "Bogus Company");
g_assert_cmpfloat (slots->get_slot("options/Accounts/Day Threshold for Read-Only Transactions (red line)")->get<double>(), ==, 17); g_assert_cmpfloat (slots->get_slot({"options", "Accounts", "Day Threshold for Read-Only Transactions (red line)"})->get<double>(), ==, 17);
gnc_option_db_destroy (odb); gnc_option_db_destroy (odb);
} }

View File

@@ -132,15 +132,13 @@ setup_memory (Fixture* fixture, gconstpointer pData)
xaccAccountSetCommodity (acct1, currency); xaccAccountSetCommodity (acct1, currency);
auto frame = qof_instance_get_slots (QOF_INSTANCE (acct1)); auto frame = qof_instance_get_slots (QOF_INSTANCE (acct1));
frame->set ("int64-val", new KvpValue (INT64_C (100))); frame->set ({"int64-val"}, new KvpValue (INT64_C (100)));
frame->set ("double-val", new KvpValue (3.14159)); frame->set ({"double-val"}, new KvpValue (3.14159));
frame->set ("numeric-val", new KvpValue (gnc_numeric_zero ())); frame->set ({"numeric-val"}, new KvpValue (gnc_numeric_zero ()));
frame->set ({"timespec-val"}, new KvpValue (timespec_now ()));
frame->set ("timespec-val", new KvpValue (timespec_now ())); frame->set ({"string-val"}, new KvpValue ("abcdefghijklmnop"));
frame->set ("string-val", new KvpValue ("abcdefghijklmnop"));
auto guid = qof_instance_get_guid (QOF_INSTANCE (acct1)); auto guid = qof_instance_get_guid (QOF_INSTANCE (acct1));
frame->set ("guid-val", new KvpValue (const_cast<GncGUID*> (guid_copy ( frame->set ({"guid-val"}, new KvpValue (const_cast<GncGUID*> (guid_copy (
guid)))); guid))));
gnc_account_append_child (root, acct1); gnc_account_append_child (root, acct1);

View File

@@ -226,7 +226,7 @@ set_slot_from_value (slot_info_t* pInfo, KvpValue* pValue)
case FRAME: case FRAME:
{ {
auto key = get_key_from_path (pInfo->path); auto key = get_key_from_path (pInfo->path);
pInfo->pKvpFrame->set (key.c_str(), pValue); pInfo->pKvpFrame->set ({key.c_str()}, pValue);
break; break;
} }
case LIST: case LIST:
@@ -245,7 +245,7 @@ set_slot_from_value (slot_info_t* pInfo, KvpValue* pValue)
frame->set_path ({path.c_str(), key.c_str()}, pValue); frame->set_path ({path.c_str(), key.c_str()}, pValue);
} }
else else
frame->set (key.c_str(), pValue); frame->set ({key.c_str()}, pValue);
break; break;
} }
} }
@@ -464,7 +464,7 @@ set_guid_val (gpointer pObject, gpointer pValue)
slots_load_info (newInfo); slots_load_info (newInfo);
pValue = new KvpValue {newInfo->pList}; pValue = new KvpValue {newInfo->pList};
pInfo->pKvpFrame->set (key.c_str(), pValue); pInfo->pKvpFrame->set ({key.c_str()}, pValue);
delete newInfo; delete newInfo;
break; break;
} }
@@ -487,7 +487,7 @@ set_guid_val (gpointer pObject, gpointer pValue)
default: default:
{ {
auto key = get_key_from_path (pInfo->path); auto key = get_key_from_path (pInfo->path);
pInfo->pKvpFrame->set (key.c_str(), new KvpValue {newFrame}); pInfo->pKvpFrame->set ({key.c_str()}, new KvpValue {newFrame});
break; break;
} }
} }

View File

@@ -808,7 +808,7 @@ kvp_frame_slot_end_handler (gpointer data_for_children,
if (key_node_count != 1) return (FALSE); if (key_node_count != 1) return (FALSE);
value_cr->should_cleanup = TRUE; value_cr->should_cleanup = TRUE;
f->set (key, value); f->set ({key}, value);
if (delete_value) if (delete_value)
delete value; delete value;
return (TRUE); return (TRUE);

View File

@@ -440,7 +440,7 @@ dom_tree_to_kvp_frame_given (xmlNodePtr node, KvpFrame* frame)
if (val) if (val)
{ {
//We're deleting the old KvpValue returned by replace_nc(). //We're deleting the old KvpValue returned by replace_nc().
delete frame->set (key, val); delete frame->set ({key}, val);
} }
else else
{ {

View File

@@ -25,7 +25,7 @@ test_kvp_get_slot (int run,
KvpFrame* test_frame1, const KvpValue* test_val1, KvpFrame* test_frame1, const KvpValue* test_val1,
const gchar* test_key) const gchar* test_key)
{ {
auto test_val2 = test_frame1->get_slot (test_key); auto test_val2 = test_frame1->get_slot ({test_key});
auto msg = "KvpFrame::get_slot"; auto msg = "KvpFrame::get_slot";
if (compare (test_val1, test_val2) == 0) if (compare (test_val1, test_val2) == 0)
{ {
@@ -70,7 +70,7 @@ test_kvp_copy_get_slot (int run,
const gchar* test_key) const gchar* test_key)
{ {
auto test_frame2 = new KvpFrame (*test_frame1); auto test_frame2 = new KvpFrame (*test_frame1);
auto test_val2 = test_frame2->get_slot (test_key); auto test_val2 = test_frame2->get_slot ({test_key});
auto msg = "KvpFrame::get_slot() from a copy-constructed frame"; auto msg = "KvpFrame::get_slot() from a copy-constructed frame";
if (compare (test_val1, test_val2) == 0) if (compare (test_val1, test_val2) == 0)
{ {
@@ -114,7 +114,7 @@ test_kvp_frames1 (void)
auto test_frame1 = new KvpFrame; auto test_frame1 = new KvpFrame;
auto test_key = get_random_string_without ("/"); auto test_key = get_random_string_without ("/");
test_frame1->set (test_key, test_val1); test_frame1->set ({test_key}, test_val1);
test_kvp_get_slot (i, test_frame1, test_val1, test_key); test_kvp_get_slot (i, test_frame1, test_val1, test_key);
test_kvp_copy_compare (i, test_frame1, test_val1, test_key); test_kvp_copy_compare (i, test_frame1, test_val1, test_key);

View File

@@ -5440,7 +5440,7 @@ parse_bayes_imap_info (std::string const & imap_bayes_entry)
auto guid_start = imap_bayes_entry.size() - GUID_ENCODING_LENGTH; auto guid_start = imap_bayes_entry.size() - GUID_ENCODING_LENGTH;
std::string keyword {imap_bayes_entry.substr (header_length + 1, guid_start - header_length - 2)}; std::string keyword {imap_bayes_entry.substr (header_length + 1, guid_start - header_length - 2)};
std::string account_guid {imap_bayes_entry.substr (guid_start)}; std::string account_guid {imap_bayes_entry.substr (guid_start)};
return {header, keyword, account_guid}; return std::tuple <std::string, std::string, std::string> {header, keyword, account_guid};
} }
static void static void
@@ -5530,9 +5530,9 @@ gnc_account_delete_map_entry (Account *acc, char *full_category, gboolean empty)
{ {
xaccAccountBeginEdit (acc); xaccAccountBeginEdit (acc);
if (empty) if (empty)
qof_instance_slot_delete_if_empty (QOF_INSTANCE(acc), kvp_path); qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), {kvp_path});
else else
qof_instance_slot_delete (QOF_INSTANCE(acc), kvp_path); qof_instance_slot_path_delete (QOF_INSTANCE(acc), {kvp_path});
PINFO("Account is '%s', path is '%s'", xaccAccountGetName (acc), kvp_path); PINFO("Account is '%s', path is '%s'", xaccAccountGetName (acc), kvp_path);
qof_instance_set_dirty (QOF_INSTANCE(acc)); qof_instance_set_dirty (QOF_INSTANCE(acc));
xaccAccountCommitEdit (acc); xaccAccountCommitEdit (acc);
@@ -5620,7 +5620,7 @@ static std::vector<std::pair<std::string, KvpValue*>>
get_new_guid_imap (Account * acc) get_new_guid_imap (Account * acc)
{ {
auto frame = qof_instance_get_slots (QOF_INSTANCE (acc)); auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
auto slot = frame->get_slot (IMAP_FRAME_BAYES); auto slot = frame->get_slot ({IMAP_FRAME_BAYES});
if (!slot) if (!slot)
return {}; return {};
auto imap_frame = slot->get<KvpFrame*> (); auto imap_frame = slot->get<KvpFrame*> ();
@@ -5640,9 +5640,9 @@ convert_imap_account_bayes_to_guid (Account *acc)
return; return;
auto new_imap = get_new_guid_imap(acc); auto new_imap = get_new_guid_imap(acc);
xaccAccountBeginEdit(acc); xaccAccountBeginEdit(acc);
frame->set(IMAP_FRAME_BAYES, nullptr); frame->set({IMAP_FRAME_BAYES}, nullptr);
std::for_each(new_imap.begin(), new_imap.end(), [&frame] (std::pair<std::string, KvpValue*> const & entry) { std::for_each(new_imap.begin(), new_imap.end(), [&frame] (std::pair<std::string, KvpValue*> const & entry) {
frame->set(entry.first.c_str(), entry.second); frame->set({entry.first.c_str()}, entry.second);
}); });
qof_instance_set_dirty (QOF_INSTANCE (acc)); qof_instance_set_dirty (QOF_INSTANCE (acc));
xaccAccountCommitEdit(acc); xaccAccountCommitEdit(acc);

View File

@@ -106,13 +106,13 @@ KvpFrame*
_GncABTransTempl::make_kvp_frame() _GncABTransTempl::make_kvp_frame()
{ {
auto frame = new KvpFrame; auto frame = new KvpFrame;
frame->set(TT_NAME, new KvpValue(m_name.c_str())); frame->set({TT_NAME}, new KvpValue(m_name.c_str()));
frame->set(TT_RNAME, new KvpValue(m_recipient_name.c_str())); frame->set({TT_RNAME}, new KvpValue(m_recipient_name.c_str()));
frame->set(TT_RACC, new KvpValue(m_recipient_account.c_str())); frame->set({TT_RACC}, new KvpValue(m_recipient_account.c_str()));
frame->set(TT_RBCODE, new KvpValue(m_recipient_bankcode.c_str())); frame->set({TT_RBCODE}, new KvpValue(m_recipient_bankcode.c_str()));
frame->set(TT_AMOUNT, new KvpValue(m_amount)); frame->set({TT_AMOUNT}, new KvpValue(m_amount));
frame->set(TT_PURPOS, new KvpValue(m_purpose.c_str())); frame->set({TT_PURPOS}, new KvpValue(m_purpose.c_str()));
frame->set(TT_PURPOSCT, new KvpValue(m_purpose_continuation.c_str())); frame->set({TT_PURPOSCT}, new KvpValue(m_purpose_continuation.c_str()));
return frame; return frame;
} }
@@ -145,12 +145,12 @@ gnc_ab_trans_templ_list_new_from_book(QofBook *b)
{ {
KvpFrame *frame = static_cast<KvpValue*>(node->data)->get<KvpFrame*>(); KvpFrame *frame = static_cast<KvpValue*>(node->data)->get<KvpFrame*>();
auto c_func = [frame](const char* key) auto c_func = [frame](const char* key)
{ auto slot = frame->get_slot(key); { auto slot = frame->get_slot({key});
return slot == nullptr ? std::string("") : std::string(slot->get<const char*>());}; return slot == nullptr ? std::string("") : std::string(slot->get<const char*>());};
auto n_func = [frame](const char* key) auto n_func = [frame](const char* key)
{ auto slot = frame->get_slot(key); { auto slot = frame->get_slot({key});
return slot == nullptr ? gnc_numeric_zero() : slot->get<gnc_numeric>();}; return slot == nullptr ? gnc_numeric_zero() : slot->get<gnc_numeric>();};
auto amt_slot = frame->get_slot(TT_AMOUNT); auto amt_slot = frame->get_slot({TT_AMOUNT});
auto templ = new _GncABTransTempl (c_func(TT_NAME), c_func(TT_RNAME), auto templ = new _GncABTransTempl (c_func(TT_NAME), c_func(TT_RNAME),
c_func(TT_RACC), c_func(TT_RBCODE), c_func(TT_RACC), c_func(TT_RBCODE),
n_func(TT_AMOUNT), c_func(TT_PURPOS), n_func(TT_AMOUNT), c_func(TT_PURPOS),

View File

@@ -68,124 +68,90 @@ KvpFrameImpl::~KvpFrameImpl() noexcept
m_valuemap.clear(); m_valuemap.clear();
} }
static inline Path KvpFrame *
make_vector(std::string key) KvpFrame::get_child_frame_or_nullptr (Path const & path) noexcept
{ {
Path path; if (!path.size ())
for (auto length = key.find(delim); length != std::string::npos;) return this;
{ auto key = path.front ();
if (length != 0) if (m_valuemap.find (key.c_str ()) == m_valuemap.end ())
path.push_back(key.substr(0, length)); return nullptr;
key = key.substr(length + 1); auto child = m_valuemap.at (key.c_str ())->get <KvpFrame *> ();
length = key.find(delim); Path send;
} std::copy (path.begin () + 1, path.end (), std::back_inserter (send));
if (!key.empty()) return child->get_child_frame_or_nullptr (send);
path.push_back(key);
return path;
} }
/* KvpFrame *
* If the key is delimited, calls set(path) with the parsed result KvpFrame::get_child_frame_or_create (Path const & path) noexcept
* otherwise, inserts the key and value locally and returns the
* old value if there was one.
*/
KvpValue*
KvpFrameImpl::set(const char* key, KvpValue* value) noexcept
{ {
if (!key) return nullptr; if (!path.size ())
if (strchr(key, delim)) return this;
return set(make_vector(key), value); auto key = path.front ();
KvpValue* ret {nullptr}; auto spot = m_valuemap.find (key.c_str ());
auto spot = m_valuemap.find(key); if (spot == m_valuemap.end () || spot->second->get_type () != KvpValue::Type::FRAME)
if (spot != m_valuemap.end()) delete set_impl (key.c_str (), new KvpValue {new KvpFrame});
{ Path send;
qof_string_cache_remove(spot->first); std::copy (path.begin () + 1, path.end (), std::back_inserter (send));
ret = spot->second; auto child_val = m_valuemap.at (key.c_str ());
m_valuemap.erase(spot); auto child = child_val->get <KvpFrame *> ();
} return child->get_child_frame_or_create (send);
}
KvpValue *
KvpFrame::set_impl (std::string const & key, KvpValue * value) noexcept
{
KvpValue * ret {};
auto spot = m_valuemap.find (key.c_str ());
if (spot != m_valuemap.end ())
{
qof_string_cache_remove (spot->first);
ret = spot->second;
m_valuemap.erase (spot);
}
if (value) if (value)
{ {
auto cachedkey = auto cachedkey = static_cast <char const *> (qof_string_cache_insert (key.c_str ()));
static_cast<const char *>(qof_string_cache_insert(key)); m_valuemap.emplace (cachedkey, value);
m_valuemap.insert({cachedkey,value});
} }
return ret; return ret;
} }
static inline KvpFrameImpl* KvpValue *
walk_path_or_nullptr(const KvpFrameImpl* frame, Path& path) KvpFrameImpl::set (Path path, KvpValue* value) noexcept
{ {
KvpFrameImpl* cur_frame = const_cast<KvpFrameImpl*>(frame); auto key = path.back ();
for(auto key:path) path.pop_back ();
{ auto target = get_child_frame_or_nullptr (path);
auto slot = cur_frame->get_slot(key.c_str()); if (!target)
if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME)
return nullptr;
cur_frame = slot->get<KvpFrame*>();
}
return cur_frame;
}
/*
* If the last path parameter has a delimiter, the path before that point is ignored,
* and set is called with only the last parameter with the delimiter as the key.
*/
KvpValue*
KvpFrameImpl::set(Path path, KvpValue* value) noexcept
{
auto last_key = path.back();
path.pop_back();
auto cur_frame = walk_path_or_nullptr(this, path);
if (cur_frame == nullptr)
return nullptr; return nullptr;
if (last_key.find(delim) != std::string::npos) return target->set_impl (key, value);
return set(make_vector(last_key), value);
return cur_frame->set(last_key.c_str(), value);
} }
static inline KvpFrameImpl* KvpValue *
walk_path_and_create(KvpFrameImpl* frame, Path path) KvpFrameImpl::set_path (Path path, KvpValue* value) noexcept
{ {
for(auto key:path) auto key = path.back();
{
if (key.empty())
continue;
if (key.find(delim) != std::string::npos)
{
frame = walk_path_and_create(frame, make_vector(key));
continue;
}
auto slot = frame->get_slot(key.c_str());
if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME)
{
auto new_frame = new KvpFrame;
delete frame->set(key.c_str(), new KvpValue{new_frame});
frame = new_frame;
continue;
}
frame = slot->get<KvpFrame*>();
}
return frame;
}
KvpValue*
KvpFrameImpl::set_path(const char* path, KvpValue* value) noexcept
{
return set_path(make_vector(path), value);
}
KvpValue*
KvpFrameImpl::set_path(Path path, KvpValue* value) noexcept
{
auto cur_frame = this;
auto last_key = path.back();
path.pop_back(); path.pop_back();
cur_frame = walk_path_and_create(const_cast<KvpFrame*>(this), path); auto target = get_child_frame_or_create (path);
if (last_key.find(delim) != std::string::npos) if (!target)
return set_path(make_vector(last_key), value); return nullptr;
return cur_frame->set(last_key.c_str(), value); return target->set_impl (key, value);
}
KvpValue *
KvpFrameImpl::get_slot (Path path) noexcept
{
auto key = path.back();
path.pop_back();
auto target = get_child_frame_or_nullptr (path);
if (!target)
return nullptr;
auto spot = target->m_valuemap.find (key.c_str ());
if (spot != target->m_valuemap.end ())
return spot->second;
return nullptr;
} }
std::string std::string
@@ -231,32 +197,6 @@ KvpFrameImpl::get_keys() const noexcept
return ret; return ret;
} }
KvpValueImpl *
KvpFrameImpl::get_slot(const char * key) const noexcept
{
if (!key) return nullptr;
if (strchr(key, delim))
return get_slot(make_vector(key));
auto spot = m_valuemap.find(key);
if (spot == m_valuemap.end())
return nullptr;
return spot->second;
}
KvpValueImpl *
KvpFrameImpl::get_slot(Path path) const noexcept
{
auto last_key = path.back();
path.pop_back();
auto cur_frame = walk_path_or_nullptr(this, path);
if (cur_frame == nullptr)
return nullptr;
if (last_key.find(delim) != std::string::npos)
return get_slot(make_vector(last_key));
return cur_frame->get_slot(last_key.c_str());
}
int compare(const KvpFrameImpl * one, const KvpFrameImpl * two) noexcept int compare(const KvpFrameImpl * one, const KvpFrameImpl * two) noexcept
{ {
if (one && !two) return 1; if (one && !two) return 1;
@@ -483,7 +423,7 @@ gnc_value_list_get_type (void)
} }
void void
KvpFrame::flatten_kvp_impl(std::vector <std::string> path, std::vector <std::pair <std::vector <std::string>, KvpValue*>> & entries) const KvpFrame::flatten_kvp_impl(std::vector <std::string> path, std::vector <std::pair <std::vector <std::string>, KvpValue*>> & entries) const noexcept
{ {
for (auto const & entry : m_valuemap) for (auto const & entry : m_valuemap)
{ {
@@ -504,7 +444,7 @@ KvpFrame::flatten_kvp_impl(std::vector <std::string> path, std::vector <std::pai
} }
std::vector <std::pair <std::vector <std::string>, KvpValue*>> std::vector <std::pair <std::vector <std::string>, KvpValue*>>
KvpFrame::flatten_kvp(void) const KvpFrame::flatten_kvp(void) const noexcept
{ {
std::vector <std::pair <std::vector <std::string>, KvpValue*>> ret; std::vector <std::pair <std::vector <std::string>, KvpValue*>> ret;
flatten_kvp_impl({}, ret); flatten_kvp_impl({}, ret);

View File

@@ -141,7 +141,7 @@ struct KvpFrameImpl
* @param newvalue: The value to set at key. * @param newvalue: The value to set at key.
* @return The old value if there was one or nullptr. * @return The old value if there was one or nullptr.
*/ */
KvpValue* set(const char * key, KvpValue* newvalue) noexcept; //KvpValue* set(const char * key, KvpValue* newvalue) noexcept;
/** /**
* Set the value with the key in a subframe following the keys in path, * Set the value with the key in a subframe following the keys in path,
* replacing and returning the old value if it exists or nullptr if it * replacing and returning the old value if it exists or nullptr if it
@@ -156,18 +156,6 @@ struct KvpFrameImpl
* @return The old value if there was one or nullptr. * @return The old value if there was one or nullptr.
*/ */
KvpValue* set(Path path, KvpValue* newvalue) noexcept; KvpValue* set(Path path, KvpValue* newvalue) noexcept;
/**
* Set the value with the key in a subframe following the keys in path,
* replacing and returning the old value if it exists or nullptr if it
* doesn't. Creates any missing intermediate frames. Takes
* ownership of new value and releases ownership of the returned old
* value. Values must be allocated on the free store with operator new.
* @param path: The path of subframes as a '/'-delimited string leading to
* the frame in which to insert/replace.
* @param newvalue: The value to set at key.
* @return The old value if there was one or nullptr.
*/
KvpValue* set_path(const char* path, KvpValue* newvalue) noexcept;
/** /**
* Set the value with the key in a subframe following the keys in path, * Set the value with the key in a subframe following the keys in path,
* replacing and returning the old value if it exists or nullptr if it * replacing and returning the old value if it exists or nullptr if it
@@ -198,16 +186,11 @@ struct KvpFrameImpl
*/ */
std::vector<std::string> get_keys() const noexcept; std::vector<std::string> get_keys() const noexcept;
/** Get the value for the key or nullptr if it doesn't exist.
* @param key: The key.
* @return The value at the key or nullptr.
*/
KvpValue* get_slot(const char * key) const noexcept;
/** Get the value for the tail of the path or nullptr if it doesn't exist. /** Get the value for the tail of the path or nullptr if it doesn't exist.
* @param path: Path of keys leading to the desired value. * @param path: Path of keys leading to the desired value.
* @return The value at the key or nullptr. * @return The value at the key or nullptr.
*/ */
KvpValue* get_slot(Path keys) const noexcept; KvpValue* get_slot(Path keys) noexcept;
/** /**
* proc is called with each of the immediate contents of this frame, passing it the key, * proc is called with each of the immediate contents of this frame, passing it the key,
@@ -240,7 +223,7 @@ struct KvpFrameImpl
* the frame-containing values. * the frame-containing values.
*/ */
std::vector <std::pair <std::vector <std::string>, KvpValue*>> std::vector <std::pair <std::vector <std::string>, KvpValue*>>
flatten_kvp(void) const; flatten_kvp(void) const noexcept;
/** Test for emptiness /** Test for emptiness
* @return true if the frame contains nothing. * @return true if the frame contains nothing.
@@ -251,7 +234,10 @@ struct KvpFrameImpl
private: private:
map_type m_valuemap; map_type m_valuemap;
void flatten_kvp_impl(std::vector <std::string>, std::vector <std::pair <std::vector <std::string>, KvpValue*>> &) const; KvpFrame * get_child_frame_or_nullptr (Path const &) noexcept;
KvpFrame * get_child_frame_or_create (Path const &) noexcept;
void flatten_kvp_impl(std::vector <std::string>, std::vector <std::pair <std::vector <std::string>, KvpValue*>> &) const noexcept;
KvpValue * set_impl (std::string const &, KvpValue *) noexcept;
}; };
template<typename func_type> template<typename func_type>

View File

@@ -1040,7 +1040,7 @@ GDate* qof_book_get_autoreadonly_gdate (const QofBook *book)
const char* const char*
qof_book_get_string_option(const QofBook* book, const char* opt_name) qof_book_get_string_option(const QofBook* book, const char* opt_name)
{ {
auto slot = qof_instance_get_slots(QOF_INSTANCE (book))->get_slot(opt_name); auto slot = qof_instance_get_slots(QOF_INSTANCE (book))->get_slot({opt_name});
if (slot == nullptr) if (slot == nullptr)
return nullptr; return nullptr;
return slot->get<const char*>(); return slot->get<const char*>();
@@ -1052,9 +1052,9 @@ qof_book_set_string_option(QofBook* book, const char* opt_name, const char* opt_
qof_book_begin_edit(book); qof_book_begin_edit(book);
auto frame = qof_instance_get_slots(QOF_INSTANCE(book)); auto frame = qof_instance_get_slots(QOF_INSTANCE(book));
if (opt_val && (*opt_val != '\0')) if (opt_val && (*opt_val != '\0'))
delete frame->set(opt_name, new KvpValue(g_strdup(opt_val))); delete frame->set({opt_name}, new KvpValue(g_strdup(opt_val)));
else else
delete frame->set(opt_name, nullptr); delete frame->set({opt_name}, nullptr);
qof_instance_set_dirty (QOF_INSTANCE (book)); qof_instance_set_dirty (QOF_INSTANCE (book));
qof_book_commit_edit(book); qof_book_commit_edit(book);
} }
@@ -1086,7 +1086,7 @@ qof_book_get_features (QofBook *book)
GHashTable *features = g_hash_table_new_full (g_str_hash, g_str_equal, GHashTable *features = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, g_free); NULL, g_free);
auto slot = frame->get_slot(GNC_FEATURES); auto slot = frame->get_slot({GNC_FEATURES});
if (slot != nullptr) if (slot != nullptr)
{ {
frame = slot->get<KvpFrame*>(); frame = slot->get<KvpFrame*>();
@@ -1100,11 +1100,11 @@ qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr)
{ {
KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book)); KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
KvpValue* feature = nullptr; KvpValue* feature = nullptr;
auto feature_slot = frame->get_slot(GNC_FEATURES); auto feature_slot = frame->get_slot({GNC_FEATURES});
if (feature_slot) if (feature_slot)
{ {
auto feature_frame = feature_slot->get<KvpFrame*>(); auto feature_frame = feature_slot->get<KvpFrame*>();
feature = feature_frame->get_slot(key); feature = feature_frame->get_slot({key});
} }
if (feature == nullptr || g_strcmp0 (feature->get<const char*>(), descr)) if (feature == nullptr || g_strcmp0 (feature->get<const char*>(), descr))
{ {
@@ -1178,7 +1178,7 @@ qof_book_options_delete (QofBook *book, GSList *path)
delete root->set_path(path_v, nullptr); delete root->set_path(path_v, nullptr);
} }
else else
delete root->set_path(KVP_OPTION_PATH, nullptr); delete root->set_path({KVP_OPTION_PATH}, nullptr);
} }
/* QofObject function implementation and registration */ /* QofObject function implementation and registration */

View File

@@ -154,10 +154,7 @@ void qof_instance_kvp_merge_guids (const QofInstance *target,
const QofInstance *donor, const char* path); const QofInstance *donor, const char* path);
gboolean qof_instance_has_slot (const QofInstance *inst, const char *path); gboolean qof_instance_has_slot (const QofInstance *inst, const char *path);
void qof_instance_slot_var_delete (const QofInstance *, unsigned count, ...); void qof_instance_slot_var_delete (const QofInstance *, unsigned count, ...);
void qof_instance_slot_delete (const QofInstance *inst, const char *path);
void qof_instance_slot_var_delete_if_empty (const QofInstance *, unsigned count, ...); void qof_instance_slot_var_delete_if_empty (const QofInstance *, unsigned count, ...);
void qof_instance_slot_delete_if_empty (const QofInstance *inst,
const char *path);
void qof_instance_foreach_slot (const QofInstance *inst, const char *path, void qof_instance_foreach_slot (const QofInstance *inst, const char *path,
void(*proc)(const char*, const GValue*, void*), void(*proc)(const char*, const GValue*, void*),
void* data); void* data);
@@ -183,7 +180,7 @@ template<typename func_type, typename data_type>
void qof_instance_foreach_slot_temp (QofInstance const * inst, std::string const & path, void qof_instance_foreach_slot_temp (QofInstance const * inst, std::string const & path,
func_type const & func, data_type & data) func_type const & func, data_type & data)
{ {
auto slot = inst->kvp_data->get_slot(path.c_str()); auto slot = inst->kvp_data->get_slot({path});
if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME) if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME)
return; return;
auto frame = slot->get<KvpFrame*>(); auto frame = slot->get<KvpFrame*>();

View File

@@ -1144,8 +1144,8 @@ qof_instance_kvp_add_guid (const QofInstance *inst, const char* path,
g_return_if_fail (inst->kvp_data != NULL); g_return_if_fail (inst->kvp_data != NULL);
auto container = new KvpFrame; auto container = new KvpFrame;
container->set(key, new KvpValue(const_cast<GncGUID*>(guid))); container->set({key}, new KvpValue(const_cast<GncGUID*>(guid)));
container->set("date", new KvpValue(time)); container->set({"date"}, new KvpValue(time));
delete inst->kvp_data->set_path({path}, new KvpValue(container)); delete inst->kvp_data->set_path({path}, new KvpValue(container));
} }
@@ -1286,7 +1286,7 @@ bool qof_instance_has_path_slot (QofInstance const * inst, std::vector<std::stri
gboolean gboolean
qof_instance_has_slot (const QofInstance *inst, const char *path) qof_instance_has_slot (const QofInstance *inst, const char *path)
{ {
return inst->kvp_data->get_slot(path) != NULL; return inst->kvp_data->get_slot({path}) != NULL;
} }
void qof_instance_slot_path_delete (QofInstance const * inst, std::vector<std::string> const & path) void qof_instance_slot_path_delete (QofInstance const * inst, std::vector<std::string> const & path)
@@ -1306,12 +1306,6 @@ qof_instance_slot_var_delete (QofInstance const *inst, unsigned count, ...)
delete inst->kvp_data->set (path, nullptr); delete inst->kvp_data->set (path, nullptr);
} }
void
qof_instance_slot_delete (const QofInstance *inst, const char *path)
{
delete inst->kvp_data->set(path, nullptr);
}
void qof_instance_slot_path_delete_if_empty (QofInstance const * inst, std::vector<std::string> const & path) void qof_instance_slot_path_delete_if_empty (QofInstance const * inst, std::vector<std::string> const & path)
{ {
auto slot = inst->kvp_data->get_slot (path); auto slot = inst->kvp_data->get_slot (path);
@@ -1341,18 +1335,6 @@ qof_instance_slot_var_delete_if_empty (QofInstance const *inst, unsigned count,
} }
} }
void
qof_instance_slot_delete_if_empty (const QofInstance *inst, const char *path)
{
auto slot = inst->kvp_data->get_slot(path);
if (slot)
{
auto frame = slot->get<KvpFrame*>();
if (frame && frame->empty())
delete inst->kvp_data->set(path, nullptr);
}
}
std::vector <std::pair <std::string, KvpValue*>> std::vector <std::pair <std::string, KvpValue*>>
qof_instance_get_slots_prefix (QofInstance const * inst, std::string const & prefix) qof_instance_get_slots_prefix (QofInstance const * inst, std::string const & prefix)
{ {
@@ -1393,7 +1375,7 @@ qof_instance_foreach_slot (const QofInstance *inst, const char* path,
void (*proc)(const char*, const GValue*, void*), void (*proc)(const char*, const GValue*, void*),
void* data) void* data)
{ {
auto slot = inst->kvp_data->get_slot(path); auto slot = inst->kvp_data->get_slot({path});
if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME) if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME)
return; return;
auto frame = slot->get<KvpFrame*>(); auto frame = slot->get<KvpFrame*>();

View File

@@ -381,7 +381,7 @@ get_random_kvp_frame_depth (gint depth)
val_added = TRUE; val_added = TRUE;
ret->set_path(key, val); ret->set_path({key}, val);
g_free(key); g_free(key);
} }

View File

@@ -254,12 +254,12 @@ TEST_F(ImapBayesTest, FindAccountBayes)
auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2)); auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2));
auto value = new KvpValue(INT64_C(42)); auto value = new KvpValue(INT64_C(42));
root->set_path((std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid).c_str(), value); root->set_path({std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid}, value);
root->set_path((std::string{IMAP_FRAME_BAYES} + "-" + bar + "-" + acct1_guid).c_str(), new KvpValue{*value}); root->set_path({std::string{IMAP_FRAME_BAYES} + "-" + bar + "-" + acct1_guid}, new KvpValue{*value});
root->set_path((std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid).c_str(), new KvpValue{*value}); root->set_path({std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid}, new KvpValue{*value});
root->set_path((std::string{IMAP_FRAME_BAYES} + "-" + waldo + "-" + acct2_guid).c_str(), new KvpValue{*value}); root->set_path({std::string{IMAP_FRAME_BAYES} + "-" + waldo + "-" + acct2_guid}, new KvpValue{*value});
root->set_path((std::string{IMAP_FRAME_BAYES} + "-" + pepper + "-" + acct1_guid).c_str(), new KvpValue{*value}); root->set_path({std::string{IMAP_FRAME_BAYES} + "-" + pepper + "-" + acct1_guid}, new KvpValue{*value});
root->set_path((std::string{IMAP_FRAME_BAYES} + "-" + salt + "-" + acct2_guid).c_str(), new KvpValue{*value}); root->set_path({std::string{IMAP_FRAME_BAYES} + "-" + salt + "-" + acct2_guid}, new KvpValue{*value});
auto account = gnc_account_imap_find_account_bayes(t_imap, t_list1); auto account = gnc_account_imap_find_account_bayes(t_imap, t_list1);
EXPECT_EQ(t_expense_account1, account); EXPECT_EQ(t_expense_account1, account);
@@ -292,29 +292,29 @@ TEST_F(ImapBayesTest, AddAccountBayes)
auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account));
auto acct1_guid = guid_to_string (xaccAccountGetGUID(t_expense_account1)); auto acct1_guid = guid_to_string (xaccAccountGetGUID(t_expense_account1));
auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2)); auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2));
auto value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-foo-bar").c_str()); auto value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-foo-bar"});
auto check_account = [this](KvpValue* v) { auto check_account = [this](KvpValue* v) {
return (v->get<const char*>(), this->t_imap->book); }; return (v->get<const char*>(), this->t_imap->book); };
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + bar + "-" + acct1_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + bar + "-" + acct1_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + waldo + "-" + acct2_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + waldo + "-" + acct2_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + pepper + "-" + acct1_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + pepper + "-" + acct1_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + salt + "-" + acct2_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + salt + "-" + acct2_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct1_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct1_guid});
EXPECT_EQ(nullptr, value); EXPECT_EQ(nullptr, value);
qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account));
gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2);
qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account));
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid});
EXPECT_EQ(2, value->get<int64_t>()); EXPECT_EQ(2, value->get<int64_t>());
} }
@@ -335,43 +335,43 @@ TEST_F(ImapBayesTest, ConvertAccountBayes)
auto val2 = new KvpValue(static_cast<int64_t>(5)); auto val2 = new KvpValue(static_cast<int64_t>(5));
auto val3 = new KvpValue(static_cast<int64_t>(2)); auto val3 = new KvpValue(static_cast<int64_t>(2));
// Test for existing entries, all will be 1 // Test for existing entries, all will be 1
auto value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid).c_str()); auto value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + bar + "-" + acct1_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + bar + "-" + acct1_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + baz + "-" + acct2_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + waldo + "-" + acct2_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + waldo + "-" + acct2_guid});
EXPECT_EQ(1, value->get<int64_t>()); EXPECT_EQ(1, value->get<int64_t>());
// Set up some old entries // Set up some old entries
root->set_path((std::string{IMAP_FRAME_BAYES} + "/token/with/slashes/" + "Asset-Bank").c_str(), val1); root->set_path({IMAP_FRAME_BAYES, "token", "with", "slashes", "Asset-Bank"}, val1);
root->set_path((std::string{IMAP_FRAME_BAYES} + "/" + salt + "/" + "Asset-Bank#Bank").c_str(), new KvpValue{*val1}); root->set_path({IMAP_FRAME_BAYES, salt, "Asset-Bank#Bank"}, new KvpValue{*val1});
root->set_path((std::string{IMAP_FRAME_BAYES} + "/" + salt + "/" + "Asset>Bank#Bank").c_str(), val2); root->set_path({IMAP_FRAME_BAYES, salt, "Asset>Bank#Bank"}, val2);
root->set_path((std::string{IMAP_FRAME_BAYES} + "/" + pork + "/" + "Expense#Food").c_str(), new KvpValue{*val2}); root->set_path({IMAP_FRAME_BAYES, pork, "Expense#Food"}, new KvpValue{*val2});
root->set_path((std::string{IMAP_FRAME_BAYES} + "/" + sausage + "/" + "Expense#Drink").c_str(), val3); root->set_path({IMAP_FRAME_BAYES, sausage, "Expense#Drink"}, val3);
root->set_path((std::string{IMAP_FRAME_BAYES} + "/" + foo + "/" + "Expense#Food").c_str(), new KvpValue{*val2}); root->set_path({IMAP_FRAME_BAYES, foo, "Expense#Food"}, new KvpValue{*val2});
EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account))); EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
// Start Convert // Start Convert
gnc_account_imap_convert_bayes (t_imap->book); gnc_account_imap_convert_bayes (t_imap->book);
// convert from 'Asset-Bank' to 'Asset-Bank' guid // convert from 'Asset-Bank' to 'Asset-Bank' guid
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-token-with-slashes-" + acct3_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-token-with-slashes-" + acct3_guid});
EXPECT_EQ(10, value->get<int64_t>()); EXPECT_EQ(10, value->get<int64_t>());
// convert from 'Asset-Bank#Bank' to 'Sav Bank' guid // convert from 'Asset-Bank#Bank' to 'Sav Bank' guid
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + salt + "-" + acct4_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + salt + "-" + acct4_guid});
EXPECT_EQ(10, value->get<int64_t>()); EXPECT_EQ(10, value->get<int64_t>());
// convert from 'Expense#Food' to 'Food' guid // convert from 'Expense#Food' to 'Food' guid
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + pork + "-" + acct1_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + pork + "-" + acct1_guid});
EXPECT_EQ(5, value->get<int64_t>()); EXPECT_EQ(5, value->get<int64_t>());
// convert from 'Expense#Drink' to 'Drink' guid // convert from 'Expense#Drink' to 'Drink' guid
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + sausage + "-" + acct2_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + sausage + "-" + acct2_guid});
EXPECT_EQ(2, value->get<int64_t>()); EXPECT_EQ(2, value->get<int64_t>());
// convert from 'Expense#Food' to 'Food' guid but add to original value // convert from 'Expense#Food' to 'Food' guid but add to original value
value = root->get_slot((std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid).c_str()); value = root->get_slot({std::string{IMAP_FRAME_BAYES} + "-" + foo + "-" + acct1_guid});
EXPECT_EQ(5, value->get<int64_t>()); EXPECT_EQ(5, value->get<int64_t>());
// Check for run once flag // Check for run once flag
auto vals = book->get_slot("changed-bayesian-to-guid"); auto vals = book->get_slot({"changed-bayesian-to-guid"});
EXPECT_STREQ("true", vals->get<const char*>()); EXPECT_STREQ("true", vals->get<const char*>());
EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account))); EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));

View File

@@ -35,10 +35,10 @@ public:
t_int_val{new KvpValue {INT64_C(15)}}, t_int_val{new KvpValue {INT64_C(15)}},
t_str_val{new KvpValue{"a value"}} { t_str_val{new KvpValue{"a value"}} {
auto f1 = new KvpFrame; auto f1 = new KvpFrame;
t_root.set("top", new KvpValue{f1}); t_root.set({"top"}, new KvpValue{f1});
f1->set("first", t_int_val); f1->set({"first"}, t_int_val);
f1->set("second", new KvpValue{new KvpFrame}); f1->set({"second"}, new KvpValue{new KvpFrame});
f1->set("third", t_str_val); f1->set({"third"}, t_str_val);
} }
protected: protected:
KvpFrameImpl t_root; KvpFrameImpl t_root;
@@ -59,13 +59,12 @@ TEST_F (KvpFrameTest, SetLocal)
auto v1 = new KvpValueImpl {15.0}; auto v1 = new KvpValueImpl {15.0};
auto v2 = new KvpValueImpl { (int64_t)52}; auto v2 = new KvpValueImpl { (int64_t)52};
const char* k1 = "first key"; const char* k1 = "first key";
const char* k2 = "first key/second key";
EXPECT_EQ (nullptr, f1->set (k1, v1)); EXPECT_EQ (nullptr, f1->set ({k1}, v1));
auto first_frame = new KvpFrame; auto first_frame = new KvpFrame;
EXPECT_EQ (v1, f1->set (k1, new KvpValue{first_frame})); EXPECT_EQ (v1, f1->set ({k1}, new KvpValue{first_frame}));
EXPECT_EQ (nullptr, f1->set(k2, v2)); EXPECT_EQ (nullptr, f1->set({"first key", "second key"}, v2));
EXPECT_EQ (v2, first_frame->get_slot("second key")); EXPECT_EQ (v2, first_frame->get_slot({"second key"}));
delete f1; //this should also delete v2. delete f1; //this should also delete v2.
delete v1; delete v1;
@@ -88,15 +87,14 @@ TEST_F (KvpFrameTest, SetPath)
TEST_F (KvpFrameTest, SetPathSlash) TEST_F (KvpFrameTest, SetPathSlash)
{ {
Path path1 {"top", "second/twenty", "twenty-first"}; Path path1 {"top", "second", "twenty", "twenty-first"};
Path path2 {"top", "third", "thirty-first"}; Path path2 {"top", "third", "thirty-first"};
auto v1 = new KvpValueImpl {15.0}; auto v1 = new KvpValueImpl {15.0};
auto v2 = new KvpValueImpl { (int64_t)52}; auto v2 = new KvpValueImpl { (int64_t)52};
EXPECT_EQ (nullptr, t_root.set(path1, v1)); EXPECT_EQ (nullptr, t_root.set(path1, v1));
EXPECT_EQ (nullptr, t_root.set(path1, v2)); EXPECT_EQ (nullptr, t_root.set(path1, v2));
auto second_frame = t_root.get_slot("top")->get<KvpFrame*>()->get_slot("second")->get<KvpFrame*>(); auto second_frame = t_root.get_slot({"top"})->get<KvpFrame*>()->get_slot({"second"})->get<KvpFrame*>();
second_frame->set("twenty", new KvpValue{new KvpFrame}); second_frame->set({"twenty"}, new KvpValue{new KvpFrame});
EXPECT_EQ (nullptr, t_root.set(path1, v1)); EXPECT_EQ (nullptr, t_root.set(path1, v1));
EXPECT_EQ (v1, t_root.set(path1, v2)); EXPECT_EQ (v1, t_root.set(path1, v2));
EXPECT_EQ (v2, t_root.get_slot(path1)); EXPECT_EQ (v2, t_root.get_slot(path1));
@@ -104,16 +102,6 @@ TEST_F (KvpFrameTest, SetPathSlash)
delete v1; delete v1;
} }
TEST_F (KvpFrameTest, SetPathIgnoreBeginEndSlash)
{
Path path1 {"top", "/second/", "twenty-first"};
Path path2 {"top", "second", "twenty-first"};
auto v1 = new KvpValueImpl {15.0};
EXPECT_EQ (nullptr, t_root.set_path(path1, v1));
EXPECT_EQ (v1, t_root.get_slot(path2));
}
TEST_F (KvpFrameTest, SetPathWithCreate) TEST_F (KvpFrameTest, SetPathWithCreate)
{ {
Path path1 {"top", "second", "twenty-first"}; Path path1 {"top", "second", "twenty-first"};
@@ -130,7 +118,7 @@ TEST_F (KvpFrameTest, SetPathWithCreate)
TEST_F (KvpFrameTest, SetPathWithCreateSlash) TEST_F (KvpFrameTest, SetPathWithCreateSlash)
{ {
Path path1 {"top", "second/twenty", "twenty-first"}; Path path1 {"top", "second", "twenty", "twenty-first"};
Path path2 {"top", "third", "thirty-first"}; Path path2 {"top", "third", "thirty-first"};
Path path1a {"top", "second", "twenty", "twenty-first"}; Path path1a {"top", "second", "twenty", "twenty-first"};
auto v1 = new KvpValueImpl {15.0}; auto v1 = new KvpValueImpl {15.0};
@@ -154,7 +142,7 @@ TEST_F (KvpFrameTest, GetKeys)
EXPECT_EQ (keys.size (), 1ul); EXPECT_EQ (keys.size (), 1ul);
assert_contains (keys, k1); assert_contains (keys, k1);
auto frameval = t_root.get_slot(k1); auto frameval = t_root.get_slot({k1});
ASSERT_EQ(frameval->get_type(), KvpValue::Type::FRAME); ASSERT_EQ(frameval->get_type(), KvpValue::Type::FRAME);
keys = frameval->get<KvpFrame*>()->get_keys(); keys = frameval->get<KvpFrame*>()->get_keys();
assert_contains (keys, k2); assert_contains (keys, k2);
@@ -166,15 +154,13 @@ TEST_F (KvpFrameTest, GetLocalSlot)
auto k1 = "first"; auto k1 = "first";
auto k2 = "third"; auto k2 = "third";
auto k3 = "doesn't exist"; auto k3 = "doesn't exist";
auto k4 = "top/first"; auto frameval = t_root.get_slot({"top"});
auto frameval = t_root.get_slot("top");
ASSERT_EQ(frameval->get_type(), KvpValue::Type::FRAME); ASSERT_EQ(frameval->get_type(), KvpValue::Type::FRAME);
auto f1 = frameval->get<KvpFrame*>(); auto f1 = frameval->get<KvpFrame*>();
EXPECT_EQ (t_int_val, f1->get_slot(k1)); EXPECT_EQ (t_int_val, f1->get_slot({k1}));
EXPECT_EQ (t_str_val, f1->get_slot(k2)); EXPECT_EQ (t_str_val, f1->get_slot({k2}));
EXPECT_EQ (nullptr, f1->get_slot(k3)); EXPECT_EQ (nullptr, f1->get_slot({k3}));
EXPECT_EQ (t_int_val, t_root.get_slot(k4)); EXPECT_EQ (t_int_val, t_root.get_slot({"top", "first"}));
} }
TEST_F (KvpFrameTest, GetSlotPath) TEST_F (KvpFrameTest, GetSlotPath)
@@ -182,7 +168,7 @@ TEST_F (KvpFrameTest, GetSlotPath)
Path path1 {"top", "second", "twenty-first"}; Path path1 {"top", "second", "twenty-first"};
Path path2 {"top", "third", "thirty-first"}; Path path2 {"top", "third", "thirty-first"};
Path path3 {"top", "second", "twenty", "twenty-first"}; Path path3 {"top", "second", "twenty", "twenty-first"};
Path path3a {"top", "second/twenty", "twenty-first"}; Path path3a {"top", "second", "twenty", "twenty-first"};
auto v1 = new KvpValueImpl {15.0}; auto v1 = new KvpValueImpl {15.0};
auto v2 = new KvpValueImpl { (int64_t)52}; auto v2 = new KvpValueImpl { (int64_t)52};
@@ -198,7 +184,7 @@ TEST_F (KvpFrameTest, GetSlotPath)
TEST_F (KvpFrameTest, Empty) TEST_F (KvpFrameTest, Empty)
{ {
KvpFrameImpl f1, f2; KvpFrameImpl f1, f2;
f2.set("value", new KvpValue {2.2}); f2.set({"value"}, new KvpValue {2.2});
EXPECT_TRUE(f1.empty()); EXPECT_TRUE(f1.empty());
EXPECT_FALSE(f2.empty()); EXPECT_FALSE(f2.empty());
} }
@@ -206,12 +192,12 @@ TEST_F (KvpFrameTest, Empty)
TEST (KvpFrameTestForEachPrefix, for_each_prefix_1) TEST (KvpFrameTestForEachPrefix, for_each_prefix_1)
{ {
KvpFrame fr; KvpFrame fr;
fr.set("one", new KvpValue{new KvpFrame}); fr.set({"one"}, new KvpValue{new KvpFrame});
fr.set("one/two", new KvpValue{new KvpFrame}); fr.set({"one", "two"}, new KvpValue{new KvpFrame});
fr.set("top/two/three", new KvpValue {15.0}); fr.set({"top", "two", "three"}, new KvpValue {15.0});
fr.set("onetwo", new KvpValue{new KvpFrame}); fr.set({"onetwo"}, new KvpValue{new KvpFrame});
fr.set("onetwo/three", new KvpValue {15.0}); fr.set({"onetwo", "three"}, new KvpValue {15.0});
fr.set("onetwothree", new KvpValue {(int64_t)52}); fr.set({"onetwothree"}, new KvpValue {(int64_t)52});
unsigned count {}; unsigned count {};
auto counter = [] (char const *, KvpValue*, unsigned & count) { ++count; }; auto counter = [] (char const *, KvpValue*, unsigned & count) { ++count; };
fr.for_each_slot_prefix("one", counter, count); fr.for_each_slot_prefix("one", counter, count);
@@ -230,8 +216,8 @@ TEST (KvpFrameTestForEachPrefix, for_each_prefix_1)
TEST (KvpFrameTestForEachPrefix, for_each_prefix_2) TEST (KvpFrameTestForEachPrefix, for_each_prefix_2)
{ {
KvpFrame fr; KvpFrame fr;
fr.set("onetwo/three", new KvpValue {15.0}); fr.set({"onetwo", "three"}, new KvpValue {15.0});
fr.set("onethree", new KvpValue {(int64_t)52}); fr.set({"onethree"}, new KvpValue {(int64_t)52});
unsigned count; unsigned count;
fr.for_each_slot_prefix("onetwo", [](char const *, KvpValue * value, unsigned) { fr.for_each_slot_prefix("onetwo", [](char const *, KvpValue * value, unsigned) {
EXPECT_EQ(value->get_type(), KvpValue::Type::FRAME); EXPECT_EQ(value->get_type(), KvpValue::Type::FRAME);

View File

@@ -735,12 +735,12 @@ test_xaccSplitDetermineGainStatus (Fixture *fixture, gconstpointer pData)
fixture->split->gains = GAINS_STATUS_UNKNOWN; fixture->split->gains = GAINS_STATUS_UNKNOWN;
fixture->split->gains_split = NULL; fixture->split->gains_split = NULL;
g_assert (fixture->split->inst.kvp_data->get_slot("gains_source") == NULL); g_assert (fixture->split->inst.kvp_data->get_slot({"gains_source"}) == NULL);
xaccSplitDetermineGainStatus (fixture->split); xaccSplitDetermineGainStatus (fixture->split);
g_assert (fixture->split->gains_split == NULL); g_assert (fixture->split->gains_split == NULL);
g_assert_cmpint (fixture->split->gains, ==, GAINS_STATUS_A_VDIRTY | GAINS_STATUS_DATE_DIRTY); g_assert_cmpint (fixture->split->gains, ==, GAINS_STATUS_A_VDIRTY | GAINS_STATUS_DATE_DIRTY);
fixture->split->inst.kvp_data->set("gains-source", new KvpValue(guid_copy(g_guid))); fixture->split->inst.kvp_data->set({"gains-source"}, new KvpValue(guid_copy(g_guid)));
g_assert (fixture->split->gains_split == NULL); g_assert (fixture->split->gains_split == NULL);
fixture->split->gains = GAINS_STATUS_UNKNOWN; fixture->split->gains = GAINS_STATUS_UNKNOWN;
xaccSplitDetermineGainStatus (fixture->split); xaccSplitDetermineGainStatus (fixture->split);
@@ -1802,7 +1802,7 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
g_assert (xaccSplitGetOtherSplit (split1) == NULL); g_assert (xaccSplitGetOtherSplit (split1) == NULL);
g_assert (xaccTransUseTradingAccounts (txn) == FALSE); g_assert (xaccTransUseTradingAccounts (txn) == FALSE);
g_assert (split->inst.kvp_data->get_slot("lot-split") == NULL); g_assert (split->inst.kvp_data->get_slot({"lot-split"}) == NULL);
g_assert_cmpint (xaccTransCountSplits (txn), !=, 2); g_assert_cmpint (xaccTransCountSplits (txn), !=, 2);
g_assert (xaccSplitGetOtherSplit (split) == NULL); g_assert (xaccSplitGetOtherSplit (split) == NULL);
@@ -1813,18 +1813,18 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
xaccSplitSetParent (split2, txn); xaccSplitSetParent (split2, txn);
g_assert (xaccSplitGetOtherSplit (split) == NULL); g_assert (xaccSplitGetOtherSplit (split) == NULL);
split->inst.kvp_data->set("lot-split", kvpnow); split->inst.kvp_data->set({"lot-split"}, kvpnow);
g_assert (split->inst.kvp_data->get_slot("lot-split")); g_assert (split->inst.kvp_data->get_slot({"lot-split"}));
g_assert (xaccSplitGetOtherSplit (split) == NULL); g_assert (xaccSplitGetOtherSplit (split) == NULL);
split1->inst.kvp_data->set("lot-split", kvpnow); split1->inst.kvp_data->set({"lot-split"}, kvpnow);
g_assert (split1->inst.kvp_data->get_slot("lot-split")); g_assert (split1->inst.kvp_data->get_slot({"lot-split"}));
g_assert (xaccSplitGetOtherSplit (split) == split2); g_assert (xaccSplitGetOtherSplit (split) == split2);
split->inst.kvp_data->set("lot-split", NULL); split->inst.kvp_data->set({"lot-split"}, NULL);
g_assert (split->inst.kvp_data->get_slot("lot-split") == NULL); g_assert (split->inst.kvp_data->get_slot({"lot-split"}) == NULL);
split1->inst.kvp_data->set("lot-split", NULL); split1->inst.kvp_data->set({"lot-split"}, NULL);
g_assert (split1->inst.kvp_data->get_slot("lot-split") == NULL); g_assert (split1->inst.kvp_data->get_slot({"lot-split"}) == NULL);
qof_book_begin_edit (book); qof_book_begin_edit (book);
qof_instance_set (QOF_INSTANCE (book), qof_instance_set (QOF_INSTANCE (book),
"trading-accts", "t", "trading-accts", "t",

View File

@@ -153,8 +153,8 @@ setup (Fixture *fixture, gconstpointer pData)
xaccTransSetCurrency (txn, fixture->curr); xaccTransSetCurrency (txn, fixture->curr);
xaccSplitSetParent (split1, txn); xaccSplitSetParent (split1, txn);
xaccSplitSetParent (split2, txn); xaccSplitSetParent (split2, txn);
frame->set(trans_notes_str, new KvpValue("Salt pork sausage")); frame->set({trans_notes_str}, new KvpValue("Salt pork sausage"));
frame->set_path("/qux/quux/corge", new KvpValue(123.456)); frame->set_path({"qux", "quux", "corge"}, new KvpValue(123.456));
qof_instance_set_slots (QOF_INSTANCE (txn), frame); qof_instance_set_slots (QOF_INSTANCE (txn), frame);
} }
xaccTransCommitEdit (txn); xaccTransCommitEdit (txn);
@@ -562,7 +562,7 @@ test_dupe_trans (Fixture *fixture, gconstpointer pData)
oldtxn->date_posted = posted; oldtxn->date_posted = posted;
oldtxn->date_entered = entered; oldtxn->date_entered = entered;
oldtxn->inst.kvp_data->set("/foo/bar/baz", oldtxn->inst.kvp_data->set({"foo", "bar", "baz"},
new KvpValue("The Great Waldo Pepper")); new KvpValue("The Great Waldo Pepper"));
newtxn = fixture->func->dupe_trans (oldtxn); newtxn = fixture->func->dupe_trans (oldtxn);
@@ -881,7 +881,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
g_free(clone->description); g_free(clone->description);
clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper")); clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
auto frame = qof_instance_get_slots (QOF_INSTANCE (clone)); auto frame = qof_instance_get_slots (QOF_INSTANCE (clone));
frame->set("/qux/quux/corge", new KvpValue(654.321)); frame->set({"qux", "quux", "corge"}, new KvpValue(654.321));
xaccTransCommitEdit (clone); xaccTransCommitEdit (clone);
g_free (cleanup->msg); g_free (cleanup->msg);
g_free (check->msg); g_free (check->msg);
@@ -893,7 +893,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
xaccTransBeginEdit (clone); xaccTransBeginEdit (clone);
cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig); cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig);
clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper")); clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
frame->set("/qux/quux/corge", new KvpValue(123.456)); frame->set({"qux", "quux", "corge"}, new KvpValue(123.456));
xaccTransCommitEdit (clone); xaccTransCommitEdit (clone);
g_free (cleanup->msg); g_free (cleanup->msg);
g_free (check->msg); g_free (check->msg);
@@ -1858,22 +1858,22 @@ test_xaccTransVoid (Fixture *fixture, gconstpointer pData)
/* Actual function variables start here. */ /* Actual function variables start here. */
auto frame = fixture->txn->inst.kvp_data; auto frame = fixture->txn->inst.kvp_data;
auto void_reason = "Voided for Unit Test"; auto void_reason = "Voided for Unit Test";
auto txn_notes = g_strdup (frame->get_slot(trans_notes_str)->get<const char*>()); auto txn_notes = g_strdup (frame->get_slot({trans_notes_str})->get<const char*>());
Timespec now = timespec_now (); Timespec now = timespec_now ();
char iso8601_str[ISO_DATELENGTH + 1] = ""; char iso8601_str[ISO_DATELENGTH + 1] = "";
GList *split = NULL; GList *split = NULL;
xaccTransVoid (fixture->txn, void_reason); xaccTransVoid (fixture->txn, void_reason);
g_assert_cmpstr (frame->get_slot(trans_notes_str)->get<const char*>(), ==, g_assert_cmpstr (frame->get_slot({trans_notes_str})->get<const char*>(), ==,
"Voided transaction"); "Voided transaction");
g_assert_cmpstr (frame->get_slot(void_former_notes_str)->get<const char*>(), g_assert_cmpstr (frame->get_slot({void_former_notes_str})->get<const char*>(),
==, txn_notes); ==, txn_notes);
g_assert_cmpstr (frame->get_slot(void_reason_str)->get<const char*>(), ==, g_assert_cmpstr (frame->get_slot({void_reason_str})->get<const char*>(), ==,
void_reason); void_reason);
gnc_timespec_to_iso8601_buff (now, iso8601_str); gnc_timespec_to_iso8601_buff (now, iso8601_str);
g_assert_cmpstr (frame->get_slot(void_time_str)->get<const char*>(), ==, g_assert_cmpstr (frame->get_slot({void_time_str})->get<const char*>(), ==,
iso8601_str); iso8601_str);
g_assert_cmpstr (frame->get_slot(TRANS_READ_ONLY_REASON)->get<const char*>(), g_assert_cmpstr (frame->get_slot({TRANS_READ_ONLY_REASON})->get<const char*>(),
==, "Transaction Voided"); ==, "Transaction Voided");
for (split = fixture->txn->splits; split; split=g_list_next (split)) for (split = fixture->txn->splits; split; split=g_list_next (split))
{ {
@@ -1883,12 +1883,12 @@ test_xaccTransVoid (Fixture *fixture, gconstpointer pData)
xaccTransUnvoid (fixture->txn); xaccTransUnvoid (fixture->txn);
g_assert_cmpstr (frame->get_slot(trans_notes_str)->get<const char*>(), ==, g_assert_cmpstr (frame->get_slot({trans_notes_str})->get<const char*>(), ==,
txn_notes); txn_notes);
g_assert (frame->get_slot(void_former_notes_str) == NULL); g_assert (frame->get_slot({void_former_notes_str}) == NULL);
g_assert (frame->get_slot(void_reason_str) == NULL); g_assert (frame->get_slot({void_reason_str}) == NULL);
g_assert (frame->get_slot(void_time_str) == NULL); g_assert (frame->get_slot({void_time_str}) == NULL);
g_assert (frame->get_slot(TRANS_READ_ONLY_REASON) == NULL); g_assert (frame->get_slot({TRANS_READ_ONLY_REASON}) == NULL);
for (split = fixture->txn->splits; split; split=g_list_next (split)) for (split = fixture->txn->splits; split; split=g_list_next (split))
{ {
g_assert (!gnc_numeric_zero_p (((Split*)(split->data))->value)); g_assert (!gnc_numeric_zero_p (((Split*)(split->data))->value));
@@ -1909,7 +1909,7 @@ test_xaccTransReverse (Fixture *fixture, gconstpointer pData)
auto frame = fixture->txn->inst.kvp_data; auto frame = fixture->txn->inst.kvp_data;
GList *orig_splits = NULL, *rev_splits = NULL; GList *orig_splits = NULL, *rev_splits = NULL;
g_assert (guid_equal (frame->get_slot(TRANS_REVERSED_BY)->get<GncGUID*>(), g_assert (guid_equal (frame->get_slot({TRANS_REVERSED_BY})->get<GncGUID*>(),
xaccTransGetGUID (rev))); xaccTransGetGUID (rev)));
g_assert (!qof_instance_is_dirty (QOF_INSTANCE (rev))); //Cleared by commit g_assert (!qof_instance_is_dirty (QOF_INSTANCE (rev))); //Cleared by commit