From 6bae4fd17d2660d53279dac9287de52be2a00c6c Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Fri, 4 Feb 2011 13:34:40 +0000
Subject: Database pool is now used instead of one connection per session.
 Admin interface supports session unlock.

---
 server/src/admin_connection.cc   | 36 ++++++++++++++++----
 server/src/admin_connection.h    |  5 ++-
 server/src/database.h            | 44 +++++++++++++++----------
 server/src/environment.cc        |  7 ++--
 server/src/environment.h         |  4 +--
 server/src/pracrodao.h           |  1 +
 server/src/pracrodaopgsql.cc     | 21 ++++++++++++
 server/src/pracrodaopgsql.h      |  1 +
 server/src/pracrodaotest.h       |  1 +
 server/src/queryhandlerpracro.cc |  2 +-
 server/src/server.cc             |  2 +-
 server/src/session.cc            | 71 ++++++++++++++++++++++++++--------------
 server/src/session.h             | 13 +++++---
 server/src/sessionserialiser.cc  | 12 ++++---
 server/src/sessionserialiser.h   |  5 ++-
 server/src/transactionhandler.cc | 21 +++++++-----
 server/src/widgetgenerator.cc    |  5 +--
 server/src/widgetgenerator.h     |  1 +
 18 files changed, 176 insertions(+), 76 deletions(-)

(limited to 'server/src')

diff --git a/server/src/admin_connection.cc b/server/src/admin_connection.cc
index 517b17a..32cc67e 100644
--- a/server/src/admin_connection.cc
+++ b/server/src/admin_connection.cc
@@ -27,19 +27,46 @@
  */
 #include "admin_connection.h"
 
-AdminConnection::AdminConnection(Environment &e, headers_t a)
-  : env(e), args(a) {}
+#include "debug.h"
+
+static std::string admin_sessionunlock(Environment &env, std::string id)
+{
+  Session *session = env.sessions.session(id);
+  if(session) {
+    if(session->isreadonly) {
+      env.sessions.deleteSession(id);
+      return "Session " + id + " was 'readonly' and has been discarded.";
+    } else {
+      session->setActive(false);
+      return "Session " + id + " has been deactivated (set to idle).";
+    }
+  }
+  return "Session " + id + " does not exist or has been committed.";
+}
+
+AdminConnection::AdminConnection(Environment &e, headers_t a, std::string u)
+  : env(e), args(a), uri(u) {}
 
 AdminConnection::~AdminConnection() {}
 
 bool AdminConnection::handle(const char *data, size_t size)
 {
+  if(data == NULL && size == 0) {
+    if(uri == "/sessionunlock" && args.find("id") != args.end()) {
+      reply = admin_sessionunlock(env, args["id"]);
+      return true;
+    }
+
+    reply = "Try something else...";
+    return false;
+  }
+
   return true;
 }
 
 std::string AdminConnection::getResponse()
 {
-  return "Hello Admin World";
+  return reply;
 }
 
 headers_t AdminConnection::getHeaders()
@@ -50,11 +77,8 @@ headers_t AdminConnection::getHeaders()
 
 
 #ifdef TEST_ADMIN_CONNECTION
-//Additional dependency files
 //deps:
-//Required cflags (autoconf vars may be used)
 //cflags:
-//Required link options (autoconf vars may be used)
 //libs:
 #include "test.h"
 
diff --git a/server/src/admin_connection.h b/server/src/admin_connection.h
index 98ddda7..c3f70b7 100644
--- a/server/src/admin_connection.h
+++ b/server/src/admin_connection.h
@@ -35,7 +35,7 @@
 
 class AdminConnection : public Connection {
 public:
-  AdminConnection(Environment &e, headers_t args);
+  AdminConnection(Environment &e, headers_t args, std::string uri);
   ~AdminConnection();
 
   bool handle(const char *data, size_t size);
@@ -46,6 +46,9 @@ public:
 private:
   Environment &env;
   headers_t args;
+  std::string uri;
+
+  std::string reply;
 };
 
 #endif/*__PRACRO_ADMIN_CONNECTION_H__*/
diff --git a/server/src/database.h b/server/src/database.h
index f3b42e2..fe644bc 100644
--- a/server/src/database.h
+++ b/server/src/database.h
@@ -42,23 +42,24 @@ public:
            std::string _passwd, std::string _dbname);
   ~Database();
 
-  std::string sessionId()
+  std::string newSessionId()
   {
-    if(dao && sessionid == "") {
-      sessionid = dao->newSessionId();
+    if(dao) {
+      return dao->newSessionId();
     }
-    return sessionid;
+    return "";
   }
-
+  /*
   void setSessionId(std::string sessionid)
   {
     this->sessionid = sessionid;
   }
-
+  */
   // Make a commit to the db
   void commitTransaction(Transaction &transaction,
                          Commit &commit,
                          Macro &macro,
+                         std::string sessionid,
                          time_t now = time(NULL))
   {
     if(!dao) return;
@@ -67,13 +68,14 @@ public:
     DEBUG(db, "%s, %s, %s,...\n",
           transaction.user.c_str(), transaction.cpr.c_str(),
           macro.attributes["name"].c_str());
-    dao->commitTransaction(sessionId(), transaction, commit, macro, now);
+    dao->commitTransaction(sessionid, transaction, commit, macro, now);
     mutex.unlock();
   }
 
   // Get a list of values from the db
   Values getValues(std::string patientid,
                    Fieldnames &fieldnames,
+                   std::string sessionid,
                    time_t oldest = 0)
   {
     if(!dao) return Values();
@@ -89,6 +91,7 @@ public:
   // Check if a macro has been committed.
   bool checkMacro(std::string patientid,
                   std::string macro,
+                  std::string sessionid,
                   time_t oldest = 0)
   {
     DEBUG(db, "%s, %s, %ld\n",
@@ -101,7 +104,8 @@ public:
   }
   
   // Get latest resume of a given macro
-  std::string getResume(std::string patientid, Macro &macro, time_t oldest)
+  std::string getResume(std::string patientid, Macro &macro,
+                        time_t oldest, std::string sessionid)
   {
     DEBUG(db, "%s, %s, %ld\n",
           patientid.c_str(), macro.attributes["name"].c_str(), oldest);
@@ -144,22 +148,22 @@ public:
     return fieldnames;
   }
 
-  void commit()
+  void commit(std::string sessionid)
   {
     if(!dao || sessionid == "") return;
-    return dao->commit(sessionId());
+    return dao->commit(sessionid);
   }
 
-  void nocommit()
+  void nocommit(std::string sessionid)
   {
     if(!dao || sessionid == "") return;
-    return dao->nocommit(sessionId());
+    return dao->nocommit(sessionid);
   }
 
-  void discard()
+  void discard(std::string sessionid)
   {
     if(!dao || sessionid == "") return;
-    return dao->discard(sessionId());
+    return dao->discard(sessionid);
   }
 
   std::string serialise()
@@ -174,16 +178,22 @@ public:
     return dao->restore(data);
   }
 
-  bool active()
+  bool active(std::string sessionid)
   {
     if(!dao || sessionid == "") return false;
-    return dao->active(sessionId());
+    return dao->active(sessionid);
+  }
+
+  void setActive(std::string sessionid, bool val)
+  {
+    if(dao && sessionid != "") {
+      dao->setActive(sessionid, val);
+    }
   }
 
 private:
   PracroDAO *dao;
   Mutex mutex;
-  std::string sessionid;
 };
 
 #endif/*__PRACRO_DATABASE_H__*/
diff --git a/server/src/environment.cc b/server/src/environment.cc
index a2b7cb9..b40c3ca 100644
--- a/server/src/environment.cc
+++ b/server/src/environment.cc
@@ -31,15 +31,16 @@
 #include "database.h"
 
 Environment::Environment()
-  : macrolist(Conf::xml_basedir + "/macros"),
+  : sessions(this),
+    macrolist(Conf::xml_basedir + "/macros"),
     templatelist(Conf::xml_basedir + "/templates")
 {
-  /*
+
   for(int i = 0; i < Conf::database_poolsize; i++) {
     dbpool.add(new Database(Conf::database_backend, Conf::database_addr,
                           "", Conf::database_user, Conf::database_passwd, ""));
   }
-  */
+
   for(int i = 0; i < Conf::artefact_poolsize; i++) {
     atfpool.add(new Artefact);
   }
diff --git a/server/src/environment.h b/server/src/environment.h
index 3e2ac95..a7b9677 100644
--- a/server/src/environment.h
+++ b/server/src/environment.h
@@ -28,7 +28,7 @@
 #ifndef __PRACRO_ENVIRONMENT_H__
 #define __PRACRO_ENVIRONMENT_H__
 
-//#include "database.h"
+#include "database.h"
 #include "artefact.h"
 #include "connectionpool.h"
 #include "session.h"
@@ -40,7 +40,7 @@ public:
   Environment();
   ~Environment();
 
-  //  ConnectionPool<Database*> dbpool;
+  ConnectionPool<Database*> dbpool;
   ConnectionPool<Artefact*> atfpool;
   Sessions sessions;
   MacroList macrolist;
diff --git a/server/src/pracrodao.h b/server/src/pracrodao.h
index d74aeaa..53c7db2 100644
--- a/server/src/pracrodao.h
+++ b/server/src/pracrodao.h
@@ -69,6 +69,7 @@ public:
   virtual std::string serialise() = 0;
   virtual void restore(const std::string &data) = 0;
   virtual bool active(std::string sessionid) = 0;
+  virtual void setActive(std::string sessionid, bool active) = 0;
 
 protected:
   std::string host;
diff --git a/server/src/pracrodaopgsql.cc b/server/src/pracrodaopgsql.cc
index 5a08e3a..c86797d 100644
--- a/server/src/pracrodaopgsql.cc
+++ b/server/src/pracrodaopgsql.cc
@@ -510,6 +510,27 @@ bool PracroDAOPgsql::active(std::string sessionid)
   return false;
 }
 
+void PracroDAOPgsql::setActive(std::string sessionid, bool a)
+{
+  std::string ts;
+  try {
+    pqxx::work W(*conn);
+    if(a) {
+      ts = "UPDATE commits SET status='idle' WHERE uid="+sessionid+
+        " AND status='active';";
+    } else {
+      ts = "UPDATE commits SET status='active' WHERE uid="+sessionid+
+        " AND status='idle';";
+    }
+    /*pqxx::result R = */W.exec(ts);
+    
+    W.commit();
+  } catch (std::exception &e) {
+    ERR_LOG(db, "setActive failed: %s: %s\n", e.what(), ts.c_str());
+  }
+ 
+}
+
 #endif/*WITHOUT_DB*/
 
 #ifdef TEST_PRACRODAOPGSQL
diff --git a/server/src/pracrodaopgsql.h b/server/src/pracrodaopgsql.h
index 4d424f0..c943e93 100644
--- a/server/src/pracrodaopgsql.h
+++ b/server/src/pracrodaopgsql.h
@@ -70,6 +70,7 @@ public:
   std::string serialise() { return ""; }
   void restore(const std::string &data) {}
   bool active(std::string sessionid);
+  void setActive(std::string sessionid, bool active);
 
 private:
   pqxx::connection  *conn;
diff --git a/server/src/pracrodaotest.h b/server/src/pracrodaotest.h
index 67df596..1e1a8c0 100644
--- a/server/src/pracrodaotest.h
+++ b/server/src/pracrodaotest.h
@@ -105,6 +105,7 @@ public:
   std::string serialise() { return ""; }
   void restore(const std::string &data) {}
   bool active(std::string sessionid) {return false;}
+  void setActive(std::string sessionid, bool active) {}
 
 private: 
   Data data;
diff --git a/server/src/queryhandlerpracro.cc b/server/src/queryhandlerpracro.cc
index 6868e47..85dcdf9 100644
--- a/server/src/queryhandlerpracro.cc
+++ b/server/src/queryhandlerpracro.cc
@@ -56,7 +56,7 @@ QueryResult QueryHandlerPracro::exec(Query &query)
     oldest = time(NULL) - Conf::db_max_ttl;
   }
 
-  Values values = db.getValues(cpr, fields, oldest);
+  Values values = db.getValues(cpr, fields, ""/*no session*/, oldest);
 
   if(values.find(field) != values.end()) {
     std::string value = values[field].value;
diff --git a/server/src/server.cc b/server/src/server.cc
index 1665bbf..745b77b 100644
--- a/server/src/server.cc
+++ b/server/src/server.cc
@@ -61,7 +61,7 @@ public:
 
     if(headers.find("User-Agent") != headers.end() &&
        headers["User-Agent"].find("Pracro") == std::string::npos) { // Admin
-      connection = new AdminConnection(env, getargs);
+      connection = new AdminConnection(env, getargs, url);
     } else { // Pracro client
       ClientConnection::Parameters parms;
       if(headers.contains("SessionID"))
diff --git a/server/src/session.cc b/server/src/session.cc
index c919e54..7290c31 100644
--- a/server/src/session.cc
+++ b/server/src/session.cc
@@ -43,29 +43,35 @@
 #include "configuration.h"
 #include "connectionpool.h"
 #include "sessionserialiser.h"
+#include "environment.h"
 
-Session::Session(std::string sessionid, std::string pid, std::string t)
+Session::Session(Environment *e,
+                 std::string sid, std::string pid, std::string t)
+ : env(e)
 {
   _journal = NULL;
-  _database = NULL;
 
+  sessionid = sid;
   patientid = pid;
   templ = t;
   
   isreadonly = true;
-
-  database()->setSessionId(sessionid);
 }
 
 Session::~Session()
 {
   if(_journal) delete _journal;
-  if(_database) delete _database;
 }
 
 std::string Session::id()
 {
-  return database()->sessionId();
+  if(sessionid == "") {
+    AutoBorrower<Database*> borrower(env->dbpool);
+    Database *db = borrower.get();
+    sessionid = db->newSessionId();
+  }
+
+  return sessionid;
 }
 
 void Session::lock()
@@ -80,7 +86,22 @@ void Session::unlock()
 
 bool Session::active()
 {
-  return isreadonly || database()->active();
+  if(isreadonly) return true;
+
+  {
+    AutoBorrower<Database*> borrower(env->dbpool);
+    Database *db = borrower.get();
+    return db->active(id());
+  }
+}
+
+void Session::setActive(bool a)
+{
+  if(isreadonly == false) {
+    AutoBorrower<Database*> borrower(env->dbpool);
+    Database *db = borrower.get();
+    return db->setActive(id(), a);
+  }
 }
 
 void Session::commit()
@@ -90,17 +111,19 @@ void Session::commit()
     delete _journal;
     _journal = NULL;
   }
-  if(_database != NULL) {
-    _database->commit();
-    delete _database;
-    _database = NULL;
+  if(isreadonly == false) {
+    AutoBorrower<Database*> borrower(env->dbpool);
+    Database *db = borrower.get();
+    db->commit(id());
   }
 }
 
 void Session::nocommit()
 {
-  if(_database != NULL) {
-    _database->nocommit();
+  if(isreadonly == false) {
+    AutoBorrower<Database*> borrower(env->dbpool);
+    Database *db = borrower.get();
+    db->nocommit(id());
   }
 }
 
@@ -110,10 +133,10 @@ void Session::discard()
     delete _journal;
     _journal = NULL;
   }
-  if(_database != NULL) {
-    _database->discard();
-    delete _database;
-    _database = NULL;
+  if(isreadonly == false) {
+    AutoBorrower<Database*> borrower(env->dbpool);
+    Database *db = borrower.get();
+    db->discard(id());
   }
 }
 
@@ -126,7 +149,7 @@ Journal *Session::journal()
   }
   return _journal;
 }
-
+/*
 Database *Session::database()
 {
   if(_database == NULL) {
@@ -136,8 +159,8 @@ Database *Session::database()
   }
   return _database;
 }
-
-Sessions::Sessions()
+*/
+Sessions::Sessions(Environment *e) : env(e)
 {
 }
 
@@ -168,7 +191,7 @@ Session *Sessions::newSession(std::string patientid, std::string templ)
   }
 
   { // Look up patientid / template tupple in session files.
-    SessionSerialiser ser(Conf::session_path);
+    SessionSerialiser ser(env, Conf::session_path);
     Session *session = ser.findFromTupple(patientid, templ);
     if(session) {
       sessions[session->id()] = session;
@@ -176,7 +199,7 @@ Session *Sessions::newSession(std::string patientid, std::string templ)
     }
   }
 
-  Session *session = new Session("", patientid, templ);
+  Session *session = new Session(env, "", patientid, templ);
   sessions[session->id()] = session;
   return session;
 }
@@ -188,7 +211,7 @@ Session *Sessions::session(std::string sessionid)
 
   std::string filename = getSessionFilename(Conf::session_path, sessionid);
   if(fexists(filename)) {
-    SessionSerialiser ser(Conf::session_path);
+    SessionSerialiser ser(env, Conf::session_path);
     Session *s = ser.load(sessionid);
     sessions[s->id()] = s;
     return s;
@@ -229,7 +252,7 @@ void Sessions::store()
 {
   std::map<std::string, Session*>::iterator i = sessions.begin();
   while(i != sessions.end()) {
-    SessionSerialiser ser(Conf::session_path);
+    SessionSerialiser ser(env, Conf::session_path);
     ser.save(i->second);
     delete i->second;
     sessions.erase(i);
diff --git a/server/src/session.h b/server/src/session.h
index 31dee3f..f532452 100644
--- a/server/src/session.h
+++ b/server/src/session.h
@@ -34,12 +34,13 @@
 
 #include "mutex.h"
 
-class Database;
+class Environment;
 class Journal;
 
 class Session {
 public:
-  Session(std::string sessionid, std::string patientid, std::string templ);
+  Session(Environment *env,
+          std::string sessionid, std::string patientid, std::string templ);
   ~Session();
 
   std::string id();
@@ -52,19 +53,20 @@ public:
   void discard();
 
   Journal *journal();
-  Database *database();
 
   std::string patientid;
   std::string templ;
 
   bool active();
+  void setActive(bool active);
 
   bool isreadonly;
 
 private:
+  Environment *env;
   Journal *_journal;
-  Database *_database;
   Mutex mutex;
+  std::string sessionid;
 };
 
 class Sessions {
@@ -76,7 +78,7 @@ public:
     const std::string sessionid;
   };
 
-  Sessions();
+  Sessions(Environment *env);
 
   /**
    * Create a new session, with a unique id. Insert it into the session list,
@@ -114,6 +116,7 @@ public:
 
 private:
   std::map<std::string, Session *> sessions;
+  Environment *env;
 };
 
 class SessionAutolock {
diff --git a/server/src/sessionserialiser.cc b/server/src/sessionserialiser.cc
index f2e2f39..0929a30 100644
--- a/server/src/sessionserialiser.cc
+++ b/server/src/sessionserialiser.cc
@@ -39,6 +39,8 @@
 #include "xml_encode_decode.h"
 //#include "base64.h"
 
+#include "environment.h"
+
 #include <stdio.h>
 #include <string.h>
 
@@ -58,7 +60,8 @@ static std::string itostr(int i)
   return sid;
 }
 
-SessionSerialiser::SessionSerialiser(std::string path)
+SessionSerialiser::SessionSerialiser(Environment *e, std::string path)
+ : env(e)
 {
   this->path = path;
 }
@@ -75,7 +78,8 @@ Session *SessionSerialiser::loadStr(const std::string &xml)
   SessionParser parser;
   parser.parse(xml.data(), xml.length());
 
-  Session *session = new Session(XDEC(parser.sessionid),
+  Session *session = new Session(env,
+                                 XDEC(parser.sessionid),
                                  XDEC(parser.patientid),
                                  XDEC(parser.templ));
   Journal *j = session->journal();
@@ -87,7 +91,7 @@ Session *SessionSerialiser::loadStr(const std::string &xml)
     i++;
   }
 
-  session->database()->restore(XDEC(parser.database));
+  //  session->database()->restore(XDEC(parser.database));
 
   return session;
 }
@@ -125,7 +129,7 @@ std::string SessionSerialiser::saveStr(Session *session)
 
   std::string dbtype = "pgsql";
   xml += "  <database type=\""+dbtype+"\">"+
-    XENC(session->database()->serialise())+
+    //    XENC(session->database()->serialise())+
     "</database>\n";
 
   xml += "</session>\n";
diff --git a/server/src/sessionserialiser.h b/server/src/sessionserialiser.h
index acc9ad6..a85fc63 100644
--- a/server/src/sessionserialiser.h
+++ b/server/src/sessionserialiser.h
@@ -32,9 +32,11 @@
 
 #include "session.h"
 
+class Environment;
+
 class SessionSerialiser {
 public:
-  SessionSerialiser(std::string path);
+  SessionSerialiser(Environment *e, std::string path);
 
   Session *loadStr(const std::string &xml);
   std::string saveStr(Session *session);
@@ -47,6 +49,7 @@ public:
 
 private:
   std::string path;
+  Environment *env;
 };
 
 std::string getSessionFilename(const std::string &path,
diff --git a/server/src/transactionhandler.cc b/server/src/transactionhandler.cc
index 6d0b922..32d37eb 100644
--- a/server/src/transactionhandler.cc
+++ b/server/src/transactionhandler.cc
@@ -54,9 +54,9 @@ static std::string handleCommits(Transaction &transaction, Environment &env,
   std::string answer;
 
   if(transaction.commits.size() > 0) {
-    //    AutoBorrower<Database*> borrower(env.dbpool);
-    //    Database *db = borrower.get();
-    Database *db = session.database();
+    AutoBorrower<Database*> borrower(env.dbpool);
+    Database *db = borrower.get();
+    //Database *db = session.database();
 
     Commits::iterator i = transaction.commits.begin();
     while(i != transaction.commits.end()) {
@@ -69,7 +69,7 @@ static std::string handleCommits(Transaction &transaction, Environment &env,
       std::string resume = resume_parser(*macro, commit);
       commit.fields["journal.resume"] = resume;
       session.isreadonly = false;
-      db->commitTransaction(transaction, commit, *macro);
+      db->commitTransaction(transaction, commit, *macro, session.id());
 
       if(resume != "") {
         
@@ -94,9 +94,9 @@ static std::string handleRequest(Transaction &transaction, Environment &env,
 
   if(transaction.requests.size() > 0) {
 
-    //    AutoBorrower<Database*> borrower(env.dbpool);
-    //    Database *db = borrower.get();
-    Database *db = session.database();
+    AutoBorrower<Database*> borrower(env.dbpool);
+    Database *db = borrower.get();
+    //    Database *db = session.database();
     
     Requests::iterator i = transaction.requests.begin();
     while(i != transaction.requests.end()) {
@@ -133,6 +133,7 @@ static std::string handleRequest(Transaction &transaction, Environment &env,
 
         bool completed = db->checkMacro(transaction.cpr,
                                         macro.attributes["name"],
+                                        session.id(),
                                         time(NULL)-Conf::db_max_ttl);
 
         answer += "    <macro uid=\"42\" completed=";
@@ -228,7 +229,8 @@ static std::string handleRequest(Transaction &transaction, Environment &env,
             answer += "      </scripts>\n";
           }
 
-          answer += widgetgenerator(transaction.cpr, *m, lqm, *db);
+          answer += widgetgenerator(transaction.cpr, session.id(),
+                                    *m, lqm, *db);
         } else {
           // only find macro title
           MacroParser mp(env.macrolist.getLatestVersion(macro.attributes["name"]));
@@ -246,7 +248,8 @@ static std::string handleRequest(Transaction &transaction, Environment &env,
           std::string state = "old";
           std::string resume = db->getResume(transaction.cpr,
                                              macro,
-                                             time(NULL) - Conf::db_max_ttl);
+                                             time(NULL) - Conf::db_max_ttl,
+                                             session.id());
           if(session.journal()->dirty(macro.attributes["name"])) {
             state = "dirty";
           } else {
diff --git a/server/src/widgetgenerator.cc b/server/src/widgetgenerator.cc
index aa5786d..7a39190 100644
--- a/server/src/widgetgenerator.cc
+++ b/server/src/widgetgenerator.cc
@@ -90,13 +90,14 @@ static void get_fields(Widget &widget, Fieldnames &fields)
   }
 }
 
-std::string widgetgenerator(std::string cpr, Macro &macro,
+std::string widgetgenerator(std::string cpr, std::string sessionid,
+                            Macro &macro,
                             LUAQueryMapper &mapper, Database &db)
 {
   Fieldnames fields;
   get_fields(macro.widgets, fields);
 
-  Values values = db.getValues(cpr, fields);
+  Values values = db.getValues(cpr, fields, sessionid);
   
   return getWidgetString(macro, macro.widgets, "      ", mapper, values);
 }
diff --git a/server/src/widgetgenerator.h b/server/src/widgetgenerator.h
index 17160fc..0e87cac 100644
--- a/server/src/widgetgenerator.h
+++ b/server/src/widgetgenerator.h
@@ -50,6 +50,7 @@
  * @return An std::srting containing the prettyprinted version of the Macro.
  */
 std::string widgetgenerator(std::string cpr,
+                            std::string sessionid,
                             Macro &macro,
                             LUAQueryMapper &mapper,
                             Database &db);
-- 
cgit v1.2.3