summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-06-28 18:08:51 +0000
committerrandomdan <randomdan@localhost>2010-06-28 18:08:51 +0000
commit910b44e64023f707496a097b9b0b289b8bb061fd (patch)
tree06d007f68f0e5fa056907cb337795dbd3c3cccfc
parentUse cgicc, add checks, tasks, dynamic loader, atom feed, login page (diff)
downloadproject2-910b44e64023f707496a097b9b0b289b8bb061fd.tar.bz2
project2-910b44e64023f707496a097b9b0b289b8bb061fd.tar.xz
project2-910b44e64023f707496a097b9b0b289b8bb061fd.zip
Use FCgiIO C++ wrapper
Add iterates Change some inheritances Add a numeric load order loader Add support for sessions Add support for a SHM session backend Lots of other little changes
-rw-r--r--project2/FCgiIO.cpp63
-rw-r--r--project2/FCgiIO.h153
-rw-r--r--project2/Jamfile.jam2
-rw-r--r--project2/appEngine.h2
-rw-r--r--project2/cgiAppEngine.cpp56
-rw-r--r--project2/cgiAppEngine.h16
-rw-r--r--project2/dataSource.cpp4
-rw-r--r--project2/dataSource.h2
-rw-r--r--project2/iterate.cpp41
-rw-r--r--project2/iterate.h33
-rw-r--r--project2/noOutputExecute.h20
-rw-r--r--project2/p2webMain.cpp66
-rw-r--r--project2/paramChecker.cpp11
-rw-r--r--project2/paramChecker.h5
-rw-r--r--project2/perRowValues.h12
-rw-r--r--project2/rdbmsDataSource.cpp1
-rw-r--r--project2/regexCheck.cpp1
-rw-r--r--project2/session.cpp27
-rw-r--r--project2/session.h42
-rw-r--r--project2/sessionClearTask.cpp21
-rw-r--r--project2/sessionClearTask.h26
-rw-r--r--project2/sessionSetTask.cpp33
-rw-r--r--project2/sessionSetTask.h27
-rw-r--r--project2/sessionShm.cpp128
-rw-r--r--project2/sessionShm.h38
-rw-r--r--project2/sourceObject.cpp9
-rw-r--r--project2/sourceObject.h11
-rw-r--r--project2/sqlCheck.cpp1
-rw-r--r--project2/sqlIterate.cpp61
-rw-r--r--project2/sqlIterate.h29
-rw-r--r--project2/sqlTask.cpp3
-rw-r--r--project2/sqlTask.h2
-rw-r--r--project2/sqlView.cpp5
-rw-r--r--project2/task.cpp20
-rw-r--r--project2/task.h9
-rw-r--r--project2/view.cpp12
-rw-r--r--project2/view.h4
37 files changed, 910 insertions, 86 deletions
diff --git a/project2/FCgiIO.cpp b/project2/FCgiIO.cpp
new file mode 100644
index 0000000..7a3dd09
--- /dev/null
+++ b/project2/FCgiIO.cpp
@@ -0,0 +1,63 @@
+/*
+ * $Id: FCgiIO.cpp,v 1.6 2007/07/02 18:48:19 sebdiaz Exp $
+ *
+ * Copyright (C) 2002 Steve McAndrewSmith
+ * Copyright (C) 2002 - 2004 Stephen F. Booth
+ * 2007 Sebastien DIAZ <sebastien.diaz@gmail.com>
+ * Part of the GNU cgicc library, http://www.gnu.org/software/cgicc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ */
+
+#ifdef __GNUG__
+# pragma implementation
+#endif
+
+#include <iostream>
+#include <stdexcept>
+#include <cstdlib>
+
+#include "FCgiIO.h"
+
+cgicc::FCgiIO::FCgiIO(FCGX_Request& request)
+ : std::ostream(&fOutBuf),
+ fRequest(request),
+ fOutBuf(request.out),
+ fErrBuf(request.err),
+ fErr(&fErrBuf)
+{
+ rdbuf(&fOutBuf);
+ fErr.rdbuf(&fErrBuf);
+
+ // Parse environment
+ for(char **e = fRequest.envp; *e != NULL; ++e) {
+ std::string s(*e);
+ std::string::size_type i = s.find('=');
+ if(i == std::string::npos)
+ throw std::runtime_error("Illegally formed environment");
+ fEnv[s.substr(0, i)] = s.substr(i + 1);
+ }
+}
+
+cgicc::FCgiIO::FCgiIO(const FCgiIO& io)
+ : CgiInput(io),
+ std::ostream(&fOutBuf),
+ fRequest(io.fRequest),
+ fErr(&fErrBuf),
+ fEnv(io.fEnv)
+{
+ rdbuf(&fOutBuf);
+ fErr.rdbuf(&fErrBuf);
+}
diff --git a/project2/FCgiIO.h b/project2/FCgiIO.h
new file mode 100644
index 0000000..a8b67f3
--- /dev/null
+++ b/project2/FCgiIO.h
@@ -0,0 +1,153 @@
+/* -*-c++-*- */
+/*
+ * $Id: FCgiIO.h,v 1.3 2007/07/02 18:48:19 sebdiaz Exp $
+ *
+ * Copyright (C) 2002 Steve McAndrewSmith
+ * Copyright (C) 2002 Stephen F. Booth
+ * 2007 Sebastien DIAZ <sebastien.diaz@gmail.com>
+ * Part of the GNU cgicc library, http://www.gnu.org/software/cgicc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA*
+ */
+
+#ifndef _FCGIIO_H_
+#define _FCGIIO_H_ 1
+
+#ifdef __GNUG__
+# pragma interface
+#endif
+
+/*! \file FCgiIO.h
+ * \brief Class that implements input and output through a FastCGI request.
+ *
+ * This class provides access to the input byte-stream and environment
+ * variable interfaces of a FastCGI request. It is fully compatible with the
+ * Cgicc input API.
+ *
+ * It also provides access to the request's output and error streams, using a
+ * similar interface.
+ */
+
+#include <ostream>
+#include <string>
+#include <map>
+
+#include "fcgio.h"
+
+#include "cgicc/CgiInput.h"
+
+namespace cgicc {
+
+ // ============================================================
+ // Class FCgiIO
+ // ============================================================
+
+ /*! \class FCgiIO FCgiIO.h FCgiIO.h
+ * \brief Class that implements input and output through a FastCGI request.
+ *
+ * This class provides access to the input byte-stream and environment
+ * variable interfaces of a FastCGI request. It is fully compatible with the
+ * Cgicc input API.
+ *
+ * It also provides access to the request's output and error streams, using a
+ * similar interface.
+ */
+ class CGICC_API FCgiIO : public cgicc::CgiInput, public std::ostream
+ {
+ public:
+
+ // ============================================================
+
+ /*! \name Constructor and Destructor */
+ //@{
+
+ /*!
+ * \brief Constructor
+ *
+ * Create a new FCgiIO object
+ */
+ FCgiIO(FCGX_Request& request);
+
+ /*!
+ * \brief Copy constructor
+ *
+ */
+ FCgiIO(const FCgiIO& io);
+
+ /*!
+ * \brief Destructor
+ *
+ * Delete this FCgiIO object
+ */
+ virtual inline
+ ~FCgiIO()
+ {}
+ //@}
+
+ // ============================================================
+
+ /*! \name Data Sources */
+ //@{
+
+ /*!
+ * \brief Read data from the request's input stream.
+ *
+ * \param data The target buffer
+ * \param length The number of characters to read
+ * \return The number of characters read
+ */
+ virtual inline size_t read(char *data, size_t length)
+ {
+ return FCGX_GetStr(data, length, fRequest.in);
+ }
+
+ /*!
+ * \brief Query the value of an environment variable stored in the request.
+ *
+ * \param varName The name of an environment variable
+ * \return The value of the requested environment variable, or an empty
+ * string if not found.
+ */
+ virtual inline std::string getenv(const char *varName)
+ {
+ return fEnv[varName];
+ }
+ //@}
+
+ // ============================================================
+
+ /*! \name Data Target Streams */
+ //@{
+
+ /*!
+ * \brief Provides access to the error stream.
+ */
+ inline std::ostream& err(void)
+ {
+ return fErr;
+ }
+ //@}
+
+ protected:
+ FCGX_Request& fRequest;
+ fcgi_streambuf fOutBuf;
+ fcgi_streambuf fErrBuf;
+ std::ostream fErr;
+ std::map<std::string, std::string> fEnv;
+ };
+
+} // namespace cgicc
+
+#endif /* ! _FCGIIO_H_ */
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam
index a8cf8ae..4fdd54c 100644
--- a/project2/Jamfile.jam
+++ b/project2/Jamfile.jam
@@ -5,6 +5,7 @@ alias libxmlpp : : : :
<linkflags>"`pkg-config --libs libxml++-2.6`" ;
lib fcgi : : <name>fcgi ;
+lib fcgi++ : : <name>fcgi++ ;
lib odbc : : <name>odbc ;
lib boost_regex : : <name>boost_regex ;
lib cgicc : : <name>cgicc ;
@@ -19,4 +20,5 @@ exe p2web :
<library>boost_regex
<library>odbc
<library>cgicc
+ <library>fcgi++
<library>fcgi ;
diff --git a/project2/appEngine.h b/project2/appEngine.h
index cffd44e..d2cff10 100644
--- a/project2/appEngine.h
+++ b/project2/appEngine.h
@@ -14,6 +14,8 @@ class ApplicationEngine {
virtual void process() const = 0;
virtual const Environment * env() const = 0;
+ virtual void SessionSet(const Glib::ustring & name, const Glib::ustring & value) const = 0;
+ virtual void SessionClear(const Glib::ustring & name) const = 0;
template <class DataSourceType>
const DataSourceType * dataSource(const std::string & name) const
diff --git a/project2/cgiAppEngine.cpp b/project2/cgiAppEngine.cpp
index 860ce51..f1c38d7 100644
--- a/project2/cgiAppEngine.cpp
+++ b/project2/cgiAppEngine.cpp
@@ -1,17 +1,36 @@
#include "cgiAppEngine.h"
#include <syslog.h>
#include <cgicc/Cgicc.h>
+#include <cgicc/HTTPContentHeader.h>
+#include "cgiEnvironment.h"
#include <libxml++/parsers/domparser.h>
#include <libxml/xinclude.h>
#include "xmlObjectLoader.h"
#include "rdbmsDataSource.h"
+#include "iterate.h"
#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include "sessionShm.h"
+#include <boost/uuid/uuid_generators.hpp>
+const std::string SESSIONID = "sessionID";
+typedef boost::uuids::uuid SIDKey;
+typedef std::string SValue;
-CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e) :
+SessionContainer * sessionsContainer = new SessionContainerShm();
+
+CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e, cgicc::HTTPContentHeader * h) :
ApplicationEngine(e),
- _env(e)
+ _env(e),
+ header(h),
+ sessionID(boost::uuids::nil_generator()())
{
+ BOOST_FOREACH(const cgicc::HTTPCookie c, e->getCookieList()) {
+ if (c.getName() == SESSIONID) {
+ sessionID = boost::uuids::string_generator()(c.getValue());
+ }
+ }
if (_env->getRequestMethod() == "POST") {
currentStage = new RequestStage(this, e->elems[0]);
}
@@ -38,6 +57,10 @@ CgiApplicationEngine::process() const
currentStage = currentStage->run();
delete prev;
}
+ if (!sessionID.is_nil()) {
+ header->setCookie(cgicc::HTTPCookie(SESSIONID, boost::lexical_cast<std::string>(sessionID), "Session ID",
+ _env->getServerName().substr(_env->getServerName().find(".")), 3600, "/", false));
+ }
}
CgiApplicationEngine::Stage::Stage(const CgiApplicationEngine * e) : appEngine(e)
@@ -94,6 +117,19 @@ CgiApplicationEngine::PresentStage::run()
param->add_child_text(fe.getValue());
param->set_attribute("name", fe.getName());
}
+ // 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));
+ syslog(LOG_DEBUG, "> var dump");
+ Session::Values session(sessionsContainer->GetSession(appEngine->sessionID)->GetValuesCopy());
+ //BOOST_FOREACH(SessionShm::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);
+ //}
+ syslog(LOG_DEBUG, "< var dump");
+ }
// XSLT Style
char * buf;
if (asprintf(&buf, "type=\"text/xsl\" href=\"%s\"",
@@ -103,6 +139,7 @@ CgiApplicationEngine::PresentStage::run()
}
free(buf);
appEngine->doc = responseDoc;
+ sessionsContainer->CleanUp();
return NULL;
}
@@ -117,6 +154,7 @@ CgiApplicationEngine::RequestStage::RequestStage(const CgiApplicationEngine * e,
_DataSource::AddLoaders(loaders, appEngine->datasources);
_ParamChecker::AddLoaders(loaders, parameterChecks);
_Task::AddLoaders(loaders, tasks);
+ _Iterate::AddLoaders(loaders, tasks);
_LoaderBase::collectAll(loaders, "project2", requestRoot, true, true);
}
CgiApplicationEngine::RequestStage::~RequestStage()
@@ -130,9 +168,8 @@ CgiApplicationEngine::RequestStage::run()
return new PresentStage(appEngine, pc.second->present);
}
}
- syslog(LOG_DEBUG, "Checks passed");
try {
- BOOST_FOREACH(OrderedTasks::value_type t, tasks) {
+ BOOST_FOREACH(NoOutputExecutes::value_type t, tasks) {
t.second->execute(appEngine);
}
// Commit data source transactions (without invoking a connection)
@@ -150,3 +187,14 @@ CgiApplicationEngine::RequestStage::run()
return new PresentStage(appEngine, present);
}
+void
+CgiApplicationEngine::SessionSet(const Glib::ustring & name, const Glib::ustring & value) const
+{
+ sessionsContainer->GetSession(sessionID)->SetValue(name, value);
+}
+void
+CgiApplicationEngine::SessionClear(const Glib::ustring & name) const
+{
+ sessionsContainer->GetSession(sessionID)->ClearValue(name);
+}
+
diff --git a/project2/cgiAppEngine.h b/project2/cgiAppEngine.h
index 80707a0..9532ed4 100644
--- a/project2/cgiAppEngine.h
+++ b/project2/cgiAppEngine.h
@@ -2,15 +2,20 @@
#define CGIAPPENGINE_H
#include "appEngine.h"
-#include "cgiEnvironment.h"
#include "task.h"
#include "paramChecker.h"
#include <boost/shared_ptr.hpp>
+#include <boost/uuid/uuid.hpp>
#include <libxml++/document.h>
+class CgiEnvironment;
+namespace cgicc {
+ class HTTPContentHeader;
+}
+
class CgiApplicationEngine : public ApplicationEngine {
public:
- CgiApplicationEngine(const CgiEnvironment *);
+ CgiApplicationEngine(const CgiEnvironment *, cgicc::HTTPContentHeader *);
virtual ~CgiApplicationEngine();
void process() const;
@@ -20,7 +25,11 @@ class CgiApplicationEngine : public ApplicationEngine {
w(doc->cobj());
}
const Environment * env() const;
+ virtual void SessionSet(const Glib::ustring & name, const Glib::ustring & value) const;
+ virtual void SessionClear(const Glib::ustring & name) const;
const CgiEnvironment * _env;
+ protected:
+ cgicc::HTTPContentHeader * header;
private:
mutable boost::shared_ptr<xmlpp::Document> doc;
class Stage {
@@ -39,7 +48,7 @@ class CgiApplicationEngine : public ApplicationEngine {
virtual Stage * run();
std::string present;
protected:
- OrderedTasks tasks;
+ NoOutputExecutes tasks;
};
class PresentStage : public Stage {
public:
@@ -52,6 +61,7 @@ class CgiApplicationEngine : public ApplicationEngine {
Glib::ustring responseStyle;
};
mutable Stage * currentStage;
+ mutable boost::uuids::uuid sessionID;
};
#endif
diff --git a/project2/dataSource.cpp b/project2/dataSource.cpp
index 984ea53..9b6bd18 100644
--- a/project2/dataSource.cpp
+++ b/project2/dataSource.cpp
@@ -4,7 +4,7 @@
#include "rdbmsDataSource.h"
_DataSource::_DataSource(const xmlpp::Element * p) :
- _Project2SourceObject(p)
+ _SourceObject(p)
{
}
@@ -15,5 +15,5 @@ _DataSource::~_DataSource()
void
_DataSource::AddLoaders(Loaders & l, DataSources & dss)
{
- l.insert(LoadersVT("rdbmsdatasource", _LoaderBase::Make<_RdbmsDataSource, _DataSource, std::string, _Project2SourceObject, &_Project2SourceObject::name>(&dss)));
+ l.insert(LoadersVT("rdbmsdatasource", _LoaderBase::Make<_RdbmsDataSource, _DataSource, std::string, _SourceObject, &_SourceObject::name>(&dss)));
}
diff --git a/project2/dataSource.h b/project2/dataSource.h
index 9d30d07..0cc0124 100644
--- a/project2/dataSource.h
+++ b/project2/dataSource.h
@@ -11,7 +11,7 @@ class _DataSource;
typedef boost::shared_ptr<_DataSource> DataSource;
typedef std::map<std::string, DataSource> DataSources;
-class _DataSource : public _Project2SourceObject {
+class _DataSource : public virtual _SourceObject {
public:
_DataSource(const xmlpp::Element * p);
virtual ~_DataSource();
diff --git a/project2/iterate.cpp b/project2/iterate.cpp
new file mode 100644
index 0000000..02fc149
--- /dev/null
+++ b/project2/iterate.cpp
@@ -0,0 +1,41 @@
+#include "iterate.h"
+#include <boost/foreach.hpp>
+#include <syslog.h>
+#include "xmlObjectLoader.h"
+#include "sqlIterate.h"
+#include "task.h"
+
+_Iterate::_Iterate(const xmlpp::Element * p) :
+ _SourceObject(p),
+ _NoOutputExecute(p)
+{
+ Loaders loaders;
+ _Iterate::AddLoaders(loaders, subIterates);
+ _Task::AddLoaders(loaders, subIterates);
+ _LoaderBase::collectAll(loaders, "project2", p, true, true);
+}
+
+_Iterate::~_Iterate()
+{
+}
+
+void
+_Iterate::AddLoaders(Loaders & l, Iterates & iterates)
+{
+ l.insert(LoadersVT("sqliterate", _LoaderBase::Make<_SqlIterate, _Iterate, std::string, _SourceObject, &_SourceObject::name>(&iterates)));
+}
+
+void
+_Iterate::AddLoaders(Loaders & l, NoOutputExecutes & iterates)
+{
+ l.insert(LoadersVT("sqliterate", _LoaderBase::Make<_SqlIterate, _NoOutputExecute, unsigned int, _SourceObject, &_SourceObject::order>(&iterates)));
+}
+
+void
+_Iterate::executeChildren(const ApplicationEngine * ep, const PerRowValues * parent) const
+{
+ BOOST_FOREACH(NoOutputExecutes::value_type sq, subIterates) {
+ sq.second->execute(ep, this);
+ }
+}
+
diff --git a/project2/iterate.h b/project2/iterate.h
new file mode 100644
index 0000000..c113585
--- /dev/null
+++ b/project2/iterate.h
@@ -0,0 +1,33 @@
+#ifndef ITERATE_H
+#define ITERATE_H
+
+#include <libxml++/nodes/element.h>
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include "sourceObject.h"
+#include "xmlObjectLoader.h"
+#include "perRowValues.h"
+#include "noOutputExecute.h"
+
+class ApplicationEngine;
+class _Iterate;
+typedef boost::shared_ptr<_Iterate> Iterate;
+typedef std::map<std::string, Iterate> Iterates;
+
+class _Iterate : public virtual _SourceObject, public PerRowValues, public _NoOutputExecute {
+ public:
+ _Iterate(const xmlpp::Element * p);
+ virtual ~_Iterate();
+ virtual void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const = 0;
+ virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const = 0;
+
+ static void AddLoaders(Loaders & l, Iterates & vs);
+ static void AddLoaders(Loaders & l, NoOutputExecutes & vs);
+ protected:
+ void executeChildren(const ApplicationEngine *, const PerRowValues * parent = NULL) const;
+ NoOutputExecutes subIterates;
+};
+
+#endif
+
+
diff --git a/project2/noOutputExecute.h b/project2/noOutputExecute.h
new file mode 100644
index 0000000..ad5df92
--- /dev/null
+++ b/project2/noOutputExecute.h
@@ -0,0 +1,20 @@
+#ifndef NOOUTPUTEXECUTE_H
+#define NOOUTPUTEXECUTE_H
+
+#include "sourceObject.h"
+
+class ApplicationEngine;
+class PerRowValues;
+
+class _NoOutputExecute;
+typedef boost::shared_ptr<_NoOutputExecute> NoOutputExecute;
+typedef std::map<unsigned int, NoOutputExecute> NoOutputExecutes;
+
+class _NoOutputExecute : public virtual _SourceObject {
+ public:
+ _NoOutputExecute(const xmlpp::Element * p) : _SourceObject(p) { };
+ virtual ~_NoOutputExecute() { }
+ virtual void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const = 0;
+};
+#endif
+
diff --git a/project2/p2webMain.cpp b/project2/p2webMain.cpp
index 1eafd2d..f424e0a 100644
--- a/project2/p2webMain.cpp
+++ b/project2/p2webMain.cpp
@@ -1,76 +1,62 @@
#include <libxml/tree.h>
#include <cgicc/Cgicc.h>
#include <cgicc/CgiEnvironment.h>
+#include <cgicc/HTTPContentHeader.h>
+FILE * realstdout = stdout;
#include <fcgi_stdio.h>
#include "cgiEnvironment.h"
#include "cgiAppEngine.h"
#include <boost/bind.hpp>
+#include "FCgiIO.h"
int
xmlWrite(void * _out, const char * buf, int len)
{
- return FCGX_PutStr(buf, len, (FCGX_Stream*)_out);
+ cgicc::FCgiIO & IO = *((cgicc::FCgiIO*)_out);
+ IO.write(buf, len);
+ return len;
}
-class CgiReader : public cgicc::CgiInput {
- public:
- CgiReader(FCGX_Stream * i, FCGX_ParamArray & e) :
- in(i),
- envp(e)
- {
- }
- ~CgiReader() { }
-
- size_t read(char * data, size_t length)
- {
- return FCGX_GetStr(data, length, in);
- }
- std::string getenv(const char * env)
- {
- const char * e = FCGX_GetParam(env, envp);
- return e ? e : "";
- }
- private:
- FCGX_Stream *in;
- FCGX_ParamArray envp;
-};
int main(void)
{
if (!FCGX_IsCGI()) {
- FCGX_Stream *in, *_out, *err;
- FCGX_ParamArray envp;
+ FCGX_Request request;
+
+ FCGX_Init();
+ FCGX_InitRequest(&request, 0, 0);
- while (FCGX_Accept(&in, &_out, &err, &envp) >= 0)
- {
- CgiReader reader(in, envp);
- cgicc::Cgicc cgi(&reader);
+ while (FCGX_Accept_r(&request) == 0) {
+ cgicc::FCgiIO IO(request);
try {
+ cgicc::Cgicc cgi(&IO);
CgiEnvironment env(&cgi);
- CgiApplicationEngine app(&env);
+ cgicc::HTTPContentHeader header("text/xml-xslt");
+ CgiApplicationEngine app(&env, &header);
app.process();
- FCGX_FPrintF(_out, "Content-type: text/xml-xslt\r\n\r\n");
+ header.render(IO);
xmlOutputBufferPtr out = xmlOutputBufferCreateIO(
- xmlWrite, NULL, _out, xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8));
+ xmlWrite, NULL, &IO, xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8));
app.write(boost::bind(xmlSaveFileTo, out, _1, "utf-8"));
}
catch (const std::exception & e) {
- FCGX_FPrintF(_out, "Content-type: text/plain\r\n\r\n");
- FCGX_FPrintF(_out, "Kaboom!\r\n\r\n");
- FCGX_FPrintF(_out, "%s\r\n\r\n", e.what());
+ cgicc::HTTPContentHeader header("text/plain");
+ header.render(IO);
+ IO << "Kaboom!" << std::endl << std::endl << e.what();
}
catch (...) {
- FCGX_FPrintF(_out, "Content-type: text/plain\r\n\r\n");
- FCGX_FPrintF(_out, "Kaboom!\r\n\r\n");
- FCGX_FPrintF(_out, "Unknown exception.\r\n\r\n");
+ cgicc::HTTPContentHeader header("text/plain");
+ header.render(IO);
+ IO << "Kaboom!" << std::endl << std::endl << "Unknown exception.";
}
}
}
else {
cgicc::Cgicc cgi(NULL);
CgiEnvironment env(&cgi);
- CgiApplicationEngine app(&env);
+ cgicc::HTTPContentHeader header("text/xml-xslt");
+ CgiApplicationEngine app(&env, &header);
app.process();
- //app.write(boost::bind(xmlDocDump, stdout, _1));
+ app.write(boost::bind(xmlDocDump, realstdout, _1));
}
return 0;
}
diff --git a/project2/paramChecker.cpp b/project2/paramChecker.cpp
index 697728a..627f1be 100644
--- a/project2/paramChecker.cpp
+++ b/project2/paramChecker.cpp
@@ -4,14 +4,11 @@
#include "regexCheck.h"
#include "sqlCheck.h"
-unsigned int _ParamChecker::loadOrder = 1;
-
_ParamChecker::_ParamChecker(const xmlpp::Element * p) :
- _Project2SourceObject(p),
+ _SourceObject(p),
message(xmlChildText(p, "message")),
applyTo(p->get_attribute_value("apply-to")),
- present(p->get_attribute_value("present")),
- order(loadOrder++)
+ present(p->get_attribute_value("present"))
{
}
@@ -22,7 +19,7 @@ _ParamChecker::~_ParamChecker()
void
_ParamChecker::AddLoaders(Loaders & l, OrderedParamCheckers & checks)
{
- l.insert(LoadersVT("regexcheck", _LoaderBase::Make<_RegexCheck, _ParamChecker, unsigned int, _ParamChecker, &_ParamChecker::order>(&checks)));
- l.insert(LoadersVT("sqlcheck", _LoaderBase::Make<_SqlCheck, _ParamChecker, unsigned int, _ParamChecker, &_ParamChecker::order>(&checks)));
+ l.insert(LoadersVT("regexcheck", _LoaderBase::Make<_RegexCheck, _ParamChecker, unsigned int, _SourceObject, &_SourceObject::order>(&checks)));
+ l.insert(LoadersVT("sqlcheck", _LoaderBase::Make<_SqlCheck, _ParamChecker, unsigned int, _SourceObject, &_SourceObject::order>(&checks)));
}
diff --git a/project2/paramChecker.h b/project2/paramChecker.h
index 28c0275..1ffe89f 100644
--- a/project2/paramChecker.h
+++ b/project2/paramChecker.h
@@ -13,7 +13,7 @@ typedef boost::shared_ptr<_ParamChecker> ParamChecker;
typedef std::map<std::string, ParamChecker> ParamCheckers;
typedef std::map<unsigned int, ParamChecker> OrderedParamCheckers;
-class _ParamChecker : public _Project2SourceObject {
+class _ParamChecker : public virtual _SourceObject {
public:
_ParamChecker(const xmlpp::Element * p);
virtual ~_ParamChecker();
@@ -23,11 +23,8 @@ class _ParamChecker : public _Project2SourceObject {
const Glib::ustring message;
const std::string applyTo;
const std::string present;
- const unsigned int order;
static void AddLoaders(Loaders & l, OrderedParamCheckers & vs);
- private:
- static unsigned int loadOrder;
};
#endif
diff --git a/project2/perRowValues.h b/project2/perRowValues.h
new file mode 100644
index 0000000..2a46763
--- /dev/null
+++ b/project2/perRowValues.h
@@ -0,0 +1,12 @@
+#ifndef PERROWVALUES_H
+#define PERROWVALUES_H
+
+#include <glibmm/ustring.h>
+
+class PerRowValues {
+ public:
+ virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const = 0;
+};
+
+#endif
+
diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp
index dad35a3..1a55fb8 100644
--- a/project2/rdbmsDataSource.cpp
+++ b/project2/rdbmsDataSource.cpp
@@ -3,6 +3,7 @@
#include <libxml++/nodes/textnode.h>
_RdbmsDataSource::_RdbmsDataSource(const xmlpp::Element * p) :
+ _SourceObject(p),
_DataSource(p),
masterDsn(xmlChildText(p, "masterdsn"))
{
diff --git a/project2/regexCheck.cpp b/project2/regexCheck.cpp
index abe134c..672194f 100644
--- a/project2/regexCheck.cpp
+++ b/project2/regexCheck.cpp
@@ -4,6 +4,7 @@
#include <boost/regex.hpp>
_RegexCheck::_RegexCheck(const xmlpp::Element * p) :
+ _SourceObject(p),
_ParamChecker(p),
regex(xmlChildText(p, "regex").raw())
{
diff --git a/project2/session.cpp b/project2/session.cpp
new file mode 100644
index 0000000..87bea0c
--- /dev/null
+++ b/project2/session.cpp
@@ -0,0 +1,27 @@
+#include "session.h"
+#include <syslog.h>
+
+Session::Session()
+{
+}
+
+Session::~Session()
+{
+}
+
+SessionContainer::SessionContainer()
+{
+}
+
+SessionContainer::~SessionContainer()
+{
+}
+
+SessionPtr
+SessionContainer::GetSession(boost::uuids::uuid & id)
+{
+ SessionPtr s = getSession(id);
+ s->ExpiryTime(time(NULL) + 3600);
+ return s;
+}
+
diff --git a/project2/session.h b/project2/session.h
new file mode 100644
index 0000000..de31626
--- /dev/null
+++ b/project2/session.h
@@ -0,0 +1,42 @@
+#ifndef SESSION_H
+#define SESSION_H
+
+#include <map>
+#include <glibmm/ustring.h>
+#include <boost/uuid/uuid.hpp>
+#include <boost/shared_ptr.hpp>
+
+class Session {
+ public:
+ typedef std::map<Glib::ustring, Glib::ustring> Values;
+
+ Session();
+ virtual ~Session() = 0;
+
+ virtual Glib::ustring GetValue(const Glib::ustring & name) const = 0;
+ virtual Values GetValuesCopy() const = 0;
+ virtual void SetValue(const Glib::ustring & name, const Glib::ustring & value) = 0;
+ virtual void ClearValue(const Glib::ustring & name) = 0;
+ virtual time_t ExpiryTime() const = 0;
+
+ protected:
+ virtual void ExpiryTime(time_t) = 0;
+ friend class SessionContainer;
+};
+typedef boost::shared_ptr<Session> SessionPtr;
+
+class SessionContainer {
+ public:
+ SessionContainer();
+ virtual ~SessionContainer() = 0;
+
+ SessionPtr GetSession(boost::uuids::uuid & sid);
+ virtual void CleanUp() { }
+
+ protected:
+ virtual SessionPtr getSession(boost::uuids::uuid & sid) = 0;
+};
+
+
+#endif
+
diff --git a/project2/sessionClearTask.cpp b/project2/sessionClearTask.cpp
new file mode 100644
index 0000000..c5d6d0d
--- /dev/null
+++ b/project2/sessionClearTask.cpp
@@ -0,0 +1,21 @@
+#include <boost/foreach.hpp>
+#include "xmlObjectLoader.h"
+#include "sessionClearTask.h"
+#include "appEngine.h"
+
+_SessionClearTask::_SessionClearTask(const xmlpp::Element * p) :
+ _SourceObject(p),
+ _Task(p)
+{
+}
+
+_SessionClearTask::~_SessionClearTask()
+{
+}
+
+void
+_SessionClearTask::execute(const ApplicationEngine * ep, const PerRowValues *) const
+{
+ ep->SessionClear(key);
+}
+
diff --git a/project2/sessionClearTask.h b/project2/sessionClearTask.h
new file mode 100644
index 0000000..f3b779b
--- /dev/null
+++ b/project2/sessionClearTask.h
@@ -0,0 +1,26 @@
+#ifndef SESSIONCLEARTASK_H
+#define SESSIONCLEARTASK_H
+
+#include <libxml++/nodes/element.h>
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include "sourceObject.h"
+#include "xmlObjectLoader.h"
+#include "task.h"
+
+class ApplicationEngine;
+class _SessionClearTask;
+typedef boost::shared_ptr<_SessionClearTask> SessionClearTask;
+
+class _SessionClearTask : public virtual _Task {
+ public:
+ _SessionClearTask(const xmlpp::Element * p);
+ virtual ~_SessionClearTask();
+ void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const;
+
+ const Glib::ustring key;
+};
+
+#endif
+
+
diff --git a/project2/sessionSetTask.cpp b/project2/sessionSetTask.cpp
new file mode 100644
index 0000000..abd02b0
--- /dev/null
+++ b/project2/sessionSetTask.cpp
@@ -0,0 +1,33 @@
+#include <syslog.h>
+#include <boost/foreach.hpp>
+#include "xmlObjectLoader.h"
+#include "sessionSetTask.h"
+#include "appEngine.h"
+
+_SessionSetTask::_SessionSetTask(const xmlpp::Element * p) :
+ _SourceObject(p),
+ _Task(p),
+ IHaveParameters(p),
+ key(p->get_attribute_value("key"))
+{
+}
+
+_SessionSetTask::~_SessionSetTask()
+{
+}
+
+void
+_SessionSetTask::execute(const ApplicationEngine * ep, const PerRowValues * parent) const
+{
+ Parameter p = parameters.find(0)->second;
+ if (p->source == "uri") {
+ ep->SessionSet(key, ep->env()->getParamUri(p->id));
+ }
+ else if (p->source == "parent") {
+ ep->SessionSet(key, parent->getCurrentValue(p->id));
+ }
+ else if (p->source == "query") {
+ ep->SessionSet(key, ep->env()->getParamQuery(p->id));
+ }
+}
+
diff --git a/project2/sessionSetTask.h b/project2/sessionSetTask.h
new file mode 100644
index 0000000..32df37b
--- /dev/null
+++ b/project2/sessionSetTask.h
@@ -0,0 +1,27 @@
+#ifndef SESSIONSETTASK_H
+#define SESSIONSETTASK_H
+
+#include <libxml++/nodes/element.h>
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include "sourceObject.h"
+#include "xmlObjectLoader.h"
+#include "task.h"
+#include "iHaveParameters.h"
+
+class ApplicationEngine;
+class _SessionSetTask;
+typedef boost::shared_ptr<_SessionSetTask> SessionSetTask;
+
+class _SessionSetTask : public virtual _Task, public IHaveParameters {
+ public:
+ _SessionSetTask(const xmlpp::Element * p);
+ virtual ~_SessionSetTask();
+ void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const;
+
+ const Glib::ustring key;
+};
+
+#endif
+
+
diff --git a/project2/sessionShm.cpp b/project2/sessionShm.cpp
new file mode 100644
index 0000000..c9f748c
--- /dev/null
+++ b/project2/sessionShm.cpp
@@ -0,0 +1,128 @@
+#include "sessionShm.h"
+#include <syslog.h>
+#include <set>
+#include <boost/uuid/uuid.hpp>
+#include <boost/foreach.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/uuid/uuid_io.hpp>
+
+using namespace boost::interprocess;
+using namespace boost::uuids;
+class SessionShmData {
+ public:
+ typedef boost::interprocess::string SKey;
+ typedef boost::interprocess::string SValue;
+
+ typedef std::pair<const SKey, SValue> SValueType;
+ typedef boost::interprocess::allocator<SValueType, boost::interprocess::managed_mapped_file::segment_manager> AllocatorValueType;
+ typedef boost::interprocess::map<SKey, SValue, std::less<SKey>, AllocatorValueType> SessionValues;
+
+ SessionShmData();
+ ~SessionShmData();
+
+ SessionValues svs;
+ time_t expiryTime;
+
+ static boost::interprocess::managed_mapped_file shm;
+ friend class SessionContainerShm;
+};
+
+const char * shmFile = "/tmp/project2.sessions";
+
+boost::interprocess::managed_mapped_file SessionShmData::shm(open_or_create, shmFile, 1024 * 1024);
+
+SessionContainerShm::SessionContainerShm()
+{
+}
+
+SessionContainerShm::~SessionContainerShm()
+{
+}
+
+void
+SessionContainerShm::CleanUp()
+{
+ std::set<std::string> toDelete;
+ for (managed_mapped_file::const_named_iterator i = SessionShmData::shm.named_begin();
+ i != SessionShmData::shm.named_end(); i++) {
+ const SessionShmData * s = static_cast<const SessionShmData *>(i->value());
+ if (s) {
+ if (s->expiryTime < time(NULL)) {
+ toDelete.insert(i->name());
+ }
+ }
+ }
+ for(std::set<std::string>::const_iterator s = toDelete.begin(); s != toDelete.end(); s++) {
+ SessionShmData::shm.destroy<const SessionShmData>(s->c_str());
+ }
+}
+
+SessionPtr
+SessionContainerShm::getSession(boost::uuids::uuid & sid)
+{
+ if (sid.is_nil()) {
+ sid = boost::uuids::random_generator()();
+ }
+ return SessionPtr(new SessionShm(
+ SessionShmData::shm.find_or_construct<SessionShmData>(boost::lexical_cast<std::string>(sid).c_str())()));
+}
+
+SessionShm::SessionShm(SessionShmData * d) : data(d)
+{
+}
+
+SessionShm::~SessionShm()
+{
+}
+
+void
+SessionShm::ExpiryTime(time_t t)
+{
+ data->expiryTime = t;
+}
+
+time_t
+SessionShm::ExpiryTime() const
+{
+ return data->expiryTime;
+}
+
+SessionShmData::SessionShmData() :
+ svs(std::less<SKey>(), AllocatorValueType(shm.get_segment_manager()))
+{
+}
+
+SessionShmData::~SessionShmData()
+{
+}
+
+Glib::ustring
+SessionShm::GetValue(const Glib::ustring & name) const
+{
+ return data->svs.find(name.c_str())->second.c_str();
+}
+
+void
+SessionShm::SetValue(const Glib::ustring & name, const Glib::ustring & value)
+{
+ data->svs.erase(name.c_str());
+ data->svs.insert(std::pair<SessionShmData::SKey, SessionShmData::SValue>(name.c_str(), value.c_str()));
+}
+
+void
+SessionShm::ClearValue(const Glib::ustring & name)
+{
+ data->svs.erase(name.c_str());
+}
+
+Session::Values
+SessionShm::GetValuesCopy() const
+{
+ Values v;
+ BOOST_FOREACH(SessionShmData::SessionValues::value_type kvp, data->svs) {
+ v[kvp.first.c_str()] = kvp.second.c_str();
+ }
+ return v;
+}
+
diff --git a/project2/sessionShm.h b/project2/sessionShm.h
new file mode 100644
index 0000000..2794303
--- /dev/null
+++ b/project2/sessionShm.h
@@ -0,0 +1,38 @@
+#ifndef SESSIONSHM_H
+#define SESSIONSHM_H
+
+#include "session.h"
+#include <boost/interprocess/containers/string.hpp>
+#include <boost/interprocess/managed_mapped_file.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/map.hpp>
+
+class SessionShmData;
+class SessionShm : public Session {
+ public:
+ SessionShm(SessionShmData *);
+ virtual ~SessionShm();
+
+ Glib::ustring GetValue(const Glib::ustring & name) const;
+ Values GetValuesCopy() const;
+ void SetValue(const Glib::ustring & name, const Glib::ustring & value);
+ void ClearValue(const Glib::ustring & name);
+ time_t ExpiryTime() const;
+ void ExpiryTime(time_t);
+
+ private:
+ SessionShmData * data;
+};
+
+class SessionContainerShm : public SessionContainer {
+ public:
+ SessionContainerShm();
+ ~SessionContainerShm();
+
+ void CleanUp();
+
+ protected:
+ SessionPtr getSession(boost::uuids::uuid & sid);
+};
+
+#endif
diff --git a/project2/sourceObject.cpp b/project2/sourceObject.cpp
index 9d10f52..bb989b5 100644
--- a/project2/sourceObject.cpp
+++ b/project2/sourceObject.cpp
@@ -1,11 +1,14 @@
#include "sourceObject.h"
-_Project2SourceObject::_Project2SourceObject(const xmlpp::Element * p) :
- name(p->get_attribute_value("name"))
+unsigned int _SourceObject::loadOrder = 1;
+
+_SourceObject::_SourceObject(const xmlpp::Element * p) :
+ name(p->get_attribute_value("name")),
+ order(loadOrder++)
{
}
-_Project2SourceObject::~_Project2SourceObject()
+_SourceObject::~_SourceObject()
{
}
diff --git a/project2/sourceObject.h b/project2/sourceObject.h
index 421054d..b4472d4 100644
--- a/project2/sourceObject.h
+++ b/project2/sourceObject.h
@@ -4,12 +4,15 @@
#include <libxml++/nodes/element.h>
#include <boost/shared_ptr.hpp>
-class _Project2SourceObject {
+class _SourceObject {
public:
- _Project2SourceObject(const xmlpp::Element * p);
- virtual ~_Project2SourceObject() = 0;
+ _SourceObject(const xmlpp::Element * p);
+ virtual ~_SourceObject() = 0;
const std::string name;
+ const unsigned int order;
+ private:
+ static unsigned int loadOrder;
};
-typedef boost::shared_ptr<_Project2SourceObject> Project2SourceObject;
+typedef boost::shared_ptr<_SourceObject> Project2SourceObject;
#endif
diff --git a/project2/sqlCheck.cpp b/project2/sqlCheck.cpp
index 25094a6..1dab147 100644
--- a/project2/sqlCheck.cpp
+++ b/project2/sqlCheck.cpp
@@ -7,6 +7,7 @@
#include <boost/regex.hpp>
_SqlCheck::_SqlCheck(const xmlpp::Element * p) :
+ _SourceObject(p),
IHaveParameters(p),
_ParamChecker(p),
dataSource(p->get_attribute_value("datasource")),
diff --git a/project2/sqlIterate.cpp b/project2/sqlIterate.cpp
new file mode 100644
index 0000000..90a8bc1
--- /dev/null
+++ b/project2/sqlIterate.cpp
@@ -0,0 +1,61 @@
+#include "sqlIterate.h"
+#include "xml.h"
+#include "selectcommand.h"
+#include "column.h"
+#include <string.h>
+#include <syslog.h>
+#include <libxml++/nodes/textnode.h>
+#include "xmlObjectLoader.h"
+#include "environment.h"
+#include "appEngine.h"
+
+_SqlIterate::_SqlIterate(const xmlpp::Element * p) :
+ _SourceObject(p),
+ IHaveParameters(p),
+ _Iterate(p),
+ dataSource(p->get_attribute_value("datasource")),
+ sql(xmlChildText(p, "sql")),
+ query(NULL)
+{
+}
+
+Glib::ustring
+_SqlIterate::getCurrentValue(const Glib::ustring & id) const
+{
+ return (*query)[id].compose();
+}
+
+void
+_SqlIterate::rebindCurrentValue(const Glib::ustring & id, ODBC::Command * cmd, unsigned int bind) const
+{
+ (*query)[id].rebind(cmd, bind);
+}
+
+void _SqlIterate::execute(const ApplicationEngine * ep, const PerRowValues * parent) const
+{
+ typedef std::map<std::string, xmlpp::Element *> Columns;
+ query = new ODBC::SelectCommand(ep->dataSource<_RdbmsDataSource>(dataSource)->getReadonly(), sql);
+ BOOST_FOREACH(Parameters::value_type p, parameters) {
+ if (p.second->source == "uri") {
+ query->bindParamS(p.second->bind, ep->env()->getParamUri(p.second->id));
+ }
+ else if (p.second->source == "query") {
+ query->bindParamS(p.second->bind, ep->env()->getParamQuery(p.second->id));
+ }
+ else if (parent && p.second->source == "parent") {
+ const _SqlIterate * psqlIterate = dynamic_cast<const _SqlIterate *>(parent);
+ if (psqlIterate) {
+ psqlIterate->rebindCurrentValue(p.second->id, query, p.second->bind);
+ }
+ else {
+ query->bindParamS(p.second->bind, parent->getCurrentValue(p.second->id));
+ }
+ }
+ }
+ while (query->fetch()) {
+ executeChildren(ep, this);
+ }
+ delete query;
+ query = NULL;
+}
+
diff --git a/project2/sqlIterate.h b/project2/sqlIterate.h
new file mode 100644
index 0000000..c9cef49
--- /dev/null
+++ b/project2/sqlIterate.h
@@ -0,0 +1,29 @@
+#ifndef SQLITERATE_H
+#define SQLITERATE_H
+
+#include <libxml++/nodes/element.h>
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include "selectcommand.h"
+#include "iterate.h"
+#include "rdbmsDataSource.h"
+#include "iHaveParameters.h"
+
+class ApplicationEngine;
+
+class _SqlIterate : public IHaveParameters, public _Iterate {
+ public:
+ _SqlIterate(const xmlpp::Element * p);
+ void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const;
+ Glib::ustring getCurrentValue(const Glib::ustring & id) const;
+ const std::string dataSource;
+ const Glib::ustring sql;
+ void rebindCurrentValue(const Glib::ustring & id, ODBC::Command *, unsigned int) const;
+ private:
+ mutable ODBC::SelectCommand * query;
+};
+typedef boost::shared_ptr<_SqlIterate> SqlIterate;
+typedef std::map<std::string, SqlIterate> SqlIterates;
+
+#endif
+
diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp
index 2832f73..93e656e 100644
--- a/project2/sqlTask.cpp
+++ b/project2/sqlTask.cpp
@@ -7,6 +7,7 @@
#include "sqlView.h"
_SqlTask::_SqlTask(const xmlpp::Element * p) :
+ _SourceObject(p),
_Task(p),
IHaveParameters(p),
dataSource(p->get_attribute_value("datasource")),
@@ -19,7 +20,7 @@ _SqlTask::~_SqlTask()
}
void
-_SqlTask::execute(const ApplicationEngine * ep, const _View * parent) const
+_SqlTask::execute(const ApplicationEngine * ep, const PerRowValues * parent) const
{
ODBC::ModifyCommand modify(ep->dataSource<_RdbmsDataSource>(dataSource)->getWritable(), sql);
BOOST_FOREACH(Parameters::value_type p, parameters) {
diff --git a/project2/sqlTask.h b/project2/sqlTask.h
index 75333e3..a64b837 100644
--- a/project2/sqlTask.h
+++ b/project2/sqlTask.h
@@ -14,7 +14,7 @@ class _SqlTask : public _Task, public IHaveParameters {
public:
_SqlTask(const xmlpp::Element * p);
virtual ~_SqlTask();
- virtual void execute(const ApplicationEngine *, const _View * parent = NULL) const;
+ virtual void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const;
const std::string dataSource;
const std::string sql;
diff --git a/project2/sqlView.cpp b/project2/sqlView.cpp
index 1fe0a0d..cab4ca5 100644
--- a/project2/sqlView.cpp
+++ b/project2/sqlView.cpp
@@ -9,6 +9,7 @@
#include "appEngine.h"
_SqlView::_SqlView(const xmlpp::Element * p) :
+ _SourceObject(p),
IHaveParameters(p),
_View(p),
dataSource(p->get_attribute_value("datasource")),
@@ -98,9 +99,7 @@ void _SqlView::execute(xmlpp::Element * par, const ApplicationEngine * ep, const
free(name);
free(attr);
}
- BOOST_FOREACH(Views::value_type sq, subViews) {
- sq.second->execute(record, ep, this);
- }
+ executeChildren(record, ep, this);
}
delete query;
query = NULL;
diff --git a/project2/task.cpp b/project2/task.cpp
index 9800b78..a84ad7e 100644
--- a/project2/task.cpp
+++ b/project2/task.cpp
@@ -2,12 +2,12 @@
#include <boost/foreach.hpp>
#include "xmlObjectLoader.h"
#include "sqlTask.h"
-
-unsigned int _Task::loadOrder = 1;
+#include "sessionClearTask.h"
+#include "sessionSetTask.h"
_Task::_Task(const xmlpp::Element * p) :
- _Project2SourceObject(p),
- order(loadOrder++)
+ _SourceObject(p),
+ _NoOutputExecute(p)
{
}
@@ -18,6 +18,16 @@ _Task::~_Task()
void
_Task::AddLoaders(Loaders & l, OrderedTasks & tasks)
{
- l.insert(LoadersVT("sqltask", _LoaderBase::Make<_SqlTask, _Task, unsigned int, _Task, &_Task::order>(&tasks)));
+ l.insert(LoadersVT("sqltask", _LoaderBase::Make<_SqlTask, _Task, unsigned int, _SourceObject, &_SourceObject::order>(&tasks)));
+ l.insert(LoadersVT("sessionclear", _LoaderBase::Make<_SessionClearTask, _Task, unsigned int, _SourceObject, &_SourceObject::order>(&tasks)));
+ l.insert(LoadersVT("sessionset", _LoaderBase::Make<_SessionSetTask, _Task, unsigned int, _SourceObject, &_SourceObject::order>(&tasks)));
+}
+
+void
+_Task::AddLoaders(Loaders & l, NoOutputExecutes & tasks)
+{
+ l.insert(LoadersVT("sqltask", _LoaderBase::Make<_SqlTask, _NoOutputExecute, unsigned int, _SourceObject, &_SourceObject::order>(&tasks)));
+ l.insert(LoadersVT("sessionclear", _LoaderBase::Make<_SessionClearTask, _NoOutputExecute, unsigned int, _SourceObject, &_SourceObject::order>(&tasks)));
+ l.insert(LoadersVT("sessionset", _LoaderBase::Make<_SessionSetTask, _NoOutputExecute, unsigned int, _SourceObject, &_SourceObject::order>(&tasks)));
}
diff --git a/project2/task.h b/project2/task.h
index 00fce4b..b79687b 100644
--- a/project2/task.h
+++ b/project2/task.h
@@ -7,6 +7,7 @@
#include "sourceObject.h"
#include "xmlObjectLoader.h"
#include "view.h"
+#include "noOutputExecute.h"
class ApplicationEngine;
class _Task;
@@ -14,16 +15,14 @@ typedef boost::shared_ptr<_Task> Task;
typedef std::map<std::string, Task> Tasks;
typedef std::map<unsigned int, Task> OrderedTasks;
-class _Task : public _Project2SourceObject {
+class _Task : public virtual _SourceObject, public _NoOutputExecute {
public:
_Task(const xmlpp::Element * p);
virtual ~_Task();
- virtual void execute(const ApplicationEngine *, const _View * parent = NULL) const = 0;
- const unsigned int order;
+ virtual void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const = 0;
static void AddLoaders(Loaders & l, OrderedTasks & vs);
- private:
- static unsigned int loadOrder;
+ static void AddLoaders(Loaders & l, NoOutputExecutes & vs);
};
#endif
diff --git a/project2/view.cpp b/project2/view.cpp
index 31596d5..799d1ae 100644
--- a/project2/view.cpp
+++ b/project2/view.cpp
@@ -4,7 +4,7 @@
#include "sqlView.h"
_View::_View(const xmlpp::Element * p) :
- _Project2SourceObject(p),
+ _SourceObject(p),
recordName(p->get_attribute_value("recordname"))
{
}
@@ -16,6 +16,14 @@ _View::~_View()
void
_View::AddLoaders(Loaders & l, Views & views)
{
- l.insert(LoadersVT("sqlview", _LoaderBase::Make<_SqlView, _View, std::string, _Project2SourceObject, &_Project2SourceObject::name>(&views)));
+ l.insert(LoadersVT("sqlview", _LoaderBase::Make<_SqlView, _View, std::string, _SourceObject, &_SourceObject::name>(&views)));
+}
+
+void
+_View::executeChildren(xmlpp::Element * record, const ApplicationEngine * ep, const _View * parent) const
+{
+ BOOST_FOREACH(Views::value_type sq, subViews) {
+ sq.second->execute(record, ep, this);
+ }
}
diff --git a/project2/view.h b/project2/view.h
index 43f2792..9bd88ed 100644
--- a/project2/view.h
+++ b/project2/view.h
@@ -6,13 +6,14 @@
#include <map>
#include "sourceObject.h"
#include "xmlObjectLoader.h"
+#include "perRowValues.h"
class ApplicationEngine;
class _View;
typedef boost::shared_ptr<_View> View;
typedef std::map<std::string, View> Views;
-class _View : public _Project2SourceObject {
+class _View : public virtual _SourceObject, public PerRowValues {
public:
_View(const xmlpp::Element * p);
virtual ~_View();
@@ -22,6 +23,7 @@ class _View : public _Project2SourceObject {
static void AddLoaders(Loaders & l, Views & vs);
protected:
+ void executeChildren(xmlpp::Element *, const ApplicationEngine *, const _View * parent = NULL) const;
Views subViews;
};