From ca15ae4d605a3bcd11435d92eda0800d28edceb8 Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Mon, 5 Jul 2010 07:00:08 +0000
Subject: Partial commit: Move all value prefill code to its own file.

---
 server/src/widgetgenerator.cc | 136 +++-------------
 server/src/widgetvalue.cc     | 354 ++++++++++++++++++++++++++++++++++++++++++
 server/src/widgetvalue.h      |  41 +++++
 3 files changed, 414 insertions(+), 117 deletions(-)
 create mode 100644 server/src/widgetvalue.cc
 create mode 100644 server/src/widgetvalue.h

diff --git a/server/src/widgetgenerator.cc b/server/src/widgetgenerator.cc
index 425c71e..f257228 100644
--- a/server/src/widgetgenerator.cc
+++ b/server/src/widgetgenerator.cc
@@ -24,131 +24,33 @@
  *  along with Pracro; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
-#include "debug.h"
 #include "widgetgenerator.h"
 
-#include "configuration.h"
-#include "xml_encode_decode.h"
-
-static std::string automap(std::string name)
-{
-  std::string group;
-  std::string groupcheck = "if(";
-
-  for(size_t i = 0; i < name.length(); i++) {
-    group += name[i];
-    if(name[i] == '.') groupcheck += " and " + group;
-    else groupcheck += name[i];
-  }
-  groupcheck += " and " + name + ".value and " + name + ".timestamp and " + name + ".source";
-  groupcheck += ")\n";
-
-  std::string automapstring =
-    "-- Returning 0, 0 invalidates the result\n"
-    "value = 0\n"
-    "timestamp = 0\n"
-    "source = 0\n"
-    "\n"
-    + groupcheck + 
-    "then\n"
-    "  value = " + name + ".value\n"
-    "  timestamp = " + name + ".timestamp\n"
-    "  source = " + name + ".source\n"
-    "end\n"
-    "return value, timestamp, source\n";
+#include "widgetvalue.h"
 
-  PRACRO_DEBUG(widget, "Automap:\n%s\n", automapstring.c_str());
-
-  return automapstring;
-}
+#include "xml_encode_decode.h"
 
-static std::string send_macro_widget(Macro &macro,
-                                     Widget &widget,
-                                     std::string tabs,
-                                     LUAQueryMapper &mapper,
-                                     Values &values)
+static std::string getWidgetString(Macro &macro,
+                                   Widget &widget,
+                                   std::string tabs,
+                                   LUAQueryMapper &mapper,
+                                   Values &values)
 {
   std::string result;
 
-  std::string prefilled;
-  time_t timestamp = 0;
-  time_t now = time(NULL);
-
   result = tabs + "<" + widget.attributes["tagname"];
-  std::map< std::string, std::string >::iterator p = widget.attributes.begin();
+  attr_t::iterator p = widget.attributes.begin();
 
-  PRACRO_DEBUG(prefill, "%s: %s\n",
+  PRACRO_DEBUG(prefill, "TAG: %s - NAME: %s\n",
                widget.attributes["tagname"].c_str(),
                widget.attributes["name"].c_str());
 
-  PRACRO_DEBUG(prefill, "0: (%s, %s, %d)\n",
-               prefilled.c_str(),
-               widget.attributes["value"].c_str(),
-               (int)timestamp);
-
-  // Check if the field has a map, and fill in the value if it has...
-  if(widget.attributes.find("map") != widget.attributes.end()) {
-    std::string luamap;
-
-    std::vector< Map >::iterator li = macro.maps.begin();
-    while(li != macro.maps.end()) {
-      Map &map = *li;
-      if(map.attributes["name"] == widget.attributes["map"]) {
-        luamap = map.attributes["lua"];
-      }
-      li++;
-    }
-
-    // Check to see if we should automap
-    if(luamap == "") {
-      luamap = automap(widget.attributes["map"]);
-    }
-    
-    //    printf("LUAMAP: %s\n", luamap.c_str()); fflush(stdout);
-
-    if(luamap != "") {
-      Value value = mapper.map(luamap);
-      if(value.timestamp > now - Conf::pentominos_max_ttl) {
-        widget.attributes["value"] = value.value;
-        timestamp = value.timestamp;
-        prefilled = value.source;
-      }
-
-      PRACRO_DEBUG(prefill, "map: (%s, %d)\n",
-                   value.value.c_str(),
-                   (int)value.timestamp);
-
-    }
-
-    //    widget.attributes.erase(widget.attributes.find("map"));
+  Value value;
+  if(getValue(value, widget.attributes, macro.maps, mapper, values)) {
+    widget.attributes["value"] = value.value;
+    if(value.source != "") widget.attributes["prefilled"] = value.source;
   }
 
-  PRACRO_DEBUG(prefill, "1: (%s, %s, %d)\n",
-               prefilled.c_str(),
-               widget.attributes["value"].c_str(),
-               (int)timestamp);
-
-  // Check if there is a previously stored value in the db...
-  if(values.find(widget.attributes["name"]) != values.end()) {
-
-    PRACRO_DEBUG(prefill, "db: (%s, %d)\n",
-                 values[widget.attributes["name"]].value.c_str(),
-                 (int)values[widget.attributes["name"]].timestamp);
-    
-    if(values[widget.attributes["name"]].timestamp > timestamp) {
-      if(values[widget.attributes["name"]].timestamp > now - Conf::db_max_ttl) {
-        widget.attributes["value"] = values[widget.attributes["name"]].value;
-        timestamp = values[widget.attributes["name"]].timestamp;
-        prefilled = "pracro";
-      }
-    }
-  }
-
-  PRACRO_DEBUG(prefill, "2: (%s, %s, %d)\n",
-               prefilled.c_str(),
-               widget.attributes["value"].c_str(),
-               (int)timestamp);
-
   while(p != widget.attributes.end()) {
     if(p->first != "tagname" && p->first != "map") {
       if( ! (p->first == "name" && p->second == "") )
@@ -157,8 +59,6 @@ static std::string send_macro_widget(Macro &macro,
     p++;
   }
 
-  if(prefilled != "") result += " prefilled=\"" + prefilled + "\"";
-
   if(widget.widgets.size() == 0) { // If node is empty, use short tag form
     result += "/>\n";
     return result;
@@ -168,7 +68,7 @@ static std::string send_macro_widget(Macro &macro,
 
   std::vector< Widget >::iterator w = widget.widgets.begin();
   while(w != widget.widgets.end()) {
-    result += send_macro_widget(macro, *w, tabs + "  ", mapper, values);
+    result += getWidgetString(macro, *w, tabs + "  ", mapper, values);
     w++;
   }
   result += tabs + "</" + widget.attributes["tagname"] + ">\n";
@@ -179,7 +79,8 @@ static std::string send_macro_widget(Macro &macro,
 static void get_fields(Widget &widget, Fieldnames &fields)
 {
   if(widget.attributes.find("value") != widget.attributes.end()) {
-    if(widget.attributes["name"] != "") fields.push_back(widget.attributes["name"]);
+    if(widget.attributes["name"] != "")
+      fields.push_back(widget.attributes["name"]);
   }
   
   std::vector< Widget >::iterator w = widget.widgets.begin();
@@ -189,14 +90,15 @@ static void get_fields(Widget &widget, Fieldnames &fields)
   }
 }
 
-std::string widgetgenerator(std::string cpr, Macro &macro, LUAQueryMapper &mapper, Database &db)
+std::string widgetgenerator(std::string cpr, Macro &macro,
+                            LUAQueryMapper &mapper, Database &db)
 {
   Fieldnames fields;
   get_fields(macro.widgets, fields);
 
   Values values = db.getValues(cpr, fields);
   
-  return send_macro_widget(macro, macro.widgets, "      ", mapper, values);
+  return getWidgetString(macro, macro.widgets, "      ", mapper, values);
 }
 
 #ifdef TEST_WIDGETGENERATOR
diff --git a/server/src/widgetvalue.cc b/server/src/widgetvalue.cc
new file mode 100644
index 0000000..ddb0e9c
--- /dev/null
+++ b/server/src/widgetvalue.cc
@@ -0,0 +1,354 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ *            widgetvalue.cc
+ *
+ *  Fri Jul  2 11:40:12 CEST 2010
+ *  Copyright 2010 Bent Bisballe Nyeng
+ *  deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ *  This file is part of Pracro.
+ *
+ *  Pracro is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Pracro is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Pracro; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#include "widgetvalue.h"
+
+#include "debug.h"
+#include "configuration.h"
+
+static bool getMapValue(Value &value,
+                        maps_t &maps,
+                        std::string map,
+                        LUAQueryMapper &mapper)
+{
+  std::string luamap;
+
+  maps_t::iterator li = maps.begin();
+  while(li != maps.end()) {
+    Map &_map = *li;
+    if(_map.attributes["name"] == map) {
+      luamap = _map.attributes["lua"];
+    }
+    li++;
+  }
+
+  // Check to see if we should automap
+  if(luamap == "") {
+    luamap = mapper.automap(map);
+  }
+    
+    //    printf("LUAMAP: %s\n", luamap.c_str()); fflush(stdout);
+
+  if(luamap != "") {
+    value = mapper.map(luamap);
+
+    // Value too old?
+    if(value.timestamp < time(NULL) - Conf::pentominos_max_ttl) return false;
+
+    PRACRO_DEBUG(prefill, "map: (%s, %d)\n",
+                 value.value.c_str(),
+                 (int)value.timestamp);
+    
+  }
+
+  return true;
+}
+
+static bool getDBValue(Value &value,
+                       attr_t &attr,
+                       Values &values)
+{
+  if(attr.find("name") == attr.end()) return false;
+
+  // Check if there is a previously stored value in the db...
+  if(values.find(attr["name"]) == values.end()) return false;
+
+  value = values[attr["name"]];
+
+  // Value too old?
+  if(value.timestamp < time(NULL) - Conf::db_max_ttl) return false;
+
+  value.source = "pracro";
+
+  return true;
+}
+
+bool getValue(Value &value,
+              attr_t &attr,
+              maps_t &maps,
+              LUAQueryMapper &mapper,
+              Values &values)
+{
+  std::map<time_t, Value> prio;
+
+  // Value of value-tag.
+  if(attr.find("value") != attr.end()) {
+    Value v;
+    v.timestamp = 0;
+    v.source = "";
+    v.value = attr["value"];
+    prio[v.timestamp] = v;
+  }
+
+  // Value from query map
+  if(attr.find("map") != attr.end()) {
+    Value v;
+    if(getMapValue(v, maps, attr["map"], mapper)) {
+      prio[v.timestamp] = v;
+    }
+  }
+
+  // Value from database
+  {
+    Value v;
+    if(getDBValue(v, attr, values)) {
+      prio[v.timestamp] = v;
+    }
+  }
+
+  if(prio.size() != 0) {
+    value = prio.rbegin()->second;
+  }
+
+  std::map<time_t, Value>::iterator i = prio.begin();
+  while(i != prio.end()) {
+    PRACRO_DEBUG(prefill, "% 11ld - \"%s\" (src: '%s')\n",
+                 i->second.timestamp,
+                 i->second.value.c_str(),
+                 i->second.source.c_str());
+    i++;
+  }
+
+  return prio.size() != 0;
+}
+
+
+#ifdef TEST_WIDGETVALUE
+//deps: debug.cc exception.cc log.cc configuration.cc luaquerymapper.cc 
+//cflags: -I.. $(LUA_CXXFLAGS)
+//libs: $(LUA_LIBS) 
+#include "test.h"
+
+TEST_BEGIN;
+
+pracro_debug_init();
+pracro_debug_parse("+all");
+
+time_t now = time(NULL);
+
+{
+  Value value;
+  attr_t attr;
+  maps_t maps;
+  LUAQueryMapper mapper;
+  Values values;
+  TEST_FALSE(getValue(value, attr, maps, mapper, values), "Empty values");
+}
+
+{
+  Value value;
+  attr_t attr;
+  attr["value"] = "hello";
+  maps_t maps;
+  LUAQueryMapper mapper;
+  Values values;
+  TEST_TRUE(getValue(value, attr, maps, mapper, values), "Got value?");
+  TEST_EQUAL_STR(attr["value"], value.value, "Got the right value?");
+  TEST_EQUAL_INT(value.timestamp, 0, "Got the right timestamp?");
+  TEST_EQUAL_STR(value.source, "", "Got the right source?");
+}
+
+{
+  Conf::db_max_ttl = 1000;
+
+  Value value;
+
+  attr_t attr;
+  attr["name"] = "foo";
+  attr["value"] = "hello";
+
+  maps_t maps;
+  LUAQueryMapper mapper;
+
+  Values values;
+  Value v;
+  v.value = "world";
+  v.source = "pracro";
+  v.timestamp = now - (Conf::db_max_ttl * 2);
+  values["foo"] = v;
+
+  TEST_TRUE(getValue(value, attr, maps, mapper, values), "Got value?");
+  TEST_EQUAL_STR(attr["value"], value.value, "Got the right value?");
+  TEST_EQUAL_INT(value.timestamp, 0, "Got the right timestamp?");
+  TEST_EQUAL_STR(value.source, "", "Got the right source?");
+}
+
+{
+  Conf::db_max_ttl = 1000;
+
+  Value value;
+
+  attr_t attr;
+  attr["name"] = "foo";
+  attr["value"] = "hello";
+
+  maps_t maps;
+  LUAQueryMapper mapper;
+
+  Values values;
+  Value v;
+  v.value = "world";
+  v.source = "pracro";
+  v.timestamp = now;
+  values["foo"] = v;
+
+  TEST_TRUE(getValue(value, attr, maps, mapper, values), "Got value?");
+  TEST_EQUAL_STR(v.value, value.value, "Got the right value?");
+  TEST_EQUAL_INT(value.timestamp, v.timestamp, "Got the right timestamp?");
+  TEST_EQUAL_STR(value.source, v.source, "Got the right source?");
+}
+
+{
+  Conf::db_max_ttl = 1000;
+  Conf::pentominos_max_ttl = 500;
+
+  Value value;
+
+  attr_t attr;
+  attr["name"] = "foo";
+  attr["value"] = "hello";
+  attr["map"] = "bar";
+
+  maps_t maps;
+  Map m;
+  char tbuf[32]; sprintf(tbuf, "%ld", now);
+  std::string val = "le valu";
+  m.attributes["name"] = "bar";
+  m.attributes["lua"] = "return '"+val+"', "+tbuf+", 'artefact'";
+  maps.push_back(m);
+  LUAQueryMapper mapper;
+
+  Values values;
+
+  TEST_TRUE(getValue(value, attr, maps, mapper, values), "Got value?");
+  TEST_EQUAL_STR(value.value, val, "Got the right value?");
+  TEST_EQUAL_INT(value.timestamp, now, "Got the right timestamp?");
+  TEST_EQUAL_STR(value.source, "artefact", "Got the right source?");
+}
+
+{
+  Conf::db_max_ttl = 1000;
+  Conf::pentominos_max_ttl = 500;
+
+  Value value;
+
+  attr_t attr;
+  attr["name"] = "foo";
+  attr["value"] = "hello";
+  attr["map"] = "bar";
+
+  maps_t maps;
+  Map m;
+  char tbuf[32]; sprintf(tbuf, "%ld", now - (Conf::pentominos_max_ttl * 2));
+  std::string val = "le valu";
+  m.attributes["name"] = "bar";
+  m.attributes["lua"] = "return '"+val+"', "+tbuf+", 'artefact'";
+  maps.push_back(m);
+  LUAQueryMapper mapper;
+
+  Values values;
+  Value v;
+  v.value = "world";
+  v.source = "pracro";
+  v.timestamp = now;
+  values["foo"] = v;
+
+  TEST_TRUE(getValue(value, attr, maps, mapper, values), "Got value?");
+  TEST_EQUAL_STR(v.value, value.value, "Got the right value?");
+  TEST_EQUAL_INT(value.timestamp, v.timestamp, "Got the right timestamp?");
+  TEST_EQUAL_STR(value.source, v.source, "Got the right source?");
+}
+
+{
+  Conf::db_max_ttl = 1000;
+  Conf::pentominos_max_ttl = 500;
+
+  Value value;
+
+  attr_t attr;
+  attr["name"] = "foo";
+  attr["value"] = "hello";
+  attr["map"] = "bar";
+
+  maps_t maps;
+  Map m;
+  char tbuf[32]; sprintf(tbuf, "%ld", now);
+  std::string val = "le valu";
+  m.attributes["name"] = "bar";
+  m.attributes["lua"] = "return '"+val+"', "+tbuf+", 'artefact'";
+  maps.push_back(m);
+  LUAQueryMapper mapper;
+
+  Values values;
+  Value v;
+  v.value = "world";
+  v.source = "pracro";
+  v.timestamp = now - 1;
+  values["foo"] = v;
+
+  TEST_TRUE(getValue(value, attr, maps, mapper, values), "Got value?");
+  TEST_EQUAL_STR(value.value, val, "Got the right value?");
+  TEST_EQUAL_INT(value.timestamp, now, "Got the right timestamp?");
+  TEST_EQUAL_STR(value.source, "artefact", "Got the right source?");
+}
+
+{
+  Conf::db_max_ttl = 1000;
+  Conf::pentominos_max_ttl = 500;
+
+  Value value;
+
+  attr_t attr;
+  attr["name"] = "foo";
+  attr["value"] = "hello";
+  attr["map"] = "bar";
+
+  maps_t maps;
+  Map m;
+  char tbuf[32]; sprintf(tbuf, "%ld", now - 1);
+  std::string val = "le valu";
+  m.attributes["name"] = "bar";
+  m.attributes["lua"] = "return '"+val+"', "+tbuf+", 'artefact'";
+  maps.push_back(m);
+  LUAQueryMapper mapper;
+
+  Values values;
+  Value v;
+  v.value = "world";
+  v.source = "pracro";
+  v.timestamp = now    ;
+  values["foo"] = v;
+
+  TEST_TRUE(getValue(value, attr, maps, mapper, values), "Got value?");
+  TEST_EQUAL_STR(value.value, v.value, "Got the right value?");
+  TEST_EQUAL_INT(value.timestamp, v.timestamp, "Got the right timestamp?");
+  TEST_EQUAL_STR(value.source, v.source, "Got the right source?");
+}
+
+TEST_END;
+
+#endif/*TEST_WIDGETVALUE*/
diff --git a/server/src/widgetvalue.h b/server/src/widgetvalue.h
new file mode 100644
index 0000000..eb5e9a6
--- /dev/null
+++ b/server/src/widgetvalue.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ *            widgetvalue.h
+ *
+ *  Fri Jul  2 11:40:12 CEST 2010
+ *  Copyright 2010 Bent Bisballe Nyeng
+ *  deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ *  This file is part of Pracro.
+ *
+ *  Pracro is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Pracro is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Pracro; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef __PRACRO_WIDGETVALUE_H__
+#define __PRACRO_WIDGETVALUE_H__
+
+#include "template.h"
+#include "dbtypes.h"
+#include "luaquerymapper.h"
+
+bool getValue(Value &value,
+              attr_t &attr,
+              maps_t &maps,
+              LUAQueryMapper &mapper,
+              Values &values);
+
+#endif/*__PRACRO_WIDGETVALUE_H__*/
-- 
cgit v1.2.3