From 23f39df8b8edeacfa5821050abbdc855acb2edd6 Mon Sep 17 00:00:00 2001 From: deva Date: Fri, 1 Jul 2011 11:54:26 +0000 Subject: removed macrotool. add lua wrapper for praxisd. new type attributes_t for sax parser and children. make macros/templates use real vars instead of var map. add data ttl on macro level. add 'important' attribute to macrotags in templates. --- server/configure.in | 1 - server/src/Makefile.am | 4 +- server/src/database.h | 8 +- server/src/fieldnamescanner.cc | 2 +- server/src/journal.cc | 8 +- server/src/luapraxisd.cc | 241 ++++++++++++++++++++++++++++++++++++ server/src/luapraxisd.h | 35 ++++++ server/src/luaresume.cc | 3 + server/src/macroheaderparser.cc | 6 +- server/src/macroheaderparser.h | 2 +- server/src/macrolist.cc | 4 +- server/src/macroparser.cc | 21 ++-- server/src/macroparser.h | 2 +- server/src/macrotool/dump.cc | 20 ++- server/src/macrotool/filehandler.cc | 11 +- server/src/pracrodaopgsql.cc | 26 ++-- server/src/pracrodaotest.cc | 8 +- server/src/praxisd.cc | 41 +++--- server/src/queryparser.cc | 14 +-- server/src/queryparser.h | 2 +- server/src/saxparser.cc | 22 +++- server/src/saxparser.h | 44 ++++--- server/src/sessionparser.cc | 23 ++-- server/src/sessionparser.h | 3 +- server/src/template.h | 25 +++- server/src/templateheaderparser.cc | 8 +- server/src/templateheaderparser.h | 2 +- server/src/templatelist.cc | 4 +- server/src/templateparser.cc | 23 +++- server/src/templateparser.h | 2 +- server/src/transactionhandler.cc | 57 +++++---- server/src/transactionparser.cc | 26 ++-- server/src/transactionparser.h | 2 +- server/src/widgetgenerator.cc | 6 +- server/src/widgetgenerator.h | 2 +- server/xml/courses/test.xml | 4 + 36 files changed, 533 insertions(+), 179 deletions(-) create mode 100644 server/src/luapraxisd.cc create mode 100644 server/src/luapraxisd.h create mode 100644 server/xml/courses/test.xml diff --git a/server/configure.in b/server/configure.in index 068d8c0..fcab921 100644 --- a/server/configure.in +++ b/server/configure.in @@ -246,7 +246,6 @@ AC_SUBST(PTHREAD_LIBS) AC_OUTPUT( Makefile src/Makefile - src/macrotool/Makefile getdata/Makefile gentoo/init.d/Makefile gentoo/init.d/pracrod diff --git a/server/src/Makefile.am b/server/src/Makefile.am index ccbc63b..2697fed 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = macrotool +SUBDIRS = bin_PROGRAMS = pracrod @@ -34,6 +34,7 @@ pracrod_SOURCES = \ journal.cc \ journal_uploadserver.cc \ log.cc \ + luapraxisd.cc \ luaquerymapper.cc \ luaresume.cc \ luautil.cc \ @@ -92,6 +93,7 @@ EXTRA_DIST = \ journal.h \ journal_uploadserver.h \ log.h \ + luapraxisd.h \ luaquerymapper.h \ luaresume.h \ luautil.h \ diff --git a/server/src/database.h b/server/src/database.h index 8876ae7..27169fe 100644 --- a/server/src/database.h +++ b/server/src/database.h @@ -67,7 +67,7 @@ public: mutex.lock(); DEBUG(db, "%s, %s, %s,...\n", transaction.user.c_str(), transaction.cpr.c_str(), - macro.attributes["name"].c_str()); + macro.name.c_str()); dao->commitTransaction(sessionid, transaction, commit, macro, now); mutex.unlock(); } @@ -76,7 +76,7 @@ public: Values getValues(std::string patientid, Fieldnames &fieldnames, std::string sessionid, - time_t oldest = 0) + time_t oldest) { if(!dao) return Values(); mutex.lock(); @@ -92,7 +92,7 @@ public: bool checkMacro(std::string patientid, std::string macro, std::string sessionid, - time_t oldest = 0) + time_t oldest) { DEBUG(db, "%s, %s, %ld\n", patientid.c_str(), macro.c_str(), oldest); @@ -108,7 +108,7 @@ public: time_t oldest, std::string sessionid) { DEBUG(db, "%s, %s, %ld\n", - patientid.c_str(), macro.attributes["name"].c_str(), oldest); + patientid.c_str(), macro.name.c_str(), oldest); if(!dao) return ""; Fieldnames fn; fn.push_back("journal.resume"); diff --git a/server/src/fieldnamescanner.cc b/server/src/fieldnamescanner.cc index 585657b..5418bb4 100644 --- a/server/src/fieldnamescanner.cc +++ b/server/src/fieldnamescanner.cc @@ -81,7 +81,7 @@ templates_t scanfieldnames(std::set &filter) std::vector::iterator ms = t->macros.begin(); while(ms != t->macros.end()) { if(ms->isHeader == false) { - std::string macro = ms->attributes["name"]; + std::string macro = ms->name; DEBUG(scanner, "Name '%s'\n", macro.c_str()); std::string macrofile = macrolist.getLatestVersion(macro); DEBUG(scanner, "File '%s'\n", macrofile.c_str()); diff --git a/server/src/journal.cc b/server/src/journal.cc index b9f5c82..c38246f 100644 --- a/server/src/journal.cc +++ b/server/src/journal.cc @@ -38,19 +38,19 @@ void Journal::addEntry(Transaction &transaction, Commit &commit, std::vector< Macro >::iterator i = templ->macros.begin(); while(i != templ->macros.end()) { Macro &m = *i; - if(commit.macro == m.attributes["name"]) break; + if(commit.macro == m.name) break; index++; i++; } if(index >= templ->macros.size()) { ERR(journal, "Could not find macro %s in template %s\n", - commit.macro.c_str(), templ->attributes["name"].c_str()); + commit.macro.c_str(), templ->name.c_str()); // return; } else { DEBUG(journal, "Found macro %s as index %u in template %s\n", commit.macro.c_str(), index, - templ->attributes["name"].c_str()); + templ->name.c_str()); } if(entrylist.size() == 0) { @@ -59,7 +59,7 @@ void Journal::addEntry(Transaction &transaction, Commit &commit, } DEBUG(journal, "addEntry: template(%s)\n", - templ->attributes["name"].c_str()); + templ->name.c_str()); // Test if the username or the cpr has changed... // if so, commit and clear the list. diff --git a/server/src/luapraxisd.cc b/server/src/luapraxisd.cc new file mode 100644 index 0000000..6025aa5 --- /dev/null +++ b/server/src/luapraxisd.cc @@ -0,0 +1,241 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * luapraxisd.cc + * + * Wed Apr 27 11:59:53 CEST 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 "luapraxisd.h" + +#include "praxisd.h" + +#include +#include + +#include "debug.h" + +#define luaL_checkbool(L, i) \ + (lua_isboolean(L,i) ? lua_toboolean(L,i) : luaL_checkint(L,i)) + +typedef struct px_userdata { + Praxisd *px; +} px_userdata; + +static int px_addcave(lua_State *L) +{ + px_userdata *pxu; + pxu = (px_userdata *)luaL_checkudata(L, 1, "Praxisd"); + luaL_argcheck(L, pxu, 1, "Praxisd expected"); + + const char *cpr = luaL_checkstring(L, 2); + const char *cave = luaL_checkstring(L, 3); + + std::string sogeord; + std::string sogetxt; + + std::vector cavelist = pxu->px->diverse_get_cave(""); + std::vector::iterator i = cavelist.begin(); + while(i != cavelist.end()) { + Praxisd::cave_t &c = *i; + if(strcasecmp(cave, c.cave.c_str()) == 0) { + pxu->px->add_sogeord(cpr, c.sogenr, ""); + return 0; + } + i++; + } + + pxu->px->add_sogeord(cpr, "CA0003", cave); // CA0003 == 'ANDET' + + return 0; +} + +static int px_getcave(lua_State *L) +{ + px_userdata *pxu; + pxu = (px_userdata *)luaL_checkudata(L, 1, "Praxisd"); + luaL_argcheck(L, pxu, 1, "Praxisd expected"); + + const char *cpr = luaL_checkstring(L, 2); + + std::vector cavelist; + + Praxisd::patient_t pat = pxu->px->patient_get_by_cpr(cpr); + std::vector::iterator i = pat.sogeord.begin(); + while(i != pat.sogeord.end()) { + Praxisd::sogeord_t &s = *i; + if(s.sogenr[0] == 'C') { + std::string csogenr = s.sogenr.substr(1, s.sogenr.length() - 1); + std::vector cl = pxu->px->diverse_get_cave(csogenr); + if(cl.size() == 1) { + if(cl[0].cave == "ANDET") cl[0].cave = s.sogetxt; + cavelist.push_back(cl[0]); + } + } + + i++; + } + + lua_createtable(L, 0, cavelist.size()); + int top = lua_gettop(L); + + for(size_t i = 0; i < cavelist.size(); i++) { + lua_pushstring(L, cavelist[i].cave.c_str()); + lua_rawseti(L, top, i); + } + + return 1; +} + +static int px_cavelist(lua_State *L) +{ + px_userdata *pxu; + pxu = (px_userdata *)luaL_checkudata(L, 1, "Praxisd"); + luaL_argcheck(L, pxu, 1, "Praxisd expected"); + + const char *sogenr = luaL_checkstring(L, 2); + + std::vector cavelist = pxu->px->diverse_get_cave(sogenr); + + lua_createtable(L, 0, cavelist.size()); + int top = lua_gettop(L); + + for(size_t i = 0; i < cavelist.size(); i++) { + lua_pushstring(L, cavelist[i].cave.c_str()); + lua_rawseti(L, top, i); + } + + return 1; +} + +static int px_new(lua_State *L) +{ + const char *host = luaL_checkstring(L, 1); + int port = luaL_checknumber(L, 2); + + px_userdata *pxu; + pxu = (px_userdata *)lua_newuserdata(L, sizeof(px_userdata)); + + luaL_getmetatable(L, "Praxisd"); + lua_setmetatable(L, -2); + + pxu->px = new Praxisd(host, port); + + return 1; +} + +static int px_gc(lua_State *L) +{ + px_userdata *pxu; + + pxu = (px_userdata *)luaL_checkudata(L, 1, "Praxisd"); + luaL_argcheck(L, pxu, 1, "Praxisd expected"); + + delete pxu->px; + + return 0; +} + +static const struct luaL_Reg px_meths[] = { + {"__gc" ,px_gc}, + {"cavelist", px_cavelist}, + {"getcave", px_getcave}, + {"addcave", px_addcave}, + {NULL, NULL} +}; + +static const struct luaL_reg px_funcs[] = { + {"new", px_new}, + {NULL, NULL} +}; + +void register_praxisd(lua_State *L) +{ + luaL_newmetatable(L, "Praxisd"); + lua_pushliteral(L, "__index"); + lua_pushvalue(L, -2); + lua_rawset(L, -3); + luaL_register(L, NULL, px_meths); + luaL_openlib (L, "Praxisd", px_funcs, 0); +} + +#ifdef TEST_LUAPRAXISD +//deps: praxisd.cc debug.cc saxparser.cc log.cc +//cflags: -I.. $(LUA_CFLAGS) $(CURL_CFLAGS) $(EXPAT_CFLAGS) +//libs: $(LUA_LIBS) $(CURL_LIBS) $(EXPAT_LIBS) +#include "test.h" + +TEST_BEGIN; + +lua_State *L = luaL_newstate(); +if(L == NULL) { + ERR(luaresume, "Could not create LUA state.\n"); +} + +luaL_openlibs(L); + +register_praxisd(L); + +///// +std::string program = + "px = Praxisd.new('localhost', 10000)\n" + "cl = px:cavelist('')\n" + "for i=1,#cl do\n" + " print(cl[i])\n" + "end\n" + "\n" + "--pcl = px:addcave('1505050505', 'LUMIGAN')\n" + "\n" + "pcl = px:addcave('1505050505', os.date('%H%M%S'))\n" + "\n" + "pcl = px:getcave('1505050505')\n" + "for i=1,#pcl do\n" + " print('p: ' .. pcl[i])\n" + "end\n" + ; + +//int top = lua_gettop(L); + +if(luaL_loadbuffer(L, program.c_str(), program.size(), "luapraxisd test")) { + ERR(luaresume, "loadbufer: %s\n", lua_tostring(L, lua_gettop(L))); +} + +if(lua_pcall(L, 0, LUA_MULTRET, 0)) { + ERR(luaresume, "pcall: %s\n" , lua_tostring(L, lua_gettop(L))); +} +/* +if(top != lua_gettop(L) - 1) { + ERR(luaresume, "Program did not return a single value.\n"); +} + +if(lua_isstring(L, lua_gettop(L)) == false) { + ERR(luaresume, "Program did not return a string value.\n"); +} + +std::string res = lua_tostring(L, lua_gettop(L)); +lua_pop(L, 1); +*/ +lua_close(L); + +TEST_END; + +#endif/*TEST_LUAPRAXISD*/ diff --git a/server/src/luapraxisd.h b/server/src/luapraxisd.h new file mode 100644 index 0000000..2ab9ab5 --- /dev/null +++ b/server/src/luapraxisd.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * luapraxisd.h + * + * Wed Apr 27 11:59:53 CEST 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. + */ +#ifndef __PRACRO_LUAPRAXISD_H__ +#define __PRACRO_LUAPRAXISD_H__ + +#include + +void register_praxisd(lua_State *L); + +#endif/*__PRACRO_LUAPRAXISD_H__*/ diff --git a/server/src/luaresume.cc b/server/src/luaresume.cc index 9202c27..d3597ad 100644 --- a/server/src/luaresume.cc +++ b/server/src/luaresume.cc @@ -27,6 +27,7 @@ #include "luaresume.h" #include "luautil.h" +#include "luapraxisd.h" #include "debug.h" @@ -72,6 +73,8 @@ LUAResume::LUAResume(Commit &c) lua_setglobal(L, GLOBAL_POINTER); // Assign it to a global lua var. lua_register(L, "value", _value); + + register_praxisd(L); } LUAResume::~LUAResume() diff --git a/server/src/macroheaderparser.cc b/server/src/macroheaderparser.cc index c8d5fb2..3262888 100644 --- a/server/src/macroheaderparser.cc +++ b/server/src/macroheaderparser.cc @@ -92,13 +92,15 @@ MacroHeaderParser::~MacroHeaderParser() if(m) delete m; } -void MacroHeaderParser::startTag(std::string name, std::map< std::string, std::string> attributes) +void MacroHeaderParser::startTag(std::string name, attributes_t &attr) { if(m) return; if(name == "macro") { m = new Macro(); - m->attributes = attributes; + if(attr.find("name") != attr.end()) m->name = attr["name"]; + if(attr.find("version") != attr.end()) m->version = attr["version"]; + } else { throw Exception("Missing root tag 'macro' - found '" + name + "'"); } diff --git a/server/src/macroheaderparser.h b/server/src/macroheaderparser.h index a4bb8bc..9b41d0c 100644 --- a/server/src/macroheaderparser.h +++ b/server/src/macroheaderparser.h @@ -60,7 +60,7 @@ public: /** * Overloaded parser callback method. */ - void startTag(std::string name, std::map< std::string, std::string> attributes); + void startTag(std::string name, attributes_t &attr); /** * Overloaded parser callback method. diff --git a/server/src/macrolist.cc b/server/src/macrolist.cc index fc54ce9..935c403 100644 --- a/server/src/macrolist.cc +++ b/server/src/macrolist.cc @@ -52,9 +52,7 @@ void MacroList::addFile(std::string file) try { parser.parse(); Macro *macro = parser.getMacro(); - insertEntity(macro->attributes["name"], - macro->attributes["version"], - file); + insertEntity(macro->name, macro->version, file); } catch(Exception &e) { WARN(macrolist, "Skipping %s: %s\n", file.c_str(), e.what()); } diff --git a/server/src/macroparser.cc b/server/src/macroparser.cc index bf6ff13..d1604b2 100644 --- a/server/src/macroparser.cc +++ b/server/src/macroparser.cc @@ -118,8 +118,7 @@ void MacroParser::characterData(std::string &data) } } -void MacroParser::startTag(std::string name, - std::map< std::string, std::string> attributes) +void MacroParser::startTag(std::string name, attributes_t &attr) { // Create macro and enable parsing of queries, maps and widgets if(name == "macro") { @@ -129,7 +128,9 @@ void MacroParser::startTag(std::string name, assert(!m); // A Macro has already been allocated, cannot create macro! m = new Macro(); - m->attributes = attributes; + + if(attr.find("name") != attr.end()) m->name = attr["name"]; + if(attr.find("version") != attr.end()) m->version = attr["version"]; return; } @@ -139,7 +140,7 @@ void MacroParser::startTag(std::string name, if(state != MACRO) error("resume found outside macro."); state = RESUME; - m->resume.attributes = attributes; + m->resume.attributes = attr; assert(m); // No macro is currently available, cannot create resume! @@ -164,7 +165,7 @@ void MacroParser::startTag(std::string name, assert(m); // No macro is currently available, cannot create query! Query q; - q.attributes = attributes; + q.attributes = attr; m->queries.push_back(q); return; @@ -188,7 +189,7 @@ void MacroParser::startTag(std::string name, assert(m); // No macro is currently available, cannot create map! Map map; - map.attributes = attributes; + map.attributes = attr; m->maps.push_back(map); current_map = &(m->maps.back()); @@ -216,7 +217,7 @@ void MacroParser::startTag(std::string name, state = SCRIPT; Script s; - s.attributes = attributes; + s.attributes = attr; m->scripts.push_back(s); current_script = &(m->scripts.back()); } @@ -226,7 +227,7 @@ void MacroParser::startTag(std::string name, state = RESUME_SCRIPT; Script s; - s.attributes = attributes; + s.attributes = attr; m->resume_scripts.push_back(s); current_resume_script = &(m->resume_scripts.back()); } @@ -246,7 +247,7 @@ void MacroParser::startTag(std::string name, assert(m); // No macro is currently available, cannot create widgets! - m->widgets.attributes = attributes; + m->widgets.attributes = attr; m->widgets.attributes["tagname"] = name; Widget *current = &(m->widgets); @@ -262,7 +263,7 @@ void MacroParser::startTag(std::string name, assert(widgetstack.size()); // Widget stack is empty, cannot create! Widget w; - w.attributes = attributes; + w.attributes = attr; w.attributes["tagname"] = name; Widget *parent = widgetstack.back(); diff --git a/server/src/macroparser.h b/server/src/macroparser.h index eaa5638..71ef911 100644 --- a/server/src/macroparser.h +++ b/server/src/macroparser.h @@ -50,7 +50,7 @@ public: ~MacroParser(); void characterData(std::string &data); - void startTag(std::string name, std::map< std::string, std::string> attributes); + void startTag(std::string name, attributes_t &attr); void endTag(std::string name); void parseError(const char *buf, size_t len, std::string error, int lineno); diff --git a/server/src/macrotool/dump.cc b/server/src/macrotool/dump.cc index b567768..3d28181 100644 --- a/server/src/macrotool/dump.cc +++ b/server/src/macrotool/dump.cc @@ -104,12 +104,12 @@ static std::map macroList() parser.parse(); Macro *macro = parser.getMacro(); - std::string key = macro->attributes["name"];// + "-" + macro->attributes["version"]; - macros[key].name = macro->attributes["name"]; + std::string key = macro->name;// + "-" + macro->version; + macros[key].name = macro->name; macros[key].file = *mfs; macros[key].title = macro->widgets.attributes["caption"]; macros[key].fields = getFields(macro->widgets); - macros[key].version = macro->attributes["version"]; + macros[key].version = macro->version; } catch( Exception &e ) { printf("Skipping: %s: %s\n", mfs->c_str(), e.what()); } @@ -127,8 +127,7 @@ static std::map macroList() Template *t = parser.getTemplate(); std::vector::iterator ms = t->macros.begin(); while(ms != t->macros.end()) { - if(ms->attributes.find("header") == ms->attributes.end()) - macros[ms->attributes["name"]].templates.insert(templ); + if(ms->isHeader) macros[ms->name].templates.insert(templ); ms++; } } catch( Exception &e ) { @@ -234,17 +233,16 @@ static std::map templateList() parser.parse(); Template *t = parser.getTemplate(); - std::string key = t->attributes["name"]; + std::string key = t->name; templates[key].file = *tfs; - templates[key].name = t->attributes["name"]; - templates[key].title = t->attributes["title"]; - templates[key].version = t->attributes["version"]; + templates[key].name = t->name; + templates[key].title = t->title; + templates[key].version = t->version; std::vector::iterator ms = t->macros.begin(); while(ms != t->macros.end()) { - if(ms->attributes.find("header") == ms->attributes.end()) - templates[key].macros.push_back(ms->attributes["name"]); + if(ms->isHeader) templates[key].macros.push_back(ms->name); ms++; } } catch( Exception &e ) { diff --git a/server/src/macrotool/filehandler.cc b/server/src/macrotool/filehandler.cc index 3c80a1c..738b687 100644 --- a/server/src/macrotool/filehandler.cc +++ b/server/src/macrotool/filehandler.cc @@ -74,11 +74,11 @@ static bool check(std::string file, std::string *name, std::string *version) } printf("Parsing of %s was succesful.\n", file.c_str()); - printf("Name: %s\n", macro->attributes["name"].c_str()); - printf("Version: %s\n", macro->attributes["version"].c_str()); + printf("Name: %s\n", macro->name.c_str()); + printf("Version: %s\n", macro->version.c_str()); - if(name) *name = macro->attributes["name"]; - if(version) *version = macro->attributes["version"]; + if(name) *name = macro->name; + if(version) *version = macro->version; } catch( std::exception &e ) { printf("%s\n", e.what()); @@ -102,8 +102,7 @@ static bool macro_exists(std::string name, std::string version, std::string &cla parser.parse(); Macro *macro = parser.getMacro(); - if(name == macro->attributes["name"] && - version == macro->attributes["version"]) { + if(name == macro->name && version == macro->version) { clashfile = *mfs; return true; } diff --git a/server/src/pracrodaopgsql.cc b/server/src/pracrodaopgsql.cc index 774fb0c..c1a0c93 100644 --- a/server/src/pracrodaopgsql.cc +++ b/server/src/pracrodaopgsql.cc @@ -108,7 +108,7 @@ void PracroDAOPgsql::commitTransaction(std::string sessionid, { DEBUG(db, "commitTransaction (%s, %s, %s, <%u fields>, %ld)\n", transaction.user.c_str(), transaction.cpr.c_str(), - _macro.attributes["name"].c_str(), + _macro.name.c_str(), commit.fields.size(), now); if(!conn) { @@ -120,8 +120,8 @@ void PracroDAOPgsql::commitTransaction(std::string sessionid, pqxx::work W(*conn); - std::string version = _macro.attributes["version"]; - std::string macro = _macro.attributes["name"]; + std::string version = _macro.version; + std::string macro = _macro.name; std::stringstream timestamp; timestamp << now; std::string ts; @@ -245,7 +245,7 @@ Values PracroDAOPgsql::getLatestValues(std::string sessionid, DEBUG(db, "(%s, %s, <%u fieldnames>, %ld)\n", patientid.c_str(), - macro ? macro->attributes["name"].c_str() : "(null)", + macro ? macro->name.c_str() : "(null)", fieldnames.size(), oldest); std::string query; @@ -278,16 +278,18 @@ Values PracroDAOPgsql::getLatestValues(std::string sessionid, " (SELECT f.name, MAX(t.timestamp) AS ts " " FROM commits c, fields f, transactions t " " WHERE "; - //if(!uncom) query += "(c.status='committed' OR c.uid="+sessionid+") AND "; - if(!uncom) query += "((c.status='committed' AND t.timestamp >= " + soldest.str() + ") OR c.uid="+sessionid+") AND "; + if(!uncom) { + query += "((c.status='committed' AND t.timestamp >= " + soldest.str() + + ") OR c.uid="+sessionid+") AND "; + } query += "c.uid = t.cid AND t.uid = f.transaction" // " AND t.timestamp >= " + soldest.str() + " AND c.patientid = '" + W.esc(patientid) + "' " + namecond; if(macro) { - query += " AND t.macro = '" + macro->attributes["name"] + "'"; - if(macro->attributes["version"].size() > 0) - query += " AND t.version = '" + macro->attributes["version"] + "'"; + query += " AND t.macro = '" + macro->name + "'"; + if(macro->version != "") + query += " AND t.version = '" + macro->version + "'"; } query += " GROUP BY f.name) xx, " // End inner query @@ -301,9 +303,9 @@ Values PracroDAOPgsql::getLatestValues(std::string sessionid, " AND cc.patientid = '" + W.esc(patientid) + "' " ; if(macro) { - query += " AND tt.macro = '" + macro->attributes["name"] + "'"; - if(macro->attributes["version"].size() > 0) - query += " AND tt.version = '" + macro->attributes["version"] + "'"; + query += " AND tt.macro = '" + macro->name + "'"; + if(macro->version != "") + query += " AND tt.version = '" + macro->version + "'"; } DEBUG(sql, "Query: %s\n", query.c_str()); diff --git a/server/src/pracrodaotest.cc b/server/src/pracrodaotest.cc index dd62016..532877b 100644 --- a/server/src/pracrodaotest.cc +++ b/server/src/pracrodaotest.cc @@ -72,13 +72,13 @@ void PracroDAOTest::commitTransaction(std::string sessionid, DEBUG(db, "(%s, %s, %s, <%u fields>, %ld)\n", transaction.user.c_str(), transaction.cpr.c_str(), - _macro.attributes["name"].c_str(), + _macro.name.c_str(), commit.fields.size(), now); if(commit.fields.size() == 0) return; - std::string version = _macro.attributes["version"]; - std::string macro = _macro.attributes["name"]; + std::string version = _macro.version; + std::string macro = _macro.name; std::stringstream timestamp; timestamp << now; dbtable_t::iterator ci = select(data.commits, "uid", sessionid); @@ -153,7 +153,7 @@ Values PracroDAOTest::getLatestValues(std::string sessionid, std::string patientid, Macro *macro, Fieldnames &fieldnames, time_t oldest) { - std::string macro_name = macro ? macro->attributes["name"].c_str() : "(null)"; + std::string macro_name = macro ? macro->name.c_str() : "(null)"; DEBUG(db, "(%s, %s, <%u fieldnames>, %ld)\n", patientid.c_str(), macro_name.c_str(), fieldnames.size(), diff --git a/server/src/praxisd.cc b/server/src/praxisd.cc index 4a9c2f1..d814b54 100644 --- a/server/src/praxisd.cc +++ b/server/src/praxisd.cc @@ -246,7 +246,7 @@ public: } } - void endTag(std::string name) + void endTag(std::string) { str = NULL; } @@ -304,7 +304,7 @@ class AdresseParser : public SAXParser { public: AdresseParser(std::vector &al) : div(al) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_adresse") { @@ -340,7 +340,7 @@ public: BehandlingParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_behandling") { @@ -374,7 +374,7 @@ public: CaveParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_cave") { @@ -407,7 +407,7 @@ public: DiagnoseParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_diagnose") { @@ -440,7 +440,7 @@ public: FraseParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_frase") { @@ -473,7 +473,7 @@ public: GrafikParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_grafik") { @@ -504,7 +504,7 @@ public: IndholdstofParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_indholdstof") { @@ -539,7 +539,7 @@ public: KlageParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_klage") { @@ -572,7 +572,7 @@ public: OversigtParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_oversigt") { @@ -604,7 +604,7 @@ public: PostnummerParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_postnummer") { @@ -641,7 +641,7 @@ public: TypeParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_type") { @@ -675,7 +675,7 @@ public: UndersoegelseParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_undersoegelse") { @@ -708,7 +708,7 @@ public: YdelseParser(std::vector &d) : div(d) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "div_ydelse") { @@ -745,7 +745,7 @@ class AftaleParser : public SAXParser { public: AftaleParser(std::vector &a) : div(a) { str = NULL; } void characterData(std::string &data) { if(str) *str += data; } - void endTag(std::string name) { str = NULL; } + void endTag(std::string) { str = NULL; } void startTag(std::string name, std::map attr) { if(name == "aftale") { @@ -877,6 +877,17 @@ TEST_EQUAL_STR(exp, j2, "Did we correctly append to the journal?"); p.add_sogeord(CPR, "CA0003", "Nolder"); +{ + std::vector cave = p.diverse_get_cave("A0001"); + TEST_EQUAL_INT(cave.size(), 1, "Precicely one result."); + TEST_EQUAL_STR(cave[0].cave, "AZOPT", "The correct one?"); +} + +{ + std::vector cave = p.diverse_get_cave(""); + TEST_EQUAL_INT(cave.size(), 25, "Get them all."); +} + TEST_END; #endif/*TEST_PRAXISD*/ diff --git a/server/src/queryparser.cc b/server/src/queryparser.cc index 3d228f6..138b7ab 100644 --- a/server/src/queryparser.cc +++ b/server/src/queryparser.cc @@ -36,7 +36,7 @@ QueryParser::QueryParser() stack.push_back(&result); } -void QueryParser::startTag(std::string name, std::map< std::string, std::string> attributes) +void QueryParser::startTag(std::string name, attributes_t &attr) { if(name == "results") { @@ -44,24 +44,24 @@ void QueryParser::startTag(std::string name, std::map< std::string, std::string> } if(name == "result") { - this->timestamp = atol(attributes["timestamp"].c_str()); + this->timestamp = atol(attr["timestamp"].c_str()); QueryResult q; q.source = "pentominos"; q.timestamp = this->timestamp; - stack.back()->groups[attributes["class"]] = q; - stack.push_back(&stack.back()->groups[attributes["class"]]); + stack.back()->groups[attr["class"]] = q; + stack.push_back(&stack.back()->groups[attr["class"]]); } if(name == "group") { QueryResult q; q.timestamp = this->timestamp; - stack.back()->groups[attributes["name"]] = q; - stack.push_back(&stack.back()->groups[attributes["name"]]); + stack.back()->groups[attr["name"]] = q; + stack.push_back(&stack.back()->groups[attr["name"]]); } if(name == "value") { - stack.back()->values[attributes["name"]] = utf8.decode(attributes["value"]); + stack.back()->values[attr["name"]] = utf8.decode(attr["value"]); } } diff --git a/server/src/queryparser.h b/server/src/queryparser.h index f901d2c..80a51e1 100644 --- a/server/src/queryparser.h +++ b/server/src/queryparser.h @@ -57,7 +57,7 @@ public: /** * Private parser callback. */ - void startTag(std::string name, std::map< std::string, std::string> attributes); + void startTag(std::string name, attributes_t &attr); /** * Private parser callback. diff --git a/server/src/saxparser.cc b/server/src/saxparser.cc index 72f0fe4..597b853 100644 --- a/server/src/saxparser.cc +++ b/server/src/saxparser.cc @@ -155,8 +155,10 @@ bool SAXParser::parse(const char *data, size_t size) } } - if(done) DEBUG(sax, "Got END_OF_DOCUMENT [%s] at %ld\n", - outertag.c_str(), XML_GetCurrentByteIndex(p)); + if(done) { + DEBUG(sax, "Got END_OF_DOCUMENT [%s] at %ld\n", + outertag.c_str(), XML_GetCurrentByteIndex(p)); + } return done; } @@ -176,6 +178,22 @@ unsigned int SAXParser::usedBytes() return bufferbytes + (XML_GetCurrentByteIndex(p) - totalbytes); } +int SAXParser::readData(char *, size_t) +{ + return 0; +} + +void SAXParser::endTag(std::string) +{ +} + +void SAXParser::startTag(std::string, attributes_t &) +{ +} + +void SAXParser::characterData(std::string &) +{ +} #ifdef TEST_SAXPARSER //deps: log.cc debug.cc exception.cc diff --git a/server/src/saxparser.h b/server/src/saxparser.h index 265727f..c303d41 100644 --- a/server/src/saxparser.h +++ b/server/src/saxparser.h @@ -31,6 +31,8 @@ #include #include +typedef std::map< std::string, std::string> attributes_t; + /** * This class implements a SAX Parser, utilising the eXpat XML parser library. * It uses virtual methods for the callbacks, and transforms tagnames and @@ -61,11 +63,11 @@ public: /** * Character data callback method. * Reimplement this to get character callbacks. - * This callback might be called several times, if a character block is big. In - * that cae it might be nessecary to buffer to received bytes. + * This callback might be called several times, if a character block is big. + * In that cae it might be nessecary to buffer to received bytes. * @param data A std::string containing the character data. */ - virtual void characterData(std::string &data) {} + virtual void characterData(std::string &data); /** * Start tag callback mehtod. @@ -75,7 +77,7 @@ public: * @param attributes A std::map of std::string to std::string containing all * attributes for the tag. */ - virtual void startTag(std::string name, std::map< std::string, std::string> attributes) {} + virtual void startTag(std::string name, attributes_t &attr); /** * End tag callback mehtod. @@ -83,19 +85,22 @@ public: * It is called each time an end tag is seen. * @param name A std::string containing the tag name. */ - virtual void endTag(std::string name) {} + virtual void endTag(std::string name); /** * Error callback method. * Reimplement this to handle error messages. - * A default implementation prints out the current buffer, linenumber and error - * message to the screen. + * A default implementation prints out the current buffer, linenumber and + * error message to the screen. * @param buf A char* containing the current buffer being parsed. - * @param len A size_t containing the length of the current buffer being parsed. + * @param len A size_t containing the length of the current buffer being + * parsed. * @param error A std::string containing the error message. - * @param lineno An integer containing the line number on which the error occurred. + * @param lineno An integer containing the line number on which the error + * occurred. */ - virtual void parseError(const char *buf, size_t len, std::string error, int lineno); + virtual void parseError(const char *buf, size_t len, std::string error, + int lineno); /** * Buffer parse method. @@ -111,10 +116,11 @@ public: /** * Get the number of bytes used from the last buffer. - * If the buffer parse method is used, and the buffer comes from a stream of xml - * doxuments, this method can be used to figure out how many bytes from the stream - * should be replayed, to another parser. - * @return an integer containing the number of bytes used from the last buffer. + * If the buffer parse method is used, and the buffer comes from a stream of + * xml doxuments, this method can be used to figure out how many bytes from + * the stream should be replayed, to another parser. + * @return an integer containing the number of bytes used from the last + * buffer. * @see bool parse(char *buf, size_t size) */ unsigned int usedBytes(); @@ -129,13 +135,13 @@ protected: * This method is used when the parse() method is used. * It can be used to connect the parser with eg. a file. * @param data A char* containing the buffer to be filled. - * @param size A size_t containing the maximum number of bytes to be filled (ie. - * the size of data) - * @return An integer contaning the actual number of bytes filled. 0 if no more - * bytes are available. + * @param size A size_t containing the maximum number of bytes to be filled + * (ie. the size of data) + * @return An integer contaning the actual number of bytes filled. 0 if no + * more bytes are available. * @see int parse() */ - virtual int readData(char *data, size_t size) { return 0; } + virtual int readData(char *data, size_t size); XML_Parser p; diff --git a/server/src/sessionparser.cc b/server/src/sessionparser.cc index 17cc4fb..6b3653e 100644 --- a/server/src/sessionparser.cc +++ b/server/src/sessionparser.cc @@ -54,33 +54,32 @@ void SessionParser::characterData(std::string &data) } } -void SessionParser::startTag(std::string name, - std::map attributes) +void SessionParser::startTag(std::string name, attributes_t &attr) { DEBUG(sessionparser, "<%s>\n", name.c_str()); if(name == "session") { - patientid = attributes["patientid"]; - sessionid = attributes["id"]; - templ = attributes["template"]; - status = attributes["status"]; + patientid = attr["patientid"]; + sessionid = attr["id"]; + templ = attr["template"]; + status = attr["status"]; } if(name == "journal") { - // patientid = attributes["patientid"]; - // userid = attributes["userid"]; + // patientid = attr["patientid"]; + // userid = attr["userid"]; } if(name == "database") { - dbtype = attributes["type"]; + dbtype = attr["type"]; indatabase = true; } if(name == "entry") { Entry e; - e.index = atoi(attributes["index"].c_str()); - e.macro = attributes["macro"]; - e.user = attributes["user"]; + e.index = atoi(attr["index"].c_str()); + e.macro = attr["macro"]; + e.user = attr["user"]; entries.push_back(e); } diff --git a/server/src/sessionparser.h b/server/src/sessionparser.h index 229ae10..df32b06 100644 --- a/server/src/sessionparser.h +++ b/server/src/sessionparser.h @@ -39,8 +39,7 @@ public: ~SessionParser(); void characterData(std::string &data); - void startTag(std::string name, - std::map< std::string, std::string> attributes); + void startTag(std::string name, attributes_t &attr); void endTag(std::string name); void parseError(const char *buf, size_t len, std::string error, int lineno); diff --git a/server/src/template.h b/server/src/template.h index 479e6ee..a069cff 100644 --- a/server/src/template.h +++ b/server/src/template.h @@ -68,15 +68,36 @@ public: std::vector< Script > scripts; std::vector< Script > resume_scripts; Widget widgets; - attr_t attributes; Resume resume; + bool isHeader; + bool isStatic; + bool isCompact; + bool isImportant; + + std::string name; + std::string version; + std::string caption; + std::string requires; + std::string ttl; }; class Template { public: std::vector< Macro > macros; - attr_t attributes; + + std::string name; + std::string title; + std::string version; +}; + +class Course { +public: + std::vector< Template > templates; + + std::string name; + std::string title; + std::string version; }; #endif/*__PRACRO_TEMPLATE_H__*/ diff --git a/server/src/templateheaderparser.cc b/server/src/templateheaderparser.cc index e549035..57b0a4e 100644 --- a/server/src/templateheaderparser.cc +++ b/server/src/templateheaderparser.cc @@ -92,13 +92,17 @@ TemplateHeaderParser::~TemplateHeaderParser() if(t) delete t; } -void TemplateHeaderParser::startTag(std::string name, std::map< std::string, std::string> attributes) +void TemplateHeaderParser::startTag(std::string name, attributes_t &attr) { if(t) return; if(name == "template") { t = new Template(); - t->attributes = attributes; + + if(attr.find("name") != attr.end()) t->name = attr["name"]; + if(attr.find("title") != attr.end()) t->title = attr["title"]; + if(attr.find("version") != attr.end()) t->version = attr["version"]; + } else { throw Exception("Missing root tag 'template' - found '" + name + "'"); } diff --git a/server/src/templateheaderparser.h b/server/src/templateheaderparser.h index ce63180..6c51912 100644 --- a/server/src/templateheaderparser.h +++ b/server/src/templateheaderparser.h @@ -60,7 +60,7 @@ public: /** * Overloaded parser callback method. */ - void startTag(std::string name, std::map< std::string, std::string> attributes); + void startTag(std::string name, attributes_t &attr); /** * Overloaded parser callback method. diff --git a/server/src/templatelist.cc b/server/src/templatelist.cc index 7d19bfb..48dbab5 100644 --- a/server/src/templatelist.cc +++ b/server/src/templatelist.cc @@ -49,8 +49,8 @@ void TemplateList::addFile(std::string file) try { parser.parse(); Template *templ = parser.getTemplate(); - insertEntity(templ->attributes["name"], - templ->attributes["version"], + insertEntity(templ->name, + templ->version, file); } catch(Exception &e) { WARN(templatelist, "Skipping %s: %s\n", file.c_str(), e.what()); diff --git a/server/src/templateparser.cc b/server/src/templateparser.cc index 20270c6..b9c65f5 100644 --- a/server/src/templateparser.cc +++ b/server/src/templateparser.cc @@ -83,7 +83,7 @@ void TemplateParser::characterData(std::string &data) { } -void TemplateParser::startTag(std::string name, std::map< std::string, std::string> attributes) +void TemplateParser::startTag(std::string name, attributes_t &attr) { // Enable macro parsing if(name == "template") { @@ -92,7 +92,9 @@ void TemplateParser::startTag(std::string name, std::map< std::string, std::stri assert(t); // A Template has not yet been allocated, cannot create template! - t->attributes = attributes; + if(attr.find("name") != attr.end()) t->name = attr["name"]; + if(attr.find("title") != attr.end()) t->title = attr["title"]; + if(attr.find("version") != attr.end()) t->version = attr["version"]; return; } @@ -105,7 +107,19 @@ void TemplateParser::startTag(std::string name, std::map< std::string, std::stri assert(t); // A Template has not yet been allocated, cannot create macro! Macro m; - m.attributes = attributes; + + if(attr.find("name") != attr.end()) m.name = attr["name"]; + if(attr.find("version") != attr.end()) m.version = attr["version"]; + if(attr.find("caption") != attr.end()) m.caption = attr["caption"]; + if(attr.find("requires") != attr.end()) m.requires = attr["requires"]; + if(attr.find("ttl") != attr.end()) m.ttl = attr["ttl"]; + + m.isImportant = attr.find("important") != attr.end() && + attr["important"] == "true"; + m.isStatic = attr.find("static") != attr.end() && attr["static"] == "true"; + m.isCompact = attr.find("compact") != attr.end() && + attr["compact"] == "true"; + m.isHeader = name == "header"; t->macros.push_back(m); current_macro = &(t->macros.back()); @@ -139,7 +153,8 @@ int TemplateParser::readData(char *data, size_t size) return r; } -void TemplateParser::parseError(const char *buf, size_t len, std::string error, int lineno) +void TemplateParser::parseError(const char *buf, size_t len, std::string error, + int lineno) { fprintf(stderr, "TemplateParser[%s] error at line %d: %s\n", file.c_str(), lineno, error.c_str()); diff --git a/server/src/templateparser.h b/server/src/templateparser.h index 51e24a7..5b8302f 100644 --- a/server/src/templateparser.h +++ b/server/src/templateparser.h @@ -42,7 +42,7 @@ public: ~TemplateParser(); void characterData(std::string &data); - void startTag(std::string name, std::map< std::string, std::string> attributes); + void startTag(std::string name, attributes_t &attr); void endTag(std::string name); void parseError(const char *buf, size_t len, std::string error, int lineno); diff --git a/server/src/transactionhandler.cc b/server/src/transactionhandler.cc index bcdd638..4b4e7ca 100644 --- a/server/src/transactionhandler.cc +++ b/server/src/transactionhandler.cc @@ -107,11 +107,8 @@ static std::string handleRequest(Transaction &transaction, Environment &env, Template *templ = tp.getTemplate(); - answer += "