summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project2/Jamfile.jam2
-rw-r--r--project2/cgi/cgiStageRequest.cpp2
-rw-r--r--project2/commonObjects.cpp2
-rw-r--r--project2/console/consoleAppEngine.cpp2
-rw-r--r--project2/if.cpp33
-rw-r--r--project2/iterate.cpp3
-rw-r--r--project2/library.cpp41
-rw-r--r--project2/library.h17
-rw-r--r--project2/noOutputExecute.cpp13
-rw-r--r--project2/noOutputExecute.h5
-rw-r--r--project2/rowView.cpp3
-rw-r--r--project2/sqlMergeTask.cpp3
-rw-r--r--project2/sqlTask.cpp35
-rw-r--r--project2/sqlTask.h5
-rw-r--r--project2/xmlObjectLoader.cpp70
-rw-r--r--project2/xmlObjectLoader.h1
-rw-r--r--project2/xmlPresenter.cpp2
-rw-r--r--project2/xmlStorage.h22
18 files changed, 170 insertions, 91 deletions
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(&parameterChecks));
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(&parameterChecks));
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 <boost/foreach.hpp>
+#include <algorithm>
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 <class Range, class Pred>
+bool all(const Range & c, const Pred & p)
+{
+ return (std::find_if(c.begin(), c.end(), !p) == c.end());
+}
+template <class Range, class Pred>
+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<bySOOrder>()) {
- if (!pc->performCheck()) {
- return false;
- }
- }
- return true;
+ return all(checks.get<bySOOrder>(), boost::bind(&ParamChecker::performCheck, _1));
}
- else {
- BOOST_FOREACH(const ParamCheckers::value_type & pc, checks.get<bySOOrder>()) {
- if (pc->performCheck()) {
- return true;
- }
- }
- return false;
+ else if (mode == Or) {
+ return any(checks.get<bySOOrder>(), 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 <boost/foreach.hpp>
#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 <dlfcn.h>
+#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<Library>::Objects libraries;
+class LibraryLoader : public ElementLoaderImpl<Library> {
+ 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<Library>::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<NoOutputExecute> O = boost::dynamic_pointer_cast<NoOutputExecute>(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<NoOutputExecute> {
public:
- typedef Storage<NoOutputExecute>::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 <boost/foreach.hpp>
@@ -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<NoOutputExecute> {
+ 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<const SqlVariableBinder, const VariableType>(SqlVariableBinder(modify, atoi(p.second->name.c_str())), p.second->value);
+ boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(modify,
+ atoi(p.second->name.c_str())), p.second->value);
+ }
+ if (modify->execute() == 0) {
+ BOOST_FOREACH(const SubNOEs::value_type & sq, noChangesNOEs.get<bySOOrder>()) {
+ sq->execute();
+ }
+ }
+ else {
+ BOOST_FOREACH(const SubNOEs::value_type & sq, changesNOEs.get<bySOOrder>()) {
+ 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<NoOutputExecute>::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 <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
-#include <dlfcn.h>
#include <libxml++/nodes/textnode.h>
unsigned int LoaderBase::depth = 0;
std::set<SourceObjectPtr> LoaderBase::loadedObjects;
typedef std::map<std::string, boost::shared_ptr<ElementLoader> > 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<Library>::Objects libraries;
-class LibraryLoader : public ElementLoaderImpl<Library> {
- 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<ElementLoader>(l)));
+ objLoaders()->insert(ElementLoaderMap::value_type(n, boost::shared_ptr<ElementLoader>(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(&parameterChecks));
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 X>
-class StorerImpl : public Storer {
+class StorerBase : public Storer {
public:
- StorerImpl(typename Storage<X>::ObjectsPtr m) : map(m)
+ typedef typename Storage<X>::ObjectsPtr Map;
+ StorerBase()
{
}
- bool save(SourceObjectPtr obj, const xmlpp::Element *) const {
+ bool save(SourceObjectPtr obj, const xmlpp::Element * p) const {
boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>(obj);
if (O) {
- if (map->insert(O).second) {
+ if (getMap(p)->insert(O).second) {
return true;
}
throw StoreFailed(obj->name);
}
return false;
}
- typename Storage<X>::ObjectsPtr map;
+ virtual Map getMap(const xmlpp::Element *) const = 0;
+};
+
+template <class X>
+class StorerImpl : public StorerBase<X> {
+ public:
+ StorerImpl(typename StorerBase<X>::Map m) : map(m)
+ {
+ }
+
+ typename StorerBase<X>::Map getMap(const xmlpp::Element *) const { return map; }
+ typename StorerBase<X>::Map map;
};
template <class X>