summaryrefslogtreecommitdiff
path: root/server/src/admin_export.cc
diff options
context:
space:
mode:
authordeva <deva>2011-02-14 10:43:17 +0000
committerdeva <deva>2011-02-14 10:43:17 +0000
commitdc8cfaa08168fdd332faded2f78679a2a1904fbe (patch)
tree27d9939d1e8c57f98e819c25ae1a0021c1b97435 /server/src/admin_export.cc
parentc1f0cdeb919864e0f93fcfecb8c27d889b473acb (diff)
'Ported' export functionality from macrotool.
Diffstat (limited to 'server/src/admin_export.cc')
-rw-r--r--server/src/admin_export.cc273
1 files changed, 273 insertions, 0 deletions
diff --git a/server/src/admin_export.cc b/server/src/admin_export.cc
new file mode 100644
index 0000000..9475bc3
--- /dev/null
+++ b/server/src/admin_export.cc
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * admin_export.cc
+ *
+ * Fri Feb 11 11:43:13 CET 2011
+ * Copyright 2011 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 "admin_export.h"
+
+#include <config.h>
+#include <stdio.h>
+#include "debug.h"
+
+#ifndef WITHOUT_DB
+
+#include <stdlib.h>
+#include <pqxx/pqxx>
+
+#include "macrotool/fieldnamescanner.h"
+#include "configuration.h"
+
+#define SEP "\t"
+
+static std::string escape(std::string &str)
+{
+ std::string out = "\"";
+ std::string::iterator i = str.begin();
+ while(i != str.end()) {
+ if(*i == '\"') out += "''";
+ else out += *i;
+ i++;
+ }
+ out += "\"";
+ return out;
+}
+
+class File {
+public:
+ File(fieldnames_t &f, pqxx::work &w)
+ : work(w), fieldnames(f)
+ {
+ // name += ".csf";
+ // fp = fopen(name.c_str(), "w");
+
+ pos["id"] = 0;
+ pos["patientid"] = 1;
+ pos["time"] = 2;
+ pos["template"] = 3;
+
+ //printf("%s\n", n.c_str());
+
+ size_t idx = 4;
+ fieldnames_t::iterator i = f.begin();
+ while(i != f.end()) {
+ //printf("%s ", i->c_str());
+ pos[*i] = idx;
+ idx++;
+ i++;
+ }
+ // printf("\n");
+
+ output_header();
+ }
+
+ ~File()
+ {
+ // if(fp) fclose(fp);
+ }
+
+ void output_header()
+ {
+ beginrow();
+ addcell("id", "ID");
+ addcell("patientid", "Patient");
+ addcell("time", "Time");
+ addcell("template", "Template");
+
+ {
+ pqxx::result result =
+ work.exec("SELECT DISTINCT ON(name) name, caption FROM fieldnames"
+ " WHERE extract='true';");
+ pqxx::result::const_iterator ri = result.begin();
+ for(unsigned int r = 0; r < result.size(); r++) {
+ pqxx::result::tuple tuple = result.at(r);
+ std::string name = tuple.at(0).c_str();
+ std::string caption = tuple.at(1).c_str();
+ addcell(name, caption);
+ }
+ }
+
+ endrow();
+ }
+
+ void beginrow()
+ {
+ cells.clear();
+ cells.insert(cells.begin(), pos.size(), "");
+ }
+
+ void addcell(std::string key, std::string value)
+ {
+ if(pos.find(key) == pos.end()) return;
+ cells[pos[key]] = value;
+ }
+
+ void endrow()
+ {
+ std::vector<std::string>::iterator i = cells.begin();
+ while(i != cells.end()) {
+ result += escape(*i) + SEP;
+ i++;
+ }
+ result += "\n";
+ }
+
+ std::string result;
+
+private:
+ pqxx::work &work;
+ std::map<std::string, int> pos;
+ std::vector<std::string> cells;
+ std::string name;
+ fieldnames_t &fieldnames;
+};
+
+
+static std::string do_export(std::string templ, bool *ok)
+{
+ if(Conf::database_backend != "pgsql") {
+ *ok = false;
+ return "ERROR: Export only available for the pgsql database backend.\n";
+ }
+
+ std::string host = Conf::database_addr;
+ std::string port = "";//Conf::database_port;
+ std::string user = Conf::database_user;;
+ std::string passwd = Conf::database_passwd;
+ std::string dbname = "";//Conf::database_database;
+
+ std::string cs;
+ if(host.size()) cs += " host=" + host;
+ if(port.size()) cs += " port=" + port;
+ if(user.size()) cs += " user=" + user;
+ if(passwd.size()) cs += " password=" + passwd;
+ cs += " dbname=" + (dbname.size() ? dbname : "pracro");
+
+ pqxx::connection conn(cs);
+ pqxx::work work(conn);
+
+ std::set<std::string> filter;
+
+ {
+ pqxx::result result =
+ work.exec("SELECT DISTINCT name FROM fieldnames"
+ " WHERE extract='true';");
+ pqxx::result::const_iterator ri = result.begin();
+ for(unsigned int r = 0; r < result.size(); r++) {
+ pqxx::result::tuple tuple = result.at(r);
+ std::string name = tuple.at(0).c_str();
+ filter.insert(name);
+ //printf("filter: '%s'\n", name.c_str());
+ }
+ }
+
+ templates_t t = scanfieldnames(filter);
+ /*
+ templates_t::iterator ti = t.begin();
+ while(ti != t.end()) {
+ printf("%s\n", ti->first.c_str());
+ fieldnames_t::iterator fi = ti->second.begin();
+ while(fi != ti->second.end()) {
+ printf("\t%s\n", (*fi).c_str());
+ fi++;
+ }
+ ti++;
+ }
+ */
+
+ File file(t[templ], work);
+
+ {
+ pqxx::result result =
+ work.exec("SELECT * FROM commits WHERE template='"+templ+"'"
+ " AND status='committed' ORDER BY patientid, timestamp;");
+ pqxx::result::const_iterator ri = result.begin();
+ for(unsigned int r = 0; r < result.size(); r++) {
+ pqxx::result::tuple tuple = result.at(r);
+ std::string patientid = tuple.at(0).c_str();
+ std::string templ = tuple.at(1).c_str();
+ std::string version = tuple.at(2).c_str();
+ std::string timestamp = tuple.at(3).c_str();
+ std::string uid = tuple.at(4).c_str();
+ std::string status = tuple.at(5).c_str();
+
+ file.beginrow();
+ file.addcell("id", uid);
+ file.addcell("patientid", patientid);
+ file.addcell("template", templ);
+ time_t t = atol(timestamp.c_str());
+ std::string timestr = ctime(&t);
+ if(timestr[timestr.size() - 1] == '\n')
+ timestr = timestr.substr(0, timestr.size() - 1);
+ file.addcell("time", timestr.c_str());
+
+ DEBUG(export, "%s %s %s\n",
+ timestamp.c_str(), patientid.c_str(), templ.c_str());
+
+ {
+ pqxx::result result =
+ work.exec("SELECT f.name, f.value"
+ " FROM transactions t, fields f, fieldnames n"
+ " WHERE t.cid='"+uid+"' AND f.transaction=t.uid"
+ " AND f.name=n.name AND n.extract='true'"
+ " ORDER BY t.timestamp;");
+ pqxx::result::const_iterator ri = result.begin();
+ for(unsigned int r = 0; r < result.size(); r++) {
+ pqxx::result::tuple tuple = result.at(r);
+ std::string name = tuple.at(0).c_str();
+ std::string value = tuple.at(1).c_str();
+
+ file.addcell(name, value);
+
+ }
+ }
+
+ file.endrow();
+ }
+ }
+
+ *ok = true;
+ return file.result;
+}
+
+#endif/* WITHOUT_DB */
+
+std::string admin_export(Environment &env, std::string templ, bool *ok)
+{
+ return do_export(templ, ok);
+}
+
+#ifdef TEST_ADMIN_EXPORT
+//deps:
+//cflags:
+//libs:
+#include "test.h"
+
+TEST_BEGIN;
+
+// TODO: Put some testcode here (see test.h for usable macros).
+
+TEST_END;
+
+#endif/*TEST_ADMIN_EXPORT*/