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