/* -*- 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*/