From d35bafeec39b6688a8dd07c51ea304e348b10fa2 Mon Sep 17 00:00:00 2001 From: deva Date: Fri, 7 Aug 2009 11:27:18 +0000 Subject: Added new testdb, that can be activated through the cli (-d testdb) or through the config file (database_backend = testdb) . --- server/src/pracrodaotest.cc | 336 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 server/src/pracrodaotest.cc (limited to 'server/src/pracrodaotest.cc') diff --git a/server/src/pracrodaotest.cc b/server/src/pracrodaotest.cc new file mode 100644 index 0000000..c084e5b --- /dev/null +++ b/server/src/pracrodaotest.cc @@ -0,0 +1,336 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * pracrodaotest.cc + * + * Fri Aug 7 10:25:07 CEST 2009 + * Copyright 2009 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 "pracrodaotest.h" + +#include +#include + +#include "debug.h" + +PracroDAOTest::PracroDAOTest(Data &data, bool ignore_fieldnames) + : PracroDAO("", "", "", "", "") +{ + this->data = data; + this->ignore_fieldnames = ignore_fieldnames; + PRACRO_DEBUG(db, "New test (memory only) database\n"); +} + +PracroDAOTest::~PracroDAOTest() +{ + PRACRO_DEBUG(db, "Delete test (memory only) database\n"); +} + +void PracroDAOTest::commitTransaction(std::string user, std::string patientid, + Macro &_macro, Fields &fields, time_t now) +{ + PRACRO_DEBUG(db, "(%s, %s, %s, <%u fields>, %ld)\n", + user.c_str(), + patientid.c_str(), + _macro.attributes["name"].c_str(), + fields.size(), + now); + if(fields.size() == 0) return; + + std::string version = _macro.attributes["version"]; + std::string macro = _macro.attributes["name"]; + std::stringstream timestamp; timestamp << now; + + dbrow_t t; + t["uid"] = data.trseq.nextval(); + t["patientid"] = patientid; + t["macro"] = macro; + t["version"] = version; + t["timestamp"] = timestamp.str(); + t["user"] = user; + data.transactions.push_back(t); + + // Iterate fields... + Fields::iterator fi = fields.begin(); + while(fi != fields.end()) { + + if(ignore_fieldnames == false) { + // Search for it in fieldnames table + dbtable_t::iterator ti = data.fieldnames.begin(); + while(ti != data.fieldnames.end()) { + + // If found, insert the field values into the fields table. + if(fi->first == (*ti)["name"]) { + + dbrow_t f; + f["transaction"] = data.trseq.currval(); + f["name"] = fi->first; + f["value"] = fi->second; + data.fields.push_back(f); + + } + + ti++; + } + } else { + dbrow_t f; + f["transaction"] = data.trseq.currval(); + f["name"] = fi->first; + f["value"] = fi->second; + data.fields.push_back(f); + } + + fi++; + } +} + +Values PracroDAOTest::getLatestValues(std::string patientid, Macro *macro, + Fieldnames &fieldnames, time_t oldest) +{ + PRACRO_DEBUG(db, "(%s, %s, <%u fieldnames>, %ld)\n", + patientid.c_str(), + macro ? macro->attributes["name"].c_str() : "(null)", fieldnames.size(), + oldest); + Values values; + + // TODO: Take Macro* into account. If supplied (not NULL) the macro name, and + // optionally version number should match the transaction. + + Fieldnames::iterator fi = fieldnames.begin(); + while(fi != fieldnames.end()) { + std::string fieldname = *fi; + + // Find matching transactions + dbtable_t::iterator ti = data.transactions.begin(); + while(ti != data.transactions.end()) { + std::map &transaction = *ti; + time_t timestamp = atol(transaction["timestamp"].c_str()); + if(transaction["patientid"] == patientid && timestamp >= oldest) { + std::string tid = transaction["uid"]; + + // Find transaction values + dbtable_t::iterator vi = data.fields.begin(); + while(vi != data.fields.end()) { + std::map &field = *vi; + + // Upon match, insert it into values + if(field["transaction"] == tid && field["name"] == fieldname) { + if(values.find(fieldname) == values.end() || values[fieldname].timestamp < timestamp) { + values[fieldname].timestamp = timestamp; + values[fieldname].value = field["value"]; + values[fieldname].source = "testdb"; + } + } + vi++; + } + + } + ti++; + } + + fi++; + } + + return values; +} + + +unsigned PracroDAOTest::nrOfCommits(std::string patientid, std::string macroname, time_t oldest) +{ + unsigned num = 0; + + // Find and count matching transactions + dbtable_t::iterator ti = data.transactions.begin(); + while(ti != data.transactions.end()) { + std::map &transaction = *ti; + time_t timestamp = atol(transaction["timestamp"].c_str()); + if(transaction["patientid"] == patientid && + transaction["macro"] == macroname && + timestamp >= oldest) { + num++; + } + ti++; + } + + return num; +} + +void PracroDAOTest::addFieldname(std::string name, std::string description) +{ + // TODO + + /* + std::stringstream timestamp; timestamp << time(NULL); + std::string ts; + try { + pqxx::work W(*conn); + ts = "INSERT INTO fieldnames (name, description, \"timestamp\") VALUES (" + " '" + W.esc(name) + "', " + " '" + W.esc(description) + "', " + " '" + W.esc(timestamp.str()) + "' " + ")" + ; + PRACRO_DEBUG(sql, "Query: %s\n", ts.c_str()); + pqxx::result R = W.exec(ts); + W.commit(); + } catch (std::exception &e) { + PRACRO_ERR_LOG(db, "Query failed: %s: %s\n", e.what(), ts.c_str()); + } + */ +} + +void PracroDAOTest::delFieldname(std::string name) +{ + // TODO + + /* + std::string ts; + try { + pqxx::work W(*conn); + ts = "DELETE FROM fieldnames WHERE name=" + "'" + W.esc(name) + "' "; + PRACRO_DEBUG(sql, "Query: %s\n", ts.c_str()); + pqxx::result R = W.exec(ts); + W.commit(); + } catch (std::exception &e) { + PRACRO_ERR_LOG(db, "Query failed: %s: %s\n", e.what(), ts.c_str()); + } + */ +} + +std::vector PracroDAOTest::getFieldnames() +{ + // TODO + + std::vector fieldnames; + /* + std::string query; + try { + pqxx::work W(*conn); + query = "SELECT * FROM fieldnames"; + PRACRO_DEBUG(sql, "Query: %s\n", query.c_str()); + pqxx::result R = W.exec(query); + pqxx::result::const_iterator ri = R.begin(); + while(ri != R.end()) { + Fieldname f; + f.name = (*ri)[0].c_str(); + f.description = (*ri)[1].c_str(); + f.timestamp = atol((*ri)[2].c_str()); + fieldnames.push_back(f); + ri++; + } + } catch (std::exception &e) { + PRACRO_ERR_LOG(db, "Query failed: %s: %s\n", e.what(), query.c_str()); + } + */ + return fieldnames; +} + + + + +#ifdef TEST_PRACRODAOTEST + +#define PATIENTID "1234567890" + +int main() +{ + time_t now = time(NULL); + + Data data; + + // Add some fieldnames + dbrow_t f; + f["name"] = "field1"; data.fieldnames.push_back(f); + f["name"] = "field2"; data.fieldnames.push_back(f); + f["name"] = "field3"; data.fieldnames.push_back(f); + + PracroDAOTest db(data); + + // Make a commit + Macro macro; + macro.attributes["version"] = "1.0"; + macro.attributes["name"] = "testmacro"; + + Fields fields; + fields["field1"] = "testval1"; + fields["field2"] = "testval2"; + fields["field3"] = "testval3"; + fields["field4"] = "testval4"; + db.commitTransaction("testuser", PATIENTID, macro, fields, now); + + // Retrieve the data again + unsigned num = db.nrOfCommits(PATIENTID, "testmacro", now); + if(num != 1) return 1; + + Fieldnames fieldnames; + fieldnames.push_back("field1"); + fieldnames.push_back("field2"); + fieldnames.push_back("field3"); + fieldnames.push_back("field4"); + Values values = db.getLatestValues(PATIENTID, NULL, fieldnames, now); + + Values::iterator i = values.begin(); + while(i != values.end()) { + printf("%s => %s\n", i->first.c_str(), i->second.value.c_str()); + i++; + } + if(values["field1"].value != "testval1") return 1; + if(values["field2"].value != "testval2") return 1; + if(values["field3"].value != "testval3") return 1; + + // This value was not committed, since it wasn't in the fieldnames table. + if(values.find("field4") != values.end()) return 1; + + // Make another commit (one second later) + fields["field1"] = "testval1-2"; + fields["field2"] = "testval2-2"; + fields["field3"] = "testval3-2"; + fields["field4"] = "testval4-2"; + db.commitTransaction("testuser", PATIENTID, macro, fields, now+1); + + // Retrieve the data again + num = db.nrOfCommits(PATIENTID, "testmacro", now); + if(num != 2) return 1; + + fieldnames.push_back("field1"); + fieldnames.push_back("field2"); + fieldnames.push_back("field3"); + fieldnames.push_back("field4"); + values = db.getLatestValues(PATIENTID, NULL, fieldnames, now); + + i = values.begin(); + while(i != values.end()) { + printf("%s => %s\n", i->first.c_str(), i->second.value.c_str()); + i++; + } + if(values["field1"].value != "testval1-2") return 1; + if(values["field2"].value != "testval2-2") return 1; + if(values["field3"].value != "testval3-2") return 1; + + // This value was not committed, since it wasn't in the fieldnames table. + if(values.find("field4") != values.end()) return 1; + + return 0; +} + +#endif/*TEST_PRACRODAOTEST*/ -- cgit v1.2.3