summaryrefslogtreecommitdiff
path: root/project2/common/variables/lookup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'project2/common/variables/lookup.cpp')
-rw-r--r--project2/common/variables/lookup.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/project2/common/variables/lookup.cpp b/project2/common/variables/lookup.cpp
new file mode 100644
index 0000000..892968e
--- /dev/null
+++ b/project2/common/variables/lookup.cpp
@@ -0,0 +1,74 @@
+#include <pch.hpp>
+#include "../variables.h"
+#include "../safeMapFind.h"
+#include "../logger.h"
+#include "../rowProcessor.h"
+#include "../rowSet.h"
+#include <boost/foreach.hpp>
+#include "../scriptLoader.h"
+#include "../scriptStorage.h"
+
+
+/// Variable implementation that looks up it's value in a map of key(s)/value pairs
+class VariableLookup : public VariableImplDyn, public RowProcessor {
+ private:
+ typedef std::vector<VariableType> Key;
+ typedef std::map<Key, VariableType> Map;
+ public:
+ class NotFound : public std::runtime_error {
+ public:
+ NotFound(const Key & k) :
+ std::runtime_error(mklist(k)) {
+ }
+ static std::string mklist(const Key & k) {
+ std::string l("(");
+ for (Key::const_iterator kp = k.begin(); kp != k.end(); ++kp) {
+ if (kp != k.begin()) l += ", ";
+ l += kp->operator const std::string &();
+ }
+ l += ")";
+ return l;
+ }
+ };
+ VariableLookup(ScriptNodePtr e) :
+ VariableImplDyn(e),
+ RowProcessor(e),
+ name(e->value("name").as<Glib::ustring>())
+ {
+ e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&rowSets));
+ }
+ VariableType value() const
+ {
+ if (map.empty()) {
+ fillCache();
+ }
+ Key k;
+ k.reserve(parameters.size());
+ BOOST_FOREACH(const Parameters::value_type & p, parameters) {
+ k.push_back(p.second);
+ }
+ return safeMapLookup<NotFound>(map, k);
+ }
+ private:
+ void fillCache() const
+ {
+ BOOST_FOREACH(const RowSets::value_type & rs, rowSets) {
+ rs->execute(filter, this);
+ }
+ Logger()->messagef(LOG_DEBUG, "%s: %s has filled cached with %zu items",
+ __PRETTY_FUNCTION__, name.c_str(), map.size());
+ }
+ void rowReady(const RowState * rs) const
+ {
+ Key k;
+ BOOST_FOREACH(const Parameters::value_type & p, parameters) {
+ k.push_back(rs->getCurrentValue(p.first));
+ }
+ map[k] = rs->getCurrentValue(name);
+ }
+ mutable Map map;
+ typedef ANONSTORAGEOF(RowSet) RowSets;
+ RowSets rowSets;
+ const Glib::ustring name;
+};
+DECLARE_COMPONENT_LOADER("lookup", VariableLookup, VariableLoader);