diff options
33 files changed, 522 insertions, 410 deletions
diff --git a/project2/cgiAppEngine.cpp b/project2/cgiAppEngine.cpp index 363bcb7..98009a1 100644 --- a/project2/cgiAppEngine.cpp +++ b/project2/cgiAppEngine.cpp @@ -162,7 +162,7 @@ CgiApplicationEngine::RequestStage::run()  	}  	try {  		BOOST_FOREACH(NoOutputExecutes::value_type t, tasks) { -			t.second->execute(appEngine); +			t.second->execute();  		}  		// Commit data source transactions (without invoking a connection)  		BOOST_FOREACH(DataSources::value_type ds, appEngine->datasources) { diff --git a/project2/fileRows.cpp b/project2/fileRows.cpp new file mode 100644 index 0000000..57ff8e5 --- /dev/null +++ b/project2/fileRows.cpp @@ -0,0 +1,138 @@ +#include "fileRows.h" +#include "fileStarGlibIoChannel.h" +#include <stdexcept> + +_FileRows::_FileRows(const xmlpp::Element * p) : +	path(p->get_attribute_value("path")), +	fieldSep(p->get_attribute_value("fieldSeps")[0]), +	quoteChar(p->get_attribute_value("quoteChars")[0]), +	newline(p->get_attribute_value("newline")), +	encoding(p->get_attribute_value("encoding")) +{ +	BOOST_FOREACH(const xmlpp::Node * node, p->find("columns/column")) { +		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); +		if (elem) { +			columns.push_back(elem->get_child_text()->get_content()); +		} +	} +} + +_FileRows::~_FileRows() +{ +} + +unsigned int +_FileRows::columnCount() const +{ +	return columns.size(); +} + +Glib::ustring +_FileRows::getColumnName(unsigned int col) const +{ +	return columns[col]; +} + +void +_FileRows::execute() const +{ +	FILE * f = fopen(path.c_str(), "r"); +	if (!f) { +		throw std::runtime_error("Could not open file"); +	} +	FileStrChannel c(f); +	c.set_encoding(encoding); +	c.set_line_term(newline); +	Glib::ustring line; +	while (c.read_line(line) == Glib::IO_STATUS_NORMAL) { +		line.erase(line.length() - newline.length()); +		Columns::const_iterator curCol = columns.begin(); +		bool mkCols = columns.empty(); +		bool inQuotes = false; +		bool prevWasQuote = false; +		Glib::ustring tok; +		BOOST_FOREACH(gunichar c, line) { +			if (c == quoteChar) { +				if (prevWasQuote) { +					tok += c; +					prevWasQuote = false; +				} +				else { +					inQuotes = !inQuotes; +					prevWasQuote = true; +				} +			} +			else if ((!inQuotes) && (c == fieldSep)) { +				prevWasQuote = false; +				if (mkCols) { +					addColumn(tok); +				} +				else { +					values.push_back(ValPtr(new Glib::ustring(tok))); +					curCol++; +				} +				tok.clear(); +			} +			else { +				prevWasQuote = false; +				tok += c; +			} +		} +		if (tok.length()) { +			if (mkCols) { +				addColumn(tok); +			} +			else { +				values.push_back(ValPtr(new Glib::ustring(tok))); +				curCol++; +			} +		} +		if (!mkCols) { +			while (curCol != columns.end()) { +				values.push_back(ValPtr(new Glib::ustring())); +				curCol++; +			} +			rowReady(); +		} +		values.empty(); +	} +} + +Glib::ustring +_FileRows::getCurrentValue(unsigned int col) const +{ +	return *values[col]; +} + +Glib::ustring +_FileRows::getCurrentValue(const Glib::ustring & id) const +{ +	Values::const_iterator v = values.begin(); +	for (Columns::const_iterator i = columns.begin(); i != columns.end(); i++, v++) { +		if (*i == id) { +			return **v; +		} +	} +	return ""; +} + +void +_FileRows::addColumn(const Glib::ustring & rawtok) const +{ +	columns.push_back(rawtok); +	Glib::ustring & tok(columns.back()); +	for (Glib::ustring::iterator i = tok.begin(); i != tok.end(); ) { +		if (!isalnum(*i)) { +			tok.erase(i); +		} +		else { +			i++; +		} +	} +} + +#include "view.hpp" +template class _GenericView<_FileRows>; +#include "iterate.hpp" +template class _GenericIterate<_FileRows>; + diff --git a/project2/fileRows.h b/project2/fileRows.h new file mode 100644 index 0000000..84c7a5b --- /dev/null +++ b/project2/fileRows.h @@ -0,0 +1,52 @@ +#ifndef FILEITERATE_H +#define FILEITERATE_H + +#include <libxml++/nodes/element.h> +#include <boost/shared_ptr.hpp> +#include <map> +#include "view.h" +#include "iterate.h" +#include "rowBase.h" + +class ApplicationEngine; + +class _FileRows : public RowBase { +	public: +		_FileRows(const xmlpp::Element * p); +		~_FileRows(); + +		void execute() const; +		unsigned int columnCount() const; +		Glib::ustring getColumnName(unsigned int col) const; +		Glib::ustring getCurrentValue(const Glib::ustring & id) const; +		Glib::ustring getCurrentValue(unsigned int col) const; + +		typedef std::set<gunichar> CharSet; +		const Glib::ustring path; + +	protected: +		void addColumn(const Glib::ustring & rawtok) const; +		typedef boost::shared_ptr<Glib::ustring> ValPtr; +		typedef std::vector<ValPtr> Values; +		mutable Values values; +	private: +		gunichar fieldSep; +		gunichar quoteChar; +		std::string newline; +		std::string encoding; +		typedef std::vector<Glib::ustring> Columns; +		mutable Columns columns; +}; +typedef boost::shared_ptr<_FileRows> FileRows; + +typedef _GenericView<_FileRows> _FileView; +typedef boost::shared_ptr<_FileView> FileView; +typedef std::map<std::string, FileView> FileViews; + +typedef _GenericIterate<_FileRows> _FileIterate; +typedef boost::shared_ptr<_FileIterate> FileIterate; +typedef std::map<std::string, FileIterate> FileIterates; + +#endif + + diff --git a/project2/fileStarGlibIoChannel.cpp b/project2/fileStarGlibIoChannel.cpp new file mode 100644 index 0000000..551763d --- /dev/null +++ b/project2/fileStarGlibIoChannel.cpp @@ -0,0 +1,61 @@ +#include "fileStarGlibIoChannel.h" +#include <stdio.h> + +FileStrChannel::FileStrChannel(FILE * f) : +	Glib::IOChannel(), +	file(f) +{ +	gobj()->is_seekable = 1; +	gobj()->is_readable = 1; +	gobj()->is_writeable = 0; +} + +FileStrChannel::~FileStrChannel() +{ +	if (file) { +		fclose(file); +	} +} + +Glib::IOStatus FileStrChannel::close_vfunc() +{ +	if (file) { +		fclose(file); +		file = NULL; +	} +	return Glib::IO_STATUS_NORMAL; +} + +Glib::IOStatus FileStrChannel::set_flags_vfunc(Glib::IOFlags flags) +{ +	return Glib::IO_STATUS_NORMAL; +} + +Glib::IOFlags FileStrChannel::get_flags_vfunc() +{ +	return Glib::IO_FLAG_IS_SEEKABLE | Glib::IO_FLAG_IS_READABLE; +} + +Glib::IOStatus FileStrChannel::seek_vfunc(gint64 offset, Glib::SeekType type) +{ +	if (fseek(file, offset, type)) { +		return Glib::IO_STATUS_ERROR; +	} +	return Glib::IO_STATUS_NORMAL; +} + +Glib::IOStatus FileStrChannel::read_vfunc(char* buf, gsize count, gsize& bytes_read) +{ +	bytes_read = fread(buf, 1, count, file); +	if (bytes_read == 0) { +		if (feof(file)) { +			return Glib::IO_STATUS_EOF; +		} +		if (ferror(file)) { +			return Glib::IO_STATUS_ERROR; +		} +		return Glib::IO_STATUS_AGAIN; +	} +	return Glib::IO_STATUS_NORMAL; +} + diff --git a/project2/fileStarGlibIoChannel.h b/project2/fileStarGlibIoChannel.h new file mode 100644 index 0000000..69f09ac --- /dev/null +++ b/project2/fileStarGlibIoChannel.h @@ -0,0 +1,21 @@ +#ifndef FILESTARGLIBIOCHANNEL_H +#define FILESTARGLIBIOCHANNEL_H + +#include <glibmm/iochannel.h> + +class FileStrChannel : public Glib::IOChannel { +	public: +		FileStrChannel(FILE * f); +		virtual ~FileStrChannel(); + +		virtual Glib::IOStatus close_vfunc(); +		virtual Glib::IOStatus set_flags_vfunc(Glib::IOFlags flags); +		virtual Glib::IOFlags get_flags_vfunc(); +		virtual Glib::IOStatus seek_vfunc(gint64 offset, Glib::SeekType type); +		virtual Glib::IOStatus read_vfunc(char* buf, gsize count, gsize& bytes_read); +	private: +		FILE * file; +}; + +#endif + diff --git a/project2/fileView.cpp b/project2/fileView.cpp deleted file mode 100644 index 61a6059..0000000 --- a/project2/fileView.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "fileView.h" -#include <stdexcept> -#include <glibmm/iochannel.h> - -_FileView::_FileView(const xmlpp::Element * p) : -	_SourceObject(p), -	_View(p), -	path(p->get_attribute_value("path")), -	fieldSep(p->get_attribute_value("fieldSeps")[0]), -	quoteChar(p->get_attribute_value("quoteChars")[0]), -	newline(p->get_attribute_value("newline")), -	encoding(p->get_attribute_value("encoding")) -{ -	BOOST_FOREACH(const xmlpp::Node * node, p->find("columns/column")) { -		const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node); -		if (elem) { -			columns.push_back(elem->get_child_text()->get_content()); -		} -	} -} - -_FileView::~_FileView() -{ -} - -class FileStrChannel : public Glib::IOChannel { -	public: -		FileStrChannel(FILE * f) : Glib::IOChannel(), file(f) -		{ -			gobj()->is_seekable = 1; -			gobj()->is_readable = 1; -			gobj()->is_writeable = 0; -		} -		~FileStrChannel() -		{ -			if (file) -				fclose(file); -		} -		virtual Glib::IOStatus close_vfunc() -		{ -			if (file) { -				fclose(file); -				file = NULL; -			} -			return Glib::IO_STATUS_NORMAL; -		} -		virtual Glib::IOStatus set_flags_vfunc(Glib::IOFlags flags) -		{ -			return Glib::IO_STATUS_NORMAL; -		} -		virtual Glib::IOFlags get_flags_vfunc() -		{ -			return Glib::IO_FLAG_IS_SEEKABLE | Glib::IO_FLAG_IS_READABLE; -		} -		virtual Glib::IOStatus seek_vfunc(gint64 offset, Glib::SeekType type) -		{ -			if (fseek(file, offset, type)) { -				return Glib::IO_STATUS_ERROR; -			} -			return Glib::IO_STATUS_NORMAL; -		} -		virtual Glib::IOStatus read_vfunc(char* buf, gsize count, gsize& bytes_read) -		{ -			bytes_read = fread(buf, 1, count, file); -			if (bytes_read == 0) { -				if (feof(file)) { -					return Glib::IO_STATUS_EOF; -				} -				if (ferror(file)) { -					return Glib::IO_STATUS_ERROR; -				} -				return Glib::IO_STATUS_AGAIN; -			} -			return Glib::IO_STATUS_NORMAL; -		} -	private: -		FILE * file; -}; - -void -_FileView::execute(xmlpp::Element * par, const ApplicationEngine * ep, const _View * parent) const -{ -	FILE * f = fopen(path.c_str(), "r"); -	if (!f) { -		throw std::runtime_error("Could not open file"); -	} -	FileStrChannel c(f); -	c.set_encoding(encoding); -	c.set_line_term(newline); -	xmlpp::Element * set = par->add_child(name); -	Glib::ustring line; -	while (c.read_line(line) == Glib::IO_STATUS_NORMAL) { -		line.erase(line.length() - newline.length()); -		Columns::const_iterator curCol = columns.begin(); -		bool mkCols = columns.empty(); -		xmlpp::Element * recordNode = NULL; -		if (!mkCols) { -			recordNode = set->add_child(recordName); -		} -		bool inQuotes = false; -		bool prevWasQuote = false; -		Glib::ustring tok; -		BOOST_FOREACH(gunichar c, line) { -			if (c == quoteChar) { -				if (prevWasQuote) { -					tok += c; -					prevWasQuote = false; -				} -				else { -					inQuotes = !inQuotes; -					prevWasQuote = true; -				} -			} -			else if ((!inQuotes) && (c == fieldSep)) { -				prevWasQuote = false; -				if (mkCols) { -					for (Glib::ustring::iterator i = tok.begin(); i != tok.end(); ) { -						if (!isalnum(*i)) { -							tok.erase(i); -						} -						else { -							i++; -						} -					} -					columns.push_back(tok); -				} -				else { -					recordNode->add_child(*curCol)->set_child_text(tok); -					record[*curCol] = tok; -					curCol++; -				} -				tok.clear(); -			} -			else { -				prevWasQuote = false; -				tok += c; -			} -		} -		if (tok.length()) { -			if (mkCols) { -				for (Glib::ustring::iterator i = tok.begin(); i != tok.end(); ) { -					if (!isalnum(*i)) { -						tok.erase(i); -					} -					else { -						i++; -					} -				} -				columns.push_back(tok); -			} -			else { -				recordNode->add_child(*curCol)->set_child_text(tok); -				record[*curCol] = tok; -				curCol++; -			} -		} -		if (!mkCols) { -			while (curCol != columns.end()) { -				recordNode->add_child(*curCol); -				record[*curCol].clear(); -				curCol++; -			} -		} -		executeChildren(recordNode, ep, this); -	} -} - -Glib::ustring -_FileView::getCurrentValue(const Glib::ustring & id) const -{ -	return record[id]; -} - diff --git a/project2/fileView.h b/project2/fileView.h deleted file mode 100644 index 7b7ab9b..0000000 --- a/project2/fileView.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef FILEVIEW_H -#define FILEVIEW_H - -#include <libxml++/nodes/element.h> -#include <boost/shared_ptr.hpp> -#include <map> -#include "view.h" - -class ApplicationEngine; - -class _FileView : public _View { -	public: -		_FileView(const xmlpp::Element * p); -		~_FileView(); -		void execute(xmlpp::Element *, const ApplicationEngine *, const _View * parent = NULL) const; -		Glib::ustring getCurrentValue(const Glib::ustring & id) const; - -		typedef std::set<gunichar> CharSet; -		const Glib::ustring path; - -	private: -		gunichar fieldSep; -		gunichar quoteChar; -		std::string newline; -		std::string encoding; -		typedef std::vector<Glib::ustring> Columns; -		mutable Columns columns; -		typedef std::map<Glib::ustring, Glib::ustring> Record; -		mutable Record record; -}; -typedef boost::shared_ptr<_FileView> FileView; -typedef std::map<std::string, FileView> FileViews; - -#endif - - diff --git a/project2/iterate.cpp b/project2/iterate.cpp index 843d598..59f41ff 100644 --- a/project2/iterate.cpp +++ b/project2/iterate.cpp @@ -2,7 +2,8 @@  #include <boost/foreach.hpp>  #include <syslog.h>  #include "xmlObjectLoader.h" -#include "sqlIterate.h" +#include "sqlRows.h" +#include "fileRows.h"  #include "task.h"  _Iterate::_Iterate(const xmlpp::Element * p) : @@ -10,8 +11,8 @@ _Iterate::_Iterate(const xmlpp::Element * p) :  	_NoOutputExecute(p)  {  	Loaders loaders; -	_Iterate::AddLoaders(loaders, subIterates); -	_Task::AddLoaders(loaders, subIterates); +	_Iterate::AddLoaders(loaders, subNOEs); +	_Task::AddLoaders(loaders, subNOEs);  	_LoaderBase::collectAll(loaders, "project2", p, true, true);  } @@ -20,24 +21,19 @@ _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))); +	l.insert(LoadersVT("fileiterate", _LoaderBase::Make<_FileIterate, _NoOutputExecute, unsigned int, _SourceObject, &_SourceObject::order>(&iterates)));  }  void -_Iterate::executeChildren(const ApplicationEngine * ep, const PerRowValues * parent) const +_Iterate::executeChildren() const  {  	try {  		PerRowValues::beginRow(this); -		BOOST_FOREACH(NoOutputExecutes::value_type sq, subIterates) { -			sq.second->execute(ep, this); +		BOOST_FOREACH(NoOutputExecutes::value_type sq, subNOEs) { +			sq.second->execute();  		}  		PerRowValues::endRow(this);  	} diff --git a/project2/iterate.h b/project2/iterate.h index c113585..1f6dfda 100644 --- a/project2/iterate.h +++ b/project2/iterate.h @@ -18,14 +18,26 @@ class _Iterate : public virtual _SourceObject, public PerRowValues, public _NoOu  	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); +		virtual void execute() const = 0; +		virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const = 0;  		static void AddLoaders(Loaders & l, NoOutputExecutes & vs); +  	protected: -		void executeChildren(const ApplicationEngine *, const PerRowValues * parent = NULL) const; -		NoOutputExecutes subIterates; +		void executeChildren() const; +		NoOutputExecutes subNOEs; +}; + +template <class Driver> +class _GenericIterate : public _Iterate, public Driver { +	public: +		_GenericIterate(const xmlpp::Element * p); + +		virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const { return Driver::getCurrentValue(id); } +		virtual void executeChildren() const; +		virtual void execute() const; +		virtual void rowReady() const; +	private:  };  #endif diff --git a/project2/iterate.hpp b/project2/iterate.hpp new file mode 100644 index 0000000..87701cc --- /dev/null +++ b/project2/iterate.hpp @@ -0,0 +1,31 @@ +#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>::execute() const +{ +	Driver::execute(); +} + +template <class Driver> +void +_GenericIterate<Driver>::rowReady() const +{ +	executeChildren(); +} + +template <class Driver> +void +_GenericIterate<Driver>::executeChildren() const +{ +	_Iterate::executeChildren(); +} + diff --git a/project2/noOutputExecute.h b/project2/noOutputExecute.h index ad5df92..56e7b76 100644 --- a/project2/noOutputExecute.h +++ b/project2/noOutputExecute.h @@ -14,7 +14,7 @@ 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; +		virtual void execute() const = 0;  };  #endif diff --git a/project2/presenter.cpp b/project2/presenter.cpp index 95ac53d..a471b3d 100644 --- a/project2/presenter.cpp +++ b/project2/presenter.cpp @@ -27,7 +27,7 @@ Presenter::getDataDocument() const  	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, appEngine); +		s.second->execute(responseRoot);  	}  	// These were for debug... but why not pass them on?  	xmlNewNs(responseRoot->cobj(), BAD_CAST "http://project2.randomdan.homeip.net/", BAD_CAST "project2"); diff --git a/project2/rawView.cpp b/project2/rawView.cpp index 1b79815..920a900 100644 --- a/project2/rawView.cpp +++ b/project2/rawView.cpp @@ -18,7 +18,7 @@ _RawView::getCurrentValue(const Glib::ustring & id) const  	return "";  } -void _RawView::execute(xmlpp::Element * par, const ApplicationEngine * ep, const _View * parent) const +void _RawView::execute(xmlpp::Element * par) const  {  	BOOST_FOREACH(xmlpp::Node * node, copyRoot->get_children()) {  		par->import_node(node); diff --git a/project2/rawView.h b/project2/rawView.h index 8d069b0..9d7dd44 100644 --- a/project2/rawView.h +++ b/project2/rawView.h @@ -11,7 +11,7 @@ class ApplicationEngine;  class _RawView : public _View {  	public:  		_RawView(const xmlpp::Element * p); -		void execute(xmlpp::Element *, const ApplicationEngine *, const _View * parent = NULL) const; +		void execute(xmlpp::Element *) const;  		Glib::ustring getCurrentValue(const Glib::ustring & id) const;  	private:  		const xmlpp::Element * copyRoot; diff --git a/project2/rowBase.h b/project2/rowBase.h new file mode 100644 index 0000000..337a72e --- /dev/null +++ b/project2/rowBase.h @@ -0,0 +1,14 @@ +#ifndef ROWBASE_H +#define ROWBASE_H + +class RowBase { +	public: +		virtual unsigned int columnCount() const = 0; +		virtual Glib::ustring getColumnName(unsigned int col) const = 0; +		virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const = 0; +		virtual Glib::ustring getCurrentValue(unsigned int col) const = 0; +		virtual void rowReady() const = 0; +}; + +#endif + diff --git a/project2/sendmailTask.cpp b/project2/sendmailTask.cpp index bb11017..0cbc88b 100644 --- a/project2/sendmailTask.cpp +++ b/project2/sendmailTask.cpp @@ -35,9 +35,9 @@ _SendMailTask::writeMailWrapper(void ** buf, int * len, void * arg)  }  void -_SendMailTask::execute(const ApplicationEngine * ep, const PerRowValues * parent) const +_SendMailTask::execute() const  { -	PresenterPtr p = ep->getPresenter("emails", present); +	PresenterPtr p = ApplicationEngine::getCurrent()->getPresenter("emails", present);  	Presenter::XmlDocumentPtr data = p->getDataDocument();  	typedef boost::shared_ptr<xsltStylesheet> XsltStyleSheetPtr;  	typedef boost::shared_ptr<xmlDoc> XmlDocumentPtr; diff --git a/project2/sendmailTask.h b/project2/sendmailTask.h index e3504b6..7783816 100644 --- a/project2/sendmailTask.h +++ b/project2/sendmailTask.h @@ -15,7 +15,7 @@ class _SendMailTask : public _Task {  	public:  		_SendMailTask(const xmlpp::Element * p);  		virtual ~_SendMailTask(); -		virtual void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const; +		virtual void execute() const;  	protected:  		const Variable to; diff --git a/project2/sessionClearTask.cpp b/project2/sessionClearTask.cpp index 696f250..146c85b 100644 --- a/project2/sessionClearTask.cpp +++ b/project2/sessionClearTask.cpp @@ -16,8 +16,8 @@ _SessionClearTask::~_SessionClearTask()  }  void -_SessionClearTask::execute(const ApplicationEngine * ep, const PerRowValues *) const +_SessionClearTask::execute() const  { -	ep->session()->ClearValue(key); +	ApplicationEngine::getCurrent()->session()->ClearValue(key);  } diff --git a/project2/sessionClearTask.h b/project2/sessionClearTask.h index f3b779b..0f15fef 100644 --- a/project2/sessionClearTask.h +++ b/project2/sessionClearTask.h @@ -16,7 +16,7 @@ class _SessionClearTask : public virtual _Task {  	public:  		_SessionClearTask(const xmlpp::Element * p);  		virtual ~_SessionClearTask(); -		void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const; +		void execute() const;  		const Glib::ustring key;  }; diff --git a/project2/sessionSetTask.cpp b/project2/sessionSetTask.cpp index 8304494..7d937f0 100644 --- a/project2/sessionSetTask.cpp +++ b/project2/sessionSetTask.cpp @@ -18,8 +18,8 @@ _SessionSetTask::~_SessionSetTask()  }  void -_SessionSetTask::execute(const ApplicationEngine * ep, const PerRowValues * parent) const +_SessionSetTask::execute() const  { -	ep->session()->SetValue(key, value); +	ApplicationEngine::getCurrent()->session()->SetValue(key, value);  } diff --git a/project2/sessionSetTask.h b/project2/sessionSetTask.h index 491c55d..c1a7432 100644 --- a/project2/sessionSetTask.h +++ b/project2/sessionSetTask.h @@ -17,7 +17,7 @@ class _SessionSetTask : public virtual _Task {  	public:  		_SessionSetTask(const xmlpp::Element * p);  		virtual ~_SessionSetTask(); -		void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const; +		void execute() const;  		const Glib::ustring key;  		const Variable value; diff --git a/project2/sqlIterate.cpp b/project2/sqlIterate.cpp deleted file mode 100644 index 6e8ecab..0000000 --- a/project2/sqlIterate.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "sqlIterate.h" -#include "xml.h" -#include "selectcommand.h" -#include "rdbmsDataSource.h" -#include "column.h" -#include <string.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) -{ -} - -_SqlIterate::~_SqlIterate() -{ -	delete query; -} - -Glib::ustring -_SqlIterate::getCurrentValue(const Glib::ustring & id) const -{ -	return (*query)[id].compose(); -} - -void _SqlIterate::execute(const ApplicationEngine * ep, const PerRowValues * parent) const -{ -	if (!query) { -		query = new ODBC::SelectCommand(ep->dataSource<_RdbmsDataSource>(dataSource)->getReadonly(), sql); -	} -	BOOST_FOREACH(Parameters::value_type p, parameters) { -		query->bindParamS(p.second->bind, p.second->value); -	} -	while (query->fetch()) { -		executeChildren(ep, this); -	} -} - diff --git a/project2/sqlIterate.h b/project2/sqlIterate.h deleted file mode 100644 index 382bf38..0000000 --- a/project2/sqlIterate.h +++ /dev/null @@ -1,29 +0,0 @@ -#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 "iHaveParameters.h" - -class ApplicationEngine; - -class _SqlIterate : public IHaveParameters, public _Iterate { -	public: -		_SqlIterate(const xmlpp::Element * p); -		~_SqlIterate(); -		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; - -	private: -		mutable ODBC::SelectCommand * query; -}; -typedef boost::shared_ptr<_SqlIterate> SqlIterate; -typedef std::map<std::string, SqlIterate> SqlIterates; - -#endif - diff --git a/project2/sqlRows.cpp b/project2/sqlRows.cpp new file mode 100644 index 0000000..fc4c91c --- /dev/null +++ b/project2/sqlRows.cpp @@ -0,0 +1,67 @@ +#include "sqlRows.h" +#include "xml.h" +#include "selectcommand.h" +#include "rdbmsDataSource.h" +#include "column.h" +#include <string.h> +#include <libxml++/nodes/textnode.h> +#include "xmlObjectLoader.h" +#include "appEngine.h" + +_SqlRows::_SqlRows(const xmlpp::Element * p) : +	IHaveParameters(p), +	dataSource(p->get_attribute_value("datasource")), +	sql(xmlChildText(p, "sql")), +	query(NULL) +{ +} + +_SqlRows::~_SqlRows() +{ +	delete query; +} + +Glib::ustring +_SqlRows::getCurrentValue(const Glib::ustring & id) const +{ +	return (*query)[id].compose(); +} + +Glib::ustring +_SqlRows::getCurrentValue(unsigned int col) const +{ +	return (*query)[col].compose(); +} + +unsigned int +_SqlRows::columnCount() const +{ +	return query->columnCount(); +} + +Glib::ustring +_SqlRows::getColumnName(unsigned int col) const +{ +	return (*query)[col].name; +} + +void +_SqlRows::execute() const +{ +	if (!query) { +		query = new ODBC::SelectCommand(ApplicationEngine::getCurrent()->dataSource<_RdbmsDataSource>( +					dataSource)->getReadonly(), sql); +	} +	BOOST_FOREACH(Parameters::value_type p, parameters) { +		query->bindParamS(p.second->bind, p.second->value); +	} +	while (query->fetch()) { +		rowReady(); +	} +} + +#include "view.hpp" +template class _GenericView<_SqlRows>; +#include "iterate.hpp" +template class _GenericIterate<_SqlRows>; + diff --git a/project2/sqlRows.h b/project2/sqlRows.h new file mode 100644 index 0000000..fb64caf --- /dev/null +++ b/project2/sqlRows.h @@ -0,0 +1,43 @@ +#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 "view.h" +#include "iHaveParameters.h" +#include "rowBase.h" + +class ApplicationEngine; + +class _SqlRows : public IHaveParameters, public RowBase { +	public: +		_SqlRows(const xmlpp::Element * p); +		~_SqlRows(); + +		void execute() const; +		unsigned int columnCount() const; +		Glib::ustring getColumnName(unsigned int col) const; +		Glib::ustring getCurrentValue(const Glib::ustring & id) const; +		Glib::ustring getCurrentValue(unsigned int col) const; + +		const std::string dataSource; +		const Glib::ustring sql; + +	private: +		mutable ODBC::SelectCommand * query; +}; +typedef boost::shared_ptr<_SqlRows> SqlRows; + +typedef _GenericView<_SqlRows> _SqlView; +typedef boost::shared_ptr<_SqlView> SqlView; +typedef std::map<std::string, SqlView> SqlViews; + +typedef _GenericIterate<_SqlRows> _SqlIterate; +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 08da656..b21c6c0 100644 --- a/project2/sqlTask.cpp +++ b/project2/sqlTask.cpp @@ -19,10 +19,11 @@ _SqlTask::~_SqlTask()  }  void -_SqlTask::execute(const ApplicationEngine * ep, const PerRowValues * parent) const +_SqlTask::execute() const  {  	if (!modify) { -		modify = CommandPtr(new ODBC::ModifyCommand(ep->dataSource<_RdbmsDataSource>(dataSource)->getWritable(), sql)); +		modify = CommandPtr(new ODBC::ModifyCommand(ApplicationEngine::getCurrent()->dataSource<_RdbmsDataSource>( +						dataSource)->getWritable(), sql));  	}  	BOOST_FOREACH(Parameters::value_type p, parameters) {  		modify->bindParamS(p.second->bind, p.second->value); diff --git a/project2/sqlTask.h b/project2/sqlTask.h index 3532937..f079bb8 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 execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const; +		virtual void execute() const;  		const std::string dataSource;  		const std::string sql; diff --git a/project2/sqlView.cpp b/project2/sqlView.cpp deleted file mode 100644 index bd743e9..0000000 --- a/project2/sqlView.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "sqlView.h" -#include "xml.h" -#include "selectcommand.h" -#include "column.h" -#include <string.h> -#include <libxml++/nodes/textnode.h> -#include "xmlObjectLoader.h" -#include "environment.h" -#include "appEngine.h" - -_SqlView::_SqlView(const xmlpp::Element * p) : -	_SourceObject(p), -	IHaveParameters(p), -	_View(p), -	dataSource(p->get_attribute_value("datasource")), -	sql(xmlChildText(p, "sql")), -	query(NULL) -{ -} - -_SqlView::~_SqlView() -{ -	delete query; -} - -Glib::ustring -_SqlView::getCurrentValue(const Glib::ustring & id) const -{ -	return (*query)[id].compose(); -} - -void _SqlView::execute(xmlpp::Element * par, const ApplicationEngine * ep, const _View * parent) const -{ -	if (!query) { -		query = new ODBC::SelectCommand(ep->dataSource<_RdbmsDataSource>(dataSource)->getReadonly(), sql); -	} -	BOOST_FOREACH(Parameters::value_type p, parameters) { -		query->bindParamS(p.second->bind, p.second->value); -	} -	xmlpp::Element * set = par->add_child(name); -	while (query->fetch()) { -		unsigned int cols = query->columnCount(); -		xmlpp::Element * record = set->add_child(recordName); -		for (unsigned int col = 0; col < cols; col += 1) { -			xmlpp::Element * ch = record->add_child((*query)[col].name); -			char * buf = NULL; -			(*query)[col].writeToBuf(&buf); -			if (buf) { -				ch->set_child_text(buf); -				free(buf); -			} -		} -		executeChildren(record, ep, this); -	} -} - diff --git a/project2/sqlView.h b/project2/sqlView.h deleted file mode 100644 index c025c88..0000000 --- a/project2/sqlView.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef SQLVIEW_H -#define SQLVIEW_H - -#include <libxml++/nodes/element.h> -#include <boost/shared_ptr.hpp> -#include <map> -#include "selectcommand.h" -#include "view.h" -#include "rdbmsDataSource.h" -#include "iHaveParameters.h" - -class ApplicationEngine; - -class _SqlView : public IHaveParameters, public _View { -	public: -		_SqlView(const xmlpp::Element * p); -		~_SqlView(); -		void execute(xmlpp::Element *, const ApplicationEngine *, const _View * parent = NULL) const; -		Glib::ustring getCurrentValue(const Glib::ustring & id) const; -		const std::string dataSource; -		const Glib::ustring sql; - -	private: -		mutable ODBC::SelectCommand * query; -}; -typedef boost::shared_ptr<_SqlView> SqlView; -typedef std::map<std::string, SqlView> SqlViews; - -#endif - diff --git a/project2/task.h b/project2/task.h index b79687b..6cc8c3e 100644 --- a/project2/task.h +++ b/project2/task.h @@ -19,7 +19,7 @@ class _Task : public virtual _SourceObject, public _NoOutputExecute {  	public:  		_Task(const xmlpp::Element * p);  		virtual ~_Task(); -		virtual void execute(const ApplicationEngine *, const PerRowValues * parent = NULL) const = 0; +		virtual void execute() const = 0;  		static void AddLoaders(Loaders & l, OrderedTasks & vs);  		static void AddLoaders(Loaders & l, NoOutputExecutes & vs); diff --git a/project2/view.cpp b/project2/view.cpp index c0f239f..f4f99b2 100644 --- a/project2/view.cpp +++ b/project2/view.cpp @@ -1,9 +1,9 @@  #include "view.h"  #include <boost/foreach.hpp>  #include "xmlObjectLoader.h" -#include "sqlView.h"  #include "rawView.h" -#include "fileView.h" +#include "fileRows.h" +#include "sqlRows.h"  _View::_View(const xmlpp::Element * p) :  	_SourceObject(p), @@ -27,12 +27,12 @@ _View::AddLoaders(Loaders & l, Views & views)  }  void -_View::executeChildren(xmlpp::Element * record, const ApplicationEngine * ep, const _View * parent) const +_View::executeChildren(xmlpp::Element * record) const  {  	try {  		PerRowValues::beginRow(this);  		BOOST_FOREACH(Views::value_type sq, subViews) { -			sq.second->execute(record, ep, this); +			sq.second->execute(record);  		}  		PerRowValues::endRow(this);  	} diff --git a/project2/view.h b/project2/view.h index 9bd88ed..a5f9453 100644 --- a/project2/view.h +++ b/project2/view.h @@ -7,6 +7,7 @@  #include "sourceObject.h"  #include "xmlObjectLoader.h"  #include "perRowValues.h" +#include "noOutputExecute.h"  class ApplicationEngine;  class _View; @@ -17,16 +18,28 @@ class _View : public virtual _SourceObject, public PerRowValues {  	public:  		_View(const xmlpp::Element * p);  		virtual ~_View(); -		virtual void execute(xmlpp::Element *, const ApplicationEngine *, const _View * parent = NULL) const = 0; +		virtual void execute(xmlpp::Element *) const = 0;  		virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const = 0;  		const Glib::ustring recordName;  		static void AddLoaders(Loaders & l, Views & vs);  	protected: -		void executeChildren(xmlpp::Element *, const ApplicationEngine *, const _View * parent = NULL) const; +		void executeChildren(xmlpp::Element *) const;  		Views subViews;  }; +template <class Driver> +class _GenericView : public _View, public Driver { +	public: +		_GenericView(const xmlpp::Element * p); + +		virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const { return Driver::getCurrentValue(id); } +		virtual void execute(xmlpp::Element * e) const; +		virtual void rowReady() const; +	private: +		mutable xmlpp::Element * node; +}; +  #endif diff --git a/project2/view.hpp b/project2/view.hpp new file mode 100644 index 0000000..be15eb5 --- /dev/null +++ b/project2/view.hpp @@ -0,0 +1,32 @@ +#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) { +		xmlpp::Element * ch = record->add_child(Driver::getColumnName(col)); +		ch->set_child_text(Driver::getCurrentValue(col)); +	} +	executeChildren(record); +} +  | 
