Commit 4ddfe657 by maarten

pas op, niet goed, werk aan erase in progress

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@389 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent 95d0d557
...@@ -641,10 +641,17 @@ struct ConditionImpl ...@@ -641,10 +641,17 @@ struct ConditionImpl
virtual std::string str() const = 0; virtual std::string str() const = 0;
}; };
struct AllConditionImpl : public ConditionImpl
{
virtual bool test(const Category& c, const Row& r) const { return true; }
virtual std::string str() const { return "ALL"; }
};
} }
struct Condition struct Condition
{ {
Condition() : mImpl(new detail::AllConditionImpl()) {}
Condition(detail::ConditionImpl* impl) : mImpl(impl) {} Condition(detail::ConditionImpl* impl) : mImpl(impl) {}
Condition(Condition&& rhs) Condition(Condition&& rhs)
...@@ -920,6 +927,13 @@ inline Condition operator||(Condition&& a, Condition&& b) ...@@ -920,6 +927,13 @@ inline Condition operator||(Condition&& a, Condition&& b)
return Condition(new detail::orConditionImpl(std::move(a), std::move(b))); return Condition(new detail::orConditionImpl(std::move(a), std::move(b)));
} }
inline
std::ostream& operator<<(std::ostream& os, const Condition& rhs)
{
os << rhs.str();
return os;
}
struct Empty {}; struct Empty {};
struct Key struct Key
......
...@@ -113,8 +113,10 @@ struct ValidateCategory ...@@ -113,8 +113,10 @@ struct ValidateCategory
struct ValidateLink struct ValidateLink
{ {
ValidateItem* mParent; std::string mParentCategory;
ValidateItem* mChild; std::vector<std::string> mParentKeys;
std::string mChildCategory;
std::vector<std::string> mChildKeys;
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -140,8 +142,8 @@ class Validator ...@@ -140,8 +142,8 @@ class Validator
const ValidateCategory* getValidatorForCategory(std::string category) const; const ValidateCategory* getValidatorForCategory(std::string category) const;
void addLinkValidator(ValidateLink&& v); void addLinkValidator(ValidateLink&& v);
std::vector<ValidateLink> getLinksForParent(std::string category, std::string item) const; std::vector<const ValidateLink*> getLinksForParent(const std::string& category) const;
std::vector<ValidateLink> getLinksForChild(std::string category, std::string item) const; std::vector<const ValidateLink*> getLinksForChild(const std::string& category) const;
void reportError(const std::string& msg, bool fatal); void reportError(const std::string& msg, bool fatal);
......
...@@ -1429,6 +1429,8 @@ void Category::erase(Condition&& cond) ...@@ -1429,6 +1429,8 @@ void Category::erase(Condition&& cond)
remove.push_back(r); remove.push_back(r);
} }
cerr << "Erasing " << remove.size() << " entries" << endl;
for (auto r: remove) for (auto r: remove)
erase(r); erase(r);
} }
...@@ -1443,50 +1445,96 @@ void Category::erase(Row r) ...@@ -1443,50 +1445,96 @@ void Category::erase(Row r)
iset keys; iset keys;
if (mCatValidator) if (mCatValidator)
keys = iset(mCatValidator->mKeys.begin(), mCatValidator->mKeys.end()); keys = iset(mCatValidator->mKeys.begin(), mCatValidator->mKeys.end());
for (auto& col: mColumns) // links are created based on the _pdbx_item_linked_group_list entries
// in mmcif_pdbx.dic dictionary.
//
// For each link group in _pdbx_item_linked_group_list
// a set of keys from one category is mapped to another.
// If all values in a child are the same as the specified parent ones
// the child is removed as well, recursively of course.
for (auto& link: mValidator->getLinksForParent(mName))
{ {
for (auto& l: mValidator->getLinksForParent(mName, col.mName))
{
assert(l.mParent == col.mValidator);
if (not keys.count(col.mName))
continue;
const char* value = r[col.mName].c_str(); cerr << "Follow links from " << endl
<< "\t" << mName << " - " << ba::join(link->mParentKeys, ", ")
<< "\t" << "to" << endl
<< "\t" << link->mChildCategory << " - " << ba::join(link->mChildKeys, ", ")
<< endl;
auto childCat = mDb.get(link->mChildCategory);
if (childCat == nullptr)
continue;
Condition cond;
auto childCat = mDb.get(l.mChild->mCategory->mName); for (size_t ix = 0; ix < link->mParentKeys.size(); ++ix)
if (childCat == nullptr) {
continue; const char* value = r[link->mParentKeys[ix]].c_str();
auto rows = childCat->find(Key(l.mChild->mTag) == value); cond = move(cond) && (Key(link->mChildKeys[ix]) == value);
for (auto& cr: rows)
childCat->erase(cr);
} }
// auto iv = col.mValidator; cerr << "about to erase: " << cond << endl;
// if (iv == nullptr or iv->mChildren.empty())
// continue; childCat->erase(move(cond));
// }
// if (not keys.count(col.mName))
// continue; // for (auto& col: mColumns)
// // {
// const char* value = r[col.mName].c_str(); // for (auto& l: mValidator->getLinksForParent(mName, col.mName))
//
// for (auto child: iv->mChildren)
// { // {
// if (child->mCategory == nullptr) // assert(l.mParent == col.mValidator);
// continue; //
//cerr << __FILE__ << ':' << __LINE__ << " "
// << l.mParent->mCategory->mName << '.' << l.mParent->mTag << " linked to "
// << l.mChild->mCategory->mName << '.' << l.mChild->mTag << endl;
// //
// auto childCat = mDb.get(child->mCategory->mName); //// if (not keys.count(col.mName))
//// continue;
//
//cerr << __FILE__ << ':' << __LINE__ << endl;
//
// const char* value = r[col.mName].c_str();
//
// auto childCat = mDb.get(l.mChild->mCategory->mName);
// if (childCat == nullptr) // if (childCat == nullptr)
// continue; // continue;
// //
// auto rows = childCat->find(Key(child->mTag) == value); //cerr << __FILE__ << ':' << __LINE__ << endl;
//
// auto rows = childCat->find(Key(l.mChild->mTag) == value);
// for (auto& cr: rows) // for (auto& cr: rows)
// {
//cerr << __FILE__ << ':' << __LINE__ << " erase" << endl;
// childCat->erase(cr); // childCat->erase(cr);
// }
// } // }
} //
//// auto iv = col.mValidator;
//// if (iv == nullptr or iv->mChildren.empty())
//// continue;
////
//// if (not keys.count(col.mName))
//// continue;
////
//// const char* value = r[col.mName].c_str();
////
//// for (auto child: iv->mChildren)
//// {
//// if (child->mCategory == nullptr)
//// continue;
////
//// auto childCat = mDb.get(child->mCategory->mName);
//// if (childCat == nullptr)
//// continue;
////
//// auto rows = childCat->find(Key(child->mTag) == value);
//// for (auto& cr: rows)
//// childCat->erase(cr);
//// }
// }
if (mHead == nullptr) if (mHead == nullptr)
throw runtime_error("erase"); throw runtime_error("erase");
......
...@@ -858,11 +858,15 @@ void DictParser::linkItems() ...@@ -858,11 +858,15 @@ void DictParser::linkItems()
error("no datablock"); error("no datablock");
auto& dict = *mDataBlock; auto& dict = *mDataBlock;
map<tuple<string,string,int>,size_t> linkIndex;
vector<tuple<vector<string>,vector<string>>> linkKeys;
for (auto gl: dict["pdbx_item_linked_group_list"]) for (auto gl: dict["pdbx_item_linked_group_list"])
{ {
string child, parent; string child, parent;
cif::tie(child, parent) = gl.get("child_name", "parent_name"); int link_group_id;
cif::tie(child, parent, link_group_id) = gl.get("child_name", "parent_name", "link_group_id");
auto civ = mValidator.getValidatorForItem(child); auto civ = mValidator.getValidatorForItem(child);
if (civ == nullptr) if (civ == nullptr)
...@@ -872,26 +876,54 @@ void DictParser::linkItems() ...@@ -872,26 +876,54 @@ void DictParser::linkItems()
if (piv == nullptr) if (piv == nullptr)
error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified"); error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
// civ->setParent(piv); auto key = make_tuple(piv->mCategory->mName, civ->mCategory->mName, link_group_id);
// civ->addLinked(piv, piv->mTag, civ->mTag); if (not linkIndex.count(key))
mValidator.addLinkValidator({piv, civ}); {
linkIndex[key] = linkKeys.size();
linkKeys.push_back({});
}
size_t ix = linkIndex.at(key);
get<0>(linkKeys.at(ix)).push_back(piv->mTag);
get<1>(linkKeys.at(ix)).push_back(civ->mTag);
} }
for (auto li: mImpl->mLinkedItems) // for (auto li: mImpl->mLinkedItems)
// {
// string child, parent;
// std::tie(child, parent) = li;
//
// auto civ = mValidator.getValidatorForItem(child);
// if (civ == nullptr)
// error("in pdbx_item_linked_group_list, item '" + child + "' is not specified");
//
// auto piv = mValidator.getValidatorForItem(parent);
// if (piv == nullptr)
// error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
//
// auto key = make_tuple(piv->mCategory->mName, civ->mCategory->mName, piv->mTag);
// if (not linkIndex.count(key))
// {
// linkIndex[key] = linkKeys.size();
// linkKeys.push_back({});
// }
//
// size_t ix = linkIndex.at(key);
// auto& keys = linkKeys.at(ix);
//
// keys.insert(civ->mTag);
// }
// now store the links in the validator
for (auto& kv: linkIndex)
{ {
string child, parent; ValidateLink link;
std::tie(child, parent) = li; std::tie(link.mParentCategory, link.mChildCategory, std::ignore) = kv.first;
auto civ = mValidator.getValidatorForItem(child); std::tie(link.mParentKeys, link.mChildKeys) = linkKeys[kv.second];
if (civ == nullptr)
error("in pdbx_item_linked_group_list, item '" + child + "' is not specified");
auto piv = mValidator.getValidatorForItem(parent);
if (piv == nullptr)
error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
// civ->addLinked(piv, piv->mTag, civ->mTag); mValidator.addLinkValidator(move(link));
mValidator.addLinkValidator({piv, civ});
} }
// now make sure the itemType is specified for all itemValidators // now make sure the itemType is specified for all itemValidators
......
...@@ -264,34 +264,57 @@ ValidateItem* Validator::getValidatorForItem(string tag) const ...@@ -264,34 +264,57 @@ ValidateItem* Validator::getValidatorForItem(string tag) const
void Validator::addLinkValidator(ValidateLink&& v) void Validator::addLinkValidator(ValidateLink&& v)
{ {
if (v.mChild->mType == nullptr and v.mParent->mType != nullptr) assert(v.mParentKeys.size() == v.mChildKeys.size());
v.mChild->mType = v.mParent->mType; if (v.mParentKeys.size() != v.mChildKeys.size())
throw runtime_error("unequal number of keys for parent and child in link");
mLinkValidators.emplace_back(move(v)); auto pcv = getValidatorForCategory(v.mParentCategory);
} auto ccv = getValidatorForCategory(v.mChildCategory);
if (pcv == nullptr)
throw runtime_error("unknown parent category " + v.mParentCategory);
vector<ValidateLink> Validator::getLinksForParent(string category, string item) const if (ccv == nullptr)
{ throw runtime_error("unknown child category " + v.mChildCategory);
vector<ValidateLink> result;
for (auto& l: mLinkValidators) for (size_t i = 0; i < v.mParentKeys.size(); ++i)
{ {
if (l.mParent->mCategory->mName == category and l.mParent->mTag == item) auto piv = pcv->getValidatorForItem(v.mParentKeys[i]);
result.push_back(l);
} if (piv == nullptr)
return result; throw runtime_error("unknown parent tag _" + v.mParentCategory + '.' + v.mParentKeys[i]);
auto civ = ccv->getValidatorForItem(v.mChildKeys[i]);
if (civ == nullptr)
throw runtime_error("unknown child tag _" + v.mChildCategory + '.' + v.mChildKeys[i]);
if (civ->mType == nullptr and piv->mType != nullptr)
const_cast<ValidateItem*>(civ)->mType = piv->mType;
}
mLinkValidators.emplace_back(move(v));
} }
vector<ValidateLink> Validator::getLinksForChild(string category, string item) const vector<const ValidateLink*> Validator::getLinksForParent(const string& category) const
{ {
vector<ValidateLink> result; vector<const ValidateLink*> result;
for (auto& l: mLinkValidators) for (auto& l: mLinkValidators)
{ {
if (l.mChild->mCategory->mName == category and l.mChild->mTag == item) if (l.mParentCategory == category)
result.push_back(l); result.push_back(&l);
} }
return result; return result;
} }
//const ValidateLink* Validator::getLinksForChild(const string& category) const
//{
// auto i = find_if(mLinkValidators.begin(), mLinkValidators.end(),
// [&](auto& l) { return l.mChildCategory == category; });
//
// return i == mLinkValidators.end() ? nullptr : &(*i);
//}
void Validator::reportError(const string& msg, bool fatal) void Validator::reportError(const string& msg, bool fatal)
{ {
...@@ -301,5 +324,4 @@ void Validator::reportError(const string& msg, bool fatal) ...@@ -301,5 +324,4 @@ void Validator::reportError(const string& msg, bool fatal)
cerr << msg << endl; cerr << msg << endl;
} }
} }
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