Commit 9a3eced3 by Maarten L. Hekkelman

new update_value in category

parent 2fed7a76
...@@ -964,6 +964,32 @@ class category ...@@ -964,6 +964,32 @@ class category
// -------------------------------------------------------------------- // --------------------------------------------------------------------
using value_provider_type = std::function<std::string_view(std::string_view)>;
/// \brief Update a single item named @a item_name in the rows that match
/// \a cond to values provided by a callback function \a value_provider
/// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split.
void update_value(condition &&cond, std::string_view item_name,
value_provider_type &&value_provider)
{
auto rs = find(std::move(cond));
std::vector<row_handle> rows;
std::copy(rs.begin(), rs.end(), std::back_inserter(rows));
update_value(rows, item_name, std::move(value_provider));
}
/// \brief Update a single item named @a item_name in the rows \a rows
/// to values provided by a callback function \a value_provider
/// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split.
void update_value(const std::vector<row_handle> &rows, std::string_view item_name,
value_provider_type &&value_provider);
/// \brief Update a single item named @a item_name in the rows that match \a cond to value \a value /// \brief Update a single item named @a item_name in the rows that match \a cond to value \a value
/// making sure the linked categories are updated according to the link. /// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute /// That means, child categories are updated if the links are absolute
...@@ -982,7 +1008,10 @@ class category ...@@ -982,7 +1008,10 @@ class category
/// That means, child categories are updated if the links are absolute /// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split. /// and unique. If they are not, the child category rows are split.
void update_value(const std::vector<row_handle> &rows, std::string_view item_name, std::string_view value); void update_value(const std::vector<row_handle> &rows, std::string_view item_name, std::string_view value)
{
update_value(rows, item_name, [value](std::string_view) { return value; });
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Naming used to be very inconsistent. For backward compatibility, // Naming used to be very inconsistent. For backward compatibility,
......
...@@ -1339,7 +1339,8 @@ std::string category::get_unique_value(std::string_view item_name) ...@@ -1339,7 +1339,8 @@ std::string category::get_unique_value(std::string_view item_name)
return result; return result;
} }
void category::update_value(const std::vector<row_handle> &rows, std::string_view item_name, std::string_view value) void category::update_value(const std::vector<row_handle> &rows, std::string_view item_name,
value_provider_type &&value_provider)
{ {
using namespace std::literals; using namespace std::literals;
...@@ -1352,40 +1353,29 @@ void category::update_value(const std::vector<row_handle> &rows, std::string_vie ...@@ -1352,40 +1353,29 @@ void category::update_value(const std::vector<row_handle> &rows, std::string_vie
auto &col = m_items[colIx]; auto &col = m_items[colIx];
// this is expensive, but better throw early on
// check the value // check the value
if (col.m_validator) if (col.m_validator)
{ {
std::error_code ec; for (auto row : rows)
col.m_validator->validate_value(value, ec);
if (ec)
throw validation_exception(ec, m_name, item_name);
}
// first some sanity checks, what was the old value and is it the same for all rows?
std::string oldValue{ rows.front()[item_name].text() };
for (auto row : rows)
{
if (oldValue != row[item_name].text())
{ {
std::ostringstream os; std::string value{ value_provider(row[item_name].text()) };
os << "Inconsistent old values in update_value, trying to set " << std::quoted(value) std::error_code ec;
<< " as value for item " << item_name << " in category " << m_name; col.m_validator->validate_value(value, ec);
if (ec)
throw std::runtime_error(os.str()); throw validation_exception(ec, m_name, item_name);
} }
} }
if (oldValue == value) // no need to do anything // update and see if we need to update any child categories that depend on this value
return;
// update rows, but do not cascade
for (auto row : rows)
row.assign(colIx, value, false);
// see if we need to update any child categories that depend on this value
for (auto parent : rows) for (auto parent : rows)
{ {
std::string oldValue{ parent[item_name].text() };
std::string value{ value_provider(oldValue) };
parent.assign(colIx, value, false);
for (auto &&[childCat, linked] : m_child_links) for (auto &&[childCat, linked] : m_child_links)
{ {
if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), item_name) == linked->m_parent_keys.end()) if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), item_name) == linked->m_parent_keys.end())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment