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
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
{
Condition() : mImpl(new detail::AllConditionImpl()) {}
Condition(detail::ConditionImpl* impl) : mImpl(impl) {}
Condition(Condition&& rhs)
......@@ -920,6 +927,13 @@ inline Condition operator||(Condition&& a, Condition&& 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 Key
......
......@@ -113,8 +113,10 @@ struct ValidateCategory
struct ValidateLink
{
ValidateItem* mParent;
ValidateItem* mChild;
std::string mParentCategory;
std::vector<std::string> mParentKeys;
std::string mChildCategory;
std::vector<std::string> mChildKeys;
};
// --------------------------------------------------------------------
......@@ -140,8 +142,8 @@ class Validator
const ValidateCategory* getValidatorForCategory(std::string category) const;
void addLinkValidator(ValidateLink&& v);
std::vector<ValidateLink> getLinksForParent(std::string category, std::string item) const;
std::vector<ValidateLink> getLinksForChild(std::string category, std::string item) const;
std::vector<const ValidateLink*> getLinksForParent(const std::string& category) const;
std::vector<const ValidateLink*> getLinksForChild(const std::string& category) const;
void reportError(const std::string& msg, bool fatal);
......
......@@ -1429,6 +1429,8 @@ void Category::erase(Condition&& cond)
remove.push_back(r);
}
cerr << "Erasing " << remove.size() << " entries" << endl;
for (auto r: remove)
erase(r);
}
......@@ -1443,50 +1445,96 @@ void Category::erase(Row r)
iset keys;
if (mCatValidator)
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);
if (childCat == nullptr)
continue;
auto rows = childCat->find(Key(l.mChild->mTag) == value);
for (auto& cr: rows)
childCat->erase(cr);
for (size_t ix = 0; ix < link->mParentKeys.size(); ++ix)
{
const char* value = r[link->mParentKeys[ix]].c_str();
cond = move(cond) && (Key(link->mChildKeys[ix]) == value);
}
// 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)
cerr << "about to erase: " << cond << endl;
childCat->erase(move(cond));
}
// for (auto& col: mColumns)
// {
// for (auto& l: mValidator->getLinksForParent(mName, col.mName))
// {
// if (child->mCategory == nullptr)
// continue;
// assert(l.mParent == col.mValidator);
//
//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)
// 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)
// {
//cerr << __FILE__ << ':' << __LINE__ << " erase" << endl;
// 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)
throw runtime_error("erase");
......
......@@ -858,11 +858,15 @@ void DictParser::linkItems()
error("no datablock");
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"])
{
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);
if (civ == nullptr)
......@@ -872,26 +876,54 @@ void DictParser::linkItems()
if (piv == nullptr)
error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
// civ->setParent(piv);
// civ->addLinked(piv, piv->mTag, civ->mTag);
mValidator.addLinkValidator({piv, civ});
auto key = make_tuple(piv->mCategory->mName, civ->mCategory->mName, link_group_id);
if (not linkIndex.count(key))
{
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;
std::tie(child, parent) = li;
ValidateLink link;
std::tie(link.mParentCategory, link.mChildCategory, std::ignore) = kv.first;
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");
std::tie(link.mParentKeys, link.mChildKeys) = linkKeys[kv.second];
// civ->addLinked(piv, piv->mTag, civ->mTag);
mValidator.addLinkValidator({piv, civ});
mValidator.addLinkValidator(move(link));
}
// now make sure the itemType is specified for all itemValidators
......
......@@ -264,34 +264,57 @@ ValidateItem* Validator::getValidatorForItem(string tag) const
void Validator::addLinkValidator(ValidateLink&& v)
{
if (v.mChild->mType == nullptr and v.mParent->mType != nullptr)
v.mChild->mType = v.mParent->mType;
assert(v.mParentKeys.size() == v.mChildKeys.size());
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
{
vector<ValidateLink> result;
for (auto& l: mLinkValidators)
if (ccv == nullptr)
throw runtime_error("unknown child category " + v.mChildCategory);
for (size_t i = 0; i < v.mParentKeys.size(); ++i)
{
if (l.mParent->mCategory->mName == category and l.mParent->mTag == item)
result.push_back(l);
}
return result;
auto piv = pcv->getValidatorForItem(v.mParentKeys[i]);
if (piv == nullptr)
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)
{
if (l.mChild->mCategory->mName == category and l.mChild->mTag == item)
result.push_back(l);
if (l.mParentCategory == category)
result.push_back(&l);
}
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)
{
......@@ -301,5 +324,4 @@ void Validator::reportError(const string& msg, bool fatal)
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