summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-07-13 19:54:42 +0000
committerrandomdan <randomdan@localhost>2010-07-13 19:54:42 +0000
commit402a25412fd54d233028e20854178b433ee65dd3 (patch)
tree5572f6b6ce51a4e57638a4987f043db7772e8873
parentUse master DB after writes (diff)
downloadproject2-402a25412fd54d233028e20854178b433ee65dd3.tar.bz2
project2-402a25412fd54d233028e20854178b433ee65dd3.tar.xz
project2-402a25412fd54d233028e20854178b433ee65dd3.zip
Don't cache session variables, they can change
Uncache parent row variables on end of row Reuse ModifyCommand for every sqlTask iteration
-rw-r--r--project2/perRowValues.cpp17
-rw-r--r--project2/perRowValues.h12
-rw-r--r--project2/sqlTask.cpp8
-rw-r--r--project2/sqlTask.h4
-rw-r--r--project2/variables.cpp66
-rw-r--r--project2/variables.h5
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;
};