diff options
-rw-r--r-- | project2/perRowValues.cpp | 17 | ||||
-rw-r--r-- | project2/perRowValues.h | 12 | ||||
-rw-r--r-- | project2/sqlTask.cpp | 8 | ||||
-rw-r--r-- | project2/sqlTask.h | 4 | ||||
-rw-r--r-- | project2/variables.cpp | 66 | ||||
-rw-r--r-- | project2/variables.h | 5 |
6 files changed, 84 insertions, 28 deletions
diff --git a/project2/perRowValues.cpp b/project2/perRowValues.cpp index 30433fd..f5cd2e7 100644 --- a/project2/perRowValues.cpp +++ b/project2/perRowValues.cpp @@ -1,5 +1,6 @@ #include "perRowValues.h" #include <cstdlib> +#include <boost/foreach.hpp> PerRowValues::RowValuesStack PerRowValues::stack; @@ -24,5 +25,21 @@ PerRowValues::endRow(const PerRowValues * r) std::abort(); } stack.pop_back(); + BOOST_FOREACH(const RowUser * ru, r->rowUsers) { + ru->rowChanged(); + } +} + +RowUser::RowUser() +{ +} + +RowUser::~RowUser() +{ +} + +void +RowUser::rowChanged() const +{ } diff --git a/project2/perRowValues.h b/project2/perRowValues.h index eec8e37..26a0a6b 100644 --- a/project2/perRowValues.h +++ b/project2/perRowValues.h @@ -3,6 +3,15 @@ #include <glibmm/ustring.h> #include <vector> +#include <set> + +class RowUser { + public: + RowUser(); + ~RowUser(); + + void rowChanged() const; +}; class PerRowValues { public: @@ -11,12 +20,15 @@ class PerRowValues { virtual ~PerRowValues() = 0; virtual Glib::ustring getCurrentValue(const Glib::ustring & id) const = 0; + void use(const RowUser * r) const { rowUsers.insert(r); } + static const RowValuesStack & Stack() { return stack; } static void beginRow(const PerRowValues * r); static void endRow(const PerRowValues * r); private: static RowValuesStack stack; + mutable std::set<const RowUser *> rowUsers; }; #endif diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp index 3811b43..930502c 100644 --- a/project2/sqlTask.cpp +++ b/project2/sqlTask.cpp @@ -22,10 +22,12 @@ _SqlTask::~_SqlTask() void _SqlTask::execute(const ApplicationEngine * ep, const PerRowValues * parent) const { - ODBC::ModifyCommand modify(ep->dataSource<_RdbmsDataSource>(dataSource)->getWritable(), sql); + if (!modify) { + modify = CommandPtr(new ODBC::ModifyCommand(ep->dataSource<_RdbmsDataSource>(dataSource)->getWritable(), sql)); + } BOOST_FOREACH(Parameters::value_type p, parameters) { - modify.bindParamS(p.second->bind, p.second->value); + modify->bindParamS(p.second->bind, p.second->value); } - modify.execute(); + modify->execute(); } diff --git a/project2/sqlTask.h b/project2/sqlTask.h index a64b837..3532937 100644 --- a/project2/sqlTask.h +++ b/project2/sqlTask.h @@ -10,6 +10,8 @@ class ApplicationEngine; class _View; +namespace ODBC { class ModifyCommand; } + class _SqlTask : public _Task, public IHaveParameters { public: _SqlTask(const xmlpp::Element * p); @@ -19,6 +21,8 @@ class _SqlTask : public _Task, public IHaveParameters { const std::string dataSource; const std::string sql; protected: + typedef boost::shared_ptr<ODBC::ModifyCommand> CommandPtr; + mutable CommandPtr modify; }; typedef boost::shared_ptr<_SqlTask> SqlTask; typedef std::map<std::string, SqlTask> SqlTasks; diff --git a/project2/variables.cpp b/project2/variables.cpp index f8fe4bb..cafb336 100644 --- a/project2/variables.cpp +++ b/project2/variables.cpp @@ -6,6 +6,7 @@ #include <stdexcept> #include <boost/tokenizer.hpp> #include <boost/foreach.hpp> +#include <boost/algorithm/string/predicate.hpp> class VariableLiteral : public VariableImpl { public: @@ -29,10 +30,7 @@ class VariableSession : public VariableImplDyn { VariableSession(const Glib::ustring & src) : VariableImplDyn(src) { } const Glib::ustring & value() const { - if (!cacheValid) { - cache = ApplicationEngine::getCurrent()->session()->GetValue(source.substr(1)); - cacheValid = true; - } + cache = ApplicationEngine::getCurrent()->session()->GetValue(source.substr(1)); return cache; } }; @@ -63,39 +61,55 @@ class VariableUri : public VariableImplDyn { } }; -class VariableParent : public VariableImplDyn { +class VariableParent : public VariableImplDyn, public RowUser { public: - VariableParent(const Glib::ustring & src) : VariableImplDyn(src) { } + VariableParent(const Glib::ustring & src, RowUser * dep) : + VariableImplDyn(Glib::ustring(std::find_if(src.begin(), src.end(), isalpha), src.end())) + { + PerRowValues::RowValuesStack::const_iterator r = PerRowValues::Stack().end(); + size_t p = src.length() - source.length(); + while (--p) { + r--; + } + row = *r; + row->use(this); + if (dep) { + row->use(dep); + } + } const Glib::ustring & value() const { if (!cacheValid) { - PerRowValues::RowValuesStack::const_iterator r = PerRowValues::Stack().end(); - Glib::ustring::const_iterator c = source.begin(); - while (*c == '^') { - r--; - c++; - } - cache = (*r)->getCurrentValue(Glib::ustring(c, source.end())); + cache = row->getCurrentValue(source); cacheValid = true; } return cache; } + void rowChanged() const + { + cacheValid = false; + } + protected: + const PerRowValues * row; }; -class VariableParse : public VariableImplDyn { +class VariableParse : public VariableImplDyn, public RowUser { public: - VariableParse(const Glib::ustring & src) : VariableImplDyn(src) { } + VariableParse(const Glib::ustring & src) : + VariableImplDyn(src) + { + boost::char_separator<char> sep(" "); + boost::tokenizer<boost::char_separator<char> > tokens(source.raw(), sep); + BOOST_FOREACH(std::string t, tokens) { + vars.push_back(Variable::create(t, this)); + } + } const Glib::ustring & value() const { if (!cacheValid) { - boost::char_separator<char> sep(" "); - boost::tokenizer<boost::char_separator<char> > tokens(source.raw(), sep); - std::list<Variable::VariableImplPtr> vars; size_t len = 0; - BOOST_FOREACH(std::string t, tokens) { - Variable::VariableImplPtr vip = Variable::create(t); + BOOST_FOREACH(Variable::VariableImplPtr vip, vars) { len += vip->value().length() + 1; - vars.push_back(vip); } cache.reserve(len); BOOST_FOREACH(Variable::VariableImplPtr v, vars) { @@ -108,6 +122,12 @@ class VariableParse : public VariableImplDyn { } return cache; } + void rowChanged() const + { + cacheValid = false; + } + private: + std::list<Variable::VariableImplPtr> vars; }; Variable::Variable(const Glib::ustring & s) : @@ -126,7 +146,7 @@ Variable::Variable(xmlpp::Element * e) : } Variable::VariableImplPtr -Variable::create(const Glib::ustring & s) +Variable::create(const Glib::ustring & s, RowUser * dep) { switch (s[0]) { case '$': // param @@ -134,7 +154,7 @@ Variable::create(const Glib::ustring & s) case '%': // session return VariableImplPtr(new VariableSession(s)); case '^': // parent - return VariableImplPtr(new VariableParent(s)); + return VariableImplPtr(new VariableParent(s, dep)); case '/': // uri return VariableImplPtr(new VariableUri(s)); case '*': // parser diff --git a/project2/variables.h b/project2/variables.h index cba303e..3387a0a 100644 --- a/project2/variables.h +++ b/project2/variables.h @@ -6,6 +6,8 @@ #include <libxml++/nodes/element.h> #include <libxml++/attribute.h> +class RowUser; + class VariableImpl { public: virtual const Glib::ustring & value() const = 0; @@ -15,7 +17,6 @@ class VariableImpl { const Glib::ustring source; }; - class Variable { public: typedef boost::shared_ptr<VariableImpl> VariableImplPtr; @@ -29,7 +30,7 @@ class Variable { private: friend class VariableParse; - static VariableImplPtr create(const Glib::ustring & s); + static VariableImplPtr create(const Glib::ustring & s, RowUser * dep = NULL); VariableImplPtr var; }; |