Consolidated solution for RDB merge ('apply'). Potentially one bug fixed (tag mapping)

This commit is contained in:
Matthias Koefferlein 2024-08-17 22:03:00 +02:00
parent 2eef9c38d6
commit 0f833da652
3 changed files with 196 additions and 161 deletions

View File

@ -278,7 +278,7 @@ template <> RDB_PUBLIC bool Value<db::DText>::is_shape () const
}
bool ValueBase::compare (const ValueBase *a, const ValueBase *b)
bool ValueBase::compare (const ValueBase *a, const ValueBase *b)
{
// compare is the intrinsic compare of equal type and type index for different types.
if (a->type_index () == b->type_index ()) {
@ -416,7 +416,7 @@ ValueBase::create_from_shape (const db::Shape &shape, const db::CplxTrans &trans
// ------------------------------------------------------------------------------------------
// ValueWrapper implementation
std::string
std::string
ValueWrapper::to_string () const
{
std::string r;
@ -437,14 +437,14 @@ ValueWrapper::to_string () const
return r;
}
void
void
ValueWrapper::from_string (const std::string &s)
{
tl::Extractor ex (s.c_str ());
from_string (ex);
}
void
void
ValueWrapper::from_string (tl::Extractor &ex)
{
id_type tag_id = 0;
@ -453,7 +453,7 @@ ValueWrapper::from_string (tl::Extractor &ex)
bool user_tag = ex.test ("#");
std::string tn;
std::string tn;
ex.read_word_or_quoted (tn);
tag_id = rdb::Tags::id_for_name (tn, user_tag);
@ -482,11 +482,11 @@ Values::compare (const Values &other, const std::set<id_type> &common_tags) cons
Values::const_iterator a = begin (), b = other.begin ();
while (a != end () && b != other.end ()) {
id_type t12 = 0;
id_type t1 = 0;
while (a != end () && a->tag_id () != 0) {
auto j = common_tags.find (a->tag_id ());
if (j != common_tags.end ()) {
t12 = a->tag_id ();
t1 = a->tag_id ();
break;
}
++a;
@ -506,8 +506,8 @@ Values::compare (const Values &other, const std::set<id_type> &common_tags) cons
return b != other.end ();
}
if (t12 != t2) {
return t12 < t2;
if (t1 != t2) {
return t1 < t2;
}
if (a->get () && b->get ()) {
@ -528,7 +528,7 @@ Values::compare (const Values &other, const std::set<id_type> &common_tags) cons
return b != other.end ();
}
std::string
std::string
Values::to_string () const
{
std::string r;
@ -547,7 +547,7 @@ Values::to_string () const
return r;
}
void
void
Values::from_string (const std::string &s)
{
tl::Extractor ex (s.c_str ());
@ -567,7 +567,7 @@ Values::from_string (const std::string &s)
// ------------------------------------------------------------------------------------------
// Cell implementation
void
void
Cells::import_cell (const Cell &c)
{
Cell *cell;
@ -582,7 +582,7 @@ Cells::import_cell (const Cell &c)
cell->references ().insert (*r);
}
}
// ------------------------------------------------------------------------------------------
// Cell implementation
@ -615,7 +615,7 @@ Cell::~Cell ()
// .. nothing yet ..
}
std::pair<bool, db::DCplxTrans>
std::pair<bool, db::DCplxTrans>
Cell::path_to (id_type parent_cell_id, const Database *db) const
{
if (parent_cell_id == id ()) {
@ -626,7 +626,7 @@ Cell::path_to (id_type parent_cell_id, const Database *db) const
}
}
std::pair<bool, db::DCplxTrans>
std::pair<bool, db::DCplxTrans>
Cell::path_to (id_type parent_cell_id, const Database *db, std::set <id_type> &visited, const db::DCplxTrans &trans) const
{
for (reference_iterator r = references ().begin (); r != references ().end (); ++r) {
@ -654,15 +654,15 @@ Cell::path_to (id_type parent_cell_id, const Database *db, std::set <id_type> &v
return std::pair<bool, db::DCplxTrans> (false, db::DCplxTrans ());
}
void
void
Cell::import_references (const References &references)
{
for (References::const_iterator r = references.begin (); r != references.end (); ++r) {
m_references.insert (*r);
}
}
std::string
std::string
Cell::qname () const
{
if (m_variant.empty ()) {
@ -687,7 +687,7 @@ References::References (Cell *cell)
// .. nothing yet ..
}
void
void
References::set_database (Database *database)
{
mp_database = database;
@ -705,20 +705,20 @@ Reference::Reference (References *references)
// .. nothing yet ..
}
void
void
Reference::set_trans_str (const std::string &s)
{
tl::Extractor ex (s.c_str ());
ex.read (m_trans);
}
std::string
std::string
Reference::trans_str () const
{
return m_trans.to_string ();
}
void
void
Reference::set_parent_cell_qname (const std::string &qname)
{
tl_assert (mp_database != 0);
@ -729,7 +729,7 @@ Reference::set_parent_cell_qname (const std::string &qname)
m_parent_cell_id = cell->id ();
}
std::string
std::string
Reference::parent_cell_qname () const
{
tl_assert (mp_database != 0);
@ -787,7 +787,7 @@ Category::sub_categories ()
return *mp_sub_categories;
}
std::string
std::string
Category::path () const
{
std::vector <std::string> path_elements;
@ -810,7 +810,7 @@ Category::path () const
return r;
}
void
void
Category::import_sub_categories (Categories *categories)
{
if (mp_sub_categories) {
@ -826,7 +826,7 @@ Category::import_sub_categories (Categories *categories)
}
}
void
void
Category::set_database (Database *database)
{
mp_database = database;
@ -838,14 +838,14 @@ Category::set_database (Database *database)
// ------------------------------------------------------------------------------------------
// Categories implementation
void
void
Categories::clear ()
{
m_categories.clear ();
m_categories_by_name.clear ();
}
void
void
Categories::add_category (Category *cat)
{
cat->set_database (mp_database.get ());
@ -853,7 +853,7 @@ Categories::add_category (Category *cat)
m_categories_by_name.insert (std::make_pair (cat->name (), cat));
}
void
void
Categories::set_database (Database *database)
{
mp_database = database;
@ -863,7 +863,7 @@ Categories::set_database (Database *database)
}
Category *
Categories::category_by_name (const char *path)
Categories::category_by_name (const char *path)
{
std::string component;
tl::Extractor ex (path);
@ -881,7 +881,7 @@ Categories::category_by_name (const char *path)
return 0;
}
void
void
Categories::import_category (Category *category)
{
Category *cat;
@ -945,13 +945,31 @@ Tags::Tags ()
// .. nothing yet ..
}
void
void
Tags::clear ()
{
m_tags_per_id.clear ();
m_tags.clear ();
}
void
Tags::remove_tag (id_type id)
{
auto j = m_tags_per_id.find (id);
if (j != m_tags_per_id.end ()) {
m_tags.erase (m_tags.begin () + j->second);
for (auto i = m_tags_per_id.begin (); i != m_tags_per_id.end (); ++i) {
if (i->second > j->second) {
i->second -= 1;
}
}
m_tags_per_id.erase (id);
}
}
const Tag &
Tags::tag (const std::string &name, bool user_tag) const
{
@ -995,7 +1013,7 @@ Tags::import_tag (const Tag &t)
tt.set_description (t.description ());
}
bool
bool
Tags::has_tag (const std::string &name, bool user_tag) const
{
return m_tags_per_id.find (id_for_name (name, user_tag)) != m_tags_per_id.end ();
@ -1043,31 +1061,31 @@ Item &Item::operator= (const Item &d)
return *this;
}
void
void
Item::add_tag (id_type tag_id)
{
m_tag_ids.insert (tag_id);
}
void
void
Item::remove_tag (id_type tag_id)
{
m_tag_ids.erase (tag_id);
}
void
void
Item::remove_tags ()
{
m_tag_ids.clear ();
}
bool
bool
Item::has_tag (id_type tag_id) const
{
return m_tag_ids.find (tag_id) != m_tag_ids.end ();
}
std::string
std::string
Item::cell_qname () const
{
tl_assert (mp_database != 0);
@ -1076,7 +1094,7 @@ Item::cell_qname () const
return cell->qname ();
}
void
void
Item::set_cell_qname (const std::string &qname)
{
tl_assert (mp_database != 0);
@ -1096,7 +1114,7 @@ Item::category_name () const
return category->path ();
}
void
void
Item::set_category_name (const std::string &path)
{
tl_assert (mp_database != 0);
@ -1107,7 +1125,7 @@ Item::set_category_name (const std::string &path)
m_category_id = category->id ();
}
std::string
std::string
Item::tag_str () const
{
tl_assert (mp_database != 0);
@ -1135,7 +1153,7 @@ Item::tag_str () const
return r;
}
void
void
Item::set_tag_str (const std::string &tags)
{
tl_assert (mp_database != 0);
@ -1153,7 +1171,7 @@ Item::set_tag_str (const std::string &tags)
}
#if defined(HAVE_QT)
void
void
Item::set_image (const QImage &image)
{
if (image.isNull ()) {
@ -1341,7 +1359,7 @@ Database::import_tags (const Tags &tags)
}
}
void
void
Database::import_categories (Categories *categories)
{
set_modified ();
@ -1352,7 +1370,7 @@ Database::import_categories (Categories *categories)
mp_categories->set_database (this);
}
void
void
Database::import_cells (const Cells &cells)
{
set_modified ();
@ -1399,13 +1417,13 @@ Database::create_category (Categories *container, const std::string &name)
}
Category *
Database::category_by_name_non_const (const std::string &name)
Database::category_by_name_non_const (const std::string &name)
{
return mp_categories->category_by_name (name.c_str ());
}
Category *
Database::category_by_id_non_const (id_type id)
Database::category_by_id_non_const (id_type id)
{
std::map <id_type, Category *>::const_iterator c = m_categories_by_id.find (id);
if (c != m_categories_by_id.end ()) {
@ -1460,7 +1478,7 @@ Database::create_cell (const std::string &name, const std::string &variant, cons
} else {
new_cell = new Cell (++m_next_id, name, std::string (), layout_name);
}
m_cells.add_cell (new_cell);
@ -1468,7 +1486,7 @@ Database::create_cell (const std::string &name, const std::string &variant, cons
m_cells_by_qname.insert (std::make_pair (new_cell->qname (), new_cell));
} else {
new_cell = new Cell (++m_next_id, name, variant, layout_name);
m_cells.add_cell (new_cell);
m_cells_by_id.insert (std::make_pair (new_cell->id (), new_cell));
@ -1496,7 +1514,7 @@ Database::create_cell (const std::string &name, const std::string &variant, cons
}
other_cell->set_variant (tl::to_string (variant_index + 1));
m_cells_by_qname.insert (std::make_pair (other_cell->qname (), other_cell));
}
@ -1542,21 +1560,21 @@ Database::cell_by_id_non_const (id_type id)
}
}
void
void
Database::set_tag_description (id_type tag_id, const std::string &description)
{
set_modified ();
tags_non_const ().tag (tag_id).set_description (description);
}
void
void
Database::add_item_tag (const Item *item, id_type tag)
{
set_modified ();
const_cast <Item *> (item)->add_tag (tag);
}
void
void
Database::remove_item_tag (const Item *item, id_type tag)
{
set_modified ();
@ -1571,7 +1589,7 @@ Database::set_item_comment (const Item *item, const std::string &comment)
}
#if defined(HAVE_QT)
void
void
Database::set_item_image (const Item *item, const QImage &image)
{
set_modified ();
@ -1586,14 +1604,14 @@ Database::set_item_image_str (const Item *item, const std::string &image_str)
const_cast <Item *> (item)->set_image_str (image_str);
}
void
void
Database::set_item_multiplicity (const Item *item, size_t n)
{
set_modified ();
const_cast <Item *> (item)->set_multiplicity (n);
}
void
void
Database::set_item_visited (const Item *item_c, bool visited)
{
if (visited != item_c->visited ()) {
@ -1654,7 +1672,7 @@ Database::create_item (id_type cell_id, id_type category_id)
static std::list<ItemRef> empty_list;
std::pair<Database::const_item_ref_iterator, Database::const_item_ref_iterator>
std::pair<Database::const_item_ref_iterator, Database::const_item_ref_iterator>
Database::items_by_cell_and_category (id_type cell_id, id_type category_id) const
{
std::map <std::pair <id_type, id_type>, std::list<ItemRef> >::const_iterator i = m_items_by_cell_and_category_id.find (std::make_pair (cell_id, category_id));
@ -1731,7 +1749,7 @@ Database::num_items (id_type cell_id, id_type category_id) const
}
}
size_t
size_t
Database::num_items_visited (id_type cell_id, id_type category_id) const
{
std::map <std::pair <id_type, id_type>, size_t>::const_iterator n = m_num_items_visited_by_cell_and_category.find (std::make_pair (cell_id, category_id));
@ -1915,8 +1933,6 @@ Database::apply (const rdb::Database &other)
{
std::map<id_type, id_type> cell2cell;
std::map<id_type, id_type> cat2cat;
std::map<id_type, id_type> tag2tag;
std::map<id_type, id_type> rev_tag2tag;
for (auto c = other.cells ().begin (); c != other.cells ().end (); ++c) {
// TODO: do we have a consistent scheme of naming variants? What requirements

View File

@ -68,10 +68,10 @@ class Items;
/**
* @brief A report item's category
*
* An item is member of exactly one category. This can be a check for example.
* An item is member of exactly one category. This can be a check for example.
* A category is described by a name and a description string. An Id is provided
* to reference this category from actual report items.
* Categories can be organized hierarchically for which a category collection
* Categories can be organized hierarchically for which a category collection
* is provided and member of the individual category.
*
* A category can only be created by the database object, since the
@ -112,7 +112,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_id (id_type id)
void set_id (id_type id)
{
m_id = id;
}
@ -130,7 +130,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_name (const std::string &d)
void set_name (const std::string &d)
{
m_name = d;
}
@ -155,7 +155,7 @@ public:
/**
* @brief The description string (setter)
*/
void set_description (const std::string &d)
void set_description (const std::string &d)
{
m_description = d;
}
@ -181,7 +181,7 @@ public:
/**
* @brief The parent (owner) of this category (getter)
*/
Category *parent ()
Category *parent ()
{
return mp_parent;
}
@ -192,7 +192,7 @@ public:
* This method is provided for persistency application only. It should not be used otherwise.
* The Category object will take over ownership over the sub categories.
*/
void import_sub_categories (Categories *categories);
void import_sub_categories (Categories *categories);
/**
* @brief Report the number of items
@ -242,7 +242,7 @@ private:
* @brief Default constructor
*
* Creates a category object with empty name and description.
* This constructor is private to allow only the database to produce a
* This constructor is private to allow only the database to produce a
* category object.
*/
Category (const std::string &name);
@ -262,9 +262,9 @@ private:
{
m_num_items_visited += d;
}
/**
* @brief Add an offset to the number of items
* @brief Add an offset to the number of items
*/
void add_to_num_items (int d)
{
@ -279,7 +279,7 @@ private:
m_num_items = 0;
m_num_items_visited = 0;
}
/**
* @brief Set the database reference
*/
@ -293,10 +293,10 @@ private:
/**
* @brief The collection of categories
*
* A generic collection of categories used for the root node and
* A generic collection of categories used for the root node and
* sub-category nodes.
*/
class RDB_PUBLIC Categories
class RDB_PUBLIC Categories
{
public:
typedef tl::shared_collection<Category>::const_iterator const_iterator;
@ -327,39 +327,39 @@ public:
/**
* @brief Iterate the categories inside this collection (begin iterator)
*/
const_iterator begin () const
{
return m_categories.begin ();
const_iterator begin () const
{
return m_categories.begin ();
}
/**
* @brief Iterate the categories inside this collection (end iterator)
*/
const_iterator end () const
{
return m_categories.end ();
const_iterator end () const
{
return m_categories.end ();
}
/**
* @brief Iterate the categories inside this collection (begin iterator)
*/
iterator begin ()
{
return m_categories.begin ();
iterator begin ()
{
return m_categories.begin ();
}
/**
* @brief Iterate the categories inside this collection (end iterator)
*/
iterator end ()
{
return m_categories.end ();
iterator end ()
{
return m_categories.end ();
}
/**
* @brief Find a category by name
*
* The name is actually a path expression which specifies the category starting from the given
* The name is actually a path expression which specifies the category starting from the given
* node with a '.' separated path notation. I.e. 'a.b' is the sub-category 'b' of category 'a'.
* If no such category can be found, 0 is returned.
*/
@ -371,7 +371,7 @@ public:
/**
* @brief Find a category by name (non-const version)
*
* The name is actually a path expression which specifies the category starting from the given
* The name is actually a path expression which specifies the category starting from the given
* node with a '.' separated path notation. I.e. 'a.b' is the sub-category 'b' of category 'a'.
* If no such category can be found, 0 is returned.
*/
@ -388,7 +388,7 @@ public:
* This method is provided for persistency application only. It should not be used otherwise.
* This will take over ownership over the category.
*/
void import_category (Category *category);
void import_category (Category *category);
/**
* @brief Gets the database reference
@ -403,7 +403,7 @@ public:
friend class Category;
tl::shared_collection<Category> m_categories;
std::map <std::string, Category *> m_categories_by_name;
std::map <std::string, Category *> m_categories_by_name;
tl::weak_ptr<Database> mp_database;
Categories ()
@ -422,7 +422,7 @@ public:
* A value has a value (as the name says) and an optional tag id. Tag id's identify
* the value and make the value a named one.
*/
class RDB_PUBLIC ValueBase
class RDB_PUBLIC ValueBase
{
public:
ValueBase ()
@ -496,14 +496,14 @@ public:
return m_value;
}
C &value ()
C &value ()
{
return m_value;
}
int type_index () const
{
return type_index_of<C> ();
int type_index () const
{
return type_index_of<C> ();
}
bool compare (const ValueBase *other) const;
@ -535,7 +535,7 @@ RDB_PUBLIC_TEMPLATE ValueBase *make_value (const T &value)
/**
* @brief A class encapsulating ValueBase pointer
*/
class RDB_PUBLIC ValueWrapper
class RDB_PUBLIC ValueWrapper
{
public:
/**
@ -592,7 +592,7 @@ public:
/**
* @brief Get the pointer
*/
ValueBase *get ()
ValueBase *get ()
{
return mp_ptr;
}
@ -627,7 +627,7 @@ public:
}
/**
* @brief Convert the values collection to a string
* @brief Convert the values collection to a string
*/
std::string to_string () const;
@ -672,19 +672,16 @@ public:
}
/**
* @brief Assignment
* @brief Assignment
*/
Values &operator= (const Values &d);
/**
* @brief Compare two value sets (less operator)
*
* This compare function will use the tag mapping provided by tag map ("this" tag id to "other" tag id).
* Values with tags not listed in the tag map will not be compared.
* This compare function will use the tags provide in "common_tags". Tags outside this set are ignored.
* Untagged values (tag_id 0) will be compared always.
*
* "rev_tag_map" needs to be the reverse of "tag_map".
*
* The order of the values matters.
*/
bool compare (const Values &other, const std::set<id_type> &common_tags) const;
@ -708,7 +705,7 @@ public:
/**
* @brief The non-const iterator (begin)
*/
iterator begin ()
iterator begin ()
{
return m_values.begin ();
}
@ -758,7 +755,7 @@ public:
}
/**
* @brief Convert the values collection to a string
* @brief Convert the values collection to a string
*/
std::string to_string () const;
@ -774,8 +771,8 @@ private:
/**
* @brief A report item
*
* A report item is one information item in the report.
* The value of a report item is manyfold. Values can be keyed,
* A report item is one information item in the report.
* The value of a report item is manyfold. Values can be keyed,
* i.e. multiple values can be present with different keys.
* Each value can be of different types where the type is specified by a type Id.
*/
@ -789,12 +786,12 @@ public:
Item (Items *items);
/**
* @brief Copy constructor
* @brief Copy constructor
*/
Item (const Item &d);
/**
* @brief Assignment
* @brief Assignment
*/
Item &operator= (const Item &d);
@ -816,7 +813,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_cell_id (id_type id)
void set_cell_id (id_type id)
{
m_cell_id = id;
}
@ -846,7 +843,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_category_id (id_type id)
void set_category_id (id_type id)
{
m_category_id = id;
}
@ -1073,9 +1070,9 @@ private:
};
/**
* @brief An item reference
* @brief An item reference
*
* This is basically a wrapper for a pointer that correctly
* This is basically a wrapper for a pointer that correctly
* maps const * and non-const * values through the operator->
* overloads.
*/
@ -1141,7 +1138,7 @@ public:
/**
* @brief Construct an item list with a database reference
*/
Items (Database *database)
Items (Database *database)
: mp_database (database)
{
// .. nothing yet ..
@ -1150,33 +1147,33 @@ public:
/**
* @brief Iterate the items inside this collection (begin iterator)
*/
const_iterator begin () const
{
return m_items.begin ();
const_iterator begin () const
{
return m_items.begin ();
}
/**
* @brief Iterate the items inside this collection (end iterator)
*/
const_iterator end () const
{
return m_items.end ();
const_iterator end () const
{
return m_items.end ();
}
/**
* @brief Iterate the items inside this collection (non-const begin iterator)
*/
iterator begin ()
{
return m_items.begin ();
{
return m_items.begin ();
}
/**
* @brief Iterate the items inside this collection (non-const end iterator)
*/
iterator end ()
{
return m_items.end ();
{
return m_items.end ();
}
/**
@ -1195,7 +1192,7 @@ public:
*
* This method is provided for persistency application only. It should not be used otherwise.
*/
Item &back ()
Item &back ()
{
return m_items.back ();
}
@ -1203,7 +1200,7 @@ public:
/**
* @brief Get the database reference
*/
Database *database ()
Database *database ()
{
return mp_database;
}
@ -1350,7 +1347,7 @@ private:
};
/**
* @brief A collection of references
* @brief A collection of references
*/
class RDB_PUBLIC References
{
@ -1393,7 +1390,7 @@ public:
/**
* @brief Begin iterator (non-const)
*/
iterator begin ()
iterator begin ()
{
return m_references.begin ();
}
@ -1401,7 +1398,7 @@ public:
/**
* @brief End iterator (non-const)
*/
iterator end ()
iterator end ()
{
return m_references.end ();
}
@ -1417,7 +1414,7 @@ public:
/**
* @brief Get the database reference
*/
Database *database ()
Database *database ()
{
return mp_database;
}
@ -1500,7 +1497,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_id (id_type id)
void set_id (id_type id)
{
m_id = id;
}
@ -1518,7 +1515,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_name (const std::string &d)
void set_name (const std::string &d)
{
m_name = d;
}
@ -1536,7 +1533,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_variant (const std::string &v)
void set_variant (const std::string &v)
{
m_variant = v;
}
@ -1591,7 +1588,7 @@ public:
/**
* @brief The reference collection (non-const)
*/
References &references ()
References &references ()
{
return m_references;
}
@ -1604,10 +1601,10 @@ public:
void import_references (const References &references);
/**
* @brief Get one example transformation leading from this cell to a given parent cell
* @brief Get one example transformation leading from this cell to a given parent cell
*
* This method will try to determine one path from the given cell to the given parent
* cell and return the accumulated transformation for this path.
* cell and return the accumulated transformation for this path.
* If no path is found, the first parameter of the returned pair is false, otherwise it's
* true.
*/
@ -1616,7 +1613,7 @@ public:
/**
* @brief Get the database reference
*/
Database *database ()
Database *database ()
{
return mp_database;
}
@ -1654,7 +1651,7 @@ private:
}
/**
* @brief Add an offset to the number of items
* @brief Add an offset to the number of items
*/
void add_to_num_items (int d)
{
@ -1669,7 +1666,7 @@ private:
m_num_items = 0;
m_num_items_visited = 0;
}
/**
* @brief Set the database reference
*/
@ -1683,7 +1680,7 @@ private:
};
/**
* @brief A collection of cells
* @brief A collection of cells
*/
class RDB_PUBLIC Cells
{
@ -1743,7 +1740,7 @@ public:
/**
* @brief Begin iterator (non-const)
*/
iterator begin ()
iterator begin ()
{
return m_cells.begin ();
}
@ -1751,7 +1748,7 @@ public:
/**
* @brief End iterator (non-const)
*/
iterator end ()
iterator end ()
{
return m_cells.end ();
}
@ -1784,7 +1781,7 @@ public:
/**
* @brief Get the database reference (non-const)
*/
Database *database ()
Database *database ()
{
return mp_database.get ();
}
@ -1848,9 +1845,9 @@ public:
/**
* @brief Gets a flag indicating whether the tag is a user tag or a system tag
*
*
* If this flag is false, the tag is a system tag used for tagging "waived" and
* similar conditions. Otherwise it is a user tag which can be used freely to
* similar conditions. Otherwise it is a user tag which can be used freely to
* tag arbitrary conditions.
*/
bool is_user_tag () const
@ -1863,7 +1860,7 @@ public:
*
* See \is_user_tag for details.
*/
void set_user_tag (bool user)
void set_user_tag (bool user)
{
m_is_user_tag = user;
}
@ -1881,7 +1878,7 @@ public:
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_id (id_type id)
void set_id (id_type id)
{
m_id = id;
}
@ -1900,7 +1897,7 @@ public:
* The name of the tag must not be changed when the tag is already part of a Tags collection.
* Otherwise, the tag collection becomes inconsistent.
*/
void set_name (const std::string &name)
void set_name (const std::string &name)
{
m_name = name;
}
@ -1921,7 +1918,7 @@ public:
typedef tag_list_type::const_iterator const_iterator;
/**
* @brief Default constructor for the tags list
* @brief Default constructor for the tags list
*
* This method is provided for persistency application only. It should not be used otherwise.
*/
@ -1972,16 +1969,27 @@ public:
* @brief Import a tag
*
* This method is provided for persistency application only. It should not be used otherwise.
* This will assign a new id to the tag and replace any tag with that
* This will assign a new id to the tag and replace any tag with that
* name.
*/
void import_tag (const Tag &tag);
/**
* @brief Clear the collection of tags
*
* NOTE: this will not remove the tags from items or values, so the use cases for this method
* are limited.
*/
void clear ();
/**
* @brief Removes the tag with the given ID
*
* NOTE: this will not remove the tags from items or values, so the use cases for this method
* are limited.
*/
void remove_tag (id_type id);
/**
* @brief Gets the name and user flag for a tag ID
*
@ -2013,7 +2021,7 @@ private:
/**
* @brief The database object
*/
class RDB_PUBLIC Database
class RDB_PUBLIC Database
: public gsi::ObjectBase,
public tl::Object
{
@ -2123,7 +2131,7 @@ public:
}
/**
* @brief Set the top cell name
* @brief Set the top cell name
*/
void set_top_cell_name (const std::string &topcell)
{
@ -2179,17 +2187,17 @@ public:
void import_categories (Categories *categories);
/**
* @brief Create a category and register it
* @brief Create a category and register it
*/
Category *create_category (const std::string &name);
/**
* @brief Create a category as a subcategory and register it
* @brief Create a category as a subcategory and register it
*/
Category *create_category (Category *parent, const std::string &name);
/**
* @brief Create a category as a subcategory in the container and register it
* @brief Create a category as a subcategory in the container and register it
*
* Hint: this method does not set the parent properly and must not be used
* under normal circumstances. It is provided as a internal method and
@ -2268,7 +2276,7 @@ public:
* @brief Create a cell variant and register it
*
* A cell with name name/variant combination must not exist already.
* If the variant string is empty, this method behaves the same as the
* If the variant string is empty, this method behaves the same as the
* method without variant.
*
* "layout_name" is the name of the cell in the layout. If empty, the layout
@ -2417,7 +2425,7 @@ public:
/**
* @brief Get an iterator pair that delivers the const items (ItemRef) for a given cell
*/
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell (id_type cell_id) const;
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell (id_type cell_id) const;
/**
* @brief Get an iterator pair that delivers the non-const items (ItemRef) for a given cell
@ -2427,7 +2435,7 @@ public:
/**
* @brief Get an iterator that delivers the const items (ItemRef) for a given category
*/
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_category (id_type category_id) const;
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_category (id_type category_id) const;
/**
* @brief Get an iterator that delivers the non-const items (ItemRef) for a given category
@ -2437,7 +2445,7 @@ public:
/**
* @brief Get an iterator that delivers the const items (ItemRef) for a given cell and category
*/
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell_and_category (id_type cell_id, id_type category_id) const;
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell_and_category (id_type cell_id, id_type category_id) const;
/**
* @brief Get an iterator that delivers the non-const items (ItemRef) for a given cell and category
@ -2455,7 +2463,7 @@ public:
/**
* @brief Reset the modified file
*/
void reset_modified ()
void reset_modified ()
{
m_modified = false;
}
@ -2526,7 +2534,7 @@ private:
void clear ();
void set_modified ()
void set_modified ()
{
m_modified = true;
}

View File

@ -816,7 +816,18 @@ TEST(13_ApplyIgnoreUnknownTag)
i2->values ().clear ();
i2->add_value (std::string ("xyz"), vtag22);
// values with incompatible tags are ignored -> tag2 is applied
// values with incompatible tags are ignored, but vtag1 is a common tag.
// So far, nothing is applied as the we match abc[vtag1] vs. xyz[vtag2] which is both different value and tag-
db1.apply (db2);
EXPECT_EQ (i1->tag_str (), "");
// NOTE: don't do this at home
const_cast<rdb::Tags &> (db2.tags ()).remove_tag (vtag21);
// vtag1 is no longer a common tag -> we match abc[vtag1] vs. xyz[vtag2] where vtag1 is not known on the
// other side and vtag2 is not known on the self side.
// Hence, the values are ignored and the tag is applied.
db1.apply (db2);
EXPECT_EQ (i1->tag_str (), "tag2");