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); +} + |