From eab5027694025e34b9ed0ad44f22a2db3e89feda Mon Sep 17 00:00:00 2001 From: deva Date: Thu, 17 Feb 2011 15:03:46 +0000 Subject: Finished implementation of new database layout in testdb. --- server/src/database.cc | 6 +- server/src/pracrodaotest.cc | 391 ++++++++++++++++++++++++-------------------- server/src/pracrodaotest.h | 2 +- 3 files changed, 214 insertions(+), 185 deletions(-) diff --git a/server/src/database.cc b/server/src/database.cc index 81b495f..27e903f 100644 --- a/server/src/database.cc +++ b/server/src/database.cc @@ -34,7 +34,8 @@ #include "pracrodaopgsql.h" #include "pracrodaotest.h" -Database::Database(std::string _backend, std::string _host, std::string _port, std::string _user, std::string _passwd, std::string _dbname) +Database::Database(std::string _backend, std::string _host, std::string _port, + std::string _user, std::string _passwd, std::string _dbname) { dao = NULL; #ifndef WITHOUT_DB @@ -48,8 +49,7 @@ Database::Database(std::string _backend, std::string _host, std::string _port, s #endif/*WITHOUT_DB*/ if(_backend == "testdb") { DEBUG(db, "Running with 'testdb'\n"); - Data data; - dao = new PracroDAOTest(data, true); + dao = new PracroDAOTest(true); return; } diff --git a/server/src/pracrodaotest.cc b/server/src/pracrodaotest.cc index efd94f6..dd62016 100644 --- a/server/src/pracrodaotest.cc +++ b/server/src/pracrodaotest.cc @@ -32,10 +32,23 @@ #include "debug.h" -PracroDAOTest::PracroDAOTest(Data &data, bool ignore_fieldnames) +static dbtable_t::iterator select(dbtable_t &table, + std::string key, std::string value) +{ + dbtable_t::iterator i = table.begin(); + while(i != table.end()) { + dbrow_t &r = *i; + if(r.find(key) != r.end() && r[key] == value) return i; + i++; + } + + return i; +} + + +PracroDAOTest::PracroDAOTest(bool ignore_fieldnames) : PracroDAO("", "", "", "", "") { - this->data = data; this->ignore_fieldnames = ignore_fieldnames; DEBUG(db, "New test (memory only) database\n"); } @@ -68,17 +81,10 @@ void PracroDAOTest::commitTransaction(std::string sessionid, std::string macro = _macro.attributes["name"]; std::stringstream timestamp; timestamp << now; - dbtable_t::iterator ci = data.commits.begin(); - while(ci != data.commits.end()) { - dbrow_t &c = *ci; - if(c["uid"] == sessionid) { - break; - } - ci++; - } + dbtable_t::iterator ci = select(data.commits, "uid", sessionid); if(ci == data.commits.end()) { - DEBUG(testdb, "Create new commit: %s", sessionid.c_str()); + DEBUG(db, "Create new commit: %s\n", sessionid.c_str()); dbrow_t c; c["patientid"] = transaction.cpr; c["template"] = commit.templ; @@ -87,77 +93,56 @@ void PracroDAOTest::commitTransaction(std::string sessionid, c["uid"] = sessionid; c["status"] = "active"; data.commits.push_back(c); + ci = select(data.commits, "uid", sessionid);//data.commits.rbegin(); } else { dbrow_t &c = *ci; if(c["status"] == "committed") { - ERR_LOG(db, "Attempt to add to committed session %s blocked!\n", + ERR_LOG(db, "Attempt to resume committed session %s blocked!\n", sessionid.c_str()); return; } - DEBUG(testdb, "Working on old commit: %s", sessionid.c_str()); + DEBUG(db, "Resuming commit: %s\n", sessionid.c_str()); c["status"] = "active"; } - - - - - - - - - - - - - - - - - - - - + dbrow_t &c = *ci; dbrow_t t; t["uid"] = data.trseq.nextval(); - t["patientid"] = transaction.cpr; - t["template"] = commit.templ; t["macro"] = macro; t["version"] = version; t["timestamp"] = timestamp.str(); t["user"] = transaction.user; + t["cid"] = c["uid"]; data.transactions.push_back(t); // Iterate fields... Fields::iterator fi = commit.fields.begin(); while(fi != commit.fields.end()) { - + std::string key = fi->first; + std::string value = fi->second; + 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); + + dbtable_t::iterator fni = select(data.fieldnames, "name", key); + if(fni != data.fieldnames.end()) { + dbrow_t f; + f["transaction"] = data.trseq.currval(); + f["name"] = key; + f["value"] = value; + data.fields.push_back(f); - } - - ti++; } + } else { + dbrow_t f; f["transaction"] = data.trseq.currval(); - f["name"] = fi->first; - f["value"] = fi->second; + f["name"] = key; + f["value"] = value; data.fields.push_back(f); + } fi++; @@ -179,43 +164,55 @@ Values PracroDAOTest::getLatestValues(std::string sessionid, while(fi != fieldnames.end()) { std::string fieldname = *fi; - // Find matching transactions - dbtable_t::iterator ti = data.transactions.begin(); - while(ti != data.transactions.end()) { - dbrow_t &transaction = *ti; - time_t timestamp = atol(transaction["timestamp"].c_str()); - if(transaction["patientid"] == patientid && timestamp >= oldest && - (transaction["macro"] == macro_name || macro == NULL)) { - std::string tid = transaction["uid"]; - - // Find transaction values - dbtable_t::iterator vi = data.fields.begin(); - while(vi != data.fields.end()) { - dbrow_t &field = *vi; + dbtable_t::iterator ci = data.commits.begin(); + while(ci != data.commits.end()) { + dbrow_t &c = *ci; + + if(c["status"] == "committed" || + (c["status"] != "committed" && c["uid"] == sessionid)) { + + // Find matching transactions + dbtable_t::iterator ti = data.transactions.begin(); + while(ti != data.transactions.end()) { + dbrow_t &t = *ti; + + time_t timestamp = atol(t["timestamp"].c_str()); - // 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"; + if(t["cid"] == c["uid"] && timestamp >= oldest && + (t["macro"] == macro_name || macro == NULL)) { + + std::string tid = t["uid"]; + + // Find transaction values + dbtable_t::iterator vi = data.fields.begin(); + while(vi != data.fields.end()) { + dbrow_t &f = *vi; + + // Upon match, insert it into values + if(f["transaction"] == tid && f["name"] == fieldname) { + if(values.find(fieldname) == values.end() || + values[fieldname].timestamp < timestamp) { + + values[fieldname].timestamp = timestamp; + values[fieldname].value = f["value"]; + values[fieldname].source = "testdb"; + } + } + + vi++; } } - vi++; + ti++; } - } - ti++; + ci++; } - fi++; } return values; } - unsigned PracroDAOTest::nrOfCommits(std::string sessionid, std::string patientid, std::string macroname, @@ -223,17 +220,22 @@ unsigned PracroDAOTest::nrOfCommits(std::string sessionid, { unsigned num = 0; - // Find and count matching transactions - dbtable_t::iterator ti = data.transactions.begin(); - while(ti != data.transactions.end()) { - dbrow_t &transaction = *ti; - time_t timestamp = atol(transaction["timestamp"].c_str()); - if(transaction["patientid"] == patientid && - transaction["macro"] == macroname && - timestamp >= oldest) { - num++; + dbtable_t::iterator ci = data.commits.begin(); + while(ci != data.commits.end()) { + dbrow_t &c = *ci; + time_t timestamp = atol(c["timestamp"].c_str()); + std::string cid = c["uid"]; + if(c["patientid"] == patientid && timestamp >= oldest) { + + dbtable_t::iterator ti = data.transactions.begin(); + while(ti != data.transactions.end()) { + dbrow_t &t = *ti; + if(t["cid"] == cid && t["macro"] == macroname) num++; + ti++; + } + } - ti++; + ci++; } return num; @@ -252,15 +254,8 @@ void PracroDAOTest::addFieldname(std::string name, std::string description) void PracroDAOTest::delFieldname(std::string name) { - dbtable_t::iterator i = data.fieldnames.begin(); - while(i != data.fieldnames.end()) { - dbrow_t &row = *i; - if(row["name"] == name) { - data.fieldnames.erase(i); - return; - } - i++; - } + dbtable_t::iterator i = select(data.fieldnames, "name", name); + if(i != data.fieldnames.end()) data.fieldnames.erase(i); } std::vector PracroDAOTest::getFieldnames() @@ -283,13 +278,10 @@ std::vector PracroDAOTest::getFieldnames() bool PracroDAOTest::idle(std::string sessionid) { - dbtable_t::iterator i = data.commits.begin(); - while(i != data.commits.end()) { + dbtable_t::iterator i = select(data.commits, "uid", sessionid); + if(i != data.commits.end()) { dbrow_t &commit = *i; - if(commit["uid"] == sessionid) { - return commit["status"] == "idle"; - } - i++; + return commit["status"] == "idle"; } return false; @@ -297,52 +289,45 @@ bool PracroDAOTest::idle(std::string sessionid) void PracroDAOTest::setIdle(std::string sessionid, bool idle) { - dbtable_t::iterator i = data.commits.begin(); - while(i != data.commits.end()) { + dbtable_t::iterator i = select(data.commits, "uid", sessionid); + if(i != data.commits.end()) { dbrow_t &commit = *i; - if(commit["uid"] == sessionid && commit["status"] != "committed") { + if(commit["status"] != "committed") { commit["status"] = idle?"idle":"active"; } - i++; } } void PracroDAOTest::commit(std::string sessionid) { - dbtable_t::iterator i = data.commits.begin(); - while(i != data.commits.end()) { + dbtable_t::iterator i = select(data.commits, "uid", sessionid); + if(i != data.commits.end()) { dbrow_t &commit = *i; - if(commit["uid"] == sessionid && commit["status"] != "committed") { + if(commit["status"] != "committed") { commit["status"] = "committed"; - return; } - i++; } } void PracroDAOTest::nocommit(std::string sessionid) { - dbtable_t::iterator i = data.commits.begin(); - while(i != data.commits.end()) { + dbtable_t::iterator i = select(data.commits, "uid", sessionid); + if(i != data.commits.end()) { dbrow_t &commit = *i; - if(commit["uid"] == sessionid && commit["status"] != "committed") { + if(commit["status"] != "committed") { commit["status"] = "idle"; - return; } - i++; } } void PracroDAOTest::discard(std::string sessionid) { - dbtable_t::iterator i = data.commits.begin(); - while(i != data.commits.end()) { + dbtable_t::iterator i = select(data.commits, "uid", sessionid); + if(i != data.commits.end()) { dbrow_t &commit = *i; - if(commit["uid"] == sessionid && commit["status"] != "committed") { + if(commit["status"] != "committed") { data.commits.erase(i); - return; } - i++; } } @@ -374,8 +359,7 @@ TEST_BEGIN; debug_parse("+all"); -Data data; -PracroDAOTest db(data); +PracroDAOTest db; db.addFieldname("field1", "desc1"); db.addFieldname("field2", "desc2"); @@ -458,83 +442,128 @@ TEST_NOTEQUAL(vals.find("field1"), vals.end(), "find value"); TEST_FALSE(db.idle("no such session"), "Missing session is not idle."); -/* - time_t now = time(NULL); +{ + Commit commit; + commit.templ = "tester"; + + std::string sid = db.newSessionId(); + + commit.fields["field1"] = "hello"; + commit.fields["field2"] = "world"; + db.commitTransaction(sid, transaction, commit, macro, now + 1); - Data data; + commit.fields["field1"] = "hello2"; + commit.fields["field2"] = "world2"; + db.commitTransaction(sid, transaction, commit, macro, now + 2); - // 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); + Fieldnames fieldnames; + fieldnames.push_back("field1"); + fieldnames.push_back("field2"); + Values vals = db.getLatestValues(sid, PATIENTID, ¯o, fieldnames, 0); + TEST_EQUAL_STR(vals["field1"].value, "hello2", "Latest one only please"); + TEST_EQUAL_STR(vals["field2"].value, "world2", "Latest one only please"); +} - PracroDAOTest db(data); +{ + Commit commit; + commit.templ = "tester"; - // Make a commit - Macro macro; - macro.attributes["version"] = "1.0"; - macro.attributes["name"] = "testmacro"; + std::string sid = db.newSessionId(); - Fields fields; - fields["field1"] = "testval1"; - fields["field2"] = "testval2"; - fields["field3"] = "testval3"; - fields["field4"] = "testval4"; - db.commitTransaction("testuser", PATIENTID, macro, fields, now); + commit.fields["field1"] = "hello1"; + commit.fields["field2"] = "world1"; + db.commitTransaction(sid, transaction, commit, macro, now + 4); - // Retrieve the data again - unsigned num = db.nrOfCommits(PATIENTID, "testmacro", now); - if(num != 1) return 1; + commit.fields["field1"] = "hello2"; + commit.fields["field2"] = "world2"; + db.commitTransaction(sid, transaction, commit, macro, now + 3); 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 vals = db.getLatestValues(sid, PATIENTID, ¯o, fieldnames, 0); + TEST_EQUAL_STR(vals["field1"].value, "hello1", "Latest one only please"); + TEST_EQUAL_STR(vals["field2"].value, "world1", "Latest one only please"); +} - 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; +{ + Commit commit; + commit.templ = "tester"; - // This value was not committed, since it wasn't in the fieldnames table. - if(values.find("field4") != values.end()) return 1; + std::string sid = db.newSessionId(); + + commit.fields["field1"] = "hello3"; + commit.fields["field2"] = "world3"; + db.commitTransaction(sid, transaction, commit, macro, now + 5); - // 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); + db.commit(sid); - // Retrieve the data again - num = db.nrOfCommits(PATIENTID, "testmacro", now); - if(num != 2) return 1; + commit.fields["field1"] = "hello4"; + commit.fields["field2"] = "world4"; + db.commitTransaction(sid, transaction, commit, macro, now + 6); + Fieldnames fieldnames; fieldnames.push_back("field1"); fieldnames.push_back("field2"); - fieldnames.push_back("field3"); - fieldnames.push_back("field4"); - values = db.getLatestValues(PATIENTID, NULL, fieldnames, now); + Values vals = db.getLatestValues(sid, PATIENTID, ¯o, fieldnames, 0); + TEST_EQUAL_STR(vals["field1"].value, "hello3", "Latest one only please"); + TEST_EQUAL_STR(vals["field2"].value, "world3", "Latest one only please"); +} - i = values.begin(); - while(i != values.end()) { - printf("%s => %s\n", i->first.c_str(), i->second.value.c_str()); - i++; +{ // Only see values if they are from your own session or committed. + Commit commit; + commit.templ = "tester"; + + std::string sid1 = db.newSessionId(); + std::string sid2 = db.newSessionId(); + + commit.fields["field1"] = "hello1"; + commit.fields["field2"] = "world1"; + db.commitTransaction(sid1, transaction, commit, macro, now + 7); + + commit.fields["field1"] = "hello2"; + commit.fields["field2"] = "world2"; + db.commitTransaction(sid2, transaction, commit, macro, now + 6); + + Fieldnames fieldnames; + fieldnames.push_back("field1"); + fieldnames.push_back("field2"); + { + Values vals = db.getLatestValues(sid2, PATIENTID, ¯o, fieldnames, 0); + TEST_EQUAL_STR(vals["field1"].value, "hello2", "Latest one only please"); + TEST_EQUAL_STR(vals["field2"].value, "world2", "Latest one only please"); + } + + db.commit(sid1); + + { + Values vals = db.getLatestValues(sid2, PATIENTID, ¯o, fieldnames, 0); + TEST_EQUAL_STR(vals["field1"].value, "hello1", "Latest one only please"); + TEST_EQUAL_STR(vals["field2"].value, "world1", "Latest one only please"); } - if(values["field1"].value != "testval1-2") return 1; - if(values["field2"].value != "testval2-2") return 1; - if(values["field3"].value != "testval3-2") return 1; +} + +{ + PracroDAOTest db(true); + + Commit commit; + commit.templ = "tester"; + + std::string sid = db.newSessionId(); + + commit.fields["foo"] = "hello"; + commit.fields["bar"] = "world"; + db.commitTransaction(sid, transaction, commit, macro, now); + + Fieldnames fieldnames; + fieldnames.push_back("foo"); + fieldnames.push_back("bar"); + Values vals = db.getLatestValues(sid, PATIENTID, ¯o, fieldnames, 0); + TEST_EQUAL_STR(vals["foo"].value, "hello", "Latest one only please"); + TEST_EQUAL_STR(vals["bar"].value, "world", "Latest one only please"); +} + - // This value was not committed, since it wasn't in the fieldnames table. - if(values.find("field4") != values.end()) return 1; -*/ TEST_END; #endif/*TEST_PRACRODAOTEST*/ diff --git a/server/src/pracrodaotest.h b/server/src/pracrodaotest.h index ac7ea2e..3419978 100644 --- a/server/src/pracrodaotest.h +++ b/server/src/pracrodaotest.h @@ -77,7 +77,7 @@ public: class PracroDAOTest : public PracroDAO { public: - PracroDAOTest(Data &data, bool ignore_fieldnames = false); + PracroDAOTest(bool ignore_fieldnames = false); ~PracroDAOTest(); std::string newSessionId(); -- cgit v1.2.3