diff options
Diffstat (limited to 'server/src')
| -rw-r--r-- | server/src/admin_connection.cc | 36 | ||||
| -rw-r--r-- | server/src/admin_connection.h | 5 | ||||
| -rw-r--r-- | server/src/database.h | 44 | ||||
| -rw-r--r-- | server/src/environment.cc | 7 | ||||
| -rw-r--r-- | server/src/environment.h | 4 | ||||
| -rw-r--r-- | server/src/pracrodao.h | 1 | ||||
| -rw-r--r-- | server/src/pracrodaopgsql.cc | 21 | ||||
| -rw-r--r-- | server/src/pracrodaopgsql.h | 1 | ||||
| -rw-r--r-- | server/src/pracrodaotest.h | 1 | ||||
| -rw-r--r-- | server/src/queryhandlerpracro.cc | 2 | ||||
| -rw-r--r-- | server/src/server.cc | 2 | ||||
| -rw-r--r-- | server/src/session.cc | 71 | ||||
| -rw-r--r-- | server/src/session.h | 13 | ||||
| -rw-r--r-- | server/src/sessionserialiser.cc | 12 | ||||
| -rw-r--r-- | server/src/sessionserialiser.h | 5 | ||||
| -rw-r--r-- | server/src/transactionhandler.cc | 21 | ||||
| -rw-r--r-- | server/src/widgetgenerator.cc | 5 | ||||
| -rw-r--r-- | server/src/widgetgenerator.h | 1 | 
18 files changed, 176 insertions, 76 deletions
| 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 ¯o, +                         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 ¯o, time_t oldest) +  std::string getResume(std::string patientid, Macro ¯o, +                        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 ¯o, +std::string widgetgenerator(std::string cpr, std::string sessionid, +                            Macro ¯o,                              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 ¯o,                              LUAQueryMapper &mapper,                              Database &db); | 
