summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authordeva <deva>2011-02-04 13:34:40 +0000
committerdeva <deva>2011-02-04 13:34:40 +0000
commit6bae4fd17d2660d53279dac9287de52be2a00c6c (patch)
tree595f7aa65558735a3fc05062d39e95e88b026a51 /server
parente6a824034c742b9a414d32ecfbcc8531180f93dc (diff)
Database pool is now used instead of one connection per session. Admin interface supports session unlock.
Diffstat (limited to 'server')
-rw-r--r--server/src/admin_connection.cc36
-rw-r--r--server/src/admin_connection.h5
-rw-r--r--server/src/database.h44
-rw-r--r--server/src/environment.cc7
-rw-r--r--server/src/environment.h4
-rw-r--r--server/src/pracrodao.h1
-rw-r--r--server/src/pracrodaopgsql.cc21
-rw-r--r--server/src/pracrodaopgsql.h1
-rw-r--r--server/src/pracrodaotest.h1
-rw-r--r--server/src/queryhandlerpracro.cc2
-rw-r--r--server/src/server.cc2
-rw-r--r--server/src/session.cc71
-rw-r--r--server/src/session.h13
-rw-r--r--server/src/sessionserialiser.cc12
-rw-r--r--server/src/sessionserialiser.h5
-rw-r--r--server/src/transactionhandler.cc21
-rw-r--r--server/src/widgetgenerator.cc5
-rw-r--r--server/src/widgetgenerator.h1
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 &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);