Commit f1dfe12c by maarten

address/port

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@472 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent 0bdda461
......@@ -101,6 +101,7 @@ class Validator;
struct ValidateItem;
struct ValidateCategory;
struct ValidateLink;
struct ItemColumn;
struct ItemRow;
......@@ -207,6 +208,8 @@ class Datablock
std::tuple<iterator,bool> emplace(const std::string& name);
bool isValid();
void validateLinks() const;
void setValidator(Validator* v);
// this one only looks up a Category, returns nullptr if it does not exist
......@@ -1105,7 +1108,7 @@ class Category
bool operator!=(const const_iterator& rhs) const { return not (mCurrent == rhs.mCurrent); }
private:
const Row mCurrent;
Row mCurrent;
};
const_iterator begin() const;
......@@ -1121,7 +1124,7 @@ class Category
Row operator[](Condition&& cond);
RowSet find(Condition&& cond);
bool exists(Condition&& cond);
bool exists(Condition&& cond) const;
RowSet orderBy(const string& Item)
{ return orderBy({ Item }); }
......@@ -1147,8 +1150,10 @@ class Category
/// an orphan is a row that is the child side of one or more
/// links and for which there is no single parent left.
bool isOrphan(Row r);
bool hasParent(Row r, const Category& parentCat, const ValidateLink& link) const;
bool isValid();
void validateLinks() const;
const Validator& getValidator() const;
const ValidateCategory* getCatValidator() const { return mCatValidator; }
......@@ -1225,6 +1230,7 @@ class File
void loadDictionary(std::istream& is); // load dictionary from input stream
bool isValid();
void validateLinks() const;
Datablock& firstDatablock() { return *mHead; }
void append(Datablock* e);
......
......@@ -118,6 +118,7 @@ struct ValidateLink
std::vector<std::string> mParentKeys;
std::string mChildCategory;
std::vector<std::string> mChildKeys;
std::string mLinkGroupLabel;
};
// --------------------------------------------------------------------
......
......@@ -361,6 +361,12 @@ bool Datablock::isValid()
return result;
}
void Datablock::validateLinks() const
{
for (auto& cat: *this)
cat.validateLinks();
}
void Datablock::setValidator(Validator* v)
{
mValidator = v;
......@@ -1333,7 +1339,7 @@ RowSet Category::find(Condition&& cond)
return result;
}
bool Category::exists(Condition&& cond)
bool Category::exists(Condition&& cond) const
{
bool result = false;
......@@ -1597,6 +1603,21 @@ Category::const_iterator Category::end() const
return const_iterator(nullptr);
}
bool Category::hasParent(Row r, const Category& parentCat, const ValidateLink& link) const
{
Condition cond;
for (size_t ix = 0; ix < link.mChildKeys.size(); ++ix)
{
const char* value = r[link.mChildKeys[ix]].c_str();
cond = move(cond) && (Key(link.mParentKeys[ix]) == value);
}
if (VERBOSE > 2)
cerr << "Check condition '" << cond << "' in parent category " << link.mParentCategory << " for child cat " << mName << endl;
return parentCat.exists(std::move(cond));
}
bool Category::isOrphan(Row r)
{
// be safe
......@@ -1728,6 +1749,29 @@ bool Category::isValid()
return result;
}
void Category::validateLinks() const
{
auto& validator = getValidator();
for (auto linkValidator: validator.getLinksForChild(mName))
{
auto parent = mDb.get(linkValidator->mParentCategory);
if (parent == nullptr)
continue;
size_t missing = 0;
for (auto r: *this)
if (not hasParent(r, *parent, *linkValidator))
++missing;
if (missing)
{
cerr << "Links for " << linkValidator->mLinkGroupLabel << " are incomplete" << endl
<< " There are " << missing << " items in " << mName << " that don't have matching parent items in " << parent->mName << endl;
}
}
}
const Validator& Category::getValidator() const
{
if (mValidator == nullptr)
......@@ -1792,6 +1836,12 @@ auto Category::iterator::operator++() -> iterator&
return *this;
}
auto Category::const_iterator::operator++() -> const_iterator&
{
mCurrent = Row(mCurrent.data()->mNext);
return *this;
}
namespace detail
{
......@@ -2592,6 +2642,12 @@ bool File::isValid()
return result;
}
void File::validateLinks() const
{
for (auto d = mHead; d != nullptr; d = d->mNext)
d->validateLinks();
}
const Validator& File::getValidator() const
{
if (mValidator == nullptr)
......
......@@ -915,6 +915,8 @@ void DictParser::linkItems()
// keys.insert(civ->mTag);
// }
auto& linkedGroup = dict["pdbx_item_linked_group"];
// now store the links in the validator
for (auto& kv: linkIndex)
{
......@@ -922,7 +924,14 @@ void DictParser::linkItems()
std::tie(link.mParentCategory, link.mChildCategory, link.mLinkGroupId) = kv.first;
std::tie(link.mParentKeys, link.mChildKeys) = linkKeys[kv.second];
// look up the label
for (auto r: linkedGroup.find(cif::Key("category_id") == link.mChildCategory and cif::Key("link_group_id") == link.mLinkGroupId))
{
link.mLinkGroupLabel = r["label"].as<string>();
break;
}
mValidator.addLinkValidator(move(link));
}
......
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