diff options
| author | randomdan <randomdan@localhost> | 2010-12-14 00:20:38 +0000 | 
|---|---|---|
| committer | randomdan <randomdan@localhost> | 2010-12-14 00:20:38 +0000 | 
| commit | 3f452dd8b71e546d91377153e24e6ed530307e90 (patch) | |
| tree | a4ecc86baff05083ee7149a06c735c28eb79c8b5 | |
| parent | Support binding null to an SQL command parameter (diff) | |
| download | project2-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
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(¶meterChecks)); +	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(¶meterChecks));  	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(¶meterChecks)); -	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  | 
