diff options
-rw-r--r-- | project2/Jamfile.jam | 1 | ||||
-rw-r--r-- | project2/iHaveParameters.cpp | 27 | ||||
-rw-r--r-- | project2/iHaveParameters.h | 8 | ||||
-rw-r--r-- | project2/iterate.cpp | 4 | ||||
-rw-r--r-- | project2/rowView.cpp | 3 | ||||
-rw-r--r-- | project2/sqlRows.cpp | 18 | ||||
-rw-r--r-- | project2/sqlRows.h | 14 | ||||
-rw-r--r-- | project2/variables-modlocalparam.cpp | 31 | ||||
-rw-r--r-- | project2/variables.cpp | 16 | ||||
-rw-r--r-- | project2/variables.h | 1 |
10 files changed, 105 insertions, 18 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index 80befb9..f7dd242 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -61,6 +61,7 @@ lib p2common : rowView.cpp rowSet.cpp rowProcessor.cpp config.cpp fileStrmVarWriter.cpp noOutputExecute.cpp columns.cpp scopeObject.cpp transform.cpp transformHtml.cpp transformText.cpp definedColumns.cpp structExceptHandling.cpp validDateCheck.cpp variables-modconfig.cpp + variables-modlocalparam.cpp variables-modlookup.cpp variables-modparam.cpp variables-modsession.cpp diff --git a/project2/iHaveParameters.cpp b/project2/iHaveParameters.cpp index 323cc0b..d47fc42 100644 --- a/project2/iHaveParameters.cpp +++ b/project2/iHaveParameters.cpp @@ -3,6 +3,8 @@ #include "appEngine.h" #include <boost/foreach.hpp> +IHaveParameters::Stack IHaveParameters::scope; + IHaveParameters::IHaveParameters(const xmlpp::Element * p) { BOOST_FOREACH(xmlpp::Node * node, p->find("parameters/param")) { @@ -34,3 +36,28 @@ IHaveParameters::getParameter(const Glib::ustring & name) const throw ParamNotFound(name); } +void +IHaveParameters::push(const IHaveParameters * p) +{ + scope.push_back(p); +} + +void +IHaveParameters::pop(const IHaveParameters * p) +{ + assert(scope.back() == p); + scope.pop_back(); +} + +VariableType +IHaveParameters::getScopedParameter(const Glib::ustring & name) +{ + for(Stack::const_reverse_iterator ihp = scope.rbegin(); ihp != scope.rend(); ihp++) { + Parameters::const_iterator i = (*ihp)->parameters.find(name); + if (i != (*ihp)->parameters.end()) { + return i->second->value; + } + } + throw ParamNotFound(name); +} + diff --git a/project2/iHaveParameters.h b/project2/iHaveParameters.h index 0f8d154..c6dcd45 100644 --- a/project2/iHaveParameters.h +++ b/project2/iHaveParameters.h @@ -3,6 +3,7 @@ #include <libxml++/nodes/element.h> #include <boost/intrusive_ptr.hpp> +#include <vector> #include "variables.h" #include "intrusivePtrBase.h" @@ -19,11 +20,18 @@ class IHaveParameters { virtual ~IHaveParameters() = 0; VariableType getParameter(const Glib::ustring &) const; + static VariableType getScopedParameter(const Glib::ustring &); typedef boost::intrusive_ptr<Parameter> ParameterPtr; typedef std::map<Glib::ustring, ParameterPtr> Parameters; protected: Parameters parameters; + + static void push(const IHaveParameters *); + static void pop(const IHaveParameters *); + private: + typedef std::vector<const IHaveParameters *> Stack; + static Stack scope; }; #endif diff --git a/project2/iterate.cpp b/project2/iterate.cpp index 99c5004..dc59757 100644 --- a/project2/iterate.cpp +++ b/project2/iterate.cpp @@ -1,7 +1,9 @@ #include "iterate.h" #include "logger.h" #include <boost/foreach.hpp> +#include <boost/bind.hpp> #include "xmlObjectLoader.h" +#include "scopeObject.h" DECLARE_LOADER("iterate", Iterate); @@ -34,6 +36,8 @@ Iterate::rowReady(const RowState *) const void Iterate::execute() const { + IHaveParameters::push(this); + ScopeObject _ihp(boost::bind(&IHaveParameters::pop, this)); source->execute(filter, this); } diff --git a/project2/rowView.cpp b/project2/rowView.cpp index 2ac5081..51472c5 100644 --- a/project2/rowView.cpp +++ b/project2/rowView.cpp @@ -2,6 +2,7 @@ #include "presenter.h" #include "scopeObject.h" #include "xmlObjectLoader.h" +#include "scopeObject.h" #include <boost/foreach.hpp> #include <boost/bind.hpp> #include <libxml++/nodes/textnode.h> @@ -58,6 +59,8 @@ RowView::execute(const Presenter * p) const { presenter = p; presenter->pushSub(rootName); + ScopeObject _ihp(boost::bind(&IHaveParameters::pop, this)); + IHaveParameters::push(this); ScopeObject pres(boost::bind(&Presenter::popSub, p)); source->execute(filter, this); } diff --git a/project2/sqlRows.cpp b/project2/sqlRows.cpp index fb2de33..48774ae 100644 --- a/project2/sqlRows.cpp +++ b/project2/sqlRows.cpp @@ -80,7 +80,7 @@ SqlRows::execute(const Glib::ustring & filter, const RowProcessor * rp) const Glib::ustring sql; sqlCommand.writeSql(sql); SqlState ss(SelectPtr(db->getReadonly().newSelectCommand(sql))); - sqlCommand.bindParams(rp, ss.query.get(), offset); + sqlCommand.bindParams(ss.query.get(), offset); while (ss.query->fetch()) { HandleAsVariableType h; if (ss.fields.empty()) { @@ -133,10 +133,10 @@ SqlRows::SqlCommand::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlCommand::bindParams(const RowProcessor * rp, DB::SelectCommand * cmd, unsigned int & offset) const +SqlRows::SqlCommand::bindParams(DB::SelectCommand * cmd, unsigned int & offset) const { BOOST_FOREACH(const SqlWriterPtr & w, writers) { - w->bindParams(rp, cmd, offset); + w->bindParams(cmd, offset); } } @@ -169,17 +169,17 @@ SqlRows::SqlFilter::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlFilter::bindParams(const RowProcessor * rp, DB::SelectCommand * cmd, unsigned int & offset) const +SqlRows::SqlFilter::bindParams(DB::SelectCommand * cmd, unsigned int & offset) const { if (active) { BOOST_FOREACH(const SqlWriterPtr & w, writers) { - w->bindParams(rp, cmd, offset); + w->bindParams(cmd, offset); } } } SqlRows::SqlParameter::SqlParameter(const xmlpp::Element * n) : - name(n->get_attribute_value("name")) + Variable(n, boost::optional<Glib::ustring>("local")) { } @@ -190,9 +190,9 @@ SqlRows::SqlParameter::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlParameter::bindParams(const RowProcessor * rp, DB::SelectCommand * cmd, unsigned int & offset) const +SqlRows::SqlParameter::bindParams(DB::SelectCommand * cmd, unsigned int & offset) const { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), rp->getParameter(name)); + boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), (*this)); } SqlRows::SqlText::SqlText(const xmlpp::TextNode * n) : @@ -207,7 +207,7 @@ SqlRows::SqlText::writeSql(Glib::ustring & sql) const } void -SqlRows::SqlText::bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int &) const +SqlRows::SqlText::bindParams(DB::SelectCommand *, unsigned int &) const { } diff --git a/project2/sqlRows.h b/project2/sqlRows.h index 10f57f1..494f188 100644 --- a/project2/sqlRows.h +++ b/project2/sqlRows.h @@ -30,29 +30,27 @@ class SqlRows : public RowSet { SqlWriter(); virtual ~SqlWriter(); virtual void writeSql(Glib::ustring & sql) const = 0; - virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const = 0; + virtual void bindParams(DB::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 *, DB::SelectCommand *, unsigned int & offset) const; + virtual void bindParams(DB::SelectCommand *, unsigned int & offset) const; const Glib::ustring text; }; - class SqlParameter : public SqlWriter { + class SqlParameter : public SqlWriter, Variable { public: SqlParameter(const xmlpp::Element *); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const; - - const Glib::ustring name; + virtual void bindParams(DB::SelectCommand *, unsigned int & offset) const; }; class SqlFilter : public SqlWriter { public: SqlFilter(const xmlpp::Element *); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const; + virtual void bindParams(DB::SelectCommand *, unsigned int & offset) const; const Glib::ustring name; bool active; @@ -64,7 +62,7 @@ class SqlRows : public RowSet { public: SqlCommand(const xmlpp::Element *); virtual void writeSql(Glib::ustring & sql) const; - virtual void bindParams(const RowProcessor *, DB::SelectCommand *, unsigned int & offset) const; + virtual void bindParams(DB::SelectCommand *, unsigned int & offset) const; typedef std::multimap<Glib::ustring, SqlFilterPtr> Filters; typedef std::pair<Filters::const_iterator, Filters::const_iterator> FiltersRangeType; Filters filters; diff --git a/project2/variables-modlocalparam.cpp b/project2/variables-modlocalparam.cpp new file mode 100644 index 0000000..24e1d54 --- /dev/null +++ b/project2/variables-modlocalparam.cpp @@ -0,0 +1,31 @@ +#include "variables.h" +#include "xmlObjectLoader.h" +#include "logger.h" +#include "xmlStorage.h" +#include "iHaveParameters.h" + +/// Variable implementation to access call parameters +class VariableLocalParam : public VariableImplDyn { + public: + VariableLocalParam(const xmlpp::Element * e) : + VariableImplDyn(e), + name(e->get_attribute_value("name")) + { + } + VariableType value() const + { + try { + return IHaveParameters::getScopedParameter(name); + } + catch (ParamNotFound) { + if (!defaultValue) { + throw; + } + return (*defaultValue)(); + } + } + private: + const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("local", VariableLocalParam, VariableLoader); + diff --git a/project2/variables.cpp b/project2/variables.cpp index 70f51b8..7e7ea2c 100644 --- a/project2/variables.cpp +++ b/project2/variables.cpp @@ -150,7 +150,7 @@ class VariableParent : public VariableImplDyn { public: VariableParent(const xmlpp::Element * e) : VariableImplDyn(e), - depth(atoi(e->get_attribute_value("depth").c_str())), + depth(e->get_attribute("depth") ? atoi(e->get_attribute_value("depth").c_str()) : 1), attr(e->get_attribute("attribute")), name(attr ? e->get_attribute_value("attribute") : e->get_attribute_value("name")) { @@ -251,6 +251,20 @@ Variable::Variable(const xmlpp::Element * e, const Glib::ustring & n, bool requi throw NoVariableDefinition(n); } +Variable::Variable(const xmlpp::Element * c, const boost::optional<Glib::ustring> & defaultSource) +{ + xmlpp::Attribute * source = c->get_attribute("source"); + if (source) { + var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(c); + } + else if (defaultSource) { + var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(defaultSource.get())->create(c); + } + else { + var = new VariableLiteral(c); + } +} + Variable::Variable(VariableImpl * v) : var(v) { diff --git a/project2/variables.h b/project2/variables.h index a22ebf4..4c06f96 100644 --- a/project2/variables.h +++ b/project2/variables.h @@ -73,6 +73,7 @@ class Variable { typedef boost::intrusive_ptr<VariableImpl> VariableImplPtr; Variable(const xmlpp::Element *, const Glib::ustring & n, bool required = true, VariableType def = VariableType()); + Variable(const xmlpp::Element *, const boost::optional<Glib::ustring> &); Variable(VariableType def); static Variable makeFromCode(const Glib::ustring & s); |