summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-12-14 00:20:38 +0000
committerrandomdan <randomdan@localhost>2010-12-14 00:20:38 +0000
commit3f452dd8b71e546d91377153e24e6ed530307e90 (patch)
treea4ecc86baff05083ee7149a06c735c28eb79c8b5
parentSupport binding null to an SQL command parameter (diff)
downloadproject2-3f452dd8b71e546d91377153e24e6ed530307e90.tar.bz2
project2-3f452dd8b71e546d91377153e24e6ed530307e90.tar.xz
project2-3f452dd8b71e546d91377153e24e6ed530307e90.zip
All new fangled iterators, views, row engines, exceptions, the list goes on
Includes site and console updates to match
-rw-r--r--project2/Doxyfile6
-rw-r--r--project2/Jamfile.jam4
-rw-r--r--project2/appEngine.h23
-rw-r--r--project2/cgi/cgiAppEngine.cpp82
-rw-r--r--project2/cgi/cgiAppEngine.h9
-rw-r--r--project2/cgi/cgiEnvironment.cpp5
-rw-r--r--project2/cgi/p2webMain.cpp10
-rw-r--r--project2/commonObjects.cpp13
-rw-r--r--project2/commonObjects.h32
-rw-r--r--project2/console/consoleAppEngine.cpp27
-rw-r--r--project2/console/consoleAppEngine.h13
-rw-r--r--project2/dumpTask.cpp2
-rw-r--r--project2/dumpTask.h2
-rw-r--r--project2/exceptions.cpp7
-rw-r--r--project2/exceptions.h16
-rw-r--r--project2/fileRows.cpp27
-rw-r--r--project2/fileRows.h19
-rw-r--r--project2/iHaveParameters.cpp21
-rw-r--r--project2/iHaveParameters.h9
-rw-r--r--project2/iterate.cpp51
-rw-r--r--project2/iterate.h24
-rw-r--r--project2/iterate.hpp73
-rw-r--r--project2/noOutputExecute.h1
-rw-r--r--project2/perRowValues.cpp30
-rw-r--r--project2/perRowValues.h28
-rw-r--r--project2/presenter.cpp109
-rw-r--r--project2/presenter.h41
-rw-r--r--project2/procRows.cpp19
-rw-r--r--project2/procRows.h4
-rw-r--r--project2/rawView.cpp63
-rw-r--r--project2/rawView.h12
-rw-r--r--project2/rdbmsDataSource.cpp20
-rw-r--r--project2/rdbmsDataSource.h6
-rw-r--r--project2/regexCheck.cpp4
-rw-r--r--project2/regexCheck.h2
-rw-r--r--project2/sendmailTask.cpp21
-rw-r--r--project2/sendmailTask.h2
-rw-r--r--project2/sessionClearTask.cpp2
-rw-r--r--project2/sessionClearTask.h4
-rw-r--r--project2/sessionSetTask.cpp2
-rw-r--r--project2/sessionSetTask.h4
-rw-r--r--project2/sourceObject.h4
-rw-r--r--project2/sqlCheck.cpp9
-rw-r--r--project2/sqlCheck.h2
-rw-r--r--project2/sqlMergeTask.cpp22
-rw-r--r--project2/sqlMergeTask.h2
-rw-r--r--project2/sqlRows.cpp160
-rw-r--r--project2/sqlRows.h77
-rw-r--r--project2/sqlTask.cpp8
-rw-r--r--project2/sqlTask.h2
-rw-r--r--project2/task.h2
-rw-r--r--project2/urlRows.cpp38
-rw-r--r--project2/urlRows.h26
-rw-r--r--project2/variables.cpp7
-rw-r--r--project2/view.cpp63
-rw-r--r--project2/view.h44
-rw-r--r--project2/view.hpp76
-rw-r--r--project2/xmlObjectLoader.cpp28
-rw-r--r--project2/xmlObjectLoader.h2
-rw-r--r--project2/xmlRows.cpp29
-rw-r--r--project2/xmlRows.h19
61 files changed, 892 insertions, 577 deletions
diff --git a/project2/Doxyfile b/project2/Doxyfile
index e5f9500..2142e66 100644
--- a/project2/Doxyfile
+++ b/project2/Doxyfile
@@ -47,7 +47,7 @@ OUTPUT_DIRECTORY = docs
# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.
-CREATE_SUBDIRS = NO
+CREATE_SUBDIRS = YES
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
@@ -313,12 +313,12 @@ EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
-EXTRACT_PRIVATE = NO
+EXTRACT_PRIVATE = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
-EXTRACT_STATIC = NO
+EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam
index 4a2e6d1..7040562 100644
--- a/project2/Jamfile.jam
+++ b/project2/Jamfile.jam
@@ -19,8 +19,8 @@ lib curl : : <name>curl ;
lib p2common :
appEngine.cpp dataSource.cpp environment.cpp fileStarGlibIoChannel.cpp iHaveParameters.cpp
iterate.cpp paramChecker.cpp perRowValues.cpp presenter.cpp rawView.cpp dumpTask.cpp
- sourceObject.cpp task.cpp variables.cpp view.cpp xmlObjectLoader.cpp
- sessionClearTask.cpp session.cpp sessionSetTask.cpp
+ sourceObject.cpp task.cpp variables.cpp view.cpp xmlObjectLoader.cpp exceptions.cpp
+ sessionClearTask.cpp session.cpp sessionSetTask.cpp commonObjects.cpp
:
<library>../libmisc//misc
<library>libxmlpp
diff --git a/project2/appEngine.h b/project2/appEngine.h
index 223a928..04fe486 100644
--- a/project2/appEngine.h
+++ b/project2/appEngine.h
@@ -2,41 +2,20 @@
#define APPENGINE_H
#include "environment.h"
-#include "dataSource.h"
#include "session.h"
#include "presenter.h"
class ApplicationEngine {
public:
- class UriElementOutOfRange : public std::exception { };
- class ParamNotFound : public std::exception { };
- class DataSourceNotFound : public std::exception { };
- class DataSourceNotCompatible : public std::exception { };
-
ApplicationEngine();
virtual ~ApplicationEngine() = 0;
virtual void process() const = 0;
virtual const Environment * env() const = 0;
virtual SessionPtr session() const = 0;
- virtual PresenterPtr getPresenter(const std::string & group, const std::string & id) const = 0;
+ virtual void addAppData(const Presenter * p) const = 0;
- template <class DataSourceType>
- const DataSourceType * dataSource(const std::string & name) const
- {
- DataSources::const_iterator i = datasources.find(name);
- if (i == datasources.end()) {
- throw DataSourceNotFound();
- }
- const DataSourceType * s = dynamic_cast<const DataSourceType *>(i->second.get());
- if (!s) {
- throw DataSourceNotCompatible();
- }
- return s;
- }
static ApplicationEngine * getCurrent() { return currentEngine; }
- // protected:
- mutable DataSources datasources;
private:
static ApplicationEngine * currentEngine;
};
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp
index 94de818..f4a4fb0 100644
--- a/project2/cgi/cgiAppEngine.cpp
+++ b/project2/cgi/cgiAppEngine.cpp
@@ -72,17 +72,20 @@ CgiApplicationEngine::Stage::~Stage()
CgiApplicationEngine::PresentStage::PresentStage(const CgiApplicationEngine * e, const std::string & id) :
CgiApplicationEngine::Stage(e),
- Presenter("present", id)
+ XmlPresenter("present", id)
{
}
+
CgiApplicationEngine::PresentStage::PresentStage(const CgiApplicationEngine * e, const std::string & group, const std::string & id) :
CgiApplicationEngine::Stage(e),
- Presenter(group, id)
+ XmlPresenter(group, id)
{
}
+
CgiApplicationEngine::PresentStage::~PresentStage()
{
}
+
CgiApplicationEngine::Stage *
CgiApplicationEngine::PresentStage::run()
{
@@ -91,52 +94,46 @@ CgiApplicationEngine::PresentStage::run()
return new PresentStage(appEngine, pc.second->present);
}
}
+ execute();
appEngine->doc = getDataDocument();
+ appEngine->header = new cgicc::HTTPContentHeader(contentType);
sessionsContainer->CleanUp();
return NULL;
}
-Presenter::XmlDocumentPtr
-CgiApplicationEngine::PresentStage::getDataDocument() const
+void
+CgiApplicationEngine::addAppData(const Presenter * p) const
{
- XmlDocumentPtr responseDoc = Presenter::getDataDocument();
- xmlpp::Element * responseRoot = responseDoc->get_root_node();
// URL elements
- xmlpp::Element * uriElems = responseRoot->add_child("uriElems", "project2");
- BOOST_FOREACH(std::string s, appEngine->_env->elems) {
- uriElems->add_child("uriElem", "project2")->set_child_text(s);
+ p->pushSub("uriElems", "project2");
+ BOOST_FOREACH(std::string s, _env->elems) {
+ p->addField("uriElem", "project2", s);
}
+ p->popSub();
+
// Parameters
- xmlpp::Element * paramsXml = responseRoot->add_child("params", "project2");
- BOOST_FOREACH(cgicc::FormEntry fe, appEngine->_env->cgi->getElements()) {
- xmlpp::Element * param = paramsXml->add_child("param", "project2");
- param->add_child_text(fe.getValue());
- param->set_attribute("name", fe.getName());
+ p->pushSub("params", "project2");
+ BOOST_FOREACH(cgicc::FormEntry fe, _env->cgi->getElements()) {
+ p->pushSub("param", "project2");
+ p->addAttr("name", fe.getName());
+ p->addAttr("value", fe.getValue());
+ p->popSub();
}
+ p->popSub();
+
// Sessions variables
- if (!appEngine->sessionID.is_nil()) {
- xmlpp::Element * sessionXml = responseRoot->add_child("session", "project2");
- sessionXml->set_attribute("id", boost::lexical_cast<Glib::ustring>(appEngine->sessionID));
- Session::Values session(sessionsContainer->GetSession(appEngine->sessionID)->GetValuesCopy());
+ if (!sessionID.is_nil()) {
+ p->pushSub("session", "project2");
+ p->addField("id", boost::lexical_cast<Glib::ustring>(sessionID));
+ Session::Values session(sessionsContainer->GetSession(sessionID)->GetValuesCopy());
BOOST_FOREACH(Session::Values::value_type sv, session) {
- xmlpp::Element * param = sessionXml->add_child("var", "project2");
- param->add_child_text(sv.second);
- param->set_attribute("name", sv.first);
+ p->pushSub("var", "project2");
+ p->addAttr("value", sv.second);
+ p->addAttr("name", sv.first);
+ p->popSub();
}
+ p->popSub();
}
- // XSLT Style
- char * buf;
- if (responseStyle.length() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"",
- responseStyle.c_str()) > 0) {
- xmlAddPrevSibling(responseRoot->cobj(),
- xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf));
- free(buf);
- appEngine->header = new cgicc::HTTPContentHeader("text/xml-xslt");
- }
- else {
- appEngine->header = new cgicc::HTTPContentHeader("text/xml");
- }
- return responseDoc;
}
CgiApplicationEngine::RequestStage::RequestStage(const CgiApplicationEngine * e, const std::string & id) :
@@ -148,10 +145,11 @@ CgiApplicationEngine::RequestStage::RequestStage(const CgiApplicationEngine * e,
present = requestRoot->get_attribute_value("present");
LoaderBase loader("http://project2.randomdan.homeip.net", true);
- loader.supportedStorers.insert(Storer::into(&appEngine->datasources));
+ loader.supportedStorers.insert(Storer::into(&datasources));
loader.supportedStorers.insert(Storer::into(&parameterChecks));
+ loader.supportedStorers.insert(Storer::into(&rowSets));
loader.supportedStorers.insert(Storer::into(&tasks));
- loader.collectAll(requestRoot, true);
+ loader.collectAll(this, requestRoot, true);
}
CgiApplicationEngine::RequestStage::~RequestStage()
{
@@ -169,18 +167,18 @@ CgiApplicationEngine::RequestStage::run()
t.second->execute();
}
// Commit data source transactions (without invoking a connection)
- BOOST_FOREACH(DataSources::value_type ds, appEngine->datasources) {
+ BOOST_FOREACH(DataSources::value_type ds, datasources) {
ds.second->commit();
}
+ return new PresentStage(appEngine, present);
}
catch (...) {
// Do something about the error
- BOOST_FOREACH(DataSources::value_type ds, appEngine->datasources) {
+ BOOST_FOREACH(DataSources::value_type ds, datasources) {
ds.second->rollback();
}
throw;
}
- return new PresentStage(appEngine, present);
}
SessionPtr
@@ -189,9 +187,3 @@ CgiApplicationEngine::session() const
return sessionsContainer->GetSession(sessionID);
}
-PresenterPtr
-CgiApplicationEngine::getPresenter(const std::string & group, const std::string & id) const
-{
- return PresenterPtr(new PresentStage(this, group, id));
-}
-
diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h
index cebb294..db4d696 100644
--- a/project2/cgi/cgiAppEngine.h
+++ b/project2/cgi/cgiAppEngine.h
@@ -5,6 +5,7 @@
#include "../task.h"
#include "../paramChecker.h"
#include "../presenter.h"
+#include "../commonObjects.h"
#include <boost/intrusive_ptr.hpp>
#include <boost/uuid/uuid.hpp>
#include <libxml++/document.h>
@@ -30,13 +31,13 @@ class CgiApplicationEngine : public ApplicationEngine {
}
const Environment * env() const;
SessionPtr session() const;
- PresenterPtr getPresenter(const std::string & group, const std::string & id) const;
+ void addAppData(const Presenter * p) const;
const CgiEnvironment * _env;
protected:
mutable cgicc::HTTPContentHeader * header;
private:
mutable boost::shared_ptr<xmlpp::Document> doc;
- class Stage {
+ class Stage : public CommonObjects {
public:
Stage(const CgiApplicationEngine *);
virtual ~Stage() = 0;
@@ -54,14 +55,12 @@ class CgiApplicationEngine : public ApplicationEngine {
OrderedParamCheckers parameterChecks;
NoOutputExecutes tasks;
};
- class PresentStage : public Stage, public Presenter {
+ class PresentStage : public Stage, public XmlPresenter {
public:
PresentStage(const CgiApplicationEngine *, const std::string & id);
PresentStage(const CgiApplicationEngine *, const std::string & group, const std::string & id);
virtual ~PresentStage();
virtual Stage * run();
- protected:
- XmlDocumentPtr getDataDocument() const;
};
mutable Stage * currentStage;
mutable boost::uuids::uuid sessionID;
diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp
index 630629a..3461973 100644
--- a/project2/cgi/cgiEnvironment.cpp
+++ b/project2/cgi/cgiEnvironment.cpp
@@ -1,5 +1,6 @@
#include "cgiEnvironment.h"
#include "../appEngine.h"
+#include "../exceptions.h"
#include <map>
#include <cgicc/Cgicc.h>
#include <boost/tokenizer.hpp>
@@ -25,7 +26,7 @@ Glib::ustring
CgiEnvironment::getParamUri(unsigned int p) const
{
if (p >= elems.size()) {
- throw ApplicationEngine::UriElementOutOfRange();
+ throw UriElementOutOfRange();
}
return elems[p];
}
@@ -35,7 +36,7 @@ CgiEnvironment::getParamQuery(const std::string & p) const
{
cgicc::const_form_iterator i = cgi->getElement(p);
if (i == cgi->getElements().end()) {
- throw ApplicationEngine::ParamNotFound();
+ throw ParamNotFound();
}
return (*cgi)(p);
}
diff --git a/project2/cgi/p2webMain.cpp b/project2/cgi/p2webMain.cpp
index c36335a..59e8d7b 100644
--- a/project2/cgi/p2webMain.cpp
+++ b/project2/cgi/p2webMain.cpp
@@ -40,6 +40,7 @@ p2webGoingIdle(int)
int main(void)
{
if (!FCGX_IsCGI()) {
+ syslog(LOG_NOTICE, "FCGID Startup ($Id$)");
FCGX_Request request;
FCGX_Init();
@@ -69,12 +70,17 @@ int main(void)
catch (const std::exception & e) {
cgicc::HTTPContentHeader header("text/plain");
header.render(IO);
- IO << "Kaboom!" << std::endl << std::endl << e.what();
+ IO << "Kaboom!" << std::endl
+ << std::endl
+ << typeid(e).name() << std::endl
+ << e.what() << std::endl;
}
catch (...) {
cgicc::HTTPContentHeader header("text/plain");
header.render(IO);
- IO << "Kaboom!" << std::endl << std::endl << "Unknown exception.";
+ IO << "Kaboom!" << std::endl
+ << std::endl
+ << "Unknown exception." << std::endl;
}
alarm(60);
LoaderBase::onIteration();
diff --git a/project2/commonObjects.cpp b/project2/commonObjects.cpp
new file mode 100644
index 0000000..f39eb60
--- /dev/null
+++ b/project2/commonObjects.cpp
@@ -0,0 +1,13 @@
+#include "commonObjects.h"
+
+PerRowValuesPtr
+CommonObjects::getSource(const std::string & name) const
+{
+ RowSets::const_iterator i = rowSets.find(name);
+ if (i != rowSets.end()) {
+ return i->second;
+ }
+ throw CommonObjects::DataSourceNotFound();
+}
+
+
diff --git a/project2/commonObjects.h b/project2/commonObjects.h
new file mode 100644
index 0000000..32e201c
--- /dev/null
+++ b/project2/commonObjects.h
@@ -0,0 +1,32 @@
+#ifndef COMMONOBJECTS_H
+#define COMMONOBJECTS_H
+
+#include "dataSource.h"
+#include "perRowValues.h"
+
+class CommonObjects : public virtual IntrusivePtrBase {
+ public:
+ class DataSourceNotFound : public std::exception { };
+ class DataSourceNotCompatible : public std::exception { };
+
+ PerRowValuesPtr getSource(const std::string &) const;
+ template <class DataSourceType>
+ const DataSourceType * dataSource(const std::string & name) const
+ {
+ DataSources::const_iterator i = datasources.find(name);
+ if (i == datasources.end()) {
+ throw DataSourceNotFound();
+ }
+ const DataSourceType * s = dynamic_cast<const DataSourceType *>(i->second.get());
+ if (!s) {
+ throw DataSourceNotCompatible();
+ }
+ return s;
+ }
+ protected:
+ RowSets rowSets;
+ DataSources datasources;
+};
+
+#endif
+
diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp
index 98d280d..908c1a1 100644
--- a/project2/console/consoleAppEngine.cpp
+++ b/project2/console/consoleAppEngine.cpp
@@ -57,10 +57,11 @@ ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * en
while (xmlXIncludeProcessFlags(request.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0);
LoaderBase loader("http://project2.randomdan.homeip.net", true);
- loader.supportedStorers.insert(Storer::into(&this->datasources));
+ loader.supportedStorers.insert(Storer::into(&datasources));
loader.supportedStorers.insert(Storer::into(&parameterChecks));
loader.supportedStorers.insert(Storer::into(&tasks));
- loader.collectAll(request.get_document()->get_root_node(), true);
+ loader.supportedStorers.insert(Storer::into(&rowSets));
+ loader.collectAll(this, request.get_document()->get_root_node(), true);
}
ConsoleApplicationEngine::~ConsoleApplicationEngine()
@@ -105,10 +106,9 @@ ConsoleApplicationEngine::session() const
return runtime;
}
-PresenterPtr
-ConsoleApplicationEngine::getPresenter(const std::string & group, const std::string & id) const
+void
+ConsoleApplicationEngine::addAppData(const Presenter * p) const
{
- return PresenterPtr(new ConsolePresenter(this, group, id));
}
ConsoleApplicationEngine::ConsolePresenter::ConsolePresenter(const ConsoleApplicationEngine *,
@@ -121,9 +121,20 @@ ConsoleApplicationEngine::ConsolePresenter::~ConsolePresenter()
{
}
-Presenter::XmlDocumentPtr
-ConsoleApplicationEngine::ConsolePresenter::getDataDocument() const
+void
+ConsoleApplicationEngine::ConsolePresenter::pushSub(const Glib::ustring & name, const Glib::ustring & ns) const
+{
+ indent += 2;
+}
+
+void
+ConsoleApplicationEngine::ConsolePresenter::addField(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const
+{
+}
+
+void
+ConsoleApplicationEngine::ConsolePresenter::popSub() const
{
- return Presenter::getDataDocument();
+ indent -= 2;
}
diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h
index b40ef8a..9d4ee96 100644
--- a/project2/console/consoleAppEngine.h
+++ b/project2/console/consoleAppEngine.h
@@ -5,6 +5,7 @@
#include "../task.h"
#include "../paramChecker.h"
#include "../presenter.h"
+#include "../commonObjects.h"
#include <boost/intrusive_ptr.hpp>
#include <boost/filesystem/path.hpp>
#include <libxml++/document.h>
@@ -12,7 +13,7 @@
class ConsoleEnvironment;
-class ConsoleApplicationEngine : public ApplicationEngine {
+class ConsoleApplicationEngine : public ApplicationEngine, public CommonObjects {
public:
ConsoleApplicationEngine(const ConsoleEnvironment *, const boost::filesystem::path &);
virtual ~ConsoleApplicationEngine();
@@ -20,7 +21,7 @@ class ConsoleApplicationEngine : public ApplicationEngine {
void process() const;
const Environment * env() const;
SessionPtr session() const;
- PresenterPtr getPresenter(const std::string & group, const std::string & id) const;
+ virtual void addAppData(const Presenter * p) const;
protected:
const ConsoleEnvironment * _env;
private:
@@ -29,8 +30,12 @@ class ConsoleApplicationEngine : public ApplicationEngine {
ConsolePresenter(const ConsoleApplicationEngine *, const std::string & id);
ConsolePresenter(const ConsoleApplicationEngine *, const std::string & group, const std::string & id);
virtual ~ConsolePresenter();
- protected:
- XmlDocumentPtr getDataDocument() const;
+
+ void pushSub(const Glib::ustring & ns, const Glib::ustring & name) const;
+ void addField(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const;
+ void popSub() const;
+ private:
+ mutable unsigned int indent;
};
OrderedParamCheckers parameterChecks;
NoOutputExecutes tasks;
diff --git a/project2/dumpTask.cpp b/project2/dumpTask.cpp
index 1e94e65..3db29f6 100644
--- a/project2/dumpTask.cpp
+++ b/project2/dumpTask.cpp
@@ -16,7 +16,7 @@ _DumpTask::~_DumpTask()
}
void
-_DumpTask::loadComplete()
+_DumpTask::loadComplete(const CommonObjects *)
{
}
diff --git a/project2/dumpTask.h b/project2/dumpTask.h
index ec004c4..bc6f69c 100644
--- a/project2/dumpTask.h
+++ b/project2/dumpTask.h
@@ -7,7 +7,7 @@ class _DumpTask : public _Task {
public:
_DumpTask(const xmlpp::Element * p);
virtual ~_DumpTask();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
virtual void execute() const;
};
diff --git a/project2/exceptions.cpp b/project2/exceptions.cpp
new file mode 100644
index 0000000..9aaeb07
--- /dev/null
+++ b/project2/exceptions.cpp
@@ -0,0 +1,7 @@
+#include "exceptions.h"
+
+NotSupported::NotSupported(const std::string & what) :
+ std::runtime_error(what)
+{
+}
+
diff --git a/project2/exceptions.h b/project2/exceptions.h
new file mode 100644
index 0000000..84c8c19
--- /dev/null
+++ b/project2/exceptions.h
@@ -0,0 +1,16 @@
+#ifndef EXCEPTION_H
+#define EXCEPTION_H
+
+#include <stdexcept>
+
+class UriElementOutOfRange : public std::exception { };
+class ParamNotFound : public std::exception { };
+class NotSupported : public std::runtime_error {
+ public:
+ NotSupported(const std::string & what);
+};
+class FileNotReadable : public std::exception { };
+class FileNotWritable : public std::exception { };
+
+#endif
+
diff --git a/project2/fileRows.cpp b/project2/fileRows.cpp
index f28c96d..2f4d6cf 100644
--- a/project2/fileRows.cpp
+++ b/project2/fileRows.cpp
@@ -1,10 +1,12 @@
#include "fileRows.h"
-#include <stdexcept>
+#include "xmlObjectLoader.h"
+#include "exceptions.h"
-ElementLoaderImpl<_FileIterate> fileiterateLoader("fileiterate");
-ElementLoaderImpl<_FileView> fileviewLoader("fileview");
+ElementLoaderImpl<_FileRows> filerowsLoader("filerows");
_FileRows::_FileRows(const xmlpp::Element * p) :
+ _SourceObject(p),
+ PerRowValues(p),
path(p->get_attribute_value("path")),
fieldSep(p->get_attribute_value("fieldSep")[0]),
quoteChar(p->get_attribute_value("quoteChar")[0]),
@@ -24,10 +26,16 @@ _FileRows::~_FileRows()
}
void
-_FileRows::loadComplete()
+_FileRows::loadComplete(const CommonObjects *)
{
}
+void
+_FileRows::setFilter(const Glib::ustring &)
+{
+ throw NotSupported(__PRETTY_FUNCTION__);
+}
+
unsigned int
_FileRows::columnCount() const
{
@@ -41,7 +49,7 @@ _FileRows::getColumnName(unsigned int col) const
}
void
-_FileRows::execute() const
+_FileRows::execute(const RowProcessor * rp) const
{
FileStarChannel c(doOpen());
c.set_encoding(encoding);
@@ -96,7 +104,7 @@ _FileRows::execute() const
values.push_back(ValPtr(new Glib::ustring()));
curCol++;
}
- rowReady();
+ rp->rowReady();
}
values.clear();
}
@@ -146,13 +154,8 @@ _FileRows::doOpen() const
{
FILE * f = fopen(path->c_str(), "r");
if (!f) {
- throw std::runtime_error("Could not open file");
+ throw FileNotReadable();
}
return FileStarChannel(f, true, fclose);
}
-#include "view.hpp"
-template class _GenericView<_FileRows>;
-#include "iterate.hpp"
-template class _GenericIterate<_FileRows>;
-
diff --git a/project2/fileRows.h b/project2/fileRows.h
index 7c99c55..60916ac 100644
--- a/project2/fileRows.h
+++ b/project2/fileRows.h
@@ -5,24 +5,25 @@
#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <map>
-#include "view.h"
#include "variables.h"
-#include "iterate.h"
+#include "perRowValues.h"
#include "fileStarGlibIoChannel.h"
+class CommonObjects;
+
class _FileRows : public PerRowValues {
public:
_FileRows(const xmlpp::Element * p);
~_FileRows();
- void execute() const;
- virtual void loadComplete();
+ void execute(const RowProcessor *) const;
+ virtual void loadComplete(const CommonObjects *);
+ virtual void setFilter(const Glib::ustring &);
unsigned int columnCount() const;
const Glib::ustring & getColumnName(unsigned int col) const;
const Glib::ustring & getCurrentValue(const Glib::ustring & id) const;
const Glib::ustring & getCurrentValue(unsigned int col) const;
bool isNull(unsigned int col) const;
- virtual void rowReady() const = 0;
typedef std::set<gunichar> CharSet;
const Variable path;
@@ -44,14 +45,6 @@ class _FileRows : public PerRowValues {
};
typedef boost::intrusive_ptr<_FileRows> FileRows;
-typedef _GenericView<_FileRows> _FileView;
-typedef boost::intrusive_ptr<_FileView> FileView;
-typedef std::map<std::string, FileView> FileViews;
-
-typedef _GenericIterate<_FileRows> _FileIterate;
-typedef boost::intrusive_ptr<_FileIterate> FileIterate;
-typedef std::map<std::string, FileIterate> FileIterates;
-
#endif
diff --git a/project2/iHaveParameters.cpp b/project2/iHaveParameters.cpp
index 9ba917d..abab80c 100644
--- a/project2/iHaveParameters.cpp
+++ b/project2/iHaveParameters.cpp
@@ -1,4 +1,6 @@
#include "iHaveParameters.h"
+#include "exceptions.h"
+#include "appEngine.h"
#include "xmlObjectLoader.h"
#include <boost/foreach.hpp>
@@ -8,27 +10,28 @@ IHaveParameters::IHaveParameters(const xmlpp::Element * p)
const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
if (elem) {
Parameter p = new _Parameter(elem);
- parameters[p->bind] = p;
+ parameters[p->name] = p;
}
}
}
-ElementLoaderImpl<IHaveParameters::_Parameter> paramLoader("param");
-
IHaveParameters::~IHaveParameters()
{
}
IHaveParameters::_Parameter::_Parameter(const xmlpp::Element * p) :
- _SourceObject(p),
- value(p->get_attribute("value")),
- bind(atoi(p->get_attribute_value("bind").c_str()))
+ name(p->get_attribute_value("name")),
+ value(p->get_attribute("value"))
{
}
-void
-IHaveParameters::_Parameter::loadComplete()
+const Glib::ustring &
+IHaveParameters::getParameter(const Glib::ustring & name) const
{
+ Parameters::const_iterator i = parameters.find(name);
+ if (i != parameters.end()) {
+ return i->second->value;
+ }
+ throw ParamNotFound();
}
-
diff --git a/project2/iHaveParameters.h b/project2/iHaveParameters.h
index 14c1639..83a77b4 100644
--- a/project2/iHaveParameters.h
+++ b/project2/iHaveParameters.h
@@ -9,18 +9,19 @@
class IHaveParameters : public virtual IntrusivePtrBase {
public:
- class _Parameter : public _SourceObject {
+ class _Parameter : public virtual IntrusivePtrBase {
public:
_Parameter(const xmlpp::Element * p);
- void loadComplete();
+ const Glib::ustring name;
const Variable value;
- const unsigned int bind;
};
IHaveParameters(const xmlpp::Element * p);
virtual ~IHaveParameters() = 0;
+ const Glib::ustring & getParameter(const Glib::ustring &) const;
+
typedef boost::intrusive_ptr<_Parameter> Parameter;
- typedef std::map<unsigned int, Parameter> Parameters;
+ typedef std::map<Glib::ustring, Parameter> Parameters;
protected:
Parameters parameters;
};
diff --git a/project2/iterate.cpp b/project2/iterate.cpp
index d114acb..7e86c4b 100644
--- a/project2/iterate.cpp
+++ b/project2/iterate.cpp
@@ -3,9 +3,12 @@
#include <syslog.h>
#include "xmlObjectLoader.h"
+ElementLoaderImpl<_Iterate> iterateLoader("iterate");
+
_Iterate::_Iterate(const xmlpp::Element * p) :
_SourceObject(p),
- _NoOutputExecute(p)
+ _NoOutputExecute(p),
+ RowProcessor(p)
{
LoaderBase loader("http://project2.randomdan.homeip.net", true);
loader.supportedStorers.insert(Storer::into(&subNOEs));
@@ -17,18 +20,50 @@ _Iterate::~_Iterate()
}
void
-_Iterate::executeChildren() const
+_Iterate::loadComplete(const CommonObjects * co)
+{
+ RowProcessor::loadComplete(co);
+}
+
+void
+_Iterate::rowReady() const
{
+ executeChildren();
+ source->rowChanged();
+}
+
+void
+_Iterate::execute() const
+{
+ PerRowValues::beginRow(source.get());
try {
- PerRowValues::beginRow(this);
- BOOST_FOREACH(NoOutputExecutes::value_type sq, subNOEs) {
- sq.second->execute();
- }
- PerRowValues::endRow(this);
+ source->execute(this);
+ PerRowValues::endRow(source.get());
}
catch (...) {
- PerRowValues::endRow(this);
+ PerRowValues::endRow(source.get());
throw;
}
}
+void
+_Iterate::executeChildren() const
+{
+ BOOST_FOREACH(NoOutputExecutes::value_type sq, subNOEs) {
+ if (dynamic_cast<const RowProcessor *>(sq.second.get())) {
+ sq.second->execute();
+ }
+ else {
+ PerRowValues::beginRow(NULL);
+ try {
+ sq.second->execute();
+ PerRowValues::endRow(NULL);
+ }
+ catch (...) {
+ PerRowValues::endRow(NULL);
+ throw;
+ }
+ }
+ }
+}
+
diff --git a/project2/iterate.h b/project2/iterate.h
index 9dc9019..852310b 100644
--- a/project2/iterate.h
+++ b/project2/iterate.h
@@ -9,39 +9,25 @@
#include "perRowValues.h"
#include "noOutputExecute.h"
-class ApplicationEngine;
class _Iterate;
typedef boost::intrusive_ptr<_Iterate> Iterate;
typedef std::map<std::string, Iterate> Iterates;
-class _Iterate : public virtual _SourceObject, public PerRowValues, public _NoOutputExecute {
+class _Iterate : public _NoOutputExecute, public RowProcessor {
public:
_Iterate(const xmlpp::Element * p);
virtual ~_Iterate();
+ void loadComplete(const CommonObjects *);
+ void rowReady() const;
+ void execute() const;
+
NoOutputExecutes subNOEs;
protected:
void executeChildren() const;
};
-template <class Driver>
-class _GenericIterate : public _Iterate, public Driver {
- public:
- _GenericIterate(const xmlpp::Element * p);
-
- virtual void loadComplete();
- virtual unsigned int columnCount() const;
- virtual const Glib::ustring & getCurrentValue(const unsigned int id) const;
- virtual const Glib::ustring & getCurrentValue(const Glib::ustring & id) const;
- virtual const Glib::ustring & getColumnName(const unsigned int id) const;
- virtual bool isNull(unsigned int col) const;
- virtual void executeChildren() const;
- virtual void execute() const;
- virtual void rowReady() const;
- private:
-};
-
#endif
diff --git a/project2/iterate.hpp b/project2/iterate.hpp
deleted file mode 100644
index f71ca9e..0000000
--- a/project2/iterate.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "iterate.h"
-
-template <class Driver>
-_GenericIterate<Driver>::_GenericIterate(const xmlpp::Element * p) :
- _SourceObject(p),
- _Iterate(p),
- Driver(p)
-{
-}
-
-template <class Driver>
-void
-_GenericIterate<Driver>::loadComplete()
-{
- Driver::loadComplete();
-}
-
-template <class Driver>
-void
-_GenericIterate<Driver>::execute() const
-{
- Driver::execute();
-}
-
-template <class Driver>
-void
-_GenericIterate<Driver>::rowReady() const
-{
- executeChildren();
-}
-
-template <class Driver>
-void
-_GenericIterate<Driver>::executeChildren() const
-{
- _Iterate::executeChildren();
-}
-
-template <class Driver>
-unsigned int
-_GenericIterate<Driver>::columnCount() const
-{
- return Driver::columnCount();
-}
-
-template <class Driver>
-const Glib::ustring &
-_GenericIterate<Driver>::getCurrentValue(const unsigned int id) const
-{
- return Driver::getCurrentValue(id);
-}
-
-template <class Driver>
-const Glib::ustring &
-_GenericIterate<Driver>::getCurrentValue(const Glib::ustring & id) const
-{
- return Driver::getCurrentValue(id);
-}
-
-template <class Driver>
-bool
-_GenericIterate<Driver>::isNull(const unsigned int id) const
-{
- return Driver::isNull(id);
-}
-
-template <class Driver>
-const Glib::ustring &
-_GenericIterate<Driver>::getColumnName(const unsigned int id) const
-{
- return Driver::getColumnName(id);
-}
-
diff --git a/project2/noOutputExecute.h b/project2/noOutputExecute.h
index 55fdf7a..3e92aba 100644
--- a/project2/noOutputExecute.h
+++ b/project2/noOutputExecute.h
@@ -17,5 +17,6 @@ class _NoOutputExecute : public virtual _SourceObject {
virtual ~_NoOutputExecute() { }
virtual void execute() const = 0;
};
+
#endif
diff --git a/project2/perRowValues.cpp b/project2/perRowValues.cpp
index 9f80924..82b46bc 100644
--- a/project2/perRowValues.cpp
+++ b/project2/perRowValues.cpp
@@ -1,11 +1,13 @@
#include "perRowValues.h"
+#include "commonObjects.h"
#include <cstdlib>
#include <boost/foreach.hpp>
#include <syslog.h>
PerRowValues::RowValuesStack PerRowValues::stack;
-PerRowValues::PerRowValues()
+PerRowValues::PerRowValues(const xmlpp::Element * p) :
+ _SourceObject(p)
{
}
@@ -34,12 +36,17 @@ PerRowValues::beginRow(const PerRowValues * r)
void
PerRowValues::endRow(const PerRowValues * r)
{
- if ((*stack.rbegin()) != r) {
+ if (stack.back() != r) {
syslog(LOG_ERR, "PerRowValues::endRow: stack is corrupted");
std::abort();
}
stack.pop_back();
- BOOST_FOREACH(const RowUser * ru, r->rowUsers) {
+}
+
+void
+PerRowValues::rowChanged() const
+{
+ BOOST_FOREACH(const RowUser * ru, rowUsers) {
ru->rowChanged();
}
}
@@ -52,3 +59,20 @@ RowUser::~RowUser()
{
}
+RowProcessor::RowProcessor(const xmlpp::Element * p) :
+ _SourceObject(p),
+ IHaveParameters(p),
+ recordSource(p->get_attribute_value("source")),
+ filter(p->get_attribute_value("filter"))
+{
+}
+
+void
+RowProcessor::loadComplete(const CommonObjects * co)
+{
+ source = co->getSource(recordSource);
+ if (!filter.empty()) {
+ source->setFilter(filter);
+ }
+}
+
diff --git a/project2/perRowValues.h b/project2/perRowValues.h
index 09c77f5..abd1507 100644
--- a/project2/perRowValues.h
+++ b/project2/perRowValues.h
@@ -4,6 +4,10 @@
#include <glibmm/ustring.h>
#include <vector>
#include <set>
+#include <map>
+#include <boost/intrusive_ptr.hpp>
+#include "sourceObject.h"
+#include "iHaveParameters.h"
class RowUser {
public:
@@ -13,25 +17,45 @@ class RowUser {
virtual void rowChanged() const = 0;
};
-class PerRowValues {
+class PerRowValues;
+typedef boost::intrusive_ptr<PerRowValues> PerRowValuesPtr;
+typedef std::map<std::string, PerRowValuesPtr> RowSets;
+
+class RowProcessor : public IHaveParameters, public virtual _SourceObject {
+ public:
+ RowProcessor(const xmlpp::Element *);
+ virtual void rowReady() const = 0;
+ void loadComplete(const CommonObjects *);
+
+ const std::string recordSource;
+ const Glib::ustring filter;
+
+ protected:
+ PerRowValuesPtr source;
+};
+
+class PerRowValues : public virtual _SourceObject {
public:
class ParentOutOfRange : public std::exception { };
class FieldDoesNotExist : public std::exception { };
typedef std::vector<const PerRowValues *> RowValuesStack;
- PerRowValues();
+ PerRowValues(const xmlpp::Element *);
virtual ~PerRowValues() = 0;
+ virtual void setFilter(const Glib::ustring &) = 0;
virtual unsigned int columnCount() const = 0;
virtual const Glib::ustring & getColumnName(unsigned int col) const = 0;
virtual const Glib::ustring & getCurrentValue(const Glib::ustring & id) const = 0;
virtual const Glib::ustring & getCurrentValue(unsigned int col) const = 0;
virtual bool isNull(unsigned int col) const = 0;
+ virtual void execute(const RowProcessor *) const = 0;
void use(const RowUser * r) const;
void finish(const RowUser * r) const;
static const RowValuesStack & Stack() { return stack; }
static void beginRow(const PerRowValues * r);
static void endRow(const PerRowValues * r);
+ void rowChanged() const;
private:
static RowValuesStack stack;
diff --git a/project2/presenter.cpp b/project2/presenter.cpp
index 71ed45b..d7ddf5a 100644
--- a/project2/presenter.cpp
+++ b/project2/presenter.cpp
@@ -4,36 +4,117 @@
#include "appEngine.h"
Presenter::Presenter(const std::string & group, const std::string & file) :
- present(group + "/" + file + ".xml"),
- responseRootNodeName(present.get_document()->get_root_node()->get_attribute_value("root")),
- responseStyle(present.get_document()->get_root_node()->get_attribute_value("style"))
+ present(group + "/" + file + ".xml")
{
while (xmlXIncludeProcessFlags(present.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0);
LoaderBase loader("http://project2.randomdan.homeip.net", true);
- loader.supportedStorers.insert(Storer::into(&ApplicationEngine::getCurrent()->datasources));
+ loader.supportedStorers.insert(Storer::into(&datasources));
+ loader.supportedStorers.insert(Storer::into(&rowSets));
loader.supportedStorers.insert(Storer::into(&views));
loader.supportedStorers.insert(Storer::into(&parameterChecks));
- loader.collectAll(present.get_document()->get_root_node(), true);
+ loader.collectAll(this, present.get_document()->get_root_node(), true);
}
Presenter::~Presenter()
{
}
-Presenter::XmlDocumentPtr
-Presenter::getDataDocument() const
+void
+Presenter::execute() const
{
- ApplicationEngine * appEngine = ApplicationEngine::getCurrent();
- XmlDocumentPtr responseDoc = boost::shared_ptr<xmlpp::Document>(new xmlpp::Document("1.0"));
- xmlpp::Element * responseRoot = responseDoc->create_root_node(responseRootNodeName);
BOOST_FOREACH(Views::value_type s, views) {
- s.second->execute(responseRoot);
+ s.second->execute(this);
}
// These were for debug... but why not pass them on?
- xmlNewNs(responseRoot->cobj(), BAD_CAST "http://project2.randomdan.homeip.net", BAD_CAST "project2");
- responseRoot->add_child("servername", "project2")->set_child_text(appEngine->env()->getServerName());
- responseRoot->add_child("scriptname", "project2")->set_child_text(appEngine->env()->getScriptName());
+ ApplicationEngine * appEngine = ApplicationEngine::getCurrent();
+ addField("servername", "project2", appEngine->env()->getServerName());
+ addField("scriptname", "project2", appEngine->env()->getScriptName());
+ appEngine->addAppData(this);
+}
+
+void
+Presenter::pushSub(const Glib::ustring & name) const
+{
+ pushSub(name, Glib::ustring());
+}
+
+void
+Presenter::addAttr(const Glib::ustring & name, const Glib::ustring & value) const
+{
+ addAttr(name, Glib::ustring(), value);
+}
+
+void
+Presenter::addAttr(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const
+{
+ addField(name, ns, value);
+}
+
+void
+Presenter::addField(const Glib::ustring & name, const Glib::ustring & value) const
+{
+ addField(name, Glib::ustring(), value);
+}
+
+void
+Presenter::addField(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const
+{
+ pushSub(name, ns);
+ setText(value);
+ popSub();
+}
+
+XmlPresenter::~XmlPresenter()
+{
+}
+
+XmlPresenter::XmlPresenter(const std::string & group, const std::string & file) :
+ Presenter(group, file),
+ responseRootNodeName(present.get_document()->get_root_node()->get_attribute_value("root")),
+ responseStyle(present.get_document()->get_root_node()->get_attribute_value("style")),
+ contentType(present.get_document()->get_root_node()->get_attribute_value("contenttype")),
+ responseDoc(XmlDocumentPtr(new xmlpp::Document("1.0")))
+{
+ nodeStack.push_back(responseDoc->create_root_node(responseRootNodeName));
+ xmlNewNs(nodeStack.back()->cobj(), BAD_CAST "http://project2.randomdan.homeip.net", BAD_CAST "project2");
+ // XSLT Style
+ char * buf;
+ if (responseStyle.length() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"",
+ responseStyle.c_str()) > 0) {
+ xmlAddPrevSibling(nodeStack.back()->cobj(),
+ xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf));
+ free(buf);
+ }
+}
+
+XmlPresenter::XmlDocumentPtr
+XmlPresenter::getDataDocument() const
+{
return responseDoc;
}
+void
+XmlPresenter::pushSub(const Glib::ustring & name, const Glib::ustring & ns) const
+{
+ nodeStack.push_back(nodeStack.back()->add_child(name, ns));
+}
+
+void
+XmlPresenter::addAttr(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const
+{
+ nodeStack.back()->set_attribute(name, value, ns);
+}
+
+void
+XmlPresenter::setText(const Glib::ustring & value) const
+{
+ nodeStack.back()->set_child_text(value);
+}
+
+void
+XmlPresenter::popSub() const
+{
+ nodeStack.pop_back();
+}
+
diff --git a/project2/presenter.h b/project2/presenter.h
index 977aa4d..7968b88 100644
--- a/project2/presenter.h
+++ b/project2/presenter.h
@@ -7,24 +7,55 @@
#include <libxml++/parsers/domparser.h>
#include "view.h"
#include "paramChecker.h"
+#include "commonObjects.h"
-class Presenter : public virtual IntrusivePtrBase {
+class Presenter : public CommonObjects, public virtual IntrusivePtrBase {
public:
- typedef boost::shared_ptr<xmlpp::Document> XmlDocumentPtr;
Presenter(const std::string & group, const std::string & file);
- ~Presenter();
+ virtual ~Presenter() = 0;
- virtual XmlDocumentPtr getDataDocument() const;
+ virtual void pushSub(const Glib::ustring & name) const;
+ virtual void pushSub(const Glib::ustring & name, const Glib::ustring & ns) const = 0;
+ virtual void addAttr(const Glib::ustring & name, const Glib::ustring & value) const;
+ virtual void addAttr(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const;
+ virtual void addField(const Glib::ustring & name, const Glib::ustring & value) const;
+ virtual void addField(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const;
+ virtual void setText(const Glib::ustring & value) const = 0;
+ virtual void popSub() const = 0;
+ void execute() const;
protected:
Views views;
OrderedParamCheckers parameterChecks;
xmlpp::DomParser present;
+};
+
+typedef boost::intrusive_ptr<const Presenter> PresenterCPtr;
+typedef boost::intrusive_ptr<Presenter> PresenterPtr;
+
+class XmlPresenter : public Presenter {
public:
+ typedef boost::shared_ptr<xmlpp::Document> XmlDocumentPtr;
+ XmlPresenter(const std::string & group, const std::string & file);
+ ~XmlPresenter();
+
+ void pushSub(const Glib::ustring & name, const Glib::ustring & ns) const;
+ void addAttr(const Glib::ustring & name, const Glib::ustring & ns, const Glib::ustring & value) const;
+ void setText(const Glib::ustring & value) const;
+ void popSub() const;
+
+ virtual XmlDocumentPtr getDataDocument() const;
+
const Glib::ustring responseRootNodeName;
const Glib::ustring responseStyle;
+ const Glib::ustring contentType;
+
+ private:
+ XmlDocumentPtr responseDoc;
+ mutable std::vector<xmlpp::Element *> nodeStack;
};
-typedef boost::intrusive_ptr<Presenter> PresenterPtr;
+
+typedef boost::intrusive_ptr<XmlPresenter> XmlPresenterPtr;
#endif
diff --git a/project2/procRows.cpp b/project2/procRows.cpp
index e5ed86a..f4a34a1 100644
--- a/project2/procRows.cpp
+++ b/project2/procRows.cpp
@@ -1,10 +1,14 @@
#include "procRows.h"
+#include "xmlObjectLoader.h"
#include <stdexcept>
-ElementLoaderImpl<_ProcIterate> prociterateLoader("prociterate");
-ElementLoaderImpl<_ProcView> procviewLoader("procview");
+ElementLoaderImpl<_ProcRows> procrowsLoader("procrows");
+
+class SubProcessFailedToStart : public std::exception { };
+class SubProcessFailed : public std::exception { };
_ProcRows::_ProcRows(const xmlpp::Element * p) :
+ _SourceObject(p),
_FileRows(p)
{
}
@@ -14,7 +18,7 @@ _ProcRows::~_ProcRows()
}
void
-_ProcRows::loadComplete()
+_ProcRows::loadComplete(const CommonObjects *)
{
}
@@ -23,7 +27,7 @@ _ProcRows::doOpen() const
{
FILE * f = popen(path->c_str(), "re");
if (!f) {
- throw std::runtime_error("Could not open file");
+ throw SubProcessFailedToStart();
}
return FileStarChannel(f, false, doClose);
}
@@ -33,13 +37,8 @@ _ProcRows::doClose(FILE * f)
{
int pclo = pclose(f);
if (pclo != 0) {
- throw std::runtime_error("Subprocess returned an error");
+ throw SubProcessFailed();
}
return 0;
}
-#include "view.hpp"
-template class _GenericView<_ProcRows>;
-#include "iterate.hpp"
-template class _GenericIterate<_ProcRows>;
-
diff --git a/project2/procRows.h b/project2/procRows.h
index e28a5f5..bada523 100644
--- a/project2/procRows.h
+++ b/project2/procRows.h
@@ -8,12 +8,10 @@ class _ProcRows : public _FileRows {
_ProcRows(const xmlpp::Element * p);
~_ProcRows();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
virtual FileStarChannel doOpen() const;
static int doClose(FILE*);
};
-typedef _GenericView<_ProcRows> _ProcView;
-typedef _GenericIterate<_ProcRows> _ProcIterate;
#endif
diff --git a/project2/rawView.cpp b/project2/rawView.cpp
index 1378f17..3a97cd3 100644
--- a/project2/rawView.cpp
+++ b/project2/rawView.cpp
@@ -1,4 +1,4 @@
-#include <stdexcept>
+#include "exceptions.h"
#include "rawView.h"
#include "xml.h"
#include "xmlObjectLoader.h"
@@ -14,46 +14,41 @@ _RawView::_RawView(const xmlpp::Element * p) :
{
}
-void
-_RawView::loadComplete()
-{
-}
-
-unsigned int
-_RawView::columnCount() const
+ void
+_RawView::loadComplete(const CommonObjects *)
{
- throw std::runtime_error("_RawView::columnCount not implemented");
}
-const Glib::ustring &
-_RawView::getCurrentValue(unsigned int id) const
-{
- throw std::runtime_error("_RawView::getCurrentValue not implemented");
-}
-
-const Glib::ustring &
-_RawView::getCurrentValue(const Glib::ustring & id) const
-{
- throw std::runtime_error("_RawView::getCurrentValue not implemented");
-}
-
-bool
-_RawView::isNull(unsigned int id) const
-{
- throw std::runtime_error("_RawView::isNull not implemented");
-}
-
-const Glib::ustring &
-_RawView::getColumnName(unsigned int id) const
+void
+_RawView::execute(const Presenter * p) const
{
- throw std::runtime_error("_RawView::getColumnName not implemented");
+ BOOST_FOREACH(xmlpp::Node * node, copyRoot->get_children()) {
+ const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(node);
+ if (e) {
+ copyNode(p, e);
+ }
+ }
}
-void _RawView::execute(xmlpp::Element * par) const
+void
+_RawView::copyNode(const Presenter * p, const xmlpp::Element * n) const
{
- BOOST_FOREACH(xmlpp::Node * node, copyRoot->get_children()) {
- par->import_node(node);
+ p->pushSub(n->get_name());
+ xmlpp::Element::AttributeList al = n->get_attributes();
+ BOOST_FOREACH(const xmlpp::Attribute * a, al) {
+ p->addAttr(a->get_name(), a->get_value());
+ }
+ const xmlpp::TextNode * t = n->get_child_text();
+ if (t) {
+ p->setText(t->get_content());
}
+ xmlpp::Node::NodeList ch = n->get_children();
+ BOOST_FOREACH(const xmlpp::Node * c, ch) {
+ const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(c);
+ if (e) {
+ copyNode(p, e);
+ }
+ }
+ p->popSub();
}
-
diff --git a/project2/rawView.h b/project2/rawView.h
index a6d85de..3f0de83 100644
--- a/project2/rawView.h
+++ b/project2/rawView.h
@@ -6,19 +6,13 @@
#include <map>
#include "view.h"
-class ApplicationEngine;
-
class _RawView : public _View {
public:
_RawView(const xmlpp::Element * p);
- void execute(xmlpp::Element *) const;
- virtual void loadComplete();
- virtual unsigned int columnCount() const;
- virtual const Glib::ustring & getColumnName(unsigned int col) const;
- virtual const Glib::ustring & getCurrentValue(const Glib::ustring & id) const;
- virtual const Glib::ustring & getCurrentValue(unsigned int col) const;
- virtual bool isNull(unsigned int col) const;
+ void execute(const Presenter *) const;
+ virtual void loadComplete(const CommonObjects *);
private:
+ void copyNode(const Presenter *, const xmlpp::Element *) const;
const xmlpp::Element * copyRoot;
};
typedef boost::intrusive_ptr<_RawView> RawView;
diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp
index 4f9c7d7..4dccc08 100644
--- a/project2/rdbmsDataSource.cpp
+++ b/project2/rdbmsDataSource.cpp
@@ -28,17 +28,21 @@ class RdbmsDataSourceLoader : public ElementLoaderImpl<_RdbmsDataSource> {
_RdbmsDataSource::dbhosts.erase(i);
}
}
+ void onIteration()
+ {
+ _RdbmsDataSource::changedDSNs.clear();
+ }
} rdbmsLoader;
_RdbmsDataSource::DBHosts _RdbmsDataSource::dbhosts;
_RdbmsDataSource::FailedHosts _RdbmsDataSource::failedhosts;
+_RdbmsDataSource::DSNSet _RdbmsDataSource::changedDSNs;
_RdbmsDataSource::_RdbmsDataSource(const xmlpp::Element * p) :
_SourceObject(p),
_DataSource(p),
masterDsn(xmlChildText(p, "masterdsn")),
- preferLocal(p->get_attribute_value("preferlocal") != "false"),
- changesMade(false)
+ preferLocal(p->get_attribute_value("preferlocal") != "false")
{
BOOST_FOREACH(const xmlpp::Node * node, p->find("readonly/dsn")) {
const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
@@ -48,8 +52,12 @@ _RdbmsDataSource::_RdbmsDataSource(const xmlpp::Element * p) :
}
}
+_RdbmsDataSource::~_RdbmsDataSource()
+{
+}
+
void
-_RdbmsDataSource::loadComplete()
+_RdbmsDataSource::loadComplete(const CommonObjects *)
{
}
@@ -60,14 +68,14 @@ _RdbmsDataSource::getWritable() const
if (!master->inTx()) {
master->beginTx();
}
- changesMade = true;
+ changedDSNs.insert(name);
return *master;
}
ODBC::Connection &
_RdbmsDataSource::getReadonly() const
{
- if (changesMade) {
+ if (changedDSNs.find(name) != changedDSNs.end()) {
return *connectTo(masterDsn);
}
if (localhost.length() == 0 && preferLocal) {
@@ -121,7 +129,7 @@ _RdbmsDataSource::rollback()
if (m != dbhosts.end() && m->second->inTx()) {
m->second->rollbackTx();
}
- changesMade = false;
+ changedDSNs.erase(name);
}
_RdbmsDataSource::ConnectionPtr
diff --git a/project2/rdbmsDataSource.h b/project2/rdbmsDataSource.h
index 77fbe3a..5421b3f 100644
--- a/project2/rdbmsDataSource.h
+++ b/project2/rdbmsDataSource.h
@@ -23,9 +23,10 @@ class _RdbmsDataSource : public _DataSource {
typedef std::map<std::string, ConnectionPtr> DBHosts; // Map DSN strings to connections
typedef std::map<std::string, const ODBC::ConnectionError> FailedHosts; // Map DSN strings to failures
_RdbmsDataSource(const xmlpp::Element * p);
+ ~_RdbmsDataSource();
ODBC::Connection & getReadonly() const;
ODBC::Connection & getWritable() const;
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
virtual void commit();
virtual void rollback();
const std::string masterDsn;
@@ -34,12 +35,13 @@ class _RdbmsDataSource : public _DataSource {
protected:
static ConnectionPtr connectTo(const std::string & dsn);
ReadonlyDSNs roDSNs;
- mutable bool changesMade;
private:
mutable std::string localhost;
static DBHosts dbhosts;
static FailedHosts failedhosts;
+ typedef std::set<std::string> DSNSet;
+ static DSNSet changedDSNs;
friend class RdbmsDataSourceLoader;
};
diff --git a/project2/regexCheck.cpp b/project2/regexCheck.cpp
index 62be6b1..92b7563 100644
--- a/project2/regexCheck.cpp
+++ b/project2/regexCheck.cpp
@@ -1,6 +1,6 @@
#include "regexCheck.h"
#include "xmlObjectLoader.h"
-#include "appEngine.h"
+#include "commonObjects.h"
#include <boost/regex.hpp>
ElementLoaderImpl<_RegexCheck> regexCheckLoader("regexcheck");
@@ -18,7 +18,7 @@ _RegexCheck::~_RegexCheck()
}
void
-_RegexCheck::loadComplete()
+_RegexCheck::loadComplete(const CommonObjects *)
{
}
diff --git a/project2/regexCheck.h b/project2/regexCheck.h
index e848ef0..868f97e 100644
--- a/project2/regexCheck.h
+++ b/project2/regexCheck.h
@@ -9,7 +9,7 @@ class _RegexCheck : public _ParamChecker {
_RegexCheck(const xmlpp::Element * p);
virtual ~_RegexCheck();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
bool performCheck() const;
const Variable applyTo;
diff --git a/project2/sendmailTask.cpp b/project2/sendmailTask.cpp
index 65d55d8..97c7b4f 100644
--- a/project2/sendmailTask.cpp
+++ b/project2/sendmailTask.cpp
@@ -13,6 +13,11 @@
ElementLoaderImpl<_SendMailTask> sendmailLoader("sendmail");
+class SendEmailFailed : public std::runtime_error {
+ public:
+ SendEmailFailed(const std::string & what) : std::runtime_error(what) { }
+};
+
typedef boost::shared_ptr<xmlDoc> XmlDocumentPtr;
_SendMailTask::_SendMailTask(const xmlpp::Element * p) :
@@ -31,7 +36,7 @@ _SendMailTask::~_SendMailTask()
}
void
-_SendMailTask::loadComplete()
+_SendMailTask::loadComplete(const CommonObjects *)
{
}
@@ -125,18 +130,22 @@ class TextContent : public _SendMailTask::MailPart {
void
_SendMailTask::execute() const
{
- PresenterPtr p = ApplicationEngine::getCurrent()->getPresenter("emails", present);
- Presenter::XmlDocumentPtr data = p->getDataDocument();
+ XmlPresenterPtr p = new XmlPresenter("emails", present);
+ p->execute();
+ XmlPresenter::XmlDocumentPtr data = p->getDataDocument();
+#if DEBUG
+ data->write_to_file("/tmp/email.xml");
+#endif
typedef boost::shared_ptr<xsltStylesheet> XsltStyleSheetPtr;
// Do transform
XsltStyleSheetPtr cur = XsltStyleSheetPtr(xsltParseStylesheetFile(BAD_CAST p->responseStyle.c_str()), xsltFreeStylesheet);
if (!cur) {
- throw std::runtime_error("Failed to load stylesheet");
+ throw xmlpp::exception("Failed to load stylesheet");
}
XmlDocumentPtr result = XmlDocumentPtr(xsltApplyStylesheet(cur.get(), data->cobj(), NULL), xmlFreeDoc);
if (!result) {
- throw std::runtime_error("Failed to perform transformation");
+ throw xmlpp::exception("Failed to perform transformation");
}
parts.clear();
@@ -163,7 +172,7 @@ _SendMailTask::execute() const
if (!smtp_start_session(session)) {
char buf[BUFSIZ];
smtp_strerror(smtp_errno(), buf, sizeof buf);
- throw std::runtime_error(buf);
+ throw SendEmailFailed(buf);
}
}
diff --git a/project2/sendmailTask.h b/project2/sendmailTask.h
index 2193974..f9ab6bd 100644
--- a/project2/sendmailTask.h
+++ b/project2/sendmailTask.h
@@ -20,7 +20,7 @@ class _SendMailTask : public _Task {
_SendMailTask(const xmlpp::Element * p);
virtual ~_SendMailTask();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
virtual void execute() const;
protected:
diff --git a/project2/sessionClearTask.cpp b/project2/sessionClearTask.cpp
index 95b1145..8af2b4a 100644
--- a/project2/sessionClearTask.cpp
+++ b/project2/sessionClearTask.cpp
@@ -18,7 +18,7 @@ _SessionClearTask::~_SessionClearTask()
}
void
-_SessionClearTask::loadComplete()
+_SessionClearTask::loadComplete(const CommonObjects *)
{
}
diff --git a/project2/sessionClearTask.h b/project2/sessionClearTask.h
index ab602b1..94bca1d 100644
--- a/project2/sessionClearTask.h
+++ b/project2/sessionClearTask.h
@@ -8,7 +8,7 @@
#include "xmlObjectLoader.h"
#include "task.h"
-class ApplicationEngine;
+class CommonObjects;
class _SessionClearTask;
typedef boost::intrusive_ptr<_SessionClearTask> SessionClearTask;
@@ -16,7 +16,7 @@ class _SessionClearTask : public virtual _Task {
public:
_SessionClearTask(const xmlpp::Element * p);
virtual ~_SessionClearTask();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
void execute() const;
const Glib::ustring key;
diff --git a/project2/sessionSetTask.cpp b/project2/sessionSetTask.cpp
index 2340468..a8ac749 100644
--- a/project2/sessionSetTask.cpp
+++ b/project2/sessionSetTask.cpp
@@ -20,7 +20,7 @@ _SessionSetTask::~_SessionSetTask()
}
void
-_SessionSetTask::loadComplete()
+_SessionSetTask::loadComplete(const CommonObjects *)
{
}
diff --git a/project2/sessionSetTask.h b/project2/sessionSetTask.h
index 164b562..f85e8f1 100644
--- a/project2/sessionSetTask.h
+++ b/project2/sessionSetTask.h
@@ -9,7 +9,7 @@
#include "task.h"
#include "variables.h"
-class ApplicationEngine;
+class CommonObjects;
class _SessionSetTask;
typedef boost::intrusive_ptr<_SessionSetTask> SessionSetTask;
@@ -17,7 +17,7 @@ class _SessionSetTask : public virtual _Task {
public:
_SessionSetTask(const xmlpp::Element * p);
virtual ~_SessionSetTask();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
void execute() const;
const Glib::ustring key;
diff --git a/project2/sourceObject.h b/project2/sourceObject.h
index b37aad1..1ccc4af 100644
--- a/project2/sourceObject.h
+++ b/project2/sourceObject.h
@@ -5,6 +5,7 @@
#include <boost/intrusive_ptr.hpp>
#include "intrusivePtrBase.h"
+class CommonObjects;
class _SourceObject;
typedef boost::intrusive_ptr<_SourceObject> Project2SourceObject;
class _SourceObject : public virtual IntrusivePtrBase {
@@ -12,7 +13,8 @@ class _SourceObject : public virtual IntrusivePtrBase {
_SourceObject(const xmlpp::Element * p);
_SourceObject(const std::string & name);
virtual ~_SourceObject() = 0;
- virtual void loadComplete() = 0;
+
+ virtual void loadComplete(const CommonObjects *) = 0;
const std::string name;
const unsigned int order;
diff --git a/project2/sqlCheck.cpp b/project2/sqlCheck.cpp
index 8d48d24..f348689 100644
--- a/project2/sqlCheck.cpp
+++ b/project2/sqlCheck.cpp
@@ -1,10 +1,10 @@
#include "sqlCheck.h"
#include "xmlObjectLoader.h"
-#include "appEngine.h"
#include "selectcommand.h"
#include "column.h"
#include "rdbmsDataSource.h"
#include <boost/regex.hpp>
+#include "commonObjects.h"
ElementLoaderImpl<_SqlCheck> sqlCheckLoader("sqlcheck");
@@ -26,17 +26,16 @@ _SqlCheck::~_SqlCheck()
}
void
-_SqlCheck::loadComplete()
+_SqlCheck::loadComplete(const CommonObjects * co)
{
- query = new ODBC::SelectCommand(ApplicationEngine::getCurrent()->dataSource<_RdbmsDataSource>(
- dataSource)->getReadonly(), sql);
+ query = new ODBC::SelectCommand(co->dataSource<_RdbmsDataSource>(dataSource)->getReadonly(), sql);
}
bool
_SqlCheck::performCheck() const
{
BOOST_FOREACH(Parameters::value_type p, parameters) {
- query->bindParamS(p.second->bind, p.second->value);
+ query->bindParamS(atoi(p.second->name.c_str()), p.second->value);
}
bool retVal = false;
while (query->fetch()) {
diff --git a/project2/sqlCheck.h b/project2/sqlCheck.h
index 0c5efcc..40c6e9a 100644
--- a/project2/sqlCheck.h
+++ b/project2/sqlCheck.h
@@ -11,7 +11,7 @@ class _SqlCheck : public IHaveParameters, public _ParamChecker {
_SqlCheck(const xmlpp::Element * p);
virtual ~_SqlCheck();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
bool performCheck() const;
const std::string dataSource;
diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp
index 3abf4ee..279fa05 100644
--- a/project2/sqlMergeTask.cpp
+++ b/project2/sqlMergeTask.cpp
@@ -1,6 +1,7 @@
#include "sqlMergeTask.h"
#include "appEngine.h"
#include "rdbmsDataSource.h"
+#include "exceptions.h"
#include <misc.h>
#include <stdio.h>
#include <stdexcept>
@@ -31,7 +32,7 @@ _SqlMergeTask::_SqlMergeTask(const xmlpp::Element * p) :
loader.collectAll(p, true);
if (!sources.empty() && useView) {
- throw std::runtime_error("useview not supported with iterate fillers");
+ throw NotSupported("useview not supported with iterate fillers");
}
BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column")) {
@@ -40,7 +41,7 @@ _SqlMergeTask::_SqlMergeTask(const xmlpp::Element * p) :
tcp->maptable = e->get_attribute_value("maptable");
if (!tcp->maptable.empty()) {
if (useView) {
- throw std::runtime_error("useview not supported with mapped columns");
+ throw NotSupported("useview not supported with mapped columns");
}
tcp->mapcolumn = e->get_attribute_value("mapcolumn");
}
@@ -60,9 +61,9 @@ _SqlMergeTask::~_SqlMergeTask()
}
void
-_SqlMergeTask::loadComplete()
+_SqlMergeTask::loadComplete(const CommonObjects * co)
{
- destdb = &ApplicationEngine::getCurrent()->dataSource<_RdbmsDataSource>(dataSource)->getWritable();
+ destdb = &co->dataSource<_RdbmsDataSource>(dataSource)->getWritable();
insCmd = insertCommand();
BOOST_FOREACH(const Iterates::value_type & i, sources) {
attach(i.second, insCmd);
@@ -188,18 +189,18 @@ _SqlMergeTask::insertCommand() const
class _Populate : public _NoOutputExecute {
public:
- _Populate(Iterate i, ModifyCommand * c) :
+ _Populate(ModifyCommand * c) :
_SourceObject(__FUNCTION__),
_NoOutputExecute(__FUNCTION__),
- iter(i),
cmd(c)
{
}
- virtual void loadComplete()
+ virtual void loadComplete(const CommonObjects *)
{
}
void execute() const
{
+ const PerRowValues * iter = *++PerRowValues::Stack().rbegin();
if (idxs.empty()) {
idxs.resize(iter->columnCount());
// Sure this can be improved upon... but hey.
@@ -227,19 +228,18 @@ class _Populate : public _NoOutputExecute {
}
private:
mutable std::vector<unsigned int> idxs;
- Iterate iter;
ModifyCommand * cmd;
};
typedef boost::intrusive_ptr<_Populate> Populate;
-static void attach(Iterate i, ModifyCommand * insert)
+static void
+attach(Iterate i, ModifyCommand * insert)
{
if (!i) {
return;
}
if (i->subNOEs.empty()) {
- Populate p(new _Populate(i, insert));
- i->subNOEs.insert(NoOutputExecutes::value_type(0, p));
+ i->subNOEs.insert(NoOutputExecutes::value_type(0, new _Populate(insert)));
}
else {
BOOST_FOREACH(const NoOutputExecutes::value_type & n, i->subNOEs) {
diff --git a/project2/sqlMergeTask.h b/project2/sqlMergeTask.h
index 633dc2a..532367e 100644
--- a/project2/sqlMergeTask.h
+++ b/project2/sqlMergeTask.h
@@ -40,7 +40,7 @@ class _SqlMergeTask : public _Task {
_SqlMergeTask(const xmlpp::Element * p);
virtual ~_SqlMergeTask();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
void execute() const;
Columns cols;
Keys keys;
diff --git a/project2/sqlRows.cpp b/project2/sqlRows.cpp
index 751a459..9244a9c 100644
--- a/project2/sqlRows.cpp
+++ b/project2/sqlRows.cpp
@@ -6,29 +6,37 @@
#include <string.h>
#include <libxml++/nodes/textnode.h>
#include "xmlObjectLoader.h"
-#include "appEngine.h"
+#include "commonObjects.h"
-ElementLoaderImpl<_SqlIterate> sqliterateLoader("sqliterate");
-ElementLoaderImpl<_SqlView> sqlviewLoader("sqlview");
+ElementLoaderImpl<_SqlRows> sqlviewLoader("sqlrows");
_SqlRows::_SqlRows(const xmlpp::Element * p) :
- IHaveParameters(p),
+ _SourceObject(p),
+ PerRowValues(p),
dataSource(p->get_attribute_value("datasource")),
- sql(xmlChildText(p, "sql")),
- query(NULL)
+ sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front())),
+ query(NULL),
+ db(NULL)
{
}
_SqlRows::~_SqlRows()
{
- delete query;
}
void
-_SqlRows::loadComplete()
+_SqlRows::loadComplete(const CommonObjects * co)
+{
+ db = co->dataSource<_RdbmsDataSource>(dataSource);
+}
+
+void
+_SqlRows::setFilter(const Glib::ustring & name)
{
- query = new ODBC::SelectCommand(ApplicationEngine::getCurrent()->dataSource<_RdbmsDataSource>(
- dataSource)->getReadonly(), sql);
+ SqlCommand::FiltersRangeType r = sqlCommand.filters.equal_range(name);
+ for (SqlCommand::Filters::const_iterator i = r.first; i != r.second; i++) {
+ i->second->active = true;
+ }
}
const Glib::ustring &
@@ -62,18 +70,132 @@ _SqlRows::getColumnName(unsigned int col) const
}
void
-_SqlRows::execute() const
+_SqlRows::execute(const RowProcessor * rp) const
{
- BOOST_FOREACH(Parameters::value_type p, parameters) {
- query->bindParamS(p.second->bind, p.second->value);
- }
+ unsigned int offset = 0;
+ Glib::ustring sql;
+ sqlCommand.writeSql(sql);
+ query = new ODBC::SelectCommand(db->getReadonly(), sql);
+ sqlCommand.bindParams(rp, query, offset);
while (query->fetch()) {
- rowReady();
+ rp->rowReady();
+ }
+ delete query;
+}
+
+_SqlRows::SqlWriter::SqlWriter()
+{
+}
+
+_SqlRows::SqlWriter::~SqlWriter()
+{
+}
+
+_SqlRows::SqlCommand::SqlCommand(const xmlpp::Element * N)
+{
+ BOOST_FOREACH(xmlpp::Node * n, N->get_children()) {
+ const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n);
+ if (t) {
+ writers.push_back(new SqlText(t));
+ }
+ const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n);
+ if (e) {
+ if (e->get_name() == "filter") {
+ SqlFilterPtr f = new SqlFilter(e);
+ writers.push_back(f);
+ filters.insert(Filters::value_type(f->name, f));
+ }
+ else if (e->get_name() == "param") {
+ writers.push_back(new SqlParameter(e));
+ }
+ }
+ }
+}
+
+void
+_SqlRows::SqlCommand::writeSql(Glib::ustring & sql) const
+{
+ BOOST_FOREACH(const SqlWriterPtr & w, writers) {
+ w->writeSql(sql);
+ }
+}
+
+void
+_SqlRows::SqlCommand::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const
+{
+ BOOST_FOREACH(const SqlWriterPtr & w, writers) {
+ w->bindParams(rp, cmd, offset);
+ }
+}
+
+_SqlRows::SqlFilter::SqlFilter(const xmlpp::Element * N) :
+ name(N->get_attribute_value("name")),
+ active(false)
+{
+ BOOST_FOREACH(xmlpp::Node * n, N->get_children()) {
+ const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n);
+ if (t) {
+ writers.push_back(new SqlText(t));
+ }
+ const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n);
+ if (e) {
+ if (e->get_name() == "param") {
+ writers.push_back(new SqlParameter(e));
+ }
+ }
}
}
-#include "view.hpp"
-template class _GenericView<_SqlRows>;
-#include "iterate.hpp"
-template class _GenericIterate<_SqlRows>;
+void
+_SqlRows::SqlFilter::writeSql(Glib::ustring & sql) const
+{
+ if (active) {
+ BOOST_FOREACH(const SqlWriterPtr & w, writers) {
+ w->writeSql(sql);
+ }
+ }
+}
+
+void
+_SqlRows::SqlFilter::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const
+{
+ if (active) {
+ BOOST_FOREACH(const SqlWriterPtr & w, writers) {
+ w->bindParams(rp, cmd, offset);
+ }
+ }
+}
+
+_SqlRows::SqlParameter::SqlParameter(const xmlpp::Element * n) :
+ name(n->get_attribute_value("name"))
+{
+}
+
+void
+_SqlRows::SqlParameter::writeSql(Glib::ustring & sql) const
+{
+ sql.append("?");
+}
+
+void
+_SqlRows::SqlParameter::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const
+{
+ cmd->bindParamS(offset++, rp->getParameter(name));
+}
+
+_SqlRows::SqlText::SqlText(const xmlpp::TextNode * n) :
+ text(n->get_content())
+{
+}
+
+void
+_SqlRows::SqlText::writeSql(Glib::ustring & sql) const
+{
+ sql.append(text);
+}
+
+void
+_SqlRows::SqlText::bindParams(const RowProcessor * rp, ODBC::SelectCommand * cmd, unsigned int & offset) const
+{
+}
diff --git a/project2/sqlRows.h b/project2/sqlRows.h
index 37ca72e..b983743 100644
--- a/project2/sqlRows.h
+++ b/project2/sqlRows.h
@@ -1,45 +1,86 @@
-#ifndef SQLITERATE_H
-#define SQLITERATE_H
+#ifndef SQLROWS_H
+#define SQLROWS_H
#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <map>
#include "selectcommand.h"
-#include "iterate.h"
-#include "view.h"
#include "iHaveParameters.h"
+#include "perRowValues.h"
-class ApplicationEngine;
+class _RdbmsDataSource;
-class _SqlRows : public IHaveParameters, public PerRowValues {
+class _SqlRows : public PerRowValues {
public:
_SqlRows(const xmlpp::Element * p);
~_SqlRows();
- void execute() const;
- virtual void loadComplete();
+ void execute(const RowProcessor *) const;
+ virtual void loadComplete(const CommonObjects *);
+ virtual void setFilter(const Glib::ustring &);
unsigned int columnCount() const;
const Glib::ustring & getColumnName(unsigned int col) const;
const Glib::ustring & getCurrentValue(const Glib::ustring & id) const;
const Glib::ustring & getCurrentValue(unsigned int col) const;
bool isNull(unsigned int col) const;
- virtual void rowReady() const = 0;
const std::string dataSource;
- const Glib::ustring sql;
private:
+ class SqlWriter;
+ typedef boost::intrusive_ptr<SqlWriter> SqlWriterPtr;
+ typedef std::list<SqlWriterPtr> Writers;
+ class SqlWriter : public IntrusivePtrBase {
+ public:
+ SqlWriter();
+ virtual ~SqlWriter();
+ virtual void writeSql(Glib::ustring & sql) const = 0;
+ virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const = 0;
+ };
+ class SqlText : public SqlWriter {
+ public:
+ SqlText(const xmlpp::TextNode *);
+ virtual void writeSql(Glib::ustring & sql) const;
+ virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const;
+
+ const Glib::ustring text;
+ };
+ class SqlParameter : public SqlWriter {
+ public:
+ SqlParameter(const xmlpp::Element *);
+ virtual void writeSql(Glib::ustring & sql) const;
+ virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const;
+
+ const Glib::ustring name;
+ };
+ class SqlFilter : public SqlWriter {
+ public:
+ SqlFilter(const xmlpp::Element *);
+ virtual void writeSql(Glib::ustring & sql) const;
+ virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const;
+
+ const Glib::ustring name;
+ bool active;
+ private:
+ Writers writers;
+ };
+ typedef boost::intrusive_ptr<SqlFilter> SqlFilterPtr;
+ class SqlCommand : public SqlWriter {
+ public:
+ SqlCommand(const xmlpp::Element *);
+ virtual void writeSql(Glib::ustring & sql) const;
+ virtual void bindParams(const RowProcessor *, ODBC::SelectCommand *, unsigned int & offset) const;
+ typedef std::multimap<Glib::ustring, SqlFilterPtr> Filters;
+ typedef std::pair<Filters::const_iterator, Filters::const_iterator> FiltersRangeType;
+ Filters filters;
+ private:
+ Writers writers;
+ };
+ SqlCommand sqlCommand;
mutable ODBC::SelectCommand * query;
+ const _RdbmsDataSource * db;
};
typedef boost::intrusive_ptr<_SqlRows> SqlRows;
-typedef _GenericView<_SqlRows> _SqlView;
-typedef boost::intrusive_ptr<_SqlView> SqlView;
-typedef std::map<std::string, SqlView> SqlViews;
-
-typedef _GenericIterate<_SqlRows> _SqlIterate;
-typedef boost::intrusive_ptr<_SqlIterate> SqlIterate;
-typedef std::map<std::string, SqlIterate> SqlIterates;
-
#endif
diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp
index 7ff5f40..2775a74 100644
--- a/project2/sqlTask.cpp
+++ b/project2/sqlTask.cpp
@@ -2,8 +2,8 @@
#include <boost/foreach.hpp>
#include "xmlObjectLoader.h"
#include "modifycommand.h"
-#include "appEngine.h"
#include "rdbmsDataSource.h"
+#include "commonObjects.h"
ElementLoaderImpl<_SqlTask> sqltaskLoader("sqltask");
@@ -23,16 +23,16 @@ _SqlTask::~_SqlTask()
}
void
-_SqlTask::loadComplete()
+_SqlTask::loadComplete(const CommonObjects * co)
{
- modify = new ODBC::ModifyCommand(ApplicationEngine::getCurrent()->dataSource<_RdbmsDataSource>(dataSource)->getWritable(), sql);
+ modify = new ODBC::ModifyCommand(co->dataSource<_RdbmsDataSource>(dataSource)->getWritable(), sql);
}
void
_SqlTask::execute() const
{
BOOST_FOREACH(Parameters::value_type p, parameters) {
- modify->bindParamS(p.second->bind, p.second->value);
+ modify->bindParamS(atoi(p.second->name.c_str()), p.second->value);
}
modify->execute();
}
diff --git a/project2/sqlTask.h b/project2/sqlTask.h
index e24fe24..5984c6f 100644
--- a/project2/sqlTask.h
+++ b/project2/sqlTask.h
@@ -16,7 +16,7 @@ class _SqlTask : public _Task, public IHaveParameters {
public:
_SqlTask(const xmlpp::Element * p);
virtual ~_SqlTask();
- virtual void loadComplete();
+ virtual void loadComplete(const CommonObjects *);
virtual void execute() const;
const std::string dataSource;
diff --git a/project2/task.h b/project2/task.h
index d100042..563a623 100644
--- a/project2/task.h
+++ b/project2/task.h
@@ -6,10 +6,8 @@
#include <map>
#include "sourceObject.h"
#include "xmlObjectLoader.h"
-#include "view.h"
#include "noOutputExecute.h"
-class ApplicationEngine;
class _Task;
typedef boost::intrusive_ptr<_Task> Task;
typedef std::map<std::string, Task> Tasks;
diff --git a/project2/urlRows.cpp b/project2/urlRows.cpp
index 6354aa7..8381d68 100644
--- a/project2/urlRows.cpp
+++ b/project2/urlRows.cpp
@@ -1,12 +1,15 @@
#include "urlRows.h"
+#include "xmlObjectLoader.h"
+#include "exceptions.h"
#include "../libmisc/curlsup.h"
#include <stdexcept>
#include <queue>
-ElementLoaderImpl<_UrlIterate> urliterateLoader("urliterate");
-ElementLoaderImpl<_UrlView> urlviewLoader("urlview");
+ElementLoaderImpl<_UrlRows> urlrowsLoader("urlrows");
_UrlRows::_UrlRows(const xmlpp::Element * p) :
+ _SourceObject(p),
+ PerRowValues(p),
url(p->get_attribute_value("url")),
fieldSep(p->get_attribute_value("fieldSep")[0]),
quoteChar(p->get_attribute_value("quoteChar")[0]),
@@ -30,10 +33,16 @@ _UrlRows::~_UrlRows()
}
void
-_UrlRows::loadComplete()
+_UrlRows::loadComplete(const CommonObjects *)
{
}
+void
+_UrlRows::setFilter(const Glib::ustring &)
+{
+ throw NotSupported(__PRETTY_FUNCTION__);
+}
+
unsigned int
_UrlRows::columnCount() const
{
@@ -73,12 +82,13 @@ _UrlRows::getCurrentValue(const Glib::ustring & id) const
size_t
_UrlRows::_handleData(const char * ptr, size_t size, size_t nmemb, void *stream)
{
- size_t used = static_cast<const _UrlRows *>(stream)->handleData(ptr, size * nmemb);
+ const callback * cb = static_cast<const callback *>(stream);
+ size_t used = cb->urlRows->handleData(cb->rp, ptr, size * nmemb);
return used;
}
size_t
-_UrlRows::handleData(const char * bytes, size_t bytesLen) const
+_UrlRows::handleData(const RowProcessor * rp, const char * bytes, size_t bytesLen) const
{
size_t used = 0, len = 0;
char * utf8 = g_convert(bytes, bytesLen, "utf-8", encoding.c_str(), &used, &len, NULL);
@@ -98,7 +108,7 @@ _UrlRows::handleData(const char * bytes, size_t bytesLen) const
while (values.size() < columns.size()) {
values.push_back(ValPtr(new Glib::ustring()));
}
- rowReady();
+ rp->rowReady();
}
else {
mkCols = false;
@@ -155,7 +165,7 @@ _UrlRows::addColumn(const Glib::ustring & rawtok) const
}
void
-_UrlRows::execute() const
+_UrlRows::execute(const RowProcessor * rp) const
{
CurlHandle::Ptr c = new CurlHandle();
c->setopt(CURLOPT_URL, url.c_str());
@@ -165,7 +175,8 @@ _UrlRows::execute() const
//c->setopt(CURLOPT_COOKIEJAR, (std::string(cacheRoot) + "/ytfs.cookies").c_str());
c->setopt(CURLOPT_ENCODING, "deflate, gzip");
c->setopt(CURLOPT_USERAGENT, "project2/0.3");
- c->setopt(CURLOPT_WRITEDATA, this);
+ callback cb(this, rp);
+ c->setopt(CURLOPT_WRITEDATA, &cb);
c->setopt(CURLOPT_WRITEFUNCTION, &_handleData);
c->perform();
if (!tok.empty()) {
@@ -182,14 +193,15 @@ _UrlRows::execute() const
while (values.size() < columns.size()) {
values.push_back(ValPtr(new Glib::ustring()));
}
- rowReady();
+ rp->rowReady();
values.clear();
}
values.clear();
}
-#include "view.hpp"
-template class _GenericView<_UrlRows>;
-#include "iterate.hpp"
-template class _GenericIterate<_UrlRows>;
+_UrlRows::callback::callback(const _UrlRows * u, const RowProcessor * r) :
+ urlRows(u),
+ rp(r)
+{
+}
diff --git a/project2/urlRows.h b/project2/urlRows.h
index 5ee7597..08acffc 100644
--- a/project2/urlRows.h
+++ b/project2/urlRows.h
@@ -5,22 +5,21 @@
#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <map>
-#include "view.h"
-#include "iterate.h"
+#include "perRowValues.h"
class _UrlRows : public PerRowValues {
public:
_UrlRows(const xmlpp::Element * p);
~_UrlRows();
- virtual void loadComplete();
- void execute() const;
+ virtual void loadComplete(const CommonObjects *);
+ void execute(const RowProcessor *) const;
+ virtual void setFilter(const Glib::ustring &);
unsigned int columnCount() const;
const Glib::ustring & getColumnName(unsigned int col) const;
const Glib::ustring & getCurrentValue(const Glib::ustring & id) const;
const Glib::ustring & getCurrentValue(unsigned int col) const;
bool isNull(unsigned int col) const;
- virtual void rowReady() const = 0;
typedef std::set<gunichar> CharSet;
const Glib::ustring url;
@@ -32,8 +31,13 @@ class _UrlRows : public PerRowValues {
mutable Values values;
private:
+ struct callback {
+ callback(const _UrlRows * urlRows, const RowProcessor * rp);
+ const _UrlRows * urlRows;
+ const RowProcessor * rp;
+ };
static size_t _handleData(const char * ptr, size_t size, size_t nmemb, void * stream);
- size_t handleData(const char * bytes, size_t bytesLen) const;
+ size_t handleData(const RowProcessor * rp, const char * bytes, size_t bytesLen) const;
gunichar fieldSep;
gunichar quoteChar;
gunichar newline;
@@ -50,15 +54,5 @@ class _UrlRows : public PerRowValues {
};
typedef boost::intrusive_ptr<_UrlRows> UrlRows;
-typedef _GenericView<_UrlRows> _UrlView;
-typedef boost::intrusive_ptr<_UrlView> UrlView;
-typedef std::map<std::string, UrlView> UrlViews;
-
-typedef _GenericIterate<_UrlRows> _UrlIterate;
-typedef boost::intrusive_ptr<_UrlIterate> UrlIterate;
-typedef std::map<std::string, UrlIterate> UrlIterates;
-
#endif
-
-
diff --git a/project2/variables.cpp b/project2/variables.cpp
index 3c27d44..09ea36e 100644
--- a/project2/variables.cpp
+++ b/project2/variables.cpp
@@ -1,4 +1,5 @@
#include "variables.h"
+#include "exceptions.h"
#include "appEngine.h"
#include "perRowValues.h"
#include "session.h"
@@ -52,7 +53,7 @@ class VariableParam : public VariableImplDyn {
try {
cache = ApplicationEngine::getCurrent()->env()->getParamQuery(name);
}
- catch (ApplicationEngine::ParamNotFound) {
+ catch (ParamNotFound) {
if (!defaultValue) {
throw;
}
@@ -73,7 +74,7 @@ class VariableUri : public VariableImplDyn {
try {
cache = ApplicationEngine::getCurrent()->env()->getParamUri(atoi(name.c_str()));
}
- catch (ApplicationEngine::UriElementOutOfRange) {
+ catch (UriElementOutOfRange) {
if (!defaultValue) {
throw;
}
@@ -109,7 +110,7 @@ class VariableParent : public VariableImplDyn, public RowUser {
try {
if (!row) {
PerRowValues::RowValuesStack::const_reverse_iterator r = PerRowValues::Stack().rbegin();
- for (size_t p = depth; --p; r++) ;
+ for (size_t p = depth; p--; r++) ;
if (r == PerRowValues::Stack().rend()) {
throw PerRowValues::ParentOutOfRange();
}
diff --git a/project2/view.cpp b/project2/view.cpp
index 44a162a..06eb6cc 100644
--- a/project2/view.cpp
+++ b/project2/view.cpp
@@ -1,8 +1,24 @@
#include "view.h"
+#include "presenter.h"
#include <boost/foreach.hpp>
+#include <stdexcept>
+
+ElementLoaderImpl<_RowView> viewLoader("view");
_View::_View(const xmlpp::Element * p) :
+ _SourceObject(p)
+{
+}
+
+_View::~_View()
+{
+}
+
+_RowView::_RowView(const xmlpp::Element * p) :
_SourceObject(p),
+ _View(p),
+ RowProcessor(p),
+ rootName(p->get_attribute_value("rootname")),
recordName(p->get_attribute_value("recordname"))
{
LoaderBase loader("http://project2.randomdan.homeip.net", true);
@@ -10,23 +26,54 @@ _View::_View(const xmlpp::Element * p) :
loader.collectAll(p, true);
}
-_View::~_View()
+_RowView::~_RowView()
{
}
void
-_View::executeChildren(xmlpp::Element * record) const
+_RowView::loadComplete(const CommonObjects * co)
{
- try {
- PerRowValues::beginRow(this);
- BOOST_FOREACH(Views::value_type sq, subViews) {
- sq.second->execute(record);
+ RowProcessor::loadComplete(co);
+}
+
+void
+_RowView::rowReady() const
+{
+ presenter->pushSub(recordName);
+ unsigned int cols = source->columnCount();
+ for (unsigned int c = 0; c < cols; c += 1) {
+ if (!source->isNull(c)) {
+ presenter->addField(source->getColumnName(c), source->getCurrentValue(c));
}
- PerRowValues::endRow(this);
+ }
+ executeChildren();
+ source->rowChanged();
+ presenter->popSub();
+}
+
+void
+_RowView::execute(const Presenter * p) const
+{
+ presenter = p;
+ presenter->pushSub(rootName);
+ PerRowValues::beginRow(source.get());
+ try {
+ source->execute(this);
+ PerRowValues::endRow(source.get());
+ presenter->popSub();
}
catch (...) {
- PerRowValues::endRow(this);
+ presenter->popSub();
+ PerRowValues::endRow(source.get());
throw;
}
}
+void
+_RowView::executeChildren() const
+{
+ BOOST_FOREACH(Views::value_type sq, subViews) {
+ sq.second->execute(presenter);
+ }
+}
+
diff --git a/project2/view.h b/project2/view.h
index cadb4c9..332e13f 100644
--- a/project2/view.h
+++ b/project2/view.h
@@ -7,43 +7,37 @@
#include "sourceObject.h"
#include "xmlObjectLoader.h"
#include "perRowValues.h"
-#include "noOutputExecute.h"
-class ApplicationEngine;
+class Presenter;
class _View;
typedef boost::intrusive_ptr<_View> View;
typedef std::map<std::string, View> Views;
-class _View : public virtual _SourceObject, public PerRowValues {
+class _View : public virtual _SourceObject {
public:
- _View(const xmlpp::Element * p);
+ _View(const xmlpp::Element *);
virtual ~_View();
- virtual void execute(xmlpp::Element *) const = 0;
- virtual const Glib::ustring & getCurrentValue(const Glib::ustring & id) const = 0;
- const Glib::ustring recordName;
- protected:
- void executeChildren(xmlpp::Element *) const;
- Views subViews;
+ virtual void execute(const Presenter *) const = 0;
};
-template <class Driver>
-class _GenericView : public _View, public Driver {
+class _RowView : public _View, public RowProcessor {
public:
- _GenericView(const xmlpp::Element * p);
-
- virtual unsigned int columnCount() const;
- virtual void loadComplete();
- virtual const Glib::ustring & getCurrentValue(const unsigned int id) const;
- virtual const Glib::ustring & getCurrentValue(const Glib::ustring & id) const;
- virtual const Glib::ustring & getColumnName(const unsigned int id) const;
- virtual bool isNull(unsigned int col) const;
- virtual void execute(xmlpp::Element * e) const;
- virtual void rowReady() const;
- private:
- mutable xmlpp::Element * node;
+ _RowView(const xmlpp::Element *);
+ virtual ~_RowView();
+
+ void loadComplete(const CommonObjects *);
+ void execute(const Presenter *) const;
+ void rowReady() const;
+
+ const Glib::ustring rootName;
+ const Glib::ustring recordName;
+
+ protected:
+ void executeChildren() const;
+ Views subViews;
+ mutable const Presenter * presenter;
};
#endif
-
diff --git a/project2/view.hpp b/project2/view.hpp
deleted file mode 100644
index a065097..0000000
--- a/project2/view.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "view.h"
-
-template <class Driver>
-_GenericView<Driver>::_GenericView(const xmlpp::Element * p) :
- _SourceObject(p),
- _View(p),
- Driver(p),
- node(NULL)
-{
-}
-
-template <class Driver>
-void
-_GenericView<Driver>::execute(xmlpp::Element * e) const
-{
- node = e->add_child(name);
- Driver::execute();
-}
-
-template <class Driver>
-void
-_GenericView<Driver>::rowReady() const
-{
- xmlpp::Element * record = node->add_child(recordName);
- unsigned int cols = Driver::columnCount();
- for (unsigned int col = 0; col < cols; col += 1) {
- if (!Driver::isNull(col)) {
- xmlpp::Element * ch = record->add_child(Driver::getColumnName(col));
- ch->set_child_text(Driver::getCurrentValue(col));
- }
- }
- executeChildren(record);
-}
-
-template <class Driver>
-unsigned int
-_GenericView<Driver>:: columnCount() const
-{
- return Driver::columnCount();
-}
-
-template <class Driver>
-void
-_GenericView<Driver>:: loadComplete()
-{
- Driver::loadComplete();
-}
-
-template <class Driver>
-bool
-_GenericView<Driver>:: isNull(const unsigned int id) const
-{
- return Driver::isNull(id);
-}
-
-template <class Driver>
-const Glib::ustring &
-_GenericView<Driver>:: getCurrentValue(const unsigned int id) const
-{
- return Driver::getCurrentValue(id);
-}
-
-template <class Driver>
-const Glib::ustring &
-_GenericView<Driver>:: getCurrentValue(const Glib::ustring & id) const
-{
- return Driver::getCurrentValue(id);
-}
-
-template <class Driver>
-const Glib::ustring &
-_GenericView<Driver>:: getColumnName(const unsigned int id) const
-{
- return Driver::getColumnName(id);
-}
-
diff --git a/project2/xmlObjectLoader.cpp b/project2/xmlObjectLoader.cpp
index e789275..cfbf1a4 100644
--- a/project2/xmlObjectLoader.cpp
+++ b/project2/xmlObjectLoader.cpp
@@ -1,5 +1,5 @@
#include "xmlObjectLoader.h"
-#include <stdexcept>
+#include "exceptions.h"
#include <stdio.h>
unsigned int LoaderBase::depth = 0;
@@ -43,8 +43,11 @@ LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly) const
}
}
}
+ if (created < 1) {
+ throw NotSupported(name);
+ }
if (stored < created) {
- throw std::runtime_error("Unexpected object");
+ throw NotSupported(name);
}
}
if (created == 0 && (recursive || childrenOnly)) {
@@ -53,12 +56,19 @@ LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly) const
}
}
depth -= 1;
- if (depth == 0) {
- BOOST_FOREACH(Project2SourceObject o, loadedObjects) {
- o->loadComplete();
- }
- loadedObjects.clear();
+}
+
+void
+LoaderBase::collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly) const
+{
+ if (depth != 0) {
+ throw std::logic_error("Cannot set CommonObjects in subloader");
}
+ collectAll(node, childrenOnly);
+ BOOST_FOREACH(Project2SourceObject o, loadedObjects) {
+ o->loadComplete(co);
+ }
+ loadedObjects.clear();
}
void
@@ -72,6 +82,10 @@ LoaderBase::onIdle()
void
LoaderBase::onIteration()
{
+ // This is a fail safe in the event that something goes pearshape
+ depth = 0;
+ loadedObjects.clear();
+
BOOST_FOREACH(ElementLoaderMap::value_type l, getMap()) {
l.second->onIteration();
}
diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h
index 8b71561..5f79122 100644
--- a/project2/xmlObjectLoader.h
+++ b/project2/xmlObjectLoader.h
@@ -15,6 +15,7 @@
Glib::ustring xmlChildText(const xmlpp::Node * p, const Glib::ustring & n);
class ElementLoader;
+class CommonObjects;
class Storer : public virtual IntrusivePtrBase {
public:
@@ -87,6 +88,7 @@ class LoaderBase {
LoaderBase(const Glib::ustring & ns, bool recursive);
virtual ~LoaderBase();
+ void collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly) const;
void collectAll(const xmlpp::Element * node, bool childrenOnly) const;
static ElementLoaderMap & getMap();
diff --git a/project2/xmlRows.cpp b/project2/xmlRows.cpp
index 8ed912e..63a14cc 100644
--- a/project2/xmlRows.cpp
+++ b/project2/xmlRows.cpp
@@ -1,19 +1,19 @@
#include "xmlRows.h"
#include "xml.h"
+#include "exceptions.h"
#include <libxml++/nodes/textnode.h>
#include <libxml/xmlreader.h>
-#include <stdexcept>
#include "xmlObjectLoader.h"
-#include "appEngine.h"
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp>
-ElementLoaderImpl<_XmlIterate> xmliterateLoader("xmliterate");
-ElementLoaderImpl<_XmlView> xmlviewLoader("xmlview");
+ElementLoaderImpl<_XmlRows> xmlrowLoader("xmlrows");
_XmlRows::_XmlRows(const xmlpp::Element * p) :
+ _SourceObject(p),
+ PerRowValues(p),
recordRoot(p->get_attribute_value("recordroot")),
recordTrigger(p->get_attribute_value("recordtrigger")),
filename(p->get_attribute_value("filename")),
@@ -49,9 +49,15 @@ _XmlRows::~_XmlRows()
{
}
- void
-_XmlRows::loadComplete()
+void
+_XmlRows::loadComplete(const CommonObjects *)
+{
+}
+
+void
+_XmlRows::setFilter(const Glib::ustring &)
{
+ throw NotSupported(__PRETTY_FUNCTION__);
}
const Glib::ustring &
@@ -102,7 +108,7 @@ store(const _XmlRows::Path & position, _XmlRows::Values & values, const _XmlRows
}
void
-_XmlRows::execute() const
+_XmlRows::execute(const RowProcessor * rp) const
{
xmlTextReaderPtr reader = xmlReaderForFile(filename.c_str(), NULL, 0);
if (reader == NULL) {
@@ -129,7 +135,7 @@ _XmlRows::execute() const
}
if (empty) {
if (position == trigger) {
- rowReady();
+ rp->rowReady();
}
if (position == root) {
values.clear();
@@ -146,7 +152,7 @@ _XmlRows::execute() const
case XML_READER_TYPE_END_ELEMENT:
if (enableCapture) {
if (position == trigger) {
- rowReady();
+ rp->rowReady();
}
if (position == root) {
values.clear();
@@ -160,8 +166,3 @@ _XmlRows::execute() const
xmlCleanupParser();
}
-#include "view.hpp"
-template class _GenericView<_XmlRows>;
-#include "iterate.hpp"
-template class _GenericIterate<_XmlRows>;
-
diff --git a/project2/xmlRows.h b/project2/xmlRows.h
index 8b19e9a..05c127d 100644
--- a/project2/xmlRows.h
+++ b/project2/xmlRows.h
@@ -4,10 +4,7 @@
#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <map>
-#include "iterate.h"
-#include "view.h"
-
-class ApplicationEngine;
+#include "perRowValues.h"
class _XmlRows : public PerRowValues {
public:
@@ -18,14 +15,14 @@ class _XmlRows : public PerRowValues {
_XmlRows(const xmlpp::Element * p);
~_XmlRows();
- void execute() const;
- virtual void loadComplete();
+ void execute(const RowProcessor *) const;
+ virtual void loadComplete(const CommonObjects *);
+ virtual void setFilter(const Glib::ustring &);
unsigned int columnCount() const;
const Glib::ustring & getColumnName(unsigned int col) const;
const Glib::ustring & getCurrentValue(const Glib::ustring & id) const;
const Glib::ustring & getCurrentValue(unsigned int col) const;
bool isNull(unsigned int col) const;
- virtual void rowReady() const = 0;
const Glib::ustring recordRoot;
const Glib::ustring recordTrigger;
@@ -42,13 +39,5 @@ class _XmlRows : public PerRowValues {
};
typedef boost::intrusive_ptr<_XmlRows> XmlRows;
-typedef _GenericView<_XmlRows> _XmlView;
-typedef boost::intrusive_ptr<_XmlView> XmlView;
-typedef std::map<std::string, XmlView> XmlViews;
-
-typedef _GenericIterate<_XmlRows> _XmlIterate;
-typedef boost::intrusive_ptr<_XmlIterate> XmlIterate;
-typedef std::map<std::string, XmlIterate> XmlIterates;
-
#endif