Use dependency graph when deleting objects

refs #9096
This commit is contained in:
Gunnar Beutner 2015-08-25 16:43:48 +02:00
parent 2a9ac26338
commit de09a562f6
3 changed files with 38 additions and 10 deletions

View File

@ -24,6 +24,7 @@
#include "config/configwriter.hpp" #include "config/configwriter.hpp"
#include "base/exception.hpp" #include "base/exception.hpp"
#include "base/serializer.hpp" #include "base/serializer.hpp"
#include "base/dependencygraph.hpp"
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
@ -145,15 +146,26 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
return true; return true;
} }
bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, const Array::Ptr& errors) bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors)
{ {
if (object->GetModule() != "_api") { std::vector<Object::Ptr> parents = DependencyGraph::GetParents(object);
if (!parents.empty() && !cascade) {
if (errors) if (errors)
errors->Add("Object cannot be deleted because it was not created using the API."); errors->Add("Object cannot be deleted because other objects depend on it. Use cascading delete to delete it anyway.");
return false; return false;
} }
BOOST_FOREACH(const Object::Ptr& pobj, parents) {
ConfigObject::Ptr parentObj = dynamic_pointer_cast<ConfigObject>(pobj);
if (!parentObj)
continue;
DeleteObjectHelper(parentObj, cascade, errors);
}
Type::Ptr type = object->GetReflectionType(); Type::Ptr type = object->GetReflectionType();
ConfigItem::Ptr item = ConfigItem::GetObject(type->GetName(), object->GetName()); ConfigItem::Ptr item = ConfigItem::GetObject(type->GetName(), object->GetName());
@ -191,3 +203,15 @@ bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, const Ar
return true; return true;
} }
bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors)
{
if (object->GetModule() != "_api") {
if (errors)
errors->Add("Object cannot be deleted because it was not created using the API.");
return false;
}
return DeleteObjectHelper(object, cascade, errors);
}

View File

@ -44,10 +44,11 @@ public:
const Array::Ptr& templates, const Dictionary::Ptr& attrs, const Array::Ptr& templates, const Dictionary::Ptr& attrs,
const Array::Ptr& errors); const Array::Ptr& errors);
static bool DeleteObject(const ConfigObject::Ptr& object, const Array::Ptr& errors); static bool DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
private: private:
static String EscapeName(const String& name); static String EscapeName(const String& name);
static bool DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
}; };
} }

View File

@ -60,6 +60,8 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
std::vector<ConfigObject::Ptr> objs = FilterUtility::GetFilterTargets(qd, params); std::vector<ConfigObject::Ptr> objs = FilterUtility::GetFilterTargets(qd, params);
bool cascade = HttpUtility::GetLastParameter(params, "cascade");
Array::Ptr results = new Array(); Array::Ptr results = new Array();
BOOST_FOREACH(const ConfigObject::Ptr& obj, objs) { BOOST_FOREACH(const ConfigObject::Ptr& obj, objs) {
@ -70,9 +72,10 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
Array::Ptr errors = new Array(); Array::Ptr errors = new Array();
if (!ConfigObjectUtility::DeleteObject(obj, errors)) { if (!ConfigObjectUtility::DeleteObject(obj, cascade, errors)) {
result1->Set("code", 500); result1->Set("code", 500);
result1->Set("status", "Object could not be deleted."); result1->Set("status", "Object could not be deleted.");
result1->Set("errors", errors);
} else { } else {
result1->Set("code", 200); result1->Set("code", 200);
result1->Set("status", "Object was deleted."); result1->Set("status", "Object was deleted.");