From 7487d564d30d954e483a559a438a3f0a1ebc327b Mon Sep 17 00:00:00 2001 From: randomdan Date: Thu, 31 Mar 2011 16:18:22 +0000 Subject: Add conditional execution from sqlTask And a good tidy up in a few other places --- project2/Jamfile.jam | 2 +- project2/cgi/cgiStageRequest.cpp | 2 +- project2/commonObjects.cpp | 2 +- project2/console/consoleAppEngine.cpp | 2 +- project2/if.cpp | 33 +++++++++-------- project2/iterate.cpp | 3 +- project2/library.cpp | 41 ++++++++++++++++++++ project2/library.h | 17 +++++++++ project2/noOutputExecute.cpp | 13 ++----- project2/noOutputExecute.h | 5 +-- project2/rowView.cpp | 3 +- project2/sqlMergeTask.cpp | 3 +- project2/sqlTask.cpp | 35 +++++++++++++++++- project2/sqlTask.h | 5 +++ project2/xmlObjectLoader.cpp | 70 +++++++++++++---------------------- project2/xmlObjectLoader.h | 1 + project2/xmlPresenter.cpp | 2 +- project2/xmlStorage.h | 22 ++++++++--- 18 files changed, 170 insertions(+), 91 deletions(-) create mode 100644 project2/library.cpp create mode 100644 project2/library.h diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index b82c457..0a2c778 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -54,7 +54,7 @@ lib p2uuid : ; lib p2common : - appEngine.cpp dataSource.cpp environment.cpp fileStarGlibIoChannel.cpp iHaveParameters.cpp + appEngine.cpp dataSource.cpp environment.cpp fileStarGlibIoChannel.cpp iHaveParameters.cpp library.cpp iterate.cpp paramChecker.cpp presenter.cpp rawView.cpp logger.cpp if.cpp xmlScriptParser.cpp sourceObject.cpp task.cpp variables.cpp variableConvert.cpp view.cpp xmlObjectLoader.cpp exceptions.cpp sessionClearTask.cpp session.cpp sessionSetTask.cpp commonObjects.cpp xmlPresenter.cpp requestHost.cpp diff --git a/project2/cgi/cgiStageRequest.cpp b/project2/cgi/cgiStageRequest.cpp index 774b67d..22cb2e8 100644 --- a/project2/cgi/cgiStageRequest.cpp +++ b/project2/cgi/cgiStageRequest.cpp @@ -13,7 +13,7 @@ CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, const rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true"; localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local"; - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(Storer::into(¶meterChecks)); loader.supportedStorers.insert(Storer::into(&rowSets)); loader.supportedStorers.insert(new NOEErrorStorer(&normTasks, &errorTasks)); diff --git a/project2/commonObjects.cpp b/project2/commonObjects.cpp index d661588..039e105 100644 --- a/project2/commonObjects.cpp +++ b/project2/commonObjects.cpp @@ -24,7 +24,7 @@ CommonObjects::loadDataSource(const std::string & name) const { XmlScriptParser xml(ApplicationEngine::getCurrent()->env()->getDatasourceRoot(), name, true); - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(Storer::into(&datasources)); loader.collectAll(xml.get_document()->get_root_node(), false); diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index 645fde3..3db8ce9 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -64,7 +64,7 @@ ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * en rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true"; localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local"; - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(Storer::into(¶meterChecks)); loader.supportedStorers.insert(new NOEErrorStorer(&normTasks, &errorTasks)); loader.supportedStorers.insert(Storer::into(&rowSets)); diff --git a/project2/if.cpp b/project2/if.cpp index 3474815..5fa7a8c 100644 --- a/project2/if.cpp +++ b/project2/if.cpp @@ -1,8 +1,8 @@ #include "if.h" -#include "appEngine.h" #include "logger.h" #include "xmlObjectLoader.h" #include +#include DECLARE_LOADER("if", If); @@ -11,29 +11,30 @@ SimpleMessageException(IfModeIsNonsense); IfSet::IfSet(const xmlpp::Element * e) : mode(e->get_attribute_value("mode") == "or" ? Or : And) { - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(Storer::into(&checks)); loader.collectAll(e, true, IgnoreUnsupported); } +template +bool all(const Range & c, const Pred & p) +{ + return (std::find_if(c.begin(), c.end(), !p) == c.end()); +} +template +bool any(const Range & c, const Pred & p) +{ + return (std::find_if(c.begin(), c.end(), p) != c.end()); +} + bool IfSet::passes() const { if (mode == And) { - BOOST_FOREACH(const ParamCheckers::value_type & pc, checks.get()) { - if (!pc->performCheck()) { - return false; - } - } - return true; + return all(checks.get(), boost::bind(&ParamChecker::performCheck, _1)); } - else { - BOOST_FOREACH(const ParamCheckers::value_type & pc, checks.get()) { - if (pc->performCheck()) { - return true; - } - } - return false; + else if (mode == Or) { + return any(checks.get(), boost::bind(&ParamChecker::performCheck, _1)); } throw IfModeIsNonsense(getName()); } @@ -45,7 +46,7 @@ If::If(const xmlpp::Element * e) : IfSet(e), localErrorHandling(e->get_attribute_value("errorHandling") == "local") { - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(new NOEErrorStorer(&normNOEs, &errorNOEs)); loader.supportedStorers.insert(Storer::into(&subViews)); loader.collectAll(e, true, IgnoreUnsupported); diff --git a/project2/iterate.cpp b/project2/iterate.cpp index 569bb3d..e7af8f1 100644 --- a/project2/iterate.cpp +++ b/project2/iterate.cpp @@ -1,5 +1,4 @@ #include "iterate.h" -#include "appEngine.h" #include #include "xmlObjectLoader.h" @@ -11,7 +10,7 @@ Iterate::Iterate(const xmlpp::Element * p) : RowProcessor(p), localErrorHandling(p->get_attribute_value("errorHandling") == "local") { - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(new NOEErrorStorer(&normNOEs, &errorNOEs)); loader.collectAll(p, true, IgnoreUnsupported); } diff --git a/project2/library.cpp b/project2/library.cpp new file mode 100644 index 0000000..1941254 --- /dev/null +++ b/project2/library.cpp @@ -0,0 +1,41 @@ +#include +#include "xmlStorage.h" +#include "exceptions.h" +#include "library.h" + +SimpleMessageException(LoadLibraryFailed); +SimpleMessageException(UnloadLibraryFailed); + +Library::Library(const xmlpp::Element * p) : + SourceObject(p), + handle(dlopen(p->get_attribute_value("path").c_str(), RTLD_NOW)) +{ + if (!handle) { + throw LoadLibraryFailed(dlerror()); + } +} + +Library::~Library() +{ + if (dlclose(handle)) { + throw UnloadLibraryFailed(dlerror()); + } +} + +void +Library::loadComplete(const CommonObjects*) +{ +} + +Storage::Objects libraries; +class LibraryLoader : public ElementLoaderImpl { + public: + void onIteration() + { + libraries.clear(); + } +}; + +DECLARE_CUSTOM_LOADER("library", LibraryLoader); + + diff --git a/project2/library.h b/project2/library.h new file mode 100644 index 0000000..4dfdadd --- /dev/null +++ b/project2/library.h @@ -0,0 +1,17 @@ +#ifndef LIBRARY_LOADER_H +#define LIBRARY_LOADER_H + +#include "xmlObjectLoader.h" + +class Library : public SourceObject { + public: + Library(const xmlpp::Element * p); + ~Library(); + void loadComplete(const CommonObjects*); + private: + void * handle; +}; +extern Storage::Objects libraries; + +#endif + diff --git a/project2/noOutputExecute.cpp b/project2/noOutputExecute.cpp index 4416933..6f599c4 100644 --- a/project2/noOutputExecute.cpp +++ b/project2/noOutputExecute.cpp @@ -15,14 +15,7 @@ NOEErrorStorer::NOEErrorStorer(Map m, Map em) : { } -bool -NOEErrorStorer::save(SourceObjectPtr obj, const xmlpp::Element * p) const { - boost::intrusive_ptr O = boost::dynamic_pointer_cast(obj); - if (O) { - if (((p->get_attribute_value("onerror") == "true") ? errorMap : map)->insert(O).second) { - return true; - } - throw StoreFailed(obj->name); - } - return false; +NOEErrorStorer::Map +NOEErrorStorer::getMap(const xmlpp::Element * p) const { + return ((p->get_attribute_value("onerror") == "true") ? errorMap : map); } diff --git a/project2/noOutputExecute.h b/project2/noOutputExecute.h index 87c17a7..fe1c638 100644 --- a/project2/noOutputExecute.h +++ b/project2/noOutputExecute.h @@ -17,11 +17,10 @@ class NoOutputExecute : public virtual SourceObject { virtual void execute() const = 0; }; -class NOEErrorStorer : public Storer { +class NOEErrorStorer : public StorerBase { public: - typedef Storage::ObjectsPtr Map; NOEErrorStorer(Map m, Map em); - bool save(SourceObjectPtr obj, const xmlpp::Element *) const; + Map getMap(const xmlpp::Element *) const; Map map, errorMap; }; diff --git a/project2/rowView.cpp b/project2/rowView.cpp index 541bf5e..cdbe071 100644 --- a/project2/rowView.cpp +++ b/project2/rowView.cpp @@ -1,5 +1,4 @@ #include "rowView.h" -#include "appEngine.h" #include "presenter.h" #include "xmlObjectLoader.h" #include @@ -21,7 +20,7 @@ RowView::RowView(const xmlpp::Element * p) : Variable::makeParent(elem->get_child_text()->get_content(), elem->get_attribute_value("source") == "attribute", 0))); } } - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(Storer::into(&subViews)); loader.collectAll(p, true, IgnoreUnsupported); } diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp index 84feb18..a4c8611 100644 --- a/project2/sqlMergeTask.cpp +++ b/project2/sqlMergeTask.cpp @@ -1,5 +1,4 @@ #include "sqlMergeTask.h" -#include "appEngine.h" #include "commonObjects.h" #include "rdbmsDataSource.h" #include "exceptions.h" @@ -57,7 +56,7 @@ SqlMergeTask::SqlMergeTask(const xmlpp::Element * p) : dtable(p->get_attribute_value("targettable")), dtablet(stringf("tmp_%s_%d", dtable.c_str(), getpid())) { - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(Storer::into(&sources)); loader.collectAll(p, true); diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp index e145a3d..0b58423 100644 --- a/project2/sqlTask.cpp +++ b/project2/sqlTask.cpp @@ -7,6 +7,24 @@ #include "sqlVariableBinder.h" DECLARE_LOADER("sqltask", SqlTask); +StaticMessageException(RunOnNotSpecified, "runon attribute must be specified"); + +class SqlIfChangesStorer : public StorerBase { + public: + SqlIfChangesStorer(Map c, Map nc) : + changes(c), + noChanges(nc) + { + } + Map getMap(const xmlpp::Element * p) const { + xmlpp::Attribute * runon = p->get_attribute("runon"); + if (!runon) { + throw RunOnNotSpecified(); + } + return ((runon->get_value() == "changes") ? changes : noChanges); + } + Map changes, noChanges; +}; SqlTask::SqlTask(const xmlpp::Element * p) : SourceObject(p), @@ -16,6 +34,9 @@ SqlTask::SqlTask(const xmlpp::Element * p) : sql(xmlChildText(p, "sql")), modify(NULL) { + LoaderBase loader(true); + loader.supportedStorers.insert(new SqlIfChangesStorer(&changesNOEs, &noChangesNOEs)); + loader.collectAll(p, true, IgnoreUnsupported); } SqlTask::~SqlTask() @@ -33,8 +54,18 @@ void SqlTask::execute() const { BOOST_FOREACH(Parameters::value_type p, parameters) { - boost::apply_visitor(SqlVariableBinder(modify, atoi(p.second->name.c_str())), p.second->value); + boost::apply_visitor(SqlVariableBinder(modify, + atoi(p.second->name.c_str())), p.second->value); + } + if (modify->execute() == 0) { + BOOST_FOREACH(const SubNOEs::value_type & sq, noChangesNOEs.get()) { + sq->execute(); + } + } + else { + BOOST_FOREACH(const SubNOEs::value_type & sq, changesNOEs.get()) { + sq->execute(); + } } - modify->execute(); } diff --git a/project2/sqlTask.h b/project2/sqlTask.h index d8f9fe1..83f4062 100644 --- a/project2/sqlTask.h +++ b/project2/sqlTask.h @@ -19,6 +19,11 @@ class SqlTask : public Task, IHaveParameters { const Variable dataSource; const std::string sql; + + typedef Storage::Objects SubNOEs; + SubNOEs changesNOEs; + SubNOEs noChangesNOEs; + protected: mutable DB::ModifyCommand * modify; }; diff --git a/project2/xmlObjectLoader.cpp b/project2/xmlObjectLoader.cpp index 30e2865..9187c82 100644 --- a/project2/xmlObjectLoader.cpp +++ b/project2/xmlObjectLoader.cpp @@ -1,55 +1,32 @@ #include "xmlObjectLoader.h" #include "xmlStorage.h" -#include "exceptions.h" #include "logger.h" +#include "library.h" +#include "appEngine.h" #include #include -#include #include unsigned int LoaderBase::depth = 0; std::set LoaderBase::loadedObjects; typedef std::map > ElementLoaderMap; -ElementLoaderMap & +ElementLoaderMap * & objLoaders() { - static ElementLoaderMap * _objLoaders = new ElementLoaderMap(); - return *_objLoaders; + static ElementLoaderMap * _objLoaders = NULL; + if (!_objLoaders) { + _objLoaders = new ElementLoaderMap(); + } + return _objLoaders; } -SimpleMessageException(LoadLibraryFailed); -SimpleMessageException(UnloadLibraryFailed); - -class Library : public SourceObject { - public: - Library(const xmlpp::Element * p) : - SourceObject(p), - handle(dlopen(p->get_attribute_value("path").c_str(), RTLD_NOW)) - { - if (!handle) { - throw LoadLibraryFailed(dlerror()); - } - } - ~Library() { - if (dlclose(handle)) { - throw UnloadLibraryFailed(dlerror()); - } - } - void loadComplete(const CommonObjects*) { - } - private: - void * handle; -}; -Storage::Objects libraries; -class LibraryLoader : public ElementLoaderImpl { - public: - void onIteration() - { - libraries.clear(); - } -}; -DECLARE_CUSTOM_LOADER("library", LibraryLoader); +LoaderBase::LoaderBase(bool r) : + recursive(r), + ns(ApplicationEngine::getCurrent()->env()->getXmlNamespace()) +{ + supportedStorers.insert(Storer::into(&libraries)); +} LoaderBase::LoaderBase(const Glib::ustring & n, bool r) : recursive(r), @@ -73,8 +50,8 @@ LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly, Unsupport if (!childrenOnly && node->get_namespace_uri() == ns) { Glib::ustring name = node->get_name(); unsigned int stored = 0; - ElementLoaderMap::const_iterator i = objLoaders().find(name); - if (i != objLoaders().end()) { + ElementLoaderMap::const_iterator i = objLoaders()->find(name); + if (i != objLoaders()->end()) { SourceObjectPtr o = i->second->go(node); created += 1; loadedObjects.insert(o); @@ -120,19 +97,24 @@ LoaderBase::collectAll(const CommonObjects * co, const xmlpp::Element * node, bo void LoaderBase::newLoader(const std::string & n, ElementLoader * l) { - objLoaders().insert(ElementLoaderMap::value_type(n, boost::shared_ptr(l))); + objLoaders()->insert(ElementLoaderMap::value_type(n, boost::shared_ptr(l))); } void LoaderBase::removeLoader(const std::string & n) { - objLoaders().erase(n); + ElementLoaderMap * & o = objLoaders(); + o->erase(n); + if (o->empty()) { + delete o; + o = NULL; + } } void LoaderBase::onIdle() { - BOOST_FOREACH(ElementLoaderMap::value_type l, objLoaders()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders()) { l.second->onIdle(); } } @@ -144,7 +126,7 @@ LoaderBase::onIteration() depth = 0; loadedObjects.clear(); - BOOST_FOREACH(ElementLoaderMap::value_type l, objLoaders()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders()) { l.second->onIteration(); } } @@ -152,7 +134,7 @@ LoaderBase::onIteration() void LoaderBase::onPeriodic() { - BOOST_FOREACH(ElementLoaderMap::value_type l, objLoaders()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders()) { l.second->onPeriodic(); } } diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h index 9dd3881..fb0ac16 100644 --- a/project2/xmlObjectLoader.h +++ b/project2/xmlObjectLoader.h @@ -20,6 +20,7 @@ class Storer; class LoaderBase { public: + LoaderBase(bool recursive); LoaderBase(const Glib::ustring & ns, bool recursive); virtual ~LoaderBase(); void collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly, diff --git a/project2/xmlPresenter.cpp b/project2/xmlPresenter.cpp index 494a88e..cc31c2f 100644 --- a/project2/xmlPresenter.cpp +++ b/project2/xmlPresenter.cpp @@ -37,7 +37,7 @@ XmlProcessPresenter::XmlProcessPresenter(const std::string & group, const std::s responseStyle(present.get_document()->get_root_node()->get_attribute_value("style")), contentType(present.get_document()->get_root_node()->get_attribute_value("contenttype")) { - LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true); + LoaderBase loader(true); loader.supportedStorers.insert(Storer::into(&rowSets)); loader.supportedStorers.insert(Storer::into(&views)); loader.supportedStorers.insert(Storer::into(¶meterChecks)); diff --git a/project2/xmlStorage.h b/project2/xmlStorage.h index 443ad81..9263b48 100644 --- a/project2/xmlStorage.h +++ b/project2/xmlStorage.h @@ -37,23 +37,35 @@ class Storer : public virtual IntrusivePtrBase { }; template -class StorerImpl : public Storer { +class StorerBase : public Storer { public: - StorerImpl(typename Storage::ObjectsPtr m) : map(m) + typedef typename Storage::ObjectsPtr Map; + StorerBase() { } - bool save(SourceObjectPtr obj, const xmlpp::Element *) const { + bool save(SourceObjectPtr obj, const xmlpp::Element * p) const { boost::intrusive_ptr O = boost::dynamic_pointer_cast(obj); if (O) { - if (map->insert(O).second) { + if (getMap(p)->insert(O).second) { return true; } throw StoreFailed(obj->name); } return false; } - typename Storage::ObjectsPtr map; + virtual Map getMap(const xmlpp::Element *) const = 0; +}; + +template +class StorerImpl : public StorerBase { + public: + StorerImpl(typename StorerBase::Map m) : map(m) + { + } + + typename StorerBase::Map getMap(const xmlpp::Element *) const { return map; } + typename StorerBase::Map map; }; template -- cgit v1.2.3